in font/sfnt/sfnt.go [759:866]
func (f *Font) initializeTables(offset int, isDfont bool) (buf1 []byte, finalTableOffset int32, isPostScript bool, err error) {
f.initialOffset = int32(offset)
if int(f.initialOffset) != offset {
return nil, 0, false, errUnsupportedTableOffsetLength
}
// https://www.microsoft.com/typography/otspec/otff.htm "Organization of an
// OpenType Font" says that "The OpenType font starts with the Offset
// Table", which is 12 bytes.
buf, err := f.src.view(nil, offset, 12)
if err != nil {
return nil, 0, false, err
}
// When updating the cases in this switch statement, also update the
// Collection.initialize method.
switch u32(buf) {
default:
return nil, 0, false, errInvalidFont
case dfontResourceDataOffset:
return nil, 0, false, errInvalidSingleFont
case 0x00010000:
// No-op.
case 0x4f54544f: // "OTTO".
isPostScript = true
case 0x74727565: // "true"
// No-op.
case 0x74746366: // "ttcf".
return nil, 0, false, errInvalidSingleFont
}
numTables := int(u16(buf[4:]))
if numTables > maxNumTables {
return nil, 0, false, errUnsupportedNumberOfTables
}
// "The Offset Table is followed immediately by the Table Record entries...
// sorted in ascending order by tag", 16 bytes each.
buf, err = f.src.view(buf, offset+12, 16*numTables)
if err != nil {
return nil, 0, false, err
}
for b, first, prevTag := buf, true, uint32(0); len(b) > 0; b = b[16:] {
tag := u32(b)
if first {
first = false
} else if tag <= prevTag {
return nil, 0, false, errInvalidTableTagOrder
}
prevTag = tag
o, n := u32(b[8:12]), u32(b[12:16])
// For dfont files, the offset is relative to the resource, not the
// file.
if isDfont {
origO := o
o += uint32(offset)
if o < origO {
return nil, 0, false, errUnsupportedTableOffsetLength
}
}
if o > maxTableOffset || n > maxTableLength {
return nil, 0, false, errUnsupportedTableOffsetLength
}
// We ignore the checksums, but "all tables must begin on four byte
// boundries [sic]".
if o&3 != 0 {
return nil, 0, false, errInvalidTableOffset
}
if finalTableOffset < int32(o+n) {
finalTableOffset = int32(o + n)
}
// Match the 4-byte tag as a uint32. For example, "OS/2" is 0x4f532f32.
switch tag {
case 0x43424c43:
f.cblc = table{o, n}
case 0x43464620:
f.cff = table{o, n}
case 0x4f532f32:
f.os2 = table{o, n}
case 0x636d6170:
f.cmap = table{o, n}
case 0x676c7966:
f.glyf = table{o, n}
case 0x47504f53:
f.gpos = table{o, n}
case 0x68656164:
f.head = table{o, n}
case 0x68686561:
f.hhea = table{o, n}
case 0x686d7478:
f.hmtx = table{o, n}
case 0x6b65726e:
f.kern = table{o, n}
case 0x6c6f6361:
f.loca = table{o, n}
case 0x6d617870:
f.maxp = table{o, n}
case 0x6e616d65:
f.name = table{o, n}
case 0x706f7374:
f.post = table{o, n}
}
}
if (f.src.b != nil) && (int(finalTableOffset) > len(f.src.b)) {
return nil, 0, false, errInvalidSourceData
}
return buf, finalTableOffset, isPostScript, nil
}