omacranger / fontawesome-subset

Creates subsets of FontAwesome fonts for optimized use on the web.
GNU General Public License v3.0
66 stars 15 forks source link

Ensure deterministic output #11

Closed fenichelar closed 3 years ago

fenichelar commented 3 years ago
  1. Remove SVG metadata
  2. Remove SVG comments
  3. Set ttf description to font name
  4. Set ttf url to empty string
  5. Set ttf creation timestamp to 0
fenichelar commented 3 years ago

svg2ttf doesn't create the same output when run multiple times even if the same set of icons are used. This causes a problem if fontawesome-subset is used in a build pipeline because each build results in a different fingerprint which is inefficient from a caching perspective.

omacranger commented 3 years ago

Agreed, good catch. I'd like to see the replacing for the metadata & other components cleaned up a bit so it's not quite so chained, and make sure it's not removing anything parsed by a browser / client, but otherwise I like it. Will try to review / run through it soon.

fenichelar commented 3 years ago

I can seperate the replaces onto new lines.

const svgContentsNew = svgFile
  .replace(/<metadata>.*</metadata>/s, "")
  .replace(/<!--.*-->/s, "")
  .replace(/`(<glyph glyph-name="(${glyphsToRemove.join("|")})".*?\\/>)`, "gms"), "")
  .replace(/>\s+</gms, "><");

Or do you want an intermediate variable?

const svgFileWithoutMetadataOrComments = svgFile.replace(/<metadata>.*</metadata>/s, "").replace(/<!--.*-->/s, "");
const svgContentsNew = svgFileWithoutMetadataOrComments.replace(/`(<glyph glyph-name="(${glyphsToRemove.join("|")})".*?\\/>)`, "gms"), "").replace(/>\s+</gms, "><");

Below is the first 23 lines of fa-solid-900.svg

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20201107 at Wed Aug  4 12:25:29 2021
 By Robert Madole
Copyright (c) Font Awesome
</metadata>
<!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><defs>
<font id="FontAwesome5Free-Solid" horiz-adv-x="512" >
  <font-face 
    font-family="Font Awesome 5 Free Solid"
    font-weight="900"
    font-stretch="normal"
    units-per-em="512"
    panose-1="2 0 5 3 0 0 0 0 0 0"
    ascent="448"
    descent="-64"
    bbox="-1.00195 -64.9795 640.104 448.576"
    underline-thickness="25"
    underline-position="-50"
    unicode-range="U+0020-F8FF"
  />

The metadata contains a timestamp which is a problem. The comment contains a version number that could cause the file to change even if the actual icons being used didn't change.

omacranger commented 3 years ago

I prefer the newlines (I personally used Prettier when setting this one up so that would match the existing styles - I really should have that pushed in as a dev dependency).

I don't necessarily want to remove any of the licensing unless it's invalidating the timestamps since we are using open source software to generate the output and it's only fair to credit them. I'd say leave the comments untouched and only remove the timestamp from the metadata. Thoughts?

fenichelar commented 3 years ago
  1. I put each replace on its own line.
  2. I removed the replace statement that removes the comment.
  3. I statically set the copyright notice to Copyright (c) Font Awesome. I'm worried trying to parse the timestamp out of the metadata might be brittle.
  4. I statically set the url to https://fontawesome.com

Thoughts?

omacranger commented 3 years ago

Pushed a beta branch for version 3.0 which should resolve this. If you want to give it a shot and report back you can use npm install fontawesome-subset@beta, otherwise I'll try to do any final testing and roll it out soon.

omacranger commented 3 years ago

Fixed by 3.0.0.