Code coverage report for fontkit/src/cff/CFFOperand.coffee

Statements: 98.78% (81 / 82)      Branches: 97.62% (41 / 42)      Functions: 100% (4 / 4)      Lines: 98.57% (69 / 70)      Ignored: none     

All files » fontkit/src/cff/ » CFFOperand.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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 1181 1 1         1             731 469   262 103   159 47   112 45   67 59   8 8 8 25   25 25 24   24 24 17   8             1233 87   1233 18 18   1215 891   324 195   129 39     90         117   117 14 14   103 2   2 2 6   6 1   5 5   6   2 1   101 66   35 20 20 20   15 9 9 9   6 5 5     1 1   1  
class CFFOperand
  FLOAT_EOF = 0xf
  FLOAT_LOOKUP = [
    '0', '1', '2', '3', '4', '5', '6', '7', 
    '8', '9', '.', 'E', 'E-', null, '-'
  ]
  
  FLOAT_ENCODE_LOOKUP = 
    '.': 10
    'E': 11
    'E-': 12
    '-': 14
  
  decode: (stream, value) ->
    if 32 <= value <= 246
      return value - 139
      
    if 247 <= value <= 250
      return (value - 247) * 256 + stream.readUInt8() + 108
      
    if 251 <= value <= 254
      return -(value - 251) * 256 - stream.readUInt8() - 108
      
    if value is 28
      return stream.readInt16BE()
      
    if value is 29
      return stream.readInt32BE()
      
    Eif value is 30
      str = ''
      loop
        b = stream.readUInt8()
        
        n1 = b >> 4
        break if n1 is FLOAT_EOF
        str += FLOAT_LOOKUP[n1]
        
        n2 = b & 15
        break if n2 is FLOAT_EOF
        str += FLOAT_LOOKUP[n2]
      
      return parseFloat(str)
      
    return null
    
  size: (value) ->
    # if the value needs to be forced to the largest size (32 bit)
    # e.g. for unknown pointers, set to 32768
    if value.forceLarge
      value = 32768
    
    if (value | 0) isnt value # floating point
      str = '' + value
      return 1 + Math.ceil (str.length + 1) / 2
      
    else if -107 <= value <= 107
      return 1
 
    else if 108 <= value <= 1131 or -1131 <= value <= -108
      return 2
 
    else if -32768 <= value <= 32767
      return 3
      
    else
      return 5
          
  encode: (stream, value) ->
    # if the value needs to be forced to the largest size (32 bit)
    # e.g. for unknown pointers, save the old value and set to 32768
    val = Number(value)
    
    if value.forceLarge
      stream.writeUInt8 29
      stream.writeInt32BE val
    
    else if (val | 0) isnt val # floating point
      stream.writeUInt8 30
      
      str = '' + val
      for c1, i in str by 2
        n1 = FLOAT_ENCODE_LOOKUP[c1] or +c1
        
        if i is str.length - 1
          n2 = FLOAT_EOF
        else
          c2 = str[i + 1]
          n2 = FLOAT_ENCODE_LOOKUP[c2] or +c2
          
        stream.writeUInt8 (n1 << 4) | (n2 & 15)
        
      if n2 isnt FLOAT_EOF
        stream.writeUInt8 (FLOAT_EOF << 4)
        
    else if -107 <= val <= 107
      stream.writeUInt8 val + 139
 
    else if 108 <= val <= 1131
      val -= 108
      stream.writeUInt8 (val >> 8) + 247
      stream.writeUInt8 val & 0xff
 
    else if -1131 <= val <= -108
      val = -val - 108
      stream.writeUInt8 (val >> 8) + 251
      stream.writeUInt8 val & 0xff
 
    else if -32768 <= val <= 32767
      stream.writeUInt8 28
      stream.writeInt16BE val
      
    else
      stream.writeUInt8 29
      stream.writeInt32BE val
 
module.exports = new CFFOperand