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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -0
  3. data/examples/027-composer_optional_content.rb +6 -4
  4. data/examples/030-pdfa.rb +13 -11
  5. data/lib/hexapdf/composer.rb +23 -0
  6. data/lib/hexapdf/content/canvas.rb +3 -3
  7. data/lib/hexapdf/content/canvas_composer.rb +1 -0
  8. data/lib/hexapdf/document/files.rb +7 -2
  9. data/lib/hexapdf/document/layout.rb +15 -3
  10. data/lib/hexapdf/document/metadata.rb +12 -1
  11. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  12. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  13. data/lib/hexapdf/layout/box.rb +180 -66
  14. data/lib/hexapdf/layout/box_fitter.rb +1 -0
  15. data/lib/hexapdf/layout/column_box.rb +18 -28
  16. data/lib/hexapdf/layout/container_box.rb +6 -6
  17. data/lib/hexapdf/layout/frame.rb +13 -94
  18. data/lib/hexapdf/layout/image_box.rb +4 -4
  19. data/lib/hexapdf/layout/list_box.rb +13 -31
  20. data/lib/hexapdf/layout/style.rb +8 -4
  21. data/lib/hexapdf/layout/table_box.rb +55 -58
  22. data/lib/hexapdf/layout/text_box.rb +84 -71
  23. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  24. data/lib/hexapdf/layout/text_layouter.rb +7 -8
  25. data/lib/hexapdf/parser.rb +5 -2
  26. data/lib/hexapdf/rectangle.rb +4 -4
  27. data/lib/hexapdf/type/file_specification.rb +9 -5
  28. data/lib/hexapdf/type/form.rb +2 -2
  29. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  30. data/lib/hexapdf/version.rb +1 -1
  31. data/test/hexapdf/content/test_canvas_composer.rb +13 -8
  32. data/test/hexapdf/document/test_files.rb +5 -0
  33. data/test/hexapdf/document/test_layout.rb +16 -0
  34. data/test/hexapdf/document/test_metadata.rb +21 -0
  35. data/test/hexapdf/layout/test_box.rb +93 -37
  36. data/test/hexapdf/layout/test_box_fitter.rb +7 -0
  37. data/test/hexapdf/layout/test_column_box.rb +7 -13
  38. data/test/hexapdf/layout/test_container_box.rb +1 -1
  39. data/test/hexapdf/layout/test_frame.rb +7 -46
  40. data/test/hexapdf/layout/test_image_box.rb +14 -6
  41. data/test/hexapdf/layout/test_list_box.rb +26 -27
  42. data/test/hexapdf/layout/test_table_box.rb +47 -54
  43. data/test/hexapdf/layout/test_text_box.rb +83 -83
  44. data/test/hexapdf/test_composer.rb +20 -5
  45. data/test/hexapdf/test_parser.rb +8 -0
  46. data/test/hexapdf/test_serializer.rb +1 -0
  47. data/test/hexapdf/type/test_file_specification.rb +2 -1
  48. metadata +2 -2
@@ -45,7 +45,7 @@ module HexaPDF
45
45
  #
46
46
  # == Usage
47
47
  #
48
- # After a Frame object is initialized, it is ready for drawing boxes on it.
48
+ # After a Frame object is initialized, it is ready for fitting boxes in it and drawing them.
49
49
  #
50
50
  # The explicit way of drawing a box follows these steps:
51
51
  #
@@ -65,10 +65,6 @@ module HexaPDF
65
65
  # splitting is successful, the first box can be drawn (Make sure that the second box is
66
66
  # handled correctly). Otherwise, start over with #find_next_region.
67
67
  #
68
- # For applications where splitting is not necessary, an easier way is to just use #draw and
69
- # #find_next_region together, as #draw calls #fit if the box was not fit into the current
70
- # region.
71
- #
72
68
  # == Used Box Properties
73
69
  #
74
70
  # The style properties 'position', 'align', 'valign', 'margin' and 'mask_mode' are taken into
@@ -88,80 +84,6 @@ module HexaPDF
88
84
 
89
85
  include HexaPDF::Utils
90
86
 
91
- # Stores the result of fitting a box in a Frame.
92
- class FitResult
93
-
94
- # The frame into which the box was fitted.
95
- attr_accessor :frame
96
-
97
- # The box that was fitted into the frame.
98
- attr_accessor :box
99
-
100
- # The horizontal position where the box will be drawn.
101
- attr_accessor :x
102
-
103
- # The vertical position where the box will be drawn.
104
- attr_accessor :y
105
-
106
- # The available width in the frame for this particular box.
107
- attr_accessor :available_width
108
-
109
- # The available height in the frame for this particular box.
110
- attr_accessor :available_height
111
-
112
- # The rectangle (a Geom2D::Rectangle object) that will be removed from the frame when
113
- # drawing the box.
114
- attr_accessor :mask
115
-
116
- # Initialize the result object for the given frame and box.
117
- def initialize(frame, box)
118
- @frame = frame
119
- @box = box
120
- @available_width = 0
121
- @available_height = 0
122
- @success = false
123
- end
124
-
125
- # Marks the fitting status as success.
126
- def success!
127
- @success = true
128
- end
129
-
130
- # Returns +true+ if fitting was successful.
131
- def success?
132
- @success
133
- end
134
-
135
- # Draws the #box onto the canvas at (#x + *dx*, #y + *dy*).
136
- #
137
- # The relative offset (dx, dy) is useful when rendering results that were accumulated and
138
- # then need to be moved because the container holding them changes its position.
139
- #
140
- # The configuration option "debug" can be used to add visual debug output with respect to
141
- # box placement.
142
- def draw(canvas, dx: 0, dy: 0)
143
- doc = canvas.context.document
144
- if doc.config['debug']
145
- name = (frame.parent_boxes + [box]).map do |box|
146
- box.class.to_s.sub(/.*::/, '')
147
- end.join('-') << "##{box.object_id}"
148
- name = "#{name} (#{(x + dx).to_i},#{(y + dy).to_i}-#{mask.width.to_i}x#{mask.height.to_i})"
149
- ocg = doc.optional_content.ocg(name)
150
- canvas.optional_content(ocg) do
151
- canvas.translate(dx, dy) do
152
- canvas.fill_color("green").stroke_color("darkgreen").
153
- opacity(fill_alpha: 0.1, stroke_alpha: 0.2).
154
- draw(:geom2d, object: mask, path_only: true).fill_stroke
155
- end
156
- end
157
- page = "Page #{canvas.context.index + 1}" rescue "XObject"
158
- doc.optional_content.default_configuration.add_ocg_to_ui(ocg, path: ['Debug', page])
159
- end
160
- box.draw(canvas, x + dx, y + dy)
161
- end
162
-
163
- end
164
-
165
87
  # The x-coordinate of the bottom-left corner.
166
88
  attr_reader :left
167
89
 
@@ -205,7 +127,7 @@ module HexaPDF
205
127
 
206
128
  # An array of box objects representing the parent boxes.
207
129
  #
208
- # The immediate parent is the last array entry, the top most parent the first one. All boxes
130
+ # The immediate parent is the last array entry, the top-most parent the first one. All boxes
209
131
  # that are fitted into this frame have to be child boxes of the immediate parent box.
210
132
  attr_reader :parent_boxes
211
133
 
@@ -253,16 +175,15 @@ module HexaPDF
253
175
  @context&.document
254
176
  end
255
177
 
256
- # Fits the given box into the current region of available space and returns a FitResult
257
- # object.
178
+ # Fits the given box into the current region of available space and returns the associated
179
+ # Box::FitResult object.
258
180
  #
259
181
  # Fitting a box takes the style properties 'position', 'align', 'valign', 'margin', and
260
182
  # 'mask_mode' into account.
261
183
  #
262
- # Use the FitResult#success? method to determine whether fitting was successful.
184
+ # Use the Box::FitResult#success? method to determine whether fitting was successful.
263
185
  def fit(box)
264
- fit_result = FitResult.new(self, box)
265
- return fit_result if full?
186
+ return Box::FitResult.new(box, frame: self) if full?
266
187
 
267
188
  margin = box.style.margin if box.style.margin?
268
189
 
@@ -277,7 +198,7 @@ module HexaPDF
277
198
 
278
199
  aw = width - x
279
200
  ah = height - y
280
- box.fit(aw, ah, self)
201
+ fit_result = box.fit(aw, ah, self)
281
202
  fit_result.success!
282
203
 
283
204
  x += left
@@ -294,7 +215,8 @@ module HexaPDF
294
215
  ah -= margin_top = margin.top unless float_equal(@y, @bottom + @height)
295
216
  end
296
217
 
297
- fit_result.success! if box.fit(aw, ah, self)
218
+ fit_result = box.fit(aw, ah, self)
219
+ return fit_result if fit_result.failure?
298
220
 
