hexapdf 0.39.1 → 0.40.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07f7fd9468ec9c36993f4b1f2189704d65c1c73f7fa1ea30d44f6cb0a67fa92c
4
- data.tar.gz: 1cad88a48910fd65a9dae7a90dcfe6ac34ef5ba9f69172a18bd52052fb10b99c
3
+ metadata.gz: 2dab266d2115bdd9a7c9caf6a7512b56da77c14b8fe080d631d270c89a67e49f
4
+ data.tar.gz: c05acdf542d3b65e2c763f9aa84e21de4ad4f6800a48a4b4ca6873832089a0e2
5
5
  SHA512:
6
- metadata.gz: eeee46c22616abbca812ef441100e33534384db831aadf04df9b9382920aa58105be04046a76a9da76951c1d0bc39126e4ef33c43fa3401077c34604ff414acc
7
- data.tar.gz: 1cd42546ff96980f6fbfeaae450a7f8657350ce3b23692b508b87718028e68fe50acd9ca8b744bc755f9b79029ecd41f5cb1cedc046209336594c3fba5a1807b
6
+ metadata.gz: 0e63528c1c604b06a8f07a53852ebfc2f5172a9aee43320942e4088f8aaf68953acc6f9e6017c4215591a8bb7a428b61fa20bd6e4ea180af39c62058de5b04db
7
+ data.tar.gz: 8b648570a98fcd5f1688c97ead5c05a0da6918cba49b3905bd70f526a65ddf376618e5d533c6bb04823117fc892839a600d0ba63d006699205e1ef399e0b64f5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 0.40.0 - 2024-03-23
2
+
3
+ ### Changed
4
+
5
+ * **Breaking change**: Style property 'text_overflow' is now called 'overflow'
6
+
7
+ ### Fixed
8
+
9
+ * [HexaPDF::Layout::ListBox] to hide marker in case of splitting list items with
10
+ multiple boxes
11
+ * [HexaPDF::Layout::ListBox] to create independent marker boxes for all markers
12
+ * [HexaPDF::Layout::ListBox] to correctly respect a set height
13
+
14
+
1
15
  ## 0.39.1 - 2024-03-20
2
16
 
3
17
  ### Fixed
@@ -255,7 +255,9 @@ module HexaPDF
255
255
 
256
256
  @draw_pos_x = frame.x + reserved_width_left
257
257
  @draw_pos_y = frame.y - @height + reserved_height_bottom
258
- @fit_successful = @results.all? {|r| r.box_fitter.fit_successful? } && @results.size == @children.size
258
+ @all_items_fitted = @results.all? {|r| r.box_fitter.fit_successful? } &&
259
+ @results.size == @children.size
260
+ @fit_successful = @all_items_fitted || (@initial_height > 0 && style.overflow == :truncate)
259
261
  end
260
262
 
261
263
  private
@@ -307,7 +309,7 @@ module HexaPDF
307
309
  # Splits the content of the list box. This method is called from Box#split.
308
310
  def split_content(_available_width, _available_height, _frame)
309
311
  remaining_boxes = @results[-1].box_fitter.remaining_boxes
310
- first_is_split_box = remaining_boxes.first&.split_box?
312
+ first_is_split_box = !remaining_boxes.empty?
311
313
  children = (remaining_boxes.empty? ? [] : [remaining_boxes]) + @children[@results.size..-1]
312
314
 
313
315
  box = create_split_box(split_box_value: first_is_split_box ? :hide_first_marker : :show_first_marker)
@@ -323,42 +325,47 @@ module HexaPDF
323
325
  # its contents.
324
326
  def item_marker_box(document, index)
325
327
  return @marker_type.call(document, self, index) if @marker_type.kind_of?(Proc)
