Giter VIP home page Giter VIP logo

handjet's Introduction

Handjet

Handjet is an element-based variable font (aka pixel font, modular font, …) where every glyph is composed using multiple copies of the same element. Each element can take 1 of 23 shapes and transition smoothly between them while creating various effects. The font currently supports these scripts: Arabic, Armenian, Cyrillic, Greek, Hebrew, Latin, and Korean.

Handjet’s ELSH axis animation Handjet’s ELSH axis animation Handjet’s ELSH axis animation Handjet’s wght axis animation Handjet’s ELGR axis animation

The story

In autumn 2018, I had the opportunity to teach type design to a group of talented graphic design students at the Faculty of Fine Arts in Brno. Their first exercise was to build a simple element-based font that would be tailored to work well with handjet printers. The handjet’s 32-pixel vertical matrix defined the constraints, the only contour to draw was the shape of the element, and the rest of the design job was “only” a matter of placing the elements on the grid to form letters. The clocks were ticking and the students were fierce. Most of them had their font with basic English and Czech alphabets done by the end of the day!

Upon realizing the task could be taken even further, I set out to design my own font. I did not leave the house that weekend and ended up with a complete pan-European Latin. A couple of days later I had Greek and Cyrillic too. It was hard to stop. And once I started interpolating the element shapes, it got out of control completely.

In its current version, the Handjet type system contains 23 elemental shapes. Smooth transitions between them create various effects: a triangle appears out of thin air and expands into a square, the square rotates to create a lozenge and then scales into a thin rectangle, a rounded square smoothly turns into a circle and the circle into an oval, a clover becomes a rotating star, and a spindle, and a heart. The size of elements can be changed as well, producing different font weights. Plus, one can choose to use groups of 2x2 smaller elements instead of a single element. All of these components work together within a single variable font, allowing users to produce their custom variations and animations easily.

In 2019, Google sponsored the extension and open-sourcing of Handjet. All variations and element shapes have been thoroughly revisited and extended. Working with consultants Borna Izadpanah, Khajag Apelian, and Meir Sadan, I have also added support for Arabic, Armenian, and Hebrew (respectively). Selected symbols representing wild and domestic animals were included together with various seasonal symbols and patterns. I hope you will have as much fun using them as I had designing them.

In 2023, Park Ha-neul (박하늘) and Lee-su Yoo (유이수) have included support for the Korean script.

— David Březina, November 2023

P.S. Warning: variable fonts are relatively new and Handjet sometimes challenges the limits. You might get unpredictable, yet beautiful and somewhat amusing, rendering errors in Adobe software. We have found that the InDesign 18 has issues with Handjet. Please, use an older version of InDesign until we find the cause. It works well in browsers as far as we know.

P.P.S. If you want to do this exercise with your students, have a look at this Glyphs tutorial.

P.P.P.S. To be perfectly clear, I went way beyond what a handjet's grids permit, so only some of the fonts are suited to use with these printers.

Handjet preview

Variable font

Handjet is a variable font with the following axes:

  • Weight (wght) (100-900) controls the size of the element,
  • Element Shape (ELSH) (0.0-16.0) controls the shape of the element,
  • Element Grid (ELGR) (1.0-2.0) controls how many elements are used per one grid unit.

Weight (wght)

The weight is represented by the size of the element used.

Value Description Instance
100 Thin *
200 ExtraLight *
300 Light *
400 Regular *
500 Medium *
600 SemiBold *
700 Bold *
800 ExtraBold *
900 Black *

Element Shape axis (ELSH)

The interpolation between different element shapes along this axis creates a rotation or disappearing effect for some of them. This was done (instead of having independent rotation and scale axes for example) to simplify the design space, and to keep things manageable for users as well as computers. For a preview of the available element shapes and their transitions, see the animations above.

Value Description Instance
0.00 Blank *
1.00 Triangle *
2.00 Square (default) *
2.11 Square at 20 degrees -
2.25 Lozenge *
2.36 Square at 65 degrees -
2.50 Square (transitional master) x
3.19 Block *
3.36 Rectangle *
4.00 Bar (Vertical) *
4.11 Bar at 20 degrees -
4.25 Bar (Diagonal Up) *
4.36 Bar at 65 degrees -
4.50 Bar (Horizontal) *
4.61 Bar at 110 degrees -
4.75 Bar (Diagonal Down) *
4.86 Bar at 155 degrees -
5.00 Bar at 180 degrees -
6.50 Square (transitional master) x
6.90 Rounded Square *
7.63 Squircle *
8.00 Circle *
8.69 Egg *
8.86 Oval *
9.50 Thinner Oval *
11.00 Circle (transitional master) x
12.00 Clover *
13.00 Flower *
14.00 Star *
14.11 Star at 20 degrees -
14.25 Diagonal Star *
14.36 Star at 65 degrees -
14.50 Star at 90 degrees -
14.75 Big Star *
15.00 Spindle *
15.37 Pin *
16.00 Heart *

Rows marked with * are available as instances in the STAT table.
Rows marked with x are repeated shapes that allow for a better transition.
Rows marked with - are for example only.

Element Grid axis (ELGR)

This axis controls how many elements are used per one grid unit.

Value Description Instance
1.00 Single element (single) *
2.00 Group of 2x2 elements (double) *

Source files

In principle, all glyphs remain structurally the same across all masters except for one special glyph, pixel, which represents the element shape and is different for each master.

The pixel glyph is compiled from all non-exporting pixel.xxx glyphs and is the only component that changes between the masters of this variable font. You can recompile the pixel glyph by using the production/glyphs-scripts/compile pixel glyph.py macro in the Glyphs app.

