Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Horizontal in vertical. #168

Open
therahedwig opened this issue Apr 15, 2022 · 8 comments
Open

Horizontal in vertical. #168

therahedwig opened this issue Apr 15, 2022 · 8 comments

Comments

@therahedwig
Copy link
Contributor

therahedwig commented Apr 15, 2022

This consists of two separate things.

  • The most important one is the ability to have glyphs from horizontal scripts to be laid out as horizontal instead of vertical.
  • This only applies to vertical.
  • This is not paragraph level, so a section can be upright, another section mixed, and another sideways in the same paragraph.
  • 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?
  • According to the spec, the alignment needs to be 'central' baseline for both horizontal and vertical. (This conflicts with baseline alignment, as noted in the baseline issue, should we just disable custom baseline for horizontal-in-vertical situations?)
  • Glyphs need to be rotated, so maybe return an FT_matrix?
  • Glyphs that have been rotated should take care to turn the correct direction, for cursor drawing needs.

The second horizontal in vertical is text-combine-upright.

  • This also only applies to vertical text.
  • All characters in a given section get squeezed into a single-EM's width.
  • squeezing can use 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?
  • Text-transform:full-width-kana needs to be undone before squeezing, but should that be done inside raqm, or client-side?
  • This definitely needs a special cursor_pos to ensure the next advance is located correctly, as illustrated:

image
(Text taken from the css-writing-modes-3 spec, yellow is advances, blue is suggested cursor_pos value)

Suggested API:

  • Add an enum 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)
  • Add to raqm_glyph_t: FT_Matrix transform and int x_cursor_pos, int y_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?

@therahedwig
Copy link
Contributor Author

This seems related: harfbuzz/harfbuzz#355

@therahedwig
Copy link
Contributor Author

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.

@khaledhosny
Copy link
Collaborator

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.

@liamquin
Copy link

liamquin commented Apr 6, 2024

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)

@khaledhosny
Copy link
Collaborator

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.

@liamquin
Copy link

liamquin commented Apr 7, 2024

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.

@Fahad-Alsaidi
Copy link
Contributor

@liamquin you may find this article interesting.

@liamquin
Copy link

liamquin commented Apr 7, 2024

@liamquin you may find this article interesting.

Thank you, yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants