Skip to content

Horizontal in vertical. #168

@therahedwig

Description

@therahedwig

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions