class PDF::Reader::Rectangle

PDFs represent rectangles all over the place. They’re 4 element arrays, like this:

[A, B, C, D]

Four element arrays are yucky to work with though, so here’s a class that’s better. Initialize it with the 4 elements, and get utility functions (width, height, etc) for free.

By convention the first two elements are x1, y1, the co-ords for the bottom left corner of the rectangle. The third and fourth elements are x2, y2, the co-ords for the top left corner of the rectangle. It’s valid for the alternative corners to be used though, so we don’t assume which is which.

Attributes

bottom_left[R]
bottom_right[R]
top_left[R]
top_right[R]

Public Class Methods

from_array(arr) click to toggle source
# File lib/pdf/reader/rectangle.rb, line 29
def self.from_array(arr)
  if arr.size != 4
    raise ArgumentError, "Only 4-element Arrays can be converted to a Rectangle"
  end

  PDF::Reader::Rectangle.new(
    arr[0].to_f,
    arr[1].to_f,
    arr[2].to_f,
    arr[3].to_f,
  )
end
new(x1, y1, x2, y2) click to toggle source
# File lib/pdf/reader/rectangle.rb, line 25
def initialize(x1, y1, x2, y2)
  set_corners(x1, y1, x2, y2)
end

Public Instance Methods

==(other) click to toggle source
# File lib/pdf/reader/rectangle.rb, line 42
def ==(other)
  to_a == other.to_a
end
apply_rotation(degrees) click to toggle source
# File lib/pdf/reader/rectangle.rb, line 69
def apply_rotation(degrees)
  return if degrees != 90 && degrees != 180 && degrees != 270

  if degrees == 90
    new_x1 = bottom_left.x
    new_y1 = bottom_left.y - width
    new_x2 = bottom_left.x + height
    new_y2 = bottom_left.y
  elsif degrees == 180
    new_x1 = bottom_left.x - width
    new_y1 = bottom_left.y - height
    new_x2 = bottom_left.x
    new_y2 = bottom_left.y
  elsif degrees == 270
    new_x1 = bottom_left.x - height
    new_y1 = bottom_left.y
    new_x2 = bottom_left.x
    new_y2 = bottom_left.y + width
  end
  set_corners(new_x1 || 0, new_y1 || 0, new_x2 || 0, new_y2 || 0)
end
contains?(point) click to toggle source
# File lib/pdf/reader/rectangle.rb, line 54
def contains?(point)
  point.x >= bottom_left.x && point.x <= top_right.x &&
    point.y >= bottom_left.y && point.y <= top_right.y
end
height() click to toggle source
# File lib/pdf/reader/rectangle.rb, line 46
def height
  top_right.y - bottom_right.y
end
to_a() click to toggle source

A pdf-style 4-number array

# File lib/pdf/reader/rectangle.rb, line 60
def to_a
  [
    bottom_left.x,
    bottom_left.y,
    top_right.x,
    top_right.y,
  ]
end
width() click to toggle source
# File lib/pdf/reader/rectangle.rb, line 50
def width
  bottom_right.x - bottom_left.x
end

Private Instance Methods

set_corners(x1, y1, x2, y2) click to toggle source
# File lib/pdf/reader/rectangle.rb, line 93
def set_corners(x1, y1, x2, y2)
  @bottom_left = PDF::Reader::Point.new(
    [x1, x2].min,
    [y1, y2].min,
  )
  @bottom_right = PDF::Reader::Point.new(
    [x1, x2].max,
    [y1, y2].min,
  )
  @top_left = PDF::Reader::Point.new(
    [x1, x2].min,
    [y1, y2].max,
  )
  @top_right = PDF::Reader::Point.new(
    [x1, x2].max,
    [y1, y2].max,
  )
end