[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cairo
Subject:    [cairo] Invert colors but without touching transparent parts
From:       Mihai Moldovan <ionic () ionic ! de>
Date:       2022-09-18 22:55:59
Message-ID: 46c65268-1b89-3425-d055-cf7f8ab0b6a5 () ionic ! de
[Download RAW message or body]

[Attachment #2 (multipart/mixed)]


Hi


I'm trying to invert colors from a previous drawing operation, but without
touching transparent parts.

I've tried painting with a white, opaque source and using the DIFFERENCE
operator, but that also inverts transparent elements (because the alpha
calculating is done using the logic implemented in the OVER operator?)

Is there any way to do what I have in mind?

I'm "attaching" (really inlining) a MWE to showcase the issue. I'd like to
invert the color of the rectangle from white to black, but keep the background
green. The actual thing I'm trying to do is more complicated, since it involves
reading an image into a GtkImage widget and modifying that in the draw function,
so using a mask is difficult to impossible (I initially thought of using the
internal pixbuf as a mask, but I don't know where GtkImage will actually draw
the pixbuf to, so that's not really a usable workaround).

Is what I want to do even possible? I'm not sure if transparency information
actually survive drawing operations (i.e., whether drawing operations just blend
source and destination and eventually create a fully opaque result or whether
transparency is passed-through).



Mihai


// valac --pkg gtk+-3.0 mwe-draw.vala

class App {
    public static int main (string[] argv) {
        // Create a new application
        var app = new Gtk.Application ("com.example.GtkApplication",
                                       GLib.ApplicationFlags.FLAGS_NONE);

        app.activate.connect (() => {
            // Create a new window.
            var window = new Gtk.ApplicationWindow (app);
            var window_style_ctx = window.get_style_context ();
            var bg_style = new Gtk.CssProvider ();
            bg_style.load_from_data ("* {background-color: #0F0;
                                      }", -1);
            window_style_ctx.add_provider (bg_style,
                Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);

            var drawing_area = new Gtk.DrawingArea ();
            drawing_area.draw.connect ((c) => {
                var color = Gdk.RGBA ();
                color.parse ("rgba (255, 255, 255, 1.0)");
                debug (color.to_string ());

                c.save ();
                c.set_source_rgba (0.0, 0.0, 0.0, 0.0);
                c.fill ();
                c.paint ();
                c.restore ();

                c.save ();
                c.set_source_rgba (color.red, color.green, color.blue,
                                   color.alpha);
                c.rectangle (20, 40, 100, 100);
                c.stroke_preserve ();
                c.fill ();
                c.restore ();

                c.set_source_rgb (1.0, 1.0, 1.0);
                c.set_operator (Cairo.Operator.DIFFERENCE);
                c.paint ();

                return false;
            });
            drawing_area.set_size_request (400, 300);
            drawing_area.show ();
            window.add (drawing_area);

            window.present ();
        });

        return app.run (argv);
    }
}

["OpenPGP_signature.asc" (application/pgp-signature)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic