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