299
221
  width = box.width
300
222
  height = box.height
@@ -372,27 +294,24 @@ module HexaPDF
372
294
  create_rectangle(@x, @y - available_height, @x + available_width, @y)
373
295
  end
374
296
 
375
- fit_result.available_width = aw
376
- fit_result.available_height = ah
377
297
  fit_result.x = x
378
298
  fit_result.y = y
379
299
  fit_result.mask = rectangle
380
300
  fit_result
381
301
  end
382
302
 
383
- # Tries to split the box of the given FitResult into two parts and returns both parts.
303
+ # Tries to split the box of the given Box::FitResult into two parts and returns both parts.
384
304
  #
385
305
  # See Box#split for further details.
386
306
  def split(fit_result)
387
- fit_result.box.split(fit_result.available_width, fit_result.available_height, self)
307
+ fit_result.box.split
388
308
  end
389
309
 
390
- # Draws the box of the given FitResult onto the canvas at the fitted position.
310
+ # Draws the box of the given Box::FitResult onto the canvas at the fitted position.
391
311
  #
392
312
  # After a box is successfully drawn, the frame's shape is adjusted to remove the occupied
393
313
  # area.
394
314
  def draw(canvas, fit_result)
395
- return if fit_result.box.height == 0 || fit_result.box.width == 0
396
315
  fit_result.draw(canvas)
397
316
  remove_area(fit_result.mask)
398
317
  end
@@ -464,7 +383,7 @@ module HexaPDF
464
383
  # Since not all text may start at the top of the frame, the offset argument can be used to
465
384
  # specify a vertical offset from the top of the frame where layouting should start.
466
385
  #
467
- # To be compatible with TextLayouter, the top left corner of the bounding box of the frame's
386
+ # To be compatible with TextLayouter, the top-left corner of the bounding box of the frame's
468
387
  # shape is the origin of the coordinate system for the width specification, with positive
469
388
  # x-values to the right and positive y-values downwards.
470
389
  #
@@ -79,9 +79,11 @@ module HexaPDF
79
79
  false
80
80
  end
81
81
 
82
+ private
83
+
82
84
  # Fits the image into the current region of the frame, taking the initially set width and
83
85
  # height into account (see the class description for details).
84
- def fit(available_width, available_height, _frame)
86
+ def fit_content(available_width, available_height, _frame)
85
87
  image_width = @image.width.to_f
86
88
  image_height = @image.height.to_f
87
89
  image_ratio = image_width / image_height
@@ -103,12 +105,10 @@ module HexaPDF
103
105
  @height = image_height * ratio + rh
104
106
  end
105
107
 
106
- @fit_successful = float_compare(@width, available_width) <= 0 &&
108
+ fit_result.success! if float_compare(@width, available_width) <= 0 &&
107
109
  float_compare(@height, available_height) <= 0
108
110
  end
109
111
 
110
- private
111
-
112
112
  # Draws the image onto the canvas at position [x, y].
113
113
  def draw_content(canvas, x, y)
114
114
  canvas.image(@image, at: [x, y], width: content_width, height: content_height)
@@ -186,20 +186,12 @@ module HexaPDF
186
186
  super && (!@results || @results.all? {|result| result.box_fitter.fit_results.empty? })
187
187
  end
188
188
 
189
- # Fits the list box into the current region of the frame.
190
- def fit(available_width, available_height, frame)
191
- @width = if @initial_width > 0
192
- @initial_width
193
- else
194
- (style.position == :flow ? frame.width : available_width)
195
- end
196
- height = if @initial_height > 0
197
- @initial_height - reserved_height
198
- else
199
- (style.position == :flow ? frame.y - frame.bottom : available_height) - reserved_height
200
- end
189
+ private
201
190
 
191
+ # Fits the list box into the current region of the frame.
192
+ def fit_content(_available_width, _available_height, frame)
202
193
  width = @width - reserved_width
194
+ height = @height - reserved_height
203
195
  left = (style.position == :flow ? frame.left : frame.x) + reserved_width_left
204
196
  top = frame.y - reserved_height_top
205
197
 
@@ -243,7 +235,7 @@ module HexaPDF
243
235
  Array(child).each {|ibox| box_fitter.fit(ibox) }
244
236
  item_result.box_fitter = box_fitter
245
237
  item_result.height = [item_result.height.to_i, box_fitter.content_heights[0]].max
