hexapdf 0.34.1 → 0.35.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -0
  3. data/examples/009-text_layouter_alignment.rb +7 -7
  4. data/examples/010-text_layouter_inline_boxes.rb +1 -1
  5. data/examples/011-text_layouter_line_wrapping.rb +2 -4
  6. data/examples/013-text_layouter_shapes.rb +9 -11
  7. data/examples/014-text_in_polygon.rb +2 -2
  8. data/examples/016-frame_automatic_box_placement.rb +6 -7
  9. data/examples/017-frame_text_flow.rb +2 -2
  10. data/examples/018-composer.rb +5 -6
  11. data/examples/020-column_box.rb +2 -2
  12. data/examples/021-list_box.rb +1 -1
  13. data/examples/027-composer_optional_content.rb +5 -5
  14. data/examples/028-frame_mask_mode.rb +23 -0
  15. data/examples/029-composer_fallback_fonts.rb +22 -0
  16. data/lib/hexapdf/cli/info.rb +1 -0
  17. data/lib/hexapdf/cli/inspect.rb +55 -2
  18. data/lib/hexapdf/composer.rb +2 -2
  19. data/lib/hexapdf/configuration.rb +61 -1
  20. data/lib/hexapdf/content/canvas.rb +63 -0
  21. data/lib/hexapdf/content/canvas_composer.rb +142 -0
  22. data/lib/hexapdf/content.rb +1 -0
  23. data/lib/hexapdf/dictionary.rb +14 -3
  24. data/lib/hexapdf/document/layout.rb +35 -13
  25. data/lib/hexapdf/encryption/standard_security_handler.rb +15 -0
  26. data/lib/hexapdf/error.rb +2 -1
  27. data/lib/hexapdf/font/invalid_glyph.rb +22 -6
  28. data/lib/hexapdf/font/true_type_wrapper.rb +48 -20
  29. data/lib/hexapdf/font/type1_wrapper.rb +48 -24
  30. data/lib/hexapdf/layout/box.rb +11 -8
  31. data/lib/hexapdf/layout/column_box.rb +5 -3
  32. data/lib/hexapdf/layout/frame.rb +77 -39
  33. data/lib/hexapdf/layout/image_box.rb +3 -3
  34. data/lib/hexapdf/layout/list_box.rb +20 -19
  35. data/lib/hexapdf/layout/style.rb +173 -68
  36. data/lib/hexapdf/layout/table_box.rb +3 -3
  37. data/lib/hexapdf/layout/text_box.rb +5 -5
  38. data/lib/hexapdf/layout/text_fragment.rb +50 -0
  39. data/lib/hexapdf/layout/text_layouter.rb +7 -6
  40. data/lib/hexapdf/object.rb +5 -2
  41. data/lib/hexapdf/pdf_array.rb +5 -0
  42. data/lib/hexapdf/type/acro_form/appearance_generator.rb +16 -11
  43. data/lib/hexapdf/utils/sorted_tree_node.rb +0 -10
  44. data/lib/hexapdf/version.rb +1 -1
  45. data/test/hexapdf/content/test_canvas.rb +37 -0
  46. data/test/hexapdf/content/test_canvas_composer.rb +112 -0
  47. data/test/hexapdf/document/test_layout.rb +40 -12
  48. data/test/hexapdf/encryption/test_standard_security_handler.rb +43 -0
  49. data/test/hexapdf/font/test_invalid_glyph.rb +13 -1
  50. data/test/hexapdf/font/test_true_type_wrapper.rb +15 -2
  51. data/test/hexapdf/font/test_type1_wrapper.rb +21 -2
  52. data/test/hexapdf/layout/test_column_box.rb +14 -0
  53. data/test/hexapdf/layout/test_frame.rb +181 -95
  54. data/test/hexapdf/layout/test_list_box.rb +7 -7
  55. data/test/hexapdf/layout/test_style.rb +14 -10
  56. data/test/hexapdf/layout/test_table_box.rb +3 -3
  57. data/test/hexapdf/layout/test_text_box.rb +2 -2
  58. data/test/hexapdf/layout/test_text_fragment.rb +37 -0
  59. data/test/hexapdf/layout/test_text_layouter.rb +10 -10
  60. data/test/hexapdf/test_configuration.rb +49 -0
  61. data/test/hexapdf/test_dictionary.rb +1 -1
  62. data/test/hexapdf/test_object.rb +13 -12
  63. data/test/hexapdf/test_pdf_array.rb +9 -0
  64. data/test/hexapdf/test_writer.rb +3 -3
  65. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +41 -13
  66. data/test/hexapdf/utils/test_sorted_tree_node.rb +1 -1
  67. metadata +7 -3