326
- return @item_marker_box if defined?(@item_marker_box)
327
-
328
- marker_style = {
329
- font: style.font? ? style.font : document.fonts.add("Times"),
330
- font_size: style.font_size || 10, fill_color: style.fill_color
331
- }
332
- fragment = case @marker_type
333
- when :disc
334
- TextFragment.create("•", marker_style)
335
- when :circle
336
- unless marker_style[:font].decode_codepoint("❍".ord).valid?
337
- marker_style[:font] = document.fonts.add("ZapfDingbats")
338
- end
339
- TextFragment.create("❍", **marker_style,
340
- font_size: style.font_size / 2.0,
341
- text_rise: -style.font_size / 1.8)
342
- when :square
343
- unless marker_style[:font].decode_codepoint("■".ord).valid?
344
- marker_style[:font] = document.fonts.add("ZapfDingbats")
328
+
329
+ unless (fragment = @item_marker_fragment)
330
+ marker_style = {
331
+ font: style.font? ? style.font : document.fonts.add("Times"),
332
+ font_size: style.font_size || 10, fill_color: style.fill_color
333
+ }
334
+ fragment = case @marker_type
335
+ when :disc
336
+ TextFragment.create("•", marker_style)
337
+ when :circle
338
+ unless marker_style[:font].decode_codepoint("❍".ord).valid?
339
+ marker_style[:font] = document.fonts.add("ZapfDingbats")
340
+ end
341
+ TextFragment.create("❍", **marker_style,
342
+ font_size: style.font_size / 2.0,
343
+ text_rise: -style.font_size / 1.8)
344
+ when :square
345
+ unless marker_style[:font].decode_codepoint("■".ord).valid?
346
+ marker_style[:font] = document.fonts.add("ZapfDingbats")
347
+ end
348
+ TextFragment.create("■", **marker_style,
349
+ font_size: style.font_size / 2.0,
350
+ text_rise: -style.font_size / 1.8)
351
+ when :decimal
352
+ text = (@start_number + index).to_s << "."
353
+ TextFragment.create(text, marker_style)
354
+ else
355
+ raise HexaPDF::Error, "Unknown list marker type #{@marker_type.inspect}"
345
356
  end
346
- TextFragment.create("■", **marker_style,
347
- font_size: style.font_size / 2.0,
348
- text_rise: -style.font_size / 1.8)
349
- when :decimal
350
- text = (@start_number + index).to_s << "."
351
- TextFragment.create(text, marker_style)
352
- else
353
- raise HexaPDF::Error, "Unknown list marker type #{@marker_type.inspect}"
354
- end
355
- box = TextBox.new(items: [fragment], style: {text_align: :right, padding: [0, 5, 0, 0]})
356
- @item_marker_box = box unless @marker_type == :decimal
357
- box
357
+ @item_marker_fragment = fragment unless @marker_type == :decimal
358
+ end
359
+ TextBox.new(items: [fragment], style: {text_align: :right, padding: [0, 5, 0, 0]})
358
360
  end
359
361
 
360
362
  # Draws the list items onto the canvas at position [x, y].
361
363
  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
368
+
362
369
  translate = style.position != :flow && (x != @draw_pos_x || y != @draw_pos_y)
363
370
 
364
371
  if translate
@@ -1084,25 +1084,6 @@ module HexaPDF
1084
1084
  # 'Centered',
1085
1085
  # {text: "\u{00a0}", fill_horizontal: 1, overlays: overlays}])
1086
1086
 
1087
- ##
1088
- # :method: text_overflow
1089
- # :call-seq:
1090
- # text_overflow(mode = nil)
1091
- #
1092
- # Specifies how text overflowing a box with a given initial height should be handled:
1093
- #
1094
- # Possible values:
1095
- #
1096
- # :error:: An error is raised (default).
1097
- # :truncate:: Truncates the overflowing text.
1098
- #
1099
- # Examples:
1100
- #
1101
- # #>pdf-composer100
1102
- # composer.text("This is some longer text that does appear in two lines.")
1103
- # composer.text("This is some longer text that does not appear in two lines.",
1104
- # height: 15, text_overflow: :truncate)
1105
-
1106
1087
  ##
1107
1088
  # :method: background_color
1108
1089
  # :call-seq:
@@ -1414,6 +1395,26 @@ module HexaPDF
1414
1395
  # composer.text('Mask covers everything', mask_mode: :fill)
1415
1396
  # composer.text('On the next page')
1416
1397
 
