chrissimpkins / fontname.py

Font renaming script for OpenType tables in CFF (.otf) and OT TrueType (.ttf) fonts

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Not renaming font family on MacOS

rynop opened this issue · comments

Reproduce steps:

  1. Download FontAwesome for web
  2. Run:
python fontname.py "TEST" /Users/ryan/Downloads/fontawesome-free-5.8.1-web/webfonts/fa-solid-900.ttf

[OK] Updated '/Users/ryan/Downloads/fontawesome-free-5.8.1-web/webfonts/fa-solid-900.ttf' with the name 'TEST Solid'
  1. Open fa-solid-900.ttf with Font Book app (or another app that displays .ttf font family)
  2. Note that font family is still Font Awesome 5 free

I wrote a blog post where this used to work (at least on 12/27/2018). I can't figure out what has changed.

Sorry for the troubles Ryan. Do you mind pushing the font to this issue report thread so that I can have a look at the OpenType tables after your write attempt?

No need to be sorry, really appreciate this program. Absolutely, zip attached below.

Zip contains an original un-modified fa-solid-900-before-fontname.ttf AND a fa-solid-900-after-fontname.ttf that was created by doing:

cp /Users/ryan/Downloads/fontawesome-free-5.8.1-web/webfonts/fa-solid-900-before-fontname.ttf /Users/ryan/Downloads/fontawesome-free-5.8.1-web/webfonts/fa-solid-900-after-fontname.ttf

python ~/fontname.py "test" /Users/ryan/Downloads/fontawesome-free-5.8.1-web/webfonts/fa-solid-900-after-fontname.ttf

[OK] Updated '/Users/ryan/Downloads/fontawesome-free-5.8.1-web/webfonts/fa-solid-900-after-fontname.ttf' with the name 'test Solid'

ttf-before-and-after.zip

Please LMK if you need anything else. Thanks!

It is doing the right thing:

fa-name

but it looks like those fonts define extra name table records that override the ones that we edit here. I think that this is leading to the issue of the default value of "Font Awesome 5 Free" remaining at install time.

It looks like the FontAwesome free files are released under the SIL OFL license. You can use the ttx executable released in the fonttools/fonttools project to dump the modified font binary to XML, manually edit the name table records 16, 17, and 18 (or remove all of them), then rebuild the fonts with ttx from the modified XML. Use ttx --help after you install the fonttools library for detailed help on how to use the tool.

The name table spec documentation for these name table records is available here.

I'll need to take a look at how we should handle this issue in the script here...

Thanks for letting me know about this. I will have a look at it.

Ah ok, great thanks. I'm a font noob so will have to tinker around with fonttools.

The ttx approach is very simple. ttx will dump the OpenType tables to XML where you can edit by hand and re-save the XML. Then ttx will compile the XML back into valid font binaries.

Let me know if you get stuck along the way. Happy to take a look at the XML as you do this if you need a hand with any of the OpenType spec specific things.

and I should mention that the ttx executable is installed when you install the fontTools library. Both are Python 3 based and you can install with the Py3 interpreter based pip on your platform.

$ pip install fontTools
$ ttx --version
$ ttx --help

Thx Chris. I tried ttx and it was easy to use. I'm not sure what the repercussions are on removing vs re-naming.

In either case, I'll need to make a one (or few liner) to make it easy for others to quickly "fix-up" the .ttf file. Any dev who wants to use font awesome in their native mobile app (NativeScript, React Native etc) will run into this issue of needing to change the font-family. I want to make it as easy on other devs as possible.

Something like:

ttx fa-solid-900.ttf
sed -i .bak 's|<namerecord.*>(Font Awesome 5 Free)</namerecord>|<namerecord.*>Font Awesome 5 Free Solid</namerecord>|ig' fa-solid-900.ttf
ttx fa-solid-900.ttf

