class HexaPDF::Layout::Style::Border
Represents the border of a rectangular area.
Attributes
color[R]
The colors of each edge. See Quad
.
style[R]
The styles of each edge. See Quad
.
width[R]
The widths of each edge. See Quad
.
Public Class Methods
new(width: 0, color: 0, style: :solid)
click to toggle source
Creates a new border style. All arguments can be set to any value that a Quad
can process.
# File lib/hexapdf/layout/style.rb, line 206 def initialize(width: 0, color: 0, style: :solid) @width = Quad.new(width) @color = Quad.new(color) @style = Quad.new(style) end
Public Instance Methods
draw(canvas, x, y, w, h)
click to toggle source
Draws the border onto the canvas, inside the rectangle (x, y, w, h).
# File lib/hexapdf/layout/style.rb, line 226 def draw(canvas, x, y, w, h) return if none? canvas.save_graphics_state do if width.simple? && color.simple? && style.simple? draw_simple_border(canvas, x, y, w, h) else draw_complex_border(canvas, x, y, w, h) end end end
initialize_copy(other)
click to toggle source
Duplicates a Border
object's properties.
Calls superclass method
# File lib/hexapdf/layout/style.rb, line 213 def initialize_copy(other) super @width = @width.dup @color = @color.dup @style = @style.dup end
none?()
click to toggle source
Returns true
if there is no border.
# File lib/hexapdf/layout/style.rb, line 221 def none? width.simple? && width.top == 0 end
Private Instance Methods
draw_complex_border(canvas, x, y, w, h)
click to toggle source
Draws a complex border, i.e. one where every edge is potentially differently styled.
# File lib/hexapdf/layout/style.rb, line 264 def draw_complex_border(canvas, x, y, w, h) left = x bottom = y right = left + w top = bottom + h inner_left = left + width.left inner_bottom = bottom + width.bottom inner_right = right - width.right inner_top = top - width.top if width.top > 0 canvas.save_graphics_state do canvas.polyline(left, top, right, top, inner_right, inner_top, inner_left, inner_top). clip_path.end_path canvas.stroke_color(color.top). line_width(width.top). line_cap_style(line_cap_style(:top)). line_dash_pattern(line_dash_pattern(:top, w)). line(left, top - width.top / 2.0, right, top - width.top / 2.0).stroke end end if width.right > 0 canvas.save_graphics_state do canvas.polyline(right, top, right, bottom, inner_right, inner_bottom, inner_right, inner_top). clip_path.end_path canvas.stroke_color(color.right). line_width(width.right). line_cap_style(line_cap_style(:right)). line_dash_pattern(line_dash_pattern(:right, h)). line(right - width.right / 2.0, top, right - width.right / 2.0, bottom).stroke end end if width.bottom > 0 canvas.save_graphics_state do canvas.polyline(right, bottom, left, bottom, inner_left, inner_bottom, inner_right, inner_bottom). clip_path.end_path canvas.stroke_color(color.bottom). line_width(width.bottom). line_cap_style(line_cap_style(:bottom)). line_dash_pattern(line_dash_pattern(:bottom, w)). line(right, bottom + width.bottom / 2.0, left, bottom + width.bottom / 2.0).stroke end end if width.left > 0 canvas.save_graphics_state do canvas.polyline(left, bottom, left, top, inner_left, inner_top, inner_left, inner_bottom). clip_path.end_path canvas.stroke_color(color.left). line_width(width.left). line_cap_style(line_cap_style(:left)). line_dash_pattern(line_dash_pattern(:left, h)). line(left + width.left / 2.0, bottom, left + width.left / 2.0, top).stroke end end end
draw_simple_border(canvas, x, y, w, h)
click to toggle source
Draws the border assuming that only one width, style and color are used.
# File lib/hexapdf/layout/style.rb, line 241 def draw_simple_border(canvas, x, y, w, h) offset = width.top / 2.0 canvas.stroke_color(color.top). line_width(width.top). line_join_style(:miter). miter_limit(10). line_cap_style(line_cap_style(:top)) canvas.rectangle(x, y, w, h).clip_path.end_path if style.top == :solid canvas.line_dash_pattern(0). rectangle(x + offset, y + offset, w - 2 * offset, h - 2 * offset).stroke else canvas.line_dash_pattern(line_dash_pattern(:top, w)). line(x, y + h - offset, x + w, y + h - offset). line(x + w, y + offset, x, y + offset).stroke canvas.line_dash_pattern(line_dash_pattern(:right, h)). line(x + w - offset, y + h, x + w - offset, y). line(x + offset, y, x + offset, y + h).stroke end end
line_cap_style(edge)
click to toggle source
Returns the line cap style for the given edge name.
# File lib/hexapdf/layout/style.rb, line 328 def line_cap_style(edge) case style.send(edge) when :solid then :butt when :dashed then :projecting_square when :dashed_round, :dotted then :round else raise ArgumentError, "Invalid border style specified: #{style.send(edge)}" end end
line_dash_pattern(edge, length)
click to toggle source
Returns the line dash pattern for the given edge name. The argument length
needs to contain the length of the edge.
# File lib/hexapdf/layout/style.rb, line 340 def line_dash_pattern(edge, length) case style.send(edge) when :solid 0 when :dashed, :dashed_round # Due to the used line cap styles, a dash of length w appears with a length of 2w. The # gap between dashes is nominally 3w but adjusted so that full dashes start and end in # the corners. w = width.send(edge) count = [(length.to_f / (w * 3)).floor, 1].max gap = [(length - w * (count + 2)).to_f, 0].max / count HexaPDF::Content::LineDashPattern.new([w, gap], w * 0.5 + gap) when :dotted # Adjust the gap so that full dots appear in the corners. w = width.send(edge) gap = [(length - w).to_f / (length.to_f / (w * 2)).ceil, 1].max HexaPDF::Content::LineDashPattern.new([0, gap], [gap - w * 0.5, 0].max) end end