GNOME Bugzilla – Bug 153549
Match layout between devices
Last modified: 2018-05-22 12:06:25 UTC
When creating a printing layout to match a screen layout I find myself writing code like... pango_layout_set_text (layout, pango_layout_get_text (olayout), -1); pango_layout_set_alignment (layout, pango_layout_get_alignment (olayout)); pango_layout_set_attributes (layout, pango_layout_get_attributes (olayout)); pango_layout_set_single_paragraph_mode (layout, pango_layout_get_single_paragraph_mode (olayout)); pango_layout_set_justify (layout, pango_layout_get_justify (olayout)); pango_layout_set_width (layout, pango_layout_get_width (olayout)); pango_layout_set_spacing (layout, pango_layout_get_spacing (olayout)); pango_layout_set_wrap (layout, pango_layout_get_wrap (olayout)); pango_layout_set_indent (layout, pango_layout_get_indent (olayout)); pango_layout_set_auto_dir (layout, pango_layout_get_auto_dir (olayout)); pango_layout_set_ellipsize (layout, pango_layout_get_ellipsize (olayout)); // pango_layout_set_font_description??? (That misses tabs.) Boring, eh? I cannot use pango_layout_copy because it will use the wrong context and I cannot override that. I would like the guts of pango_layout_copy factored out into pango_layout_assign doing basically the above.
Actually, the problem is bigger for multi-line layouts. the ideal (from a least-surprise point of view) would be to preserve the line breaking. I can fake that in the common one-line case by using pango_layout_set_wrap (layout, pango_layout_get_wrap (olayout) && pango_layout_get_line_count (olayout) > 1); but I don't think I have the means for doing the general case.
If you want the same line layout, then you need to be using the exactly the same metrics between the screen and printer. With cairo, you'll be able to do something like: pango_cairo_fontmap_set_device_independent_metrics (fontmap, TRUE); And a PangoContext object can (if you want) be moved between different Cairo contexts. Actually, it would be really trivial to add pango_layout_set_context(), though I haven't wanted to add that publically yet, because I'm not entirely sure there will never be a need for device-dependent information on a layout. I'm a little suprised by your need for pango_layout_assign() at all.. my expectation is that most apps will have a "create layout from app specific data structures"; that can just be called again for the printer.
We could (and did) recreate the layout from scratch, but it is not desireable: 1. The number of digits shown for "General" format: we don't want to show a different number of digits when printing. 2. A too-wide number is shown as "######". We don't want that to trigger for printing when it didn't on screen. 3. Some layouts have their widths frozen to be just right (by just the common spreadsheet command to resize a column to its desired width). We do not want to have such layouts broken or wrapped on printing. Now if the metrics do not agree 100% (and they don't) we will see things sticking ever so slightly out for printing. Since we get alignment right, it should be hard to see. I am guessing that no-one will notice. So, yes, we really would like a way to copy the line layout.
Note that a pango_layout_assign() would not copy the line layout, because the line layout of a PangoLayout is simply a cache, which is recomputed whenever PangoLayout thinks anything might have changed. Does it have any use at that point?
The functionality described (== typeset the text the same way for this new device) is still needed. Maybe it doesn't belong here. The case where the "cloned" layout is changed afterwards is of no interest. You might even be able to fake the effect by changing the string to have newlines exactly precisely where the old layout actually broke the lines and then set flags to respect newlines and not break otherwise.
The idea of doing line layout with device-independent metrics and letter layout with device-dependent metrics is discussed on http://people.redhat.com/otaylor/grid-fitting/. Quite a bit of work. The simple quick fix is something like I discussed above pango_cairo_fontmap_set_device_independent_metrics(), though that generally willl produce suboptimal screen results. I can't see copying layout between devices without adjustment .. while you talk about "stick out a little bit", if you have long strings of the same character, you can easily get 10% deviations.
Can we reach any resolutions here? I don't see much.
> Can we reach any resolutions here? I don't see much. Clearly no consensus. We (the Gnumeric team) still miss this. We need to print what we display, not a re-layed-out version thereof. In fact, any gui program that wants to print what it displays must have this problem. I am arguing that this problem must have a practical solution. I am willing to take Owen's word for the possibility of constructing particularly nasty cases where the deviation is non-trivial, but I believe the vast majority of cases will be very well behaved. Clearing target milestone -- I am not asking for the device-independent metrics solution.
Device-independent metrics is already there in pangocairo. Just use pango_cairo_context_set_font_options(), cairo_font_options_set_hint_metrics(), and CAIRO_HINT_METRICS_OFF. That results in poor display output though.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pango/issues/18.