ftcli fix

A set of commands to detect and automatically fix font errors.

ftcli fix [OPTIONS] COMMAND [ARGS]...

subcommands

decompose-transformed

Decompose glyphs with transformed components.

fontbakery check id: com.google.fonts/check/transformed_components

Rationale:

Some families have glyphs which have been constructed by using transformed components e.g. the ‘u’ being constructed from a flipped ‘n’.

From a designers point of view, this sounds like a win (less work). However, such approaches can lead to rasterization issues, such as having the ‘u’ not sitting on the baseline at certain sizes after running the font through ttfautohint.

Other issues are outlines that end up reversed when only one dimension is flipped while the other isn’t.

As of July 2019, Marc Foley observed that ttfautohint assigns cvt values to transformed glyphs as if they are not transformed and the result is they render very badly, and that vttLib does not support flipped components.

When building the font with fontmake, the problem can be fixed by adding this to the command line:

--filter DecomposeTransformedComponentsFilter

Fixing procedure:

  • Decompose composite glyphs that have transformed components.

ftcli fix decompose-transformed [OPTIONS] INPUT_PATH

Options

-r, --recursive

If input_path is a directory, recursively find font files both in input directory and its subdirectories.

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

duplicate-components

Remove duplicate components.

fontbakery check id: com.google.fonts/check/glyf_non_transformed_duplicate_components

Rationale:

There have been cases in which fonts had faulty double quote marks, with each of them containing two single quote marks as components with the same x, y coordinates which makes them visually look like single quote marks.

This check ensures that glyphs do not contain duplicate components which have the same x,y coordinates.

Fixing procedure:

  • Remove duplicate components which have the same x,y coordinates.

ftcli fix duplicate-components [OPTIONS] INPUT_PATH

Options

-r, --recursive

If input_path is a directory, recursively find font files both in input directory and its subdirectories.

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

empty-names

Remove empty NameRecords from name table.

fontbakery check id: com.adobe.fonts/check/name/empty_records

Rationale:

Check name table for empty records.

Fixing procedure:

  • Remove empty NameRecords from the name table.

ftcli fix empty-names [OPTIONS] INPUT_PATH

Options

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

empty-notdef

Fix empty .notdef glyph.

Draw a simple rectangle to fill the empty .notdef glyph.

Rationale:

Glyph 0 must be assigned to a .notdef glyph. The .notdef glyph is very important for providing the user feedback that a glyph is not found in the font. This glyph should not be left without an outline as the user will only see what looks like a space if a glyph is missing and not be aware of the active font’s limitation.

Fixing procedure:

  • Draw a simple rectangle to fill the empty .notdef glyph

ftcli fix empty-notdef [OPTIONS] INPUT_PATH

Options

-r, --recursive

If input_path is a directory, recursively find font files both in input directory and its subdirectories.

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

italic-angle

Fix italic angle and italic/oblique bits.

fontbakery check ids:

* com.google.fonts/check/italic_angle
* com.google.fonts/check/caret_slope

Rationale: The post table italicAngle property should be a reasonable amount, likely not more than 30°. Note that in the OpenType specification, the value is negative for a rightward lean.

https://docs.microsoft.com/en-us/typography/opentype/spec/post

Checks whether hhea.caretSlopeRise and hhea.caretSlopeRun match with post.italicAngle.

For Upright fonts, you can set hhea.caretSlopeRise to 1 and hhea.caretSlopeRun to 0.

For Italic fonts, you can set hhea.caretSlopeRise to head.unitsPerEm and calculate hhea.caretSlopeRun like this:

round(math.tan(math.radians(-1 * font["post"].italicAngle)) * font["head"].unitsPerEm)

This check allows for a 0.1° rounding difference between the Italic angle as calculated by the caret slope and post.italicAngle

Fixing procedure:

  • Recalculate post.italicAngle

  • Recalculate hhea.caretSlopeRise and hhea.caretSlopeRun according to the calculated post.italicAngle

  • Set/clear the italic and/or oblique bits according to the calculated values

  • In CFF fonts, recalculate also CFF.topDictIndex[0].ItalicAngle and set it to post.italicAngle rounded to

the nearest integer

ftcli fix italic-angle [OPTIONS] INPUT_PATH

Options

-m, --mode <mode>
1: sets only the italic bits and clears the oblique bit
2: sets italic and oblique bits
3: sets only the oblique bit and clears italic bits
--min-slant <min_slant>

Minimum slant value under which the font is considered upright.

The italic angle is calculated by drawing the ‘H’ glyph with the fontTools.pens.statisticsPen.StatisticsPen and rounding the value of the pen’s ‘slant’ attribute. In few cases, upright fonts may return non-zero slant values (e.g.: 1.0). They will be considered as uprights anyway, if the returned italic angle’s absolute value is lower than the minimum (default is 2.0).

Default:

2.0

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

kern-table

Fix kern table.

fontbakery check id: com.google.fonts/check/kern_table

Rationale:

Even though all fonts should have their kerning implemented in the GPOS table, there may be kerning info at the kern table as well.

Some applications such as MS PowerPoint require kerning info on the kern table. More specifically, they require a format 0 kern subtable from a kern table version 0 with only glyphs defined in the cmap table, which is the only one that Windows understands (and which is also the simplest and more limited of all the kern subtables).

Google Fonts ingests fonts made for download and use on desktops, and does all web font optimizations in the serving pipeline (using libre libraries that anyone can replicate.)

Ideally, TTFs intended for desktop users (and thus the ones intended for Google Fonts) should have both kern and GPOS tables.

Given all of the above, we currently treat kerning on a v0 kern table as a good-to-have (but optional) feature.

Fixing procedure:

  • Remove glyphs that are not defined in the cmap table from the kern table.

ftcli fix kern-table [OPTIONS] INPUT_PATH

Options

-r, --recursive

If input_path is a directory, recursively find font files both in input directory and its subdirectories.

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

monospace

Fix metadata in monospaced fonts

fontbakery check id: com.google.fonts/check/monospace

Rationale:

There are various metadata in the OpenType spec to specify if a font is monospaced or not. If

the font is not truly monospaced, then no monospaced metadata should be set (as sometimes they mistakenly are…)

Requirements for monospace fonts:

  • post.isFixedPitch - “Set to 0 if the font is proportionally spaced, non-zero if the font

is not proportionally paced (monospaced)” (https://www.microsoft.com/typography/otspec/post.htm)

  • hhea.advanceWidthMax must be correct, meaning no glyph’s width value is greater.

(https://www.microsoft.com/typography/otspec/hhea.htm)

  • OS/2.panose.bProportion must be set to 9 (monospace) on latin text fonts.

  • OS/2.panose.bSpacing must be set to 3 (monospace) on latin handwritten or latin symbol

fonts.

  • Spec says: “The PANOSE definition contains ten digits each of which currently describes up to sixteen variations.

Windows uses bFamilyType, bSerifStyle and bProportion in the font mapper to determine family type. It also uses bProportion to determine if the font is monospaced.” (https://www.microsoft.com/typography/otspec/os2.htm#pan, https://monotypecom-test.monotype.de/services/pan2)

  • OS/2.xAvgCharWidth must be set accurately. “OS/2.xAvgCharWidth is used when rendering monospaced fonts, at

least by Windows GDI” (https://typedrawers.com/discussion/comment/15397/#Comment_15397)

  • CFF.cff.TopDictIndex[0].isFixedPitch must be set to True for CFF fonts.

Fixing procedure:

If the font is monospaced, then:

  • Set post.isFixedPitch to True (1)

  • Correct the hhea.advanceWidthMax value

  • Set the OS/2.panose.bProportion value to 9 or 3, according to the OS/2.panose.bFamilyType value

  • Set CFF.cff.TopDictIndex[0].isFixedPitch to True for CFF fonts

ftcli fix monospace [OPTIONS] INPUT_PATH

Options

-r, --recursive

If input_path is a directory, recursively find font files both in input directory and its subdirectories.

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

nbsp-missing

Fix missing whitespace glyphs.

fontbakery check id: com.google.fonts/check/whitespace_glyphs

Rationale:

Font contains glyphs for whitespace characters?

Fixing procedure:

  • Add a glyph for the missing nbspace character by double mapping the space character

ftcli fix nbsp-missing [OPTIONS] INPUT_PATH

Options

-r, --recursive

If input_path is a directory, recursively find font files both in input directory and its subdirectories.

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

nbsp-width

Fix whitespace widths.

fontbakery check id: com.google.fonts/check/whitespace_widths

Rationale:

If the space and nbspace glyphs have different widths, then Google Workspace has problems with the font.

The nbspace is used to replace the space character in multiple situations in documents; such as the space before punctuation in languages that do that. It avoids the punctuation to be separated from the last word and go to next line.

This is automatic substitution by the text editors, not by fonts. It’s also used by designers in text composition practice to create nicely shaped paragraphs. If the space and the nbspace are not the same width, it breaks the text composition of documents.

Fixing procedure:

  • Check if nbspace and space glyphs have the same width. If not, correct nbspace width to match the

space width.

ftcli fix nbsp-width [OPTIONS] INPUT_PATH

Options

-r, --recursive

If input_path is a directory, recursively find font files both in input directory and its subdirectories.

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument

strip-names

Remove leading and trailing spaces from name table entries.

fontbakery check id: com.google.fonts/check/name/trailing_spaces

Rationale:

Name table records must not have trailing spaces.

Fixing procedure:

  • Remove leading and trailing spaces from all NameRecords in the name table.

ftcli fix strip-names [OPTIONS] INPUT_PATH

Options

-r, --recursive

If input_path is a directory, recursively find font files both in input directory and its subdirectories.

-out, --output-dir <output_dir>

Specify the directory where output files are to be saved. If the directory doesn’t exist, will be created. If output_dir is not specified, files will be saved to the same folder.

--recalc-timestamp

Keep the original font ‘modified’ timestamp (head.modified) or set it to current time. By default, original timestamp is kept.

--no-overwrite

Overwrite existing files or save them to a new file (numbers are appended at the end of file name). By default, files are overwritten.

Arguments

INPUT_PATH

Required argument