246
- @results << item_result
238
+ @results << item_result unless box_fitter.fit_results.empty?
247
239
 
248
240
  top -= item_result.height + item_spacing
249
241
  height -= item_result.height + item_spacing
@@ -253,15 +245,13 @@ module HexaPDF
253
245
 
254
246
  @height = @results.sum(&:height) + (@results.count - 1) * item_spacing + reserved_height
255
247
 
256
- @draw_pos_x = frame.x + reserved_width_left
257
- @draw_pos_y = frame.y - @height + reserved_height_bottom
258
- @all_items_fitted = @results.all? {|r| r.box_fitter.success? } &&
259
- @results.size == @children.size
260
- @fit_successful = @all_items_fitted || (@initial_height > 0 && style.overflow == :truncate)
248
+ if @results.size == @children.size && @results.all? {|r| r.box_fitter.success? }
249
+ fit_result.success!
250
+ elsif !@results.empty? && !@results[0].box_fitter.fit_results.empty?
251
+ fit_result.overflow!
252
+ end
261
253
  end
262
254
 
263
- private
264
-
265
255
  # Removes the +content_indentation+ from the left side of the given shape (a Geom2D::PolygonSet).
266
256
  def remove_indent_from_frame_shape(shape)
267
257
  polygon_index = 0
@@ -307,7 +297,7 @@ module HexaPDF
307
297
  end
308
298
 
309
299
  # Splits the content of the list box. This method is called from Box#split.
310
- def split_content(_available_width, _available_height, _frame)
300
+ def split_content
311
301
  remaining_boxes = @results[-1].box_fitter.remaining_boxes
312
302
  first_is_split_box = !remaining_boxes.empty?
313
303
  children = (remaining_boxes.empty? ? [] : [remaining_boxes]) + @children[@results.size..-1]
@@ -361,17 +351,9 @@ module HexaPDF
361
351
 
362
352
  # Draws the list items onto the canvas at position [x, y].
363
353
  def draw_content(canvas, x, y)
364
- if !@all_items_fitted && (@initial_height > 0 && style.overflow == :error)
365
- raise HexaPDF::Error, "Some items don't fit into box with limited height and " \
366
- "style property overflow is set to :error"
367
- end
354
+ translate = style.position != :flow && (x != @fit_x || y != @fit_y)
368
355
 
369
- translate = style.position != :flow && (x != @draw_pos_x || y != @draw_pos_y)
370
-
371
- if translate
372
- canvas.save_graphics_state
373
- canvas.translate(x - @draw_pos_x, y - @draw_pos_y)
374
- end
356
+ canvas.save_graphics_state.translate(x - @fit_x, y - @fit_y) if translate
375
357
 
376
358
  @results.each do |item_result|
377
359
  box_fitter = item_result.box_fitter
@@ -393,7 +393,7 @@ module HexaPDF
393
393
  # The object resolved in this way needs to respond to #call(canvas, box) where +canvas+ is the
394
394
  # HexaPDF::Content::Canvas object on which it should be drawn and +box+ is a box-like object
395
395
  # (e.g. Box or TextFragment). The coordinate system is translated so that the origin is at the
396
- # bottom left corner of the box during the drawing operations.
396
+ # bottom-left corner of the box during the drawing operations.
397
397
  class Layers
398
398
 
399
399
  # Creates a new Layers object popuplated with the given +layers+.
@@ -1254,7 +1254,11 @@ module HexaPDF
1254
1254
  # doesn't. If a box doesn't support this value, it is positioned as if the value :default
1255
1255
  # was set.
1256
1256
  #
1257
- # Note that the properties #align and #valign are not used with this value!
1257
+ # Notes:
1258
+ #
1259
+ # * The properties #align and #valign are not used with this value.
1260
+ # * The rectangular area of the box is the rectangle containing all the flowed content.
1261
+ # That rectangle is used for drawing the border, background and so on.
1258
1262
  #
1259
1263
  # Examples:
1260
1264
  #
@@ -1264,8 +1268,8 @@ module HexaPDF
1264
1268
  # composer.lorem_ipsum(position: :flow)
1265
1269
  #
1266
1270
  # [x, y]::
1267
- # Position the box with the bottom left corner at the given absolute position relative to
1268
- # the bottom left corner of the frame.
1271
+ # Position the box with the bottom-left corner at the given absolute position relative to
1272
+ # the bottom-left corner of the frame.
1269
1273
  #
1270
1274
  # Examples:
1271
1275
  #
