-
Notifications
You must be signed in to change notification settings - Fork 26.8k
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
FontWeight should subsume wght
in FontVariation
#148026
Comments
A small other implementation note, copying over from a comment I wrote on another issue, just so it's visible here in case it's helpful: On the framework side, one question is what to do about the |
FYI @Hixie , in case you have thoughts on how these APIs should interact. |
Interesting question. I agree that we should do something about this. In practice today what we do is strictly correct, in that fontWeight selects a different font file, and The easiest solution is probably just to make
(By "easiest" I mean "simplest", which I think is definitely valuable here. CSS makes this way too complicated.) |
That proposal sounds great to me, except for this step:
This would mean there are still two independent notions of "font weight" in play: the one specified in fontWeight, and the one specified in a I think we can accomplish that by just having this step use the value of fontWeight as the Then in fact the framework doesn't need to send a |
In practice nobody would use The reason I think the engine should honor |
OK, that makes sense. A crucial part of making that plan work will be to make it clear in the docs that |
agreed |
We could probably have left out the `const TextStyle().merge()`; I think the only difference is in the resulting style's debugLabel. But I figured we might as well be consistent in how we use weightVariableTextStyle, and in any case it should disappear with flutter/flutter#148026 .
This converts the last remaining place where we were using TextStyle.fontWeight directly, when we should have been using weightVariableTextStyle. (In a future with flutter/flutter#148026 , though, all uses of weightVariableTextStyle should be changed back to plain TextStyle.fontWeight.)
Problem
Flutter has two ways to specify the font weight in a TextStyle: you can pass either a
FontWeight
value or aFontVariation
with variationwght
. For example these look likeTextStyle(fontWeight: FontWeight.w500)
orTextStyle(fontVariations: [FontVariation('wght', 500)])
.The trouble is that, at present, neither of these subsumes the job of the other, and nor do they interact well with each other.
Setting only
fontWeight
doesn't work if the font that gets used turns out to offer variable weight. This is a pitfall that even Flutter's own Material implementation falls into: Implement full support for variable fonts #109308 (comment)Setting only a
wght
variation doesn't work, I believe, if the font that gets used turns out not to offer variable weight.Setting both a
fontWeight
and awght
variation can have interacting effects:fontWeight affects variable font even with FontVariation #136779
text: Bold text is sometimes way bolder than intended zulip/zulip-flutter#500
These effects don't follow any documented pattern, and don't seem desirable.
In general it's impossible for an app to know in advance whether the relevant font will offer variable weight: if it's displaying any kind of user-controlled text, the text may be in a variety of scripts, which may not be covered by the app's primary font and may fall back to a variety of other fonts.
As a result, there doesn't seem to be any existing way for a Flutter app to reliably control the font weight of its text, if any of the fonts it uses offer variable weight.
Proposed solution
(See revised proposal below from @Hixie. The changes to
FontWeight
are the same, but awght
FontVariation retains a separate role, for backwards compatibility and for use in a particular edge case.)When
fontWeight
is specified, interpret it as the exact font weight to use, regardless of whether the font offers variable weight and regardless of whether awght
variation is also present. Consult anywght
variation only as a fallback, for compatibility, whenfontWeight
is absent.In order to support the same fine-grained range of possible weights currently expressed with a
wght
FontVariation, add a constructorconst FontWeight(this.value)
that accepts an int. (TheFontWeight
type is already a class with a fieldint value
.)This is the same API that CSS offers: there's just one attribute
font-weight
, it accepts any number from 1 to 1000, and it works regardless of whether the font ultimately used offers variable weight. This design seems to have worked out well for CSS.Implementation
I think most of the work to implement this would be in the engine. The framework would pass the engine a single font-weight value from 1 to 1000, rather than both a
fontWeight
encoded as an int from 0 to 8 and awght
variation from 1 to 1000; the engine then needs to use that single value when it comes time to actually select fonts.Fundamentally this is the same sort of job the engine is already successfully handling: if the app said
FontWeight.w500
, and the only otherwise-matching fonts are at weights 400 and 700 (the usual "normal" and "bold" values), then the engine has to somehow pick one of those. What's new is just that the weight might be 517 instead of 500.For the exact behavior to use with that single weight, one natural model to follow is what CSS specifies for the web. That behavior is described on MDN here and here. It's found in the CSS spec here and at the step beginning "font-weight is matched next" within the font-matching algorithm (beginning a little before this example).
Alternatively, if it turns out there's some relatively easy change that can be made to the existing code to handle this, but it has some other behavior that's different from CSS's, then that's probably fine too.
The text was updated successfully, but these errors were encountered: