-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Variable GPOS feature for non-variable glyph? (invalid gvar axisCount) #815
Variable GPOS feature for non-variable glyph? (invalid gvar axisCount) #815
Comments
Sparsify all the things! |
Can you try with #779 ? |
Sorry, not instantly, as I'm running fontc from PyPI, not sources. |
I believe that should fix it, but cannot double check as I’m typing from my mobile. That PR is basically done, only needs a test to ratify it works as intended. I’ll try to complete it next week |
I tried to build your test font with the However the <gvar ERROR="decompilation error" raw="True">
<!-- An error occurred during the decompilation of this table -->
<!-- Traceback (most recent call last):
File "/Users/clupo/oss/fontc/.venv/lib/python3.11/site-packages/fontTools/ttLib/ttFont.py", line 467, in _readTable
table.decompile(data, self)
File "/Users/clupo/oss/fontc/.venv/lib/python3.11/site-packages/fontTools/ttLib/tables/_g_v_a_r.py", line 118, in decompile
assert len(axisTags) == self.axisCount
AssertionError
-->
<hexdata>
00010000 00000000 0000001a 00020000
0000001a 00000000 0000
</hexdata>
</gvar>
here's fontc-built font.ttf.zip |
fontmake also produces a 26-byte length gvar table, but ttx decompiles that as an empty gvar table. Manually extracted, that empty gvar table contains these 26 bytes:
The differing bytes are the "axisCount" field, so that does explain the error with the fontc version. The spec says this about the axisCount field in gvar:
So ttx's assert is reasonable. |
(One could argue that the gvar table is entirely redundant in this case.) |
thanks! looks like an easy fix |
the issue seems to be in fontations/write-fonts/src/tables/gvar.rs where it computes the axis_count for the new Gvar struct here: since in the case of an empty, non-variable gvar, all the GlyphVariations have axis_count Not sure how best to fix this. Should fontc simply mutate the Gvar and set the correct axis_count when it doesn't match the fvar axes.len()? |
Maybe omit the gvar table completely in that case? |
is it not required? |
If I remember correctly, it is fontmake builds an empty |
looks like the least risky action would be to emit an empty gvar too. I wonder what OTS say |
Ok, then I think we should fix both compilers to omit empty gvars |
And just for information purposes: we did do initial work to support the variable FEA syntax, but then realized that it was much slower for us to generate variable FEA from "feature writers" and then send that to the FEA compiler than it would be to just generate lookups directly for kerning/marks, so we're currently doing that. The intention is to support variable FEA, though. |
That's great to hear. The best .fea is no .fea. |
I just realised that fonttools deliberately adds the empty gvar because of some bug or old/bogus requirement in Adobe apps, see fonttools/fonttools#1855 I wonder if that's still relevant nowadays. Probably yes for the next 5-10 years until old software gets retired.. |
@rsheeter by the way, it appears that gvar is treated specially by fontbe orchestration Context, it's set to Bytes whereas most of the other tables are wrapped by a BeValue, which allows them to be optional. I'd like to do something like
or equivalent (that is, skip writing gvar altogether) whenever all the GlyphVariations' axis_count turn out to be None (because no glyph deltas). Why the context for gvar can't be BeValue? I did try but rustc complains something about Gvar not implementing some required traits (FontRead or Persistable, I haven't dug deeper). |
and yes, OTS does not complain when gvar is not present but fvar is (which is what makes a VF a VF) |
looks like this would be sufficient to not emit gvar when all glyph variations are empty -- iff we want to go that way diff --git a/fontbe/src/gvar.rs b/fontbe/src/gvar.rs
index a080938a..50071c0e 100644
--- a/fontbe/src/gvar.rs
+++ b/fontbe/src/gvar.rs
@@ -60,6 +60,12 @@ impl Work<Context, AnyWorkId, Error> for GvarWork {
.get(&WorkId::GvarFragment(glyph_name.clone()).into())
.to_deltas(&axis_order)
});
+
+ // if no glyph variation contains any deltas, we can skip the gvar table entirely
+ if variations.iter().all(|v| v.axis_count().is_none()) {
+ return Ok(());
+ }
+
let gvar = Gvar::new(variations).map_err(Error::GvarError)?;
let raw_gvar = dump_table(&gvar) But i'm a bit confused because other tables that are also optional, e.g. avar or MVAR, don't just return Ok() but they still do
where |
so my question for @rsheeter is, is there a difference, within a fontbe Work's exec method, if one does call |
All in all, I'd be inclined to still emit the empty no-op gvar (20 bytes or so) if that makes some Adobe apps happier, however I don't have a way to test this. I'll ask in the font engineering chat |
this is the font compiled from varpos.designspace, without a gvar table, in case one wants to try this inside Adobe Indesign and confirm whether it works or not there's only one glyph "A" and one wght axis, the glyph itself contains no glyph variations but there's a GPOS feature called |
Based on f2f I think we should probably pass axis_count to https://github.com/googlefonts/fontations/blob/b397a31889336ddc6f02c0a8a3cdea6cc6dd5228/write-fonts/src/tables/gvar.rs#L70 because it cannot always be determined from the input. EDIT: I'm assuming we have to emit gvar, if we can just not emit it that would be nice but IIUC that's bad for Adobe apps. |
this ensures that we (e.g. fontc) can make valid empty gvar tables where the axis_count matches the expected fvar's axis_count Will fix googlefonts/fontc#815 once fontc is updated to use the new API. This is a breaking changes which warrants minor write-fonts version bump.
Fixes #815 Untested as it requires googlefonts/fontations#919 (and write-fonts dependency bump) to work...
@justvanrossum If you don't mind I'll use that varpos.designspace of yours as a test font in #833 |
I was trying to find out whether fontc supports variable features, and while I think the error I'm getting proves that it does, I am getting an error, in the following case:
fontmake compiles this into a variable font with a working variable GPOS feature.
fontc errors like this:
.designspace + .ufo:
varpos.zip
The text was updated successfully, but these errors were encountered: