hexapdf 0.6.0 → 0.7.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 +5 -5
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTERS +1 -1
- data/LICENSE +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/hexapdf +1 -1
- data/examples/text_layouter_styling.rb +1 -2
- data/lib/hexapdf.rb +2 -2
- data/lib/hexapdf/cli.rb +3 -3
- data/lib/hexapdf/cli/batch.rb +5 -5
- data/lib/hexapdf/cli/command.rb +15 -17
- data/lib/hexapdf/cli/files.rb +3 -3
- data/lib/hexapdf/cli/images.rb +3 -4
- data/lib/hexapdf/cli/info.rb +5 -5
- data/lib/hexapdf/cli/inspect.rb +6 -6
- data/lib/hexapdf/cli/merge.rb +6 -6
- data/lib/hexapdf/cli/modify.rb +4 -4
- data/lib/hexapdf/cli/optimize.rb +3 -3
- data/lib/hexapdf/configuration.rb +4 -5
- data/lib/hexapdf/content.rb +2 -2
- data/lib/hexapdf/content/canvas.rb +35 -36
- data/lib/hexapdf/content/color_space.rb +9 -14
- data/lib/hexapdf/content/graphic_object.rb +2 -2
- data/lib/hexapdf/content/graphic_object/arc.rb +3 -3
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +4 -8
- data/lib/hexapdf/content/graphics_state.rb +4 -13
- data/lib/hexapdf/content/operator.rb +33 -35
- data/lib/hexapdf/content/parser.rb +28 -18
- data/lib/hexapdf/content/processor.rb +4 -5
- data/lib/hexapdf/content/transformation_matrix.rb +2 -2
- data/lib/hexapdf/data_dir.rb +2 -2
- data/lib/hexapdf/dictionary.rb +8 -9
- data/lib/hexapdf/dictionary_fields.rb +7 -10
- data/lib/hexapdf/document.rb +18 -18
- data/lib/hexapdf/document/files.rb +12 -10
- data/lib/hexapdf/document/fonts.rb +2 -2
- data/lib/hexapdf/document/images.rb +3 -3
- data/lib/hexapdf/document/pages.rb +4 -4
- data/lib/hexapdf/encryption.rb +2 -2
- data/lib/hexapdf/encryption/aes.rb +2 -2
- data/lib/hexapdf/encryption/arc4.rb +4 -4
- data/lib/hexapdf/encryption/fast_aes.rb +2 -2
- data/lib/hexapdf/encryption/fast_arc4.rb +4 -4
- data/lib/hexapdf/encryption/identity.rb +5 -4
- data/lib/hexapdf/encryption/ruby_aes.rb +147 -139
- data/lib/hexapdf/encryption/ruby_arc4.rb +4 -4
- data/lib/hexapdf/encryption/security_handler.rb +11 -12
- data/lib/hexapdf/encryption/standard_security_handler.rb +6 -9
- data/lib/hexapdf/error.rb +7 -9
- data/lib/hexapdf/filter.rb +2 -3
- data/lib/hexapdf/filter/ascii85_decode.rb +3 -3
- data/lib/hexapdf/filter/ascii_hex_decode.rb +2 -2
- data/lib/hexapdf/filter/dct_decode.rb +2 -2
- data/lib/hexapdf/filter/encryption.rb +2 -2
- data/lib/hexapdf/filter/flate_decode.rb +16 -33
- data/lib/hexapdf/filter/jpx_decode.rb +2 -2
- data/lib/hexapdf/filter/lzw_decode.rb +4 -4
- data/lib/hexapdf/filter/predictor.rb +2 -6
- data/lib/hexapdf/filter/run_length_decode.rb +2 -2
- data/lib/hexapdf/font/cmap.rb +2 -3
- data/lib/hexapdf/font/cmap/parser.rb +11 -11
- data/lib/hexapdf/font/cmap/writer.rb +25 -25
- data/lib/hexapdf/font/encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/base.rb +2 -2
- data/lib/hexapdf/font/encoding/difference_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/glyph_list.rb +6 -6
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/standard_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +2 -2
- data/lib/hexapdf/font/invalid_glyph.rb +7 -7
- data/lib/hexapdf/font/true_type.rb +2 -2
- data/lib/hexapdf/font/true_type/builder.rb +13 -7
- data/lib/hexapdf/font/true_type/font.rb +2 -3
- data/lib/hexapdf/font/true_type/optimizer.rb +2 -2
- data/lib/hexapdf/font/true_type/subsetter.rb +4 -4
- data/lib/hexapdf/font/true_type/table.rb +3 -5
- data/lib/hexapdf/font/true_type/table/cmap.rb +2 -2
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +9 -16
- data/lib/hexapdf/font/true_type/table/directory.rb +4 -4
- data/lib/hexapdf/font/true_type/table/glyf.rb +2 -2
- data/lib/hexapdf/font/true_type/table/head.rb +3 -2
- data/lib/hexapdf/font/true_type/table/hhea.rb +2 -2
- data/lib/hexapdf/font/true_type/table/hmtx.rb +2 -2
- data/lib/hexapdf/font/true_type/table/kern.rb +3 -3
- data/lib/hexapdf/font/true_type/table/loca.rb +3 -3
- data/lib/hexapdf/font/true_type/table/maxp.rb +2 -2
- data/lib/hexapdf/font/true_type/table/name.rb +3 -5
- data/lib/hexapdf/font/true_type/table/os2.rb +4 -3
- data/lib/hexapdf/font/true_type/table/post.rb +3 -7
- data/lib/hexapdf/font/true_type_wrapper.rb +20 -22
- data/lib/hexapdf/font/type1.rb +2 -2
- data/lib/hexapdf/font/type1/afm_parser.rb +7 -7
- data/lib/hexapdf/font/type1/character_metrics.rb +2 -2
- data/lib/hexapdf/font/type1/font.rb +3 -3
- data/lib/hexapdf/font/type1/font_metrics.rb +2 -4
- data/lib/hexapdf/font/type1/pfb_parser.rb +2 -2
- data/lib/hexapdf/font/type1_wrapper.rb +8 -9
- data/lib/hexapdf/font_loader.rb +2 -2
- data/lib/hexapdf/font_loader/from_configuration.rb +2 -2
- data/lib/hexapdf/font_loader/from_file.rb +2 -2
- data/lib/hexapdf/font_loader/standard14.rb +2 -2
- data/lib/hexapdf/image_loader.rb +2 -2
- data/lib/hexapdf/image_loader/jpeg.rb +6 -4
- data/lib/hexapdf/image_loader/pdf.rb +2 -2
- data/lib/hexapdf/image_loader/png.rb +6 -6
- data/lib/hexapdf/importer.rb +6 -4
- data/lib/hexapdf/layout.rb +2 -2
- data/lib/hexapdf/layout/box.rb +4 -4
- data/lib/hexapdf/layout/inline_box.rb +2 -2
- data/lib/hexapdf/layout/line.rb +6 -6
- data/lib/hexapdf/layout/numeric_refinements.rb +2 -2
- data/lib/hexapdf/layout/style.rb +17 -8
- data/lib/hexapdf/layout/text_fragment.rb +86 -48
- data/lib/hexapdf/layout/text_layouter.rb +40 -21
- data/lib/hexapdf/layout/text_shaper.rb +2 -2
- data/lib/hexapdf/name_tree_node.rb +2 -2
- data/lib/hexapdf/number_tree_node.rb +2 -2
- data/lib/hexapdf/object.rb +6 -8
- data/lib/hexapdf/parser.rb +10 -10
- data/lib/hexapdf/rectangle.rb +4 -4
- data/lib/hexapdf/reference.rb +2 -2
- data/lib/hexapdf/revision.rb +4 -4
- data/lib/hexapdf/revisions.rb +5 -5
- data/lib/hexapdf/serializer.rb +27 -24
- data/lib/hexapdf/stream.rb +4 -4
- data/lib/hexapdf/task.rb +2 -2
- data/lib/hexapdf/task/dereference.rb +4 -4
- data/lib/hexapdf/task/optimize.rb +5 -4
- data/lib/hexapdf/tokenizer.rb +12 -14
- data/lib/hexapdf/type.rb +2 -2
- data/lib/hexapdf/type/action.rb +3 -3
- data/lib/hexapdf/type/actions.rb +2 -2
- data/lib/hexapdf/type/actions/go_to.rb +2 -2
- data/lib/hexapdf/type/actions/go_to_r.rb +2 -2
- data/lib/hexapdf/type/actions/launch.rb +2 -2
- data/lib/hexapdf/type/actions/uri.rb +3 -3
- data/lib/hexapdf/type/annotation.rb +3 -3
- data/lib/hexapdf/type/annotations.rb +2 -2
- data/lib/hexapdf/type/annotations/link.rb +2 -2
- data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -2
- data/lib/hexapdf/type/annotations/text.rb +2 -2
- data/lib/hexapdf/type/catalog.rb +4 -4
- data/lib/hexapdf/type/cid_font.rb +4 -5
- data/lib/hexapdf/type/embedded_file.rb +3 -3
- data/lib/hexapdf/type/file_specification.rb +6 -7
- data/lib/hexapdf/type/font.rb +4 -4
- data/lib/hexapdf/type/font_descriptor.rb +3 -4
- data/lib/hexapdf/type/font_simple.rb +12 -16
- data/lib/hexapdf/type/font_true_type.rb +2 -2
- data/lib/hexapdf/type/font_type0.rb +5 -5
- data/lib/hexapdf/type/font_type1.rb +4 -4
- data/lib/hexapdf/type/form.rb +3 -3
- data/lib/hexapdf/type/graphics_state_parameter.rb +3 -3
- data/lib/hexapdf/type/image.rb +13 -14
- data/lib/hexapdf/type/info.rb +2 -2
- data/lib/hexapdf/type/names.rb +2 -2
- data/lib/hexapdf/type/object_stream.rb +5 -5
- data/lib/hexapdf/type/page.rb +9 -10
- data/lib/hexapdf/type/page_tree_node.rb +5 -6
- data/lib/hexapdf/type/resources.rb +11 -11
- data/lib/hexapdf/type/trailer.rb +3 -3
- data/lib/hexapdf/type/viewer_preferences.rb +2 -2
- data/lib/hexapdf/type/xref_stream.rb +8 -4
- data/lib/hexapdf/utils/bit_field.rb +4 -4
- data/lib/hexapdf/utils/bit_stream.rb +4 -4
- data/lib/hexapdf/utils/graphics_helpers.rb +2 -2
- data/lib/hexapdf/utils/lru_cache.rb +2 -2
- data/lib/hexapdf/utils/math_helpers.rb +2 -2
- data/lib/hexapdf/utils/object_hash.rb +3 -3
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +3 -3
- data/lib/hexapdf/utils/sorted_tree_node.rb +12 -11
- data/lib/hexapdf/version.rb +3 -3
- data/lib/hexapdf/writer.rb +8 -8
- data/lib/hexapdf/xref_section.rb +3 -3
- data/test/hexapdf/common_tokenizer_tests.rb +6 -7
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +0 -1
- data/test/hexapdf/content/test_canvas.rb +28 -36
- data/test/hexapdf/content/test_color_space.rb +4 -0
- data/test/hexapdf/content/test_graphics_state.rb +2 -0
- data/test/hexapdf/content/test_operator.rb +6 -7
- data/test/hexapdf/content/test_parser.rb +2 -2
- data/test/hexapdf/content/test_processor.rb +1 -1
- data/test/hexapdf/document/test_files.rb +1 -0
- data/test/hexapdf/document/test_images.rb +1 -1
- data/test/hexapdf/encryption/common.rb +3 -3
- data/test/hexapdf/encryption/test_aes.rb +10 -4
- data/test/hexapdf/encryption/test_identity.rb +1 -1
- data/test/hexapdf/encryption/test_security_handler.rb +13 -17
- data/test/hexapdf/encryption/test_standard_security_handler.rb +12 -12
- data/test/hexapdf/filter/test_ascii85_decode.rb +2 -3
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +6 -1
- data/test/hexapdf/filter/test_flate_decode.rb +2 -2
- data/test/hexapdf/filter/test_lzw_decode.rb +10 -10
- data/test/hexapdf/filter/test_predictor.rb +10 -2
- data/test/hexapdf/filter/test_run_length_decode.rb +1 -1
- data/test/hexapdf/font/cmap/test_parser.rb +40 -40
- data/test/hexapdf/font/cmap/test_writer.rb +29 -29
- data/test/hexapdf/font/test_true_type_wrapper.rb +3 -2
- data/test/hexapdf/font/true_type/common.rb +2 -0
- data/test/hexapdf/font/true_type/table/test_cmap.rb +1 -1
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +5 -4
- data/test/hexapdf/font/true_type/table/test_glyf.rb +2 -2
- data/test/hexapdf/font/true_type/table/test_head.rb +2 -2
- data/test/hexapdf/font/true_type/table/test_name.rb +9 -6
- data/test/hexapdf/font/true_type/test_builder.rb +8 -3
- data/test/hexapdf/font/true_type/test_optimizer.rb +1 -2
- data/test/hexapdf/font/type1/test_afm_parser.rb +2 -2
- data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
- data/test/hexapdf/image_loader/test_pdf.rb +1 -1
- data/test/hexapdf/image_loader/test_png.rb +3 -3
- data/test/hexapdf/layout/test_inline_box.rb +10 -1
- data/test/hexapdf/layout/test_line.rb +4 -4
- data/test/hexapdf/layout/test_style.rb +19 -7
- data/test/hexapdf/layout/test_text_fragment.rb +73 -27
- data/test/hexapdf/layout/test_text_layouter.rb +84 -68
- data/test/hexapdf/layout/test_text_shaper.rb +4 -6
- data/test/hexapdf/task/test_dereference.rb +2 -2
- data/test/hexapdf/task/test_optimize.rb +16 -7
- data/test/hexapdf/test_configuration.rb +1 -1
- data/test/hexapdf/test_data_dir.rb +2 -2
- data/test/hexapdf/test_dictionary.rb +6 -3
- data/test/hexapdf/test_dictionary_fields.rb +15 -14
- data/test/hexapdf/test_document.rb +47 -48
- data/test/hexapdf/test_filter.rb +30 -26
- data/test/hexapdf/test_importer.rb +14 -0
- data/test/hexapdf/test_object.rb +16 -4
- data/test/hexapdf/test_parser.rb +36 -36
- data/test/hexapdf/test_reference.rb +7 -5
- data/test/hexapdf/test_revision.rb +1 -1
- data/test/hexapdf/test_revisions.rb +90 -90
- data/test/hexapdf/test_serializer.rb +3 -2
- data/test/hexapdf/test_stream.rb +2 -4
- data/test/hexapdf/test_tokenizer.rb +2 -2
- data/test/hexapdf/test_writer.rb +80 -80
- data/test/hexapdf/test_xref_section.rb +1 -1
- data/test/hexapdf/type/annotations/test_link.rb +1 -1
- data/test/hexapdf/type/annotations/test_text.rb +3 -3
- data/test/hexapdf/type/test_font_descriptor.rb +1 -1
- data/test/hexapdf/type/test_font_simple.rb +2 -2
- data/test/hexapdf/type/test_font_type0.rb +0 -1
- data/test/hexapdf/type/test_image.rb +0 -3
- data/test/hexapdf/type/test_object_stream.rb +2 -1
- data/test/hexapdf/type/test_page.rb +5 -1
- data/test/hexapdf/type/test_page_tree_node.rb +4 -4
- data/test/hexapdf/type/test_trailer.rb +1 -1
- data/test/hexapdf/type/test_xref_stream.rb +4 -0
- data/test/hexapdf/utils/test_bit_field.rb +2 -0
- data/test/hexapdf/utils/test_bit_stream.rb +1 -1
- data/test/hexapdf/utils/test_lru_cache.rb +1 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -4
- data/test/test_helper.rb +3 -6
- metadata +3 -3
|
@@ -21,8 +21,8 @@ describe HexaPDF::Task::Dereference do
|
|
|
21
21
|
|
|
22
22
|
checker = lambda do |val, done = {}|
|
|
23
23
|
case val
|
|
24
|
-
when Array then val.all? {|v| checker.call(v, done)}
|
|
25
|
-
when Hash then val.all? {|_, v| checker.call(v, done)}
|
|
24
|
+
when Array then val.all? {|v| checker.call(v, done) }
|
|
25
|
+
when Hash then val.all? {|_, v| checker.call(v, done) }
|
|
26
26
|
when HexaPDF::Reference
|
|
27
27
|
false
|
|
28
28
|
when HexaPDF::Object
|
|
@@ -6,7 +6,9 @@ require 'hexapdf/task/optimize'
|
|
|
6
6
|
|
|
7
7
|
describe HexaPDF::Task::Optimize do
|
|
8
8
|
class TestType < HexaPDF::Dictionary
|
|
9
|
+
|
|
9
10
|
define_field :Optional, type: Symbol, default: :Optional
|
|
11
|
+
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
before do
|
|
@@ -21,20 +23,20 @@ describe HexaPDF::Task::Optimize do
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def assert_objstms_generated
|
|
24
|
-
assert(@doc.revisions.all? {|rev| rev.any? {|obj| obj.type == :ObjStm}})
|
|
25
|
-
assert(@doc.revisions.all? {|rev| rev.any? {|obj| obj.type == :XRef}})
|
|
26
|
+
assert(@doc.revisions.all? {|rev| rev.any? {|obj| obj.type == :ObjStm } })
|
|
27
|
+
assert(@doc.revisions.all? {|rev| rev.any? {|obj| obj.type == :XRef } })
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def assert_xrefstms_generated
|
|
29
|
-
assert(@doc.revisions.all? {|rev| rev.
|
|
31
|
+
assert(@doc.revisions.all? {|rev| rev.find_all {|obj| obj.type == :XRef }.size == 1 })
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def assert_no_objstms
|
|
33
|
-
assert(@doc.each(current: false).all? {|obj| obj.type != :ObjStm})
|
|
35
|
+
assert(@doc.each(current: false).all? {|obj| obj.type != :ObjStm })
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def assert_no_xrefstms
|
|
37
|
-
assert(@doc.each(current: false).all? {|obj| obj.type != :XRef})
|
|
39
|
+
assert(@doc.each(current: false).all? {|obj| obj.type != :XRef })
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
def assert_default_deleted
|
|
@@ -90,12 +92,13 @@ describe HexaPDF::Task::Optimize do
|
|
|
90
92
|
assert_objstms_generated
|
|
91
93
|
assert_default_deleted
|
|
92
94
|
assert_nil(@doc.object(objstm).value)
|
|
93
|
-
assert(3, @doc.revisions.current.find_all {|obj| obj.type == :ObjStm}.size)
|
|
94
|
-
assert([xref], @doc.revisions.current.find_all {|obj| obj.type == :XRef})
|
|
95
|
+
assert(3, @doc.revisions.current.find_all {|obj| obj.type == :ObjStm }.size)
|
|
96
|
+
assert([xref], @doc.revisions.current.find_all {|obj| obj.type == :XRef })
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
it "deletes object and xref streams" do
|
|
98
100
|
@doc.add(Type: :ObjStm)
|
|
101
|
+
@doc.add(Type: :XRef)
|
|
99
102
|
@doc.task(:optimize, object_streams: :delete, xref_streams: :delete)
|
|
100
103
|
assert_no_objstms
|
|
101
104
|
assert_no_xrefstms
|
|
@@ -118,6 +121,12 @@ describe HexaPDF::Task::Optimize do
|
|
|
118
121
|
assert_default_deleted
|
|
119
122
|
end
|
|
120
123
|
|
|
124
|
+
it "reuses an xref stream in generatation mode" do
|
|
125
|
+
@doc.add(Type: :XRef)
|
|
126
|
+
@doc.task(:optimize, xref_streams: :generate)
|
|
127
|
+
assert_xrefstms_generated
|
|
128
|
+
end
|
|
129
|
+
|
|
121
130
|
it "deletes xref streams" do
|
|
122
131
|
@doc.add(Type: :XRef)
|
|
123
132
|
@doc.task(:optimize, xref_streams: :delete)
|
|
@@ -87,7 +87,7 @@ describe HexaPDF::Configuration do
|
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
it "returns the result of the given block when no constant is found" do
|
|
90
|
-
assert_equal(:test, @config.constantize('unk') {|name| assert_equal('unk', name); :test})
|
|
90
|
+
assert_equal(:test, @config.constantize('unk') {|name| assert_equal('unk', name); :test })
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
end
|
|
@@ -19,13 +19,13 @@ describe 'HexaPDF.data_dir' do
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it "returns the global data directory if the local one isn't found" do
|
|
22
|
-
File.stub(:directory?, lambda {|path| path
|
|
22
|
+
File.stub(:directory?, lambda {|path| path != @local }) do
|
|
23
23
|
assert_equal(@global, HexaPDF.data_dir)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "fails if no data directory is found" do
|
|
28
|
-
File.stub(:directory?, lambda {|_path| false}) do
|
|
28
|
+
File.stub(:directory?, lambda {|_path| false }) do
|
|
29
29
|
assert_raises { HexaPDF.data_dir }
|
|
30
30
|
end
|
|
31
31
|
end
|
|
@@ -62,7 +62,7 @@ describe HexaPDF::Dictionary do
|
|
|
62
62
|
it "can iterate over all fields" do
|
|
63
63
|
@inherited_class = Class.new(@test_class)
|
|
64
64
|
@inherited_class.define_field(:Inherited, type: [Array, Symbol])
|
|
65
|
-
assert_equal([:Boolean, :Array, :TestClass, :Inherited], @inherited_class.each_field.map {|k, _| k})
|
|
65
|
+
assert_equal([:Boolean, :Array, :TestClass, :Inherited], @inherited_class.each_field.map {|k, _| k })
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
it "allows field access without subclassing" do
|
|
@@ -149,7 +149,7 @@ describe HexaPDF::Dictionary do
|
|
|
149
149
|
assert_equal(7, @dict.value[:NewValue])
|
|
150
150
|
end
|
|
151
151
|
|
|
152
|
-
it "stores the value
|
|
152
|
+
it "stores the value in an existing HexaPDF::Object but only if it is not such an object" do
|
|
153
153
|
@dict[:Object] = [4, 5]
|
|
154
154
|
assert_equal([4, 5], @dict.value[:Object].value)
|
|
155
155
|
|
|
@@ -256,7 +256,10 @@ describe HexaPDF::Dictionary do
|
|
|
256
256
|
end
|
|
257
257
|
|
|
258
258
|
it "validates direct PDF objects nested in hashes" do
|
|
259
|
-
@obj[:TestClass] = {
|
|
259
|
+
@obj[:TestClass] = {
|
|
260
|
+
Inherited: :symbol,
|
|
261
|
+
Nested: {Nested: {TestClass: @test_class.new(nil, document: self)}},
|
|
262
|
+
}
|
|
260
263
|
refute(@obj.validate)
|
|
261
264
|
@obj[:TestClass][:Nested][:Nested][:TestClass][:Inherited] = :symbol
|
|
262
265
|
assert(@obj.validate)
|
|
@@ -123,20 +123,21 @@ describe HexaPDF::DictionaryFields do
|
|
|
123
123
|
refute(@field.convert?('test'.b))
|
|
124
124
|
assert(@field.convert?(date))
|
|
125
125
|
|
|
126
|
-
[
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
126
|
+
[
|
|
127
|
+
["D:1998", [1998, 01, 01, 00, 00, 00, "-00:00"]],
|
|
128
|
+
["D:199812", [1998, 12, 01, 00, 00, 00, "-00:00"]],
|
|
129
|
+
["D:19981223", [1998, 12, 23, 00, 00, 00, "-00:00"]],
|
|
130
|
+
["D:1998122319", [1998, 12, 23, 19, 00, 00, "+00:00"]],
|
|
131
|
+
["D:199812231952", [1998, 12, 23, 19, 52, 00, "+00:00"]],
|
|
132
|
+
["D:19981223195210", [1998, 12, 23, 19, 52, 10, "+00:00"]],
|
|
133
|
+
["D:19981223195210-08'00'", [1998, 12, 23, 19, 52, 10, "-08:00"]],
|
|
134
|
+
["D:1998122319-08'00'", [1998, 12, 23, 19, 00, 00, "-08:00"]],
|
|
135
|
+
["D:19981223-08'00'", [1998, 12, 23, 00, 00, 00, "-08:00"]],
|
|
136
|
+
["D:199812-08'00'", [1998, 12, 01, 00, 00, 00, "-08:00"]],
|
|
137
|
+
["D:1998-08'00'", [1998, 01, 01, 00, 00, 00, "-08:00"]],
|
|
138
|
+
["D:19981223195210-08", [1998, 12, 23, 19, 52, 10, "-08:00"]], # non-standard, missing '
|
|
139
|
+
["D:19981223195210-08'00", [1998, 12, 23, 19, 52, 10, "-08:00"]], # non-standard, missing '
|
|
140
|
+
].each do |str, data|
|
|
140
141
|
obj = @field.convert(str, self)
|
|
141
142
|
assert_equal(Time.new(*data), obj, "date str used: #{str}")
|
|
142
143
|
end
|
|
@@ -7,46 +7,46 @@ require 'stringio'
|
|
|
7
7
|
|
|
8
8
|
describe HexaPDF::Document do
|
|
9
9
|
before do
|
|
10
|
-
@io = StringIO.new(
|
|
11
|
-
%PDF-1.7
|
|
12
|
-
1 0 obj
|
|
13
|
-
10
|
|
14
|
-
endobj
|
|
15
|
-
|
|
16
|
-
2 0 obj
|
|
17
|
-
20
|
|
18
|
-
endobj
|
|
19
|
-
|
|
20
|
-
3 0 obj
|
|
21
|
-
30
|
|
22
|
-
endobj
|
|
23
|
-
|
|
24
|
-
xref
|
|
25
|
-
0 4
|
|
26
|
-
0000000000 65535 f
|
|
27
|
-
0000000009 00000 n
|
|
28
|
-
0000000028 00000 n
|
|
29
|
-
0000000047 00000 n
|
|
30
|
-
trailer
|
|
31
|
-
<< /Size 4 >>
|
|
32
|
-
startxref
|
|
33
|
-
66
|
|
34
|
-
%%EOF
|
|
35
|
-
|
|
36
|
-
2 0 obj
|
|
37
|
-
200
|
|
38
|
-
endobj
|
|
39
|
-
|
|
40
|
-
xref
|
|
41
|
-
2 2
|
|
42
|
-
0000000197 00000 n
|
|
43
|
-
0000000000 00001 f
|
|
44
|
-
trailer
|
|
45
|
-
<< /Size 4 /Prev 66 >>
|
|
46
|
-
startxref
|
|
47
|
-
217
|
|
48
|
-
%%EOF
|
|
49
|
-
EOF
|
|
10
|
+
@io = StringIO.new(<<~EOF)
|
|
11
|
+
%PDF-1.7
|
|
12
|
+
1 0 obj
|
|
13
|
+
10
|
|
14
|
+
endobj
|
|
15
|
+
|
|
16
|
+
2 0 obj
|
|
17
|
+
20
|
|
18
|
+
endobj
|
|
19
|
+
|
|
20
|
+
3 0 obj
|
|
21
|
+
30
|
|
22
|
+
endobj
|
|
23
|
+
|
|
24
|
+
xref
|
|
25
|
+
0 4
|
|
26
|
+
0000000000 65535 f
|
|
27
|
+
0000000009 00000 n
|
|
28
|
+
0000000028 00000 n
|
|
29
|
+
0000000047 00000 n
|
|
30
|
+
trailer
|
|
31
|
+
<< /Size 4 >>
|
|
32
|
+
startxref
|
|
33
|
+
66
|
|
34
|
+
%%EOF
|
|
35
|
+
|
|
36
|
+
2 0 obj
|
|
37
|
+
200
|
|
38
|
+
endobj
|
|
39
|
+
|
|
40
|
+
xref
|
|
41
|
+
2 2
|
|
42
|
+
0000000197 00000 n
|
|
43
|
+
0000000000 00001 f
|
|
44
|
+
trailer
|
|
45
|
+
<< /Size 4 /Prev 66 >>
|
|
46
|
+
startxref
|
|
47
|
+
217
|
|
48
|
+
%%EOF
|
|
49
|
+
EOF
|
|
50
50
|
@io_doc = HexaPDF::Document.new(io: @io)
|
|
51
51
|
@doc = HexaPDF::Document.new
|
|
52
52
|
end
|
|
@@ -195,7 +195,7 @@ EOF
|
|
|
195
195
|
assert_raises(HexaPDF::Error) { @doc.add(obj) }
|
|
196
196
|
end
|
|
197
197
|
|
|
198
|
-
it "fails if the object number
|
|
198
|
+
it "fails if the object number is already associated with another object" do
|
|
199
199
|
obj = @doc.add(5)
|
|
200
200
|
assert_raises(HexaPDF::Error) { @doc.add(@doc.wrap(5, oid: obj.oid, gen: 1)) }
|
|
201
201
|
end
|
|
@@ -395,7 +395,7 @@ EOF
|
|
|
395
395
|
|
|
396
396
|
it "yields the revision as second argument if the block accepts exactly two arguments" do
|
|
397
397
|
objs = [[10, 20, 30], [200, nil]]
|
|
398
|
-
data = @io_doc.revisions.map.with_index {|rev, i| objs[i].map {|o| [o, rev]}}.reverse.flatten
|
|
398
|
+
data = @io_doc.revisions.map.with_index {|rev, i| objs[i].map {|o| [o, rev] } }.reverse.flatten
|
|
399
399
|
@io_doc.each(current: false) do |obj, rev|
|
|
400
400
|
assert(data.shift == obj.value)
|
|
401
401
|
assert_equal(data.shift, rev)
|
|
@@ -450,7 +450,6 @@ EOF
|
|
|
450
450
|
end
|
|
451
451
|
end
|
|
452
452
|
|
|
453
|
-
|
|
454
453
|
describe "write" do
|
|
455
454
|
it "writes the document to a file" do
|
|
456
455
|
begin
|
|
@@ -498,14 +497,14 @@ EOF
|
|
|
498
497
|
io = StringIO.new(''.b)
|
|
499
498
|
@io_doc.write(io)
|
|
500
499
|
doc = HexaPDF::Document.new(io: io)
|
|
501
|
-
assert_equal(0, doc.each.count {|o| o.type == :ObjStm})
|
|
500
|
+
assert_equal(0, doc.each.count {|o| o.type == :ObjStm })
|
|
502
501
|
end
|
|
503
502
|
|
|
504
503
|
it "allows optimizing the file by using object streams" do
|
|
505
504
|
io = StringIO.new(''.b)
|
|
506
505
|
@io_doc.write(io, optimize: true)
|
|
507
506
|
doc = HexaPDF::Document.new(io: io)
|
|
508
|
-
assert_equal(2, doc.each.count {|o| o.type == :ObjStm})
|
|
507
|
+
assert_equal(2, doc.each.count {|o| o.type == :ObjStm })
|
|
509
508
|
end
|
|
510
509
|
end
|
|
511
510
|
|
|
@@ -547,7 +546,7 @@ EOF
|
|
|
547
546
|
assert_equal(doc, @doc)
|
|
548
547
|
block.call('inside')
|
|
549
548
|
end
|
|
550
|
-
assert_equal(:done, @doc.task(:test) {|msg| assert_equal('inside', msg); :done})
|
|
549
|
+
assert_equal(:done, @doc.task(:test) {|msg| assert_equal('inside', msg); :done })
|
|
551
550
|
end
|
|
552
551
|
|
|
553
552
|
it "fails if the given task is not available" do
|
|
@@ -558,9 +557,9 @@ EOF
|
|
|
558
557
|
describe "listener interface" do
|
|
559
558
|
it "allows registering and dispatching messages" do
|
|
560
559
|
args = []
|
|
561
|
-
callable = lambda {|*a| args << [:callable, a]}
|
|
560
|
+
callable = lambda {|*a| args << [:callable, a] }
|
|
562
561
|
@doc.register_listener(:something, callable)
|
|
563
|
-
@doc.register_listener(:something) {|*a| args << [:block, a]}
|
|
562
|
+
@doc.register_listener(:something) {|*a| args << [:block, a] }
|
|
564
563
|
@doc.dispatch_message(:something, :arg)
|
|
565
564
|
assert_equal([[:callable, [:arg]], [:block, [:arg]]], args)
|
|
566
565
|
end
|
data/test/hexapdf/test_filter.rb
CHANGED
|
@@ -29,32 +29,34 @@ describe HexaPDF::Filter do
|
|
|
29
29
|
@io = StringIO.new(@str.dup)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
def from_io(**opts)
|
|
33
|
+
collector(@obj.source_from_io(@io, **opts))
|
|
34
|
+
end
|
|
35
|
+
|
|
32
36
|
it "converts an IO into a source via #source_from_io" do
|
|
33
|
-
assert_equal(@str,
|
|
37
|
+
assert_equal(@str, from_io)
|
|
34
38
|
|
|
35
|
-
assert_equal(@str,
|
|
36
|
-
assert_equal(@str[10..-1],
|
|
37
|
-
assert_equal("",
|
|
39
|
+
assert_equal(@str, from_io(pos: -10))
|
|
40
|
+
assert_equal(@str[10..-1], from_io(pos: 10))
|
|
41
|
+
assert_equal("", from_io(pos: 200))
|
|
38
42
|
|
|
39
|
-
assert_equal("",
|
|
40
|
-
assert_equal(@str[0...100],
|
|
41
|
-
assert_equal(@str,
|
|
43
|
+
assert_equal("", from_io(length: 0))
|
|
44
|
+
assert_equal(@str[0...100], from_io(length: 100))
|
|
45
|
+
assert_equal(@str, from_io(length: -15))
|
|
42
46
|
assert_equal(100, @obj.source_from_io(@io, length: 100).length)
|
|
43
47
|
|
|
44
|
-
assert_equal(@str,
|
|
45
|
-
assert_equal(@str,
|
|
46
|
-
assert_equal(@str,
|
|
47
|
-
assert_equal(@str,
|
|
48
|
+
assert_equal(@str, from_io(chunk_size: -15))
|
|
49
|
+
assert_equal(@str, from_io(chunk_size: 0))
|
|
50
|
+
assert_equal(@str, from_io(chunk_size: 100))
|
|
51
|
+
assert_equal(@str, from_io(chunk_size: 200))
|
|
48
52
|
|
|
49
|
-
assert_equal(@str[0...20],
|
|
50
|
-
assert_equal(@str[20...40],
|
|
51
|
-
assert_equal(@str[20...40],
|
|
53
|
+
assert_equal(@str[0...20], from_io(length: 20, chunk_size: 100))
|
|
54
|
+
assert_equal(@str[20...40], from_io(pos: 20, length: 20, chunk_size: 100))
|
|
55
|
+
assert_equal(@str[20...40], from_io(pos: 20, length: 20, chunk_size: 5))
|
|
52
56
|
end
|
|
53
57
|
|
|
54
58
|
it "fails if not all requested bytes could be read" do
|
|
55
|
-
assert_raises(HexaPDF::FilterError)
|
|
56
|
-
collector(@obj.source_from_io(@io, length: 200))
|
|
57
|
-
end
|
|
59
|
+
assert_raises(HexaPDF::FilterError) { from_io(length: 200) }
|
|
58
60
|
end
|
|
59
61
|
end
|
|
60
62
|
|
|
@@ -69,21 +71,23 @@ describe HexaPDF::Filter do
|
|
|
69
71
|
@file.unlink
|
|
70
72
|
end
|
|
71
73
|
|
|
74
|
+
def from_file(**opts)
|
|
75
|
+
@obj.source_from_file(@file.path, **opts)
|
|
76
|
+
end
|
|
77
|
+
|
|
72
78
|
it "converts the file into a source fiber" do
|
|
73
|
-
assert_equal(@str, collector(
|
|
74
|
-
assert_equal(@file.size,
|
|
79
|
+
assert_equal(@str, collector(from_file))
|
|
80
|
+
assert_equal(@file.size, from_file.length)
|
|
75
81
|
|
|
76
|
-
assert_equal(@str[100..-1], collector(
|
|
77
|
-
assert_equal(@str[100..-1].length,
|
|
82
|
+
assert_equal(@str[100..-1], collector(from_file(pos: 100)))
|
|
83
|
+
assert_equal(@str[100..-1].length, from_file(pos: 100).length)
|
|
78
84
|
|
|
79
|
-
assert_equal(@str[50
|
|
80
|
-
assert_equal(50,
|
|
85
|
+
assert_equal(@str[50..99], collector(from_file(pos: 50, length: 50)))
|
|
86
|
+
assert_equal(50, from_file(length: 50).length)
|
|
81
87
|
end
|
|
82
88
|
|
|
83
89
|
it "fails if more bytes are requested than stored in the file" do
|
|
84
|
-
assert_raises(HexaPDF::FilterError)
|
|
85
|
-
collector(@obj.source_from_file(@file.path, length: 200))
|
|
86
|
-
end
|
|
90
|
+
assert_raises(HexaPDF::FilterError) { collector(from_file(length: 200)) }
|
|
87
91
|
end
|
|
88
92
|
end
|
|
89
93
|
|
|
@@ -4,6 +4,14 @@ require 'test_helper'
|
|
|
4
4
|
require 'hexapdf/importer'
|
|
5
5
|
require 'hexapdf/document'
|
|
6
6
|
|
|
7
|
+
describe HexaPDF::Importer::NullableWeakRef do
|
|
8
|
+
it "returns nil instead of an error when the referred-to object is GCed" do
|
|
9
|
+
obj = HexaPDF::Importer::NullableWeakRef.new(Object.new)
|
|
10
|
+
GC.start
|
|
11
|
+
assert_equal("", obj.to_s)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
7
15
|
describe HexaPDF::Importer do
|
|
8
16
|
before do
|
|
9
17
|
@source = HexaPDF::Document.new
|
|
@@ -63,6 +71,12 @@ describe HexaPDF::Importer do
|
|
|
63
71
|
assert_equal(["one", "two"], @obj[:array])
|
|
64
72
|
end
|
|
65
73
|
|
|
74
|
+
it "duplicates the stream if it is a string" do
|
|
75
|
+
src_obj = @source.add({}, stream: 'data')
|
|
76
|
+
dst_obj = @importer.import(src_obj)
|
|
77
|
+
refute_same(dst_obj.data.stream, src_obj.data.stream)
|
|
78
|
+
end
|
|
79
|
+
|
|
66
80
|
it "does not import objects of type Catalog or Pages" do
|
|
67
81
|
@obj[:catalog] = @source.catalog
|
|
68
82
|
@obj[:pages] = @source.catalog.pages
|
data/test/hexapdf/test_object.rb
CHANGED
|
@@ -91,6 +91,11 @@ describe HexaPDF::Object do
|
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
it "returns the document or raises an error if none is set" do
|
|
95
|
+
assert_equal(:document, HexaPDF::Object.new(nil, document: :document).document)
|
|
96
|
+
assert_raises(HexaPDF::Error) { HexaPDF::Object.new(nil).document }
|
|
97
|
+
end
|
|
98
|
+
|
|
94
99
|
describe "null?" do
|
|
95
100
|
it "works for nil values" do
|
|
96
101
|
assert(HexaPDF::Object.new(nil).null?)
|
|
@@ -105,7 +110,7 @@ describe HexaPDF::Object do
|
|
|
105
110
|
invoked[:method] = true
|
|
106
111
|
block.call("error", true)
|
|
107
112
|
end
|
|
108
|
-
assert(obj.validate {|*a| invoked[:block] = a})
|
|
113
|
+
assert(obj.validate {|*a| invoked[:block] = a })
|
|
109
114
|
assert_equal([:method, :block], invoked.keys)
|
|
110
115
|
assert_equal(["error", true], invoked[:block])
|
|
111
116
|
|
|
@@ -120,7 +125,7 @@ describe HexaPDF::Object do
|
|
|
120
125
|
block.call("error", false)
|
|
121
126
|
invoked[:after] = true
|
|
122
127
|
end
|
|
123
|
-
refute(obj.validate {|*a| invoked[:block] = a})
|
|
128
|
+
refute(obj.validate {|*a| invoked[:block] = a })
|
|
124
129
|
refute(invoked.key?(:after))
|
|
125
130
|
end
|
|
126
131
|
end
|
|
@@ -150,11 +155,12 @@ describe HexaPDF::Object do
|
|
|
150
155
|
assert_equal(:two, hash[HexaPDF::Object.new(:data, oid: 2)])
|
|
151
156
|
end
|
|
152
157
|
|
|
153
|
-
it "
|
|
158
|
+
it "is sortable w.r.t to other objects implementing #oid and #gen, like Reference" do
|
|
154
159
|
a = HexaPDF::Object.new(:data, oid: 1)
|
|
155
160
|
b = HexaPDF::Object.new(:data, oid: 1, gen: 1)
|
|
156
161
|
c = HexaPDF::Reference.new(5, 7)
|
|
157
162
|
assert_equal([a, b, c], [b, c, a].sort)
|
|
163
|
+
assert_nil(HexaPDF::Object.new(:data, oid: 1) <=> 5)
|
|
158
164
|
end
|
|
159
165
|
|
|
160
166
|
describe "deep_copy" do
|
|
@@ -165,12 +171,18 @@ describe HexaPDF::Object do
|
|
|
165
171
|
assert_equal(copy.value, obj.value)
|
|
166
172
|
refute_same(copy.value[:a], obj.value[:a])
|
|
167
173
|
end
|
|
174
|
+
|
|
175
|
+
it "duplicates the stream if it is a string" do
|
|
176
|
+
obj = HexaPDF::Object.new(nil, stream: "data")
|
|
177
|
+
copy = obj.deep_copy
|
|
178
|
+
refute_same(copy.data.stream, obj.data.stream)
|
|
179
|
+
end
|
|
168
180
|
end
|
|
169
181
|
|
|
170
182
|
describe "validation" do
|
|
171
183
|
before do
|
|
172
184
|
@doc = Object.new
|
|
173
|
-
@doc.define_singleton_method(:add) {|obj| obj.oid = 1}
|
|
185
|
+
@doc.define_singleton_method(:add) {|obj| obj.oid = 1 }
|
|
174
186
|
end
|
|
175
187
|
|
|
176
188
|
it "validates that the object is indirect if it must be indirect" do
|