1398
+ ##
1399
+ # :method: overflow
1400
+ # :call-seq:
1401
+ # overflow(mode = nil)
1402
+ #
1403
+ # Specifies how overflowing boxes (e.g. the text of a box or the children of a container) with
1404
+ # a given initial height should be handled:
1405
+ #
1406
+ # Possible values:
1407
+ #
1408
+ # :error:: An error is raised (default).
1409
+ # :truncate:: Truncates the overflowing parts.
1410
+ #
1411
+ # Examples:
1412
+ #
1413
+ # #>pdf-composer100
1414
+ # composer.text("This is some longer text that does appear in two lines.")
1415
+ # composer.text("This is some longer text that does not appear in two lines.",
1416
+ # height: 15, text_overflow: :truncate)
1417
+
1417
1418
  [
1418
1419
  [:font, "raise HexaPDF::Error, 'No font set'"],
1419
1420
  [:font_size, 10],
@@ -1454,7 +1455,6 @@ module HexaPDF
1454
1455
  extra_args: ", extra_arg = nil"}],
1455
1456
  [:last_line_gap, false, {valid_values: [true, false]}],
1456
1457
  [:fill_horizontal, nil],
1457
- [:text_overflow, :error],
1458
1458
  [:background_color, nil],
1459
1459
  [:background_alpha, 1],
1460
1460
  [:padding, "Quad.new(0)", {setter: "Quad.new(value)"}],
@@ -1467,6 +1467,7 @@ module HexaPDF
1467
1467
  [:valign, :top, {valid_values: [:top, :center, :bottom]}],
1468
1468
  [:mask_mode, :default, {valid_values: [:default, :none, :box, :fill_horizontal,
1469
1469
  :fill_frame_horizontal, :fill_vertical, :fill]}],
1470
+ [:overflow, :error],
1470
1471
  ].each do |name, default, options = {}|
1471
1472
  default = default.inspect unless default.kind_of?(String)
1472
1473
  setter = options.delete(:setter) || "value"
@@ -106,7 +106,7 @@ module HexaPDF
106
106
  end
107
107
 
108
108
  @result.status == :success ||
109
- (@result.status == :height && @initial_height > 0 && style.text_overflow == :truncate)
109
+ (@result.status == :height && @initial_height > 0 && style.overflow == :truncate)
110
110
  end
111
111
 
112
112
  # Splits the text box into two boxes if necessary and possible.
@@ -136,9 +136,9 @@ module HexaPDF
136
136
  def draw_content(canvas, x, y)
137
137
  return unless @result
138
138
 
139
- if @result.status == :height && @initial_height > 0 && style.text_overflow == :error
139
+ if @result.status == :height && @initial_height > 0 && style.overflow == :error
140
140
  raise HexaPDF::Error, "Text doesn't fit into box with limited height and " \
141
- "style property text_overflow is set to :error"
141
+ "style property overflow is set to :error"
142
142
  end
143
143
 
144
144
  return if @result.lines.empty?
@@ -37,6 +37,6 @@
37
37
  module HexaPDF
38
38
 
39
39
  # The version of HexaPDF.
40
- VERSION = '0.39.1'
40
+ VERSION = '0.40.0'
41
41
 
42
42
  end
@@ -73,6 +73,12 @@ describe HexaPDF::Layout::ListBox do
73
73
  check_box(box, 100, 40)
74
74
  end
75
75
 
76
+ it "respects the set initial height and the property overflow=:truncate" do
77
+ box = create_box(children: @text_boxes[0, 2], height: 20,
78
+ style: {overflow: :truncate, position: position})
79
+ check_box(box, 100, 20)
80
+ end
81
+
76
82
  it "respects the border and padding around all list items, position #{position}" do
77
83
  box = create_box(children: @text_boxes[0, 2],
78
84
  style: {border: {width: [5, 4, 3, 2]}, padding: [5, 4, 3, 2], position: position})
@@ -108,7 +114,14 @@ describe HexaPDF::Layout::ListBox do
108
114
  check_box(box, 100, 70, [[10, 80], [10, 30]])
109
115
  end
110
116
 
