Worklog, Signika

152 views
Skip to first unread message

Stephen Nixon

unread,
Oct 26, 2018, 10:59:04 AM10/26/18
to Google Fonts Discussions
I have been working to make Signika and Signika Negative into a variable font. This typeface was originally started by Anna Giedryś.

For now, my repo is private at the request of the designer.

I will primarily document my work in the repo /docs, so once the repo is public, the most up-to-date progress will be found there. However, I will also post periodic updates here for greater visibility in the community.


Stephen Nixon

unread,
Nov 26, 2018, 3:54:40 PM11/26/18
to Google Fonts Discussions

The Signika repo is currently still private, but here are the experiments and work items I've focused on, so far.


Signika Grade Test

The stylistic axis "grade" refers to changes of font outlines to make type more or less dense, specifically without causing any change to the width of letters. As Mozilla defines it:

The term 'grade' refers to the relative weight or density of the typeface design, but differs from traditional 'weight' in that the physical space the text occupies does not change, so changing the text grade doesn't change the overall layout of the text or elements around it.

— Grade, MDN

I wanted to test out the grades of Signika vs Signika Negative, in their static versions currently-hosted on Google Fonts. These are intended as two grades of the same typeface, but do they actually meet the no-text-reflow criterion of "grades," or are they simply different font weights?

As this test shows, they cause reflow:

Signika vs Signika Negative

This shows that the two versions are, in fact, different weights rather than different grades. Or, at least, they might be called "grades" by some people, but they change letters on both stroke thickness and in character width.

This is consistent with the Glyphs source. It has two masters:

Signika Masters


...and the postive/negative instances are derived from that (here, the Signika Negative Light is an extrapolated -15 weight):


Signika Instances


Potential Action

I'll add the shifted instances as new masters for grade, then write a script to duplicate letter widths from the normal to these Negative masters. I'll try keeping the ratio of spacing the same between left and right sides, to prevent spacing from being worsened by the update.

This will allow a grade axis (GRAD) in the future.


Making a "proper" GRAD Axis

As the previous doc says, a Grade axis should keep widths and prevent reflow. According to Mozilla Dev Network:

The term 'grade' refers to the relative weight or density of the typeface design, but differs from traditional 'weight' in that the physical space the text occupies does not change, so changing the text grade doesn't change the overall layout of the text or elements around it.

—  Grade, MDN

Signika and Signika Negative have a problem: they don't currently share text width, even though they should. This prevents grade from being used in a truly useful way on the web, where the primary function is likely to be making light/dark UI changes a possibility.

Goals

  1. Make a variable Grade axis happen  without
  2. Ideally, make the Grade axis happen with just  onedoable, because the point deltas for grade are so small.

Approach

  1. Taking the  Negative Lightwght value of  -15, and converting it to a master

Light Grade Master Light Master

  1. Using  a glyphs script Light Negative Light

Grade Test

  1. Use a glyphs script (not yet written) to copy kerning values from light to light GRAD master
  2. Generating a VF and testing the result on bold weights

Generating the variable font with both axes

![image-20181019135747417](/Users/stephennixon/Library/Application Support/typora-user-images/image-20181019135747417.png)

At first, the VF that is generating is not including the Grade axis. To fix this, I'm trying a number of things:

  1. Adding a custom parameter in the Font Info

![image-20181019135811568](/Users/stephennixon/Library/Application Support/typora-user-images/image-20181019135811568.png)

  1. Setting masters as:
MasterWeightGrade
Light-GRAD00
Light0100
Bold1000100
Black1350100
  1. Setting all instances to have Grade value of either  0or  100, depending on their normal/negative name

Strangely, so far this is leading FontMake to export a designspace with  GRAD

<axis default="100" maximum="100" minimum="100" name="Grade" tag="GRAD" />
  1. I have edited the  .designspace
<axes>
        <axis default="300" maximum="900" minimum="300" name="Weight" tag="wght">
            <map input="300" output="0" />
            <map input="400" output="291" />
            <map input="600" output="577" />
            <map input="700" output="843" />
            <map input="900" output="1350" />
        </axis>
        <axis default="100" maximum="100" minimum="0" name="Grade" tag="GRAD" />
    </axes>

Changing:

  • wght default 300
  • adding  input="900"
  • setting  GRAD 0
  1. I will temporarily build from  .designspace without instances, because these have  wght values outside of the  minand  max -15).

It builds! There are some issues.signika-grade-slider

