hexapdf 0.32.2 → 0.34.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +104 -1
- data/README.md +9 -0
- data/examples/002-graphics.rb +15 -17
- data/examples/003-arcs.rb +9 -9
- data/examples/009-text_layouter_alignment.rb +1 -1
- data/examples/010-text_layouter_inline_boxes.rb +2 -2
- data/examples/011-text_layouter_line_wrapping.rb +1 -1
- data/examples/012-text_layouter_styling.rb +7 -7
- data/examples/013-text_layouter_shapes.rb +1 -1
- data/examples/014-text_in_polygon.rb +1 -1
- data/examples/015-boxes.rb +8 -7
- data/examples/016-frame_automatic_box_placement.rb +2 -2
- data/examples/017-frame_text_flow.rb +2 -1
- data/examples/018-composer.rb +1 -1
- data/examples/020-column_box.rb +2 -1
- data/examples/025-table_box.rb +46 -0
- data/examples/026-optional_content.rb +55 -0
- data/examples/027-composer_optional_content.rb +83 -0
- data/lib/hexapdf/cli/command.rb +12 -3
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +5 -5
- data/lib/hexapdf/cli/inspect.rb +5 -7
- data/lib/hexapdf/composer.rb +106 -53
- data/lib/hexapdf/configuration.rb +65 -40
- data/lib/hexapdf/content/canvas.rb +445 -267
- data/lib/hexapdf/content/color_space.rb +72 -25
- data/lib/hexapdf/content/graphic_object/arc.rb +57 -24
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -23
- data/lib/hexapdf/content/graphic_object/geom2d.rb +47 -6
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +58 -36
- data/lib/hexapdf/content/graphic_object.rb +6 -7
- data/lib/hexapdf/content/graphics_state.rb +54 -45
- data/lib/hexapdf/content/operator.rb +54 -54
- data/lib/hexapdf/content/parser.rb +2 -2
- data/lib/hexapdf/content/processor.rb +15 -15
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +5 -0
- data/lib/hexapdf/dictionary.rb +7 -5
- data/lib/hexapdf/dictionary_fields.rb +43 -16
- data/lib/hexapdf/digital_signature/cms_handler.rb +2 -2
- data/lib/hexapdf/digital_signature/handler.rb +1 -1
- data/lib/hexapdf/digital_signature/pkcs1_handler.rb +2 -3
- data/lib/hexapdf/digital_signature/signature.rb +6 -6
- data/lib/hexapdf/digital_signature/signatures.rb +13 -12
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +14 -5
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +2 -4
- data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +4 -4
- data/lib/hexapdf/digital_signature/signing.rb +4 -0
- data/lib/hexapdf/digital_signature/verification_result.rb +3 -4
- data/lib/hexapdf/digital_signature.rb +7 -2
- data/lib/hexapdf/document/destinations.rb +12 -11
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/layout.rb +170 -39
- data/lib/hexapdf/document/pages.rb +4 -3
- data/lib/hexapdf/document.rb +96 -55
- data/lib/hexapdf/encryption/aes.rb +5 -5
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +2 -2
- data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +11 -21
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +31 -24
- data/lib/hexapdf/encryption/standard_security_handler.rb +45 -36
- data/lib/hexapdf/encryption.rb +7 -2
- data/lib/hexapdf/error.rb +18 -0
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/pass_through.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/filter.rb +55 -6
- data/lib/hexapdf/font/cmap/parser.rb +2 -2
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +3 -3
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +3 -0
- data/lib/hexapdf/font/true_type_wrapper.rb +17 -4
- data/lib/hexapdf/font/type1_wrapper.rb +19 -4
- data/lib/hexapdf/font_loader/from_configuration.rb +5 -2
- data/lib/hexapdf/font_loader/from_file.rb +5 -5
- data/lib/hexapdf/font_loader/standard14.rb +3 -3
- data/lib/hexapdf/font_loader.rb +3 -0
- data/lib/hexapdf/image_loader/jpeg.rb +2 -2
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +2 -2
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +13 -0
- data/lib/hexapdf/layout/box.rb +32 -5
- data/lib/hexapdf/layout/box_fitter.rb +2 -2
- data/lib/hexapdf/layout/column_box.rb +20 -5
- data/lib/hexapdf/layout/frame.rb +53 -18
- data/lib/hexapdf/layout/image_box.rb +5 -0
- data/lib/hexapdf/layout/inline_box.rb +21 -9
- data/lib/hexapdf/layout/list_box.rb +50 -20
- data/lib/hexapdf/layout/page_style.rb +6 -5
- data/lib/hexapdf/layout/style.rb +64 -9
- data/lib/hexapdf/layout/table_box.rb +684 -0
- data/lib/hexapdf/layout/text_box.rb +12 -3
- data/lib/hexapdf/layout/text_fragment.rb +29 -3
- data/lib/hexapdf/layout/text_layouter.rb +32 -8
- data/lib/hexapdf/layout.rb +1 -0
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +18 -7
- data/lib/hexapdf/parser.rb +7 -7
- data/lib/hexapdf/pdf_array.rb +1 -1
- data/lib/hexapdf/rectangle.rb +1 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +1 -1
- data/lib/hexapdf/revisions.rb +3 -3
- data/lib/hexapdf/serializer.rb +15 -15
- data/lib/hexapdf/stream.rb +5 -4
- data/lib/hexapdf/tokenizer.rb +14 -14
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +22 -22
- data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/field.rb +2 -2
- data/lib/hexapdf/type/acro_form/form.rb +1 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +4 -4
- data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +1 -1
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/set_ocg_state.rb +86 -0
- data/lib/hexapdf/type/actions/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +2 -1
- data/lib/hexapdf/type/annotation.rb +3 -3
- data/lib/hexapdf/type/annotations/link.rb +1 -1
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +2 -3
- data/lib/hexapdf/type/annotations/widget.rb +2 -2
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +11 -2
- data/lib/hexapdf/type/cid_font.rb +18 -4
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +2 -2
- data/lib/hexapdf/type/font_type0.rb +3 -3
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +76 -6
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +1 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/mark_information.rb +1 -1
- data/lib/hexapdf/type/names.rb +2 -2
- data/lib/hexapdf/type/object_stream.rb +2 -1
- data/lib/hexapdf/type/optional_content_configuration.rb +170 -0
- data/lib/hexapdf/type/optional_content_group.rb +370 -0
- data/lib/hexapdf/type/optional_content_membership.rb +63 -0
- data/lib/hexapdf/type/optional_content_properties.rb +158 -0
- data/lib/hexapdf/type/outline.rb +1 -1
- data/lib/hexapdf/type/outline_item.rb +1 -1
- data/lib/hexapdf/type/page.rb +46 -21
- data/lib/hexapdf/type/page_label.rb +5 -9
- data/lib/hexapdf/type/page_tree_node.rb +1 -1
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +2 -2
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +2 -2
- data/lib/hexapdf/type.rb +4 -0
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -2
- data/lib/hexapdf/version.rb +1 -1
- data/lib/hexapdf/writer.rb +4 -4
- data/lib/hexapdf/xref_section.rb +2 -2
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +11 -1
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +7 -0
- data/test/hexapdf/content/test_canvas.rb +49 -1
- data/test/hexapdf/digital_signature/test_signatures.rb +22 -0
- data/test/hexapdf/document/test_files.rb +2 -2
- data/test/hexapdf/document/test_layout.rb +105 -2
- data/test/hexapdf/document/test_pages.rb +6 -6
- data/test/hexapdf/encryption/test_security_handler.rb +12 -11
- data/test/hexapdf/encryption/test_standard_security_handler.rb +35 -23
- data/test/hexapdf/font/test_true_type_wrapper.rb +18 -1
- data/test/hexapdf/font/test_type1_wrapper.rb +15 -1
- data/test/hexapdf/layout/test_box.rb +14 -5
- data/test/hexapdf/layout/test_column_box.rb +65 -21
- data/test/hexapdf/layout/test_frame.rb +27 -15
- data/test/hexapdf/layout/test_image_box.rb +4 -0
- data/test/hexapdf/layout/test_inline_box.rb +17 -3
- data/test/hexapdf/layout/test_list_box.rb +84 -33
- data/test/hexapdf/layout/test_page_style.rb +3 -2
- data/test/hexapdf/layout/test_style.rb +60 -0
- data/test/hexapdf/layout/test_table_box.rb +728 -0
- data/test/hexapdf/layout/test_text_box.rb +26 -0
- data/test/hexapdf/layout/test_text_fragment.rb +33 -0
- data/test/hexapdf/layout/test_text_layouter.rb +36 -5
- data/test/hexapdf/test_composer.rb +10 -0
- data/test/hexapdf/test_dictionary.rb +10 -0
- data/test/hexapdf/test_dictionary_fields.rb +4 -1
- data/test/hexapdf/test_document.rb +5 -0
- data/test/hexapdf/test_filter.rb +8 -0
- data/test/hexapdf/test_importer.rb +9 -0
- data/test/hexapdf/test_object.rb +16 -5
- data/test/hexapdf/test_stream.rb +7 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +13 -5
- data/test/hexapdf/type/acro_form/test_form.rb +4 -3
- data/test/hexapdf/type/actions/test_set_ocg_state.rb +40 -0
- data/test/hexapdf/type/test_catalog.rb +11 -0
- data/test/hexapdf/type/test_form.rb +119 -0
- data/test/hexapdf/type/test_optional_content_configuration.rb +112 -0
- data/test/hexapdf/type/test_optional_content_group.rb +158 -0
- data/test/hexapdf/type/test_optional_content_properties.rb +109 -0
- data/test/hexapdf/type/test_page.rb +20 -6
- metadata +28 -8
@@ -25,6 +25,14 @@ describe HexaPDF::Layout::TextBox do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
it "returns the text contents as string" do
|
29
|
+
doc = HexaPDF::Document.new
|
30
|
+
font = doc.fonts.add("Times")
|
31
|
+
box = create_box([HexaPDF::Layout::TextFragment.create('Test ', font: font), @inline_box,
|
32
|
+
HexaPDF::Layout::TextFragment.create('here', font: font)])
|
33
|
+
assert_equal('Test here', box.text)
|
34
|
+
end
|
35
|
+
|
28
36
|
describe "fit" do
|
29
37
|
it "fits into a rectangular area" do
|
30
38
|
box = create_box([@inline_box] * 5, style: {padding: 10})
|
@@ -107,6 +115,14 @@ describe HexaPDF::Layout::TextBox do
|
|
107
115
|
assert_equal([nil, box], box.split(100, 100, @frame))
|
108
116
|
end
|
109
117
|
|
118
|
+
it "works if the box fits exactly (+/- float divergence)" do
|
119
|
+
box = create_box([@inline_box] * 5)
|
120
|
+
box.fit(50, 10, @frame)
|
121
|
+
box.instance_variable_set(:@width, 50.00000000006)
|
122
|
+
box.instance_variable_set(:@height, 10.00000000003)
|
123
|
+
assert_equal([box], box.split(50, 10, @frame))
|
124
|
+
end
|
125
|
+
|
110
126
|
it "splits the box if necessary when using non-flowing text" do
|
111
127
|
box = create_box([@inline_box] * 10)
|
112
128
|
boxes = box.split(50, 10, @frame)
|
@@ -125,6 +141,16 @@ describe HexaPDF::Layout::TextBox do
|
|
125
141
|
assert_equal(box, boxes[0])
|
126
142
|
assert_equal(5, boxes[1].instance_variable_get(:@items).length)
|
127
143
|
end
|
144
|
+
|
145
|
+
it "correctly handles text indentation for split boxes" do
|
146
|
+
[{}, {position: :flow}].each do |styles|
|
147
|
+
box = create_box([@inline_box] * 202, style: {text_indent: 50, **styles})
|
148
|
+
boxes = box.split(100, 100, @frame)
|
149
|
+
assert_equal(107, boxes[1].instance_variable_get(:@items).length)
|
150
|
+
boxes = boxes[1].split(100, 100, @frame)
|
151
|
+
assert_equal(7, boxes[1].instance_variable_get(:@items).length)
|
152
|
+
end
|
153
|
+
end
|
128
154
|
end
|
129
155
|
|
130
156
|
describe "draw" do
|
@@ -51,6 +51,10 @@ describe HexaPDF::Layout::TextFragment do
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
it "returns the text value of the items as string" do
|
55
|
+
assert_equal("Hal lo\u{00a0}d\n", setup_fragment(@font.decode_utf8("Hal lo\u{00a0}d\n")).text)
|
56
|
+
end
|
57
|
+
|
54
58
|
it "allows duplicating with only its attributes while also setting new items" do
|
55
59
|
setup_fragment([20])
|
56
60
|
@fragment.properties['key'] = :value
|
@@ -392,6 +396,35 @@ describe HexaPDF::Layout::TextFragment do
|
|
392
396
|
end
|
393
397
|
end
|
394
398
|
|
399
|
+
describe "fill_horizontal!" do
|
400
|
+
before do
|
401
|
+
@fragment = HexaPDF::Layout::TextFragment.create('ab', fill_horizontal: 1, font: @font)
|
402
|
+
end
|
403
|
+
|
404
|
+
it "returns the fragment if the given width is too small" do
|
405
|
+
assert_same(@fragment, @fragment.fill_horizontal!(0.1))
|
406
|
+
end
|
407
|
+
|
408
|
+
it "repeats all items of the fragment" do
|
409
|
+
fragment = @fragment.fill_horizontal!(@fragment.width * 2)
|
410
|
+
assert_equal([*(@fragment.items * 2), 0], fragment.items)
|
411
|
+
assert_in_delta(@fragment.width * 2, fragment.width)
|
412
|
+
end
|
413
|
+
|
414
|
+
it "adds, after repeating, items from the start of the fragment to fill the available space" do
|
415
|
+
fragment = @fragment.fill_horizontal!(90)
|
416
|
+
assert_equal([*(@fragment.items * 9), @fragment.items[0], 3.3333333333332673], fragment.items)
|
417
|
+
assert_in_delta(90, fragment.width)
|
418
|
+
end
|
419
|
+
|
420
|
+
it "sets the character spacing correctly to account for the remaining space after filling with items" do
|
421
|
+
fragment = @fragment.fill_horizontal!(90)
|
422
|
+
refute_same(@fragment.style, fragment.style)
|
423
|
+
assert_equal(0.033333333333332674, fragment.style.character_spacing)
|
424
|
+
assert_in_delta(90, fragment.width)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
395
428
|
it "can be inspected" do
|
396
429
|
frag = setup_fragment(@font.decode_utf8("H") << 5)
|
397
430
|
assert_match(/:H/, frag.inspect)
|
@@ -262,7 +262,7 @@ module CommonLineWrappingTests
|
|
262
262
|
end
|
263
263
|
|
264
264
|
it "handles prohibited breakpoint penalties with non-zero width" do
|
265
|
-
item = boxes(20).first
|
265
|
+
item = boxes(20).first.item
|
266
266
|
result = call(boxes(70) + [glue(10)] + boxes(10) + [penalty(5000, item)] + boxes(30))
|
267
267
|
assert_line_wrapping(result, [70, 60])
|
268
268
|
end
|
@@ -295,11 +295,34 @@ module CommonLineWrappingTests
|
|
295
295
|
assert_equal(2, lines.count)
|
296
296
|
end
|
297
297
|
|
298
|
+
it "handles items with fill_horizontal correctly" do
|
299
|
+
doc = HexaPDF::Document.new
|
300
|
+
font = doc.fonts.add("Times")
|
301
|
+
box1 = HexaPDF::Layout::TextLayouter::Box.new(
|
302
|
+
HexaPDF::Layout::TextFragment.create('.', font: font, fill_horizontal: 1)
|
303
|
+
)
|
304
|
+
box2 = HexaPDF::Layout::TextLayouter::Box.new(
|
305
|
+
HexaPDF::Layout::TextFragment.create('.', font: font, fill_horizontal: 2)
|
306
|
+
)
|
307
|
+
items = [box1, *boxes(10), box2]
|
308
|
+
rest, lines = call(items, 40)
|
309
|
+
assert_equal(0, rest.size)
|
310
|
+
assert_equal(1, lines.size)
|
311
|
+
|
312
|
+
line = lines.first
|
313
|
+
refute_same(items[0].item, line.items[0])
|
314
|
+
assert_same(items[1].item, line.items[1])
|
315
|
+
refute_same(items[2].item, line.items[2])
|
316
|
+
assert_equal(10, line.items[0].width)
|
317
|
+
assert_equal(10, line.items[1].width)
|
318
|
+
assert_equal(20, line.items[2].width)
|
319
|
+
end
|
298
320
|
end
|
299
321
|
|
300
322
|
describe HexaPDF::Layout::TextLayouter::SimpleLineWrapping do
|
301
323
|
before do
|
302
324
|
@obj = HexaPDF::Layout::TextLayouter::SimpleLineWrapping
|
325
|
+
@mock_frame = nil
|
303
326
|
end
|
304
327
|
|
305
328
|
describe "fixed width wrapping" do
|
@@ -308,7 +331,9 @@ describe HexaPDF::Layout::TextLayouter::SimpleLineWrapping do
|
|
308
331
|
def call(items, width = 100, &block)
|
309
332
|
lines = []
|
310
333
|
block ||= proc { true }
|
311
|
-
rest = @obj.call(items, proc { width })
|
334
|
+
rest = @obj.call(items, proc { width }, @mock_frame) do |line, item|
|
335
|
+
lines << line; block.call(line, item)
|
336
|
+
end
|
312
337
|
[rest, lines]
|
313
338
|
end
|
314
339
|
end
|
@@ -319,7 +344,9 @@ describe HexaPDF::Layout::TextLayouter::SimpleLineWrapping do
|
|
319
344
|
def call(items, width = 100, &block)
|
320
345
|
lines = []
|
321
346
|
block ||= proc { true }
|
322
|
-
rest = @obj.call(items, proc {|_| width })
|
347
|
+
rest = @obj.call(items, proc {|_| width }, @mock_frame) do |line, i|
|
348
|
+
lines << line; block.call(line, i)
|
349
|
+
end
|
323
350
|
[rest, lines]
|
324
351
|
end
|
325
352
|
|
@@ -334,7 +361,7 @@ describe HexaPDF::Layout::TextLayouter::SimpleLineWrapping do
|
|
334
361
|
end
|
335
362
|
end
|
336
363
|
lines = []
|
337
|
-
rest = @obj.call(boxes([20, 10], [10, 10], [20, 15], [40, 10]), width_block) do |line|
|
364
|
+
rest = @obj.call(boxes([20, 10], [10, 10], [20, 15], [40, 10]), width_block, @mock_frame) do |line|
|
338
365
|
height += line.height
|
339
366
|
lines << line
|
340
367
|
true
|
@@ -357,7 +384,7 @@ describe HexaPDF::Layout::TextLayouter::SimpleLineWrapping do
|
|
357
384
|
lines = []
|
358
385
|
item = HexaPDF::Layout::InlineBox.create(width: 20, height: 10) {}
|
359
386
|
items = boxes([20, 10]) + [penalty(0, item)] + boxes([40, 15])
|
360
|
-
rest = @obj.call(items, width_block) do |line|
|
387
|
+
rest = @obj.call(items, width_block, @mock_frame) do |line|
|
361
388
|
height += line.height
|
362
389
|
lines << line
|
363
390
|
true
|
@@ -419,6 +446,10 @@ describe HexaPDF::Layout::TextLayouter do
|
|
419
446
|
assert(result.remaining_items.empty?)
|
420
447
|
assert_equal(:success, result.status)
|
421
448
|
end
|
449
|
+
|
450
|
+
result = @layouter.fit(boxes([20, 20], [20, 20], [20, 20], [20, 20]), 60, 200,
|
451
|
+
apply_first_text_indent: false)
|
452
|
+
assert_equal([60, 20], result.lines.map(&:width))
|
422
453
|
end
|
423
454
|
|
424
455
|
it "fits using a limited height" do
|
@@ -243,6 +243,16 @@ describe HexaPDF::Composer do
|
|
243
243
|
[:restore_graphics_state]])
|
244
244
|
end
|
245
245
|
|
246
|
+
it "returns the last drawn box" do
|
247
|
+
box = create_box(height: 400)
|
248
|
+
assert_same(box, @composer.draw_box(box))
|
249
|
+
|
250
|
+
box = create_box(height: 400)
|
251
|
+
split_box = create_box(height: 100)
|
252
|
+
box.define_singleton_method(:split) {|*| [box, split_box] }
|
253
|
+
assert_same(split_box, @composer.draw_box(box))
|
254
|
+
end
|
255
|
+
|
246
256
|
it "raises an error if a box doesn't fit onto an empty page" do
|
247
257
|
assert_raises(HexaPDF::Error) do
|
248
258
|
@composer.draw_box(create_box(height: 800))
|
@@ -94,6 +94,16 @@ describe HexaPDF::Dictionary do
|
|
94
94
|
obj = @test_class.new(nil)
|
95
95
|
assert_equal(:MyType, obj.value[:Type])
|
96
96
|
end
|
97
|
+
|
98
|
+
it "doesn't set the default values for required fields if the type class might be wrong" do
|
99
|
+
@test_class.define_type(:MyType)
|
100
|
+
obj = @test_class.new({})
|
101
|
+
assert_equal([], obj.value[:Array])
|
102
|
+
obj = @test_class.new({Type: :MyType})
|
103
|
+
assert_equal([], obj.value[:Array])
|
104
|
+
obj = @test_class.new({Type: :OtherType})
|
105
|
+
refute(obj.key?(:Array))
|
106
|
+
end
|
97
107
|
end
|
98
108
|
|
99
109
|
describe "[]" do
|
@@ -188,8 +188,11 @@ describe HexaPDF::DictionaryFields do
|
|
188
188
|
["D:19981223-08'00'", [1998, 12, 23, 00, 00, 00, "-08:00"]],
|
189
189
|
["D:199812-08'00'", [1998, 12, 01, 00, 00, 00, "-08:00"]],
|
190
190
|
["D:1998-08'00'", [1998, 01, 01, 00, 00, 00, "-08:00"]],
|
191
|
+
["D:19981223195210Z", [1998, 12, 23, 19, 52, 10, "+00:00"]],
|
192
|
+
["D:19981223195210Z00", [1998, 12, 23, 19, 52, 10, "+00:00"]],
|
193
|
+
["D:19981223195210Z00'00", [1998, 12, 23, 19, 52, 10, "+00:00"]],
|
191
194
|
["D:19981223195210-08", [1998, 12, 23, 19, 52, 10, "-08:00"]], # missing '
|
192
|
-
["D:19981223195210-08'00", [1998, 12, 23, 19, 52, 10, "-08:00"]], #
|
195
|
+
["D:19981223195210-08'00", [1998, 12, 23, 19, 52, 10, "-08:00"]], # no trailing ', as per PDF 2.0
|
193
196
|
["D:19981223195210-54'00", [1998, 12, 23, 19, 52, 10, "-23:59:59"]], # TZ hour too large
|
194
197
|
["D:19981223195210+10'65", [1998, 12, 23, 19, 52, 10, "+11:05"]], # TZ min too large
|
195
198
|
["D:19982423195210-08'00'", [1998, 12, 23, 19, 52, 10, "-08:00"]], # months too large
|
@@ -240,6 +240,7 @@ describe HexaPDF::Document do
|
|
240
240
|
assert_kind_of(@myclass2, @doc.wrap({Subtype: :Global, Test: "true"}))
|
241
241
|
assert_kind_of(@myclass2, @doc.wrap({Type: :MyClass, S: :TheSecond}))
|
242
242
|
assert_kind_of(@myclass, @doc.wrap({Type: :MyClass, Subtype: :TheThird}))
|
243
|
+
assert_kind_of(HexaPDF::Type::FontTrueType, @doc.wrap({Subtype: :TrueType, BaseFont: :Help}))
|
243
244
|
end
|
244
245
|
|
245
246
|
it "respects the given type/subtype arguments" do
|
@@ -560,6 +561,10 @@ describe HexaPDF::Document do
|
|
560
561
|
assert_kind_of(HexaPDF::Type::Outline, @doc.outline)
|
561
562
|
end
|
562
563
|
|
564
|
+
it "returns the optional content properties" do
|
565
|
+
assert_kind_of(HexaPDF::Type::OptionalContentProperties, @doc.optional_content)
|
566
|
+
end
|
567
|
+
|
563
568
|
it "can be inspected and the output is not too large" do
|
564
569
|
assert_match(/HexaPDF::Document:\d+/, @doc.inspect)
|
565
570
|
end
|
data/test/hexapdf/test_filter.rb
CHANGED
@@ -12,6 +12,14 @@ describe HexaPDF::Filter do
|
|
12
12
|
40.times { @str << [rand(2**32)].pack('N') }
|
13
13
|
end
|
14
14
|
|
15
|
+
describe "source_from_proc" do
|
16
|
+
it "returns the whole string, once" do
|
17
|
+
fib = @obj.source_from_proc { @str }
|
18
|
+
assert_equal(@str, collector(fib))
|
19
|
+
assert_equal('', collector(fib))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
15
23
|
describe "source_from_string" do
|
16
24
|
it "doesn't modify the given string" do
|
17
25
|
str = @str.dup
|
@@ -40,6 +40,15 @@ describe HexaPDF::Importer do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
describe "::copy" do
|
44
|
+
it "copies a complete object including references" do
|
45
|
+
obj1 = HexaPDF::Importer.copy(@dest, @obj)
|
46
|
+
obj2 = HexaPDF::Importer.copy(@dest, @obj)
|
47
|
+
refute_same(obj1, obj2)
|
48
|
+
refute_same(obj1[:ref], obj2[:ref])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
43
52
|
describe "import" do
|
44
53
|
it "updates the associated document" do
|
45
54
|
obj = @importer.import(@obj)
|
data/test/hexapdf/test_object.rb
CHANGED
@@ -50,26 +50,37 @@ describe HexaPDF::Object do
|
|
50
50
|
@doc = HexaPDF::Document.new
|
51
51
|
end
|
52
52
|
|
53
|
-
it "
|
53
|
+
it "makes values of wrapped direct objects also direct" do
|
54
54
|
obj = HexaPDF::Object.new(5)
|
55
|
-
assert_same(obj, HexaPDF::Object.make_direct(obj))
|
55
|
+
assert_same(obj, HexaPDF::Object.make_direct(obj, @doc))
|
56
|
+
obj = HexaPDF::Dictionary.new({a: 5, b: HexaPDF::Object.new(:a, oid: 3, document: @doc)})
|
57
|
+
assert_same(obj, HexaPDF::Object.make_direct(obj, @doc))
|
58
|
+
assert_equal(:a, obj[:b])
|
56
59
|
end
|
57
60
|
|
58
61
|
it "works for simple values" do
|
59
62
|
obj = HexaPDF::Object.new(5, oid: 1, document: @doc)
|
60
|
-
assert_same(5, HexaPDF::Object.make_direct(obj))
|
63
|
+
assert_same(5, HexaPDF::Object.make_direct(obj, @doc))
|
61
64
|
end
|
62
65
|
|
63
66
|
it "works for hashes" do
|
64
67
|
obj = HexaPDF::Dictionary.new({a: 5, b: HexaPDF::Object.new(:a, oid: 3, document: @doc)},
|
65
68
|
oid: 1, document: @doc)
|
66
|
-
assert_equal({a: 5, b: :a}, HexaPDF::Object.make_direct(obj))
|
69
|
+
assert_equal({a: 5, b: :a}, HexaPDF::Object.make_direct(obj, @doc))
|
67
70
|
end
|
68
71
|
|
69
72
|
it "works for arrays" do
|
70
73
|
obj = HexaPDF::PDFArray.new([:b, HexaPDF::Object.new(:a, oid: 3, document: @doc)],
|
71
74
|
oid: 1, document: @doc)
|
72
|
-
assert_equal([:b, :a], HexaPDF::Object.make_direct(obj))
|
75
|
+
assert_equal([:b, :a], HexaPDF::Object.make_direct(obj, @doc))
|
76
|
+
end
|
77
|
+
|
78
|
+
it "resolves references" do
|
79
|
+
@doc.add(:Test, oid: 1)
|
80
|
+
obj = HexaPDF::PDFArray.new([HexaPDF::Reference.new(1, 0)],
|
81
|
+
oid: 2, document: @doc)
|
82
|
+
assert_equal([:Test], HexaPDF::Object.make_direct(obj, @doc))
|
83
|
+
assert(@doc.object(1).null?)
|
73
84
|
end
|
74
85
|
end
|
75
86
|
|
data/test/hexapdf/test_stream.rb
CHANGED
@@ -31,6 +31,13 @@ describe HexaPDF::StreamData do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe "fiber" do
|
34
|
+
it "returns a duplicate for a FiberDoubleForString source" do
|
35
|
+
source = HexaPDF::Filter.source_from_string("str")
|
36
|
+
fiber = HexaPDF::StreamData.new(source).fiber
|
37
|
+
assert_equal("str", fiber.resume)
|
38
|
+
refute_same(source, fiber)
|
39
|
+
end
|
40
|
+
|
34
41
|
it "returns a fiber for a Proc source" do
|
35
42
|
s = HexaPDF::StreamData.new(proc { :source })
|
36
43
|
assert_equal(:source, s.fiber.resume)
|
data/test/hexapdf/test_writer.rb
CHANGED
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
|
|
40
40
|
219
|
41
41
|
%%EOF
|
42
42
|
3 0 obj
|
43
|
-
<</Producer(HexaPDF version 0.
|
43
|
+
<</Producer(HexaPDF version 0.34.0)>>
|
44
44
|
endobj
|
45
45
|
xref
|
46
46
|
3 1
|
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
|
|
72
72
|
141
|
73
73
|
%%EOF
|
74
74
|
6 0 obj
|
75
|
-
<</Producer(HexaPDF version 0.
|
75
|
+
<</Producer(HexaPDF version 0.34.0)>>
|
76
76
|
endobj
|
77
77
|
2 0 obj
|
78
78
|
<</Length 10>>stream
|
@@ -214,7 +214,7 @@ describe HexaPDF::Writer do
|
|
214
214
|
<</Type/Page/MediaBox[0 0 595 842]/Parent 2 0 R/Resources<<>>>>
|
215
215
|
endobj
|
216
216
|
5 0 obj
|
217
|
-
<</Producer(HexaPDF version 0.
|
217
|
+
<</Producer(HexaPDF version 0.34.0)>>
|
218
218
|
endobj
|
219
219
|
4 0 obj
|
220
220
|
<</Root 1 0 R/Info 5 0 R/Size 6/Type/XRef/W[1 1 2]/Index[0 6]/Filter/FlateDecode/DecodeParms<</Columns 4/Predictor 12>>/Length 33>>stream
|
@@ -467,12 +467,20 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
467
467
|
it "calculates the font size based on the rectangle height and border width" do
|
468
468
|
@generator.create_appearances
|
469
469
|
assert_operators(@widget[:AP][:N].stream,
|
470
|
-
[:set_font_and_size, [:F1,
|
470
|
+
[:set_font_and_size, [:F1, 13.235294]],
|
471
471
|
range: 5)
|
472
472
|
@widget.border_style(width: 2, color: :transparent)
|
473
473
|
@generator.create_appearances
|
474
474
|
assert_operators(@widget[:AP][:N].stream,
|
475
|
-
[:set_font_and_size, [:F1, 11.
|
475
|
+
[:set_font_and_size, [:F1, 11.764706]],
|
476
|
+
range: 5)
|
477
|
+
end
|
478
|
+
|
479
|
+
it "shrinks the font size if necessary to fit the rectangle width" do
|
480
|
+
@field.field_value = "This is some arbitrary, long text"
|
481
|
+
@generator.create_appearances
|
482
|
+
assert_operators(@widget[:AP][:N].stream,
|
483
|
+
[:set_font_and_size, [:F1, 6.909955]],
|
476
484
|
range: 5)
|
477
485
|
end
|
478
486
|
|
@@ -573,7 +581,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
573
581
|
assert_format("2, 3, #{style}, 0, \"E\", true",
|
574
582
|
[[:set_device_rgb_non_stroking_color, [style % 2, 0.0, 0.0]],
|
575
583
|
[:begin_text],
|
576
|
-
[:set_text_matrix, [1, 0, 0, 1, 2, 3.
|
584
|
+
[:set_text_matrix, [1, 0, 0, 1, 2, 3.183272]],
|
577
585
|
[:show_text, [result]]], 6..9)
|
578
586
|
end
|
579
587
|
end
|
@@ -598,10 +606,10 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
598
606
|
[:append_rectangle, [1, 1, 98, 9.25]],
|
599
607
|
[:clip_path_non_zero],
|
600
608
|
[:end_path],
|
601
|
-
[:set_font_and_size, [:F1, 6.
|
609
|
+
[:set_font_and_size, [:F1, 6.801471]],
|
602
610
|
[:set_device_rgb_non_stroking_color, [1.0, 0.0, 0.0]],
|
603
611
|
[:begin_text],
|
604
|
-
[:set_text_matrix, [1, 0, 0, 1, 2, 3.
|
612
|
+
[:set_text_matrix, [1, 0, 0, 1, 2, 3.183272]],
|
605
613
|
[:show_text, ["Text"]],
|
606
614
|
[:end_text],
|
607
615
|
[:restore_graphics_state],
|
@@ -42,11 +42,12 @@ describe HexaPDF::Type::AcroForm::Form do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "finds the root fields" do
|
45
|
-
@doc.pages.add[:Annots] = [{
|
46
|
-
|
45
|
+
@doc.pages.add[:Annots] = [{Subtype: :Widget, Rect: [0, 0, 0, 0], FT: :Tx},
|
46
|
+
{Subtype: :Widget, Rect: [0, 0, 0, 0], FT: :Tx, Parent: {FT: :Tx}}]
|
47
|
+
@doc.pages.add[:Annots] = [{Subtype: :Widget, Rect: [0, 0, 0, 0]}]
|
47
48
|
@doc.pages.add
|
48
49
|
|
49
|
-
result = [{FT: :Tx}, {FT: :
|
50
|
+
result = [{Subtype: :Widget, Rect: [0, 0, 0, 0], FT: :Tx}, {FT: :Tx}]
|
50
51
|
root_fields = @acro_form.find_root_fields
|
51
52
|
assert_equal(result, root_fields.map(&:value))
|
52
53
|
assert_kind_of(HexaPDF::Type::AcroForm::TextField, root_fields[0])
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/type/actions/set_ocg_state'
|
6
|
+
|
7
|
+
describe HexaPDF::Type::Actions::SetOCGState do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
@action = HexaPDF::Type::Actions::SetOCGState.new({}, document: @doc)
|
11
|
+
@ocg = @doc.optional_content.add_ocg('Test')
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "add_state_change" do
|
15
|
+
it "allows using Ruby-esque and PDF type names for the state change type" do
|
16
|
+
@action.add_state_change(:on, @ocg)
|
17
|
+
@action.add_state_change(:ON, @ocg)
|
18
|
+
@action.add_state_change(:off, @ocg)
|
19
|
+
@action.add_state_change(:OFF, @ocg)
|
20
|
+
@action.add_state_change(:toggle, @ocg)
|
21
|
+
@action.add_state_change(:Toggle, @ocg)
|
22
|
+
assert_equal([:ON, @ocg, :ON, @ocg, :OFF, @ocg, :OFF, @ocg, :Toggle, @ocg, :Toggle, @ocg],
|
23
|
+
@action[:State].value)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "allows specifying more than one OCG" do
|
27
|
+
@action.add_state_change(:on, [@ocg, @doc.optional_content.add_ocg('Test2')])
|
28
|
+
assert_equal([:ON, @ocg, @doc.optional_content.ocg('Test2')], @action[:State].value)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "raises an error if the provide state change type is invalid" do
|
32
|
+
assert_raises(ArgumentError) { @action.add_state_change(:unknown, nil) }
|
33
|
+
end
|
34
|
+
|
35
|
+
it "raises an error if an OCG specified via a string does not exist" do
|
36
|
+
error = assert_raises(HexaPDF::Error) { @action.add_state_change(:on, "Unknown") }
|
37
|
+
assert_match(/Invalid OCG.*Unknown.*specified/, error.message)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -39,6 +39,17 @@ describe HexaPDF::Type::Catalog do
|
|
39
39
|
assert_same(outline, @catalog.outline)
|
40
40
|
end
|
41
41
|
|
42
|
+
it "uses or creates the optional content properties dictionary on access" do
|
43
|
+
@catalog[:OCProperties] = hash = {}
|
44
|
+
assert_equal(:XXOCProperties, @catalog.optional_content.type)
|
45
|
+
assert_same(hash, @catalog.optional_content.value)
|
46
|
+
|
47
|
+
@catalog.delete(:OCProperties)
|
48
|
+
oc = @catalog.optional_content
|
49
|
+
assert_equal([], oc[:OCGs])
|
50
|
+
assert_equal(:XXOCConfiguration, oc[:D].type)
|
51
|
+
end
|
52
|
+
|
42
53
|
describe "acro_form" do
|
43
54
|
it "returns an existing form object" do
|
44
55
|
@catalog[:AcroForm] = :test
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'tempfile'
|
4
6
|
require 'hexapdf/document'
|
5
7
|
require 'hexapdf/type/form'
|
6
8
|
|
@@ -85,6 +87,18 @@ describe HexaPDF::Type::Form do
|
|
85
87
|
@form.process_contents(processor, original_resources: resources)
|
86
88
|
assert_same(resources, processor.resources)
|
87
89
|
end
|
90
|
+
|
91
|
+
it "uses the referenced content in case of a Reference XObject" do
|
92
|
+
@form[:Ref] = @doc.add({F: {}})
|
93
|
+
io = StringIO.new
|
94
|
+
HexaPDF::Document.new.tap {|d| d.pages.add.canvas.line_width(5) }.write(io)
|
95
|
+
@form[:Ref][:F].embed(io, name: 'test')
|
96
|
+
@form[:Ref][:Page] = 0
|
97
|
+
|
98
|
+
processor = HexaPDF::TestUtils::OperatorRecorder.new
|
99
|
+
@form.process_contents(processor)
|
100
|
+
assert_equal([[:set_line_width, [5]]], processor.recorded_ops)
|
101
|
+
end
|
88
102
|
end
|
89
103
|
|
90
104
|
describe "canvas" do
|
@@ -116,4 +130,109 @@ describe HexaPDF::Type::Form do
|
|
116
130
|
assert_raises(HexaPDF::Error) { @form.canvas }
|
117
131
|
end
|
118
132
|
end
|
133
|
+
|
134
|
+
describe "reference_xobject?" do
|
135
|
+
it "returns true if the form is a reference XObject" do
|
136
|
+
refute(@form.reference_xobject?)
|
137
|
+
@form[:Ref] = {}
|
138
|
+
assert(@form.reference_xobject?)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "referenced_content" do
|
143
|
+
before do
|
144
|
+
@form[:BBox] = [10, 10, 110, 60]
|
145
|
+
@form[:Matrix] = [1, 0, 0, 1, 10, 20]
|
146
|
+
@form[:Ref] = @doc.add({F: {}})
|
147
|
+
@ref = @form[:Ref]
|
148
|
+
end
|
149
|
+
|
150
|
+
it "returns a Form XObject with the imported page from an embedded file" do
|
151
|
+
io = StringIO.new
|
152
|
+
HexaPDF::Document.new.tap {|d| d.pages.add.canvas.line_width(5) }.write(io)
|
153
|
+
@ref[:F].embed(io, name: 'test.pdf')
|
154
|
+
@ref[:Page] = 0
|
155
|
+
|
156
|
+
ref_form = @form.referenced_content
|
157
|
+
refute_nil(ref_form)
|
158
|
+
assert_equal([10, 10, 110, 60], ref_form[:BBox].value)
|
159
|
+
assert_equal([1, 0, 0, 1, 10, 20], ref_form[:Matrix].value)
|
160
|
+
assert_equal("5 w\n", ref_form.contents)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "returns a Form XObject with the imported page from an external file" do
|
164
|
+
file = Tempfile.new('hexapdf')
|
165
|
+
HexaPDF::Document.new.tap {|d| d.pages.add.canvas.line_width(5) }.write(file.path)
|
166
|
+
@ref[:F].path = file.path
|
167
|
+
@ref[:Page] = 0
|
168
|
+
assert_equal("5 w\n", @form.referenced_content.contents)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "also works with a page label" do
|
172
|
+
file = Tempfile.new('hexapdf')
|
173
|
+
HexaPDF::Document.new.tap do |d|
|
174
|
+
d.pages.add
|
175
|
+
d.pages.add
|
176
|
+
d.pages.add.canvas.line_width(5)
|
177
|
+
d.pages.add
|
178
|
+
d.pages.add_labelling_range(1, numbering_style: :decimal, prefix: 'Test', start_number: 4)
|
179
|
+
end.write(file.path)
|
180
|
+
@ref[:F].path = file.path
|
181
|
+
@ref[:Page] = 'Test5'
|
182
|
+
assert_equal("5 w\n", @form.referenced_content.contents)
|
183
|
+
end
|
184
|
+
|
185
|
+
it "flattens printable annotations into the page's content stream" do
|
186
|
+
io = StringIO.new
|
187
|
+
HexaPDF::Document.new.tap do |d|
|
188
|
+
d.pages.add.canvas.line_width(5)
|
189
|
+
tf = d.acro_form(create: true).create_text_field('text')
|
190
|
+
widget = tf.create_widget(d.pages[0], Rect: [10, 10, 30, 30])
|
191
|
+
widget.border_style(color: "black")
|
192
|
+
widget = tf.create_widget(d.pages[0], Rect: [40, 10, 70, 30])
|
193
|
+
widget.border_style(color: "red")
|
194
|
+
tf.field_value = 't'
|
195
|
+
widget.unflag(:print)
|
196
|
+
end.write(io)
|
197
|
+
@ref[:F].embed(io, name: 'Test')
|
198
|
+
@ref[:Page] = 0
|
199
|
+
assert_equal(" q Q q 5 w\n Q q q\n1.0 0 0 1.0 10.0 10.0 cm\n/XO1 Do\nQ\n Q ",
|
200
|
+
@form.referenced_content.contents)
|
201
|
+
end
|
202
|
+
|
203
|
+
it "returns nil if the form is not a reference XObject" do
|
204
|
+
@form.delete(:Ref)
|
205
|
+
assert_nil(@form.referenced_content)
|
206
|
+
end
|
207
|
+
|
208
|
+
it "returns nil if the file is not embedded and not found" do
|
209
|
+
@ref[:F].path = '/tmp/non_existing_path'
|
210
|
+
assert_nil(@form.referenced_content)
|
211
|
+
end
|
212
|
+
|
213
|
+
it "returns nil if the page referenced by page number is not found" do
|
214
|
+
io = StringIO.new
|
215
|
+
HexaPDF::Document.new.tap {|d| d.pages.add; d.pages.add }.write(io)
|
216
|
+
@ref[:F].embed(io, name: 'test.pdf')
|
217
|
+
@ref[:Page] = 5
|
218
|
+
assert_nil(@form.referenced_content)
|
219
|
+
end
|
220
|
+
|
221
|
+
it "returns nil if the page referenced by page label is not found" do
|
222
|
+
io = StringIO.new
|
223
|
+
HexaPDF::Document.new.tap do |d|
|
224
|
+
d.pages.add
|
225
|
+
d.pages.add
|
226
|
+
d.pages.add_labelling_range(1, numbering_style: :decimal, prefix: 'Test')
|
227
|
+
end.write(io)
|
228
|
+
@ref[:F].embed(io, name: 'test.pdf')
|
229
|
+
@ref[:Page] = 'Test5'
|
230
|
+
assert_nil(@form.referenced_content)
|
231
|
+
end
|
232
|
+
|
233
|
+
it "returns nil if an error happens during processing" do
|
234
|
+
@ref[:F].embed(StringIO.new('temp'), name: 'test.pdf')
|
235
|
+
assert_nil(@form.referenced_content)
|
236
|
+
end
|
237
|
+
end
|
119
238
|
end
|