   ctx.fillStyle = 'white'
   ctx.fillRect 0, 0, canvas.width, canvas.height
 
+draw_title = (text, {font, x, y, gravity}) ->
+  gravity ||= ''
+  ctx.font = font if font
+  m = ctx.measureText(text)
+  # x -= m.width / 2
+  y -= m.emHeightDescent if gravity.match(/^bottom$/)
+  y += m.emHeightAscent if gravity.match(/^top|topLeft|topRight$/)
+  ctx.fillText text, x, y
+
+with_context = (ctx, fn) ->
+  ctx.save()
+  fn()
+  ctx.restore()
+
 filename = (name) -> DefaultFilename = name
 
 save_canvas_to_png = (canvas, fname) ->

  ctx = canvas.getContext('2d')
  ctx.textDrawingMode = 'glyph' if pdf
  erase_background()
  ctx.save()
  ctx.translate page_margin, page_margin
  draw_page ctx
  ctx.restore()
  unless pdf
    filename = "#{DefaultFilename or 'test'}.png"
    fs.writeFile BuildDirectory + filename, canvas.toBuffer()

  degree_colors = ['red', 'blue', 'green', 'orange']
  other_colors = ['rgba(255,0,0 ,.1)', 'rgba(0,0,255, 0.1)', 'rgba(0,255,0, 0.1)', 'rgba(255,0,255, 0.1)']

  grid cols: 4, rows: 3
  , cell_width: padded_fretboard_width
  , cell_height: padded_fretboard_height
  , gutter_height: 20
  , header_height: 40
  , (cell) ->

    ctx.fillStyle = 'rgb(128, 128, 128)'
    draw_title "#{chord.name} Chords", font: '20px Impact'
    , x: 0
    , y: 0
    , gravity: 'top'

    ctx.save()
    ctx.translate 285, 20
    ctx.scale 0.85,0.85
    draw_pitch_diagram chord.pitch_classes, degree_colors
    ctx.restore()