Most pressing: the grade axis is so subtle, it barely changes the points in the VF. It's hard to understand why immediately. Is this because...

  • Variable TTFs don't export with floating-point precision? (I don't know whether they do or not)?
  • The inserted "Grade" Light master was somehow incorrectly extrapolated or processed?

Ahhh the  Light static instance has a wght value of  50, while the  Negative Light has a  wghtof  -15. Meanwhile, the VF has a min of  0, so the Grade axis may not have as far it can travel

Next Steps

  •  Lightwght Lightbigger difference between Grade

  •  much

  • axes.

Extrapolate a  much

I've extrapolated a very light Grade instance (-300 weight), then made this a master and copied the Light metrics.

I was having issues exporting from FontMake...

KeyError: 'wght'
AssertionError: ((236, [227, 236, 236, 236]), 'int', '.BaseCount', 'BaseArray', '.BaseArray', 'MarkBasePos', '[0]', 'Lookup', '[2]', 'list', '.Lookup', 'LookupList', '.LookupList', 'GPOS', '.table', 'table_G_P_O_S_')

...so I'm instead trying to export with GlyphsApp's built-in exporter. This helpfully tells me which glyphs are blocking the export, due to "too many inflection points"

image-20181019153053384

The plugin RedArrows is extremely helpful in locating inflection points and other issues.

image-20181019153547586

I also got an error  **The font contains glyphs with duplicate production names:** for  commaaccentcomb and  commaaccent. I disabled  commaaccentcomb for now, to get past this.

Unfortunately, Glyphs export seems to be duplicating the Light GRAD master to make a faulty multiple-master VF, where the Bold Negative corner duplicates the Light Negative corner.

Problem

  • in  a,  G,  @, and resolved  commaaccentcomb and  commaaccent.

Trying with FontMake again

I've set Negative Instances to have weight values matching the positive instances.

However, I'm getting this error from FontMake:

AssertionError: Location for axis 'Weight' (mapped to 250.0) out of range for 'Signika Light-GRAD' [300.0..700.0]

Probably due to the light masters having a value of  0, while the light instances have a weight value of  50.

  • script to set the designspace in the glyphs file to something more "regular" / gridded

It appears that it may not be possible to export a 2-axis variable font with just 3 masters. Here's a relevant GitHub Issue:  https://github.com/googlei18n/fontmake/issues/454#issuecomment-431494121

FontMaking with corners

Because it seems that a 3-master, 2-axis VF may not currently be possible to export, I make this with 4-masters, simply as a proof of concept. The instance values, kerning, and metadata will still be wrong, but it should work at a basic state.

grade proof of concept

FontMaking without corners!

I learned on  this FontMake Issue

I had the grad-min set as the default, rather than the grad-max. The  GRAD default must match the Grade of the main masters on the weight axis.

It's now exporting and is 175kb for the TTF, versus the 206kb that 4 masters produced.

3-master-vf

This seems to be working well:

<axes>
    <axis default="300" maximum="750" minimum="300" name="Weight" tag="wght">
        # (I'll be tweaking these map values more, so they're not final)
        <map input="300" output="0" />
        <map input="400" output="360" />
        <map input="600" output="650" />
        <map input="700" output="920" />
        <map input="750" output="1000" />
    </axis>


    #################

    # this is the critical bit – the default *must* match the GRAD of the two main masters for wght, not the GRAD in the min-grade master

    <axis default="100" maximum="100" minimum="0" name="Grade" tag="GRAD" />

    #################

</axes>

# here are my 3 sources
<sources>
    <source familyname="Signika" filename="Signika-Light-GRAD.ufo" name="Signika Light-GRAD" stylename="Light-GRAD">
        <lib copy="1" />
        <groups copy="1" />
        <features copy="1" />
        <info copy="1" />
        <location>
            <dimension name="Weight" xvalue="0" />
            <dimension name="Grade" xvalue="0" />
        </location>
    </source>
    <source familyname="Signika" filename="Signika-Light.ufo" name="Signika Light" stylename="Light">
        <location>
            <dimension name="Weight" xvalue="0" />
            <dimension name="Grade" xvalue="100" />
        </location>
    </source>
    <source familyname="Signika" filename="Signika-Bold.ufo" name="Signika Bold" stylename="Bold">
        <location>
            <dimension name="Weight" xvalue="1000" />
            <dimension name="Grade" xvalue="100" />
        </location>
    </source>
</sources>

Can it export from a 3-master GlyphsApp source?

I'll delete the "Bold GRAD" master from  sources/experiments/Signika-MM-ext_wght_ext_grad.glyphs, and check if it still exports via FontMake.

