Class: HexaPDF::Content::CanvasComposer

Inherits:
Object
  • Object
show all
Defined in:
lib/hexapdf/content/canvas_composer.rb

Overview

The CanvasComposer class allows using the document layout functionality for a single canvas. It works in a similar manner as the HexaPDF::Composer class.

See: HexaPDF::Composer, HexaPDF::Document::Layout

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(canvas, margin: 0) ⇒ CanvasComposer

Creates a new CanvasComposer instance for the given canvas.

The margin can be any value allowed by HexaPDF::Layout::Style::Quad#set and defines the margin that should not be used during composition. For the remaining area of the canvas a frame object will be created.



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/hexapdf/content/canvas_composer.rb', line 62

def initialize(canvas, margin: 0)
  @canvas = canvas
  @document = @canvas.context.document

  box = @canvas.context.box
  margin = Layout::Style::Quad.new(margin)
  @frame = Layout::Frame.new(box.left + margin.left,
                             box.bottom + margin.bottom,
                             box.width - margin.left - margin.right,
                             box.height - margin.bottom - margin.top,
                             context: @canvas.context)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, **kwargs, &block) ⇒ Object

Draws any box that can be created using HexaPDF::Document::Layout.

This includes all named boxes defined in the ‘layout.boxes.map’ configuration option.

Examples:

#>pdf
canvas.composer(margin: 10) do |composer|
  composer.text("Some text", position: :float)
  composer.image(machu_picchu, height: 30, align: :right)
  composer.lorem_ipsum(sentences: 1, margin: [0, 0, 5])
  composer.list(item_spacing: 2) do |list|
    composer.document.config['layout.boxes.map'].each do |name, klass|
      list.formatted_text([{text: name.to_s, fill_color: "hp-blue-dark"},
                           {text: "\n#{klass}"}], font_size: 6)
    end
  end
end

See: HexaPDF::Document::Layout#box



128
129
130
131
132
133
134
# File 'lib/hexapdf/content/canvas_composer.rb', line 128

def method_missing(name, *args, **kwargs, &block)
  if @document.layout.box_creation_method?(name)
    draw_box(@document.layout.send(name, *args, **kwargs, &block))
  else
    super
  end
end

Instance Attribute Details

#canvasObject (readonly)

The associated canvas.



49
50
51
# File 'lib/hexapdf/content/canvas_composer.rb', line 49

def canvas
  @canvas
end

#documentObject (readonly)

The associated HexaPDF::Document instance.



52
53
54
# File 'lib/hexapdf/content/canvas_composer.rb', line 52

def document
  @document
end

#frameObject (readonly)

The HexaPDF::Layout::Frame instance into which the boxes are laid out.



55
56
57
# File 'lib/hexapdf/content/canvas_composer.rb', line 55

def frame
  @frame
end

Instance Method Details

#draw_box(box) ⇒ Object

Draws the given HexaPDF::Layout::Box and returns the last drawn box.

The box is drawn into the frame. If it doesn’t fit, the box is split. If it still doesn’t fit, a new region of the frame is determined and then the process starts again.

If none or only some parts of the box fit into the frame, an exception is thrown.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/hexapdf/content/canvas_composer.rb', line 87

def draw_box(box)
  while true
    result = @frame.fit(box)
    if result.success?
      @frame.draw(@canvas, result)
      break
    elsif @frame.full?
      raise HexaPDF::Error, "Frame for canvas composer is full and box doesn't fit anymore"
    else
      draw_box, box = @frame.split(result)
      if draw_box
        @frame.draw(@canvas, result)
        (box = draw_box; break) unless box
      elsif !@frame.find_next_region
        raise HexaPDF::Error, "Frame for canvas composer is full and box doesn't fit anymore"
      end
    end
  end
  box
end

#respond_to_missing?(name, _private) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


136
137
138
# File 'lib/hexapdf/content/canvas_composer.rb', line 136

def respond_to_missing?(name, _private) # :nodoc:
  @document.layout.box_creation_method?(name) || super
end

#style(name, base: :base, **properties) ⇒ Object

Invokes HexaPDF::Document::Layout#style with the given arguments to create/update and return a style object.



77
78
79
# File 'lib/hexapdf/content/canvas_composer.rb', line 77

def style(name, base: :base, **properties)
  @document.layout.style(name, base: base, **properties)
end