all files / fontkit/src/glyph/ Glyph.coffee

74.47% Statements 35/47
75% Branches 6/8
78.57% Functions 11/14
75.56% Lines 34/45
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       284× 284×         20×       189× 168×   21×       21×     168×   168×     168× 21×     147×   147× 147× 147×             168×   40×         62×   247×                                  
Path = require './Path'
unicode = require 'unicode-properties'
 
class Glyph
  get = require('../get')(this)
  constructor: (@id, @codePoints, @_font) ->
    # TODO: get this info from GDEF if available
    @isMark = @codePoints.every unicode.isMark
    @isLigature = @codePoints.length > 1
      
  _getPath: ->
    return new Path
      
  _getCBox: ->
    @path.cbox
    
  _getBBox: ->
    @path.bbox
    
  getMetrics = (table, gid) ->
    if gid < table.metrics.length
      return table.metrics.get gid
      
    res = 
      advance: table.metrics.get(table.metrics.length - 1)?.advance or 0
      bearing: table.bearings.get(gid - table.metrics.length) or 0
      
    return res
    
  _getMetrics: (cbox) ->
    Ireturn @_metrics if @_metrics
      
    {advance:advanceWidth, bearing:leftBearing} = getMetrics @_font.hmtx, @id
    
    # For vertical metrics, use vmtx if available, or fall back to global data from OS/2 or hhea
    if @_font.vmtx
      {advance:advanceHeight, bearing:topBearing} = getMetrics @_font.vmtx, @id
      
    else
      cbox ?= @cbox
      
      Eif (os2 = @_font['OS/2']) and os2.version > 0
        advanceHeight = Math.abs os2.typoAscender - os2.typoDescender
        topBearing = os2.typoAscender - cbox.maxY
    
      else
        hhea = @_font.hhea
        advanceHeight = Math.abs hhea.ascent - hhea.descent
        topBearing = hhea.ascent - cbox.maxY
    
    @_metrics = { advanceWidth, advanceHeight, leftBearing, topBearing }
      
  get 'cbox', ->
    @_cbox ?= @_getCBox()
      
  get 'bbox', ->
    @_bbox ?= @_getBBox()
    
  get 'path', ->
    # Cache the path so we only decode it once
    # Decoding is actually performed by subclasses
    @_path ?= @_getPath()
    
  get 'advanceWidth', ->
    @_advanceWidth ?= @_getMetrics().advanceWidth
    
  get 'advanceHeight', ->
    @_advanceHeight ?= @_getMetrics().advanceHeight
    
  get 'ligatureCaretPositions', ->
    
  render: (ctx, size) ->
    ctx.save()
    
    scale = 1 / @_font.head.unitsPerEm * size
    ctx.scale(scale, scale)
 
    fn = @path.toFunction()
    fn(ctx)
    ctx.fill()
    
    ctx.restore()
    
module.exports = Glyph