@@ -48,8 +48,8 @@ module HexaPDF
48
48
  # Represents a single glyph of the wrapped font.
49
49
  class Glyph
50
50
 
51
- # The associated font object.
52
- attr_reader :font
51
+ # The associated Type1Wrapper object.
52
+ attr_reader :font_wrapper
53
53
 
54
54
  # The name of the glyph.
55
55
  attr_reader :name
@@ -59,35 +59,35 @@ module HexaPDF
59
59
  attr_reader :str
60
60
 
61
61
  # Creates a new Glyph object.
62
- def initialize(font, name, str)
63
- @font = font
62
+ def initialize(font_wrapper, name, str)
63
+ @font_wrapper = font_wrapper
64
64
  @name = name
65
65
  @str = str
66
66
  end
67
67
 
68
68
  # Returns the glyph's minimum x coordinate.
69
69
  def x_min
70
- @font.metrics.character_metrics[name].bbox[0]
70
+ @font_wrapper.wrapped_font.metrics.character_metrics[name].bbox[0]
71
71
  end
72
72
 
73
73
  # Returns the glyph's maximum x coordinate.
74
74
  def x_max
75
- @font.metrics.character_metrics[name].bbox[2]
75
+ @font_wrapper.wrapped_font.metrics.character_metrics[name].bbox[2]
76
76
  end
77
77
 
78
78
  # Returns the glyph's minimum y coordinate.
79
79
  def y_min
80
- @font.metrics.character_metrics[name].bbox[1]
80
+ @font_wrapper.wrapped_font.metrics.character_metrics[name].bbox[1]
81
81
  end
82
82
 
83
83
  # Returns the glyph's maximum y coordinate.
84
84
  def y_max
85
- @font.metrics.character_metrics[name].bbox[3]
85
+ @font_wrapper.wrapped_font.metrics.character_metrics[name].bbox[3]
86
86
  end
87
87
 
88
88
  # Returns the width of the glyph.
89
89
  def width
90
- @width ||= @font.width(name)
90
+ @width ||= @font_wrapper.wrapped_font.width(name)
91
91
  end
92
92
 
93
93
  # Returns +true+ if the word spacing parameter needs to be applied for the glyph.
@@ -95,9 +95,15 @@ module HexaPDF
95
95
  @name == :space
96
96
  end
97
97
 
98
+ # Returns +true+ since this is a valid glyph.
99
+ def valid?
100
+ true
101
+ end
102
+
98
103
  #:nodoc:
99
104
  def inspect
100
- "#<#{self.class.name} font=#{@font.full_name.inspect} id=#{name.inspect} #{str.inspect}>"
105
+ "#<#{self.class.name} font=#{@font_wrapper.wrapped_font.full_name.inspect} " \
106
+ "id=#{name.inspect} #{str.inspect}>"
101
107
  end
102
108
 
103
109
  end
@@ -154,13 +160,23 @@ module HexaPDF
154
160
  1
155
161
  end
156
162
 