Problem with weights:

AssertionError: Location for axis 'Weight' (mapped to 250.0) out of range for 'Signika Light-GRAD' [300.0..700.0]

The Light instances are given a GlyphsApp weight value of  50, while the Light masters have a weight value of  0. Therefore, the instances probably have to change to allow the variable font to export successfully.

Now, this error is happening

AssertionError: Location for axis 'Weight' (mapped to 780.0) out of range for 'Signika Bold' [300.0..700.0]

The Bold instances have a weight values of  920 while the Bold masters have values of  1000. It seems that this is also blocking the export.

Likely, if fonttools and fontmake won't support aligning a variable font to instance values rather than master values, I'll probably have to create a GlyphsApp script that makes masters that match the lightest and boldest instances, then make these into masters, and deletes original masters.

This gets past the Location "out of range" errors, but now cues:

KeyError: 'wght'

I suspect this is due to the generated designspace showing that  0 is the default value for Grade – when I know that  100must be the default for the three-axis master to work. Perhaps, putting the  GRAD=100 masters first in the GlyphsApp source will make this the default Grade value?

Yes! It exports, and the Grade default is indeed  100.

Keeping weights the same

Should we keeping Grades the same? How close should we be?

The original Signika (currently on Google Fonts) have a "Grade" version that doesn't follow the formalized definitions of grade – keeping the same glyph width metrics while changing letter shapes. When this is fixed, whatever Grade versions we make now won't align with old Grade versions. So, we can't keep the new "Grade" the same as the old "Grade." However, should the overall lettershape difference be the same, or different?

Why to keep it the same

  • research / reasoning

Why to change it

Will a higher UPM have less "wobble" in the Grade Axis?

One slightly unfortunate (but probably unimportant) downside of the grade axis is that letters have a very noticeable "wobble" when they're being pulled across their grade range. (As far as I know), this is because the points of contours have to snap to their grid as the letter is interpolated.

Fonts with few Units Per Em (UPM) must round points further when interpolating. This font did have a UPM of 1000, but  Dave Crossland is now convincingly suggesting that Variable Fonts take up a standard of 2000 UPM. Could that help reduce the wobble?

It doesn't seem to change much, at least not when tested in FontView.

1000 UPM:

1000 UPM font with Grade axis

2000 UPM:

2000 UPM font with Grade axis

Fixing export issues

WARNING:glyphsLib.builder.builders.UFOBuilder:Non-existent glyph class public.kern2.hyphen found in kerning rules.
  • build (it's not blocking the VF export, but it will still be worth understanding and getting past)

Dave Crossland

unread,
Nov 26, 2018, 5:01:24 PM11/26/18
to googlefon...@googlegroups.com
Potentially you could make it a custom "Negative" (NEGA) axis and get the 1:1 matching of the original, although I think a 'true' GRAD axis is more functional. 

Stephen Nixon

unread,
Nov 26, 2018, 5:50:33 PM11/26/18
to Google Fonts Discussions
True, that would be a possibility if we want to preserve this exactly. However, after our conversations about Grade, I came away thinking that it would be better to move toward the consensus definition about how "grade" should exist in a typeface. If you're alright with the Negative family changing, I think it might be worth shifting it to a Grade style variation, where horizontal metrics don't change.

I just realized I had made a mistake, early on in looking at Signika. As an update:

Why to change it My first attempt to follow the prior "Grade" shape changes was so subtle, it was barely translating to a variable font. Potentially, if there is a wider range in the Grade axis, it may prove useful in a wider range of contexts.

Update, Nov 26: Actually, I have realized that I was somewhat mistaken. I believe that earlier, I was seeing a comparison between the "Light Negative" instance (weight -15 out of 0–1000) vs the Light master (weight 0 out of 0–1000). However, the actual exported static fonts were "Light Negative" (-15) and default "Light" (50 out of 0–1000). Whereas there are only 0–2 units difference between "Light Negative" and the Light master, there are about 8 units of difference between "Light Negative" and default "Light" instances.

light_neg-vs-light_master.png

light_neg-vs-light_default.png

light_default.png

light_neg.png


still am not quite sure whether I should stick to only this amount of difference for grade. Still, it is much more reasonable now than before, because this is actually a difference that would be visible to a human, whereas I initially (mistakenly) thought it would amount to almost nothing. 

A wider GRAD range does seem like it might allow for more user flexibility, but keeping the current range would stick to the original design, and it may provide more end-user simplicity (if we accept the claim that it is the correct amount of change for negative typesetting). I plan to test it in a simple web page before coming to a conclusion / asking for opinions.




Dave Crossland

unread,
Nov 26, 2018, 6:01:01 PM11/26/18
to googlefon...@googlegroups.com
I think we should keep in mind the engineering goal - to save bytes on the wire - which means if users are mapped from Negative static fonts to named instances in the VF design space, we want to minimize the disruption to them. 

Adding functionality is a different brief, so since static Negative family isn't actually a set of grades, I'm not sure it makes sense right now.  

Stephen Nixon

unread,
Nov 26, 2018, 6:21:06 PM11/26/18
to Google Fonts Discussions
Okay, that is a good point. What may be the right move for a new font isn't necessarily the right move for a format update to an existing font.

Instead of introducing a Grade axis, I'll plan to focus on just making two VFs to replace the existing fonts with minimal-to-no disruption to existing sites. 

Another alternative would be, as you said, making a custom "Negative" axis, but this wouldn't be picked up through conventional CSS properties (font controls excluding font-variation-settings), so it seems less useful.

If we want to make a VF containing a Grade axis in the future (in Signika or in a completely different typeface), I have a few scripts and some information that might help out.

Dave Crossland

unread,
Nov 26, 2018, 6:32:50 PM11/26/18
to googlefon...@googlegroups.com
Hi 

On Mon, Nov 26, 2018 at 4:21 PM Stephen Nixon <ste...@thundernixon.com> wrote:
Okay, that is a good point. What may be the right move for a new font isn't necessarily the right move for a format update to an existing font.

Instead of introducing a Grade axis, I'll plan to focus on just making two VFs to replace the existing fonts with minimal-to-no disruption to existing sites. 

I think the 1st VF that has a Negative axis, so the API team can map the 2nd 'child' family to the primary 'parent' family, is ideal; and then an 2nd VF that is post-processed out of the 1st, with only the Weight axis, which can be part of the 'first wave' of Weight-only families, is good. (We don't want to ship Weight-axis-only VFs for 'child' families because it will make the future mapping more tricky.) 
 
Another alternative would be, as you said, making a custom "Negative" axis, but this wouldn't be picked up through conventional CSS properties (font controls excluding font-variation-settings), so it seems less useful.

I don't follow - all custom axes including "Grade" axes are also not related to CSS? :) 
 
If we want to make a VF containing a Grade axis in the future (in Signika or in a completely different typeface), I have a few scripts and some information that might help out.

Great! I guess TypeDrawers is the best place to post that info. 

I think probably GF will standardize on Grade axes as "GRAD", ranged in 'per mille of em', as per https://github.com/Microsoft/OpenTypeDesignVariationAxisTags/blob/master/Proposals/TypeNetwork_ParametricAxes/ProposalSummary_grad.md :) 

Cheers
Dave 

Stephen Nixon

unread,
Nov 26, 2018, 7:18:13 PM11/26/18
to Google Fonts Discussions
I think the 1st VF that has a Negative axis ... and then an 2nd VF that is post-processed out of the 1st, with only the Weight axis

Okay, thanks for clarifying that, and for specifying the phases. I'll follow these guidelines and make:
  • One VF for future publication with both weight and "Negative" axis (similar to Grade, but with slightly changing glyph widths from the existing interpolation/extrapolation). This will likely require 4 masters to precisely match the existing hosted fonts.

  • Two VFs (Signika, Signika Negative) that contain only a weight axis each, to reflect the existing published child families.

all custom axes including "Grade" axes are also not related to CSS?

They are. I suppose maybe I had the incorrect notion that custom axes weren't going to be supported that soon, and that we were prioritizing properties that devs might set through older properties like font-weight, font-style, and font-stretch. 

I suppose that the custom axis may only have to really be handled by the API team, though, and most end-user web devs won't really have to know that calling font-family: "Signika Negative" is calling the @font-face declaration in the imported CSS that sets a font-variation-settings property (this is my guess at how it will be implemented, anyway – I'd need to make a CSS test myself before being certain it will work as I'm imagining it).

I guess TypeDrawers is the best place to post that info.

It's nothing super formal yet, just a GlyphsApp script to match width metrics between Masters (e.g. if one was inserted from an interpolated Instance), and the process information above and on GitHub. I imagine if people are Googling for the information, they can probably find it in those locations (once the repo is public), correct? In that case, do you think there be much benefit in posting a new thread on TypeDrawers?

Thanks for the clarity in this thread. 
Reply all
Reply to author
Forward
0 new messages