# File lib/graster.rb, line 183
  def render_tiled_image gcode, gmask
    debug "rendering tiled image"
    job_id = job_hash
    hyst = -@scale[0]/2
    gcode.comment "raster gcode for job #{job_id}"
    gcode.comment "image: #{@image.filename} #{@image.size.inspect}"
    gcode.comment "config: #{@config.inspect}"

    gcode.preamble :feed => @config[:feed], :mask => true
    gmask.preamble

    @config[:repeat][1].times do |ytile|
      debug "begin tile row #{ytile}"
      @tiled_rows.each_with_index do |spans, ypix|
        debug "pixel row #{ypix} is empty" if spans.empty?
        unless spans.empty?
          yinches = y_inches(ytile, ypix)
          forward = spans[0][0] < spans[-1][1]
          dir = forward ? 1 : -1

          debug "pixel row #{ypix} at #{yinches} inches going #{forward ? 'forward' : 'backward'} with #{spans.size} spans"

          gcode.g0 :x => spans[0][0] - dir*@config[:overshoot], :y => yinches
          gcode.g1 :x => spans[-1][1] + dir*@config[:overshoot], :y => yinches
          gmask.begin_row forward
          spans.each {|span| gmask.span forward, span[0]+hyst, span[1]+hyst }
        end # unless spans.empty?
      end # @image.each_row
      debug "end tile row #{ytile}"
    end # @config[:repeat][i].times

    gcode.epilogue
  end