How to Extract Metadata from Font Files (TTF, OTF, WOFF)
Font files carry a surprising amount of metadata in their OpenType name tables, from designer attribution and foundry info to license terms and embedding permissions. This guide walks through the practical tools and techniques for extracting that metadata from TTF, OTF, and WOFF files, whether you need to audit font licenses across a project, verify usage rights before distribution, or catalog design assets at scale.
What Metadata Lives Inside a Font File?
Every TrueType (.ttf), OpenType (.otf), and Web Open Font Format (.woff/.woff2) file includes a structured metadata container called the name table. This table stores human-readable strings that identify the font and define how it can be used. The OpenType specification defines 25+ standardized name record IDs, though most fonts populate only a subset.
Here are the most commonly populated fields:
Beyond the name table, font files also contain an OS/2 table with embedding permissions (fsType flags), supported Unicode ranges, and weight/width classification values. The head table stores creation and modification dates, units-per-em, and font direction hints. For WOFF and WOFF2 files specifically, there is also an optional XML metadata block that can carry additional licensing and description information outside the OpenType tables.
Reading Font Metadata with fontTools (Python)
The fontTools library is the standard tool for working with font files in Python. It reads TTF, OTF, WOFF, and WOFF2 formats natively and gives you direct access to every table in the font.
Install it with pip:
pip install fonttools brotli
The brotli package is needed for WOFF2 decompression. Without it, fontTools will read TTF, OTF, and WOFF files just fine but will fail on WOFF2.
Read the name table:
from fontTools.ttLib import TTFont
font = TTFont("MyFont.otf")
name_table = font["name"]
for record in name_table.names:
try:
text = record.toUnicode()
except UnicodeDecodeError:
text = record.string.decode("latin-1")
print(f"ID {record.nameID}: {text}")
This iterates through every name record and prints the ID alongside its value. Most fonts include records for multiple platforms (Windows, Mac, Unicode), so you will typically see duplicates for each name ID.
Extract specific fields by ID:
font = TTFont("MyFont.ttf")
family = font["name"].getDebugName(1)
full_name = font["name"].getDebugName(4)
version = font["name"].getDebugName(5)
license_text = font["name"].getDebugName(13)
license_url = font["name"].getDebugName(14)
print(f"Font: {full_name}")
print(f"Family: {family}")
print(f"Version: {version}")
print(f"License: {license_text}")
print(f"License URL: {license_url}")
The getDebugName() method returns the best available string for a given name ID, handling platform and encoding selection automatically. It returns None if the ID is not present.
Check embedding permissions from the OS/2 table:
os2 = font["OS/2"]
fs_type = os2.fsType
if fs_type == 0:
print("Installable embedding allowed")
elif fs_type & 0x0002:
print("Restricted: no embedding permitted")
elif fs_type & 0x0004:
print("Preview & print embedding only")
elif fs_type & 0x0008:
print("Editable embedding allowed")
The fsType field is a bitmask. A value of 0 means no restrictions. Bit 1 (0x0002) means restricted license embedding, which prevents embedding the font in documents entirely. Bits 2 and 3 define progressively more permissive levels.
Using ExifTool for Quick Font Inspection
ExifTool reads metadata from over 30 file formats, and fonts are one of them. It supports TTF, OTF, TTC (TrueType Collections), WOFF, WOFF2, DFONT, and several PostScript font formats. For quick one-off inspections where you do not want to write code, ExifTool is hard to beat.
Basic usage:
exiftool MyFont.otf
This dumps every readable metadata field. For a font file, you will typically see the font family, subfamily, version, copyright, trademark, designer, vendor URL, license description, and license URL, all extracted from the name table.
Extract specific tags:
exiftool -FontFamily -FontName -Copyright -License MyFont.ttf
Batch extract from a directory of fonts:
exiftool -csv -FontFamily -FontName -Copyright -License /path/to/fonts/ > font_metadata.csv
This scans every supported file in the directory and writes a CSV with one row per font. The CSV output is useful for license audits where you need a spreadsheet of every font, its source, and its license terms.
Check a WOFF file:
exiftool webfont.woff2
ExifTool handles WOFF and WOFF2 decompression transparently. You do not need to convert them to TTF first.
One limitation: ExifTool reads font metadata but cannot write to it. If you need to modify name table entries, use fontTools instead.
Centralize Your Font Metadata and License Audits
Upload font inventories and license reports to a shared workspace where your team can search, filter, and review them with built-in AI. 50 GB free, no credit card required.
Font Metadata from the Command Line with fc-query
On Linux and macOS (with fontconfig installed), fc-query reads metadata directly from font files without installing them into the system font cache. It is part of the fontconfig package and comes preinstalled on most Linux distributions.
Basic query:
fc-query MyFont.ttf
This outputs all fontconfig-recognized properties: family, style, weight, width, slant, spacing, supported languages, and file format.
Extract specific properties with format strings:
fc-query --format="%{family}
%{style}
%{fontformat}
" MyFont.otf
Common format tokens include %{family}, %{style}, %{weight}, %{width}, %{slant}, %{fontformat}, and %{lang}. The %{lang} token is particularly useful because it lists every language the font supports based on its Unicode coverage, something neither ExifTool nor a basic fontTools script will give you by default.
Query a specific face in a TrueType Collection:
fc-query -i 2 MyFontCollection.ttc
The -i flag selects a face by index, starting from 0.
fc-query has a narrower scope than fontTools or ExifTool. It does not read the full name table, so you will not see license text, designer URLs, or trademark notices. It is best for quick checks of family names, styles, weight classes, and language coverage.
Install on macOS (if not present):
brew install fontconfig
Auditing Font Licenses Across a Project
Font license compliance failures carry real financial risk. NBC Universal settled a font licensing dispute with Font Bureau for $2 million after using the Chalet typeface without proper licensing across broadcast materials. Blizzard Entertainment faced a $13.2 million claim over five Chinese typefaces. Even smaller organizations receive cease-and-desist letters with retroactive licensing demands that can run into thousands of dollars.
The metadata stored in font files is your first line of defense. Name ID 13 (License) and Name ID 14 (License URL) tell you the terms under which a font was distributed. The OS/2 fsType flags tell you whether embedding is permitted at all.
Build a license audit script with fontTools:
import os
from fontTools.ttLib import TTFont
font_dir = "./project-fonts"
results = []
for filename in os.listdir(font_dir):
if filename.lower().endswith((".ttf", ".otf", ".woff", ".woff2")):
path = os.path.join(font_dir, filename)
font = TTFont(path)
name = font["name"].getDebugName(4) or filename
license_text = font["name"].getDebugName(13) or "NOT FOUND"
license_url = font["name"].getDebugName(14) or "NOT FOUND"
fs_type = font["OS/2"].fsType
results.append({
"file": filename,
"name": name,
"license": license_text[:80],
"license_url": license_url,
"embedding": "restricted" if fs_type & 0x0002 else "allowed",
})
font.close()
for r in results:
print(f"{r['file']}")
print(f" Name: {r['name']}")
print(f" License: {r['license']}")
print(f" License URL: {r['license_url']}")
print(f" Embedding: {r['embedding']}")
print()
This script scans a directory, pulls the license metadata from each font, checks embedding permissions, and prints a report. Fonts that return "NOT FOUND" for license fields need manual investigation, as the metadata may have been stripped or the font may be from a source that does not populate those fields.
For teams managing large font libraries, pairing this kind of audit with a centralized storage system keeps things organized. Fast.io's Metadata Views can extract structured data from uploaded documents, though for font-specific name table parsing, you will want a dedicated script like the one above feeding results into your workspace for tracking and review.
Working with WOFF and WOFF2 Metadata
WOFF (Web Open Font Format) wraps a standard TrueType or OpenType font in a compressed container. The underlying font tables, including the name table, remain intact and accessible through the same tools.
WOFF2 uses Brotli compression instead of zlib, which achieves better compression ratios but requires a Brotli decoder. Both fontTools (with the brotli Python package) and ExifTool handle WOFF2 decompression automatically.
WOFF-specific metadata block:
WOFF files can include an optional XML metadata block that sits outside the font tables. This block follows the W3C WOFF specification and can contain:
- Unique ID for the font
- Vendor information (name, URL, directory entry)
- Credits (individual contributors with roles and URLs)
- Description text (localized)
- License text and URL (localized)
- Copyright notice
- Trademark notice
- Extended metadata fields
fontTools includes a dedicated snippet for dumping this metadata:
from fontTools.ttLib import TTFont
font = TTFont("webfont.woff")
if hasattr(font, "flavorData") and font.flavorData:
meta = font.flavorData.metaData
if meta:
print(meta.decode("utf-8"))
For WOFF2 files, the approach is identical. Just make sure brotli is installed.
Not all WOFF files include the optional metadata block. Many web fonts are converted from desktop formats without adding the XML layer. When the block is missing, fall back to reading the standard name table entries, which are always present regardless of the container format.
Converting between formats for inspection:
If you encounter issues reading a WOFF2 file, you can convert it to TTF for inspection:
from fontTools.ttLib import TTFont
font = TTFont("webfont.woff2")
font.flavor = None
font.save("webfont.ttf")
This strips the WOFF2 wrapper and writes a plain TrueType file that any font tool can read.
Batch Processing and Automation Strategies
When you are managing hundreds of font files across projects, manual inspection does not scale. Here are practical approaches for automating font metadata extraction.
ExifTool batch processing with JSON output:
exiftool -json -r /path/to/all/fonts/ > all_fonts_metadata.json
The -r flag recurses into subdirectories, and -json gives you structured output you can parse programmatically. This is the fast path from "directory of fonts" to "searchable metadata database."
Python script for comprehensive extraction:
import json
import os
from fontTools.ttLib import TTFont
def extract_font_metadata(filepath):
font = TTFont(filepath)
name = font["name"]
os2 = font["OS/2"]
head = font["head"]
metadata = {
"file": os.path.basename(filepath),
"family": name.getDebugName(1),
"subfamily": name.getDebugName(2),
"full_name": name.getDebugName(4),
"version": name.getDebugName(5),
"postscript_name": name.getDebugName(6),
"manufacturer": name.getDebugName(8),
"designer": name.getDebugName(9),
"description": name.getDebugName(10),
"license": name.getDebugName(13),
"license_url": name.getDebugName(14),
"fs_type": os2.fsType,
"weight_class": os2.usWeightClass,
"width_class": os2.usWidthClass,
"created": str(head.created),
"modified": str(head.modified),
}
font.close()
return metadata
fonts_dir = "./fonts"
all_metadata = []
for root, dirs, files in os.walk(fonts_dir):
for f in files:
if f.lower().endswith((".ttf", ".otf", ".woff", ".woff2")):
path = os.path.join(root, f)
try:
all_metadata.append(extract_font_metadata(path))
except Exception as e:
print(f"Error reading {path}: {e}")
with open("font_inventory.json", "w") as out:
json.dump(all_metadata, out, indent=2)
print(f"Extracted metadata from {len(all_metadata)} fonts")
This produces a JSON inventory with every field you would need for a license audit, design system catalog, or asset management database.
Feeding results into a shared workspace:
Once you have extracted metadata into structured JSON or CSV, uploading those results to a shared workspace makes them searchable and reviewable by the whole team. Fast.io workspaces with Intelligence enabled will auto-index uploaded documents for semantic search, so you can later ask questions like "which fonts have restricted embedding?" or "show me all fonts from Monotype" without re-running the extraction scripts. For structured querying, Metadata Views can turn the uploaded inventory into a sortable, filterable spreadsheet directly in the workspace.
Frequently Asked Questions
How do I check font file metadata?
The fast method is ExifTool: run `exiftool MyFont.ttf` to see all metadata fields. For programmatic access, use the fontTools Python library with `TTFont('MyFont.ttf')['name'].getDebugName(1)` to read specific name table entries. On Linux, `fc-query MyFont.ttf` shows family, style, and language coverage through fontconfig.
What metadata is in a TTF file?
TTF files store metadata across several internal tables. The name table contains the font family, subfamily, full name, version, copyright, trademark, designer, manufacturer, license text, and license URL. The OS/2 table holds embedding permissions, weight class, width class, and Unicode coverage ranges. The head table records creation and modification dates, units-per-em, and font direction hints.
How to find the license of a font file?
Look at name table ID 13 (License Description) and ID 14 (License Info URL). In fontTools: `TTFont('font.ttf')['name'].getDebugName(13)` returns the license text. With ExifTool: `exiftool -License -LicenseURL font.ttf`. Some fonts omit these fields, in which case you will need to trace the font back to its distributor and check their terms manually.
Can ExifTool read font metadata?
Yes. ExifTool supports TTF, OTF, TTC, WOFF, WOFF2, DFONT, PFA, PFB, PFM, AFM, ACFM, and AMFM font formats. It reads name table entries, OS/2 table properties, and WOFF XML metadata blocks. Run `exiftool font.woff2` to see all available fields. ExifTool can read but not write font metadata.
What is the OpenType name table?
The OpenType name table is a standardized structure inside TTF, OTF, and WOFF files that stores human-readable text strings. It uses numbered name IDs (0 through 25+) to identify fields like copyright (0), font family (1), version (5), license (13), and license URL (14). Strings can be stored for multiple platforms (Windows, Mac, Unicode) and in multiple languages.
How do I extract metadata from WOFF2 files?
WOFF2 files use Brotli compression but contain standard OpenType tables underneath. fontTools reads them directly if you install the `brotli` Python package: `pip install fonttools brotli`, then `TTFont('font.woff2')`. ExifTool also handles WOFF2 decompression automatically with no extra setup.
What are fsType embedding permissions in fonts?
The fsType field in the OS/2 table is a bitmask that controls how a font can be embedded in documents. A value of 0 means installable (no restrictions). Bit 1 (0x0002) means restricted, no embedding allowed. Bit 2 (0x0004) allows preview and print embedding only. Bit 3 (0x0008) allows editable embedding. These flags are important for PDF generation, ebook publishing, and web font licensing compliance.
Related Resources
Centralize Your Font Metadata and License Audits
Upload font inventories and license reports to a shared workspace where your team can search, filter, and review them with built-in AI. 50 GB free, no credit card required.