how can I get font metadata by font file (.ttf,.otf,.woff2,.woff) using javascript?

210 Views Asked by At

I am working on a web-based project that is completely in Javascript. In it, I want users to be able to format their text exactly as they want. I tried opentype.js to resolve, but it is to heavy. I just want to extract font file meta data.

input:  .ttf,.otf,.woff2,.woff font file

output: font metadata
2

There are 2 best solutions below

1
Utkarsh Chandra Srivastava On

This package might do the job https://www.npmjs.com/package/occupant-website-auto-gen

The input to these is a set of font file paths, which will produce a set of objects that describe metadata about the fonts.

0
Carson On

I'm not quite sure what you mean by meta information.

If it doesn't involve glyf, some tables are relatively independent and thus easier to extract content from.

Font files aren't designed with human readability in mind; instead, they undergo various special processes to save space. Some use compression, like the Brotli algorithm used by woff2; others use flags, such as those mentioned with glyf.

Converting these details into a human-readable format like JSON would significantly increase the file size.

I haven't come across any open-source and comprehensive font parsing tools (though fonttools is pretty good). Font data is continuously updated, for instance, with the addition of a new table, so related parsing tools must also be updated to handle this. Additionally, some adjustments are made (or not made) due to considerations of certain software limitations, making font files incredibly complex.

Parsing fonts involves reading binary data, so the programming language doesn't have much impact. JavaScript's DataView can also assist with this.

Below is the data structure(go) of the related files. With this information, you can use the offset and length to find the content or information provided by the table.

sfnt

type TTFont struct {
    TableHeader
    TableRecords []TableRecord
}

type TableHeader struct {
    SFNTVersion   uint32
    NumTables     uint16
    SearchRange   uint16
    EntrySelector uint16
    RangeShift    uint16
}

type TableRecord struct {
    Tag      [4]byte
    CheckSum uint32
    Offset   uint32
    Length   uint32
}

OpenType is actually quite similar to TTF; the biggest difference is the addition of either the CFF or CFF2 table. Additionally, for font rendering, one must also consider more complex tables like GSUP and GPOS, which require extra attention.


woff2

type Woff2 struct {
    Header    Header
    Directory []TableDirectoryEntry

    CompressData []byte // Size: Header.TotalCompressedSize
    MetaData       []byte // Size: Header.MetaLength
    PrivateData    []byte // Size: Header.PrivateLength
}

type Header struct {
    Signature           [4]byte // wOF2 // 0x774F4632
    Flavor              uint32  // sfntVersion
    Length              uint32
    NumTables           uint16
    Reserved            uint16
    TotalSFNTSize       uint32
    TotalCompressedSize uint32
    MajorVersion        uint16
    MinorVersion        uint16

    MetaOffset     uint32
    MetaLength     uint32
    MetaOrigLength uint32

    PrivateOffset uint32
    PrivateLength uint32
}

type TableDirectoryEntry struct {
    Flags uint8

    // (optional) for Flags & 0b__111111
    Tag [4]byte

    // OrigLength Size: Variable length: 1~5byte which mean uint32, see UIntBase128
    OrigLength []byte

    // (optional) TransformLength see flags 0b^^______   
    // type: UIntBase128
    TransformLength []byte
}

For further parsing of each piece of information, I recommend consulting related documentation, especially those from