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

[css-fonts] Vertical text doesn't play nicely with font-style and font-stretch #4044

Open
litherum opened this issue Jun 19, 2019 · 14 comments
Assignees
Labels
css-fonts-4 Current Work css-fonts-5 i18n-clreq Chinese language enablement i18n-jlreq Japanese language enablement i18n-mlreq Mongolian language enablement i18n-tracker Group bringing to attention of Internationalization, or tracked by i18n but not needing response. Needs Design / Proposal

Comments

@litherum
Copy link
Contributor

litherum commented Jun 19, 2019

Consider a font that supports both Japanese and Latin, and wants to work well in both vertical writing mode and horizontal writing mode. It's totally reasonable for such a font to want to react to font-style and font-stretch.

Naively, such a font would react to font-stretch by making all its characters horizontally wider, and would react to font-style by making the tops of the characters skew to the right.

However, in vertical writing mode, this isn't right. In vertical writing mode, some characters are upright (i.e. Japanese characters) while some characters are rotated (i.e. Latin characters). Therefore, the naive solution would lead to bad behavior.

Here's a video of this bad behavior of font-stretch, courtesy of Nat McCully at Adobe:
varfontbad.m4v.zip

Instead, the desired result of font-stretch is where the upright characters grow vertically and the rotated characters grow horizontally (image also courtesy of Nat McCully at Adobe):

Screen Shot 2019-06-19 at 3 38 57 PM

It's unclear whether the font can do this automatically.

  • The vert feature might not be hooked up to text-orientation: mixed and text-orientation: upright in every browser
  • Even if it was hooked up, it might be difficult for an author to make sure the interaction between vert and variation axes is correct.
  • We shouldn't require every font to encode UAX50 inside itself
    • Not all browsers/apps adhere to UAX50 so that wouldn't even be correct if it were a requirement

This was discussed at the most recent OpenType F2F, and there was interest in the font using two distinct low-level physical controls for vertical stretching and horizontal stretching, and the browser/app determining which of those types of stretching to use. (Sort of like how browsers are supposed to apply the vert feature just for some of the characters in the vertical line.)

Doing this at the CSS level is tricky because font-stretch and font-style are font selection properties. Changing their meaning causes side effects, like new different fonts get downloaded.

This issue probably requires coordination between OpenType and CSS to come up with a story for how this is supposed to work and what font creators can do to make their font work properly.

This discussion should include both font-stretch and font-style. The solutions for these two properties may end up being different.

This problem has existed since before variable fonts, but is particularly visible now as companies are more active in making CJK variable fonts that react to wdth and slnt.

@litherum
Copy link
Contributor Author

@kojiishi @jfkthame

@SergeyMalkin
Copy link

This was discussed at the most recent OpenType F2F, and there was interest in the font using two distinct low-level physical controls for vertical stretching and horizontal stretching, and the browser/app determining which of those types of stretching to use.

Important thing to remember is that value of font-stretch property affects font matching. Right now 'wdth' axis is used for this purpose. But if choice of axis will depend on orientation of particular character, then font matching can't be done before character orientation analysis is complete.

@macnmm
Copy link

macnmm commented Jun 19, 2019

This was discussed at the most recent OpenType F2F, and there was interest in the font using two distinct low-level physical controls for vertical stretching and horizontal stretching, and the browser/app determining which of those types of stretching to use.

Important thing to remember is that value of font-stretch property affects font matching. Right now 'wdth' axis is used for this purpose. But if choice of axis will depend on orientation of particular character, then font matching can't be done before character orientation analysis is complete.

Note that for Roman fonts, using the 'wdth' axis all the time should be ok -- it is only when characters are upright that the 'vwid' axis would give a better result, when matching other squashed in that dimension, for example, fonts. I am of course speaking out of turn with little knowledge of CJK font matching using that axis...

@jfkthame
Copy link
Contributor

Note that for Roman fonts, using the 'wdth' axis all the time should be ok

Not if text-orientation: upright is used, I guess.

@kojiishi
Copy link
Contributor

Thank you for raising this, @litherum. I feel great for our efforts to try to solve this problem, and I agree that we should solve both stretch and style.

Fonts using two distinct low-level physical controls look reasonable to me. Blink layout engine runs in logical, but converts all logical information to physical before calling the shaping engine, and convert the shaping results back to logical. Adding a few more conversions looks reasonable to me.

For the font matching, my preference is to keep it simple; i.e., match using horizontal control only. If vertical control is missing, we can fallback to synthesized result. If vertical is available but horizontal is missing, it's considered as missing for the font matching purpose.

Technically speaking, Blink can probably implement orientation-dependent matching if desired, because we compute glyph orientation before matching fonts. But I think the additional code has little-to-no benefits. Using horizontal control only for matching will give authors more predictable results.

