package opentype
import (
"encoding/binary"
"errors"
"fmt"
"io"
)
type otfEntry struct {
Tag Tag
CheckSum uint32
Offset uint32
Length uint32
}
const (
otfHeaderSize = 12
otfEntrySize = 16
)
func readOTFHeader(r io .Reader ) (flavor Tag , numTables uint16 , err error ) {
var buf [otfHeaderSize ]byte
if _ , err := r .Read (buf [:]); err != nil {
return 0 , 0 , fmt .Errorf ("invalid OpenType header: %s" , err )
}
return NewTag (buf [0 ], buf [1 ], buf [2 ], buf [3 ]), binary .BigEndian .Uint16 (buf [4 :6 ]), nil
}
func readOTFEntry(r io .Reader ) (otfEntry , error ) {
var (
buf [otfEntrySize ]byte
entry otfEntry
)
if _ , err := io .ReadFull (r , buf [:]); err != nil {
return entry , fmt .Errorf ("invalid directory entry: %s" , err )
}
entry .Tag = Tag (binary .BigEndian .Uint32 (buf [0 :4 ]))
entry .CheckSum = binary .BigEndian .Uint32 (buf [4 :8 ])
entry .Offset = binary .BigEndian .Uint32 (buf [8 :12 ])
entry .Length = binary .BigEndian .Uint32 (buf [12 :16 ])
return entry , nil
}
func parseOTF(file Resource , offset uint32 , relativeOffset bool ) (*Loader , error ) {
_ , err := file .Seek (int64 (offset ), io .SeekStart )
if err != nil {
return nil , fmt .Errorf ("invalid offset: %s" , err )
}
flavor , numTables , err := readOTFHeader (file )
if err != nil {
return nil , err
}
pr := &Loader {
file : file ,
tables : make (map [Tag ]tableSection , numTables ),
Type : flavor ,
}
for i := 0 ; i < int (numTables ); i ++ {
entry , err := readOTFEntry (file )
if err != nil {
return nil , err
}
if _ , found := pr .tables [entry .Tag ]; found {
continue
}
sec := tableSection {
offset : entry .Offset ,
length : entry .Length ,
}
if relativeOffset {
sec .offset += offset
if sec .offset < offset {
return nil , errors .New ("unsupported table offset or length" )
}
}
pr .tables [entry .Tag ] = sec
}
return pr , nil
}
The pages are generated with Golds v0.8.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .