Open fantasai opened 3 years ago
Relatedly, for the from-font
keyword, should we be picking from the first available font that is able to provide the desired metric?
Indeed, no adjustment when missing glyphs / metrics is probably the correct thing to do. "Best guess" fallback values are not particularly likely to be close to what the font actually looks like, and will as easily be too big or too small. Some of the time, the adjustment would end up being in the right direction, but it would be just as likely to do the opposite of what you want.
For ic
, 1em
is the correct size for the vast majority of CJK fonts, so it might still be tempting to synthesize the missing measurement to that value, but then again, if your font is missing a glyph for 水
, how likely is it that it actually is a CJK font?
For
ic
,1em
is the correct size for the vast majority of CJK fonts, so it might still be tempting to synthesize the missing measurement to that value, but then again, if your font is missing a glyph for水
, how likely is it that it actually is a CJK font?
If it's a CJK font that has been subsetted to optimize for specific content, it could well have lost its 水
.
For ic, 1em is the correct size for the vast majority of CJK fonts, so it might still be tempting to synthesize the missing measurement to that value, but then again, if your font is missing a glyph for 水, how likely is it that it actually is a CJK font? If it's a CJK font that has been subsetted to optimize for specific content, it could well have lost its 水.
An actual case found in the market is fonts that only support Kana. They do not contain the character "水" and they are typically full-width.
Another viable approach would entail establishing fallback values for each font metric by referencing the existing fallback values utilized by browser engines, as discussed in #8792. For instance, both Blink and Webkit rely on the sum of ascent and descent for the advance height of 水 when 水 or vertical glyph information is unavailable.
I am in favor of a behavior of "no adjustment"
when the metric is not available.
no adjustment when missing glyphs / metrics is probably the correct thing to do
I am in favor of a behavior of
"no adjustment"
when the metric is not available.
I agree, this seems like the correct approach to me.
It seems to me that ic-height
would be expected to parallel the behavior of the ic
unit in vertical writing mode, for which Values and Units defines a fallback of 1em
if the "real" metric cannot be determined.
In scaling or using a unit in calc()
expressions ic-height
needs to map to a number. But performing font-size-adjust
to a heuristic does not make sense to me, it results in somewhat random behavior. In this context we have an alternative of not performing any adjustment. If it desired to use font-size-adjust
to scale to any fixed values, separate unit types or percentage values can be used.
So, we currently have:
from-font
Computes to the<number>
corresponding to the specified metric of the first available font.
Proposed resolution (the "no adjustment" option):
from-font
If the specified metric exists, computes to the<number>
corresponding to the specified metric of the first available font. Otherwise, the same asnone
Thanks for the proposal, that sounds good to me for from-font
. In addition, since we have both [ from-font | [<number [0,∞]>]
isn't there a case for the [<number [0,∞]>]
case to fail as well if the metric is unavailable. I would suggest to either add text for unavaiable metric there as well (=none when not available), or to pull up the text for "if the metric doesn't exist" above both.
Edit: Meant to say unavailable, instead of available. Looks like you understood that right despite, @svgeesus despite the typo.
since we have both
[ from-font | [<number [0,∞]>]
isn't there a case for the[<number [0,∞]>]
case to fail as well if the metric is available.
Yes, indeed.
@fantasai I think the proposed text (with @drott ammendment) agrees with your OP description.
@frivoal I think it agrees with your position too.
@jfkthame thoughts?
@svgeesus What about this question from earlier, though?
Relatedly, for the from-font keyword, should we be picking from the first available font that is able to provide the desired metric?
Oh, I didn't respond to that part because the spec is already clear on that point:
from-font
Computes to the<number>
corresponding to the specified metric of the first available font.
The definition of the first available font refers to character coverage, but does not consider whether the font provides a value for any particular metric, so I don't think that really answers the question.
@jfkthame I had considered that case to evaluate to 'missing'. Do you suggest changing the definition of first available? That means that it becomes property-specific, would than not have knock-on effects on other places where the concept is used?
I thought that was exactly @fantasai's question, "should we be picking from the first available font that is able to provide the desired metric?"
ISTM there are actually two questions to consider here, and the answers might not necessarily be the same.
(1) When font-size-adjust
is in effect with a given value (however it was specified), and we encounter a font in the fallback list that doesn't provide the relevant metric, how should we compute the adjustment for that font: (a) apply no adjustment, or (b) consider what the fallback for that metric would be, and base the adjustment on that.
(2) When font-size-adjust
specifies the from-font
keyword, but the first available font doesn't provide the relevant metric, should we (a) treat this as none
, so no adjustment will be applied to fallback fonts; (b) use the fallback value of the metric for the computed adjustment factor; or (c) look for the first available font that is able to provide the desired metric?
For (1), consider what happens in extreme cases. E.g. if I say
data:text/html,<div style="font-size:20px;font-size-adjust:cap-height 5">Hello سلام</div>
this is a (slightly odd) way of saying that I want the font sized such that its cap-height will be 100px. Now, suppose the primary font doesn't include Arabic letters, and the fallback that the browser picks does not provide a cap-height metric (which isn't unreasonable, as the concept has no clear meaning for Arabic script). How should the Arabic font be scaled, then? If we say "no adjustment is applied when the metric is missing", the Arabic text will end up tiny in comparison to the English. IMO using the same fallback heuristic as when resolving the cap
unit for that font (which Values & Units says should use the ascent) is a better/less surprising result.
For (2), there isn't the same potential for an extreme mismatch if we say that a "missing" metric means no adjustment is applied; in that case, any fallback fonts used will simply not be adjusted, so the property just has no effect. I'm still not sure this is the best outcome, though. By using font-size-adjust
, an author is asking that some dimension other than em-size should be kept consistent across any fallback fonts that get used. Even if there isn't a "real" metric available to resolve the adjustment factor (and so the adjustment applied to the primary font may be somewhat arbitrary), using a fallback heuristic will still provide the same benefit of harmonization across any fallback fonts that occur.
@svgeesus wrote:
@jfkthame I had considered that case to evaluate to 'missing'.
@jfkthame wrote:
(2) When font-size-adjust specifies the from-font keyword, but the first available font doesn't provide the relevant metric, should we (a) treat this as none, so no adjustment will be applied to fallback fonts; (b) use the fallback value of the metric for the computed adjustment factor; or (c) look for the first available font that is able to provide the desired metric?
For 2, I agree with @svgeesus. I don't think we need a new concept, such as "first available font that has specified metric". To me font-size-adjust
not doing any adjustment is the most logical outcome, given the intention of the property.
@jfkthame I see your point about the fallback sizing of Arabic dropping to a small size in this example, but I find this example very synthetic, I'll explain below why:
One more point, about the prevalence of missing metrics: @jfkthame wrote:
[...Arabic font not having a cap height metric...] (which isn't unreasonable, as the concept has no clear meaning for Arabic script)
I quickly checked Segoe UI (default Arabic windows font), Geeza Pro (Mac default Arabic), Noto Nastaliq, Noto Sans Arabic - and they all have a cap height. I'd argue a font maker has to provide a less up-to-date OS/2
table in order to intentionally not provide a cap height. This is meant to put into perspective how likely the issue is to occur at all, which is IMHO less likely.
Do we still agree that the intent of font-size-adjust is to harmonize a certain metric towards the primary font, in order to a) improve legibility, b) reduce cumulative layout shift? (At least both examples in the spec compute a base value from the primary font, and use font-size adjust to normalize fallback fonts towards that.)
In my opinion, usage of font-size adjust for extreme scaling away from the font-size
is not a use-case that the property is intended for. We might even want to consider scale factor limits for the scaling equation.
From my perspective, it is okay if your example in https://github.com/w3c/csswg-drafts/issues/6384#issuecomment-2006987845 does not scale the Arabic part, as I would interpret it as incorrect usage of the property, and that is a useful signal to the content author during authoring.
Intended usage of the property, or where the property works best and in a predictable way if a) the value is calibrated to the primary font by the author in the sense that it does not alter the primary fonts' used font size b) the fallback fonts are known and have been visually checked to provide a good outcome for a given normalization font-size-adjust
value.
(Not using the property for overriding/scaling away from font-size
also avoids larger breakage where a font has an incorrectly specified / disproportional metric.)
When used in this way, I don't see proof that using a heuristic or fallback value (like approximating cap-height by something else) would achieve a better outcome than performing no adjustment.
If font-size-adjust
is used this way, a missing metric in the worst case - leads to a minor perceived font size discrepancy between primary font and fallback fonts. That's why I think specifying the behavior for (1) and (2) as "no adjustment on missing metric" is reasonable.
Thanks @jfkthame and @drott for the additional explanations.
I don't much like these options:
Thus, it seems clearer and more consistent to me if font-size-adjust
with from-font
applies no adjustment, if the requested metric is missing.
So, we currently have:
from-font
Computes to the<number>
corresponding to the specified metric of the first available font.Proposed resolution (the "no adjustment" option):
from-font
If the specified metric exists, computes to the<number>
corresponding to the specified metric of the first available font. Otherwise, the same asnone
I'd like to clarify the computed value for from-font
a bit more. Unless the specified metric exists in the used font, what is the computed value of font-size-adjust: ic-height from-font
in the proposed resolution? Is it ic-height none
or just 'none'?
what is the computed value of
font-size-adjust: ic-height from-font
in the proposed resolution? Is itic-height none
or just 'none'?
Good point, the proposed text could be interpreted either way but this is valid grammar
ic-height from-font
and this is not
ic-height none
so the computed value would be
none
I'm still struggling to see why the "no adjustment" resolution would be better than using the already-defined fallbacks that browsers rely on for the related CSS units.
If an author sets font-size-adjust
to something other than none
, they're expecting a "harmonization" of some aspect of font sizes to happen. Turning the feature off altogether because the first available font didn't provide a specific metric is surely less useful than choosing a default fallback (matching what would be used by the related CSS unit) and applying harmonization accordingly across the font stack.
Likewise, if a font-size-adjust
value is in effect (whether an explicitly-specified ratio or derived from the first available font), it's unexpected if a fallback font used for some character in the content fails to have any adjustment applied because it happened to lack that metric. Again, using the fallback heuristic is likely to be better than no adjustment.
Given something like
font-family: Apple Color Emoji, Segoe UI Emoji, Noto Color Emoji, TwEmoji, EmojiOne, SomeOtherEmojiFont, MyLatinFont, MyCyrillicFont, serif;
font-size-adjust: cap-height from-font;
the author may not know exactly what cap-height value will be applied -- it'll depend which of the emoji fonts is actually present to become the "first available font" -- but whatever value is chosen, the author will reasonably expect that both MyLatinFont and MyCyrillicFont should have their cap-heights aligned to it.
It'll be quite unexpected if some users get mismatched sizing of the Latin vs Cyrillic cap-heights because the emoji font that happened to be present on their system didn't provide that metric.
If an author sets font-size-adjust to something other than none, they're expecting a "harmonization" of some aspect of font sizes to happen.
I totally agree with this expectation. But do they get an accurate harmonization, or something random because different browsers use actually different heuristics? And does that help the author at all, or does it not instead cause more interop frustration?
IMO they do not get anything better with a heuristic than doing no adjustment and just relying on font-size scaling, if the value are not tuned away from the regular font size too much as the previous example with cap-height 5
.
Let's look at the cap height heuristic: https://drafts.csswg.org/css-values-4/#cap says:
If reliable font metrics are not available, UAs may determine the cap-height from the height of an uppercase glyph. One possible heuristic is to look at how far the glyph for the uppercase “O” extends below the baseline, and subtract that value from the top of its bounding box. In the cases where it is impossible or impractical to determine the cap-height, the font’s ascent must be used.
"may... from upercase glyph"... "letter O"... "One possible heuristic.... " ... "otherwise ascent".
This is not the kind of spec text that gets a closer to interop. It also does not function as a foundation for reliable WPT tests that produce the same results in different UAs for testing the fallback for from-font.
Again: This general situation of missing metrics is rare and the edge case, most fonts have the metrics. But let us try to find a way we can test this case and achieve interoperability.
In your newer example of the emoji fonts followed by Latin and Cyrillic: No adjustment simply means, the chosen emoji font, and MyLatinFont
and MyCyrillic
font will just be scaled by font size. The proximity of their cap heights then depends on the font designs. But these fonts share a baseline, so their above baseline parts will not be far off with no adjustment.
If the emoji font does not have a cap height (unlikely): Then we go about inventing one by each UA employing their own different non-interoperable heuristics. Then we force-scale MyLatinFont and MyCyrillic font to match the heuristically determined value. This may very well result in the uppercase Cyrillic and Latin glyphs not matching the visual emoji cap height.
I wonder what is gained with this method compared to just scaling by font size?
It potentially gets worse if MyLatinFont
or MyCyrillic
font do not have a cap-height themselves: then we force-scale two values determined by heuristics to each other. I don't think it's predictable for authors to figure out the reasons for such a result.
On the other topic of computed value:
@shivamidow wrote:
what is the computed value of
font-size-adjust: ic-height from-font
in the proposed resolution? Is itic-height none
or just 'none'?
@svgeesus wrote:
so the computed value would be
none
I am surprised the computed value would in either situation leak something from what's found in the font files. Whether that's related to a number fount in the font file, or from a heuristic, or none. Don't we need to adjust the spec text for the computed value to include from-font
? Could it be that was historically not updated when from-font was added? But I might be misunderstanding something here.
If an author sets font-size-adjust to something other than none, they're expecting a "harmonization" of some aspect of font sizes to happen.
I totally agree with this expectation. But do they get an accurate harmonization, or something random because different browsers use actually different heuristics? And does that help the author at all, or does it not instead cause more interop frustration?
I'd argue that even if the first available font didn't provide a "real" metric, and so a synthetic/heuristic fallback was used, the author's primary goal of ensuring that fallback fonts end up with a visually similar size (as judged by the selected metric) is better served by this than by turning adjustment off altogether.
Let's look at the cap height heuristic: https://drafts.csswg.org/css-values-4/#cap says:
If reliable font metrics are not available, UAs may determine the cap-height from the height of an uppercase glyph. One possible heuristic is to look at how far the glyph for the uppercase “O” extends below the baseline, and subtract that value from the top of its bounding box. In the cases where it is impossible or impractical to determine the cap-height, the font’s ascent must be used.
"may... from upercase glyph"... "letter O"... "One possible heuristic.... " ... "otherwise ascent".
This is not the kind of spec text that gets a closer to interop.
Fair point, but that's a much wider issue than just font-size-adjust; it implies that the cap
unit (for instance) is not reliably interoperable. If this kind interop for font-related measurements is important, then we need to address the fact that the result of border-width: 1cap
or height: 20cap
currently depends on "may... one possible heuristic... otherwise..." spec text.
If that's good enough for the cap
unit, I'd say it's good enough for font-size-adjust
as well. And if not, we should fix it globally, not introduce divergence between the unit and the size-adjust factor.
If the emoji font does not have a cap height (unlikely): Then we go about inventing one by each UA employing their own different non-interoperable heuristics. Then we force-scale MyLatinFont and MyCyrillic font to match the heuristically determined value. This may very well result in the uppercase Cyrillic and Latin glyphs not matching the visual emoji cap height.
I wonder what is gained with this method compared to just scaling by font size?
What's gained is that the uppercase Latin and uppercase Cyrillic can still be expected to align, even if the emoji font didn't provide a meaningful cap-height.
If that's good enough for the cap unit, I'd say it's good enough for font-size-adjust as well. And if not, we should fix it globally, not introduce divergence between the unit and the size-adjust factor.
I can see the point about keeping consistency in mapping back to the metrics values and not branching in this spec based on a specific metric's existence or not. On the other hand, we have an opportunity here to not build on shaky foundations. A good design and spec tightens the behavior for the realistic scenario in which a specific metric is not available, that's possible because some metrics are optional in OpenType/OFF. We can make the start here and define no-adjustment as the behavior for unavailable metrics.
As a consequence, without definining no-adjustment as the policy for unavaiable metrics, as this topic is relevant for interop 2024, this means, we can't test fallback behavior in any WPT test as every UA will have divergent fallback behavior. Positively phrased: Without a "no-adjustment for unavailable" rule, WPT tests for font-size-adjust can only be testing with fonts for which the respective tested metric exists.
In particular, as there is no fallback definition for ic-height
, we can't test fallback behavior for that either in an interoperable way.
Discussion for computed value moved to https://github.com/w3c/csswg-drafts/issues/10292
The CSS Working Group just discussed [css-fonts-5] font-size-adjust with missing metrics
, and agreed to the following:
RESOLVED: In cases where the specified metric is not in the first available font, we fall back to using the same thing we do for other typographical units
When the metric needed for
font-size-adjust
cannot be derived from the font (e.g. metric isn't registered / necessary glyphs are missing), what do we do?The units fall back to some magic number, but probably for
font-size-adjust
we should just not adjust the font’s size.