@r12a r12a added i18n-clreq Chinese language enablement i18n-jlreq Japanese language enablement i18n-mlreq Mongolian language enablement i18n-tracker Group bringing to attention of Internationalization, or tracked by i18n but not needing response. labels Jun 20, 2019
@litherum
Copy link
Contributor Author

litherum commented Sep 6, 2019

Masataka Hattori (from Adobe) just gave a presentation at ATypI where he describes struggling with the problem described in this issue.

@litherum
Copy link
Contributor Author

litherum commented Sep 17, 2019

Here's a proposal: Make a layer of indirection between font facilities and CSS facilities.

As described above, the OpenType group feels that having two variation axes, one for width, and another for "vertical width", where the browser applies the relevant one, is a good fit. This has to work even for non-variable fonts, so fonts should probably be able to be annotated as "this font has a vertical width of 115%" in the same way a font can be annotated (today; this is existing behavior) as "this font has a horizontal width of 115%." I can work with OpenType to see if it's possible to provide these annotations for non-variable fonts.

The @font-face descriptors for font-stretch and font-style can be extended to take vertical arguments. The new grammar for the font-stretch descriptor would change from something like

font-stretch: 110% 120% (for a variable font)

to

font-stretch: vertical 110% 120%. Alternatively, a font that supports both horizontal stretching and vertical stretching could say font-stretch: 80% 90% vertical 110% 120%.

The same approach would apply to font-style, too.

This way, a font can declare that it is horizontally stretched or vertically stretched. It supports ranges for variable fonts, too.

Also, the font-style and font-stretch properties are not modified. The browser already performs a layout before it knows which fonts to download (for unicode-range), so the browser can consider writing-mode, text-combine, etc. when determining which font to download. When content is written vertically, the browser will search for a font that has vertical width. When content is written horizontally, the browser will search for a font that has horizontal width. The same would happen for font-style.

Also, all common browsers support font-style synthesis. This would continue to work; we're allowed to synthesize horizontal oblique or vertical oblique, depending on use.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-fonts] Vertical text doesn't play nicely with font-style and font-stretch, and agreed to the following:

  • RESOLVED: Adopt the proposal for font-stretch
The full IRC log of that discussion <emilio> Topic: [css-fonts] Vertical text doesn't play nicely with font-style and font-stretch
<emilio> Github:https://github.com//issues/4044
<emilio> ??: CJK text differs from latin because of the multiple orientations
<emilio> .. because of that multiple features related to the line width become quite complex
<emilio> ... [explains example in the issue]
<emilio> ... depending on the glyph orientation glyphs get stretched in different directions
<emilio> ... as a user is backwards, as an implementor you need to poke at the internal characters
<emilio> ... while the feature is about stretching the whole line
<emilio> myles: this was discussed in OpenType and there was some discussion
<emilio> ... the font can't know how to do it right and there's an opentype feature that only gets applied to upright characters
<emilio> ... but it's pretty hard to set up
<emilio> ... so opentype would introduce a new axis
<emilio> ... vertical and horizontal width
<emilio> ... and the application would set the relevant vertical / horizontal axis depending on whether the glyph is upright or not
<emilio> ... no resolutions anywhere yet but need to move it together
<emilio> ... so we need font-face descriptor to say that it supports stretching in the vertical axis or not
<emilio> ... so plan is to extend font-stretch to specify using a `vertical` direction that it's stretched in the vertical axis
<nmccully> s/??/nmccully
<emilio> ... the font-stretch property wouldn't change syntax, but it'd change behavior
<emilio> ... rotating the font in the appropriate direction
<emilio> ... which means that writing-mode and text-combine and such would also be inputs to the font selection algorithm
<emilio> ... because if it's vertical it'd need to download the font that can expand in the vertical axes
<emilio> ... thoughts?
<emilio> fantasai: sgtm
<emilio> leaverou: would the property change?
<emilio> myles: the property has no grammar change but has behavior change
<emilio> nmccully: you may need it for TCY
<emilio> myles: the system I'm describing would either select an horizontal or vertical font, but it's important that fonts can support both so you don't require different files for fonts that support both japanese and latin scripts
<emilio> ... everything I've said also applies to font-style (for the italic angle)
<emilio> koji: what's the syntax proposal?
<emilio> myles: [explains proposal in the issue]
<emilio> myles: The OpenType piece is that we need to standardize a new axis for vertical width and for non-vertical font you also need a vertical width
<emilio> nmccully: Adobe has formed an opinion already and has a prototype
<heycam> q+
<emilio> koji: should it be physical or logical?
<emilio> fantasai: for font needs to be physical
<Rossen_> ack jcraig
<Rossen_> ack ?
<emilio> ... when you're typesetting vertical text you mix both upright and rotated characters, for the glyph's perspective depends on the uprightness
<emilio> ... upright chars get "longer" in the vertical axes, the other keeps the same height but
<emilio> ... so for the font descriptor it needs to be physical and the property is logical and only applies in the inline direction
<emilio> koji: so you're saying physical to line orientation not to glyph orientation
<emilio> fantasai: font-stretch is line-relative and the font-stretch capability in the font file is physical relative to the glyph orientation
<fantasai> koji: agree
<emilio> myles: [explains that in a different way]
<emilio> koji: agree
<emilio> ack heycam
<emilio> heycam: I think proposal makes sense, I'd like to understand how authors can achieve this without this feature and how difficult that is compared to the font
<emilio> nmccully: the browser would have to know how each browser treats the font (regarding upright-ness)
<emilio> ... then go browser by browser and change fonts per rune
<emilio> heycam: so part of the issue is that browsers disagree on that, right? (fantasai mentioned punctuation before)
<emilio> fantasai: yeah, even by that is a per-codepoint thing
<emilio> fantasai: the initial values of text-orientation mix orientation by default, the author would have to do the automated determination of rotated vs. not for the particular font
<emilio> ... way too much work to request on an author
<emilio> nmccully: it's mixing two things, whether something is sideways is not the author decision
<emilio> ... it's automated based in unicode-range
<emilio> heycam: Oh I assumed that authors would have expectations and browsers would be consistent
<emilio> fantasai: I think this is the right design, I think it works great for font-stretch
<emilio> ... for oblique and such it may not
<emilio> myles: there's another piece. Today if you say font-style: italic on vertical text you'll get weird stuff
<emilio> ... this proposal will fix that
<emilio> fantasai: don't we have a resolution on that?
<emilio> florian: I think hiroshi wanted to reopen that
<emilio> ... but didn't because nobody seemed to run into a spec
<emilio> Rossen_: would this change this resolution?
<emilio> florian: only if we apply it to font-style
<emilio> fantasai: I think we may have a font-stretch-vertical descriptor rather than stashing it on font-stretch
<emilio> ... but that's more bikeshedding and I generally agree with the proposal
<emilio> Rossen_: objections to adopt this?
<emilio> RESOLVED: Adopt the proposal for font-stretch

