Skip to content

Custom fonts CookBook example not working as expected #3591

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

Open
miquelbeltran opened this issue Jul 23, 2019 · 12 comments
Open

Custom fonts CookBook example not working as expected #3591

miquelbeltran opened this issue Jul 23, 2019 · 12 comments
Labels
a.cookbook Relates to a cookbook recipe or guide act.question Relates to issues that writers need SME help e1-hours Effort: < 8 hrs fix.code-sample Needs new or updated code sample p2-medium Necessary but not urgent concern. Resolve when possible. st.blocked Issue cannot continue until another action completes

Comments

@miquelbeltran
Copy link
Member

I added custom fonts to my project following the explanation in https://flutter.dev/docs/cookbook/design/fonts

In the example you can find:

- family: RobotoMono
      fonts:
        - asset: fonts/RobotoMono-Regular.ttf
        - asset: fonts/RobotoMono-Bold.ttf
          weight: 700

So I followed it and in my pubspec.yaml I have:

fonts:
    - family: Edmondsans
      fonts:
        - asset: fonts/Edmondsans-Regular.otf
        - asset: fonts/Edmondsans-Medium.otf
          weight: 500
        - asset: fonts/Edmondsans-Bold.otf
          weight: 700

Then in my code:

TextStyle(
      fontFamily: "Edmondsans",
      fontWeight: FontWeight.w500,
    );

However I noticed that:

  • The w500 (medium) was not being rendered, and instead, it was rendering the Edmondsans-Regular.
  • The w700 (bold) was not rendering Edmondsans-Bold but instead making a bold version of Edmondsans-Regular (they looked different)

To actually use my Medium and Bold custom font files, I had to use them in a different way:

fonts:
    - family: Edmondsans
      fonts:
        - asset: fonts/Edmondsans-Regular.otf
    - family: Edmondsans-Medium
      fonts:
        - asset: fonts/Edmondsans-Medium.otf
    - family: Edmondsans-Bold
      fonts:
        - asset: fonts/Edmondsans-Bold.otf

Then in my code, this will work as expected:

TextStyle(
      fontFamily: "Edmondsans-Medium",
    );

My configuration info:

[✓] Flutter (Channel beta, v1.7.8+hotfix.3, on Mac OS X 10.14.5 18F132, locale en-DE)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 10.3)
[✓] iOS tools - develop for iOS devices
[✓] Android Studio (version 3.4)
[✓] IntelliJ IDEA Ultimate Edition (version 2019.1.3)
[✓] IntelliJ IDEA Community Edition (version 2019.1.3)
[✓] Connected device (1 available)

This issue here seem to be related: flutter/flutter#29806

I'd suggest to change the cookbook examples until custom fonts work as expected.

@jason-simmons
Copy link
Member

The Flutter engine matches fonts within a family based on the metadata in the font itself, not the style descriptors declared in the pubspec.yaml manifest.
(We should remove the style descriptors in pubspec.yaml now that they are obsolete).

The Edmondsans regular, medium, and bold fonts contain metadata declaring their weights as 400, 410, and 420 respectively. However, the Flutter text subsystem only supports font weight buckets representing even multiples of 100 (https://api.flutter.dev/flutter/dart-ui/FontWeight-class.html). So all three of these fonts are mapped to FontWeight.w400, and the font style matcher can not choose between these fonts based on weight.

Declaring these fonts as different families in pubspec.yaml will work around this.

@miquelbeltran
Copy link
Member Author

Thanks a lot for the explanation @jason-simmons!

It didn't occur me that my font could have been the one causing this.

I think it would still be good to update the cookbook documentation so it won't confuse other developers.

@kf6gpe
Copy link
Contributor

kf6gpe commented Jan 27, 2020

Moving to the website for the cookbook.

@kf6gpe kf6gpe transferred this issue from flutter/flutter Jan 27, 2020
@orestesgaolin
Copy link
Contributor

The Flutter engine matches fonts within a family based on the metadata in the font itself, not the style descriptors declared in the pubspec.yaml manifest.
(We should remove the style descriptors in pubspec.yaml now that they are obsolete).

Should we update the docs here to explain that these descriptors are actually ignored?

@legalcodes legalcodes added e1-hours Effort: < 8 hrs p2-medium Necessary but not urgent concern. Resolve when possible. labels Mar 25, 2020
@c15yi
Copy link

c15yi commented Apr 21, 2022

The Flutter engine matches fonts within a family based on the metadata in the font itself, not the style descriptors declared in the pubspec.yaml manifest.
(We should remove the style descriptors in pubspec.yaml now that they are obsolete).

This looks like a bug in the flutter engine to me.
The font file can, as mentioned, have values between two multiple of 100 (e.g. 425).

The value specified in the pubspec.yaml should therefore allow us to override that internal value to something we can actually use.

Working with multiple font families as a workaround would work but is far from elegant in my eyes.

@GregoryConrad
Copy link

GregoryConrad commented Jul 17, 2022

Based on what @jason-simmons mentioned, I created the following python script to "fix" your custom font files to use the correct weights that flutter respects. Create a src directory and put all your fonts in there. Create an empty out directory and the script will place the new fonts there.

import os
from fontTools import ttLib

# Declare your font file names and the correct weights here
to_change = {
    'Neue Radial B Thin Italic.ttf': 100,
    'Neue Radial B Thin.ttf': 100,
    'Neue Radial B Extra Bold Italic.ttf': 800,
    'Neue Radial B Bold.ttf': 700,
    'Neue Radial B Book.ttf': 500,
    'Neue Radial B Regular Italic.ttf': 400,
    'Neue Radial B Light.ttf': 300,
    'Neue Radial B Book Italic.ttf': 500,
    'Neue Radial B Regular.ttf': 400,
    'Neue Radial B Extra Bold.ttf': 800,
    'Neue Radial B Extra Light.ttf': 200,
    'Neue Radial B Light Italic.ttf': 300,
    'Neue Radial B Extra Light Italic.ttf': 200,
    'Neue Radial B Bold Italic.ttf': 700,
    'Neue Radial B Medium.ttf': 600,
    'Neue Radial B Black.ttf': 900,
    'Neue Radial B Black Italic.ttf': 900,
    'Neue Radial B Medium Italic.ttf': 600,
}

for file, weight in to_change.items():
    with ttLib.TTFont(os.path.join('src', file)) as tt:
        tt['OS/2'].usWeightClass = weight
        tt.save(os.path.join('out',file))

This is probably the best workaround out there at the moment. No multiple font families, and no needing to modify each font individually.

@atsansone atsansone added the a.cookbook Relates to a cookbook recipe or guide label May 17, 2023
@atsansone
Copy link
Contributor

@jason-simmons : Is this font issue still occurring? If so, I can document this workaround. If not, I'll close this issue.

@atsansone atsansone added act.question Relates to issues that writers need SME help st.blocked Issue cannot continue until another action completes ltw-triage labels May 18, 2023
@sfshaza2
Copy link
Contributor

@miquelbeltran, ah the ultimate irony! You filed it, you fix it! :D

@sfshaza2 sfshaza2 added the fix.code-sample Needs new or updated code sample label Jul 13, 2023
@github-actions
Copy link

github-actions bot commented Aug 2, 2023

Without additional information we're not able to resolve this issue, so it will be closed at this time. You're still free to add more info and respond to any questions above, though. We'll reopen the case if you do. Thanks for your contribution!

@github-actions github-actions bot closed this as completed Aug 2, 2023
@miquelbeltran miquelbeltran reopened this Aug 2, 2023
@miquelbeltran
Copy link
Member Author

I'll work on this now

@miquelbeltran
Copy link
Member Author

Is this font issue still occurring? If so, I can document this workaround. If not, I'll close this issue.

For what I can see, Flutter still only supports multiples of 100 when it comes to the font weight.

Reviewing the cookbook recipe, I see that now it says:

Note that defining the weight property does not
override the actual weight of the font. You would not be able to
access RobotoMono-Bold with FontWeight.w100, even if its weight
was set to 100.

I am thinking, I could add an explanation and workaround in the recipe, e.g.

This can be an issue if the original font file doesn't define its weight
as Flutter expects it.

You can workaround this limitation by defining individual
font families for each different weight as shown below:

fonts:
 - family: Edmondsans
   fonts:
   - asset: fonts/Edmondsans-Regular.otf
 - family: Edmondsans-Bold
   fonts:
     - asset: fonts/Edmondsans-Bold.otf

And then using them directly in your code:

TextStyle(
  fontFamily: "Edmondsans-Bold",
);

Any thoughts on this? My only concern is that it could be promoting the wrong code practices, so we need to be clear that it is just a workaround for font files that aren't compliant with what Flutter expects.

@atsansone
Copy link
Contributor

@miquelbeltran : That works. These docs are fluid, so we can always change again later if this appears to be in error.

@atsansone atsansone assigned atsansone and miquelbeltran and unassigned atsansone Sep 1, 2023
@miquelbeltran miquelbeltran removed their assignment Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a.cookbook Relates to a cookbook recipe or guide act.question Relates to issues that writers need SME help e1-hours Effort: < 8 hrs fix.code-sample Needs new or updated code sample p2-medium Necessary but not urgent concern. Resolve when possible. st.blocked Issue cannot continue until another action completes
Projects
None yet
Development

No branches or pull requests

10 participants