163
+ # Returns +true+ if the font contains bold glyphs.
164
+ def bold?
165
+ @wrapped_font.weight_class > 500
166
+ end
167
+
168
+ # Returns +true+ if the font contains glyphs with an incline (italic or slant).
169
+ def italic?
170
+ @wrapped_font.italic_angle.to_i != 0
171
+ end
172
+
157
173
  # Returns a Glyph object for the given glyph name.
158
174
  def glyph(name)
159
175
  @name_to_glyph[name] ||=
160
176
  begin
161
177
  str = Encoding::GlyphList.name_to_unicode(name, **@zapf_dingbats_opt)
162
178
  if @wrapped_font.metrics.character_metrics.key?(name)
163
- Glyph.new(@wrapped_font, name, str)
179
+ Glyph.new(self, name, str)
164
180
  else
165
181
  @pdf_object.document.config['font.on_missing_glyph'].call(str, self)
166
182
  end
@@ -178,27 +194,35 @@ module HexaPDF
178
194
  raise HexaPDF::Error, "Glyph named #{name.inspect} not found in " \
179
195
  "font '#{@wrapped_font.full_name}'"
180
196
  end
181
- Glyph.new(@wrapped_font, name, string)
197
+ Glyph.new(self, name, string)
182
198
  end
183
199
 
184
200
  # Returns an array of glyph objects representing the characters in the UTF-8 encoded string.
185
201
  #
202
+ # See #decode_codepoint for details.
203
+ def decode_utf8(str)
204
+ str.codepoints.map! {|c| @codepoint_to_glyph[c] || decode_codepoint(c) }
205
+ end
206
+
207
+ # Returns a glyph object for the given Unicode codepoint.
208
+ #
186
209
  # If a Unicode codepoint is not available as glyph object, it is tried to map the codepoint
187
210
  # using the font's internal encoding. This is useful, for example, for the ZapfDingbats font
188
211
  # to use ASCII characters for accessing the glyphs.
189
- def decode_utf8(str)
190
- str.codepoints.map! do |c|
191
- @codepoint_to_glyph[c] ||=
192
- begin
193
- name = Encoding::GlyphList.unicode_to_name(+'' << c, **@zapf_dingbats_opt)
194
- if @wrapped_font.metrics.character_set == 'Special' &&
195
- (name == :'.notdef' || !@wrapped_font.metrics.character_metrics.key?(name))
196
- name = @encoding.name(c)
197
- end
198
- name = +"u" << c.to_s(16).rjust(6, '0') if name == :'.notdef'
199
- glyph(name)
212
+ #
213
+ # The configuration option 'font.on_missing_glyph' is invoked if no glyph for a given
214
+ # codepoint is available.
215
+ def decode_codepoint(codepoint)
216
+ @codepoint_to_glyph[codepoint] ||=
217
+ begin
218
+ name = Encoding::GlyphList.unicode_to_name(+'' << codepoint, **@zapf_dingbats_opt)
219
+ if @wrapped_font.metrics.character_set == 'Special' &&
220
+ (name == :'.notdef' || !@wrapped_font.metrics.character_metrics.key?(name))
221
+ name = @encoding.name(codepoint)
200
222
  end
201
- end
223
+ name = +"u" << codepoint.to_s(16).rjust(6, '0') if name == :'.notdef'
224
+ glyph(name)
225
+ end
202
226
  end
203
227
 
204
228
  # Encodes the glyph and returns the code string.
@@ -71,7 +71,7 @@ module HexaPDF
71
71
  # If the subclass supports the value :flow of the 'position' style property, this method
72
72
  # needs to be overridden to return +true+.
73
73
  #
74
- # #split:: This method splits the content so that the available space is used as good as
74
+ # #split:: This method splits the content so that the current region is used as good as
75
75
  # possible. The default implementation should be fine for most use-cases, so only
76
76
  # #split_content needs to be implemented. The method #create_split_box should be used
77
77
  # for getting a basic cloned box.
@@ -186,26 +186,29 @@ module HexaPDF
186
186
 