@svgeesus
Copy link
Contributor

So we have an (old) resolution to put the proposal into the spec. Are we waiting for a signal from OpenType to allow this to work, or can we just go ahead?

(Context - issue cleanup for an updated working draft)

@jfkthame
Copy link
Contributor

I haven't seen any sign of a "vertical-width" axis in the OpenType spec, so this seems more aspirational than concretely implementable at this point. Maybe we should put it in a spec in the hope that OpenType will catch up? Or maybe that's premature and not really useful until the font support exists.

@acli
Copy link

acli commented Jun 18, 2021

Vertical text will never play nice with font-style, because East Asian glyphs and Western glyphs have different axes of slant. If you look carefully, you’ll notice that typographically italic (by which I mean flowing styles that aren’t calligraphic – i.e. the Kai styles) East Asian glyphs slant upwards (anchored to the baseline on the left), while Western italic glyphs slant to the right. East Asian glyphs slant upwards because they were originally designed for vertical writing, but you’ll not likely find many Western fonts that will slant upwards when rotated 90° clockwise

@svgeesus
Copy link
Contributor

@litherum are we still adding this proposal?

@litherum
Copy link
Contributor Author

I think we should ask Nat McCully and Masataka Hattori if the problem is still worth solving. (My intuition is that it is.)

@macnmm
Copy link

macnmm commented Sep 19, 2023

I think we should ask Nat McCully and Masataka Hattori if the problem is still worth solving. (My intuition is that it is.)

Yes, it definitely is worth solving so each app didn't have to do its own solution, perhaps also relying on certain fonts' implementations (or influencing them with a particular hack behavior).

I suspect something lacking in the font data, as well, unless we agree on a foolproof method of determining uprightness in vertical that is cheap, and then further agree on conventions for when things switch axes. My assumption is always that the lowest level expects Latin horizontal behaviors, and requires a no-op (i.e. no difference in code) when rendering Latin text in any direction. Thus all the special-casing happens with Japanese in vertical, with rotation upright and x- and y-axis-reversal, change of slant (see above -- actually the slant is not just a shear from the Roman baseline but rather a shear, scale, and rotate all about the glyph center), uneven scaling, other distortions, etc. All this could be codified in the font data better, and make other improvements for vertical text that acknowledge the mix of orientation when mixing scripts (even in the same font).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-fonts-4 Current Work css-fonts-5 i18n-clreq Chinese language enablement i18n-jlreq Japanese language enablement i18n-mlreq Mongolian language enablement i18n-tracker Group bringing to attention of Internationalization, or tracked by i18n but not needing response. Needs Design / Proposal
Projects
None yet
Development

No branches or pull requests

10 participants