fs = require 'fs' Data = require '../data' Directory = require './directory' NameTable = require './tables/name' class DFont @open: (filename) -> contents = fs.readFileSync filename new DFont(contents) constructor: (contents) -> @contents = new Data(contents) @parse @contents parse: (data) -> dataOffset = data.readInt() mapOffset = data.readInt() dataLength = data.readInt() mapLength = data.readInt() @map = {} data.pos = mapOffset + 24 # skip header copy, next map handle, file reference, and attrs typeListOffset = data.readShort() + mapOffset nameListOffset = data.readShort() + mapOffset data.pos = typeListOffset maxIndex = data.readShort() for i in [0..maxIndex] by 1 type = data.readString(4) maxTypeIndex = data.readShort() refListOffset = data.readShort() @map[type] = list: [] named: {} pos = data.pos data.pos = typeListOffset + refListOffset for j in [0..maxTypeIndex] by 1 id = data.readShort() nameOfs = data.readShort() attr = data.readByte() b2 = data.readByte() << 16 b3 = data.readByte() << 8 b4 = data.readByte() dataOfs = dataOffset + (0 | b2 | b3 | b4) handle = data.readUInt32() entry = id: id attributes: attr offset: dataOfs handle: handle p = data.pos # if the name is easily accessible, parse it if nameOfs isnt -1 and (nameListOffset + nameOfs < mapOffset + mapLength) data.pos = nameListOffset + nameOfs len = data.readByte() entry.name = data.readString(len) # otherwise jump into the actual ttf and grab it from the 'name' table else if type is 'sfnt' data.pos = entry.offset length = data.readUInt32() font = {} font.contents = new Data(data.slice(data.pos, data.pos + length)) font.directory = new Directory(font.contents) name = new NameTable(font) entry.name = name.fontName[0].raw data.pos = p @map[type].list.push entry @map[type].named[entry.name] = entry if entry.name data.pos = pos return getNamedFont: (name) -> data = @contents pos = data.pos entry = @map.sfnt.named[name] throw new Error "Font #{name} not found in DFont file." unless entry data.pos = entry.offset length = data.readUInt32() ret = data.slice(data.pos, data.pos + length) data.pos = pos return ret module.exports = DFont