187
187
  # Fits the box into the Frame and returns +true+ if fitting was successful.
188
188
  #
189
- # The default implementation uses the whole available space for width and height if they were
190
- # initially set to 0. Otherwise the specified dimensions are used.
189
+ # The arguments +available_width+ and +available_height+ are the width and height of the
190
+ # current region of the frame. The frame itself is provided as third argument.
191
+ #
192
+ # The default implementation uses the available width and height for the box width and height
193
+ # if they were initially set to 0. Otherwise the specified dimensions are used.
191
194
  def fit(available_width, available_height, _frame)
192
195
  @width = (@initial_width > 0 ? @initial_width : available_width)
193
196
  @height = (@initial_height > 0 ? @initial_height : available_height)
194
197
  @fit_successful = (@width <= available_width && @height <= available_height)
195
198
  end
196
199
 
197
- # Tries to split the box into two, the first of which needs to fit into the available space,
198
- # and returns the parts as array.
200
+ # Tries to split the box into two, the first of which needs to fit into the current region of
201
+ # the frame, and returns the parts as array.
199
202
  #
200
203
  # If the first item in the result array is not +nil+, it needs to be this box and it means
201
204
  # that even when #fit fails, a part of the box may still fit. Note that #fit should not be
202
205
  # called before #draw on the first box since it is already fitted. If not even a part of this
203
- # box fits into the available space, +nil+ should be returned as the first array element.
206
+ # box fits into the current region, +nil+ should be returned as the first array element.
204
207
  #
205
208
  # Possible return values:
206
209
  #
207
- # [self]:: The box fully fits into the available space.
208
- # [nil, self]:: The box can't be split or no part of the box fits into the available space.
210
+ # [self]:: The box fully fits into the current region.
211
+ # [nil, self]:: The box can't be split or no part of the box fits into the current region.
209
212
  # [self, new_box]:: A part of the box fits and a new box is returned for the rest.
210
213
  #
211
214
  # This default implementation provides the basic functionality based on the #fit result that
@@ -138,12 +138,14 @@ module HexaPDF
138
138
  super && (!@box_fitter || @box_fitter.fit_results.empty?)
139
139
  end
140
140
 
141
- # Fits the column box into the available space.
141
+ # Fits the column box into the current region of the frame.
142
142
  #
143
143
  # If the style property 'position' is set to :flow, the columns might not be rectangles but
144
144
  # arbitrary (sets of) polygons since the +frame+s shape is taken into account.
145
145
  def fit(available_width, available_height, frame)
146
- initial_fit_successful = (@equal_height ? nil : false)
146
+ return false if @initial_height > available_height || @initial_width > available_width
147
+
148
+ initial_fit_successful = (@equal_height && @columns.size > 1 ? nil : false)
147
149
  tries = 0
148
150
  @width = if style.position == :flow
149
151
  (@initial_width > 0 ? @initial_width : frame.width) - reserved_width
@@ -205,7 +207,7 @@ module HexaPDF
205
207
  end
206
208
 
207
209
  @width = columns[-1].sum + reserved_width
208
- @height = @box_fitter.content_heights.max + reserved_height
210
+ @height = (@initial_height > 0 ? @initial_height : @box_fitter.content_heights.max + reserved_height)
209
211
  @draw_pos_x = frame.x + reserved_width_left
210
212
  @draw_pos_y = frame.y - @height + reserved_height_bottom
211
213
 
@@ -53,8 +53,8 @@ module HexaPDF
53
53
  # available space. If fitting is successful, the box can be drawn using #draw.
54
54
  #
55
55
  # The method #fit is also called for absolutely positioned boxes but since these boxes are not
56
- # subject to the normal constraints, the available space used is the width and height inside
57
- # the frame to the right and top of the bottom-left corner of the box.
56
+ # subject to the normal constraints, the provided available width and height are the width and
57
+ # height inside the frame to the right and top of the bottom-left corner of the box.
58
58
  #
59
59
  # * If the box didn't fit, call #find_next_region to determine the next region for placing the
60
60
  # box. If a new region was found, start over with #fit. Otherwise the frame has no more space
@@ -71,9 +71,9 @@ module HexaPDF
71
71
  #
72
72
  # == Used Box Properties
73
73
  #
74
- # The style properties "position", "position_hint" and "margin" are taken into account when
75
- # fitting, splitting or drawing a box. Note that the margin is ignored if a box's side coincides
76
- # with the frame's original boundary.
74
+ # The style properties 'position', 'align', 'valign', 'margin' and 'mask_mode' are taken into
75
+ # account when fitting, splitting or drawing a box. Note that the margin is ignored if a box's
76
+ # side coincides with the frame's original boundary.
77
77
  #
78
78
  # == Frame Shape
79
79
  #
@@ -178,12 +178,12 @@ module HexaPDF
178
178
  # Also see the note in the #x documentation for further information.
179
179
  attr_reader :y
180
180
 
181
- # The available width for placing a box.
181
+ # The available width of the current region for placing a box.
182
182
  #
183
183
  # Also see the note in the #x documentation for further information.
184
184
  attr_reader :available_width
185
185
 
186
- # The available height for placing a box.
186
+ # The available height of the current region for placing a box.
187
187
  #
188
188
  # Also see the note in the #x documentation for further information.
189
189
  attr_reader :available_height
@@ -219,19 +219,24 @@ module HexaPDF
219
219
  # Fits the given box into the current region of available space and returns a FitResult
220
220
  # object.
221
221
  #
222
+ # Fitting a box takes the style properties 'position', 'align', 'valign', 'margin', and
223
+ # 'mask_mode' into account.
224
+ #
222
225
  # Use the FitResult#success? method to determine whether fitting was successful.
223
226
  def fit(box)
224
227
  fit_result = FitResult.new(box)
225
228
  return fit_result if full?
226
229
 
230
+ margin = box.style.margin if box.style.margin?
231
+
227
232
  position = if box.style.position != :flow || box.supports_position_flow?
228
233
  box.style.position
229
234
  else
230
235
  :default
231
236
  end
232
237
 
233
- if position == :absolute
234
- x, y = box.style.position_hint
238
+ if position.kind_of?(Array)
239
+ x, y = box.style.position
235
240
 
236
241
  aw = width - x
237
242
  ah = height - y
@@ -240,23 +245,15 @@ module HexaPDF
240
245
 
241
246
  x += left
242
247
  y += bottom
243
- rectangle = if box.style.margin?
244
- margin = box.style.margin
245
- create_rectangle(x - margin.left, y - margin.bottom,
246
- x + box.width + margin.right, y + box.height + margin.top)
247
- else
248
- create_rectangle(x, y, x + box.width, y + box.height)
249
- end
250
248
  else
251
249
  aw = available_width
252
250
  ah = available_height
253
251
 
254
- margin_top = margin_right = margin_left = 0
255
- if box.style.margin?
256
- margin = box.style.margin
252
+ margin_top = margin_right = margin_left = margin_bottom = 0
253
+ if margin
257
254
  aw -= margin_right = margin.right unless float_equal(@x + aw, @left + @width)
258
255
  aw -= margin_left = margin.left unless float_equal(@x, @left)
259
- ah -= margin.bottom unless float_equal(@y - ah, @bottom)
256
+ ah -= margin_bottom = margin.bottom unless float_equal(@y - ah, @bottom)
260
257
  ah -= margin_top = margin.top unless float_equal(@y, @bottom + @height)
261
258
  end
262
259
 
@@ -266,14 +263,9 @@ module HexaPDF
266
263
  height = box.height
267
264
 
268
265
  case position
