class ScaleGenerator::PNGFormatter

Formats a single fingering as png data

Public Class Methods

new(scale_hash, strings) click to toggle source
# File lib/scale_generator/png_formatter.rb, line 8
def initialize(scale_hash, strings)
  @scale_hash = scale_hash
  @strings = strings
end

Public Instance Methods

print(options={}, show_intervals = false) click to toggle source

Private Instance Methods

get_png_data() click to toggle source
# File lib/scale_generator/png_formatter.rb, line 34
def get_png_data
  width = 160 + (@strings.size * 40)
  height = 340
  
  rvg = Magick::RVG.new(40 + (@strings.size * 40), 210).viewbox(0,0,width,height) do |canvas|
    canvas.background_fill = 'white'
    
    width_of_chord = 20 + (@strings.size * 40)
    margin_side_of_chord = (width - width_of_chord) / 2

    height_of_chord = 200
    margin_top_of_chord = ((height - height_of_chord) * 2 / 3.0).floor
    margin_bottom_of_chord = ((height - height_of_chord) / 3.0).ceil
    
    height_of_fret = height_of_chord / @number_of_frets
    radius_of_finger = (height_of_fret * 0.6) / 2
    
    width_of_fret = width_of_chord / (@strings.size - 1)

    # Draw all horizontal lines
    (@number_of_frets+1).times do |n|
      if n == 0 && @min_fret == 1
        canvas.line(margin_side_of_chord, n*height_of_fret+margin_top_of_chord, width - margin_side_of_chord, n*height_of_fret+margin_top_of_chord).styles(:stroke=>'black', :stroke_width => 5)
      else
        canvas.line(margin_side_of_chord, n*height_of_fret+margin_top_of_chord, width - margin_side_of_chord, n*height_of_fret+margin_top_of_chord)
      end
    end
    
    (@number_of_frets).times do |i|
      canvas.text(margin_side_of_chord - radius_of_finger - 4, i*height_of_fret+margin_top_of_chord + height_of_fret / 2 + 10) do |txt|
        txt.tspan(@min_fret + i).styles(
          :text_anchor => 'end',
          :font_size => 24,
          :font_family => 'helvetica',
          :fill => 'black')
      end
    end

    # bar_drawn = false
    fret_index = @strings.size
    @strings.each_with_index do |note, i|
      # Draw vertical lines
      canvas.line(i*width_of_fret+margin_side_of_chord, margin_top_of_chord, i*width_of_fret+margin_side_of_chord, height - margin_bottom_of_chord)

      str_ctx = @scale_hash[fret_index]
      fret_index = fret_index - 1
      str_ctx[:frets].each_with_index do | fret, ii |
        # Add a finger
        if str_ctx[:intervals][ii] == 1
          canvas.circle(radius_of_finger, i*width_of_fret+margin_side_of_chord,
            (fret - @min_fret + 1)*height_of_fret - (height_of_fret / 2) + margin_top_of_chord).styles(:fill => 'green')
        else
          canvas.circle(radius_of_finger, i*width_of_fret+margin_side_of_chord,
            (fret - @min_fret + 1)*height_of_fret - (height_of_fret / 2) + margin_top_of_chord)
        end

        # Add fingering to finger dot
        if str_ctx[:fingers][ii] && !@show_intervals
          canvas.text(i*width_of_fret+margin_side_of_chord + 1, (fret - @min_fret + 1)*height_of_fret - (height_of_fret / 2) + margin_top_of_chord + 8) do |txt| 
            txt.tspan(str_ctx[:fingers][ii].to_s).styles(:text_anchor => 'middle',
            :font_size => 24, 
            :font_family => 'helvetica',
            :fill => 'white')
          end
        elsif @show_intervals
          canvas.text(i*width_of_fret+margin_side_of_chord + 1, (fret - @min_fret + 1)*height_of_fret - (height_of_fret / 2) + margin_top_of_chord + 8) do |txt| 
            txt.tspan(str_ctx[:intervals][ii].to_s).styles(:text_anchor => 'middle',
            :font_size => 24, 
            :font_family => 'helvetica',
            :fill => 'white')
          end
        end
      end
      
      canvas.text(i*width_of_fret+margin_side_of_chord, height - margin_bottom_of_chord + 20) do |txt| 
        txt.tspan(note).styles(:text_anchor => 'middle',
        :font_size => 18, 
        :font_family => 'helvetica',
        :fill => 'black')
      end
    end
    
    if @label
      canvas.text(width / 2, margin_top_of_chord / 2) do |txt|
        txt.tspan(@label).styles(:text_anchor => 'middle',
          :font_size => 36,
          :font_family => 'helvetica',
          :fill => 'black',
          :font_weight => 'bold')
      end
    end

  end
  img = rvg.draw
  img = img.trim
  img.format = 'PNG'
  img.to_blob
end