Skip to content
This repository has been archived by the owner on Apr 6, 2021. It is now read-only.

Improve fonts generation: use fonttools to generate (reproducible) fonts #54

Merged
merged 13 commits into from
Sep 4, 2018

Conversation

ylemkimon
Copy link
Member

@ylemkimon ylemkimon commented Jul 24, 2018

This PR is part of #12.

  • Reproducible build: Fixes Use FontForge's SOURCE_DATE_EPOCH for repeatable builds #15
  • Calculate ascent/descent using fonttools, remove fix_os2_metrics.rb and Ruby
  • Fix OS/2 and hhea metrics using fonttools, remove modify_ascent_descent.py
  • Generate WOFF and WOFF2 using fonttools, remove woff-tools and woff2_compress, combine targets into phony fonts target
  • Update copyright year

I compared the output using ttx and differences other than above were maxInstructionDefs in head, which probably was a bug in previous fontforge and few metrics, resulting in (sub)pixel changes but nothing visible.

* set created/modified timestamp
* remove fontforge timestamp(FFTM) and GDEF table
* set font version
* fix metrics
* generate WOFF, WOFF2
@ylemkimon ylemkimon changed the title Use fonttools to generate (reproducible) fonts Improve fonts generation: use fonttools to generate (reproducible) fonts Jul 24, 2018
@ylemkimon ylemkimon added this to In progress in Improve fonts generation via automation Jul 24, 2018
ylemkimon added a commit to ylemkimon/katex-fonts that referenced this pull request Jul 24, 2018
Copy link
Member

@kevinbarabash kevinbarabash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm super excited about this change. I think it's going to unlock a lot of doors for us. Requesting a way to avoid updating font files with no changes to the glyphs themselves.

@@ -72,10 +73,11 @@ if [[ $(docker images "$IMAGE" | wc -l) -lt 2 ]]; then
fi

CMDS="set -ex
export SOURCE_DATE_EPOCH=${LAST_COMMIT_DATE}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this still result in all files being modified (albeit only on commit) whenever someone makes any change? It would be nice if we only updated font files where we changed something. I think there might be some way to do that while also bumping the timestamp in those files, but it might be easier to just set SOURCE_DATE_EPOCH to be a constant.

src/fonts/OTF/TeX/Makefile Show resolved Hide resolved
src/fonts/OTF/TeX/Makefile Show resolved Hide resolved
version = json.load(f)['version']

font['name'].setName(unicode('Version ' + version), 5, 3, 1, 1033)
font['name'].setName(unicode('Version ' + version), 5, 1, 0, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's 5, 3, 1, 1033 and 5, 1, 0, 0 about?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinbarabash They are name ID, platform ID, encoding ID, and language ID of NAME table, respectively. We have two tables, (3, 1, 1033) and (1, 0, 0), which are Unicode variants. (See Space.ttx)

font_file = sys.argv[1]
font_name = os.path.splitext(os.path.basename(font_file))[0]

font = TTFont(font_file, recalcBBoxes=False, recalcTimestamp=False)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for figuring out all of these TTFont options to produce a reproducible build.

src/fonts/OTF/TeX/generate_fonts.py Show resolved Hide resolved
mkdir -p ttf
rm -f ttf/*
.PHONY: fonts
fonts: ff
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could rewrite this rule to be a per .ff rule since makeFF outputs multiple files to ff/KaTeX_$font.ff. This would allow us to only update those .ttf, .woff, and .woff2 files that have meaningful changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd have to check in the .ff files themselves which isn't the worst. Long term we might look at splitting up makeFF. Another short term approach we might look at is setting the default timestamp to be whatever it was in the file from the last commit... write the file, if there are changes, update the timestamp to be the current timestamp and update the file with that timestamp.


# save WOFF2
font.flavor = 'woff2'
font.save(os.path.join('woff2', font_name + '.woff2'), reorderTables=None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad that FontTools makes it easy to save all these different formats.

@ylemkimon
Copy link
Member Author

@kevinbarabash I was thinking of moving MakeFF and possibly Makefile to JS, and this PR is temporary (intermediate) step. Do you think we should leave Makefile and use make?

Copy link
Member

@kevinbarabash kevinbarabash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ylemkimon I'd like to move things to JS as well. Since this is an intermediary step we can leave deciding whether or not to update individual font files to a future PR.

@kevinbarabash
Copy link
Member

kevinbarabash commented Sep 4, 2018

We should probably merge #50 first.

@ylemkimon
Copy link
Member Author

ylemkimon commented Sep 4, 2018

@kevinbarabash As circleci/test is not required check yet, I think we can merge this first.

@kevinbarabash kevinbarabash merged commit 93cbc5f into KaTeX:master Sep 4, 2018
Improve fonts generation automation moved this from In progress to Done Sep 4, 2018
@kevinbarabash
Copy link
Member

Yay!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

Use FontForge's SOURCE_DATE_EPOCH for repeatable builds
2 participants