GNOME Bugzilla – Bug 340066
Get rid of pango_layout_context_changed()
Last modified: 2012-12-06 23:06:40 UTC
As Owen suggested, this can be done by keeping a serial number in the context...
Created attachment 64505 [details] [review] Patch Patch to implement pango_context_changed and pango_context_get_serial. The former is available to backends only. PangoLayout uses pango_context_get_serial to update itself. pangocairo uses pango_context_changed to notify the context of changes to data it attaches to PangoContext. Owen, can you review please.
Needs to update docs for pango_layout_context_changed too.
*** Bug 328189 has been marked as a duplicate of this bug. ***
While patching Bug 342529, I came across the case that the fontmap may change resolution without contexts noticing, and I thought that can be implemented using a serial too. The get_serial for context then fetches get_serial for fontmap and adds to its own serial... While adding the serial APIs, we can add one to PangoLayout itself too. That may come handy in upper layers to see if redraws are needed, etc. Owen, what do you think?
Created attachment 66891 [details] [review] Final patch Going to commit something like this soon. Matthias, can you do a quick review, do you see any flaws, etc with the approach?
The patch needs to do the same thing it's doing for Xft for FT2 backend too...
Also, should add serial api to the layout itself, such that apps can check it and detect changes.
Created attachment 230757 [details] [review] Track changes in FontMaps using a serial This adds the pango_font_map_get_serial method that lets you see if a fontmap has changes since the last check. It adds implementations to all current fontmaps.
Created attachment 230758 [details] [review] Track changes in PangoContext via a serial Whenever a PangoContext or its fontmap changes we bump the contexts serial, you can get it via pango_context_get_serial() to see find out if the context changed since the last time and you need to relayout. You can also force the context to be "changed" by calling pango_context_changed().
Created attachment 230759 [details] [review] Track changes in layout and dependencies via serials We track changes in the PangoContext and automatically call pango_layout_context_changed() when needed, plus we track changes in the layout and let apps know via pango_layout_get_serial when the layout changed and needs to be redrawn.
Created attachment 230760 [details] [review] GtkLabel: Rely on the new pango support for context change tracking Now that Pango tracks changes to the context automatically there is no need to do it manually in e.g. style-updated or direction-changed, in fact the only case we have to care about is when we re-create the PangoContext due to a screen change, so we only have to clear the layouts in GtkLabel in screen-changed. This means we're not clearing all the layouts whenever the state changes, which happens to every widget when the window is unfocused, which helps performance a lot.
I updated the patch to the latest tree, fixes a few bugs and split it up. I also added a test patch for GtkLabel to rely on the pango patch to verify that it worked (in fact, this caught a bug in pango_layout_get_extents_internal() which didn't check the serial before relying on the extents cache). This is a lot more imporant now that we get a lot of state changes (every widget changes to/from backdrop state when the window is focused/unfocused) which is currently causing all labels to constantly drop their PangoLayouts.
Thanks Alex! Quick review: - I suggest making serial unsigned int, with initial number greater than zero. I expect this to do overflow in real world cases. So possibly make the increment code also skip zero? +/** + * pango_context_changed: + * @context: a #PangoContext + * + * Creates a new #PangoContext initialized to default value. Fix doc. void pango_layout_context_changed (PangoLayout *layout) { + g_return_if_fail (PANGO_IS_LAYOUT (layout)); + + layout_changed (layout); pango_layout_clear_lines (layout); So, essentially you want to remove the call to clear_lines() in every place you call layout_changed(). layout_changed then can clear_lines (and nothing else really, except for bumping serial). Please push after addressing these minor issues.
pushed and released in 1.32.4.