hexapdf 0.32.2 → 0.33.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 +4 -4
- data/CHANGELOG.md +63 -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/lib/hexapdf/cli/command.rb +5 -2
- data/lib/hexapdf/cli/form.rb +5 -5
- data/lib/hexapdf/cli/inspect.rb +3 -3
- data/lib/hexapdf/composer.rb +104 -52
- data/lib/hexapdf/configuration.rb +44 -39
- data/lib/hexapdf/content/canvas.rb +393 -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 +52 -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 +6 -5
- data/lib/hexapdf/dictionary_fields.rb +42 -14
- 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 +2 -2
- 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 +167 -39
- data/lib/hexapdf/document/pages.rb +3 -2
- data/lib/hexapdf/document.rb +89 -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 +1 -1
- 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 +9 -2
- data/lib/hexapdf/layout/box_fitter.rb +2 -2
- data/lib/hexapdf/layout/column_box.rb +18 -4
- data/lib/hexapdf/layout/frame.rb +30 -12
- data/lib/hexapdf/layout/image_box.rb +5 -0
- data/lib/hexapdf/layout/inline_box.rb +1 -0
- data/lib/hexapdf/layout/list_box.rb +17 -1
- data/lib/hexapdf/layout/page_style.rb +4 -4
- data/lib/hexapdf/layout/style.rb +18 -3
- data/lib/hexapdf/layout/table_box.rb +682 -0
- data/lib/hexapdf/layout/text_box.rb +5 -3
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +12 -4
- 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 +4 -2
- 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/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -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 +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +2 -2
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +1 -1
- data/lib/hexapdf/type/cid_font.rb +3 -3
- 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 +1 -1
- 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/outline.rb +1 -1
- data/lib/hexapdf/type/outline_item.rb +1 -1
- data/lib/hexapdf/type/page.rb +19 -10
- data/lib/hexapdf/type/page_label.rb +1 -1
- 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/utils/pdf_doc_encoding.rb +1 -1
- 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 +0 -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 +98 -0
- 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 +1 -1
- data/test/hexapdf/layout/test_column_box.rb +65 -21
- data/test/hexapdf/layout/test_frame.rb +14 -14
- data/test/hexapdf/layout/test_image_box.rb +4 -0
- data/test/hexapdf/layout/test_inline_box.rb +5 -0
- data/test/hexapdf/layout/test_list_box.rb +40 -6
- data/test/hexapdf/layout/test_page_style.rb +3 -2
- data/test/hexapdf/layout/test_style.rb +50 -0
- data/test/hexapdf/layout/test_table_box.rb +722 -0
- data/test/hexapdf/layout/test_text_box.rb +18 -0
- data/test/hexapdf/layout/test_text_layouter.rb +4 -0
- data/test/hexapdf/test_dictionary_fields.rb +4 -1
- data/test/hexapdf/test_document.rb +1 -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/test_page.rb +18 -4
- metadata +17 -8
|
@@ -107,6 +107,14 @@ describe HexaPDF::Layout::TextBox do
|
|
|
107
107
|
assert_equal([nil, box], box.split(100, 100, @frame))
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
+
it "works if the box fits exactly (+/- float divergence)" do
|
|
111
|
+
box = create_box([@inline_box] * 5)
|
|
112
|
+
box.fit(50, 10, @frame)
|
|
113
|
+
box.instance_variable_set(:@width, 50.00000000006)
|
|
114
|
+
box.instance_variable_set(:@height, 10.00000000003)
|
|
115
|
+
assert_equal([box], box.split(50, 10, @frame))
|
|
116
|
+
end
|
|
117
|
+
|
|
110
118
|
it "splits the box if necessary when using non-flowing text" do
|
|
111
119
|
box = create_box([@inline_box] * 10)
|
|
112
120
|
boxes = box.split(50, 10, @frame)
|
|
@@ -125,6 +133,16 @@ describe HexaPDF::Layout::TextBox do
|
|
|
125
133
|
assert_equal(box, boxes[0])
|
|
126
134
|
assert_equal(5, boxes[1].instance_variable_get(:@items).length)
|
|
127
135
|
end
|
|
136
|
+
|
|
137
|
+
it "correctly handles text indentation for split boxes" do
|
|
138
|
+
[{}, {position: :flow}].each do |styles|
|
|
139
|
+
box = create_box([@inline_box] * 202, style: {text_indent: 50, **styles})
|
|
140
|
+
boxes = box.split(100, 100, @frame)
|
|
141
|
+
assert_equal(107, boxes[1].instance_variable_get(:@items).length)
|
|
142
|
+
boxes = boxes[1].split(100, 100, @frame)
|
|
143
|
+
assert_equal(7, boxes[1].instance_variable_get(:@items).length)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
128
146
|
end
|
|
129
147
|
|
|
130
148
|
describe "draw" do
|
|
@@ -419,6 +419,10 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
419
419
|
assert(result.remaining_items.empty?)
|
|
420
420
|
assert_equal(:success, result.status)
|
|
421
421
|
end
|
|
422
|
+
|
|
423
|
+
result = @layouter.fit(boxes([20, 20], [20, 20], [20, 20], [20, 20]), 60, 200,
|
|
424
|
+
apply_first_text_indent: false)
|
|
425
|
+
assert_equal([60, 20], result.lines.map(&:width))
|
|
422
426
|
end
|
|
423
427
|
|
|
424
428
|
it "fits using a limited height" 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
|
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.33.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.33.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.33.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])
|
|
@@ -557,7 +557,7 @@ describe HexaPDF::Type::Page do
|
|
|
557
557
|
@page = @doc.pages.add
|
|
558
558
|
@appearance = @doc.add({Type: :XObject, Subtype: :Form, BBox: [-10, -5, 50, 20]}, stream: "")
|
|
559
559
|
@annot1 = @doc.add({Type: :Annot, Subtype: :Text, Rect: [100, 100, 160, 125], AP: {N: @appearance}})
|
|
560
|
-
@annot2 = @doc.add({Rect: [10, 10, 70, 35], AP: {N: @appearance}})
|
|
560
|
+
@annot2 = @doc.add({Type: :Annot, Subtype: :Text, Rect: [10, 10, 70, 35], AP: {N: @appearance}})
|
|
561
561
|
@page[:Annots] = [@annot1, @annot2]
|
|
562
562
|
@canvas = @page.canvas(type: :overlay)
|
|
563
563
|
end
|
|
@@ -591,6 +591,18 @@ describe HexaPDF::Type::Page do
|
|
|
591
591
|
assert(@annot2.null?)
|
|
592
592
|
end
|
|
593
593
|
|
|
594
|
+
it "gracefully handles invalid /Annot key values" do
|
|
595
|
+
@page[:Annots] << nil << @doc.add({}, stream: '')
|
|
596
|
+
result = @page.flatten_annotations
|
|
597
|
+
assert(result.empty?)
|
|
598
|
+
assert(@annot1.null?)
|
|
599
|
+
assert(@annot2.null?)
|
|
600
|
+
|
|
601
|
+
@page[:Annots] = @doc.add({}, stream: '')
|
|
602
|
+
result = @page.flatten_annotations
|
|
603
|
+
assert(result.empty?)
|
|
604
|
+
end
|
|
605
|
+
|
|
594
606
|
it "only deletes the widget annotation of a form field even if it is embedded in the field object" do
|
|
595
607
|
form = @doc.acro_form(create: true)
|
|
596
608
|
field = form.create_text_field('test')
|
|
@@ -631,7 +643,7 @@ describe HexaPDF::Type::Page do
|
|
|
631
643
|
[:restore_graphics_state]])
|
|
632
644
|
end
|
|
633
645
|
|
|
634
|
-
it "ignores annotations without
|
|
646
|
+
it "ignores annotations without appearance stream" do
|
|
635
647
|
@annot1.delete(:AP)
|
|
636
648
|
result = @page.flatten_annotations
|
|
637
649
|
assert_equal([@annot1], result)
|
|
@@ -708,10 +720,12 @@ describe HexaPDF::Type::Page do
|
|
|
708
720
|
it "yields each annotation" do
|
|
709
721
|
page = @doc.pages.add
|
|
710
722
|
annot1 = @doc.add({Type: :Annot, Subtype: :Text, Rect: [100, 100, 160, 125]})
|
|
711
|
-
annot2 = @doc.add({Rect: [10, 10, 70, 35]})
|
|
712
|
-
|
|
723
|
+
annot2 = @doc.add({Subtype: :Unknown, Rect: [10, 10, 70, 35]})
|
|
724
|
+
not_an_annot = @doc.add({}, stream: '')
|
|
725
|
+
page[:Annots] = [not_an_annot, annot1, nil, annot2]
|
|
713
726
|
|
|
714
727
|
annotations = page.each_annotation.to_a
|
|
728
|
+
assert_equal(2, annotations.size)
|
|
715
729
|
assert_equal([100, 100, 160, 125], annotations[0][:Rect])
|
|
716
730
|
assert_equal(:Annot, annotations[0].type)
|
|
717
731
|
assert_equal(:Annot, annotations[1].type)
|
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.
|
|
4
|
+
version: 0.33.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas Leitner
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-08-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cmdparse
|
|
@@ -36,14 +36,20 @@ dependencies:
|
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '0.
|
|
39
|
+
version: '0.4'
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: 0.4.1
|
|
40
43
|
type: :runtime
|
|
41
44
|
prerelease: false
|
|
42
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
43
46
|
requirements:
|
|
44
47
|
- - "~>"
|
|
45
48
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '0.
|
|
49
|
+
version: '0.4'
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: 0.4.1
|
|
47
53
|
- !ruby/object:Gem::Dependency
|
|
48
54
|
name: openssl
|
|
49
55
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -292,6 +298,7 @@ files:
|
|
|
292
298
|
- examples/022-outline.rb
|
|
293
299
|
- examples/023-images.rb
|
|
294
300
|
- examples/024-digital-signatures.rb
|
|
301
|
+
- examples/025-table_box.rb
|
|
295
302
|
- examples/emoji-smile.png
|
|
296
303
|
- examples/emoji-wink.png
|
|
297
304
|
- examples/machupicchu.jpg
|
|
@@ -430,6 +437,7 @@ files:
|
|
|
430
437
|
- lib/hexapdf/layout/numeric_refinements.rb
|
|
431
438
|
- lib/hexapdf/layout/page_style.rb
|
|
432
439
|
- lib/hexapdf/layout/style.rb
|
|
440
|
+
- lib/hexapdf/layout/table_box.rb
|
|
433
441
|
- lib/hexapdf/layout/text_box.rb
|
|
434
442
|
- lib/hexapdf/layout/text_fragment.rb
|
|
435
443
|
- lib/hexapdf/layout/text_layouter.rb
|
|
@@ -682,6 +690,7 @@ files:
|
|
|
682
690
|
- test/hexapdf/layout/test_list_box.rb
|
|
683
691
|
- test/hexapdf/layout/test_page_style.rb
|
|
684
692
|
- test/hexapdf/layout/test_style.rb
|
|
693
|
+
- test/hexapdf/layout/test_table_box.rb
|
|
685
694
|
- test/hexapdf/layout/test_text_box.rb
|
|
686
695
|
- test/hexapdf/layout/test_text_fragment.rb
|
|
687
696
|
- test/hexapdf/layout/test_text_layouter.rb
|
|
@@ -760,7 +769,7 @@ licenses:
|
|
|
760
769
|
- AGPL-3.0
|
|
761
770
|
- Nonstandard
|
|
762
771
|
metadata: {}
|
|
763
|
-
post_install_message:
|
|
772
|
+
post_install_message:
|
|
764
773
|
rdoc_options: []
|
|
765
774
|
require_paths:
|
|
766
775
|
- lib
|
|
@@ -775,8 +784,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
775
784
|
- !ruby/object:Gem::Version
|
|
776
785
|
version: '0'
|
|
777
786
|
requirements: []
|
|
778
|
-
rubygems_version: 3.
|
|
779
|
-
signing_key:
|
|
787
|
+
rubygems_version: 3.5.0.dev
|
|
788
|
+
signing_key:
|
|
780
789
|
specification_version: 4
|
|
781
790
|
summary: HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
782
791
|
test_files: []
|