269
- when :flow
270
- x = 0
271
- y = @y - height
272
- rectangle = create_rectangle(left, [bottom, y - (margin&.bottom || 0)].max,
273
- left + self.width, @y)
274
- else
275
- x = case box.style.position_hint
276
- when nil, :left
266
+ when :default, :float
267
+ x = case box.style.align
268
+ when :left
277
269
  @x + margin_left
278
270
  when :right
279
271
  @x + margin_left + aw - width
@@ -286,19 +278,63 @@ module HexaPDF
286
278
  @x + margin_left + (aw - width) / 2.0
287
279
  end
288
280
  end
289
- y = @y - height - margin_top
290
- rectangle = if position == :float
291
- create_rectangle([left, x - (margin&.left || 0)].max,
292
- [bottom, y - (margin&.bottom || 0)].max,
293
- [left + self.width, x + width + (margin&.right || 0)].min,
294
- @y)
295
- else
296
- create_rectangle(left, [bottom, y - (margin&.bottom || 0)].max,
297
- left + self.width, @y)
298
- end
281
+ y = case box.style.valign
282
+ when :top
283
+ @y - margin_top - height
284
+ when :bottom
285
+ @y - available_height + margin_bottom
286
+ when :center
287
+ max_margin = [margin_top, margin_bottom].max
288
+ # If we have enough space left for equal margins, we center perfectly
289
+ if available_height - height >= 2 * max_margin
290
+ @y - height - (available_height - height) / 2.0
291
+ else
292
+ @y - margin_top - height - (ah - height) / 2.0
293
+ end
294
+ end
295
+ when :flow
296
+ x = 0
297
+ y = @y - height
298
+ else
299
+ raise HexaPDF::Error, "Invalid value '#{position}' for style property position"
299
300
  end
300
301
  end
301
302
 
303
+ mask_mode = if box.style.mask_mode == :default
304
+ case position
305
+ when :default, :flow then :fill_frame_horizontal
306
+ else :box
307
+ end
308
+ else
309
+ box.style.mask_mode
310
+ end
311
+ rectangle =
312
+ case mask_mode
313
+ when :none
314
+ create_rectangle(x, y, x, y)
315
+ when :box
316
+ if margin
317
+ create_rectangle([left, x - (margin&.left || 0)].max,
318
+ [bottom, y - (margin&.bottom || 0)].max,
319
+ [left + self.width, x + box.width + (margin&.right || 0)].min,
320
+ [bottom + self.height, y + box.height + (margin&.top || 0)].min)
321
+ else
322
+ create_rectangle(x, y, x + box.width, y + box.height)
323
+ end
324
+ when :fill_horizontal
325
+ create_rectangle(@x, [bottom, y - (margin&.bottom || 0)].max,
326
+ @x + available_width,
327
+ [@y, y + box.height + (margin&.top || 0)].min)
328
+ when :fill_frame_horizontal
329
+ create_rectangle(left, [bottom, y - (margin&.bottom || 0)].max,
330
+ left + self.width, @y)
331
+ when :fill_vertical
332
+ create_rectangle([@x, x - (margin&.left || 0)].max, @y - available_height,
333
+ [@x + available_width, x + box.width + (margin&.right || 0)].min, @y)
334
+ when :fill
335
+ create_rectangle(@x, @y - available_height, @x + available_width, @y)
336
+ end
337
+
302
338
  fit_result.available_width = aw
303
339
  fit_result.available_height = ah
304
340
  fit_result.x = x
@@ -326,7 +362,7 @@ module HexaPDF
326
362
 
327
363
  # Finds the next region for placing boxes. Returns +false+ if no useful region was found.
328
364
  #
329
- # This method should be called after drawing a box using #draw was not successful. It finds a
365
+ # This method should be called after fitting or drawing a box was not successful. It finds a
330
366
  # different region on each invocation. So if a box doesn't fit into the first region, this
331
367
  # method should be called again to find another region and to try again.
332
368
  #
