hexapdf 0.21.1 → 0.24.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 +137 -0
- data/LICENSE +1 -1
- data/Rakefile +1 -1
- data/examples/016-frame_automatic_box_placement.rb +7 -2
- data/examples/017-frame_text_flow.rb +10 -18
- data/examples/020-column_box.rb +20 -37
- data/examples/021-list_box.rb +26 -0
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +1 -1
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +31 -4
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +2 -2
- data/lib/hexapdf/cli/inspect.rb +19 -6
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +24 -4
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/cli.rb +1 -1
- data/lib/hexapdf/composer.rb +66 -125
- data/lib/hexapdf/configuration.rb +17 -1
- data/lib/hexapdf/content/canvas.rb +1 -1
- data/lib/hexapdf/content/color_space.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/geom2d.rb +2 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +1 -1
- data/lib/hexapdf/content/parser.rb +1 -1
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +1 -1
- data/lib/hexapdf/dictionary_fields.rb +2 -2
- data/lib/hexapdf/document/destinations.rb +396 -0
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/layout.rb +397 -0
- data/lib/hexapdf/document/pages.rb +17 -1
- data/lib/hexapdf/document/signatures.rb +5 -4
- data/lib/hexapdf/document.rb +46 -90
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +1 -1
- data/lib/hexapdf/encryption/fast_arc4.rb +30 -21
- 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 +1 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/crypt.rb +1 -1
- data/lib/hexapdf/filter/encryption.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 +1 -1
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/glyph_list.rb +2 -2
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +1 -1
- data/lib/hexapdf/font/true_type/font.rb +1 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
- data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
- data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
- data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
- data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
- data/lib/hexapdf/font/true_type/table/name.rb +1 -1
- data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +1 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font.rb +1 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
- data/lib/hexapdf/font/type1.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +1 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/font_loader.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +1 -1
- data/lib/hexapdf/layout/box.rb +121 -22
- data/lib/hexapdf/layout/box_fitter.rb +136 -0
- data/lib/hexapdf/layout/column_box.rb +168 -89
- data/lib/hexapdf/layout/frame.rb +155 -140
- data/lib/hexapdf/layout/image_box.rb +19 -4
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/list_box.rb +355 -0
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.rb +285 -8
- data/lib/hexapdf/layout/text_box.rb +30 -11
- data/lib/hexapdf/layout/text_fragment.rb +3 -2
- data/lib/hexapdf/layout/text_layouter.rb +23 -3
- data/lib/hexapdf/layout/text_shaper.rb +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +12 -7
- data/lib/hexapdf/layout.rb +4 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +1 -1
- data/lib/hexapdf/parser.rb +1 -8
- 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 +9 -2
- data/lib/hexapdf/revisions.rb +152 -51
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +22 -12
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/tokenizer.rb +1 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/type/acro_form/form.rb +12 -6
- data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/text_field.rb +9 -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 +1 -1
- 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 +1 -1
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +10 -2
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +1 -1
- data/lib/hexapdf/type/font.rb +1 -1
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_true_type.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +1 -1
- data/lib/hexapdf/type/font_type1.rb +1 -1
- 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 +48 -4
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +14 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/page.rb +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +19 -2
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +1 -1
- data/lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb +1 -1
- data/lib/hexapdf/type/signature/handler.rb +1 -1
- data/lib/hexapdf/type/signature/verification_result.rb +1 -1
- data/lib/hexapdf/type/signature.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 +3 -2
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +1 -1
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
- data/lib/hexapdf/utils/lru_cache.rb +1 -1
- data/lib/hexapdf/utils/math_helpers.rb +1 -1
- data/lib/hexapdf/utils/object_hash.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +4 -2
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +23 -8
- data/lib/hexapdf/xref_section.rb +1 -1
- data/lib/hexapdf.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +1 -1
- data/test/hexapdf/document/test_destinations.rb +338 -0
- data/test/hexapdf/document/test_images.rb +1 -1
- data/test/hexapdf/document/test_layout.rb +264 -0
- data/test/hexapdf/document/test_pages.rb +9 -0
- data/test/hexapdf/document/test_signatures.rb +10 -3
- data/test/hexapdf/encryption/test_security_handler.rb +3 -3
- data/test/hexapdf/font/encoding/test_glyph_list.rb +4 -0
- data/test/hexapdf/layout/test_box.rb +53 -3
- data/test/hexapdf/layout/test_box_fitter.rb +62 -0
- data/test/hexapdf/layout/test_column_box.rb +159 -0
- data/test/hexapdf/layout/test_frame.rb +114 -39
- data/test/hexapdf/layout/test_image_box.rb +1 -1
- data/test/hexapdf/layout/test_list_box.rb +249 -0
- data/test/hexapdf/layout/test_text_box.rb +33 -2
- data/test/hexapdf/layout/test_text_fragment.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +49 -17
- data/test/hexapdf/layout/test_width_from_polygon.rb +13 -0
- data/test/hexapdf/task/test_optimize.rb +17 -4
- data/test/hexapdf/test_composer.rb +35 -1
- data/test/hexapdf/test_dictionary_fields.rb +10 -10
- data/test/hexapdf/test_document.rb +33 -136
- data/test/hexapdf/test_filter.rb +1 -1
- data/test/hexapdf/test_parser.rb +1 -3
- data/test/hexapdf/test_revision.rb +14 -0
- data/test/hexapdf/test_revisions.rb +137 -29
- data/test/hexapdf/test_serializer.rb +1 -5
- data/test/hexapdf/test_writer.rb +99 -15
- data/test/hexapdf/type/acro_form/test_form.rb +2 -1
- data/test/hexapdf/type/acro_form/test_text_field.rb +17 -0
- data/test/hexapdf/type/test_catalog.rb +8 -0
- data/test/hexapdf/type/test_image.rb +45 -9
- data/test/hexapdf/type/test_names.rb +20 -0
- data/test/hexapdf/type/test_page_tree_node.rb +21 -1
- data/test/hexapdf/type/test_trailer.rb +3 -3
- data/test/hexapdf/type/test_xref_stream.rb +2 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +11 -1
- data/test/test_helper.rb +5 -1
- metadata +29 -3
@@ -91,43 +91,6 @@ describe HexaPDF::Document do
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
describe "object" do
|
95
|
-
it "accepts a Reference object as argument" do
|
96
|
-
assert_equal(10, @io_doc.object(HexaPDF::Reference.new(1, 0)).value)
|
97
|
-
end
|
98
|
-
|
99
|
-
it "accepts an object number as arguments" do
|
100
|
-
assert_equal(10, @io_doc.object(1).value)
|
101
|
-
end
|
102
|
-
|
103
|
-
it "returns added objects" do
|
104
|
-
obj = @io_doc.add(@io_doc.wrap({Type: :Test}, oid: 100))
|
105
|
-
assert_equal(obj, @io_doc.object(100))
|
106
|
-
end
|
107
|
-
|
108
|
-
it "returns nil for unknown object references" do
|
109
|
-
assert_nil(@io_doc.object(100))
|
110
|
-
end
|
111
|
-
|
112
|
-
it "returns only the newest version of an object" do
|
113
|
-
assert_equal(200, @io_doc.object(2).value)
|
114
|
-
assert_equal(200, @io_doc.object(HexaPDF::Reference.new(2, 0)).value)
|
115
|
-
assert_nil(@io_doc.object(3).value)
|
116
|
-
assert_nil(@io_doc.object(HexaPDF::Reference.new(3, 1)).value)
|
117
|
-
assert_equal(30, @io_doc.object(HexaPDF::Reference.new(3, 0)).value)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe "object?" do
|
122
|
-
it "works with a Reference object as argument" do
|
123
|
-
assert(@io_doc.object?(HexaPDF::Reference.new(1, 0)))
|
124
|
-
end
|
125
|
-
|
126
|
-
it "works with an object number as arguments" do
|
127
|
-
assert(@io_doc.object?(1))
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
94
|
describe "deref" do
|
132
95
|
it "returns a dereferenced object when given a Reference object" do
|
133
96
|
assert_equal(@io_doc.object(1), @io_doc.deref(HexaPDF::Reference.new(1, 0)))
|
@@ -139,13 +102,6 @@ describe HexaPDF::Document do
|
|
139
102
|
end
|
140
103
|
|
141
104
|
describe "add" do
|
142
|
-
it "automatically assigns free object numbers" do
|
143
|
-
assert_equal(1, @doc.add(5).oid)
|
144
|
-
assert_equal(2, @doc.add(5).oid)
|
145
|
-
@doc.revisions.add
|
146
|
-
assert_equal(3, @doc.add(5).oid)
|
147
|
-
end
|
148
|
-
|
149
105
|
it "assigns the object's document" do
|
150
106
|
obj = @doc.add(5)
|
151
107
|
assert_equal(@doc, obj.document)
|
@@ -166,82 +122,38 @@ describe HexaPDF::Document do
|
|
166
122
|
assert_equal(5, obj.value)
|
167
123
|
end
|
168
124
|
|
169
|
-
it "returns the given object if it is already stored in the document" do
|
170
|
-
obj = @doc.add(5)
|
171
|
-
assert_same(obj, @doc.add(obj))
|
172
|
-
end
|
173
|
-
|
174
|
-
it "allows specifying a revision to which the object should be added" do
|
175
|
-
@doc.revisions.add
|
176
|
-
@doc.revisions.add
|
177
|
-
|
178
|
-
@doc.add(@doc.wrap(5, oid: 1), revision: 0)
|
179
|
-
assert_equal(5, @doc.object(1).value)
|
180
|
-
|
181
|
-
@doc.add(@doc.wrap(10, oid: 1), revision: 2)
|
182
|
-
assert_equal(10, @doc.object(1).value)
|
183
|
-
|
184
|
-
@doc.add(@doc.wrap(7.5, oid: 1), revision: 1)
|
185
|
-
assert_equal(10, @doc.object(1).value)
|
186
|
-
end
|
187
|
-
|
188
|
-
it "fails if the specified revision index is invalid" do
|
189
|
-
assert_raises(ArgumentError) { @doc.add(5, revision: 5) }
|
190
|
-
end
|
191
|
-
|
192
125
|
it "fails if the object to be added is associated with another document" do
|
193
126
|
doc = HexaPDF::Document.new
|
194
127
|
obj = doc.add(5)
|
195
128
|
assert_raises(HexaPDF::Error) { @doc.add(obj) }
|
196
129
|
end
|
197
|
-
|
198
|
-
it "fails if the object number is already associated with another object" do
|
199
|
-
obj = @doc.add(5)
|
200
|
-
assert_raises(HexaPDF::Error) { @doc.add(@doc.wrap(5, oid: obj.oid, gen: 1)) }
|
201
|
-
end
|
202
130
|
end
|
203
131
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
@doc.add(5)
|
213
|
-
@doc.delete(1, mark_as_free: false)
|
214
|
-
refute(@doc.object?(1))
|
215
|
-
end
|
216
|
-
|
217
|
-
describe "with an object in multiple revisions" do
|
218
|
-
before do
|
219
|
-
@ref = HexaPDF::Reference.new(2, 3)
|
220
|
-
obj = @doc.wrap(5, oid: @ref.oid, gen: @ref.gen)
|
221
|
-
@doc.revisions.add
|
222
|
-
@doc.add(obj, revision: 0)
|
223
|
-
@doc.add(obj, revision: 1)
|
224
|
-
end
|
225
|
-
|
226
|
-
it "deletes an object for all revisions when revision = :all" do
|
227
|
-
@doc.delete(@ref, revision: :all, mark_as_free: false)
|
228
|
-
refute(@doc.object?(@ref))
|
229
|
-
end
|
230
|
-
|
231
|
-
it "deletes an object only in the current revision when revision = :current" do
|
232
|
-
@doc.delete(@ref, revision: :current, mark_as_free: false)
|
233
|
-
assert(@doc.object?(@ref))
|
234
|
-
end
|
132
|
+
it "defers to @revisions for retrieving an object" do
|
133
|
+
revs = Minitest::Mock.new
|
134
|
+
revs.expect(:object, :retval, [:ref])
|
135
|
+
doc = HexaPDF::Document.new
|
136
|
+
doc.instance_variable_set(:@revisions, revs)
|
137
|
+
doc.object(:ref)
|
138
|
+
revs.verify
|
139
|
+
end
|
235
140
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
141
|
+
it "defers to @revisions for checking for the existence of an object" do
|
142
|
+
revs = Minitest::Mock.new
|
143
|
+
revs.expect(:object?, :retval, [:ref])
|
144
|
+
doc = HexaPDF::Document.new
|
145
|
+
doc.instance_variable_set(:@revisions, revs)
|
146
|
+
doc.object?(:ref)
|
147
|
+
revs.verify
|
148
|
+
end
|
241
149
|
|
242
|
-
|
243
|
-
|
244
|
-
|
150
|
+
it "defers to @revisions for deleting an object" do
|
151
|
+
revs = Minitest::Mock.new
|
152
|
+
revs.expect(:delete_object, :retval, [:ref])
|
153
|
+
doc = HexaPDF::Document.new
|
154
|
+
doc.instance_variable_set(:@revisions, revs)
|
155
|
+
doc.delete(:ref)
|
156
|
+
revs.verify
|
245
157
|
end
|
246
158
|
|
247
159
|
describe "import" do
|
@@ -388,28 +300,13 @@ describe HexaPDF::Document do
|
|
388
300
|
end
|
389
301
|
end
|
390
302
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
end
|
399
|
-
|
400
|
-
it "iterates over all loaded objects" do
|
401
|
-
assert_equal(200, @io_doc.object(2).value)
|
402
|
-
assert_equal([200], @io_doc.each(only_loaded: true).sort.map(&:value))
|
403
|
-
end
|
404
|
-
|
405
|
-
it "yields the revision as second argument if the block accepts exactly two arguments" do
|
406
|
-
objs = [[10, 20, 30], [200, nil]]
|
407
|
-
data = @io_doc.revisions.map.with_index {|rev, i| objs[i].map {|o| [o, rev] } }.reverse.flatten
|
408
|
-
@io_doc.each(only_current: false) do |obj, rev|
|
409
|
-
assert(data.shift == obj.value)
|
410
|
-
assert_equal(data.shift, rev)
|
411
|
-
end
|
412
|
-
end
|
303
|
+
it "defers to @revisions for iterating over all objects" do
|
304
|
+
revs = Minitest::Mock.new
|
305
|
+
revs.expect(:each_object, :retval, only_current: true, only_loaded: true)
|
306
|
+
doc = HexaPDF::Document.new
|
307
|
+
doc.instance_variable_set(:@revisions, revs)
|
308
|
+
doc.each(only_current: true, only_loaded: true)
|
309
|
+
revs.verify
|
413
310
|
end
|
414
311
|
|
415
312
|
describe "encryption" do
|
@@ -431,7 +328,7 @@ describe HexaPDF::Document do
|
|
431
328
|
|
432
329
|
it "doesn't decrypt the document if document.auto_encrypt=false" do
|
433
330
|
test_file = File.join(TEST_DATA_DIR, 'standard-security-handler', 'nopwd-arc4-40bit-V1.pdf')
|
434
|
-
doc = HexaPDF::Document.new(io: StringIO.new(File.
|
331
|
+
doc = HexaPDF::Document.new(io: StringIO.new(File.binread(test_file)),
|
435
332
|
config: {'document.auto_decrypt' => false})
|
436
333
|
assert_kind_of(String, doc.trailer[:Info][:ModDate])
|
437
334
|
handler = HexaPDF::Encryption::SecurityHandler.set_up_decryption(doc)
|
@@ -613,8 +510,8 @@ describe HexaPDF::Document do
|
|
613
510
|
|
614
511
|
it "allows to conveniently sign a document" do
|
615
512
|
mock = Minitest::Mock.new
|
616
|
-
mock.expect(:handler, :handler,
|
617
|
-
mock.expect(:add, :added, [:io, :handler,
|
513
|
+
mock.expect(:handler, :handler, name: :handler, opt: :key)
|
514
|
+
mock.expect(:add, :added, [:io, :handler], signature: :sig, write_options: :write_options)
|
618
515
|
@doc.instance_variable_set(:@signatures, mock)
|
619
516
|
result = @doc.sign(:io, handler: :handler, write_options: :write_options, signature: :sig, opt: :key)
|
620
517
|
assert_equal(:added, result)
|
data/test/hexapdf/test_filter.rb
CHANGED
data/test/hexapdf/test_parser.rb
CHANGED
@@ -543,14 +543,12 @@ describe HexaPDF::Parser do
|
|
543
543
|
xref_section, trailer = @parser.load_revision(@parser.startxref_offset)
|
544
544
|
assert_equal({Test: 'now'}, trailer)
|
545
545
|
assert(xref_section[1].in_use?)
|
546
|
-
refute(@parser.contains_xref_streams?)
|
547
546
|
end
|
548
547
|
|
549
548
|
it "works for a cross-reference stream" do
|
550
549
|
xref_section, trailer = @parser.load_revision(212)
|
551
|
-
assert_equal({Size: 2}, trailer)
|
550
|
+
assert_equal({Size: 2, Type: :XRef}, trailer)
|
552
551
|
assert(xref_section[1].in_use?)
|
553
|
-
assert(@parser.contains_xref_streams?)
|
554
552
|
end
|
555
553
|
|
556
554
|
it "fails if another object is found instead of a cross-reference stream" do
|
@@ -215,4 +215,18 @@ describe HexaPDF::Revision do
|
|
215
215
|
assert_equal([], @rev.each_modified_object.to_a)
|
216
216
|
end
|
217
217
|
end
|
218
|
+
|
219
|
+
describe "reset_objects" do
|
220
|
+
it "deletes loaded objects" do
|
221
|
+
@rev.object(2)
|
222
|
+
@rev.reset_objects
|
223
|
+
assert(@rev.instance_variable_get(:@objects).oids.empty?)
|
224
|
+
end
|
225
|
+
|
226
|
+
it "deletes added objects" do
|
227
|
+
@rev.add(@obj)
|
228
|
+
@rev.reset_objects
|
229
|
+
assert(@rev.instance_variable_get(:@objects).oids.empty?)
|
230
|
+
end
|
231
|
+
end
|
218
232
|
end
|
@@ -70,61 +70,169 @@ describe HexaPDF::Revisions do
|
|
70
70
|
@revisions = @doc.revisions
|
71
71
|
end
|
72
72
|
|
73
|
-
describe "
|
74
|
-
it "
|
75
|
-
|
76
|
-
assert_equal(
|
77
|
-
assert_equal(
|
73
|
+
describe "initialize" do
|
74
|
+
it "automatically loads all revisions from the underlying IO object" do
|
75
|
+
assert_kind_of(HexaPDF::Parser, @revisions.parser)
|
76
|
+
assert_equal(20, @revisions.all[0].object(2).value)
|
77
|
+
assert_equal(200, @revisions.all[1].object(2).value)
|
78
|
+
assert_equal(400, @revisions.all[2].object(2).value)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "creates an empty revision when not using initial revisions" do
|
82
|
+
revisions = HexaPDF::Revisions.new(@doc)
|
83
|
+
assert_equal(1, revisions.all.count)
|
78
84
|
end
|
79
85
|
end
|
80
86
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
87
|
+
it "returns the next free oid" do
|
88
|
+
assert_equal(4, @revisions.next_oid)
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "object" do
|
92
|
+
it "accepts a Reference object as argument" do
|
93
|
+
assert_equal(400, @revisions.object(HexaPDF::Reference.new(2, 0)).value)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "accepts an object number as arguments" do
|
97
|
+
assert_equal(400, @revisions.object(2).value)
|
86
98
|
end
|
87
99
|
|
88
|
-
it "
|
89
|
-
|
90
|
-
@revisions.delete(rev)
|
91
|
-
refute(@revisions.any? {|r| r == rev })
|
100
|
+
it "returns nil for unknown object references" do
|
101
|
+
assert_nil(@revisions.object(100))
|
92
102
|
end
|
93
103
|
|
94
|
-
it "
|
95
|
-
|
104
|
+
it "returns a null object for freed objects" do
|
105
|
+
@revisions.delete_object(2)
|
106
|
+
assert(@revisions.object(2).null?)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "object?" do
|
111
|
+
it "works with a Reference object as argument" do
|
112
|
+
assert(@revisions.object?(HexaPDF::Reference.new(2, 0)))
|
113
|
+
end
|
114
|
+
|
115
|
+
it "works with an object number as arguments" do
|
116
|
+
assert(@revisions.object?(2))
|
117
|
+
end
|
118
|
+
|
119
|
+
it "returns false when no object is found" do
|
120
|
+
refute(@revisions.object?(20))
|
121
|
+
end
|
122
|
+
|
123
|
+
it "returns true for freed objects" do
|
124
|
+
@revisions.delete_object(2)
|
125
|
+
assert(@revisions.object?(2))
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "add_object" do
|
130
|
+
before do
|
131
|
+
@obj = HexaPDF::Object.new(5)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "adds the object to the current revision" do
|
135
|
+
@revisions.add_object(@obj)
|
136
|
+
assert_same(@obj, @revisions.current.object(@obj))
|
137
|
+
end
|
138
|
+
|
139
|
+
it "returns the added object" do
|
140
|
+
obj = @revisions.add_object(@obj)
|
141
|
+
assert_same(@obj, obj)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "returns the given object if it is already stored in the document" do
|
145
|
+
obj = @revisions.add_object(@obj)
|
146
|
+
assert_same(obj, @revisions.add_object(obj))
|
147
|
+
end
|
148
|
+
|
149
|
+
it "fails if the object number is already associated with another object" do
|
150
|
+
@revisions.add_object(@obj)
|
151
|
+
assert_raises(HexaPDF::Error) { @revisions.add_object(@doc.wrap(5, oid: @obj.oid)) }
|
152
|
+
end
|
153
|
+
|
154
|
+
it "automatically assign an object number for direct objects" do
|
155
|
+
assert_equal(4, @revisions.add_object(@obj).oid)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "delete_object" do
|
160
|
+
it "works with a Reference object as argument" do
|
161
|
+
@revisions.delete_object(@doc.object(2))
|
162
|
+
assert(@revisions.object(2).null?)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "works with an object number as arguments" do
|
166
|
+
@revisions.delete_object(2)
|
167
|
+
assert(@revisions.object(2).null?)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "deletes an object only in the most recent revision" do
|
171
|
+
@revisions.delete_object(2)
|
172
|
+
assert_equal(20, @revisions.all[0].object(2).value)
|
173
|
+
assert_equal(200, @revisions.all[1].object(2).value)
|
174
|
+
assert(@revisions.all[2].object(2).null?)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "each_object" do
|
179
|
+
before do
|
180
|
+
@obj3 = @revisions.object(3).value
|
181
|
+
end
|
182
|
+
|
183
|
+
it "iterates over the current objects" do
|
184
|
+
assert_equal([10, 400, @obj3], @revisions.each_object(only_current: true).sort.map(&:value))
|
185
|
+
end
|
186
|
+
|
187
|
+
it "iterates over all objects" do
|
188
|
+
assert_equal([@obj3, 400, 200, @obj3, 10, 20],
|
189
|
+
@revisions.each_object(only_current: false).map(&:value))
|
190
|
+
end
|
191
|
+
|
192
|
+
it "iterates over all loaded objects" do
|
193
|
+
assert_equal([@obj3], @revisions.each_object(only_loaded: true).map(&:value))
|
194
|
+
assert_equal(400, @revisions.object(2).value)
|
195
|
+
assert_equal([400, @obj3], @revisions.each_object(only_loaded: true).sort.map(&:value))
|
196
|
+
end
|
197
|
+
|
198
|
+
it "yields the revision as second argument if the block accepts exactly two arguments" do
|
199
|
+
data = [@obj3, @revisions.all[-1], 400, @revisions.all[-1], 10, @revisions.all[0]]
|
200
|
+
@revisions.each_object do |obj, rev|
|
201
|
+
assert_equal(data.shift, obj.value)
|
202
|
+
assert_equal(data.shift, rev)
|
203
|
+
end
|
204
|
+
assert(data.empty?)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe "add" do
|
209
|
+
it "adds an empty revision as the current revision" do
|
210
|
+
rev = @revisions.add
|
211
|
+
assert_equal({Size: 4}, rev.trailer.value)
|
212
|
+
assert_equal(rev, @revisions.current)
|
96
213
|
end
|
97
214
|
end
|
98
215
|
|
99
216
|
describe "merge" do
|
100
217
|
it "does nothing when only one revision is specified" do
|
101
218
|
@revisions.merge(1..1)
|
102
|
-
assert_equal(3, @revisions.
|
219
|
+
assert_equal(3, @revisions.all.size)
|
103
220
|
end
|
104
221
|
|
105
222
|
it "merges the higher into the the lower revision" do
|
106
223
|
@revisions.merge
|
107
|
-
assert_equal(1, @revisions.
|
224
|
+
assert_equal(1, @revisions.all.size)
|
108
225
|
assert_equal([10, 400, @doc.object(3).value], @revisions.current.each.to_a.sort.map(&:value))
|
109
226
|
end
|
110
227
|
|
111
228
|
it "handles objects correctly that are in multiple revisions" do
|
112
|
-
@revisions.current.add(@revisions[0].object(1))
|
229
|
+
@revisions.current.add(@revisions.all[0].object(1))
|
113
230
|
@revisions.merge
|
114
231
|
assert_equal(1, @revisions.each.to_a.size)
|
115
232
|
assert_equal([10, 400, @doc.object(3).value], @revisions.current.each.to_a.sort.map(&:value))
|
116
233
|
end
|
117
234
|
end
|
118
235
|
|
119
|
-
describe "initialize" do
|
120
|
-
it "automatically loads all revisions from the underlying IO object" do
|
121
|
-
assert_kind_of(HexaPDF::Parser, @revisions.parser)
|
122
|
-
assert_equal(20, @revisions.revision(0).object(2).value)
|
123
|
-
assert_equal(300, @revisions[1].object(2).value)
|
124
|
-
assert_equal(400, @revisions[2].object(2).value)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
236
|
it "handles invalid PDFs that have a loop via the xref /Prev or /XRefStm entries" do
|
129
237
|
io = StringIO.new(<<~EOF)
|
130
238
|
%PDF-1.7
|
@@ -191,6 +299,6 @@ describe HexaPDF::Revisions do
|
|
191
299
|
EOF
|
192
300
|
doc = HexaPDF::Document.new(io: io)
|
193
301
|
assert_equal(2, doc.revisions.count)
|
194
|
-
assert_same(doc.revisions[0].trailer.value, doc.revisions[1].trailer.value)
|
302
|
+
assert_same(doc.revisions.all[0].trailer.value, doc.revisions.all[1].trailer.value)
|
195
303
|
end
|
196
304
|
end
|
@@ -101,16 +101,12 @@ describe HexaPDF::Serializer do
|
|
101
101
|
end
|
102
102
|
|
103
103
|
it "serializes time like objects" do
|
104
|
-
tz = ENV['TZ']
|
105
|
-
ENV['TZ'] = 'Europe/Vienna'
|
106
104
|
assert_serialized("(D:20150416094100)", Time.new(2015, 04, 16, 9, 41, 0, 0))
|
107
105
|
assert_serialized("(D:20150416094100+01'00')", Time.new(2015, 04, 16, 9, 41, 0, 3600))
|
108
106
|
assert_serialized("(D:20150416094100-01'20')", Time.new(2015, 04, 16, 9, 41, 0, -4800))
|
109
|
-
assert_serialized("(D:20150416000000
|
107
|
+
assert_serialized("(D:20150416000000)", Date.parse("2015-04-16 9:41:00 +02:00"))
|
110
108
|
assert_serialized("(D:20150416094100+02'00')",
|
111
109
|
Time.parse("2015-04-16 9:41:00 +02:00").to_datetime)
|
112
|
-
ensure
|
113
|
-
ENV['TZ'] = tz
|
114
110
|
end
|
115
111
|
|
116
112
|
it "serializes HexaPDF objects" do
|
data/test/hexapdf/test_writer.rb
CHANGED
@@ -40,13 +40,13 @@ 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.24.0)>>
|
44
44
|
endobj
|
45
45
|
xref
|
46
46
|
3 1
|
47
47
|
0000000296 00000 n
|
48
48
|
trailer
|
49
|
-
<</
|
49
|
+
<</Size 4/Root<</Type/Catalog>>/Info 3 0 R/Prev 219>>
|
50
50
|
startxref
|
51
51
|
349
|
52
52
|
%%EOF
|
@@ -64,7 +64,7 @@ describe HexaPDF::Writer do
|
|
64
64
|
20
|
65
65
|
endobj
|
66
66
|
3 0 obj
|
67
|
-
<</Size 6/
|
67
|
+
<</Type/XRef/Size 6/W[1 1 2]/Index[0 4 5 1]/Filter/FlateDecode/DecodeParms<</Columns 4/Predictor 12>>/Length 31>>stream
|
68
68
|
x\xDAcb`\xF8\xFF\x9F\x89\x89\x95\x91\x91\xE9\x7F\x19\x03\x03\x13\x83\x10\x88he`\x00\x00B4\x04\x1E
|
69
69
|
endstream
|
70
70
|
endobj
|
@@ -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.24.0)>>
|
76
76
|
endobj
|
77
77
|
2 0 obj
|
78
78
|
<</Length 10>>stream
|
@@ -80,7 +80,7 @@ describe HexaPDF::Writer do
|
|
80
80
|
endstream
|
81
81
|
endobj
|
82
82
|
4 0 obj
|
83
|
-
<</Size 7/
|
83
|
+
<</Type/XRef/Size 7/Root<</Type/Catalog>>/Info 6 0 R/Prev 141/W[1 2 2]/Index[2 1 4 1 6 1]/Filter/FlateDecode/DecodeParms<</Columns 5/Predictor 12>>/Length 22>>stream
|
84
84
|
x\xDAcbdlg``b`\xB0\x04\x93\x93\x18\x18\x00\f\e\x01[
|
85
85
|
endstream
|
86
86
|
endobj
|
@@ -94,8 +94,9 @@ describe HexaPDF::Writer do
|
|
94
94
|
document = HexaPDF::Document.new(io: input_io)
|
95
95
|
document.trailer.info[:Producer] = "unknown"
|
96
96
|
output_io = StringIO.new(''.force_encoding(Encoding::BINARY))
|
97
|
-
xref_section = HexaPDF::Writer.write(document, output_io)
|
97
|
+
start_xref_offset, xref_section = HexaPDF::Writer.write(document, output_io)
|
98
98
|
assert_kind_of(HexaPDF::XRefSection, xref_section)
|
99
|
+
assert_kind_of(Integer, start_xref_offset)
|
99
100
|
assert_equal(input_io.string, output_io.string)
|
100
101
|
end
|
101
102
|
|
@@ -112,7 +113,7 @@ describe HexaPDF::Writer do
|
|
112
113
|
HexaPDF::Writer.write(doc, output_io, incremental: true)
|
113
114
|
assert_equal(output_io.string[0, @std_input_io.string.length], @std_input_io.string)
|
114
115
|
doc = HexaPDF::Document.new(io: output_io)
|
115
|
-
assert_equal(4, doc.revisions.
|
116
|
+
assert_equal(4, doc.revisions.count)
|
116
117
|
assert_equal(2, doc.revisions.current.each.to_a.size)
|
117
118
|
end
|
118
119
|
|
@@ -136,29 +137,112 @@ describe HexaPDF::Writer do
|
|
136
137
|
end
|
137
138
|
end
|
138
139
|
|
140
|
+
it "moves modified objects into the last revision" do
|
141
|
+
io = StringIO.new
|
142
|
+
io2 = StringIO.new
|
143
|
+
|
144
|
+
document = HexaPDF::Document.new
|
145
|
+
document.pages.add
|
146
|
+
HexaPDF::Writer.new(document, io).write
|
147
|
+
|
148
|
+
document = HexaPDF::Document.new(io: io)
|
149
|
+
document.pages.add
|
150
|
+
HexaPDF::Writer.new(document, io2).write_incremental
|
151
|
+
|
152
|
+
document = HexaPDF::Document.new(io: io2)
|
153
|
+
document.revisions.add
|
154
|
+
document.pages.add
|
155
|
+
HexaPDF::Writer.new(document, io).write
|
156
|
+
|
157
|
+
document = HexaPDF::Document.new(io: io)
|
158
|
+
assert_equal(3, document.revisions.count)
|
159
|
+
assert_equal(1, document.revisions.all[0].object(2)[:Kids].length)
|
160
|
+
assert_equal(2, document.revisions.all[1].object(2)[:Kids].length)
|
161
|
+
assert_equal(3, document.revisions.all[2].object(2)[:Kids].length)
|
162
|
+
end
|
163
|
+
|
139
164
|
it "creates an xref stream if no xref stream is in a revision but object streams are" do
|
140
165
|
document = HexaPDF::Document.new
|
141
166
|
document.add({Type: :ObjStm})
|
142
167
|
HexaPDF::Writer.new(document, StringIO.new).write
|
143
|
-
|
168
|
+
assert_equal(:XRef, document.object(4).type)
|
144
169
|
end
|
145
170
|
|
146
171
|
it "creates an xref stream if a previous revision had one" do
|
147
172
|
document = HexaPDF::Document.new
|
148
173
|
document.pages.add
|
149
|
-
|
174
|
+
io = StringIO.new
|
175
|
+
HexaPDF::Writer.new(document, io).write
|
176
|
+
|
177
|
+
document = HexaPDF::Document.new(io: io)
|
150
178
|
document.pages.add
|
151
179
|
document.add({Type: :ObjStm})
|
152
|
-
|
180
|
+
io2 = StringIO.new
|
181
|
+
HexaPDF::Writer.new(document, io2).write_incremental
|
182
|
+
|
183
|
+
document = HexaPDF::Document.new(io: io2)
|
153
184
|
document.pages.add
|
154
|
-
io
|
155
|
-
HexaPDF::Writer.new(document, io).write
|
185
|
+
HexaPDF::Writer.new(document, io).write_incremental
|
156
186
|
|
157
187
|
document = HexaPDF::Document.new(io: io)
|
158
188
|
assert_equal(3, document.revisions.count)
|
159
|
-
assert(document.revisions[0].none? {|obj| obj.type == :XRef })
|
160
|
-
assert(document.revisions[1].one? {|obj| obj.type == :XRef })
|
161
|
-
assert(document.revisions[2].one? {|obj| obj.type == :XRef })
|
189
|
+
assert(document.revisions.all[0].none? {|obj| obj.type == :XRef })
|
190
|
+
assert(document.revisions.all[1].one? {|obj| obj.type == :XRef })
|
191
|
+
assert(document.revisions.all[2].one? {|obj| obj.type == :XRef })
|
192
|
+
end
|
193
|
+
|
194
|
+
it "doesn't create an xref stream if one was just used for an XRefStm entry" do
|
195
|
+
# The following document's structure is built like a typical MS Word created PDF
|
196
|
+
input = StringIO.new(<<~EOF.force_encoding(Encoding::BINARY))
|
197
|
+
%PDF-1.2
|
198
|
+
%\xCF\xEC\xFF\xE8\xD7\xCB\xCD
|
199
|
+
1 0 obj
|
200
|
+
<</Type/Catalog/Pages 2 0 R>>
|
201
|
+
endobj
|
202
|
+
2 0 obj
|
203
|
+
<</Type/Pages/Kids[3 0 R]/Count 1>>
|
204
|
+
endobj
|
205
|
+
3 0 obj
|
206
|
+
<</Type/Page/MediaBox[0 0 595 842]/Parent 2 0 R/Resources<<>>>>
|
207
|
+
endobj
|
208
|
+
5 0 obj
|
209
|
+
<</Producer(HexaPDF version 0.24.0)>>
|
210
|
+
endobj
|
211
|
+
4 0 obj
|
212
|
+
<</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
|
213
|
+
x\xDAcb`\xF8\xFF\x9F\x89Q\x88\x91\x91\x89A\x97\x81\x81\x89\xC1\x18D\xB4\x80\x88\xD3\f\f\x00C\xDE\x03\xCF
|
214
|
+
endstream
|
215
|
+
endobj
|
216
|
+
xref
|
217
|
+
0 6
|
218
|
+
0000000000 65535 f
|
219
|
+
0000000018 00000 n
|
220
|
+
0000000063 00000 n
|
221
|
+
0000000114 00000 n
|
222
|
+
0000000246 00000 n
|
223
|
+
0000000193 00000 n
|
224
|
+
trailer
|
225
|
+
<</Root 1 0 R/Info 5 0 R/Size 6>>
|
226
|
+
startxref
|
227
|
+
443
|
228
|
+
%%EOF
|
229
|
+
|
230
|
+
xref
|
231
|
+
0 0
|
232
|
+
trailer
|
233
|
+
<</Root 1 0 R/Info 5 0 R/Prev 443/XRefStm 246>>
|
234
|
+
startxref
|
235
|
+
629
|
236
|
+
%%EOF
|
237
|
+
EOF
|
238
|
+
|
239
|
+
document = HexaPDF::Document.new(io: input)
|
240
|
+
document.pages.add
|
241
|
+
io = StringIO.new
|
242
|
+
HexaPDF::Writer.new(document, io).write_incremental
|
243
|
+
|
244
|
+
document = HexaPDF::Document.new(io: io)
|
245
|
+
refute(document.trailer.key?(:Type))
|
162
246
|
end
|
163
247
|
|
164
248
|
it "raises an error if the class is misused and an xref section contains invalid entries" do
|
@@ -86,7 +86,8 @@ describe HexaPDF::Type::AcroForm::Form do
|
|
86
86
|
before do
|
87
87
|
@acro_form[:Fields] = [
|
88
88
|
{T: "root only", Kids: [{Subtype: :Widget}]},
|
89
|
-
{T: "children", Kids: [{T: "
|
89
|
+
{T: "children", Kids: [{T: "\xFE\xFF".b << "child".encode('UTF-16BE').b, FT: :Btn},
|
90
|
+
{T: "sub", Kids: [{T: "child"}]}]},
|
90
91
|
]
|
91
92
|
end
|
92
93
|
|