psb1558 / Elstob-font

A variable font for medievalists

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

STAT version

davelab6 opened this issue · comments

STAT version is 1.1, but 4 seems to offer better functionality.

The fvar table has a lot of Named Instances, but it would be better to offer those via STAT v4 and then only have a curated set, say max 20, in fvar, for legacy apps.

I suppose you're talking about STAT format 4 (not version)?

I don't see a way to produce a format 4 STAT table with fontmake. In the script gftools-fix-vf-meta.py, producing a format 4 STAT table is on the "to-do" list, so I suppose it's not doing that yet. (I'm having trouble running it, since it crashes with "KeyError: '18pt'").

Is there another tool that will produce a format 4 STAT table? I'm not sure I'm savvy enough to hand-edit the ttx.

There are currently 24 named instances. Very glad to get a smaller number, but would like some advice concerning which ones to trim (i.e. which are least likely to be useful).

Okay, I've found statmake, which can apparently generate a STAT table with format 4 axis definitions. I'm working through the well-annotated sample StyleSpace file. But I've run across this note:

ATTENTION: Using format 4 axis values bumps the STAT table version from 1.1 to
1.2. At the time of this writing (February 2019), version 1.2 is not supported by
Windows.

Leaving me to wonder if the time is right to go to this format of STAT table. Will it break under Windows, or is it backwards compatible?

statmake runs against the designspace for a font, and it drops any location that doesn't correspond to an instance defined in the designspace file. Thus decoupling the locations in STAT from the instances in fvar is not straightforward. I tried running statmake against a fuller version of the designspace file than that used to generate the font, with partial success: it is dropping the Grade location, even though it is retaining the others. Not sure yet what's goihg ont.

Statmake is also checking against the fvar table and dropping anything it finds that's not an instance there; so my scheme to fool it with a doctored designspace file is foiled again. I know how to fake up a format 4 STAT table now, and merge via ttx, but that would also mean manually adding entries in the name table, and, well, that's looking like quite a tangle--perhaps a thing one might do at the very end of the process. I think the thing to do is to cut back the number of instances, and if a fuller STAT table is wanted, use statmake to create a format 2 table. I'll leave this issue open in case anyone wanders by with a suggestion, but I've spent enough time on it for now.

I am trying out fonttools builder buildStatTable.

Okay, that worked well. Two simple scripts now in the repository, mkromanSTAT.py and mkitalicSTAT.py, replace the STAT table generated by fontmake with a v 1.2 format 4 STAT table. This has all combinations of wght and opsz, plus "Grade" or "Grade Italic" where the "Grade" axis is at its max of 1.

Tested the result in Samsa, which seems happy.

Number of instances is down to 17: ExtraLight, Light, Regular, Medium, SemiBold, Bold, ExtraBold; and then the full range of optical sizes is available only for Regular and Bold weights. No "Grade" instance, as the assumption is that this axis will be accessed more or less exclusively via CSS.

STAT version is 1.1, but 4 seems to offer better functionality.

The fvar table has a lot of Named Instances, but it would be better to offer those via STAT v4 and then only have a curated set, say max 20, in fvar, for legacy apps.

STAT v4?? Or AxisValue format 4? Perhaps it would be better to wait for @davelab6 to clarify his thought (no Google Fonts VF uses AxisValue format 4 yet).

Currently, if I look at version 1.009 of the VFs in the repo, the lack of a nameID 25, and postscriptNameID for the fvar table, prevents fonts from working well in InDesign and Photoshop. It's among other things what gftools fix-vf-meta is supposed to fix.

I looked at gftools-fix-vf-meta.py, but the comment at the top said it worked only for fonts with a single axis, and that's not this one. The good that's come out of the present thread is that I've learned to use fontTools.otlLib.builder, with which I'm confident that I can produce whatever format of STAT table GF wants in an hour or so: see the files sources/mk*py. I read through the TypeDrawers thread on problems with InDesign, and as a result added these lines to the roman script:

ttfont['name'].setName("ElstobRegular", 25, 1, 0, 0)
ttfont['name'].setName("ElstobRegular", 25, 3, 1, 0x409)

and the corresponding lines for italic. I haven't gotten around to the fvar problem, but I don't guess it's going to be too hard to fix. Which I've got to do, because I've (finally) been upgraded to InDesign 15.1.2, and Elstob is still not working!

Dave seems to be pushing hard to expand GF's ability to handle multiple axes and establish new standards for GF fonts; but he also seems to be stretched very thin ...

Yes, I mentioned it on TypeDrawers: InDesign was insanely requesting VFs to be made exactly like Adobe one's (going up to requesting AxisValue format 2), while Illustrator was much more forgiving, and Photoshop in between. InDesign 15.1.12 is like Photoshop on this point, now.

Currently a NamedInstance in your fvar table is like that (in TTX format):

<NamedInstance flags="0x0" subfamilyNameID="260">

For working with InDesign and Photoshop, the same example should be:

<NamedInstance flags="0x0" postscriptNameID="301" subfamilyNameID="260">

And in the name table:

<namerecord nameID="301" platformID="3" platEncID="1" langID="0x409">
      ElstobRoman-6pt
</namerecord>

(for this particular example, nameID 301 = nameID 25 + nameID 260, without space).

I looked at gftools-fix-vf-meta.py, but the comment at the top said it worked only for fonts with a single axis, and that's not this one.

Marc Foley, its author, used it to fix Roboto v3.002, which has two axis (he asked me to check the output results, before publishing the fonts, but I don't know if he released his version of the script).

Ah, the version has been published, but you're right, you can't use it for multiples axis:
googlefonts/gftools@6bb2264

For variable fonts with multiple axes, write a python script which
uses fontTools.otlLib.builder.buildStatTable e.g
https://github.com/googlefonts/literata/blob/master/sources/gen_stat.py

When I can, I'll try writing a script that will iterate through the namedInstances building the postscriptNames. So the rule should be: nameID 25 + "-" + subfamilyNameID with any spaces stripped out?

So, e.g., where subfamilyNameID is "6pt Bold," postscriptName should be "ElstobRegular-6ptBold"?

So, e.g., where subfamilyNameID is "6pt Bold," postscriptName should be "ElstobRegular-6ptBold"?

Yes, exactly. It will be a bit trickier for italics, as it would not be very clean (although fundamentally not incorrect) to repeat "Italic" in the name, so not "ElstobItalic-6ptBoldItalic", but rather "ElstobItalic-6ptBold".

Yes. Thanks for the tip about the italic. Which "Italic" to omit from the name is exactly the kind of question that ties me up in knots.

Where the subfamilyName is "Italic," what should the postscriptName be? I'm supposing it has to be matched to a postscriptName in the roman font. So should it be ElstobItalic, ElstobItalic-Italic, ElstobItalic-Regular?

The most important is the difference of the part before the hyphen, and a hyphen is needed. So: ElstobItalic-Regular.

It's easier to create when you have AxisValues of format 1, 2 or 3: with these formats, you must not mix the names of the axes (as we do for the fvar table): no AxisValue should be call "Axis 1 Axis 2", like "Condensed Bold" or "Bold Italic", because it's up to a STAT-based UI (like Samsa https://lorp.github.io/samsa/src/samsa-gui.html — you can try the result of a STAT table on this page) to aggregate styles (while NamedInstance have aggregated names).

So, with these formats, you have entries in the name table that will have only one style name, per axis ("Condensed", "Expanded", "Light", "SemiBold", "Regular", " Roman "," Italic " — this is also why using the name" Roman" distinguishes it from other "Regular"). And it is thus easier to compose the entry of the name table corresponding to the postscriptNameID.

To be more concrete, you can look at how Roboto VF v3.002 https://github.com/google/fonts/tree/master/apache/roboto is made: it works perfectly in InDesign or Samsa.

I added the postscriptNames with these fragments of code (having changed nameID 25 in the roman from ElstobRegular to ElstobRoman:

for inst in ttfont['fvar'].instances:
    subfamilyName = ttfont['name'].getName(inst.subfamilyNameID,1,0,0).toUnicode().replace(" ","")
    newID = ttfont['name'].addName("ElstobRoman" + "-" + subfamilyName)
    inst.postscriptNameID = newID

for inst in ttfont['fvar'].instances:
    subfamilyName = ttfont['name'].getName(inst.subfamilyNameID,1,0,0).toUnicode().replace(" Italic","").replace(" ","")
    if subfamilyName == "Italic":
        subfamilyName = "Regular"
    newID = ttfont['name'].addName("ElstobItalic" + "-" + subfamilyName)
    inst.postscriptNameID = newID

Which seems to work fine, giving me these postscriptNames (to select a sample):

ElstobRoman-Regular, ElstobItalic-Regular
ElstobRoman-6pt, ElstobItalic-6pt
ElstobRoman-ExtraLight, ElstobItalic-ExtraLight
ElstobRoman-6ptBold, ElstobItalic-6ptBold
etc.

which seems to agree well enough with the usage of Roboto and SourceSerif. But it's still not working in InDesign (fine in Illustrator and PhotoShop):
InDesign_problem
leading me to wonder if the problem now lies with the format 4 STAT table rather than my names.

I also wonder if it's worth going to a lot of trouble to get this font working in InDesign when the fact that it works perfectly in every other app (including Samsa) seems to indicate that the handling of variable fonts in InDesign (which only added the capability a few months ago) is very far from mature.

The InDesign team needs time to get its act together. They should probably spend some of that time having a little talk with the Illustrator team.

I'll drop the current variable fonts (with these changes) into the fonts/ttf folder of the repository.

I'll drop the current variable fonts (with these changes) into the fonts/ttf folder of the repository.

Your VFs seems perfectly fine, indeed. 😀

leading me to wonder if the problem now lies with the format 4 STAT table rather than my names.

Yes. Previous versions of InDesign 2020 only correctly worked with VFs done "Adobe style" (nameID 25 + postscriptNameID in fvar + AxisValue format 2). Version 15.1.12 seems to accept AxisValue format 1 and 3. I wouldn't be surprised if it doesn't accept Format 4. And likewise, I wouldn't be surprised if your fonts, made in Format 1, work (that's why I have doubts about Dave's exact request).

The InDesign team needs time to get its act together. They should probably spend some of that time having a little talk with the Illustrator team.

I agree!

Thanks for having a look! I may try out format 2 or 3 when I get a little extra time; but given that the InDesign programmers are working on variable font handling now, an equally valid approach may be to wait and see what happens a few versions down the road.

Taking a closer look: an Italic axis is missing.

I had an italic axis in both faces, but fontmake dropped it, so I figured it wasn't wanted. Roboto has an italic axis in STAT but not in fvar: why is that okay?

I've added an italic axis to the STAT table. It doesn't fix the problem with InDesign, but it seems worth having.

I had an italic axis in both faces, but fontmake dropped it, so I figured it wasn't wanted. Roboto has an italic axis in STAT but not in fvar: why is that okay?

The two tables work differently. fvar dates back to TrueType GX from Mac OS 8 (still used in Apple Skia, without a STAT table).

I quickly did a "proof of concept" with AxisValue in format 2 (to be on the safe side, but it could work with format 1 and 3), rather crude (we would have to clean up the name table, and a few other things) but it was to show that it works: the attached files work in InDesign.

Note that the STAT table is much simpler like this (and would be even simpler with format 1).

Elstob-format2.zip

Oh, this is so excellent! I was just working on this and had a ton of questions which your example is answering. So many thanks!

What is the advantage of format2 over format1? Are there apps that actually make use of the rangeValues?

Apart from Samsa, no app offers a STAT-based UI (it might come, and it's a bit expected, but for now there isn't one).

In this thread google/fonts#2391, John Hudson intervened to discuss Format 2. The discussion is interesting (with Marc, we continued the discussion elsewhere, and he was finally persuaded to adopt Format 2 — at the speed that InDesign bugs are fixed, it was perhaps better).

I can scarcely believe this, but the font is now working in InDesign 15.1.2, with one small glitch: when the "Grade" slider is all the way to the right, the outlines snap back to the zero position (if that makes any sense).

Thanks for the link to the discussion of STAT in Google Fonts. Some of it went over my head, but I got the gist, I think, and got the very concrete fact that I should have included a format 3 AxisValue for Regular Weight. Testing in Samsa, I see the point of the format 1 or 2 AxisValue in a way I didn't before: users can (if apps cooperate) get a very clean interface, selecting from short lists of axis values instead of long jumbles of instances.

Since the STAT tables for roman and italic are mostly the same, I've combined my scripts for generating STAT and adjusting names into one. I've pushed all changes to the repo.

Note that if you include a format 3 for Regular (to make the link with Bold), it will be in addition to format 2, which doesn't have this property (this need to duplicate the same AxisValue, in format 2 and in format 3 , is one of the drawbacks of format 2, format 1 doesn't have this drawback since an AxisValue in format 3 completely replaces an AxisValue in format 1).

Yes, that's what I've got:

commonWeightDict = dict(
    tag="wght",
    name="Weight",
    values=[
        dict(nominalValue=200, name="ExtraLight", rangeMinValue=200, rangeMaxValue=250),
        dict(nominalValue=300, name="Light", rangeMinValue=250, rangeMaxValue=350),
        dict(nominalValue=400, name="Regular", flags=0x2, rangeMinValue=350, rangeMaxValue=450),
        dict(nominalValue=500, name="Medium", rangeMinValue=450, rangeMaxValue=550),
        dict(nominalValue=600, name="SemiBold", rangeMinValue=550, rangeMaxValue=650),
        dict(nominalValue=700, name="Bold", rangeMinValue=650, rangeMaxValue=750),
        dict(nominalValue=800, name="ExtraBold", rangeMinValue=750, rangeMaxValue=800),
        dict(value=400, name="Regular", linkedValue=700, flags=0x2)
    ]
)

I missed that this was the situation in Roboto because I didn't know it was possible, so wasn't looking for it! But it was discussed in the thread you linked to.

I'm going to leave this issue open because it's @davelab6's issue, and I don't know but what he may look in at some point. But we've clearly reached a point of equilibrium, thanks entirely to @thlinard, to whom I'm extremely grateful. I've learned more about the STAT table (especially best practices connected with it) in the last three days than I have in the two years I've been working on this variable font.

Thank you for your kind words!

Someone just pointed me at this font and its STAT table. I haven't read all of this thread, but i see @davelab6 's opening suggestion of using "v 4" — which apparently has meant using format 4 Axis Value tables within the STAT table. I don't know why format 4 is suggested: this is not the kind of scenario that format 4 is intended for; I would have expected AVT formats 1, 2 or 3 to have been used.

You have ended up with many more AVTs than are needed---43 whereas about a dozen would suffice. Also, the family includes roman and italic, yet the STAT table doesn't mention the 'ital' axis at all, as it should (at least in the Italic font).

I also don't understand why the STAT table has format 4 AVTs giving names for 43 instances while the fvar table provides names for only 17 instances: How many named instances are you expecting apps to show in their UI?

Hi @PeterConstable

It's an old thread, and I too was surprised by @davelab6's request at the time.

Today I would rather advise looking on the side of the repo template of Google Fonts https://github.com/googlefonts/Unified-Font-Repository or the repo cited as an example of this template: https://github.com/Omnibus-Type/Texturina (especially the config.yaml in the sources folder).

@PeterConstable:

What you happened upon, unluckily, was some stranded code in mkstat.py, which I wrote as a first attempt before @thlinard intervened and helped me build a better table (not using format 4 AVTs). I should have deleted that old code. But then you should read more carefully before trashing people's work in public.

@thlinard:

Thanks for the reference to the repo template. I'll poke around there.

Sorry if my comments were seen to be publicly "trashing". They were intended as constructive feedback.

Regardless of what I didn't read and that might have been addressed somewhere, the fonts that I just downloaded from this repo yesterday have the issues I described.

OK, I see a new version of the variable fonts has been uploaded. I looked at the italic, and the AVTs look, in general, the way I would have expected them.

I see that two AVTs for "Regular" weight have been added: a format 2 table providing a range, and a format 3 table providing a style link to Bold. I'm not sure what implementations might combine complementary info from two AVTs like that. There was a suggestion from Adobe back around 2018 that there should be an AVT format that provides a range and a style link. In retrospect, perhaps it would have been better if format 3 had included range as well as style linking. They didn't pursue it, and so it was never added to the OT spec.

I see that two AVTs for "Regular" weight have been added: a format 2 table providing a range, and a format 3 table providing a style link to Bold. I'm not sure what implementations might combine complementary info from two AVTs like that. There was a suggestion from Adobe back around 2018 that there should be an AVT format that provides a range and a style link. In retrospect, perhaps it would have been better if format 3 had included range as well as style linking. They didn't pursue it, and so it was never added to the OT spec.

Adobe was still doing this (format 2, and format 3 for Bold linking) for version 3.006 of Source Sans (released on 5 September 2019): https://github.com/adobe-fonts/source-sans/releases. This will only be dropped for version 3.028 (7 September 2020). For a discussion going back to June 2020, this corresponds to the state of the support in InDesign at that time. Today I would recommend format 1 instead.

@PeterConstable: I'm sorry about my reaction: your post seemed at the time to have a "how could you be such an idiot" vibe, but maybe that was just my own mood at the time (in the midst of grading—worst time of the semester).

As to what was in the fonts/variable folder of the repo yesterday, it was not the mess you described, but (because of another idiocy of mine, an error in my build script) the minimal STAT contributed by fontmake as of May 7. I was going to copy the ttx of it here, but the whole sad story is in the history. This afternoon I replaced it with what my script was supposed to build and deleted the old (confusing) code from the script.

What I was chiefly after, back in the summer of 2020, was a STAT table that would enable the font to work in the Adobe apps, and the one built by the script accomplished that. The changes in Source Sans are interesting.

Why are you now suggesting Format 1, Thomas?

Why are you now suggesting Format 1, Thomas?

The first version of InDesign with VF support only accepted Format 2 (if one wanted more or less decent support), but at the time of our discussion, 1 + 3 support was added, although this was a bit uncertain.

Today, since format 1 is simpler than format 2, and that there is no longer a support problem (in any case, not worse than with format 2), I would recommend it. And the question arises, as Peter points out, whether there are any implementations supporting the 2 + 3 format, as Adobe seems to have finally abandoned the idea.

It is also interesting to note that the Google Fonts repo template standardized a production process (at least for fonts intended to be published on Google Fonts, but it can be used outside this framework): using a Github workflow, a build.yaml, a config.yaml and some scripts, it produces fonts that work well in Adobe software and MS Office for Mac. And these fonts have the format 1 + 3.

Thanks, @thlinard, this is interesting. This project is pretty settled, but I may change Junicode over to format 1 + 3, and also try out their repo template.

Btw, I just saw today:

Glyphs will now always export a fallback name table ID 25 for variable fonts, even if no variationsPostScriptNamePrefix is set in Font Info > Font > General. Our hope is that it will fix most variable font issues with InDesign.
https://glyphsapp.com/news/glyphs-3-0-4-released

I've noticed that Glyphs 3 builds a much better STAT table than 2 did, with format 1 AVTs linked to name table entries. And now that you mention it, I see that the current version is producing the ID 25 name table entry.

Much less fixup needed than before after Glyphs exports.