All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gems.chunky_png-1.2.8.lib.chunky_png.point.rb Maven / Gradle / Ivy

module ChunkyPNG
  
  # Factory method to create {ChunkyPNG::Point} instances.
  # 
  # This method tries to be as flexible as possible with regards to the given input: besides 
  # explicit coordinates, this method also accepts arrays, hashes, strings, {ChunkyPNG::Dimension}
  # instances and anything that responds to :x and :y.
  # 
  # @overload Point(x, y)
  #   @param [Integer, :to_i] x The x-coordinate
  #   @param [Integer, :to_i] y The y-coordinate
  #   @return [ChunkyPNG::Point] The instantiated point.
  #
  # @overload Point(array)
  #   @param [Array] array A two element array which represent the x- and y-coordinate.
  #   @return [ChunkyPNG::Point] The instantiated point.
  #
  # @overload Point(hash)
  #   @param [Hash] array A hash with the :x or 'x' and :y or
  #     'y' keys set, which will be used as coordinates.
  #   @return [ChunkyPNG::Point] The instantiated point.
  #
  # @overload Point(string)
  #   @param [String] string A string that contains the coordinates, e.g. '0, 4',
  #     '(0 4)', [0,4}', etc.
  #   @return [ChunkyPNG::Point] The instantiated point.
  #
  # @return [ChunkyPNG::Point]
  # @raise [ArgumentError] if the arguments weren't understood.
  # @see ChunkyPNG::Point
  def self.Point(*args)
    case args.length
      when 2; ChunkyPNG::Point.new(*args)
      when 1; case source = args.first
          when ChunkyPNG::Point; source
          when ChunkyPNG::Dimension; ChunkyPNG::Point.new(source.width, source.height)
          when Array; ChunkyPNG::Point.new(source[0], source[1])
          when Hash; ChunkyPNG::Point.new(source[:x] || source['x'], source[:y] || source['y'])
          when ChunkyPNG::Point::POINT_REGEXP; ChunkyPNG::Point.new($1.to_i, $2.to_i)
          else 
            if source.respond_to?(:x) && source.respond_to?(:y)
              ChunkyPNG::Point.new(source.x, source.y)
            else
              raise ArgumentError, "Don't know how to construct a point from #{source.inspect}!"
            end
        end
      else raise ArgumentError, "Don't know how to construct a point from #{args.inspect}!"
    end
  end
  
  # Simple class that represents a point on a canvas using an x and y coordinate.
  #
  # This class implements some basic methods to handle comparison, the splat operator and
  # bounds checking that make it easier to work with coordinates.
  #
  # @see ChunkyPNG.Point
  class Point
    
    # @return [Regexp] The regexp to parse points from a string.
    # @private
    POINT_REGEXP = /^[\(\[\{]?(\d+)\s*[,]?\s*(\d+)[\)\]\}]?$/

    # @return [Integer] The x-coordinate of the point.
    attr_accessor :x

    # @return [Integer] The y-coordinate of the point.
    attr_accessor :y
    
    # Initializes a new point instance.
    # @param [Integer, :to_i] x The x-coordinate.
    # @param [Integer, :to_i] y The y-coordinate.
    def initialize(x, y)
      @x, @y = x.to_i, y.to_i
    end
    
    # Checks whether 2 points are identical.
    # @return [true, false] true iff the x and y coordinates match
    def eql?(other)
      other.x == x && other.y == y
    end
    
    alias_method :==, :eql?
    
    # Compares 2 points.
    #
    # It will first compare the y coordinate, and it only takes the x-coordinate into
    # account if the y-coordinates of the points are identical. This way, an array of
    # points will be sorted into the order in which they would occur in the pixels
    # array returned by {ChunkyPNG::Canvas#pixels}.
    #
    # @param [ChunkyPNG::Point] other The point to compare this point with.
    # @return [-1, 0, 1] -1 If this point comes before the other one, 1
    #   if after, and 0 if the points are identical.
    def <=>(other)
      ((y <=> other.y) == 0) ? x <=> other.x : y <=> other.y
    end
    
    # Converts the point instance to an array.
    # @return [Array] A 2-element array, i.e. [x, y].
    def to_a
      [x, y]
    end
    
    alias_method :to_ary, :to_a
    
    # Checks whether the point falls into a dimension
    # @param [ChunkyPNG::Dimension, ...] dimension_like The dimension of which the bounds 
    #   should be taken for the check.
    # @return [true, false] true iff the x and y coordinate fall width the width 
    #   and height of the dimension.
    def within_bounds?(*dimension_like)
      ChunkyPNG::Dimension(*dimension_like).include?(self)
    end
  end
end




© 2015 - 2024 Weber Informatics LLC | Privacy Policy