Open therahedwig opened 2 years ago
This seems related: https://github.com/harfbuzz/harfbuzz/issues/355
Is there a programmatic way to learn which scripts are horizontal? Or do we just need to enummerate scripts that are vertical and treat the rest as horizontal?
I just wanted to note that I did find UTR50, so I know what needs to happen here is that there's a header with a database generated, much like harfbuzz and unibreak do for their unicode functions.
As you already outlined, this will require rotating the glyphs, but we can’t extend raqm_glyph_t
without breaking API. Also setting rotation matrix on individual glyphs is wasteful. We probably need a way to return some kind of ”runs” to the client and attach the necessary extra information to the run.
I looked a year ago at using raqm for text in GIMP. Two of the main concerns i had were (1) indications it would be a regression from Pango for us for vertical text support, and (2) that we would need to push boundaries in the graphic design area. For this issue (mixed direction text), we may have someone this Summer to look at it if that would help. Are there any more notes around the status of vertical text support in libraqm? Thanks! (this comment is only slightly on-topic, i know, feel free to contact me directly if you prefer)
Raqm was originally designed with much simpler applications in mind (mostly command line tools that were already using FreeType to do basic static text layout, with no font management, line breaking, editing, etc.) It still does not have line breaking support, and the font fallback and hit testing hooks are rudimentary.
Thank you @khaledhosny - i’m exploring alternatives, because going further as we (GIMP) are would involve fighting and/or forking pango, which is crazy. But if we start with an external library it'll need to be one where the maintainers are interested in moving to more advanced/design-centric stuffs, including yes line-breaking :) (but not editing directly, but yet, hit testing). And much better CJK support than we have today, which is why i chose this particular issue (horizontal test in vertical). An attractive thing about raqm for us is that it’s small, so easier to extend than something large that doesn’t do what we need! But i don’t want to do a hostile fork of course, so if this isn't a direction that's of interest we should drop it.
@liamquin you may find this article interesting.
This consists of two separate things.
upright
, another sectionmixed
, and anothersideways
in the same paragraph.The second horizontal in vertical is
text-combine-upright
.hwid
,twid
,qwid
, font-stretch, and of course, a final FT_matrix to be applied to all characters. Should we be proper and try all combinations to see what's shortest, or try in-sequence?cursor_pos
to ensure the next advance is located correctly, as illustrated:(Text taken from the css-writing-modes-3 spec, yellow is advances, blue is suggested cursor_pos value)
Suggested API:
raqm_text_orientation_t
{RAQM_ORIENTATION_UPRIGHT
,RAQM_ORIENTATION_MIXED
,RAQM_ORIENTATION_SIDEWAYS
}bool raqm_set_text_orientation(raqm_t *rq, raqm_text_orientation_t orientation, size_t start, size_t length)
bool raqm_combine_upright_run(raqm_t *rq, size_t start, size_t length)
raqm_glyph_t
: FT_Matrixtransform
and intx_cursor_pos
, inty_cursor_pos
, the latter which get applied to the text-pos before positioning the glyph and adding the advance.For implementation, text_info will need to keep a per-character direction and orientation, which then gets used to split up runs during itemization. After shaping, a rotation matrix is configured from the orientation and paragraph direction. A scaling matrix is configured from how big a combine-upright run is, to ensure everything is fit into a single EM. Cursor pos is calculated to ensure there's continuity between the runs.
Do we need to rotate/scale offset and advance as well? I am thinking advance should be rotated, but offset shouldn't, so you take the glyph, apply the offset, apply the matrix, then apply the advance?