@@ -363,6 +399,8 @@ module HexaPDF
363
399
 
364
400
  # Removes the given *rectilinear* polygon from the frame's shape.
365
401
  def remove_area(polygon)
402
+ return if polygon.kind_of?(Geom2D::Rectangle) && (polygon.width == 0 || polygon.height == 0)
403
+
366
404
  @shape = if @shape.kind_of?(Geom2D::Rectangle) && polygon.kind_of?(Geom2D::Rectangle) &&
367
405
  float_equal(@shape.x, polygon.x) && float_equal(@shape.width, polygon.width) &&
368
406
  float_equal(@shape.y + @shape.height, polygon.y + polygon.height)
@@ -56,7 +56,7 @@ module HexaPDF
56
56
  # #>pdf-composer100
57
57
  # composer.image(machu_picchu, width: 100, height: 30)
58
58
  #
59
- # * If neither has been set, the image is scaled to fit the available space.
59
+ # * If neither has been set, the image is scaled to fit the current region.
60
60
  #
61
61
  # #>pdf-composer100
62
62
  # composer.image(machu_picchu)
@@ -79,8 +79,8 @@ module HexaPDF
79
79
  false
80
80
  end
81
81
 
82
- # Fits the image into the available space, taking the initially set width and height into
83
- # account (see the class description for details).
82
+ # Fits the image into the current region of the frame, taking the initially set width and
83
+ # height into account (see the class description for details).
84
84
  def fit(available_width, available_height, _frame)
85
85
  image_width = @image.width.to_f
86
86
  image_height = @image.height.to_f
@@ -44,9 +44,10 @@ module HexaPDF
44
44
 
45
45
  # A ListBox arranges its children as unordered or ordered list items.
46
46
  #
47
- # The indentation of the contents from the left (#content_indentation) as well as the type of
48
- # item (#item_type) can be specified. Additionally, it is possible to define the start number
49
- # for ordered lists (#start_number) and the amount of spacing between items (#item_spacing).
47
+ # The indentation of the contents from the left (#content_indentation) as well as the marker
48
+ # type of the items (#marker_type) can be specified. Additionally, it is possible to define the
49
+ # start number for ordered lists (#start_number) and the amount of spacing between items
50
+ # (#item_spacing).
50
51
  #
51
52
  # If the list box has padding and/or borders specified, they are handled like with any other
52
53
  # box. This means they are around all items and their contents and are not used separately for
@@ -75,7 +76,7 @@ module HexaPDF
75
76
  # Draws a filled disc for the items of the unordered list.
76
77
  #
77
78
  # #>pdf-composer100
78
- # composer.box(:list, item_type: :disc) do |list|
79
+ # composer.box(:list, marker_type: :disc) do |list|
79
80
  # list.lorem_ipsum_box(sentences: 1)
80
81
  # end
81
82
  #
@@ -84,7 +85,7 @@ module HexaPDF
84
85
  # Draws an unfilled circle for the items of the unordered list.
85
86
  #
86
87
  # #>pdf-composer100
87
- # composer.box(:list, item_type: :circle) do |list|
88
+ # composer.box(:list, marker_type: :circle) do |list|
88
89
  # list.lorem_ipsum_box(sentences: 1)
89
90
  # end
90
91
  #
@@ -93,7 +94,7 @@ module HexaPDF
93
94
  # Draws a filled square for the items of the unordered list.
94
95
  #
95
96
  # #>pdf-composer100
96
- # composer.box(:list, item_type: :square) do |list|
97
+ # composer.box(:list, marker_type: :square) do |list|
97
98
  # list.lorem_ipsum_box(sentences: 1)
98
99
  # end
99
100
  #
@@ -103,7 +104,7 @@ module HexaPDF
103
104
  # the ordered list.
104
105
  #
105
106
  # #>pdf-composer100
