Code coverage report for fontkit/src/CFFFont.coffee

Statements: 80.33% (49 / 61)      Branches: 70% (14 / 20)      Functions: 76.92% (10 / 13)      Lines: 85.45% (47 / 55)      Ignored: none     

All files » fontkit/src/ » CFFFont.coffee
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 971 1 1 1 1   1 1   8     6             8 8 8 48   8     8           8   8           8     18 10   8   1 146   1 2   1     1       8 8     8   8   1   7 7 7   7 41   41 18 23 16   7         30 5 5   25   1  
r = require 'restructure'
CFFIndex = require './cff/CFFIndex'
CFFTop = require './cff/CFFTop'
CFFPrivateDict = require './cff/CFFPrivateDict'
standardStrings = require './cff/CFFStandardStrings'
  
class CFFFont
  get = require('./get')(this)
  constructor: (@stream) ->
    @decode()
  
  @decode: (stream) ->
    return new CFFFont(stream)
    
  @open: (filename, name) ->
    contents = require?('fs').readFileSync filename
    return new CFFFont new r.DecodeStream(contents)  
      
  decode: ->
    start = @stream.pos
    top = CFFTop.decode(@stream)
    for key, val of top
      this[key] = val
    
    Iif @topDictIndex.length isnt 1
      throw new Error "Only a single font is allowed in CFF"
      
    @isCIDFont = @topDict.ROS?
      
    # if @topDict.CharstringType isnt 2
    #   throw new Error "Only CharstringType 2 is supported"
      
    # charset?
    switch @topDictIndex[0].Encoding
      when 0 # standard encoding
        break
      when 1 # expert encoding
        break
      else # custom
        break
    
    return this
  
  string: (sid) ->
    if sid <= standardStrings.length
      return standardStrings[sid]
    
    return @stringIndex[sid - standardStrings.length]
    
  get 'topDict', ->
    return @topDictIndex[0]
      
  get 'postscriptName', ->
    return @nameIndex[0]
    
  get 'fullName', ->
    return @string @topDict.FullName
    
  get 'familyName', ->
    return @string @topDict.FamilyName
    
  getCharString: (glyph) ->
    @stream.pos = @topDict.CharStrings[glyph].offset
    return @stream.readBuffer @topDict.CharStrings[glyph].length
    
  fdForGlyph: (gid) ->
    Ireturn null unless @topDict.FDSelect
    
    switch @topDict.FDSelect.version
      when 0
        return @topDict.FDSelect.fds[gid]
      when 3
        ranges = @topDict.FDSelect.ranges
        low = 0
        high = ranges.length - 1
      
        while low <= high
          mid = (low + high) >> 1
        
          if gid < ranges[mid].first
            high = mid - 1
          else if gid > ranges[mid + 1]?.first
            low = mid + 1
          else
            return ranges[mid].fd
      else
        throw new Error "Unknown FDSelect version: #{@topDict.FDSelect.version}"
    
  privateDictForGlyph: (gid) ->
    if @topDict.FDSelect
      fd = @fdForGlyph gid
      return Eif fd? then @topDict.FDArray[fd]?.Private else null
      
    return @topDict.Private
 
module.exports = CFFFont