hexapdf 0.43.0 → 0.45.0

Sign up to get free protection for your applications and to get access to all the features.
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].