Class: Pdfrb::Layout::Frame

Inherits:
Object
  • Object
show all
Defined in:
lib/pdfrb/layout/frame.rb

Overview

A rectangular region of a page where boxes are placed. The Frame tracks which areas are filled and exposes find_available_area to locate the next free region of a given width and height.

Simple case: the Frame is a plain rectangle. Advanced: the shape polygon allows non-rectangular regions (L-shaped, with cutouts around images).

Area tracking: remove_area marks a rectangle as used. The Frame maintains a cursor_y that tracks the lowest free vertical position. find_available_area returns the next position at or above the cursor where the requested (width × height) fits without overlapping any removed area.

Direct Known Subclasses

PolygonFrame

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(left:, bottom:, width:, height:, shape: nil) ⇒ Frame

Returns a new instance of Frame.



21
22
23
24
25
26
27
28
29
# File 'lib/pdfrb/layout/frame.rb', line 21

def initialize(left:, bottom:, width:, height:, shape: nil)
  @left = left.to_f
  @bottom = bottom.to_f
  @width = width.to_f
  @height = height.to_f
  @shape = shape || default_shape
  @cursor_y = top
  @removed_areas = []
end

Instance Attribute Details

#bottomObject (readonly)

Returns the value of attribute bottom.



19
20
21
# File 'lib/pdfrb/layout/frame.rb', line 19

def bottom
  @bottom
end

#cursor_yObject (readonly)

Returns the value of attribute cursor_y.



19
20
21
# File 'lib/pdfrb/layout/frame.rb', line 19

def cursor_y
  @cursor_y
end

#heightObject (readonly)

Returns the value of attribute height.



19
20
21
# File 'lib/pdfrb/layout/frame.rb', line 19

def height
  @height
end

#leftObject (readonly)

Returns the value of attribute left.



19
20
21
# File 'lib/pdfrb/layout/frame.rb', line 19

def left
  @left
end

#shapeObject (readonly)

Returns the value of attribute shape.



19
20
21
# File 'lib/pdfrb/layout/frame.rb', line 19

def shape
  @shape
end

#widthObject (readonly)

Returns the value of attribute width.



19
20
21
# File 'lib/pdfrb/layout/frame.rb', line 19

def width
  @width
end

Instance Method Details

#available_heightObject



82
83
84
# File 'lib/pdfrb/layout/frame.rb', line 82

def available_height
  @cursor_y - @bottom
end

#empty?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/pdfrb/layout/frame.rb', line 78

def empty?
  @removed_areas.empty?
end

#find_available_area(width, height) ⇒ Object

Locate the next free area of (width × height) within this Frame. Scans from the cursor_y downward, checking each candidate y against the removed-areas list. Returns [x, y, w, h] or nil if nothing fits.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/pdfrb/layout/frame.rb', line 43

def find_available_area(width, height)
  w = width.to_f
  h = height.to_f
  return nil if w > @width || h > @height
  return nil if h > available_height

  y = @cursor_y - h
  while y >= @bottom
    if area_free?(@left, y, w, h)
      @cursor_y = y
      return [@left, y, w, h]
    end

    y -= 1
  end
  nil
end

#full?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/pdfrb/layout/frame.rb', line 74

def full?
  @cursor_y <= @bottom
end

#remove_area(x, y, w, h) ⇒ Object

Mark the rectangle at (x, y) of (w × h) as filled. Subsequent find_available_area calls avoid this region. Moves the cursor down when the removed area is at the current cursor.



64
65
66
67
68
69
70
71
72
# File 'lib/pdfrb/layout/frame.rb', line 64

def remove_area(x, y, w, h)
  return if x.nil? || y.nil?

  @removed_areas << [x.to_f, y.to_f, w.to_f, h.to_f]
  # If the removed area touches the cursor, advance it.
  if (y + h) >= @cursor_y - 1
    @cursor_y = [@cursor_y, y].min
  end
end

#reset!Object

Reset the cursor and removed-areas list. Used by the Composer when starting a new page with the same Frame.



88
89
90
91
# File 'lib/pdfrb/layout/frame.rb', line 88

def reset!
  @cursor_y = top
  @removed_areas = []
end

#rightObject



31
32
33
# File 'lib/pdfrb/layout/frame.rb', line 31

def right
  @left + @width
end

#topObject



35
36
37
# File 'lib/pdfrb/layout/frame.rb', line 35

def top
  @bottom + @height
end