Class: HexaPDF::Layout::Box
- Inherits:
-
Object
- Object
- HexaPDF::Layout::Box
- Defined in:
- lib/hexapdf/layout/box.rb
Overview
The base class for all layout boxes.
HexaPDF uses the following box model:
-
Each box can specify a width and height. Padding and border are inside, the margin outside of this rectangle.
-
The #content_width and #content_height accessors can be used to get the width and height of the content box without padding and the border.
-
If width or height is set to zero, they are determined automatically during layouting.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#height ⇒ Object
readonly
The height of the box, including padding and/or borders.
-
#style ⇒ Object
readonly
The style to be applied.
-
#width ⇒ Object
readonly
The width of the box, including padding and/or borders.
Class Method Summary collapse
-
.create(width: 0, height: 0, content_box: false, **style, &block) ⇒ Object
Creates a new Box object, using the provided block as drawing block (see ::new).
Instance Method Summary collapse
-
#content_height ⇒ Object
The height of the content box, i.e.
-
#content_width ⇒ Object
The width of the content box, i.e.
-
#draw(canvas, x, y) ⇒ Object
Draws the content of the box onto the canvas at the position (x, y).
-
#empty? ⇒ Boolean
Returns
true
if no drawing operations are performed. -
#fit(available_width, available_height, frame) ⇒ Object
Fits the box into the Frame and returns
true
if fitting was successful. -
#initialize(width: 0, height: 0, style: Style.new, &block) ⇒ Box
constructor
:call-seq: Box.new(width: 0, height: 0, style: Style.new) {|canv, box| block} -> box.
Constructor Details
#initialize(width: 0, height: 0, style: Style.new, &block) ⇒ Box
:call-seq:
Box.new(width: 0, height: 0, style: Style.new) {|canv, box| block} -> box
Creates a new Box object with the given width and height that uses the provided block when it is asked to draw itself on a canvas (see #draw).
Since the final location of the box is not known beforehand, the drawing operations inside the block should draw inside the rectangle (0, 0, content_width, content_height) - note that the width and height of the box may not be known beforehand.
93 94 95 96 97 98 99 |
# File 'lib/hexapdf/layout/box.rb', line 93 def initialize(width: 0, height: 0, style: Style.new, &block) @width = @initial_width = width @height = @initial_height = height @style = (style.kind_of?(Style) ? style : Style.new(style)) @draw_block = block @outline = nil end |
Instance Attribute Details
#height ⇒ Object (readonly)
The height of the box, including padding and/or borders.
71 72 73 |
# File 'lib/hexapdf/layout/box.rb', line 71 def height @height end |
#style ⇒ Object (readonly)
The style to be applied.
Only the following properties are used:
-
Style#background_color
-
Style#padding
-
Style#border
-
Style#overlay_callback
-
Style#underlay_callback
82 83 84 |
# File 'lib/hexapdf/layout/box.rb', line 82 def style @style end |
#width ⇒ Object (readonly)
The width of the box, including padding and/or borders.
68 69 70 |
# File 'lib/hexapdf/layout/box.rb', line 68 def width @width end |
Class Method Details
.create(width: 0, height: 0, content_box: false, **style, &block) ⇒ Object
Creates a new Box object, using the provided block as drawing block (see ::new). Any additional keyword arguments are used for creating the box’s Style object.
If content_box
is true
, the width and height are taken to mean the content width and height and the style’s padding and border are removed from them appropriately.
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/hexapdf/layout/box.rb', line 56 def self.create(width: 0, height: 0, content_box: false, **style, &block) style = Style.new(style) if content_box width += style.padding.left + style.padding.right + style.border.width.left + style.border.width.right height += style.padding.top + style.padding.bottom + style.border.width.top + style.border.width.bottom end new(width: width, height: height, style: style, &block) end |
Instance Method Details
#content_height ⇒ Object
The height of the content box, i.e. without padding and/or borders.
108 109 110 111 |
# File 'lib/hexapdf/layout/box.rb', line 108 def content_height [0, height - (@style.padding.top + @style.padding.bottom + @style.border.width.top + @style.border.width.bottom)].max end |
#content_width ⇒ Object
The width of the content box, i.e. without padding and/or borders.
102 103 104 105 |
# File 'lib/hexapdf/layout/box.rb', line 102 def content_width [0, width - (@style.padding.left + @style.padding.right + @style.border.width.left + @style.border.width.right)].max end |
#draw(canvas, x, y) ⇒ Object
Draws the content of the box onto the canvas at the position (x, y).
The coordinate system is translated so that the origin is at the bottom left corner of the **content box** during the drawing operations.
The block specified when creating the box is invoked with the canvas and the box as arguments. Subclasses can specify an on-demand drawing method by setting the @draw_block instance variable to nil
or a valid block. This is useful to avoid unnecessary set-up operations when the block does nothing.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/hexapdf/layout/box.rb', line 132 def draw(canvas, x, y) if style.background_color? && style.background_color canvas.save_graphics_state do canvas.fill_color(style.background_color).rectangle(x, y, width, height).fill end end style.underlays.draw(canvas, x, y, self) if style.underlays? style.border.draw(canvas, x, y, width, height) if style.border? if @draw_block canvas.translate(x + style.padding.left + style.border.width.left, y + style.padding.bottom + style.border.width.bottom) do @draw_block.call(canvas, self) end end style..draw(canvas, x, y, self) if style. end |
#empty? ⇒ Boolean
Returns true
if no drawing operations are performed.
153 154 155 156 157 158 159 |
# File 'lib/hexapdf/layout/box.rb', line 153 def empty? !(@draw_block || (style.background_color? && style.background_color) || (style.underlays? && !style.underlays.none?) || (style.border? && !style.border.none?) || (style. && !style..none?)) end |
#fit(available_width, available_height, frame) ⇒ Object
Fits the box into the Frame and returns true
if fitting was successful.
The default implementation uses the whole available space for width and height if they were initially set to 0. Otherwise the specified dimensions are used.
117 118 119 120 121 |
# File 'lib/hexapdf/layout/box.rb', line 117 def fit(available_width, available_height, frame) @width = (@initial_width > 0 ? @initial_width : available_width) @height = (@initial_height > 0 ? @initial_height : available_height) @width <= available_width && @height <= available_height end |