How to Work with WOFF Fonts in Python

How to Work with WOFF Fonts in Python

WOFF (Web Open Font Format) is the standard for delivering fonts on the web. WOFF 1 uses zlib compression and WOFF 2 uses Brotli compression, both wrapping an underlying TrueType or CFF font. Aspose.Font FOSS for Python loads both formats and exposes the inner font data through a clean API.

Step-by-Step Guide

Step 1: Install the Package

pip install "aspose-font>=1.0.0"

Step 2: Import Required Classes

from aspose_font.loader import FontLoader
from aspose_font.converter import FontConverter
from aspose_font import FontType

Step 3: Load and Inspect a WOFF Font

from aspose_font.loader import FontLoader

woff_font = FontLoader.open("MyFont.woff")
print(f"Name: {woff_font.font_name}")
print(f"Family: {woff_font.font_family}")
print(f"Glyphs: {woff_font.num_glyphs}")
print(f"Type: {woff_font.font_type}")

Step 4: Read WOFF Metadata

WOFF files may contain an XML metadata block with licensing, credits, and description. Access it through the metadata_xml property.

from aspose_font.loader import FontLoader

font = FontLoader.open("MyFont.woff")
# WOFF fonts may include an XML metadata block
xml = getattr(font, "metadata_xml", None)
if xml:
    print(xml)
else:
    print("No metadata in this WOFF file")

Step 5: Access Inner TTF Tables

Both WoffFont and Woff2Font expose an inner_font property that gives you the underlying TtfFont. Through it you can access all standard OpenType tables.

from aspose_font.loader import FontLoader

font = FontLoader.open("MyFont.woff")
# WOFF wraps a TrueType font; access its tables via inner_font
inner = getattr(font, "inner_font")
tables = inner.ttf_tables

print(f"Units/em: {tables.head.units_per_em}")
print(f"Family name: {tables.name.best_name(1)}")

Step 6: Convert TTF to WOFF

from aspose_font.loader import FontLoader
from aspose_font.converter import FontConverter
from aspose_font import FontType

ttf_font = FontLoader.open("MyFont.ttf")
woff_font = FontConverter.convert(ttf_font, FontType.WOFF)
woff_bytes = woff_font.to_bytes()

from pathlib import Path
Path("MyFont.woff").write_bytes(woff_bytes)

Step 7: Convert TTF to WOFF2

from aspose_font.loader import FontLoader
from aspose_font.converter import FontConverter
from aspose_font import FontType

ttf_font = FontLoader.open("MyFont.ttf")
woff2_font = FontConverter.convert(ttf_font, FontType.WOFF2)
woff2_bytes = woff2_font.to_bytes()

from pathlib import Path
Path("MyFont.woff2").write_bytes(woff2_bytes)

Step 8: Convert Between WOFF and WOFF2

from aspose_font.loader import FontLoader
from aspose_font.converter import FontConverter
from aspose_font import FontType

# WOFF -> WOFF2
woff_font = FontLoader.open("MyFont.woff")
woff2_font = FontConverter.convert(woff_font, FontType.WOFF2)

# WOFF2 -> WOFF
woff2_font = FontLoader.open("MyFont.woff2")
woff_font = FontConverter.convert(woff2_font, FontType.WOFF)

Common Issues and Fixes

FontParseException: Invalid WOFF signature — The file is not a valid WOFF font. Verify the file is not corrupted and starts with the WOFF magic bytes.

FontParseException: WOFF table decompression failed — A compressed table inside the WOFF file is corrupted. Try re-downloading the font file.

Large WOFF2 output — WOFF2 uses Brotli compression which produces smaller files than WOFF 1 (zlib). If your WOFF2 output is unexpectedly large, ensure you are starting from an optimized TTF source.

Frequently Asked Questions

What is the difference between WOFF and WOFF2?

WOFF 1 uses zlib compression and WOFF 2 uses Brotli compression. WOFF2 typically achieves 20-30% better compression than WOFF 1. Both wrap the same underlying TrueType or CFF font data.

Can I access font tables from a WOFF file?

Yes. Use the inner_font property to get the underlying TtfFont, then access tables via inner_font.ttf_tables.

Does the library support WOFF metadata?

Yes. Both WoffFont and Woff2Font expose a metadata_xml property containing the optional XML metadata block.

See Also