How to use fontTools to detect the font type

639 views Asked by At

Is there a way to know if a font is a TrueType or OpenType font?

I specify that the extension of the font does not matter to me, so ttx.guessFileType(fontPath) is not a good solution for me.

2

There are 2 answers

0
Justin Penner On BEST ANSWER

OpenType vs TrueType?

First, we need to define what we mean by "OpenType" and "TrueType" fonts. The OpenType font format was developed as mostly a superset of the TrueType format, and nowadays most fonts with .otf and .ttf extensions are in fact OpenType fonts.

Is the font OpenType format?

Since OpenType is a superset of TrueType, you can check whether an .otf or .ttf font is OpenType like this:

if fontPath.endswith('.otf') or fontPath.endswith('.ttf'):
  fontFormat = 'OpenType'

Are the glyph outlines TrueType (quadratic) or OpenType/CFF (cubic)?

The file extensions .otf and .ttf are theoretically interchangeable, so you're correct to avoid relying on the extension. But most of the time, OpenType fonts with an .otf extension contain glyph outlines drawn with cubic beziers and stored in a CFF or CFF2 table, whereas OpenType fonts with a .ttf extension contain glyph outlines drawn with quadratic beziers and stored in a glyf table.

So if you're unsure about the file extension, you can simply check whether the font contains a glyf table.

from fontTools.ttLib.ttFont import TTFont

font = TTFont("font.ttf")

if 'glyf' in font:
  outlineFormat = "TrueType"
elif 'CFF ' in font or 'CFF2' in font:
  outlineFormat = "OpenType/CFF"
else:
  outlineFormat = "Unknown/Invalid"

Side note: Normally, if a font contains TrueType outlines, the first four bytes of the font will also be coded as '\x00\x01\x00\x00', and if the font contains OpenType/CFF outlines, the first our bytes will be coded as 'OTTO'. In fontTools you can check this via the TTFont.sfntVersion property.

0
Lima On

You can check the file signature:

#!/usr/bin/python3
o = open('font', 'rb')

magic = o.read(5)

if magic.startswith(b'OTTO'):
    print('OpenType')
elif magic.startswith(b'\x00\x01\x00\x00\x00'):
    print('TrueType')
else:
    print('other')

Source