class Magick::Image::View::Rows

Magick::Image::View::Rows

Public Class Methods

new(view, width, height, rows) click to toggle source
# File lib/rmagick_internal.rb, line 1110
def initialize(view, width, height, rows)
  @view = view
    @width = width
    @height = height
    @rows = rows
end

Public Instance Methods

[](*args) click to toggle source
# File lib/rmagick_internal.rb, line 1117
def [](*args)
  cols(args)
    
    # Both View::Pixels and Magick::Pixel implement Observable
    if @unique
      pixels = @view[@rows[0]*@width + @cols[0]]
        pixels.add_observer(self)
    else
      pixels = View::Pixels.new
        each do |x|
          p = @view[x]
            p.add_observer(self)
            pixels << p
        end
    end
    pixels
end
[]=(*args) click to toggle source
# File lib/rmagick_internal.rb, line 1135
def []=(*args)
  rv = args.delete_at(-1)     # get rvalue
    unless rv.is_a?(Pixel)        # must be a Pixel or a color name
      begin
        rv = Pixel.from_color(rv)
    rescue TypeError
      Kernel.raise TypeError, "cannot convert #{rv.class} into Pixel"
      end
    end
    cols(args)
    each { |x| @view[x] = rv.dup }
    changed
    notify_observers(self)
    nil
end
update(pixel) click to toggle source

A pixel has been modified. Tell the view.

# File lib/rmagick_internal.rb, line 1152
def update(pixel)
  changed
    notify_observers(self)
    pixel.delete_observer(self) # Don't need to hear again.
    nil
end

Private Instance Methods

cols(*args) click to toggle source
# File lib/rmagick_internal.rb, line 1161
def cols(*args)
  @cols = args[0]     # remove the outermost array
    @unique = false
    
    # Convert @rows to an Enumerable object
    case @rows.length
        when 0                      # Create a Range for all the rows
          @rows = Range.new(0, @height, true)
        when 1                      # Range, Array, or a single integer
          # if the single element is already an Enumerable
          # object, get it.
          if @rows.first.respond_to? :each
            @rows = @rows.first
          else
            @rows = Integer(@rows.first)
              if @rows < 0
                @rows += @height
              end
              if @rows < 0 || @rows > @height-1
                Kernel.raise IndexError, "index [#{@rows}] out of range"
              end
              # Convert back to an array
              @rows = Array.new(1, @rows)
              @unique = true
          end
        when 2
          # A pair of integers representing the starting column and the number of columns
          start = Integer(@rows[0])
            length = Integer(@rows[1])
    
            # Negative start -> start from last row
            if start < 0
              start += @height
            end
    
            if start > @height || start < 0 || length < 0
              Kernel.raise IndexError, "index [#{@rows.first}] out of range"
            else
              if start + length > @height
                length = @height - length
                  length = [length, 0].max
              end
            end
            # Create a Range for the specified set of rows
            @rows = Range.new(start, start+length, true)
    end
    
    case @cols.length
        when 0                  # all rows
          @cols = Range.new(0, @width, true)  # convert to range
            @unique = false
        when 1                  # Range, Array, or a single integer
          # if the single element is already an Enumerable
          # object, get it.
          if @cols.first.respond_to? :each
            @cols = @cols.first
              @unique = false
          else
            @cols = Integer(@cols.first)
              if @cols < 0
                @cols += @width
              end
              if @cols < 0 || @cols > @width-1
                Kernel.raise IndexError, "index [#{@cols}] out of range"
              end
              # Convert back to array
              @cols = Array.new(1, @cols)
              @unique &&= true
          end
        when 2
          # A pair of integers representing the starting column and the number of columns
          start = Integer(@cols[0])
            length = Integer(@cols[1])
    
            # Negative start -> start from last row
            if start < 0
              start += @width
            end
    
            if start > @width || start < 0 || length < 0
                ; #nop
            else
                if start + length > @width
                  length = @width - length
                    length = [length, 0].max
                end
            end
            # Create a Range for the specified set of columns
            @cols = Range.new(start, start+length, true)
            @unique = false
    end
end
each() { |j| ... } click to toggle source

iterator called from subscript methods

# File lib/rmagick_internal.rb, line 1255
def each
  maxrows = @height - 1
    maxcols = @width - 1
    
    @rows.each do |j|
      if j > maxrows
        Kernel.raise IndexError, "index [#{j}] out of range"
      end
        @cols.each do |i|
          if i > maxcols
            Kernel.raise IndexError, "index [#{i}] out of range"
          end
            yield j*@width + i
        end
    end
    nil    # useless return value
end