111
- it "fails for unknown item types" do
117
+ it "creates a new box for each marker even if the marker is the same" do
118
+ box = create_box(children: @text_boxes[0, 2])
119
+ check_box(box, 100, 40)
120
+ results = box.instance_variable_get(:@results)
121
+ refute_same(results[0].marker, results[1].marker)
122
+ end
123
+
124
+ it "fails for unknown marker types" do
112
125
  box = create_box(children: @text_boxes[0, 1], marker_type: :unknown)
113
126
  assert_raises(HexaPDF::Error) { box.fit(100, 100, @frame) }
114
127
  end
@@ -136,6 +149,17 @@ describe HexaPDF::Layout::ListBox do
136
149
  assert_equal(2, box_b.children.size)
137
150
  assert_equal(1, box_b.start_number)
138
151
  end
152
+
153
+ it "splits a list item containg multiple boxes along box lines" do
154
+ box = create_box(children: [@text_boxes[0], @text_boxes[1, 2]])
155
+ box.fit(100, 40, @frame)
156
+ box_a, box_b = box.split(100, 40, @frame)
157
+ assert_same(box, box_a)
158
+ assert_equal(:hide_first_marker, box_b.split_box?)
159
+ assert_equal(1, box_a.instance_variable_get(:@results)[1].box_fitter.fit_results.size)
160
+ assert_equal(1, box_b.children.size)
161
+ assert_equal(2, box_b.start_number)
162
+ end
139
163
  end
140
164
 
141
165
  describe "draw" do
@@ -315,5 +339,10 @@ describe HexaPDF::Layout::ListBox do
315
339
  assert_equal(:ZapfDingbats, @canvas.resources.font(:F1)[:BaseFont])
316
340
  end
317
341
 
342
+ it "fails if the initial height is set and property overflow is set to :error" do
343
+ box = create_box(children: @fixed_size_boxes[0, 2], height: 10)
344
+ box.fit(100, 100, @frame)
345
+ assert_raises(HexaPDF::Error) { box.draw(@canvas, 0, 100 - box.height) }
346
+ end
318
347
  end
319
348
  end
@@ -783,7 +783,7 @@ describe HexaPDF::Layout::Style do
783
783
  refute(@style.superscript)
784
784
  refute(@style.last_line_gap)
785
785
  refute(@style.fill_horizontal)
786
- assert_equal(:error, @style.text_overflow)
786
+ assert_equal(:error, @style.overflow)
787
787
  assert_kind_of(HexaPDF::Layout::Style::Layers, @style.underlays)
788
788
  assert_kind_of(HexaPDF::Layout::Style::Layers, @style.overlays)
789
789
  assert_equal(:default, @style.position)
@@ -79,13 +79,13 @@ describe HexaPDF::Layout::TextBox do
79
79
  end
80
80
  end
81
81
 
82
- it "respects the style property text_overflow when fitting too much text" do
82
+ it "respects the style property overflow when fitting too much text" do
83
83
  box = create_box([@inline_box] * 20, height: 15)
84
84
  refute(box.fit(100, 100, @frame))
85
- box.style.text_overflow = :truncate
85
+ box.style.overflow = :truncate
86
86
  assert(box.fit(100, 100, @frame))
87
87
 
88
- box = create_box([@inline_box] * 20, style: {text_overflow: :truncate})
88
+ box = create_box([@inline_box] * 20, style: {overflow: :truncate})
89
89
  refute(box.fit(100, 15, @frame))
90
90
  end
91
91
 
@@ -196,7 +196,7 @@ describe HexaPDF::Layout::TextBox do
196
196
  assert_operators(@canvas.contents, [])
197
197
  end
198
198
 
199
- it "raises an error if there is too much content for a set height with text_overlow=:error" do
199
+ it "raises an error if there is too much content for a set height with overflow=:error" do
200
200
  box = create_box([@inline_box] * 20, height: 15)
201
201
  box.fit(100, 100, @frame)
202
202
  assert_raises(HexaPDF::Error) { box.draw(@canvas, 0, 0) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.1
4
+ version: 0.40.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-19 00:00:00.000000000 Z
11
+ date: 2024-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse