mirror of
https://github.com/foliojs/pdfkit.git
synced 2025-12-08 20:15:54 +00:00
101 lines
2.7 KiB
CoffeeScript
101 lines
2.7 KiB
CoffeeScript
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 |