Extract glyphs, metrics, and licensing from TTF and OTF fonts in Java

Inspect, measure, and analyze TrueType (.ttf) and OpenType (.otf) fonts programmatically with Aspose.Font for Java. Access global font metrics (Ascender, Descender, UnitsPerEm), map glyph indexes via cmap tables, calculate individual character bounding boxes, verify character set support, and enforce embedded licensing restrictions without reliance on native system graphics environments.

 

Deep font inspection is vital for automated typesetting, PDF creation, graphic design automation, and digital publishing pipelines. With Aspose.Font for Java, developers can:

  • Precise text layout: Retrieve exact typographic dimensions (Ascender, Descender, UnitsPerEm) to calculate line heights and text positions accurately.
  • Character set validation: Detect whether a font supports target scripts (e.g., Latin, Cyrillic, or CJK symbols) before rendering.
  • Glyph geometry analysis: Extract glyph bounding boxes (XMin, XMax, YMin, YMax) and advance widths for precise hit-testing and alignment.
  • Compliance and legal checks: Programmatically verify embedded license flags (fsType in OS/2 tables) to ensure document embedding compliance.

Core metrics and glyph features

Global font metrics - Extract Ascender, Descender, TypoAscender, TypoDescender, and UnitsPerEM metrics.

Glyph bounding boxes (BBox) - Retrieve exact bounding coordinates (XMin, XMax, YMin, YMax) and advance widths per glyph.

Unicode cmap mapping - Lookup character-to-glyph mappings across Unicode and platform-specific encoding tables.

Character set support - Validate symbol presence (e.g., Latin charset) by decoding character codes to Glyph IDs.

License restrictions inspection - Inspect OS/2 table flags to determine if a font is Editable, Installable, Preview & Print, or Restricted.

How to extract global font metrics and glyph details

Access overall font dimensions alongside character-specific metrics using the Font.getMetrics() and CMap unicode table structures.

import com.aspose.font.*;
import java.text.MessageFormat;

public class GetFontMetricsAndGlyphs {
    public static void main(String[] args) {
        // Load the TrueType / OpenType font
        String fileName = "path/to/Montserrat-Regular.ttf";
        FontDefinition fd = new FontDefinition(FontType.TTF, new FontFileDefinition("ttf", new FileSystemStreamSource(fileName)));
        TtfFont font = (TtfFont) Font.open(fd);

        // Print global font metrics
        System.out.println("Font Name: " + font.getFontName());
        System.out.println("Glyph Count: " + font.getNumGlyphs());
        
        IFontMetrics metrics = font.getMetrics();
        System.out.println(MessageFormat.format(
            "Metrics: Ascender={0}, Descender={1}, TypoAscender={2}, TypoDescender={3}, UnitsPerEm={4}",
            metrics.getAscender(), metrics.getDescender(), 
            metrics.getTypoAscender(), metrics.getTypoDescender(), metrics.getUnitsPerEM()
        ));

        // Access cmap unicode table to locate character 'A'
        TtfCMapFormatBaseTable cmapTable = null;
        if (font.getTtfTables().getCMapTable() != null) {
            cmapTable = font.getTtfTables().getCMapTable().findUnicodeTable();
        }

        if (cmapTable != null && font.getTtfTables().getGlyfTable() != null) {
            char unicodeA = 'A';
            long glyphIndex = cmapTable.getGlyphIndex(unicodeA);

            if (glyphIndex != 0) {
                Glyph glyph = font.getGlyphById(glyphIndex);
                if (glyph != null) {
                    // Step 4: Extract bounding box and advance width
                    FontBBox bbox = glyph.getGlyphBBox();
                    System.out.println(MessageFormat.format(
                        "Glyph BBox for 'A': Xmin={0}, Xmax={1}, Ymin={2}, Ymax={3}",
                        bbox.getXMin(), bbox.getXMax(), bbox.getYMin(), bbox.getYMax()
                    ));
                    System.out.println("Glyph Width: " + metrics.getGlyphWidth(new GlyphUInt32Id(glyphIndex)));
                }
            }
        }
    }
}

Detect character set support in Java

Verify whether a loaded font contains valid glyph mappings for a specified range of character codes.

import com.aspose.font.*;
import java.text.MessageFormat;

public class CheckFontLicense {
    public static void main(String[] args) {
        String fileName = "path/to/font.ttf";
        FontDefinition fd = new FontDefinition(FontType.TTF, new FontFileDefinition("ttf", new FileSystemStreamSource(fileName)));
        TtfFont font = (TtfFont) Font.open(fd);

        LicenseFlags licenseFlags = null;
        if (font.getTtfTables().getOs2Table() != null) {
            licenseFlags = font.getTtfTables().getOs2Table().getLicenseFlags();
        }

        if (licenseFlags == null || licenseFlags.isFSTypeAbsent()) {
            System.out.println(MessageFormat.format("Font {0} has no embedded license restrictions.", font.getFontName()));
        } else if (licenseFlags.isEditableEmbedding()) {
            System.out.println("License Mode: Editable Embedding allowed.");
        } else if (licenseFlags.isInstallableEmbedding()) {
            System.out.println("License Mode: Installable Embedding allowed.");
        } else if (licenseFlags.isPreviewAndPrintEmbedding()) {
            System.out.println("License Mode: Preview and Print Embedding only.");
        } else if (licenseFlags.isRestrictedLicenseEmbedding()) {
            System.out.println("License Mode: Restricted Embedding - explicit permission required.");
        }
    }
}

Installation and Setup

Include Aspose.Font for Java in your project via Maven.

Package Manager Console Command

<repository>
    <id>AsposeJavaAPI</id>
    <name>Aspose Java API</name>
    <url>https://repository.aspose.com/repo/</url>
</repository>

<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-font</artifactId>
    <version>Latest</version>
</dependency>

FAQ

1. What units are used to measure font metrics in Aspose.Font for Java?

Metrics such as Ascender, Descender, and GlyphBBox are expressed in font units defined by the UnitsPerEM property (commonly 1000 or 2048 units per EM box for TTF/OTF fonts).

2. How do I get the missing glyph representation if a character is unsupported?

When a character is not defined in the font’s encoding table, decodeToGid() returns GlyphUInt32Id.getNotDef(), which corresponds to index 0 (the standard .notdef or missing glyph symbol).

3. Can I inspect tables in OpenType (.otf) fonts as well as TrueType (.ttf)?

Yes. Aspose.Font for Java parses both .ttf and .otf (CFF-based or TrueType-based OpenType) font tables, providing access to OS/2, cmap, glyf, head, and hhea tables.