chearon / dropflow

A CSS layout engine
https://chearon.github.io/dropflow/
MIT License
1.26k stars 27 forks source link

Support for letter-spacing #10

Open maxhoffmann opened 7 months ago

maxhoffmann commented 7 months ago

Thank you for creating dropflow! It looks really cool. 🙂

I was wondering if you are also planning to add letter-spacing at some point? It’s the one essential typographic feature I’m currently missing.

chearon commented 7 months ago

Thank you! I'd love to add letter-spacing support. I think it's simple: walk the glyph array and increase advances at the end of each unicode grapheme:

This property specifies additional spacing (commonly called tracking) between adjacent typographic character units. Letter-spacing is applied after bidi reordering and is in addition to kerning and word-spacing. [CSS-WRITING-MODES-4] [CSS-FONTS-3] Depending on the justification rules in effect, user agents may further increase or decrease the space between typographic character units in order to justify text.

For the purpose of letter-spacing, each consecutive run of atomic inlines (such as images and inline blocks) is treated as a single typographic character unit.

Letter-spacing must not be applied at the beginning of a line. Whether letter-spacing is applied at the end of a line is undefined in this level.

— CSS Text §7.2

chearon commented 7 months ago

I did more reading and thinking on this. It's harder than I thought because the spacing has to be applied after bidi reordering. But letter-spacing also needs to be followed when measuring text for fit. If bidi text splits an inline, the common ancestor's letter-spacing is used. It sounds like I'm supposed to do a simple test of "will this split an inline", rather than trying to calculate the "hypothetical" bidi order.

Currently, none of the major browsers do this correctly: test.

LineWidthTracker, ShapedItem.measure, and createLineboxes all need to be updated to have letter spacing state. Those use logical order, but the total number of spaces will be the same as the after-bidi letter spacing. Also ShapedShim will need to gain an advance property since inline-blocks and <img> in the future also get spaces after them through letter-spacing.