GNOME Bugzilla – Bug 636697
GtkTextTag needs RGBA versions of properties
Last modified: 2011-05-06 21:08:35 UTC
GtkTextTag has background-gdk, foreground-gdk, and paragraph-background-gdk properties. I guess that it should have *-rgba versions too, as has been done for other classes.
On IRC, Benjamin Otte mentioned that this can't be done until Pango has had some modification to support GdkRGBA somehow.
<murrayc> What's blocking the use of GdkRGBA in GtkTextView? Just manpower? <Company> murrayc: the fact that pango can't cope with it <Company> it shouldn't even have the GdkColor versions <Company> because if i set 0.5 alpha red what GdkColor do we return? :/
Ok I looked deeply into this and at first I came to the same conclusions basically that Company did. By looking at the code.... - GtkTextLayout uses pango to render text. - GtkTextLayout uses PangoAttributes to set the foreground/background colors for cairo drawing. - Pango does not understand an alpha channel So, looking at things that way, it's a fail unless we build in an alpha channel to pango text attributes apis. However... looking even more deeply into the code I found 2 interesting bits of information regarding how the pango cairo rendering works. a.) Judging by the code of pango_renderer_draw_line(), pango only draws/fills a background rectangle if a background text color attribute is set. b.) In pangocairo-render.c, it's quite clear that if no foreground color attributes are set, the layout will be drawn in whatever color has been previously set by cairo_set_source_rgb()... or likewise cairo_set_source_rgba() This is all theoretical at the moment, I would have to try things out but my theory is that rendering GtkTextView using GdkRGBA to specify foreground and background separately is very possible in the following way: a.) Never set color attributes on the underlying PangoLayout b.) If a background rgba is set for a given GtkTextTag, render the background using: pango_layout_get_pixel_extents(); cairo_rectangle (); cairo_set_source_rgba (); cairo_fill(); c.) When a foreground rgba is set for a given GtkTextTag, we then call cairo_set_source_rgba (); before rendering the layout. With GtkTextView, a bunch of lower level pango semantics are used, like pango_cairo_show_glyph_string()... so pango_glyph_string_extents() would have to be used instead of pango_layout_get_pixel_extents() etc, it wont be exactly easy but I think it is indeed doable.
This would probably work, apart from being a bitch to implement and making the code more confusing and harder to maintain than it already is. I'd rather see someone implement PangoAttributeForeground/BackgroundPattern in pango and use that.
Actually, looking even deeper... it seems that GtkTextView under the hood uses a custom derived PangoRenderer to render the text. There is already some support for rendering rgba text in the foreground (this rgba is currently pulled from the style information), it seems not such a far cry to add support for pulling the rgba colors from the tags and applying rgba background colors too.
Created branch rgba-texttags. In this branch, GtkTextTag gets rgba properties and GtkTextView renders text translucently. Current problems and TODO: - error-underline-color GdkColor property is not applied, it should be converted to an rgba value and used. - Should probably create a new rgba style property for the error underline color. - paragraph-background still needs untangling, I added rgba properties but they are currently still unused. - regression: When text wraps... for some reason the background color is dropped for the remainder of the GtkTextIter's rendering, needs investigation.
TODO items have been covered now. The branch is clean, currently I set the "Since" gtk-doc comments to say "Since 3.2". Some shots of the translucent textview rendering can be viewed here: http://blogs.gnome.org/tvb/2011/02/14/translucent-textviews/ Or by firing up the testtextview text code.
Is this ready for consideration for merging to master for GTK+ 3.2?
I've taken a look at the branch today. Some notes: - values = g_new0 (GtkTextAttributes, 1); + values = g_slice_new0 (GtkTextAttributes); [...] + if (dest->tabs) + pango_tab_array_free (dest->tabs); Looks unrelated and should be in a separate commit + GdkRGBA *rgba[2]; + /*< private >*/ - guint padding[4]; + guint padding[2]; That is only abi compat if your pointers are integer-sized... g_param_spec_boxed ("background-rgba", + P_("Background rgba"), + P_("Background rgba as a (possibly unallocated) GdkRGBA"), 'possibly unallocated' doesn't make any sense for GdkRGBA...
We should also deprecate the GdkColor tag properties in favour of the GdkRGBA properties.
I think deprecating GdkColor is a separate step. If it should be done in the branch, all GdkColor using code should be deprecated, not just this code. Because so far, no code using GdkColor is deprecated.
Sure, doing it separately is fine
Merged, after fixing the issues I've pointed out. No deprecations yet.