Of course the regex isn't valid (don't have time ATM to work on it) but the point is it needs to be simple to do.

  • Any thoughts on how this could be made easier?
  • Any idea how the following rule determines which table name record to use? The following works with the non-modified fa-solid-900.ttf
.fas {
    font-family: 'Font Awesome 5 Free';
}

Good to hear!

I'm not sure what the repercussions are on removing vs re-naming

The extended naming fields in the OpenType name table (ID's 16 and above) are used for style linking of large font families like those that have both broad weight and width builds (e.g., Condensed Thin, Condensed, Condensed Bold, etc.). There is no spec'd subfamily name "Solid" and since FA needs this to contrast against designs without fills it looks like the authors are defining it through those OpenType name records. My suggestion would be to change the entire family name to "[NAME] Solid" and replace the current "Solid" variant with "Regular" similar to how the definitions appear below for the Roboto Regular font:

n0d76-image

Then it should behave like the Regular variant of any other typeface and you should be able to use:

.fas {
    font-family: '[NAME] Solid';
}

in your CSS files.

If you need to use the unfilled (name?) FA designs, then replace the "Solid" in the above naming scheme with whatever term is appropriate (e.g., "Unfilled") and then you should be able to access it with the following CSS definition:

.fau {
    font-family: '[NAME] Unfilled';
}

Any thoughts on how this could be made easier?

If this is a required resource out there, it might be worth pushing the builds that you develop to a repository and distribute them to other users so that they don't need to generate them on their own. That would be the simplest approach :)

I'd be happy to help whip up a Python script that performs the name table modifications if you want to create the repository and let me know how you want the naming to appear for users.

Damn you have some strong font-FU ;)

I like the re-distribute idea (for simplicity sake), and that is really nice to offer your services, however I selfishly don't want to spend time re-building and re-distributing every time FA has a release.

I was really hoping I could come up with a CSS rule that would pick the correct Regular or Solid variation without needing to modify their .ttf files at all. Let me run this by you and see if you can come up with a suggestion that can pull this off.

First some background. They have 4 fonts: Solid,Regular,Light,Brands. The free download includes Solid, Regular and Brands (even though Regular isn't supposed to be free). I really think their naming convention is poor, however thats moot at this point :)

Here the 3 fonts:
image

Note both the non-brand ones are in the Font Awesome 5 Free family. Regular isn't free anymore (I know confusing).

I was hoping I could do:

// This always works
.fab {
  font-family: 'Font Awesome 5 Brands', fa-brands-400;
}

// This doesnt work
.far {
  font-family: 'Font Awesome 5 Free Regular';
}

// This doesnt work
.fas {
  font-family: 'Font Awesome 5 Free Solid';
}

Only thing I've gotten to work is to NOT include fa-regular-400.ttf in my app, and specify this css:

.fab {
  font-family: 'Font Awesome 5 Brands', fa-brands-400;
}

// Note I omitted "Solid"
.fas {
  font-family: 'Font Awesome 5 Free', fa-solid-900;
}

Can you think of a font-family name specification hack that would allow me to "install" both regular and solid?

I know this is outside the realm of fontname.py so feel free to tell me to pound sand...

Unfortunately, I don't have much CSS-fu :) I'm not sure that I can be of much use there...

Here is how FA is defining it in their CSS file:

@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;font-display:auto;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}

.fab{font-family:"Font Awesome 5 Brands"}

@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-weight:400}

@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}

.fa,.far,.fas{font-family:"Font Awesome 5 Free"}

.fa,.fas{font-weight:900}

Have you tried using the ttf settings from the CSS there? Maybe the key is in these definitions?

.fab{font-family:"Font Awesome 5 Brands"}
.fa,.far,.fas{font-family:"Font Awesome 5 Free"}
.fa,.fas{font-weight:900}

It looks like they are distinguishing the Free solid (weight = 900) and Free regular (weight = 400) builds with weight definitions in the @font-face settings above. The fonts are being rendered as Free Regular = family Regular variant and Free Solid = family Black=900 weight variant.