106
- # composer.box(:list, item_type: :decimal) do |list|
107
+ # composer.box(:list, marker_type: :decimal) do |list|
107
108
  # 5.times { list.lorem_ipsum_box(sentences: 1) }
108
109
  # end
109
110
  #
@@ -118,19 +119,19 @@ module HexaPDF
118
119
  # image = lambda do |document, box, index|
119
120
  # document.layout.image_box(machu_picchu, height: box.style.font_size)
120
121
  # end
121
- # composer.box(:list, item_type: image) do |list|
122
+ # composer.box(:list, marker_type: image) do |list|
122
123
  # 2.times { list.lorem_ipsum_box(sentences: 1) }
123
124
  # end
124
- attr_reader :item_type
125
+ attr_reader :marker_type
125
126
 
126
- # The start number when using an #item_type that represents an ordered list.
127
+ # The start number when using a #marker_type that represents an ordered list.
127
128
  #
128
129
  # The default value for this is 1.
129
130
  #
130
131
  # Example:
131
132
  #
132
133
  # #>pdf-composer100
133
- # composer.box(:list, item_type: :decimal, start_number: 3) do |list|
134
+ # composer.box(:list, marker_type: :decimal, start_number: 3) do |list|
134
135
  # 2.times { list.lorem_ipsum_box(sentences: 1) }
135
136
  # end
136
137
  attr_reader :start_number
@@ -162,11 +163,11 @@ module HexaPDF
162
163
  attr_reader :item_spacing
163
164
 
164
165
  # Creates a new ListBox object for the given child boxes in +children+.
165
- def initialize(children: [], item_type: :disc, content_indentation: nil, start_number: 1,
166
+ def initialize(children: [], marker_type: :disc, content_indentation: nil, start_number: 1,
166
167
  item_spacing: 0, **kwargs)
167
168
  super(**kwargs)
168
169
  @children = children
169
- @item_type = item_type
170
+ @marker_type = marker_type
170
171
  @content_indentation = content_indentation || 2 * style.font_size
171
172
  @start_number = start_number
172
173
  @item_spacing = item_spacing
@@ -185,7 +186,7 @@ module HexaPDF
185
186
  super && (!@results || @results.all? {|result| result.box_fitter.fit_results.empty? })
186
187
  end
187
188
 
188
- # Fits the list box into the available space.
189
+ # Fits the list box into the current region of the frame.
189
190
  def fit(available_width, available_height, frame)
190
191
  @width = if @initial_width > 0
191
192
  @initial_width
@@ -322,10 +323,10 @@ module HexaPDF
322
323
  # Creates a box for the item marker at the given item index, using #item_style to decide on
323
324
  # its contents.
324
325
  def item_marker_box(document, index)
325
- return @item_type.call(document, self, index) if @item_type.kind_of?(Proc)
326
+ return @marker_type.call(document, self, index) if @marker_type.kind_of?(Proc)
326
327
  return @item_marker_box if defined?(@item_marker_box)
327
328
 
328
- fragment = case @item_type
329
+ fragment = case @marker_type
329
330
  when :disc
330
331
  TextFragment.create("•", font: document.fonts.add("Times"),
331
332
  font_size: style.font_size, fill_color: style.fill_color)
@@ -347,10 +348,10 @@ module HexaPDF
347
348
  }
348
349
  TextFragment.create(text, decimal_style)
349
350
  else
350
- raise HexaPDF::Error, "Unknown list item type #{@item_type.inspect}"
351
+ raise HexaPDF::Error, "Unknown list marker type #{@marker_type.inspect}"
351
352
  end
352
- box = TextBox.new(items: [fragment], style: {align: :right, padding: [0, 5, 0, 0]})
353
- @item_marker_box = box unless @item_type == :decimal
353
+ box = TextBox.new(items: [fragment], style: {text_align: :right, padding: [0, 5, 0, 0]})
354
+ @item_marker_box = box unless @marker_type == :decimal
354
355
  box
355
356
  end
356
357