Allow loading fonts from Buffers in addition to filenames

This commit is contained in:
Devon Govett 2014-04-12 20:44:19 -07:00
parent 801981728c
commit bb9b77cb82
3 changed files with 68 additions and 26 deletions

View File

@ -6,24 +6,32 @@ By Devon Govett
TTFFont = require './font/ttf'
AFMFont = require './font/afm'
Subset = require './font/subset'
zlib = require 'zlib'
fs = require 'fs'
class PDFFont
constructor: (@document, @filename, @family, @id) ->
constructor: (@document, src, family, @id) ->
@ref = @document.ref()
if @filename in @_standardFonts
@isAFM = true
@font = AFMFont.open __dirname + "/font/data/#{@filename}.afm"
@registerAFM()
if typeof src is 'string'
if src of STANDARD_FONTS
@isAFM = true
@font = AFMFont.open __dirname + "/font/data/#{@filename}.afm"
@registerAFM()
else if /\.(ttf|ttc)$/i.test src
@font = TTFFont.open src, family
@subset = new Subset @font
@registerTTF()
else if /\.(ttf|ttc)$/i.test @filename
@font = TTFFont.open @filename, @family
@subset = new Subset @font
@registerTTF()
else if /\.dfont$/i.test @filename
@font = TTFFont.fromDFont @filename, @family
else if /\.dfont$/i.test src
@font = TTFFont.fromDFont src, family
@subset = new Subset @font
@registerTTF()
else
throw new Error 'Not a supported font format or standard PDF font.'
else if Buffer.isBuffer(src)
@font = TTFFont.fromBuffer src, family
@subset = new Subset @font
@registerTTF()
@ -84,7 +92,7 @@ class PDFFont
throw new Error 'No unicode cmap for font' if not @font.cmap.unicode
embedTTF: ->
data = @subset.encode()
data = @subset.encode()
fontfile = @document.ref()
fontfile.write data

View File

@ -22,7 +22,25 @@ class TTFFont
@fromDFont: (filename, family) ->
dfont = DFont.open(filename)
new TTFFont dfont.getNamedFont(family)
@fromBuffer: (buffer, family) ->
try
ttf = new TTFFont buffer, family
# check some tables to make sure this is valid
unless ttf.head.exists and ttf.name.exists and ttf.cmap.exists
# if not, try a DFont
dfont = new DFont buffer
ttf = new TTFFont dfont.getNamedFont(family)
# check again after dfont
unless ttf.head.exists and ttf.name.exists and ttf.cmap.exists
throw new Error 'Invalid TTF file in DFont'
return ttf
catch e
throw new Error 'Unknown font format in buffer: ' + e.message
constructor: (@rawData, name) ->
data = @contents = new Data(rawData)

View File

@ -15,25 +15,41 @@ module.exports =
# Set the default font
@font 'Helvetica'
font: (filename, family, size) ->
font: (src, family, size) ->
if typeof family is 'number'
size = family
family = null
if @_registeredFonts[filename]
{filename, family} = @_registeredFonts[filename]
# check registered fonts if src is a string
if typeof src is 'string' and @_registeredFonts[src]
cacheKey = src
{src, family} = @_registeredFonts[src]
else
cacheKey = family or src
cacheKey = null unless typeof cacheKey is 'string'
@fontSize size if size?
family ?= filename
if @_fontFamilies[family]
@_font = @_fontFamilies[family]
# fast path: check if the font is already in the PDF
if font = @_fontFamilies[cacheKey]
@_font = font
return this
# load the font
id = 'F' + (++@_fontCount)
@_font = new PDFFont(this, filename, family, id)
@_fontFamilies[family] = @_font
@_font = new PDFFont(this, src, family, id)
# check for existing font familes with the same name already in the PDF
# useful if the font was passed as a buffer
if font = @_fontFamilies[@_font.name]
@_font = font
return this
# save the font for reuse later
if cacheKey
@_fontFamilies[cacheKey] = @_font
@_fontFamilies[@_font.name] = @_font
return this
fontSize: (@_fontSize) ->
@ -42,9 +58,9 @@ module.exports =
currentLineHeight: (includeGap = false) ->
@_font.lineHeight @_fontSize, includeGap
registerFont: (name, path, family) ->
registerFont: (name, src, family) ->
@_registeredFonts[name] =
filename: path
src: src
family: family
return this