Building a the Variable Font from the sources

  • In your Python 3 environment, make sure to install the required pip packages: $ pip install -r requirements.txt
  • Make sure you make the production/build.sh file executable: $ chmod +x production/build.sh
  • To recompile, run $ ./production/build.sh and new fonts will be generated in the fonts/ directory (it's a complex file and takes a while to recompile)

Scripting

If you would like to animate Handjet using Python and DrawBot, you can check out the source code for the animations.

handjet's People

Contributors

andreawong avatar eran-ben-barak avatar kontur avatar mrbrezina avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

handjet's Issues

Combinations of shaddah and other marks are spacing

Some combinations of U+0651 ARABIC SHADDA with other marks are ligated into spacing glyphs. They should not be spacing. For example, here is <U+06CC ARABIC LETTER FARSI YEH, U+064D ARABIC KASRATAN, U+0651 ARABIC SHADDA>:
یٍّ

The glyphs for U+FC5E..U+FC63 should still be spacing.

Interpolation problems in `Handjet[ELGR,ELSH,wght].ttf`

Hello!

This is an automatically-generated report about possible interpolation problems in Handjet[ELGR,ELSH,wght].ttf, as found in the Google Fonts catalog.

The particular version of the font that was tested was archive:.

To download a PDF version of this report with helpful visuals of the problems, click here; Or to view it on the GitHub website, click here.

The report follows:

Glyph pixel was not compatible:
  Masters: 'ELSH=6.49976', 'ELSH=8.00024':
    Contour 0 start point differs: 0 in 'ELSH=6.49976', 76 in 'ELSH=8.00024'; reversed: False
    Contour 1 start point differs: 0 in 'ELSH=6.49976', 76 in 'ELSH=8.00024'; reversed: False
    Contour 2 start point differs: 0 in 'ELSH=6.49976', 76 in 'ELSH=8.00024'; reversed: False
    Contour 3 start point differs: 0 in 'ELSH=6.49976', 76 in 'ELSH=8.00024'; reversed: False
  Masters: 'ELGR=2.0 ELSH=6.49976', 'ELGR=2.0 ELSH=8.00024':
    Contour 0 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976', 76 in 'ELGR=2.0 ELSH=8.00024'; reversed: False
    Contour 1 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976', 76 in 'ELGR=2.0 ELSH=8.00024'; reversed: False
    Contour 2 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976', 76 in 'ELGR=2.0 ELSH=8.00024'; reversed: False
    Contour 3 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976', 76 in 'ELGR=2.0 ELSH=8.00024'; reversed: False
  Masters: 'ELSH=6.49976 wght=100.0', 'ELSH=8.00024 wght=100.0':
    Contour 0 start point differs: 0 in 'ELSH=6.49976 wght=100.0', 4 in 'ELSH=8.00024 wght=100.0'; reversed: False
    Contour 1 start point differs: 0 in 'ELSH=6.49976 wght=100.0', 4 in 'ELSH=8.00024 wght=100.0'; reversed: False
    Contour 2 start point differs: 0 in 'ELSH=6.49976 wght=100.0', 4 in 'ELSH=8.00024 wght=100.0'; reversed: False
    Contour 3 start point differs: 0 in 'ELSH=6.49976 wght=100.0', 4 in 'ELSH=8.00024 wght=100.0'; reversed: False
  Masters: 'ELSH=6.49976 wght=900.0', 'ELSH=8.00024 wght=900.0':
    Contour 0 start point differs: 0 in 'ELSH=6.49976 wght=900.0', 76 in 'ELSH=8.00024 wght=900.0'; reversed: False
    Contour 1 start point differs: 0 in 'ELSH=6.49976 wght=900.0', 76 in 'ELSH=8.00024 wght=900.0'; reversed: False
    Contour 2 start point differs: 0 in 'ELSH=6.49976 wght=900.0', 76 in 'ELSH=8.00024 wght=900.0'; reversed: False
    Contour 3 start point differs: 0 in 'ELSH=6.49976 wght=900.0', 76 in 'ELSH=8.00024 wght=900.0'; reversed: False
  Masters: 'ELGR=2.0 ELSH=6.49976 wght=100.0', 'ELGR=2.0 ELSH=8.00024 wght=100.0':
    Contour 0 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976 wght=100.0', 76 in 'ELGR=2.0 ELSH=8.00024 wght=100.0'; reversed: False
    Contour 1 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976 wght=100.0', 76 in 'ELGR=2.0 ELSH=8.00024 wght=100.0'; reversed: False
    Contour 2 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976 wght=100.0', 76 in 'ELGR=2.0 ELSH=8.00024 wght=100.0'; reversed: False
    Contour 3 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976 wght=100.0', 76 in 'ELGR=2.0 ELSH=8.00024 wght=100.0'; reversed: False
  Masters: 'ELGR=2.0 ELSH=6.49976 wght=900.0', 'ELGR=2.0 ELSH=8.00024 wght=900.0':
    Contour 0 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976 wght=900.0', 76 in 'ELGR=2.0 ELSH=8.00024 wght=900.0'; reversed: False
    Contour 1 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976 wght=900.0', 76 in 'ELGR=2.0 ELSH=8.00024 wght=900.0'; reversed: False
    Contour 2 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976 wght=900.0', 76 in 'ELGR=2.0 ELSH=8.00024 wght=900.0'; reversed: False
    Contour 3 start point differs: 0 in 'ELGR=2.0 ELSH=6.49976 wght=900.0', 76 in 'ELGR=2.0 ELSH=8.00024 wght=900.0'; reversed: False
  Masters: 'ELSH=12.9999', 'ELSH=13.99963':
    Contour 0 start point differs: 0 in 'ELSH=12.9999', 70 in 'ELSH=13.99963'; reversed: False
    Contour 1 start point differs: 0 in 'ELSH=12.9999', 70 in 'ELSH=13.99963'; reversed: False
    Contour 2 start point differs: 0 in 'ELSH=12.9999', 70 in 'ELSH=13.99963'; reversed: False
    Contour 3 start point differs: 0 in 'ELSH=12.9999', 70 in 'ELSH=13.99963'; reversed: False
  Masters: 'ELGR=2.0 ELSH=12.9999', 'ELGR=2.0 ELSH=13.99963':
    Contour 0 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999', 70 in 'ELGR=2.0 ELSH=13.99963'; reversed: False
    Contour 1 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999', 70 in 'ELGR=2.0 ELSH=13.99963'; reversed: False
    Contour 2 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999', 70 in 'ELGR=2.0 ELSH=13.99963'; reversed: False
    Contour 3 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999', 70 in 'ELGR=2.0 ELSH=13.99963'; reversed: False
  Masters: 'ELSH=12.9999 wght=100.0', 'ELSH=13.99963 wght=100.0':
    Contour 0 start point differs: 0 in 'ELSH=12.9999 wght=100.0', 70 in 'ELSH=13.99963 wght=100.0'; reversed: False
    Contour 1 start point differs: 0 in 'ELSH=12.9999 wght=100.0', 70 in 'ELSH=13.99963 wght=100.0'; reversed: False
    Contour 2 start point differs: 0 in 'ELSH=12.9999 wght=100.0', 70 in 'ELSH=13.99963 wght=100.0'; reversed: False
    Contour 3 start point differs: 0 in 'ELSH=12.9999 wght=100.0', 70 in 'ELSH=13.99963 wght=100.0'; reversed: False
  Masters: 'ELSH=12.9999 wght=900.0', 'ELSH=13.99963 wght=900.0':
    Contour 0 start point differs: 0 in 'ELSH=12.9999 wght=900.0', 70 in 'ELSH=13.99963 wght=900.0'; reversed: False
    Contour 1 start point differs: 0 in 'ELSH=12.9999 wght=900.0', 70 in 'ELSH=13.99963 wght=900.0'; reversed: False
    Contour 2 start point differs: 0 in 'ELSH=12.9999 wght=900.0', 70 in 'ELSH=13.99963 wght=900.0'; reversed: False
    Contour 3 start point differs: 0 in 'ELSH=12.9999 wght=900.0', 70 in 'ELSH=13.99963 wght=900.0'; reversed: False
  Masters: 'ELGR=2.0 ELSH=12.9999 wght=100.0', 'ELGR=2.0 ELSH=13.99963 wght=100.0':
    Contour 0 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999 wght=100.0', 70 in 'ELGR=2.0 ELSH=13.99963 wght=100.0'; reversed: False
    Contour 1 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999 wght=100.0', 70 in 'ELGR=2.0 ELSH=13.99963 wght=100.0'; reversed: False
    Contour 2 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999 wght=100.0', 70 in 'ELGR=2.0 ELSH=13.99963 wght=100.0'; reversed: False
    Contour 3 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999 wght=100.0', 70 in 'ELGR=2.0 ELSH=13.99963 wght=100.0'; reversed: False
  Masters: 'ELGR=2.0 ELSH=12.9999 wght=900.0', 'ELGR=2.0 ELSH=13.99963 wght=900.0':
    Contour 0 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999 wght=900.0', 70 in 'ELGR=2.0 ELSH=13.99963 wght=900.0'; reversed: False
    Contour 1 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999 wght=900.0', 70 in 'ELGR=2.0 ELSH=13.99963 wght=900.0'; reversed: False
    Contour 2 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999 wght=900.0', 70 in 'ELGR=2.0 ELSH=13.99963 wght=900.0'; reversed: False
    Contour 3 start point differs: 0 in 'ELGR=2.0 ELSH=12.9999 wght=900.0', 70 in 'ELGR=2.0 ELSH=13.99963 wght=900.0'; reversed: False

This report was generated using the fonttools varLib.interpolatable tool. We understand that sometimes the tool generates false-positives. Particularly for more complicated font designs. If you did not find this report useful, please apologize and ignore & close it.

To give feedback about this report, please file an issue or open a discussion at fonttools.

GF review: fontbakery report

This is the Fontbakery report for Handjet :)

  • Tell me when you are done looking at it, and if you updated the font accordingly
  • Maybe ignore the FAIL about the coordinates instances for now, we still have issues with this one.

Fontbakery report

Fontbakery version: 0.7.27

[1] Family checks
🔥 FAIL: Do we have the latest version of FontBakery installed?

[23] Handjet-VF.ttf
🔥 FAIL: Checking file is named canonically.
--- Rationale ---

A font's filename must be composed in the following manner:
<familyname>-<stylename>.ttf

- Nunito-Regular.ttf,
- Oswald-BoldItalic.ttf

Variable fonts must list the axis tags in alphabetical order in square brackets
and separated by commas:

- Roboto[wdth,wght].ttf
- Familyname-Italic[wght].ttf


  • 🔥 FAIL The file 'Handjet-VF.ttf' must be renamed to 'Handjet[SHAP,opsz,wght].ttf' according to the Google Fonts naming policy for variable fonts. [code: bad-varfont-filename]
🔥 FAIL: Checking OS/2 fsType does not impose restrictions.
--- Rationale ---

The fsType in the OS/2 table is a legacy DRM-related field. Fonts in the Google
Fonts collection must have it set to zero (also known as "Installable
Embedding"). This setting indicates that the fonts can be embedded in documents
and permanently installed by applications on remote systems.

More detailed info is available at:
https://docs.microsoft.com/en-us/typography/opentype/spec/os2#fstype


  • 🔥 FAIL In this font fsType is set to 4 meaning that:
    The font may be embedded, and temporarily loaded on the remote system, but documents that use it must not be editable.

No such DRM restrictions can be enabled on the Google Fonts collection, so the fsType field must be set to zero (Installable Embedding) instead. [code: drm]

🔥 FAIL: Substitute copyright, registered and trademark symbols in name table entries.
🔥 FAIL: Check license file has good copyright string.
--- Rationale ---

An OFL.txt file's first line should be the font copyright e.g:
"Copyright 2019 The Montserrat Project Authors
(https://github.com/julietaula/montserrat)"


  • 🔥 FAIL First line in license file does not match expected format: "copyright 2020 handjet project authors ([email protected])"
🔥 FAIL: Check copyright namerecords match license file.
--- Rationale ---

A known licensing description must be provided in the NameID 14 (LICENSE
DESCRIPTION) entries of the name table.

The source of truth for this check (to determine which license is in use) is a
file placed side-by-side to your font project including the licensing terms.

Depending on the chosen license, one of the following string snippets is
expected to be found on the NameID 13 (LICENSE DESCRIPTION) entries of the name
table:
- "This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is available with a FAQ at: https://scripts.sil.org/OFL"
- "Licensed under the Apache License, Version 2.0"
- "Licensed under the Ubuntu Font Licence 1.0."


Currently accepted licenses are Apache or Open Font License.
For a small set of legacy families the Ubuntu Font License may be acceptable as
well.

When in doubt, please choose OFL for new font projects.


  • 🔥 FAIL License file LICENSE.txt exists but NameID 13 (LICENSE DESCRIPTION) value on platform 3 (WINDOWS) is not specified for that. Value was: "IMPORTANT, please read our license agreement at https://rosettatype.com/licence" Must be changed to "Licensed under the Apache License, Version 2.0" [code: wrong]
🔥 FAIL: Is the Grid-fitting and Scan-conversion Procedure ('gasp') table set to optimize rendering?
--- Rationale ---

Traditionally version 0 'gasp' tables were set so that font sizes below 8 ppem
had no grid fitting but did have antialiasing. From 9-16 ppem, just grid
fitting. And fonts above 17ppem had both antialiasing and grid fitting toggled
on. The use of accelerated graphics cards and higher resolution screens make
this approach obsolete. Microsoft's DirectWrite pushed this even further with
much improved rendering built into the OS and apps.

In this scenario it makes sense to simply toggle all 4 flags ON for all font
sizes.


  • 🔥 FAIL Font is missing the 'gasp' table. Try exporting the font with autohinting enabled.
    If you are dealing with an unhinted font, it can be fixed by running the fonts through the command 'gftools fix-nonhinting'
    GFTools is available at https://pypi.org/project/gftools/ [code: lacks-gasp]
🔥 FAIL: Are there non-ASCII characters in ASCII-only NAME table entries?
--- Rationale ---

The OpenType spec requires ASCII for the POSTSCRIPT_NAME (nameID 6).

For COPYRIGHT_NOTICE (nameID 0) ASCII is required because that string should be
the same in CFF fonts which also have this requirement in the OpenType spec.

Note:
A common place where we find non-ASCII strings is on name table entries with
NameID > 18, which are expressly for localising the ASCII-only IDs into Hindi /
Arabic / etc.


  • 🔥 FAIL Bad string at [nameID 0, 'utf_16_be']: 'b'Copyright © 2018 by David Brezina. All rights reserved.'' [code: bad-string]
  • 🔥 FAIL There are 1 strings containing non-ASCII characters in the ASCII-only NAME table entries. [code: non-ascii-strings]
🔥 FAIL: Copyright notices match canonical pattern in fonts
  • com.google.fonts/check/font_copyright

  • 🔥 FAIL Name Table entry: Copyright notices should match a pattern similar to: "Copyright 2019 The Familyname Project Authors (git url)"
    But instead we have got:
    "Copyright © 2018 by David Brezina. All rights reserved." [code: bad-notice-format]

🔥 FAIL: Font enables smart dropout control in "prep" table instructions?
--- Rationale ---

This setup is meant to ensure consistent rendering quality for fonts across all
devices (with different rendering/hinting capabilities).

Below is the snippet of instructions we expect to see in the fonts:
B8 01 FF    PUSHW 0x01FF
85          SCANCTRL (unconditinally turn on
                      dropout control mode)
B0 04       PUSHB 0x04
8D          SCANTYPE (enable smart dropout control)

"Smart dropout control" means activating rules 1, 2 and 5:
Rule 1: If a pixel's center falls within the glyph outline,
        that pixel is turned on.
Rule 2: If a contour falls exactly on a pixel's center,
        that pixel is turned on.
Rule 5: If a scan line between two adjacent pixel centers
        (either vertical or horizontal) is intersected
        by both an on-Transition contour and an off-Transition
        contour and neither of the pixels was already turned on
        by rules 1 and 2, turn on the pixel which is closer to
        the midpoint between the on-Transition contour and
        off-Transition contour. This is "Smart" dropout control.

For more detailed info (such as other rules not enabled in this snippet),
please refer to the TrueType Instruction Set documentation.


  • 🔥 FAIL The 'prep' table does not contain TrueType instructions enabling smart dropout control. To fix, export the font with autohinting enabled, or run ttfautohint on the font, or run the gftools fix-nonhinting script. [code: lacks-smart-dropout]
🔥 FAIL: Variable font weight coordinates must be multiples of 100.
--- Rationale ---

The named instances on the weight axis of a variable font must have coordinates
that are multiples of 100 on the design space.


  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
  • 🔥 FAIL Found a variable font instance with 'wght'=350.0. This should instead be a multiple of 100. [code: bad-coordinate]
🔥 FAIL: Check variable font instances have correct coordinate values
  • com.google.fonts/check/varfont_instance_coordinates

  • 🔥 FAIL Instance "Extralight Triangle" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Square" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Lozenge" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Rectangle" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Rounded Square" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Circle" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Flower" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Star" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Spindle" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extralight Heart" wght value is "200.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Triangle" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Square" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Lozenge" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Rectangle" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Rounded Square" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Circle" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Flower" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Star" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Spindle" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Light Heart" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Triangle" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Square" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Lozenge" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Rectangle" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Rounded Square" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Circle" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Flower" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Star" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Spindle" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Semibold Heart" wght value is "600.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Triangle" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Square" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Lozenge" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Rectangle" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Rounded Square" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Circle" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Flower" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Star" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Spindle" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Instance "Extrabold Heart" wght value is "800.0". It should be "400.0" [code: bad-coordinate]

  • 🔥 FAIL Check has either failed or produced a warning. See our wip spec for further info https://gist.github.com/m4rc1e/8f4c4498519e8a36cd54e16a004275cb

🔥 FAIL: Check variable font instances have correct names
  • com.google.fonts/check/varfont_instance_names

  • 🔥 FAIL Instance "Extralight Triangle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Square": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Lozenge": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Rectangle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Rounded Square": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Circle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Flower": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Star": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Spindle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extralight Heart": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Triangle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Square": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Lozenge": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Rectangle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Rounded Square": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Circle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Flower": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Star": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Spindle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Semibold Heart": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Triangle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Square": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Lozenge": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Rectangle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Rounded Square": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Circle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Flower": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Star": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Spindle": is missing the following name tokens [wght]

  • 🔥 FAIL Instance "Extrabold Heart": is missing the following name tokens [wght]

  • 🔥 FAIL Check has either failed or produced a warning. See our wip spec for further info https://gist.github.com/m4rc1e/8f4c4498519e8a36cd54e16a004275cb [code: bad-instance-names]

  • WARN Instance "Extralight Triangle": contains the following unparsable tokens "['Extralight', 'Triangle']"

  • WARN Instance "Extralight Triangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Square": contains the following unparsable tokens "['Extralight', 'Square']"

  • WARN Instance "Extralight Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Lozenge": contains the following unparsable tokens "['Extralight', 'Lozenge']"

  • WARN Instance "Extralight Lozenge": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Rectangle": contains the following unparsable tokens "['Extralight', 'Rectangle']"

  • WARN Instance "Extralight Rectangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Rounded Square": contains the following unparsable tokens "['Extralight', 'Rounded', 'Square']"

  • WARN Instance "Extralight Rounded Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Circle": contains the following unparsable tokens "['Extralight', 'Circle']"

  • WARN Instance "Extralight Circle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Flower": contains the following unparsable tokens "['Extralight', 'Flower']"

  • WARN Instance "Extralight Flower": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Star": contains the following unparsable tokens "['Extralight', 'Star']"

  • WARN Instance "Extralight Star": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Spindle": contains the following unparsable tokens "['Extralight', 'Spindle']"

  • WARN Instance "Extralight Spindle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extralight Heart": contains the following unparsable tokens "['Extralight', 'Heart']"

  • WARN Instance "Extralight Heart": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Triangle": contains the following unparsable tokens "['Triangle']"

  • WARN Instance "Light Triangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Square": contains the following unparsable tokens "['Square']"

  • WARN Instance "Light Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Lozenge": contains the following unparsable tokens "['Lozenge']"

  • WARN Instance "Light Lozenge": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Rectangle": contains the following unparsable tokens "['Rectangle']"

  • WARN Instance "Light Rectangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Rounded Square": contains the following unparsable tokens "['Rounded', 'Square']"

  • WARN Instance "Light Rounded Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Circle": contains the following unparsable tokens "['Circle']"

  • WARN Instance "Light Circle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Flower": contains the following unparsable tokens "['Flower']"

  • WARN Instance "Light Flower": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Star": contains the following unparsable tokens "['Star']"

  • WARN Instance "Light Star": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Spindle": contains the following unparsable tokens "['Spindle']"

  • WARN Instance "Light Spindle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Light Heart": contains the following unparsable tokens "['Heart']"

  • WARN Instance "Light Heart": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Triangle": contains the following unparsable tokens "['Triangle']"

  • WARN Instance "Regular Triangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Square": contains the following unparsable tokens "['Square']"

  • WARN Instance "Regular Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Lozenge": contains the following unparsable tokens "['Lozenge']"

  • WARN Instance "Regular Lozenge": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Rectangle": contains the following unparsable tokens "['Rectangle']"

  • WARN Instance "Regular Rectangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Rounded Square": contains the following unparsable tokens "['Rounded', 'Square']"

  • WARN Instance "Regular Rounded Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Circle": contains the following unparsable tokens "['Circle']"

  • WARN Instance "Regular Circle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Flower": contains the following unparsable tokens "['Flower']"

  • WARN Instance "Regular Flower": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Star": contains the following unparsable tokens "['Star']"

  • WARN Instance "Regular Star": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Spindle": contains the following unparsable tokens "['Spindle']"

  • WARN Instance "Regular Spindle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Regular Heart": contains the following unparsable tokens "['Heart']"

  • WARN Instance "Regular Heart": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Triangle": contains the following unparsable tokens "['Triangle']"

  • WARN Instance "Medium Triangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Square": contains the following unparsable tokens "['Square']"

  • WARN Instance "Medium Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Lozenge": contains the following unparsable tokens "['Lozenge']"

  • WARN Instance "Medium Lozenge": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Rectangle": contains the following unparsable tokens "['Rectangle']"

  • WARN Instance "Medium Rectangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Rounded Square": contains the following unparsable tokens "['Rounded', 'Square']"

  • WARN Instance "Medium Rounded Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Circle": contains the following unparsable tokens "['Circle']"

  • WARN Instance "Medium Circle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Flower": contains the following unparsable tokens "['Flower']"

  • WARN Instance "Medium Flower": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Star": contains the following unparsable tokens "['Star']"

  • WARN Instance "Medium Star": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Spindle": contains the following unparsable tokens "['Spindle']"

  • WARN Instance "Medium Spindle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Medium Heart": contains the following unparsable tokens "['Heart']"

  • WARN Instance "Medium Heart": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Triangle": contains the following unparsable tokens "['Semibold', 'Triangle']"

  • WARN Instance "Semibold Triangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Square": contains the following unparsable tokens "['Semibold', 'Square']"

  • WARN Instance "Semibold Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Lozenge": contains the following unparsable tokens "['Semibold', 'Lozenge']"

  • WARN Instance "Semibold Lozenge": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Rectangle": contains the following unparsable tokens "['Semibold', 'Rectangle']"

  • WARN Instance "Semibold Rectangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Rounded Square": contains the following unparsable tokens "['Semibold', 'Rounded', 'Square']"

  • WARN Instance "Semibold Rounded Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Circle": contains the following unparsable tokens "['Semibold', 'Circle']"

  • WARN Instance "Semibold Circle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Flower": contains the following unparsable tokens "['Semibold', 'Flower']"

  • WARN Instance "Semibold Flower": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Star": contains the following unparsable tokens "['Semibold', 'Star']"

  • WARN Instance "Semibold Star": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Spindle": contains the following unparsable tokens "['Semibold', 'Spindle']"

  • WARN Instance "Semibold Spindle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Semibold Heart": contains the following unparsable tokens "['Semibold', 'Heart']"

  • WARN Instance "Semibold Heart": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Triangle": contains the following unparsable tokens "['Triangle']"

  • WARN Instance "Bold Triangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Square": contains the following unparsable tokens "['Square']"

  • WARN Instance "Bold Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Lozenge": contains the following unparsable tokens "['Lozenge']"

  • WARN Instance "Bold Lozenge": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Rectangle": contains the following unparsable tokens "['Rectangle']"

  • WARN Instance "Bold Rectangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Rounded Square": contains the following unparsable tokens "['Rounded', 'Square']"

  • WARN Instance "Bold Rounded Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Circle": contains the following unparsable tokens "['Circle']"

  • WARN Instance "Bold Circle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Flower": contains the following unparsable tokens "['Flower']"

  • WARN Instance "Bold Flower": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Star": contains the following unparsable tokens "['Star']"

  • WARN Instance "Bold Star": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Spindle": contains the following unparsable tokens "['Spindle']"

  • WARN Instance "Bold Spindle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Bold Heart": contains the following unparsable tokens "['Heart']"

  • WARN Instance "Bold Heart": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Triangle": contains the following unparsable tokens "['Extrabold', 'Triangle']"

  • WARN Instance "Extrabold Triangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Square": contains the following unparsable tokens "['Extrabold', 'Square']"

  • WARN Instance "Extrabold Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Lozenge": contains the following unparsable tokens "['Extrabold', 'Lozenge']"

  • WARN Instance "Extrabold Lozenge": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Rectangle": contains the following unparsable tokens "['Extrabold', 'Rectangle']"

  • WARN Instance "Extrabold Rectangle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Rounded Square": contains the following unparsable tokens "['Extrabold', 'Rounded', 'Square']"

  • WARN Instance "Extrabold Rounded Square": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Circle": contains the following unparsable tokens "['Extrabold', 'Circle']"

  • WARN Instance "Extrabold Circle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Flower": contains the following unparsable tokens "['Extrabold', 'Flower']"

  • WARN Instance "Extrabold Flower": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Star": contains the following unparsable tokens "['Extrabold', 'Star']"

  • WARN Instance "Extrabold Star": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Spindle": contains the following unparsable tokens "['Extrabold', 'Spindle']"

  • WARN Instance "Extrabold Spindle": cannot determine instance name due to unparsable tokens

  • WARN Instance "Extrabold Heart": contains the following unparsable tokens "['Extrabold', 'Heart']"

  • WARN Instance "Extrabold Heart": cannot determine instance name due to unparsable tokens

🔥 FAIL: Ensure VFs do not contain opsz or ital axes.
--- Rationale ---

The 'ital' axis is not supported yet in Google Chrome. The 'opsz' axis also has
patchy support.

For the time being, we need to ensure that VFs do not contain either of these
axes. Once browser support is better, we can deprecate this check.

For more info regarding ital and opsz browser support, see:
https://arrowtype.github.io/vf-slnt-test/


  • 🔥 FAIL The "opsz" axis is not yet well supported on Google Chrome. [code: unsupported-opsz]
🔥 FAIL: Name table records must not have trailing spaces.
🔥 FAIL: Checking OS/2 usWinAscent & usWinDescent.
--- Rationale ---

A font's winAscent and winDescent values should be greater than the head
table's yMax, abs(yMin) values. If they are less than these values, clipping
can occur on Windows platforms
(https://github.com/RedHatBrand/Overpass/issues/33).

If the font includes tall/deep writing systems such as Arabic or Devanagari,
the winAscent and winDescent can be greater than the yMax and abs(yMin) to
accommodate vowel marks.

When the win Metrics are significantly greater than the upm, the linespacing
can appear too loose. To counteract this, enabling the OS/2 fsSelection bit 7
(Use_Typo_Metrics), will force Windows to use the OS/2 typo values instead.
This means the font developer can control the linespacing with the typo values,
whilst avoiding clipping by setting the win values to values greater than the
yMax and abs(yMin).


  • 🔥 FAIL OS/2.usWinAscent value should be equal or greater than 4920, but got 4320 instead [code: ascent]
🔥 FAIL: Does the font have a DSIG table?
--- Rationale ---

Microsoft Office 2013 and below products expect fonts to have a digital
signature declared in a DSIG table in order to implement OpenType features. The
EOL date for Microsoft Office 2013 products is 4/11/2023. This issue does not
impact Microsoft Office 2016 and above products. 

This checks verifies that this signature is available in the font.

A fake signature is enough to address this issue. If needed, a dummy table can
be added to the font with the `gftools fix-dsig` script available at
https://github.com/googlefonts/gftools

Reference: https://github.com/googlefonts/fontbakery/issues/1845


  • 🔥 FAIL This font lacks a digital signature (DSIG table). Some applications may require one (even if only a dummy placeholder) in order to work properly. You can add a DSIG table by running the gftools fix-dsig script. [code: lacks-signature]
🔥 FAIL: Check glyphs do not have duplicate components which have the same x,y coordinates.
--- Rationale ---

There has 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.


  • 🔥 FAIL The following glyphs have duplicate components which have the same x,y coordinates:
    • {'glyph': 'a.emphasis', 'component': 'pixel', 'x': 120, 'y': 2160}
    • {'glyph': 'a.emphasis', 'component': 'pixel', 'x': 240, 'y': 2400} and {'glyph': 'a.emphasis', 'component': 'pixel', 'x': 360, 'y': 2640} [code: found-duplicates]
WARN: Stricter unitsPerEm criteria for Google Fonts.
--- Rationale ---

Even though the OpenType spec allows unitsPerEm to be any value between 16 and
16384, the Google Fonts project aims at a narrower set of reasonable values.

The spec suggests usage of powers of two in order to get some performance
improvements on legacy renderers, so those values are acceptable.

But value of 500 or 1000 are also acceptable, with the added benefit that it
makes upm math easier for designers, while the performance hit of not using a
power of two is most likely negligible nowadays.

Another acceptable value is 2000. Since TT outlines are all integers (no
floats), then instances in a VF suffer rounding compromises, and therefore a
1000 UPM is too small because it forces too many such compromises.

Therefore 2000 is a good 'new VF standard', because 2000 is a simple 2x
conversion from existing fonts drawn on a 1000 UPM, and anyone who knows what
10 units can do for 1000 UPM will know what 20 units does too.

Additionally, values above 2048 would result in filesize increases with not
much added benefit.


  • WARN Font em size (unitsPerEm) is 4080 which may be too large (causing filesize bloat), unless you are sure that the detail level in this font requires that much precision. [code: large-value]
WARN: Are there caret positions declared for every ligature?
--- Rationale ---

All ligatures in a font must have corresponding caret (text cursor) positions
defined in the GDEF table, otherwhise, users may experience issues with caret
rendering.


  • WARN This font lacks caret positioning values for these ligature glyphs:

    • a.men_a.ken
    • hbVav_hbVav
    • a.men_a.now
    • a.men_a.xeh
    • a.men_a.eh
    • a.men_a.ech
    • hbYod_hbYod
    • a.men_a.ini
    • idieresis_idieresis
    • hbVav_hbYod

    [code: incomplete-caret-pos-data]

WARN: Is there kerning info for non-ligated sequences?
--- Rationale ---

Fonts with ligatures should have kerning on the corresponding non-ligated
sequences for text where ligatures aren't used (eg
https://github.com/impallari/Raleway/issues/14).


  • WARN GPOS table lacks kerning info for the following non-ligated sequences:

    • idieresis + idieresis
    • a.men + a.ech
    • a.ech + a.eh
    • a.eh + a.ini
    • a.ini + a.ken
    • a.ken + a.now
    • a.now + a.xeh
    • hbVav + hbVav
    • hbVav + hbYod
    • hbYod + hbYod

    [code: lacks-kern-info]

WARN: Glyph names are all valid?
--- Rationale ---

Microsoft's recommendations for OpenType Fonts states the following:

'NOTE: The PostScript glyph name must be no longer than 31 characters, include
only uppercase or lowercase English letters, European digits, the period or the
underscore, i.e. from the set [A-Za-z0-9_.] and should start with a letter,
except the special glyph name ".notdef" which starts with a period.'

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


In practice, though, particularly in modern environments, glyph names can be as
long as 63 characters.
According to the "Adobe Glyph List Specification" available at:

https://github.com/adobe-type-tools/agl-specification


  • WARN The following glyph names may be too long for some legacy systems which may expect a maximum 31-char length limit:
    arLam.init_arAlifHamzabelow.fina, arLam.medi_arAlifHamzabelow.fina, arLam.init_arLam.medi_arHeh.fina, arHehDoachashmi.init_arYehBarri.fina and arHehDoachashmi.medi_arYehBarri.fina [code: legacy-long-names]
WARN: Checking unitsPerEm value is reasonable.
--- Rationale ---

According to the OpenType spec:

The value of unitsPerEm at the head table must be a value between 16 and 16384.
Any value in this range is valid.

In fonts that have TrueType outlines, a power of 2 is recommended as this
allows performance optimizations in some rasterizers.

But 1000 is a commonly used value. And 2000 may become increasingly more common
on Variable Fonts.


  • WARN In order to optimize performance on some legacy renderers, the value of unitsPerEm at the head table should idealy be a power of between 16 to 16384. And values of 1000 and 2000 are also common and may be just fine as well. But we got 4080 instead. [code: suboptimal]
WARN: Check mark characters are in GDEF mark glyph class
--- Rationale ---

Mark characters should be in the GDEF mark glyph class.


  • WARN The following mark characters could be in the GDEF mark glyph class:
    U+0324, U+0335, U+0344, U+05B0, U+05B1, U+05B2, U+05B3, U+05B4, U+05B5, U+05B6, U+05B7, U+05B8, U+05B9, U+05BA, U+05BB, U+05BC, U+05BF, U+05C1, U+05C2, U+05C7, U+0610, U+064B, U+064C, U+064D, U+064E, U+064F, U+0650, U+0651, U+0652, U+0653, U+0654, U+0655, U+0656, U+0658 and U+0670 [code: mark-chars]

Summary

💔 ERROR 🔥 FAIL ⚠ WARN 💤 SKIP ℹ INFO 🍞 PASS 🔎 DEBUG
0 18 6 78 6 67 0
0% 10% 3% 45% 3% 38% 0%

Note: The following loglevels were omitted in this report:

  • SKIP
  • INFO
  • PASS
  • DEBUG

macOS rendering weirdness

On Chrome Version 84.0 (latest stable) and macOS 10.14.6 (so not latest 10.15) I see weird rendering up to 106 pt, then at 107 pt it resolves itself.

Screen Shot 2020-08-04 at 9 29 05 AM

Screen Shot 2020-08-04 at 9 29 16 AM

Incomplete soft-dotting

Soft dots are only removed from ⟨i⟩ and ⟨j⟩. The following should also lose their dots in the same contexts:

  • U+012F LATIN SMALL LETTER I WITH OGONEK
  • U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
  • U+0458 CYRILLIC SMALL LETTER JE
  • U+1ECB LATIN SMALL LETTER I WITH DOT BELOW

Flag all axes for visibility

Today SHAP and GRID are flagged as hidden, but I don't think they should be - the heart of the project is playing with those 2 sliders :)

Does not work in Adobe products

No matter what weight I choose and no matter what settings I choose, the letters simply do not change.
image
image

They always look like this:
image

I saw in the readme here on GitHub that "unpredictable, yet beautiful and somewhat amusing, rendering errors" are possible in Adobe products, but that would be an improvement! Instead, absolutely nothing changes. I have tried both the font file on fonts.google.com as well as the newest font file here on GitHub.

Decomposing Yiddish digraphs makes them wider

The Yiddish digraphs U+05F0..U+05F2 are decomposed. The digraph glyphs (hbVav_hbVav etc.) are narrower than the pairs they are decomposed into (hbVav hbVav etc.). For U+05F0 and U+05F1, this is harmless though pointless, but it makes a vowelless U+05F2 HEBREW LIGATURE YIDDISH DOUBLE YOD wider than it is with patah, which may have been unintentional. Here is <U+05F2, U+05F2, U+05B7>:
ײײַ

I recommend not decomposing U+05F0..U+05F2.

Weight axis value for Light should be 300

#1 (comment) reports

🔥 FAIL Instance "Light Triangle" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Square" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Lozenge" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Rectangle" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Rounded Square" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Circle" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Flower" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Star" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Spindle" wght value is "350.0". It should be "300.0" [code: bad-coordinate]
🔥 FAIL Instance "Light Heart" wght value is "350.0". It should be "300.0" [code: bad-coordinate]

Indeed, a weight style particle of Light should have a weight value of 300

let's try with flattening nested component

It's been a while that fontmake has the --flatten-components argument which flatten the nested components, and we think it may fix the rendering issue in MacOS. @kontur do you think you can add it to the build script, so I can re-ship the font and check it in GF sandbox if it displays better ?

Why is em size 4080?

Question :)

#1 (comment) reports

⚠ WARN Font em size (unitsPerEm) is 4080 which may be too large (causing filesize bloat), unless you are sure that the detail level in this font requires that much precision. [code: large-value]

I am curious why the value is 4080 and not 4000 or 2000 etc :)

I confirm that 4080 is acceptable for this font

Include combining marks in GDEF table

In #1 (comment) @m4rc1e said

the combining marks are not in the gdef table.

This means they probably don't have anchors or they're not named correctly.

If we don't have these marks in the table, users won't be able to form more exotic base+mark combos.

@RosaWagner noted

All the marks that should be in the GDEF table have 0-width and anchors in the source files. Maybe the naming is not the actual nice-naming from Glyphs though.

and @MrBrezina replied

Please, clarify if you want us to rename the mark glyphs to some other names. But I do not think the problem is there, though. Fontmake shouls not be relying on glyph names. Maybe some Glyph Info is missing in the Glyphs source?

Indeed, I believe this can be solved with either a custom GlyphsData.xml file, or, there is some way to include that data as a Custom Parameter Dictionary within the .glyphs file which fontmake can consume.

Missing Arabic positional forms

In version 2.000, U+066F ARABIC LETTER DOTLESS QAF, U+06BA ARABIC LETTER NOON GHUNNA, and U+06C2 ARABIC LETTER HEH GOAL WITH HAMZA ABOVE are missing their initial and medial forms, and U+0760 ARABIC LETTER FEH WITH TWO DOTS BELOW is missing its initial, medial, and final forms.
ٯـ ـٯـ ـٯ␤ںـ ـںـ ـں␤ۂـ ـۂـ ـۂ␤ݠـ ـݠـ ـݠ␤

Axes tag modification

Hi @kontur @MrBrezina

We are in process of registering the axes to onboard the complete VF.

At GF they decided on making the axes tag a bit clearer: Element shape would become ELSP (instead of ESHP), and Element grid would become ELGR (instead of EGRD).

Improve README

Please add a nice .gif (drawbot/etc source files) to /docs that shows off the face, and inline it near the top of README

Also, please add 1-3 short paragraphs of description text about the family, which I can use on the fonts.google.com specimen page (you can make a DESCRIPTION.en_us.html file directly, if you wish).

I am curious - what is the meaning and origin of the family name?

Recalibrate GRID

Currently GRID's range of 10..100 and key values of 10, 50, 100 doesn't make sense to me.

I propose to recalibrate this as 1..3 with -2 levels of precision (as described in https://github.com/google/fonts/tree/master/axisregistry) so that the value of the axis at 1.00 gives 1 grid, element 2.00 gives 2x2, and 3.00 gives 3x3.

Alternatives I thought about are

  • 1..9 for the total number of elements - but I think int values that map meaningfully, and minimizing the in-between space

  • 1, 50, 100 as a kind of percent

Screen Shot 2020-08-04 at 10 17 57 AM

Screen Shot 2020-08-04 at 10 17 46 AM

Screen Shot 2020-08-04 at 10 17 16 AM

Wrong glyph for U+05C7 HEBREW POINT QAMATS QATAN

In this font, U+05C7 HEBREW POINT QAMATS QATAN looks identical to U+05B8 HEBREW POINT QAMATS. According to L2/04-150, U+05C7 “is usually presented with a longer vertical; it can also be represented simply with a larger glyph, and in one case we have found the horizontal lengthened and bent.”

Recalibrating SHAP and renaming

@MrBrezina I'd like to request a recalibration of the axis, so that SHAP's default value is 400 (plain squares with no gaps.) Is this a trivial change to the .designSpace file?

@RosaWagner if David agrees, and it is trivial, perhaps you could just make this happen? :)

Axes order: wght should be last

wght axis should be ordered last in the axis order in the FVAR table. For the other 2, it is according to what makes the most sense to you, otherwise alphabetical order.

U+05BA HEBREW POINT HOLAM HASER FOR VAV is positioned wrong

When applied to U+05D5 HEBREW LETTER VAV, U+05BA HEBREW POINT HOLAM HASER FOR VAV is positioned identically to U+05B9 HEBREW POINT HOLAM. U+05BA should go above and to the left. (On other letters, U+05B9 goes above and to the left and U+05BA is invalid.)
וֹוֺ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.