diff --git a/lib/font.coffee b/lib/font.coffee index 06654b6..184c44a 100644 --- a/lib/font.coffee +++ b/lib/font.coffee @@ -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 diff --git a/lib/font/ttf.coffee b/lib/font/ttf.coffee index 66e0a38..59023b1 100644 --- a/lib/font/ttf.coffee +++ b/lib/font/ttf.coffee @@ -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) diff --git a/lib/mixins/fonts.coffee b/lib/mixins/fonts.coffee index b56872f..60e6bc0 100644 --- a/lib/mixins/fonts.coffee +++ b/lib/mixins/fonts.coffee @@ -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