@@ -211,56 +211,55 @@ module HexaPDF
211
211
  @height = height
212
212
  end
213
213
 
214
+ # :nodoc:
215
+ def inspect
216
+ "<Cell (#{row},#{column}) #{row_span}x#{col_span} #{Array(children).map(&:class)}>"
217
+ end
218
+
219
+ private
220
+
214
221
  # Fits the children of the table cell into the given rectangular area.
215
- def fit(available_width, available_height, frame)
216
- @width = available_width
222
+ def fit_content(available_width, available_height, frame)
217
223
  width = available_width - reserved_width
218
- height = available_height - reserved_height
219
- return false if width <= 0 || height <= 0
224
+ height = @used_height = available_height - reserved_height
225
+ return if width <= 0 || height <= 0
220
226
 
221
227
  frame = frame.child_frame(0, 0, width, height, box: self)
222
228
  case children
223
229
  when Box
224
- fit_result = frame.fit(children)
225
- @preferred_width = fit_result.x + fit_result.box.width + reserved_width
226
- @height = @preferred_height = fit_result.box.height + reserved_height
227
- @fit_results = [fit_result]
228
- @fit_successful = fit_result.success?
230
+ child_result = frame.fit(children)
231
+ if child_result.success?
232
+ @preferred_width = child_result.x + child_result.box.width + reserved_width
233
+ @height = @preferred_height = child_result.box.height + reserved_height
234
+ @fit_results = [child_result]
235
+ fit_result.success!
236
+ end
229
237
  when Array
230
238
  box_fitter = BoxFitter.new([frame])
231
239
  children.each {|box| box_fitter.fit(box) }
232
- max_x_result = box_fitter.fit_results.max_by {|result| result.x + result.box.width }
233
- @preferred_width = max_x_result.x + max_x_result.box.width + reserved_width
234
- @height = @preferred_height = box_fitter.content_heights[0] + reserved_height
235
- @fit_results = box_fitter.fit_results
236
- @fit_successful = box_fitter.success?
240
+ if box_fitter.success?
241
+ max_x_result = box_fitter.fit_results.max_by {|result| result.x + result.box.width }
242
+ @preferred_width = max_x_result.x + max_x_result.box.width + reserved_width
243
+ @height = @preferred_height = box_fitter.content_heights[0] + reserved_height
244
+ @fit_results = box_fitter.fit_results
245
+ fit_result.success!
246
+ end
237
247
  else
238
248
  @preferred_width = reserved_width
239
249
  @height = @preferred_height = reserved_height
240
250
  @fit_results = []
241
- @fit_successful = true
251
+ fit_result.success!
242
252
  end
243
253
  end
244
254
 
245
- # :nodoc:
246
- def inspect
247
- "<Cell (#{row},#{column}) #{row_span}x#{col_span} #{Array(children).map(&:class)}>"
248
- end
249
-
250
- private
251
-
252
255
  # Draws the content of the cell.
253
256
  def draw_content(canvas, x, y)
254
257
  return if @fit_results.empty?
255
258
 
256
259
  # available_width is always equal to content_width but we need to adjust for the
257
260
  # difference in the y direction between fitting and drawing
258
- y -= (@fit_results[0].available_height - content_height)
259
- @fit_results.each do |fit_result|
260
- #fit_result.x += x
261
- #fit_result.y += y
262
- fit_result.draw(canvas, dx: x, dy: y)
263
- end
261
+ y -= (@used_height - content_height)
262
+ @fit_results.each {|fit_result| fit_result.draw(canvas, dx: x, dy: y) }
264
263
  end
265
264
 
266
265
  end
@@ -393,7 +392,7 @@ module HexaPDF
393
392
  else
394
393
  column_info[cell.column].last
395
394
  end
396
- unless cell.fit(available_cell_width, available_height, frame)
395
+ unless cell.fit(available_cell_width, available_height, frame).success?
397
396
  row_fit = false
398
397
  break
399
398
  end
@@ -589,24 +588,23 @@ module HexaPDF
589
588
  super && (!@last_fitted_row_index || @last_fitted_row_index < 0)
590
589
  end
591
590
 
592
- # Fits the table into the current region of the frame.
593
- def fit(available_width, available_height, frame)
594
- return false if (@initial_width > 0 && @initial_width > available_width) ||
595
- (@initial_height > 0 && @initial_height > available_height)
591
+ private
596
592
 
593
+ # Fits the table into the current region of the frame.
594
+ def fit_content(_available_width, _available_height, frame)
597
595
  # Adjust reserved width/height to include space used by the edge cells for their border
598
596
  # since cell borders are drawn on the bounds and not inside.
599
597
  # This uses the top-left and bottom-right cells and so might not be correct in all cases.
600
598
  @cell_tl_border_width = @cells[0, 0].style.border.width
601
599
  cell_br_border_width = @cells[-1, -1].style.border.width
602
- rw = reserved_width + (@cell_tl_border_width.left + cell_br_border_width.right) / 2.0
603
- rh = reserved_height + (@cell_tl_border_width.top + cell_br_border_width.bottom) / 2.0
600
+ rw = (@cell_tl_border_width.left + cell_br_border_width.right) / 2.0
601
+ rh = (@cell_tl_border_width.top + cell_br_border_width.bottom) / 2.0
604
602
 
605
- width = (@initial_width > 0 ? @initial_width : available_width) - rw
606
- height = (@initial_height > 0 ? @initial_height : available_height) - rh
603
+ width = @width - reserved_width - rw
604
+ height = @height - reserved_height - rh
607
605
  used_height = 0
608
606
  columns = calculate_column_widths(width)
609
- return false if columns.empty?
607
+ return if columns.empty?
610
608
 
611
609
  frame = frame.child_frame(box: self)
612
610
  @special_cells_fit_not_successful = false
@@ -616,18 +614,21 @@ module HexaPDF
616
614
  height -= special_used_height
617
615
  used_height += special_used_height
618
616
  @special_cells_fit_not_successful = (last_fitted_row_index != special_cells.number_of_rows - 1)
619
- return false if @special_cells_fit_not_successful
617
+ return nil if @special_cells_fit_not_successful
620
618
  end
621
619
 
622
620
  main_used_height, @last_fitted_row_index = @cells.fit_rows(@start_row_index, height, columns, frame)
623
621
  used_height += main_used_height
624
622
 
625
- @width = (@initial_width > 0 ? @initial_width : columns[-1].sum + rw)
626
- @height = (@initial_height > 0 ? @initial_height : used_height + rh)
627
- @fit_successful = (@last_fitted_row_index == @cells.number_of_rows - 1)
628
- end
623
+ update_content_width { columns[-1].sum + rw }
624
+ update_content_height { used_height + rh }
629
625
 
630
- private
626
+ if @last_fitted_row_index == @cells.number_of_rows - 1
627
+ fit_result.success!
628
+ elsif @last_fitted_row_index >= 0
629
+ fit_result.overflow!
630
+ end
631
+ end
631
632
 
632
633
  # Calculates and returns the x-coordinates and widths of all columns based on the given total
633
634
  # available width.
@@ -649,20 +650,16 @@ module HexaPDF
649
650
  end
650
651
 
651
652
  # Splits the content of the table box. This method is called from Box#split.
652
- def split_content(_available_width, _available_height, _frame)
653
- if @special_cells_fit_not_successful || @last_fitted_row_index < 0
654
- [nil, self]
655
- else
656
- box = create_split_box
657
- box.instance_variable_set(:@start_row_index, @last_fitted_row_index + 1)
658
- box.instance_variable_set(:@last_fitted_row_index, -1)
659
- box.instance_variable_set(:@special_cells_fit_not_successful, nil)
660
- header_cells = @header ? Cells.new(@header.call(self), cell_style: @cell_style) : nil
661
- box.instance_variable_set(:@header_cells, header_cells)
662
- footer_cells = @footer ? Cells.new(@footer.call(self), cell_style: @cell_style) : nil
663
- box.instance_variable_set(:@footer_cells, footer_cells)
664
- [self, box]
665
- end
653
+ def split_content
654
+ box = create_split_box
655
+ box.instance_variable_set(:@start_row_index, @last_fitted_row_index + 1)
656
+ box.instance_variable_set(:@last_fitted_row_index, -1)
657
+ box.instance_variable_set(:@special_cells_fit_not_successful, nil)
658
+ header_cells = @header ? Cells.new(@header.call(self), cell_style: @cell_style) : nil
659
+ box.instance_variable_set(:@header_cells, header_cells)
660
+ footer_cells = @footer ? Cells.new(@footer.call(self), cell_style: @cell_style) : nil
661
+ box.instance_variable_set(:@footer_cells, footer_cells)
662
+ [self, box]
666
663
  end
667
664
 
668
665
  # Draws the child boxes onto the canvas at position [x, y].