hexapdf 0.34.1 → 0.35.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +76 -0
- data/examples/009-text_layouter_alignment.rb +7 -7
- data/examples/010-text_layouter_inline_boxes.rb +1 -1
- data/examples/011-text_layouter_line_wrapping.rb +2 -4
- data/examples/013-text_layouter_shapes.rb +9 -11
- data/examples/014-text_in_polygon.rb +2 -2
- data/examples/016-frame_automatic_box_placement.rb +6 -7
- data/examples/017-frame_text_flow.rb +2 -2
- data/examples/018-composer.rb +5 -6
- data/examples/020-column_box.rb +2 -2
- data/examples/021-list_box.rb +1 -1
- data/examples/027-composer_optional_content.rb +5 -5
- data/examples/028-frame_mask_mode.rb +23 -0
- data/examples/029-composer_fallback_fonts.rb +22 -0
- data/lib/hexapdf/cli/info.rb +1 -0
- data/lib/hexapdf/cli/inspect.rb +55 -2
- data/lib/hexapdf/composer.rb +4 -3
- data/lib/hexapdf/configuration.rb +61 -1
- data/lib/hexapdf/content/canvas.rb +63 -0
- data/lib/hexapdf/content/canvas_composer.rb +142 -0
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -8
- data/lib/hexapdf/content.rb +1 -0
- data/lib/hexapdf/dictionary.rb +14 -3
- data/lib/hexapdf/document/layout.rb +35 -13
- data/lib/hexapdf/document.rb +1 -0
- data/lib/hexapdf/encryption/standard_security_handler.rb +15 -0
- data/lib/hexapdf/error.rb +2 -1
- data/lib/hexapdf/font/invalid_glyph.rb +22 -6
- data/lib/hexapdf/font/true_type_wrapper.rb +48 -20
- data/lib/hexapdf/font/type1_wrapper.rb +48 -24
- data/lib/hexapdf/layout/box.rb +14 -10
- data/lib/hexapdf/layout/column_box.rb +5 -3
- data/lib/hexapdf/layout/frame.rb +78 -40
- data/lib/hexapdf/layout/image_box.rb +3 -3
- data/lib/hexapdf/layout/list_box.rb +20 -19
- data/lib/hexapdf/layout/style.rb +173 -68
- data/lib/hexapdf/layout/table_box.rb +3 -3
- data/lib/hexapdf/layout/text_box.rb +5 -5
- data/lib/hexapdf/layout/text_fragment.rb +50 -0
- data/lib/hexapdf/layout/text_layouter.rb +7 -6
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/object.rb +5 -2
- data/lib/hexapdf/pdf_array.rb +5 -0
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +16 -11
- data/lib/hexapdf/type/icon_fit.rb +2 -2
- data/lib/hexapdf/type/page.rb +35 -35
- data/lib/hexapdf/utils/sorted_tree_node.rb +0 -10
- data/lib/hexapdf/utils.rb +66 -0
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/content/test_canvas.rb +37 -0
- data/test/hexapdf/content/test_canvas_composer.rb +112 -0
- data/test/hexapdf/document/test_layout.rb +40 -12
- data/test/hexapdf/document/test_pages.rb +5 -5
- data/test/hexapdf/encryption/test_standard_security_handler.rb +43 -0
- data/test/hexapdf/font/test_invalid_glyph.rb +13 -1
- data/test/hexapdf/font/test_true_type_wrapper.rb +15 -2
- data/test/hexapdf/font/test_type1_wrapper.rb +21 -2
- data/test/hexapdf/layout/test_box.rb +7 -0
- data/test/hexapdf/layout/test_column_box.rb +18 -4
- data/test/hexapdf/layout/test_frame.rb +181 -95
- data/test/hexapdf/layout/test_list_box.rb +7 -7
- data/test/hexapdf/layout/test_page_style.rb +5 -5
- data/test/hexapdf/layout/test_style.rb +14 -10
- data/test/hexapdf/layout/test_table_box.rb +3 -3
- data/test/hexapdf/layout/test_text_box.rb +2 -2
- data/test/hexapdf/layout/test_text_fragment.rb +37 -0
- data/test/hexapdf/layout/test_text_layouter.rb +10 -10
- data/test/hexapdf/test_composer.rb +13 -13
- data/test/hexapdf/test_configuration.rb +49 -0
- data/test/hexapdf/test_dictionary.rb +1 -1
- data/test/hexapdf/test_object.rb +13 -12
- data/test/hexapdf/test_pdf_array.rb +9 -0
- data/test/hexapdf/test_utils.rb +20 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +41 -13
- data/test/hexapdf/type/test_page.rb +3 -3
- data/test/hexapdf/type/test_page_tree_node.rb +1 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +1 -1
- metadata +9 -3
@@ -69,12 +69,26 @@ describe HexaPDF::Layout::ColumnBox do
|
|
69
69
|
it "respects the set initial width, position #{position}" do
|
70
70
|
box = create_box(children: @text_boxes[0..1], width: 50, style: {position: position})
|
71
71
|
check_box(box, 50, 80)
|
72
|
+
|
73
|
+
box = create_box(columns: 1, children: @fixed_size_boxes[0..0], width: 50,
|
74
|
+
style: {position: position})
|
75
|
+
check_box(box, 50, 10)
|
76
|
+
|
77
|
+
box = create_box(children: @fixed_size_boxes[0..0], width: 110)
|
78
|
+
refute(box.fit(@frame.available_width, @frame.available_height, @frame))
|
72
79
|
end
|
73
80
|
|
74
81
|
it "respects the set initial height, position #{position}" do
|
75
82
|
box = create_box(children: @text_boxes[0..1], height: 50, equal_height: false,
|
76
83
|
style: {position: position})
|
77
84
|
check_box(box, 100, 50)
|
85
|
+
|
86
|
+
box = create_box(children: @text_boxes[0..1], height: 50, equal_height: true,
|
87
|
+
style: {position: position})
|
88
|
+
check_box(box, 100, 50)
|
89
|
+
|
90
|
+
box = create_box(children: @fixed_size_boxes[0..0], height: 110)
|
91
|
+
refute(box.fit(@frame.available_width, @frame.available_height, @frame))
|
78
92
|
end
|
79
93
|
|
80
94
|
it "respects the border and padding around all columns, position #{position}" do
|
@@ -178,19 +192,19 @@ describe HexaPDF::Layout::ColumnBox do
|
|
178
192
|
end
|
179
193
|
|
180
194
|
it "takes a different final location into account" do
|
181
|
-
box = create_box(children: @fixed_size_boxes[0, 2])
|
195
|
+
box = create_box(children: @fixed_size_boxes[0, 2], style: {padding: [2, 4, 6, 8]})
|
182
196
|
box.fit(100, 100, @frame)
|
183
197
|
box.draw(@canvas, 20, 10)
|
184
198
|
operators = [
|
185
199
|
[:save_graphics_state],
|
186
|
-
[:concatenate_matrix, [1, 0, 0, 1, 20, -
|
200
|
+
[:concatenate_matrix, [1, 0, 0, 1, 20, -72]],
|
187
201
|
[:save_graphics_state],
|
188
|
-
[:concatenate_matrix, [1, 0, 0, 1,
|
202
|
+
[:concatenate_matrix, [1, 0, 0, 1, 8, 88]],
|
189
203
|
[:move_to, [0, 0]],
|
190
204
|
[:end_path],
|
191
205
|
[:restore_graphics_state],
|
192
206
|
[:save_graphics_state],
|
193
|
-
[:concatenate_matrix, [1, 0, 0, 1,
|
207
|
+
[:concatenate_matrix, [1, 0, 0, 1, 57, 88]],
|
194
208
|
[:move_to, [0, 0]],
|
195
209
|
[:end_path],
|
196
210
|
[:restore_graphics_state],
|
@@ -114,15 +114,22 @@ describe HexaPDF::Layout::Frame do
|
|
114
114
|
when :left then Geom2D::Rectangle(10, 10, 10, 100)
|
115
115
|
when :right then Geom2D::Rectangle(100, 10, 10, 100)
|
116
116
|
when :top then Geom2D::Rectangle(10, 100, 100, 10)
|
117
|
+
when :bottom then Geom2D::Rectangle(10, 10, 100, 10)
|
117
118
|
end
|
118
119
|
)
|
119
120
|
end
|
120
121
|
end
|
121
122
|
|
123
|
+
it "fails if an unkown position value is provided" do
|
124
|
+
box = HexaPDF::Layout::Box.create(position: :unknown)
|
125
|
+
exception = assert_raises(HexaPDF::Error) { @frame.fit(box) }
|
126
|
+
assert_match(/Invalid value 'unknown'/, exception.message)
|
127
|
+
end
|
128
|
+
|
122
129
|
describe "absolute position" do
|
123
130
|
it "draws the box at the given absolute position" do
|
124
131
|
check_box(
|
125
|
-
{width: 50, height: 50, position:
|
132
|
+
{width: 50, height: 50, position: [10, 10]},
|
126
133
|
[20, 20],
|
127
134
|
[20, 20, 70, 70],
|
128
135
|
[[[10, 10], [110, 10], [110, 110], [10, 110]],
|
@@ -132,22 +139,12 @@ describe HexaPDF::Layout::Frame do
|
|
132
139
|
|
133
140
|
it "determines the available space for #fit by using the space to the right and above" do
|
134
141
|
check_box(
|
135
|
-
{position:
|
142
|
+
{position: [10, 10]},
|
136
143
|
[20, 20],
|
137
144
|
[20, 20, 110, 110],
|
138
145
|
[[[10, 10], [110, 10], [110, 20], [20, 20], [20, 110], [10, 110]]]
|
139
146
|
)
|
140
147
|
end
|
141
|
-
|
142
|
-
it "always removes the whole margin box from the frame" do
|
143
|
-
check_box(
|
144
|
-
{width: 50, height: 50, position: :absolute, position_hint: [10, 10],
|
145
|
-
margin: [10, 20, 30, 40]},
|
146
|
-
[20, 20],
|
147
|
-
[-20, -10, 90, 80],
|
148
|
-
[[[10, 80], [90, 80], [90, 10], [110, 10], [110, 110], [10, 110]]]
|
149
|
-
)
|
150
|
-
end
|
151
148
|
end
|
152
149
|
|
153
150
|
describe "default position" do
|
@@ -159,40 +156,52 @@ describe HexaPDF::Layout::Frame do
|
|
159
156
|
end
|
160
157
|
|
161
158
|
it "draws the box on the right side" do
|
162
|
-
check_box({width: 50, height: 50,
|
159
|
+
check_box({width: 50, height: 50, align: :right},
|
163
160
|
[60, 60],
|
164
161
|
[10, 60, 110, 110],
|
165
162
|
[[[10, 10], [110, 10], [110, 60], [10, 60]]])
|
166
163
|
end
|
167
164
|
|
168
165
|
it "draws the box in the center" do
|
169
|
-
check_box({width: 50, height: 50,
|
166
|
+
check_box({width: 50, height: 50, align: :center},
|
170
167
|
[35, 60],
|
171
168
|
[10, 60, 110, 110],
|
172
169
|
[[[10, 10], [110, 10], [110, 60], [10, 60]]])
|
173
170
|
end
|
174
171
|
|
172
|
+
it "draws the box vertically in the center" do
|
173
|
+
check_box({width: 50, height: 50, valign: :center},
|
174
|
+
[10, 35],
|
175
|
+
[10, 35, 110, 110],
|
176
|
+
[[[10, 10], [110, 10], [110, 35], [10, 35]]])
|
177
|
+
end
|
178
|
+
|
179
|
+
it "draws the box vertically at the bottom" do
|
180
|
+
check_box({width: 50, height: 50, valign: :bottom},
|
181
|
+
[10, 10], [10, 10, 110, 110], [])
|
182
|
+
end
|
183
|
+
|
175
184
|
describe "with margin" do
|
176
185
|
[:left, :center, :right].each do |hint|
|
177
|
-
it "ignores all margins if the box fills the whole frame, with
|
178
|
-
check_box({margin: 10,
|
186
|
+
it "ignores all margins if the box fills the whole frame, with alignment #{hint}" do
|
187
|
+
check_box({margin: 10, align: hint},
|
179
188
|
[10, 10], [10, 10, 110, 110], [])
|
180
189
|
assert_equal(100, @box.width)
|
181
190
|
assert_equal(100, @box.height)
|
182
191
|
end
|
183
192
|
|
184
193
|
it "ignores the left/top/right margin if the available bounds coincide with the " \
|
185
|
-
"frame's, with
|
186
|
-
check_box({height: 50, margin: 10,
|
194
|
+
"frame's, with alignment #{hint}" do
|
195
|
+
check_box({height: 50, margin: 10, align: hint},
|
187
196
|
[10, 60],
|
188
197
|
[10, 50, 110, 110],
|
189
198
|
[[[10, 10], [110, 10], [110, 50], [10, 50]]])
|
190
199
|
end
|
191
200
|
|
192
201
|
it "doesn't ignore top margin if the available bounds' top doesn't coincide with the " \
|
193
|
-
"frame's top, with
|
202
|
+
"frame's top, with alignment #{hint}" do
|
194
203
|
remove_area(:top)
|
195
|
-
check_box({height: 50, margin: 10,
|
204
|
+
check_box({height: 50, margin: 10, align: hint},
|
196
205
|
[10, 40],
|
197
206
|
[10, 30, 110, 100],
|
198
207
|
[[[10, 10], [110, 10], [110, 30], [10, 30]]])
|
@@ -200,9 +209,9 @@ describe HexaPDF::Layout::Frame do
|
|
200
209
|
end
|
201
210
|
|
202
211
|
it "doesn't ignore left margin if the available bounds' left doesn't coincide with the " \
|
203
|
-
"frame's left, with
|
212
|
+
"frame's left, with alignment #{hint}" do
|
204
213
|
remove_area(:left)
|
205
|
-
check_box({height: 50, margin: 10,
|
214
|
+
check_box({height: 50, margin: 10, align: hint},
|
206
215
|
[30, 60],
|
207
216
|
[10, 50, 110, 110],
|
208
217
|
[[[20, 10], [110, 10], [110, 50], [20, 50]]])
|
@@ -210,9 +219,9 @@ describe HexaPDF::Layout::Frame do
|
|
210
219
|
end
|
211
220
|
|
212
221
|
it "doesn't ignore right margin if the available bounds' right doesn't coincide with " \
|
213
|
-
"the frame's right, with
|
222
|
+
"the frame's right, with alignment #{hint}" do
|
214
223
|
remove_area(:right)
|
215
|
-
check_box({height: 50, margin: 10,
|
224
|
+
check_box({height: 50, margin: 10, align: hint},
|
216
225
|
[10, 60],
|
217
226
|
[10, 50, 110, 110],
|
218
227
|
[[[10, 10], [100, 10], [100, 50], [10, 50]]])
|
@@ -220,117 +229,194 @@ describe HexaPDF::Layout::Frame do
|
|
220
229
|
end
|
221
230
|
end
|
222
231
|
|
223
|
-
|
224
|
-
|
232
|
+
[:top, :center, :bottom].each do |hint|
|
233
|
+
it "ignores all margins if the box fills the whole frame, with vertical alignment #{hint}" do
|
234
|
+
check_box({margin: 10, valign: hint},
|
235
|
+
[10, 10], [10, 10, 110, 110], [])
|
236
|
+
assert_equal(100, @box.width)
|
237
|
+
assert_equal(100, @box.height)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "ignores the left/top/bottom margin if the available bounds coincide with the " \
|
241
|
+
"frame's, with vertical alignment #{hint}" do
|
242
|
+
check_box({width: 50, margin: 10, valign: hint},
|
243
|
+
[10, 10], [10, 10, 110, 110], [])
|
244
|
+
assert_equal(100, @box.height)
|
245
|
+
end
|
246
|
+
|
247
|
+
it "doesn't ignore top margin if the available bounds' top doesn't coincide with the " \
|
248
|
+
"frame's top, with vertical alignment #{hint}" do
|
249
|
+
remove_area(:top)
|
250
|
+
check_box({width: 50, margin: 10, valign: hint},
|
251
|
+
[10, 10], [10, 10, 110, 100], [])
|
252
|
+
assert_equal(80, @box.height)
|
253
|
+
end
|
254
|
+
|
255
|
+
it "doesn't ignore left margin if the available bounds' left doesn't coincide with the " \
|
256
|
+
"frame's left, with vertical alignment #{hint}" do
|
257
|
+
remove_area(:left)
|
258
|
+
check_box({width: 50, margin: 10, valign: hint},
|
259
|
+
[30, 10], [10, 10, 110, 110], [])
|
260
|
+
assert_equal(100, @box.height)
|
261
|
+
end
|
262
|
+
|
263
|
+
it "doesn't ignore bottom margin if the available bounds' bottom doesn't coincide with " \
|
264
|
+
"the frame's bottom, with vertical alignment #{hint}" do
|
265
|
+
remove_area(:bottom)
|
266
|
+
check_box({width: 50, margin: 10, valign: hint},
|
267
|
+
[10, 30], [10, 20, 110, 110], [])
|
268
|
+
assert_equal(80, @box.height)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
it "perfectly centers a box horizontally if possible, margins ignored" do
|
273
|
+
check_box({width: 50, height: 10, margin: [10, 10, 10, 20], align: :center},
|
225
274
|
[35, 100],
|
226
275
|
[10, 90, 110, 110],
|
227
276
|
[[[10, 10], [110, 10], [110, 90], [10, 90]]])
|
228
277
|
end
|
229
278
|
|
230
|
-
it "perfectly centers a box if possible, margins not ignored" do
|
279
|
+
it "perfectly centers a box horizontally if possible, margins not ignored" do
|
231
280
|
remove_area(:left, :right)
|
232
|
-
check_box({width: 40, height: 10, margin: [10, 10, 10, 20],
|
281
|
+
check_box({width: 40, height: 10, margin: [10, 10, 10, 20], align: :center},
|
233
282
|
[40, 100],
|
234
283
|
[10, 90, 110, 110],
|
235
284
|
[[[20, 10], [100, 10], [100, 90], [20, 90]]])
|
236
285
|
end
|
237
286
|
|
238
|
-
it "centers a box as good as possible when margins aren't equal" do
|
287
|
+
it "horizontally centers a box as good as possible when margins aren't equal" do
|
239
288
|
remove_area(:left, :right)
|
240
|
-
check_box({width: 20, height: 10, margin: [10, 10, 10, 40],
|
289
|
+
check_box({width: 20, height: 10, margin: [10, 10, 10, 40], align: :center},
|
241
290
|
[65, 100],
|
242
291
|
[10, 90, 110, 110],
|
243
292
|
[[[20, 10], [100, 10], [100, 90], [20, 90]]])
|
244
293
|
end
|
294
|
+
|
295
|
+
it "perfectly centers a box vertically if possible, margins ignored" do
|
296
|
+
check_box({width: 10, height: 50, margin: [10, 10, 20, 10], valign: :center},
|
297
|
+
[10, 35],
|
298
|
+
[10, 15, 110, 110],
|
299
|
+
[[[10, 10], [110, 10], [110, 15], [10, 15]]])
|
300
|
+
end
|
301
|
+
|
302
|
+
it "perfectly centers a box vertically if possible, margins not ignored" do
|
303
|
+
remove_area(:top, :bottom)
|
304
|
+
check_box({width: 10, height: 40, margin: [10, 10, 20, 10], valign: :center},
|
305
|
+
[10, 40], [10, 20, 110, 100], [])
|
306
|
+
end
|
307
|
+
|
308
|
+
it "vertically centers a box as good as possible when margins aren't equal" do
|
309
|
+
remove_area(:top, :bottom)
|
310
|
+
check_box({width: 10, height: 20, margin: [10, 10, 40, 10], valign: :center},
|
311
|
+
[10, 65],
|
312
|
+
[10, 25, 110, 100],
|
313
|
+
[[[10, 20], [110, 20], [110, 25], [10, 25]]])
|
314
|
+
end
|
245
315
|
end
|
246
316
|
end
|
247
317
|
|
248
|
-
describe "
|
249
|
-
it "
|
250
|
-
check_box({width:
|
251
|
-
[
|
252
|
-
[10,
|
253
|
-
[[[10, 10], [110, 10], [110,
|
318
|
+
describe "flowing boxes" do
|
319
|
+
it "flows inside the frame's outline" do
|
320
|
+
check_box({width: 10, height: 20, margin: 10, position: :flow},
|
321
|
+
[0, 90],
|
322
|
+
[10, 80, 110, 110],
|
323
|
+
[[[10, 10], [110, 10], [110, 80], [10, 80]]])
|
254
324
|
end
|
255
325
|
|
256
|
-
it "
|
257
|
-
check_box({width:
|
258
|
-
[
|
259
|
-
[
|
260
|
-
[[[10, 10], [110, 10], [110,
|
326
|
+
it "uses position=default if the box indicates it doesn't support flowing contents" do
|
327
|
+
check_box({width: 10, height: 20, margin: 10, position: :flow, doesnt_support_position_flow: true},
|
328
|
+
[10, 90],
|
329
|
+
[10, 80, 110, 110],
|
330
|
+
[[[10, 10], [110, 10], [110, 80], [10, 80]]])
|
261
331
|
end
|
332
|
+
end
|
262
333
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
[
|
334
|
+
describe "mask mode" do
|
335
|
+
describe "none" do
|
336
|
+
it "doesn't remove any area" do
|
337
|
+
check_box({width: 50, height: 50, mask_mode: :none},
|
338
|
+
[10, 60],
|
339
|
+
[10, 60, 10, 60],
|
340
|
+
[[[10, 10], [110, 10], [110, 110], [10, 110]]]
|
341
|
+
)
|
342
|
+
end
|
269
343
|
end
|
270
344
|
|
271
|
-
describe "
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
assert_equal(100, @box.height)
|
278
|
-
end
|
345
|
+
describe "box" do
|
346
|
+
it "removes the box area" do
|
347
|
+
check_box({width: 50, height: 50, mask_mode: :box},
|
348
|
+
[10, 60],
|
349
|
+
[10, 60, 60, 110],
|
350
|
+
[[[10, 10], [110, 10], [110, 110], [60, 110], [60, 60], [10, 60]]])
|
279
351
|
end
|
280
352
|
|
281
|
-
it "ignores the
|
282
|
-
check_box({
|
283
|
-
[10,
|
284
|
-
[10, 50, 70, 110],
|
285
|
-
[[[10, 10], [110, 10], [110, 110], [70, 110], [70, 50], [10, 50]]])
|
353
|
+
it "ignores the margin if sides are on the frame border" do
|
354
|
+
check_box({margin: 10, mask_mode: :box},
|
355
|
+
[10, 10], [10, 10, 110, 110], [])
|
286
356
|
end
|
287
357
|
|
288
|
-
it "uses the
|
289
|
-
remove_area(:left)
|
290
|
-
check_box({
|
291
|
-
[30,
|
292
|
-
[20, 50, 90, 110],
|
293
|
-
[[[20, 10], [110, 10], [110, 110], [90, 110], [90, 50], [20, 50]]])
|
358
|
+
it "uses the margin if sides are not on the frame border" do
|
359
|
+
remove_area(:left, :right, :top, :bottom)
|
360
|
+
check_box({margin: 10, mask_mode: :box},
|
361
|
+
[30, 30], [20, 20, 100, 100], [])
|
294
362
|
end
|
363
|
+
end
|
295
364
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
[
|
301
|
-
|
365
|
+
describe "fill_horizontal" do
|
366
|
+
it "removes the horizontal part to the bottom of the box in the current region" do
|
367
|
+
remove_area(:left, :right)
|
368
|
+
check_box({width: 50, height: 50, mask_mode: :fill_horizontal},
|
369
|
+
[20, 60],
|
370
|
+
[20, 60, 100, 110],
|
371
|
+
[[[20, 10], [100, 10], [100, 60], [20, 60]]])
|
302
372
|
end
|
303
373
|
|
304
|
-
it "
|
305
|
-
|
306
|
-
|
307
|
-
[
|
308
|
-
|
374
|
+
it "respects the top and bottom margins for the mask" do
|
375
|
+
remove_area(:top, :bottom)
|
376
|
+
check_box({width: 50, margin: 10, mask_mode: :fill_horizontal},
|
377
|
+
[10, 30], [10, 20, 110, 100], [])
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
describe "fill_frame_horizontal" do
|
382
|
+
it "removes the horizontal part to the bottom of the box in the frame" do
|
383
|
+
remove_area(:left, :right)
|
384
|
+
check_box({width: 50, height: 50, mask_mode: :fill_frame_horizontal},
|
385
|
+
[20, 60],
|
386
|
+
[10, 60, 110, 110],
|
387
|
+
[[[20, 10], [100, 10], [100, 60], [20, 60]]])
|
309
388
|
end
|
310
389
|
|
311
|
-
it "
|
312
|
-
remove_area(:right)
|
313
|
-
check_box({width: 50,
|
314
|
-
[
|
315
|
-
[30, 50, 100, 110],
|
316
|
-
[[[10, 10], [100, 10], [100, 50], [30, 50], [30, 110], [10, 110]]])
|
390
|
+
it "respects the bottom margin for the mask" do
|
391
|
+
remove_area(:left, :right, :top, :bottom)
|
392
|
+
check_box({width: 50, margin: 10, mask_mode: :fill_frame_horizontal},
|
393
|
+
[30, 30], [10, 20, 110, 100], [])
|
317
394
|
end
|
318
395
|
end
|
319
|
-
end
|
320
396
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
397
|
+
describe "fill_vertical" do
|
398
|
+
it "removes the vertical part covering the box in the current region" do
|
399
|
+
check_box({width: 50, height: 50, mask_mode: :fill_vertical, align: :center},
|
400
|
+
[35, 60],
|
401
|
+
[35, 10, 85, 110],
|
402
|
+
[[[10, 10], [35, 10], [35, 110], [10, 110]],
|
403
|
+
[[85, 10], [110, 10], [110, 110], [85, 110]]])
|
404
|
+
end
|
405
|
+
|
406
|
+
it "respects the left and right margins for the mask" do
|
407
|
+
check_box({width: 50, height: 50, margin: 10, mask_mode: :fill_vertical, align: :center},
|
408
|
+
[35, 60],
|
409
|
+
[25, 10, 95, 110],
|
410
|
+
[[[10, 10], [25, 10], [25, 110], [10, 110]],
|
411
|
+
[[95, 10], [110, 10], [110, 110], [95, 110]]])
|
412
|
+
end
|
327
413
|
end
|
328
414
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
415
|
+
describe "fill" do
|
416
|
+
it "removes the current region completely" do
|
417
|
+
check_box({width: 50, height: 50, mask_mode: :fill},
|
418
|
+
[10, 60], [10, 10, 110, 110], [])
|
419
|
+
end
|
334
420
|
end
|
335
421
|
end
|
336
422
|
|
@@ -38,10 +38,10 @@ describe HexaPDF::Layout::ListBox do
|
|
38
38
|
|
39
39
|
describe "initialize" do
|
40
40
|
it "creates a new instance with the given arguments" do
|
41
|
-
box = create_box(children: [:a],
|
41
|
+
box = create_box(children: [:a], marker_type: :circle, content_indentation: 15,
|
42
42
|
start_number: 4, item_spacing: 20)
|
43
43
|
assert_equal([:a], box.children)
|
44
|
-
assert_equal(:circle, box.
|
44
|
+
assert_equal(:circle, box.marker_type)
|
45
45
|
assert_equal(15, box.content_indentation)
|
46
46
|
assert_equal(4, box.start_number)
|
47
47
|
assert_equal(20, box.item_spacing)
|
@@ -109,7 +109,7 @@ describe HexaPDF::Layout::ListBox do
|
|
109
109
|
end
|
110
110
|
|
111
111
|
it "fails for unknown item types" do
|
112
|
-
box = create_box(children: @text_boxes[0, 1],
|
112
|
+
box = create_box(children: @text_boxes[0, 1], marker_type: :unknown)
|
113
113
|
assert_raises(HexaPDF::Error) { box.fit(100, 100, @frame) }
|
114
114
|
end
|
115
115
|
end
|
@@ -179,7 +179,7 @@ describe HexaPDF::Layout::ListBox do
|
|
179
179
|
end
|
180
180
|
|
181
181
|
it "draws a circle as marker" do
|
182
|
-
box = create_box(children: @fixed_size_boxes[0, 1],
|
182
|
+
box = create_box(children: @fixed_size_boxes[0, 1], marker_type: :circle,
|
183
183
|
style: {font_size: 11, fill_color: 0.5})
|
184
184
|
box.fit(100, 100, @frame)
|
185
185
|
box.draw(@canvas, 0, 100 - box.height)
|
@@ -201,7 +201,7 @@ describe HexaPDF::Layout::ListBox do
|
|
201
201
|
end
|
202
202
|
|
203
203
|
it "draws a square as marker" do
|
204
|
-
box = create_box(children: @fixed_size_boxes[0, 1],
|
204
|
+
box = create_box(children: @fixed_size_boxes[0, 1], marker_type: :square,
|
205
205
|
style: {font_size: 11, fill_color: 0.5})
|
206
206
|
box.fit(100, 100, @frame)
|
207
207
|
box.draw(@canvas, 0, 100 - box.height)
|
@@ -223,7 +223,7 @@ describe HexaPDF::Layout::ListBox do
|
|
223
223
|
end
|
224
224
|
|
225
225
|
it "draws decimal numbers as marker" do
|
226
|
-
box = create_box(children: @fixed_size_boxes[0, 2],
|
226
|
+
box = create_box(children: @fixed_size_boxes[0, 2], marker_type: :decimal,
|
227
227
|
style: {font_size: 11, fill_color: 0.5},
|
228
228
|
content_indentation: 20)
|
229
229
|
box.fit(100, 100, @frame)
|
@@ -260,7 +260,7 @@ describe HexaPDF::Layout::ListBox do
|
|
260
260
|
marker = lambda do |_doc, _list_box, _index|
|
261
261
|
HexaPDF::Layout::Box.create(width: 10, height: 10) {}
|
262
262
|
end
|
263
|
-
box = create_box(children: @fixed_size_boxes[0, 1],
|
263
|
+
box = create_box(children: @fixed_size_boxes[0, 1], marker_type: marker)
|
264
264
|
box.fit(100, 100, @frame)
|
265
265
|
box.draw(@canvas, 0, 100 - box.height)
|
266
266
|
operators = [
|
@@ -35,7 +35,7 @@ describe HexaPDF::Layout::PageStyle do
|
|
35
35
|
istyle.next_style = :other
|
36
36
|
end
|
37
37
|
page = style.create_page(@doc)
|
38
|
-
assert_equal([0, 0, 595,
|
38
|
+
assert_equal([0, 0, 595.275591, 841.889764], page.box(:media))
|
39
39
|
assert_equal("0 0 10 10 re\nS\n", page.contents)
|
40
40
|
assert_equal(:frame, style.frame)
|
41
41
|
assert_equal(:other, style.next_style)
|
@@ -54,8 +54,8 @@ describe HexaPDF::Layout::PageStyle do
|
|
54
54
|
assert_kind_of(HexaPDF::Layout::Frame, style.frame)
|
55
55
|
assert_equal(36, style.frame.left)
|
56
56
|
assert_equal(36, style.frame.bottom)
|
57
|
-
assert_equal(523, style.frame.width)
|
58
|
-
assert_equal(
|
57
|
+
assert_equal(523.275591, style.frame.width)
|
58
|
+
assert_equal(769.889764, style.frame.height)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -65,7 +65,7 @@ describe HexaPDF::Layout::PageStyle do
|
|
65
65
|
frame = style.create_frame(style.create_page(doc), [15, 10])
|
66
66
|
assert_equal(10, frame.left)
|
67
67
|
assert_equal(15, frame.bottom)
|
68
|
-
assert_equal(575, frame.width)
|
69
|
-
assert_equal(
|
68
|
+
assert_equal(575.275591, frame.width)
|
69
|
+
assert_equal(811.889764, frame.height)
|
70
70
|
end
|
71
71
|
end
|
@@ -767,8 +767,8 @@ describe HexaPDF::Layout::Style do
|
|
767
767
|
assert_equal(HexaPDF::Content::LineCapStyle::BUTT_CAP, @style.stroke_cap_style)
|
768
768
|
assert_equal(HexaPDF::Content::LineJoinStyle::MITER_JOIN, @style.stroke_join_style)
|
769
769
|
assert_equal(10.0, @style.stroke_miter_limit)
|
770
|
-
assert_equal(:left, @style.
|
771
|
-
assert_equal(:top, @style.
|
770
|
+
assert_equal(:left, @style.text_align)
|
771
|
+
assert_equal(:top, @style.text_valign)
|
772
772
|
assert_equal(0, @style.text_indent)
|
773
773
|
assert_nil(@style.background_color)
|
774
774
|
assert_equal(1, @style.background_alpha)
|
@@ -785,6 +785,10 @@ describe HexaPDF::Layout::Style do
|
|
785
785
|
refute(@style.fill_horizontal)
|
786
786
|
assert_kind_of(HexaPDF::Layout::Style::Layers, @style.underlays)
|
787
787
|
assert_kind_of(HexaPDF::Layout::Style::Layers, @style.overlays)
|
788
|
+
assert_equal(:default, @style.position)
|
789
|
+
assert_equal(:left, @style.align)
|
790
|
+
assert_equal(:top, @style.valign)
|
791
|
+
assert_equal(:default, @style.mask_mode)
|
788
792
|
end
|
789
793
|
|
790
794
|
it "allows using a non-standard setter for generated properties" do
|
@@ -800,18 +804,18 @@ describe HexaPDF::Layout::Style do
|
|
800
804
|
end
|
801
805
|
|
802
806
|
it "allows checking for valid values" do
|
803
|
-
error = assert_raises(ArgumentError) { @style.
|
804
|
-
assert_match(/not a valid
|
807
|
+
error = assert_raises(ArgumentError) { @style.text_align = :none }
|
808
|
+
assert_match(/not a valid text_align value \(:left, :center, :right, :justify\)/, error.message)
|
805
809
|
end
|
806
810
|
|
807
811
|
it "allows checking whether a property has been set or accessed" do
|
808
|
-
refute(@style.
|
809
|
-
assert_equal(:left, @style.
|
810
|
-
assert(@style.
|
812
|
+
refute(@style.text_align?)
|
813
|
+
assert_equal(:left, @style.text_align)
|
814
|
+
assert(@style.text_align?)
|
811
815
|
|
812
|
-
refute(@style.
|
813
|
-
@style.
|
814
|
-
assert(@style.
|
816
|
+
refute(@style.text_valign?)
|
817
|
+
@style.text_valign = :bottom
|
818
|
+
assert(@style.text_valign?)
|
815
819
|
end
|
816
820
|
|
817
821
|
it "has several dynamically generated properties with default values that take blocks" do
|
@@ -83,7 +83,7 @@ describe HexaPDF::Layout::TableBox::Cell do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
it "fits a single box with horizontal aligning not being :left" do
|
86
|
-
cell = create_cell(children: HexaPDF::Layout::Box.create(width: 20, height: 10,
|
86
|
+
cell = create_cell(children: HexaPDF::Layout::Box.create(width: 20, height: 10, align: :center))
|
87
87
|
cell.fit(100, 100, @frame)
|
88
88
|
assert_equal(66, cell.preferred_width)
|
89
89
|
end
|
@@ -100,7 +100,7 @@ describe HexaPDF::Layout::TableBox::Cell do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
it "fits multiple boxes with horizontal aligning not being :left" do
|
103
|
-
box1 = HexaPDF::Layout::Box.create(width: 20, height: 10,
|
103
|
+
box1 = HexaPDF::Layout::Box.create(width: 20, height: 10, align: :center)
|
104
104
|
box2 = HexaPDF::Layout::Box.create(width: 50, height: 15)
|
105
105
|
cell = create_cell(children: [box1, box2])
|
106
106
|
cell.fit(100, 100, @frame)
|
@@ -130,7 +130,7 @@ describe HexaPDF::Layout::TableBox::Cell do
|
|
130
130
|
|
131
131
|
it "draws the boxes at the correct location" do
|
132
132
|
draw_block = lambda {|canvas, _| canvas.move_to(0, 0).end_path }
|
133
|
-
box1 = HexaPDF::Layout::Box.create(width: 20, height: 10,
|
133
|
+
box1 = HexaPDF::Layout::Box.create(width: 20, height: 10, align: :center, &draw_block)
|
134
134
|
box2 = HexaPDF::Layout::Box.create(width: 50, height: 15, &draw_block)
|
135
135
|
box = create_cell(children: [box1, box2])
|
136
136
|
box.fit(100, 100, @frame)
|
@@ -66,7 +66,7 @@ describe HexaPDF::Layout::TextBox do
|
|
66
66
|
|
67
67
|
it "uses the whole available width when aligning to the center or right" do
|
68
68
|
[:center, :right].each do |align|
|
69
|
-
box = create_box([@inline_box], style: {
|
69
|
+
box = create_box([@inline_box], style: {text_align: align})
|
70
70
|
assert(box.fit(100, 100, @frame))
|
71
71
|
assert_equal(100, box.width)
|
72
72
|
end
|
@@ -74,7 +74,7 @@ describe HexaPDF::Layout::TextBox do
|
|
74
74
|
|
75
75
|
it "uses the whole available height when vertically aligning to the center or bottom" do
|
76
76
|
[:center, :bottom].each do |valign|
|
77
|
-
box = create_box([@inline_box], style: {
|
77
|
+
box = create_box([@inline_box], style: {text_valign: valign})
|
78
78
|
assert(box.fit(100, 100, @frame))
|
79
79
|
assert_equal(100, box.height)
|
80
80
|
end
|