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

Generating a static font from variable font results in inconsistent letter spacing #3454

Open
akiirax opened this issue Feb 26, 2024 · 9 comments

Comments

@akiirax
Copy link

akiirax commented Feb 26, 2024

I am using Roboto Flex font, and the following is the command being used to generate a static instance.

$ fonttools varLib.mutator RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF.ttf wght=100 wdth=100 and different weights.

Now, wherever (web, mobile) this font is being used, the letter spacing is completely not related to what has been I believe the default within the variable font itself.

What might I be doing wrong?

@m4rc1e
Copy link
Contributor

m4rc1e commented Feb 26, 2024

fonttools varLib.instancer is newer than mutator. I'd try that first.

@akiirax
Copy link
Author

akiirax commented Mar 10, 2024

Thanks @m4rc1e but that didn't make any difference, except, the generated static file size got increased from 75k to around 700K when changing from varLib.mutator to varLib.instancer and they both behave the same.

Still the letter spacing is like completely gone versus using the variable font directly.

varLib.mutator

[user@localhost.localdomain fonts]# fonttools varLib.mutator RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF.ttf wght=400

Location: {'wght': 400.0}
Loading variable font
Normalized location: {'wght': 0.0, 'wdth': 0.0, 'opsz': 0.0, 'GRAD': 0.0, 'slnt': 0.0, 'XTRA': 0.0, 'XOPQ': 0.0, 'YOPQ': 0.0, 'YTLC': 0.0, 'YTUC': 0.0, 'YTAS': 0.0, 'YTDE': 0.0, 'YTFI': 0.0}
Mutating glyf/gvar tables
Mutating FeatureVariations
Mutating GDEF/GPOS/GSUB tables
Pruning name table
Removing variable tables
Saving instance font RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF-instance.ttf

[user@localhost.localdomain fonts]# ls -lah RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF-instance.ttf

-rw-r--r--  1 user  staff    74K Mar 10 15:15 RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF-instance.ttf

varLib.instancer

[user@localhost.localdomain fonts]# fonttools varLib.instancer RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF.ttf wght=400

Restricting axes: {'wght': (400, 400, 400)}
Loading variable font
Restricted limits: {'wght': (400, 400, 400)}
Normalized limits: {'wght': (0, 0, 0, 300, 600)}
Instantiating glyf/gvar tables
Instantiating HVAR table
Instantiating GDEF and GPOS tables
Instantiating FeatureVariations of GSUB table
Instantiating avar table
Instantiating fvar table
Pruning name table
Saving partial variable font RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF-partial.ttf

[user@localhost.localdomain fonts]# ls -lah RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF-partial.ttf

-rw-r--r--  1 user  staff   619K Mar 10 15:17 RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF-partial.ttf

Loading the font in HTML, Android, iOS, renders the same behavior of completely no letter spacing, and susceptibly kerning as well.

@ftCLI
Copy link

ftCLI commented Mar 10, 2024

Try with OS/2.recalcAvgCharWidth

font = TTFont('static.ttf')
font['OS/2'].recalcAvgCharWidth()
font.save('static.ttf')

@akiirax
Copy link
Author

akiirax commented Mar 10, 2024

@ftCLI

To use recalcAvgCharWidth I had to pass it the actual variable font instance for it to work since it requires ttFont as an argument, which ends up with a 751K font file for weight 500; my final code is as follows.

from fontTools.ttLib import TTFont
from fontTools.varLib.instancer import instantiateVariableFont
var_font = TTFont('RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght-VF.ttf')
var_font['OS/2'].recalcAvgCharWidth(var_font)
instance_coordinates = {'wght': 500}
static_font = instantiateVariableFont(var_font, instance_coordinates)
static_font.save('rf-w500.ttf')

Will test it and update back, tho I'm not feeling confident from calling var_font['OS/2'].recalcAvgCharWidth(var_font) that way.

@ftCLI
Copy link

ftCLI commented Mar 10, 2024

Your static_font is a TTFont object.

You should use: static_font['OS/2'].recalcAvgCharWidth()

Anyway, I downloaded Robot Flex from Google and exported all the static instances

ftcli converter vf2i "RobotoFlex-VariableFont_GRAD,XOPQ,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf" --no-update-name-table -out static

The static instances didn't need the recalculation of the xAvgCharWidth vaule. See attached files: static.zip

@akiirax
Copy link
Author

akiirax commented Mar 10, 2024

Thanks @ftCLI

I tested with both your generated static fonts and I did generate my own using the same command provided and it seems working so far, need to validate on all pre-defined weights yet with what's included in Figma.

One more thing, we're using custom weights like 425 and 475 at some places, so how can I generate these as well?

Much appreciate your outstandingly fast response :)

@ftCLI
Copy link

ftCLI commented Mar 10, 2024

To generate static fonts for non-named instances, add the '-s' switch. It will allow you to choose custom values for each axis.

Without passing —no-update-name-table, actually ftcli raises a ValueError when instantiating Roboto Flex, so don’t forget to add it (order doesn’t matter)

@akiirax
Copy link
Author

akiirax commented Mar 10, 2024

So, I was just validating on a single line with only five words comparing both line spacing as in Figma versus usage in Jetpack Compose and it shows the letter spacing is actually accurate, however, when tested on a multi-line block of text with more than fifty words, it got completely messed up and the letter spacing is not as it is in Figma, or Adobe Illustrator, to make sure nothing funny caused by any of these tools tho they're giving both same output but not similar to the generated font file.

Not sure what might be the reason of that, I tried with multiple font weights from the attached statically generated fonts you did without any luck.

@ftCLI
Copy link

ftCLI commented Mar 11, 2024

I don't have Figma nor Illustrator, can't help. Those are not valid fonts anyway, at least the name table should be updated.

These ones pass fontbakery check-universal (with some warnings): static.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants