class Magick::Image::View::Rows

Magick::Image::View::Rows

Public Class Methods

new(view, width, height, rows) click to toggle source
# File lib/RMagick.rb, line 1124
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.rb, line 1131
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.rb, line 1149
def []=(*args)
    rv = args.delete_at(-1)     # get rvalue
    if ! 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.rb, line 1166
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.rb, line 1175
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.rb, line 1270
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