GNOME Bugzilla – Bug 435706
Custom layout shape
Last modified: 2018-05-22 12:27:56 UTC
So I want to implement this feature to allow custom non-rectangular layout shapes. Think: http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-flowtext.png or even: http://photos1.blogger.com/photoInclude/blogger/1073/1331/1600/text_inside_polygon5.png I say 'even' because the second link is more invovled, having lines that have more than one segment. Lets call them multi-segment lines, and act as if every segment was a regular line. They cause hard problems with mixed-direction text. In rtl, first the right segment should be filled.. But I think we can manage that since we have the line direction information. So we'll introduce new api, something like: void pango_layout_set_shape_callback (PangoLayout *layout, PangoSomeCallback callback, gpointer data); The callback will receive the previous multi-segment line, current multi-segment line number, and current line ascent+descent, and returns: - The positions for the new multi-segment line. That is, a list of segments, each having an X position and width. - Y position and Y anchor (top, bottom, baseline). - Whether it should be called back again for this line if the line height changes. The layout algorithm will start with logical ascent+descent of the first cluster of text for this line, and calls the callback, getting a list of segments for this multi-segment line. It will start filling them based on the line direction. It will go on and fill them just as if they were regular lines. At any point if putting a new cluster into the line changes line height, it will call into the callback to get new line placement. Thinking about it again, it will get very clumsy very fast. Ok, lets try again. Forget about multi-segment lines. Repeat everything with single lines, but the callback will also get a line direction setting. So it can choose which segment to return next. Does this make more sense? It's still hard to get it right in the callback for more than two segments, but I don't really care about that case.
Enhancement that is.
Someone did this years ago with pango. Nathan H(?) Hunt or Hurst. Don't know if any of his work is still available.
http://mail.gnome.org/archives/gnome-devel-list/2000-May/msg00433.html
Thanks. I failed to find that previously. Also: http://hawthorn.csse.monash.edu.au/~njh/phd/text-widget.html
Ok, checked Nathan's code. It's more stuff that can be ported to use the API I propose. And his API proposal from seven years ago pretty much matches mine sans the bidi issues... How innovative I am.../sigh
Another example, a rather cool one: http://vipul.net/perl/sources/scripts/rsa-dolphin Someone suggested in comments on my blog to be able to fill the current path of a cairo context with text. That needs other than the API proposed here a callback that does the geometry for an arbitrary polygon. It's not easy, but should be possible. Now just if we had access to cairo's internal functionalities...
(In reply to comment #5) > Ok, checked Nathan's code. It's more stuff that can be ported to use the API I > propose. And his API proposal from seven years ago pretty much matches mine > sans the bidi issues... How innovative I am.../sigh > You just proved once again, that software patents make no sense and serve no purpose - expect for making laywers rich. ;-)
Just to add the views of cworth regarding this when we spoke at guadec. It seemed apparent to him that the easiest way to get this working would be to render the surface off to an A1 texture at a resolution which was relative to the size of the line height, then you can simply inspect the edge pixels. The only problem with this is that you could only use a single line height for all of the text within the shape. With some creative use of greatest common divider there is room to maneuver however not much as if you have text sizes 11 and 12 within the shape, the GCD is 1, therefore you're still inspecting every single edge pixel along the way, and would be required to produce a much more detailed set of calculations as the horizontal offset would have to be calculated based on the line start of the previous line, and the line start of this line and finding which one would cause overlap of the edge.
We create multi-page reports, and the first posted picture (http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-flowtext.png) perfectly matches our needs. Multi-segment lines would only create confusion and would spoil the API. It is difficult not only to write them, but also to read them. If still needed, they should be treated as independent lines. Doing layout by SHAPE CALLBACKS would make it almost impossible for us to use it, because we do not have a predefined space to be filled with a text. We build the layout dynamically: when we find out that the space is not enough, we allocate a new page, and there the available space can be different than on the previous page. Also, we may have more than one text flow to be continued. Generally, it would make sense to separate the LAYOUT COMPOSER ENGINE and the LAYOUT, because logically they are different objects (in any case, the glyph positions are rebuilt when something changes). I would ask the layout composer engine to compose a text into a given rectangle. The COMPOSER would tell me how many bytes it has processed, would modify the space rectangle, and would create a LAYOUT object with lines. Then I would allocate the next bit of space and call the COMPOSER to layout the next part, or (if the space cannot be allocated) to ellipsize the last composed LAYOUT object. The LAYOUT object would be painted independently of the COMPOSER. This scheme would allow easy incremental text composition, partial composition updates, and (combined with the baseline/top/bottom alignment) user markup implementation.
-- 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/75.