hexapdf 0.43.0 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/examples/027-composer_optional_content.rb +6 -4
- data/examples/030-pdfa.rb +13 -11
- data/lib/hexapdf/composer.rb +23 -0
- data/lib/hexapdf/content/canvas.rb +3 -3
- data/lib/hexapdf/content/canvas_composer.rb +1 -0
- data/lib/hexapdf/document/files.rb +7 -2
- data/lib/hexapdf/document/layout.rb +15 -3
- data/lib/hexapdf/document/metadata.rb +12 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/layout/box.rb +180 -66
- data/lib/hexapdf/layout/box_fitter.rb +1 -0
- data/lib/hexapdf/layout/column_box.rb +18 -28
- data/lib/hexapdf/layout/container_box.rb +6 -6
- data/lib/hexapdf/layout/frame.rb +13 -94
- data/lib/hexapdf/layout/image_box.rb +4 -4
- data/lib/hexapdf/layout/list_box.rb +13 -31
- data/lib/hexapdf/layout/style.rb +8 -4
- data/lib/hexapdf/layout/table_box.rb +55 -58
- data/lib/hexapdf/layout/text_box.rb +84 -71
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +7 -8
- data/lib/hexapdf/parser.rb +5 -2
- data/lib/hexapdf/rectangle.rb +4 -4
- data/lib/hexapdf/type/file_specification.rb +9 -5
- data/lib/hexapdf/type/form.rb +2 -2
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/content/test_canvas_composer.rb +13 -8
- data/test/hexapdf/document/test_files.rb +5 -0
- data/test/hexapdf/document/test_layout.rb +16 -0
- data/test/hexapdf/document/test_metadata.rb +21 -0
- data/test/hexapdf/layout/test_box.rb +93 -37
- data/test/hexapdf/layout/test_box_fitter.rb +7 -0
- data/test/hexapdf/layout/test_column_box.rb +7 -13
- data/test/hexapdf/layout/test_container_box.rb +1 -1
- data/test/hexapdf/layout/test_frame.rb +7 -46
- data/test/hexapdf/layout/test_image_box.rb +14 -6
- data/test/hexapdf/layout/test_list_box.rb +26 -27
- data/test/hexapdf/layout/test_table_box.rb +47 -54
- data/test/hexapdf/layout/test_text_box.rb +83 -83
- data/test/hexapdf/test_composer.rb +20 -5
- data/test/hexapdf/test_parser.rb +8 -0
- data/test/hexapdf/test_serializer.rb +1 -0
- data/test/hexapdf/type/test_file_specification.rb +2 -1
- metadata +2 -2
data/lib/hexapdf/layout/box.rb
CHANGED
@@ -61,9 +61,9 @@ module HexaPDF
|
|
61
61
|
# instantiated from the common convenience method HexaPDF::Document::Layout#box. To use this
|
62
62
|
# facility subclasses need to be registered with the configuration option 'layout.boxes.map'.
|
63
63
|
#
|
64
|
-
# The methods #supports_position_flow?, #empty?, #
|
65
|
-
#
|
66
|
-
#
|
64
|
+
# The methods #supports_position_flow?, #empty?, #fit_content, #split_content, and #draw_content
|
65
|
+
# need to be customized according to the subclass's use case (also see the documentation of the
|
66
|
+
# methods besides the information below):
|
67
67
|
#
|
68
68
|
# #supports_position_flow?::
|
69
69
|
# If the subclass supports the value :flow of the 'position' style property, this method
|
@@ -72,25 +72,22 @@ module HexaPDF
|
|
72
72
|
# #empty?::
|
73
73
|
# This method should return +true+ if the subclass won't draw anything when #draw is called.
|
74
74
|
#
|
75
|
-
# #
|
76
|
-
# This method
|
77
|
-
#
|
78
|
-
# #split.
|
75
|
+
# #fit_content::
|
76
|
+
# This method determines whether the box fits into the available region and should set the
|
77
|
+
# status of #fit_result appropriately.
|
79
78
|
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
79
|
+
# It is called from the #fit method which should not be overridden in most cases. The
|
80
|
+
# default implementations of both methods provide code common to all use-cases and delegates
|
81
|
+
# the specifics to the subclass-specific #fit_content method.
|
83
82
|
#
|
84
|
-
# #
|
85
|
-
# This method
|
86
|
-
#
|
87
|
-
#
|
88
|
-
# box.
|
83
|
+
# #split_content::
|
84
|
+
# This method is called from #split which handles the common cases based on the status of
|
85
|
+
# the #fit_result. It needs to handle the case when only some part of the box fits. The
|
86
|
+
# method #create_split_box should be used for getting a basic cloned box.
|
89
87
|
#
|
90
|
-
# #
|
91
|
-
# This method draws the content and
|
92
|
-
# drawing the border and background. So
|
93
|
-
# drawing commands should be implemented in the #draw_content method.
|
88
|
+
# #draw_content::
|
89
|
+
# This method draws the box specific content and is called from #draw which already handles
|
90
|
+
# things like drawing the border and background. So #draw should usually not be overridden.
|
94
91
|
#
|
95
92
|
# This base class provides various private helper methods for use in the above methods:
|
96
93
|
#
|
@@ -118,6 +115,104 @@ module HexaPDF
|
|
118
115
|
|
119
116
|
include HexaPDF::Utils
|
120
117
|
|
118
|
+
# Stores the result of fitting a box in a frame.
|
119
|
+
class FitResult
|
120
|
+
|
121
|
+
# The box that was fitted into the frame.
|
122
|
+
attr_accessor :box
|
123
|
+
|
124
|
+
# The frame into which the box was fitted.
|
125
|
+
attr_accessor :frame
|
126
|
+
|
127
|
+
# The horizontal position where the box will be drawn.
|
128
|
+
attr_accessor :x
|
129
|
+
|
130
|
+
# The vertical position where the box will be drawn.
|
131
|
+
attr_accessor :y
|
132
|
+
|
133
|
+
# The rectangle (a Geom2D::Rectangle object) that will be removed from the frame when
|
134
|
+
# drawing the box.
|
135
|
+
attr_accessor :mask
|
136
|
+
|
137
|
+
# The status result of fitting the box in the frame.
|
138
|
+
#
|
139
|
+
# Allowed values are:
|
140
|
+
#
|
141
|
+
# +:failure+:: (default) Indicates fitting the box has failed.
|
142
|
+
# +:success+:: Indicates that the box was completely fitted.
|
143
|
+
# +:overflow+:: Indicates that only a part of the box was fitted.
|
144
|
+
attr_reader :status
|
145
|
+
|
146
|
+
# Initializes the result object for the given box and, optionally, frame.
|
147
|
+
def initialize(box, frame: nil)
|
148
|
+
@box = box
|
149
|
+
reset(frame)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Resets the result object.
|
153
|
+
def reset(frame)
|
154
|
+
@frame = frame
|
155
|
+
@x = @y = @mask = nil
|
156
|
+
@status = :failure
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
160
|
+
# Sets the result status to success.
|
161
|
+
def success!
|
162
|
+
@status = :success
|
163
|
+
end
|
164
|
+
|
165
|
+
# Returns +true+ if fitting was successful.
|
166
|
+
def success?
|
167
|
+
@status == :success
|
168
|
+
end
|
169
|
+
|
170
|
+
# Sets the result status to overflow.
|
171
|
+
def overflow!
|
172
|
+
@status = :overflow
|
173
|
+
end
|
174
|
+
|
175
|
+
# Returns +true+ if only parts of the box were fitted.
|
176
|
+
def overflow?
|
177
|
+
@status == :overflow
|
178
|
+
end
|
179
|
+
|
180
|
+
# Returns +true+ if fitting was a failure.
|
181
|
+
def failure?
|
182
|
+
@status == :failure
|
183
|
+
end
|
184
|
+
|
185
|
+
# Draws the #box onto the canvas at (#x + *dx*, #y + *dy*).
|
186
|
+
#
|
187
|
+
# The relative offset (dx, dy) is useful when rendering results that were accumulated and
|
188
|
+
# then need to be moved because the container holding them changes its position.
|
189
|
+
#
|
190
|
+
# The configuration option "debug" can be used to add visual debug output with respect to
|
191
|
+
# box placement.
|
192
|
+
def draw(canvas, dx: 0, dy: 0)
|
193
|
+
return if box.height == 0 || box.width == 0
|
194
|
+
doc = canvas.context.document
|
195
|
+
if doc.config['debug']
|
196
|
+
name = (frame.parent_boxes + [box]).map do |box|
|
197
|
+
box.class.to_s.sub(/.*::/, '')
|
198
|
+
end.join('-') << "##{box.object_id}"
|
199
|
+
name = "#{name} (#{(x + dx).to_i},#{(y + dy).to_i}-#{mask.width.to_i}x#{mask.height.to_i})"
|
200
|
+
ocg = doc.optional_content.ocg(name)
|
201
|
+
canvas.optional_content(ocg) do
|
202
|
+
canvas.translate(dx, dy) do
|
203
|
+
canvas.fill_color("green").stroke_color("darkgreen").
|
204
|
+
opacity(fill_alpha: 0.1, stroke_alpha: 0.2).
|
205
|
+
draw(:geom2d, object: mask, path_only: true).fill_stroke
|
206
|
+
end
|
207
|
+
end
|
208
|
+
page = "Page #{canvas.context.index + 1}" rescue "XObject"
|
209
|
+
doc.optional_content.default_configuration.add_ocg_to_ui(ocg, path: ['Debug', page])
|
210
|
+
end
|
211
|
+
box.draw(canvas, x + dx, y + dy)
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
121
216
|
# Creates a new Box object, using the provided block as drawing block (see ::new).
|
122
217
|
#
|
123
218
|
# If +content_box+ is +true+, the width and height are taken to mean the content width and
|
@@ -143,10 +238,15 @@ module HexaPDF
|
|
143
238
|
# The height of the box, including padding and/or borders.
|
144
239
|
attr_reader :height
|
145
240
|
|
241
|
+
# The FitResult instance holding the result after a call to #fit.
|
242
|
+
attr_reader :fit_result
|
243
|
+
|
146
244
|
# The style to be applied.
|
147
245
|
#
|
148
246
|
# Only the following properties are used:
|
149
247
|
#
|
248
|
+
# * Style#position
|
249
|
+
# * Style#overflow
|
150
250
|
# * Style#background_color
|
151
251
|
# * Style#background_alpha
|
152
252
|
# * Style#padding
|
@@ -190,7 +290,7 @@ module HexaPDF
|
|
190
290
|
@style = Style.create(style)
|
191
291
|
@properties = properties || {}
|
192
292
|
@draw_block = block
|
193
|
-
@
|
293
|
+
@fit_result = FitResult.new(self)
|
194
294
|
@split_box = false
|
195
295
|
end
|
196
296
|
|
@@ -217,78 +317,91 @@ module HexaPDF
|
|
217
317
|
height < 0 ? 0 : height
|
218
318
|
end
|
219
319
|
|
220
|
-
# Fits the box into the *frame* and returns
|
320
|
+
# Fits the box into the *frame* and returns the #fit_result.
|
221
321
|
#
|
222
322
|
# The arguments +available_width+ and +available_height+ are the width and height of the
|
223
323
|
# current region of the frame, adjusted for this box. The frame itself is provided as third
|
224
324
|
# argument.
|
225
325
|
#
|
226
|
-
#
|
227
|
-
#
|
228
|
-
#
|
326
|
+
# If the box uses flow positioning, the width is set to the frame's width and the height to
|
327
|
+
# the remaining height in the frame. Otherwise the given available width and height are used
|
328
|
+
# for the width and height if they were initially set to 0. Otherwise the intially specified
|
329
|
+
# dimensions are used. The method returns early if the thus configured box already doesn't
|
330
|
+
# fit. Otherwise, the #fit_content method is called which allows sub-classes to fit their
|
331
|
+
# content.
|
229
332
|
#
|
230
333
|
# The following variables are set that may later be used during splitting or drawing:
|
231
334
|
#
|
232
335
|
# * (@fit_x, @fit_y): The lower-left corner of the content box where fitting was done. Can be
|
233
|
-
# used to adjust the drawing position in #
|
234
|
-
# * @fit_successful: +true+ if fitting was successful.
|
336
|
+
# used to adjust the drawing position in #draw_content if necessary.
|
235
337
|
def fit(available_width, available_height, frame)
|
236
|
-
@
|
237
|
-
|
238
|
-
@
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
338
|
+
@fit_result.reset(frame)
|
339
|
+
position_flow = supports_position_flow? && style.position == :flow
|
340
|
+
@width = if @initial_width > 0
|
341
|
+
@initial_width
|
342
|
+
elsif position_flow
|
343
|
+
frame.width
|
344
|
+
else
|
345
|
+
available_width
|
346
|
+
end
|
347
|
+
@height = if @initial_height > 0
|
348
|
+
@initial_height
|
349
|
+
elsif position_flow
|
350
|
+
frame.y - frame.bottom
|
351
|
+
else
|
352
|
+
available_height
|
353
|
+
end
|
354
|
+
return @fit_result if !position_flow && (float_compare(@width, available_width) > 0 ||
|
355
|
+
float_compare(@height, available_height) > 0)
|
356
|
+
|
357
|
+
fit_content(available_width, available_height, frame)
|
243
358
|
|
244
359
|
@fit_x = frame.x + reserved_width_left
|
245
360
|
@fit_y = frame.y - @height + reserved_height_bottom
|
246
361
|
|
247
|
-
@
|
362
|
+
@fit_result
|
248
363
|
end
|
249
364
|
|
250
365
|
# Tries to split the box into two, the first of which needs to fit into the current region of
|
251
|
-
# the frame, and returns the parts as array.
|
366
|
+
# the frame, and returns the parts as array. The method #fit needs to be called before this
|
367
|
+
# method to correctly set-up the #fit_result.
|
252
368
|
#
|
253
369
|
# If the first item in the result array is not +nil+, it needs to be this box and it means
|
254
370
|
# that even when #fit fails, a part of the box may still fit. Note that #fit should not be
|
255
|
-
# called before #draw on the first box since it is already fitted. If not even a part of
|
256
|
-
# box fits into the current region, +nil+ should be returned as the first array element.
|
371
|
+
# called again before #draw on the first box since it is already fitted. If not even a part of
|
372
|
+
# this box fits into the current region, +nil+ should be returned as the first array element.
|
257
373
|
#
|
258
374
|
# Possible return values:
|
259
375
|
#
|
260
|
-
# [self]:: The box fully fits into the current region.
|
376
|
+
# [self, nil]:: The box fully fits into the current region.
|
261
377
|
# [nil, self]:: The box can't be split or no part of the box fits into the current region.
|
262
378
|
# [self, new_box]:: A part of the box fits and a new box is returned for the rest.
|
263
379
|
#
|
264
|
-
# This default implementation provides the basic functionality based on the
|
265
|
-
# should be sufficient for most subclasses; only #split_content needs to be
|
266
|
-
# necessary.
|
267
|
-
def split
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
float_compare(@height, available_height) > 0)) ||
|
273
|
-
content_height == 0 || content_width == 0
|
274
|
-
[nil, self]
|
275
|
-
else
|
276
|
-
split_content(available_width, available_height, frame)
|
380
|
+
# This default implementation provides the basic functionality based on the status of the
|
381
|
+
# #fit_result that should be sufficient for most subclasses; only #split_content needs to be
|
382
|
+
# implemented if necessary.
|
383
|
+
def split
|
384
|
+
case @fit_result.status
|
385
|
+
when :overflow then (@initial_height > 0 ? [self, nil] : split_content)
|
386
|
+
when :failure then [nil, self]
|
387
|
+
when :success then [self, nil]
|
277
388
|
end
|
278
389
|
end
|
279
390
|
|
280
391
|
# Draws the content of the box onto the canvas at the position (x, y).
|
281
392
|
#
|
282
|
-
#
|
283
|
-
#
|
393
|
+
# When +@draw_block+ is used (the block specified when creating the box), the coordinate
|
394
|
+
# system is translated so that the origin is at the bottom left corner of the **content box**.
|
284
395
|
#
|
285
|
-
#
|
286
|
-
#
|
287
|
-
#
|
288
|
-
# operations when the block does nothing.
|
289
|
-
#
|
290
|
-
# Alternatively, if a #draw_content method is defined, this method is called.
|
396
|
+
# Subclasses should not rely on the +@draw_block+ but implement the #draw_content method. The
|
397
|
+
# coordinates passed to it are also modified to represent the bottom-left corner of the
|
398
|
+
# content box but the coordinate system is not translated.
|
291
399
|
def draw(canvas, x, y)
|
400
|
+
if @fit_result.overflow? && @initial_height > 0 && style.overflow == :error
|
401
|
+
raise HexaPDF::Error, "Box with limited height doesn't completely fit and " \
|
402
|
+
"style property overflow is set to :error"
|
403
|
+
end
|
404
|
+
|
292
405
|
if (oc = properties['optional_content'])
|
293
406
|
canvas.optional_content(oc)
|
294
407
|
end
|
@@ -381,12 +494,13 @@ module HexaPDF
|
|
381
494
|
|
382
495
|
# Fits the content of the box and returns whether fitting was successful.
|
383
496
|
#
|
384
|
-
# This is just a stub implementation that
|
385
|
-
# provide the box
|
497
|
+
# This is just a stub implementation that sets the #fit_result status to success if the
|
498
|
+
# content rectangle is not degenerate. Subclasses should override it to provide the box
|
499
|
+
# specific behaviour.
|
386
500
|
#
|
387
501
|
# See #fit for details.
|
388
502
|
def fit_content(_available_width, _available_height, _frame)
|
389
|
-
|
503
|
+
fit_result.success! if content_width > 0 && content_height > 0
|
390
504
|
end
|
391
505
|
|
392
506
|
# Splits the content of the box.
|
@@ -395,12 +509,12 @@ module HexaPDF
|
|
395
509
|
# the content when it didn't fit.
|
396
510
|
#
|
397
511
|
# Subclasses that support splitting content need to provide an appropriate implementation and
|
398
|
-
# use #create_split_box to create a cloned box to supply as the second argument.
|
399
|
-
def split_content
|
512
|
+
# use #create_split_box to create a cloned box to supply as the second return argument.
|
513
|
+
def split_content
|
400
514
|
[nil, self]
|
401
515
|
end
|
402
516
|
|
403
|
-
# Draws the content of the box at position [x, y] which is the bottom
|
517
|
+
# Draws the content of the box at position [x, y] which is the bottom left corner of the
|
404
518
|
# content box.
|
405
519
|
#
|
406
520
|
# This implementation uses the drawing block provided on initialization, if set, to draw the
|
@@ -422,7 +536,7 @@ module HexaPDF
|
|
422
536
|
box = clone
|
423
537
|
box.instance_variable_set(:@width, @initial_width)
|
424
538
|
box.instance_variable_set(:@height, @initial_height)
|
425
|
-
box.instance_variable_set(:@
|
539
|
+
box.instance_variable_set(:@fit_result, FitResult.new(box))
|
426
540
|
box.instance_variable_set(:@split_box, split_box_value)
|
427
541
|
box
|
428
542
|
end
|
@@ -111,6 +111,7 @@ module HexaPDF
|
|
111
111
|
@content_heights[@frame_index] = [@content_heights[@frame_index],
|
112
112
|
@initial_frame_y[@frame_index] - result.mask.y].max
|
113
113
|
@fit_results << result
|
114
|
+
break unless box
|
114
115
|
elsif !current_frame.find_next_region
|
115
116
|
@frame_index += 1
|
116
117
|
end
|
@@ -138,31 +138,21 @@ module HexaPDF
|
|
138
138
|
super && (!@box_fitter || @box_fitter.fit_results.empty?)
|
139
139
|
end
|
140
140
|
|
141
|
+
private
|
142
|
+
|
141
143
|
# Fits the column box into the current region of the frame.
|
142
144
|
#
|
143
|
-
|
144
|
-
# arbitrary (sets of) polygons since the +frame+s shape is taken into account.
|
145
|
-
def fit(available_width, available_height, frame)
|
146
|
-
return false if @initial_height > available_height || @initial_width > available_width
|
147
|
-
|
145
|
+
def fit_content(_available_width, _available_height, frame)
|
148
146
|
initial_fit_successful = (@equal_height && @columns.size > 1 ? nil : false)
|
149
147
|
tries = 0
|
150
|
-
|
151
|
-
|
152
|
-
else
|
153
|
-
(@initial_width > 0 ? @initial_width : available_width) - reserved_width
|
154
|
-
end
|
155
|
-
height = if style.position == :flow
|
156
|
-
(@initial_height > 0 ? @initial_height : frame.height) - reserved_height
|
157
|
-
else
|
158
|
-
(@initial_height > 0 ? @initial_height : available_height) - reserved_height
|
159
|
-
end
|
148
|
+
width = @width - reserved_width
|
149
|
+
height = @height - reserved_height
|
160
150
|
|
161
|
-
columns = calculate_columns(
|
162
|
-
return
|
151
|
+
columns = calculate_columns(width)
|
152
|
+
return if columns.empty?
|
163
153
|
|
164
154
|
left = (style.position == :flow ? frame.left : frame.x) + reserved_width_left
|
165
|
-
top =
|
155
|
+
top = frame.y - reserved_height_top
|
166
156
|
successful_height = height
|
167
157
|
unsuccessful_height = 0
|
168
158
|
|
@@ -206,16 +196,16 @@ module HexaPDF
|
|
206
196
|
tries += 1
|
207
197
|
end
|
208
198
|
|
209
|
-
|
210
|
-
|
211
|
-
@draw_pos_x = frame.x + reserved_width_left
|
212
|
-
@draw_pos_y = frame.y - @height + reserved_height_bottom
|
199
|
+
update_content_width { columns[-1].sum }
|
200
|
+
update_content_height { @box_fitter.content_heights.max }
|
213
201
|
|
214
|
-
@box_fitter.success?
|
202
|
+
if @box_fitter.success?
|
203
|
+
fit_result.success!
|
204
|
+
elsif !@box_fitter.fit_results.empty?
|
205
|
+
fit_result.overflow!
|
206
|
+
end
|
215
207
|
end
|
216
208
|
|
217
|
-
private
|
218
|
-
|
219
209
|
# Calculates the x-coordinates and widths of all columns based on the given total available
|
220
210
|
# width.
|
221
211
|
#
|
@@ -241,7 +231,7 @@ module HexaPDF
|
|
241
231
|
end
|
242
232
|
|
243
233
|
# Splits the content of the column box. This method is called from Box#split.
|
244
|
-
def split_content
|
234
|
+
def split_content
|
245
235
|
box = create_split_box
|
246
236
|
box.instance_variable_set(:@children, @box_fitter.remaining_boxes)
|
247
237
|
[self, box]
|
@@ -249,8 +239,8 @@ module HexaPDF
|
|
249
239
|
|
250
240
|
# Draws the child boxes onto the canvas at position [x, y].
|
251
241
|
def draw_content(canvas, x, y)
|
252
|
-
if style.position != :flow && (x != @
|
253
|
-
canvas.translate(x - @
|
242
|
+
if style.position != :flow && (x != @fit_x || y != @fit_y)
|
243
|
+
canvas.translate(x - @fit_x, y - @fit_y) do
|
254
244
|
@box_fitter.fit_results.each {|result| result.draw(canvas) }
|
255
245
|
end
|
256
246
|
else
|
@@ -52,7 +52,7 @@ module HexaPDF
|
|
52
52
|
# setting the style properties 'mask_mode', 'align' and 'valign', it is possible to lay out the
|
53
53
|
# children bottom to top, left to right, or right to left:
|
54
54
|
#
|
55
|
-
# * The standard top
|
55
|
+
# * The standard top-to-bottom layout:
|
56
56
|
#
|
57
57
|
# #>pdf-composer100
|
58
58
|
# composer.container do |container|
|
@@ -61,7 +61,7 @@ module HexaPDF
|
|
61
61
|
# container.box(:base, height: 20, style: {background_color: "hp-blue-light"})
|
62
62
|
# end
|
63
63
|
#
|
64
|
-
# * The bottom
|
64
|
+
# * The bottom-to-top layout (using valign = :bottom to fill up from the bottom and mask_mode =
|
65
65
|
# :fill_horizontal to only remove the area to the left and right of the box):
|
66
66
|
#
|
67
67
|
# #>pdf-composer100
|
@@ -74,7 +74,7 @@ module HexaPDF
|
|
74
74
|
# mask_mode: :fill_horizontal, valign: :bottom})
|
75
75
|
# end
|
76
76
|
#
|
77
|
-
# * The left
|
77
|
+
# * The left-to-right layout (using mask_mode = :fill_vertical to fill the area to the top and
|
78
78
|
# bottom of the box):
|
79
79
|
#
|
80
80
|
# #>pdf-composer100
|
@@ -87,7 +87,7 @@ module HexaPDF
|
|
87
87
|
# mask_mode: :fill_vertical})
|
88
88
|
# end
|
89
89
|
#
|
90
|
-
# * The right
|
90
|
+
# * The right-to-left layout (using align = :right to fill up from the right and mask_mode =
|
91
91
|
# :fill_vertical to fill the area to the top and bottom of the box):
|
92
92
|
#
|
93
93
|
# #>pdf-composer100
|
@@ -143,11 +143,11 @@ module HexaPDF
|
|
143
143
|
children.empty? ? 0 : result.mask.x + result.mask.width - my_frame.left
|
144
144
|
end
|
145
145
|
update_content_height { @box_fitter.content_heights.max }
|
146
|
-
|
146
|
+
fit_result.success!
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
-
# Draws the
|
150
|
+
# Draws the children onto the canvas at position [x, y].
|
151
151
|
def draw_content(canvas, x, y)
|
152
152
|
dx = x - @fit_x
|
153
153
|
dy = y - @fit_y
|