Unfortunately NativeScript apps can only reference included fonts by font-family (iOS) or file name (Android).

No worries, I'm not blocked on this. Given the recent change of FA regular icons becoming non-free, my hunch is they will be changing their font files soon. I'll circle back on this when I have a little more time.

Closing for now as this isn't really an issue on your end. Thanks for all your time and input!

No worries. The font family name approach that I suggested earlier will do it. You just need to define three different font family names if that is a constraint on iOS.

Just ran into this issue within a NativeScript app, and Font Awesome 5.
It seems that basically you can now only use either Regular, or Solid.

There is no way to use both inside the same app.
The reason is that they both have the same name and there is no way to tell them apart.

Is this correct?

@ignaciofuentes it sounds like that is correct Ignacio. I believe that Regular and Solid are style linked and NativeScript does not have a way to distinguish between the two fonts.

If the two of you are willing to help me experiment with this, I will create a script to address the issue of naming with Font Awesome releases. The goal will be to create an approach that sets the name tables to allow NativeScript to distinguish the separate font variants so that you can use them all. Let me know if you are available for this and I will dig into the problem.

This demonstrates what is going on.

The Regular and Solid versions are being "seen" as the different weight variants in the same type family:

style_link

To get at that with CSS, you would need to specify a different weight value with the same typeface family name (or file path on Android as I understand Ryan's comments above). See #3 (comment) for the approach that I pulled from Font Awesome's own CSS files.

The weight definitions can be modified in the fonts so that all three Regular, Solid, and Brands are all seen as different font families with the same font weight.

Here is one location where that problem will need to be addressed OS/2.usWeightClass:

os2_tables

The other will be in the name tables of the fonts I think. This will be where we will need to experiment a bit.

@rynop @ignaciofuentes

Can I ask one of you to try the following modified builds in a NativeScript application:

fa-NativeScript_mods.zip

I did the following:

  • eliminated unnecessary style linking name table records
  • changed OS/2.usWeightClass in the Solid variant to 400
  • changed nameID 2 record to "Regular" (from "Solid") in the fa-solid-400 build

If those work (i.e., allow you to use Regular, Solid, Brands simultaneously in the same application) then I have an approach to build a script that will replicate these modifications with future Font Awesome updates.

Absolutely no rush!

Yup I can try it out on Tuesday

In case this is still relevant, I was able to make all 3 free versions of Font Awesome work on both platforms without any alterations to the font files.

I'm using NativeScript 5.4.1 with Angular 7.2.15 and downloaded the latest font files from the official website (I noticed they changed the file names).

Steps:

  1. Add all 3 otf files in src/fonts
  2. Add relevant classes in src/app.css
.fab {
    font-family: "Font Awesome 5 Brands", "Font Awesome 5 Brands-Regular-400";
    font-weight: 400;
}

.far {
    font-family: "Font Awesome 5 Free", "Font Awesome 5 Free-Regular-400";
    font-weight: 400;
}

.fas {
    font-family: "Font Awesome 5 Free", "Font Awesome 5 Free-Solid-900";
    font-weight: 900;
}

Note that for Android I had to use the exact filename as it appears in src/fonts folder.

  1. Use icon codes as needed (prepend all with &#x and append ;)
<Label class="far" text="Regular: &#xf2b9;"></Label>
<Label class="fas" text="Strong: &#xf2b9;"></Label>
<Label class="fab" text="Brands: &#xf270;"></Label>

iOS
Screenshot 2019-06-14 at 18 04 20
Android
Screenshot 2019-06-14 at 18 06 02

@danielnitu ty! Yes we were trying to decide whether to draft a custom script so that these can be used with a new naming scheme. Does the approach that Daniel used in #3 (comment) work for you @rynop @ignaciofuentes ? If so, let's close this and consider this the minimal effort best approach that does not require modification of the fonts as released. :)