hexapdf 0.30.0 → 0.32.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 +54 -1
- data/LICENSE +1 -1
- data/examples/020-column_box.rb +10 -11
- data/examples/021-list_box.rb +5 -5
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +17 -2
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +1 -1
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +10 -2
- data/lib/hexapdf/cli/inspect.rb +3 -3
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +1 -1
- 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 +97 -29
- data/lib/hexapdf/configuration.rb +18 -5
- 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 +1 -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 +1 -1
- data/lib/hexapdf/digital_signature/cms_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/handler.rb +1 -1
- data/lib/hexapdf/digital_signature/pkcs1_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signature.rb +1 -1
- data/lib/hexapdf/digital_signature/signatures.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signing.rb +1 -1
- data/lib/hexapdf/digital_signature/verification_result.rb +1 -1
- data/lib/hexapdf/digital_signature.rb +1 -1
- data/lib/hexapdf/document/destinations.rb +1 -1
- 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 +122 -39
- data/lib/hexapdf/document/pages.rb +2 -6
- data/lib/hexapdf/document.rb +9 -2
- data/lib/hexapdf/encryption/aes.rb +3 -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 +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 +4 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/error.rb +12 -2
- 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 +21 -9
- 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 +1 -1
- 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 +1 -1
- data/lib/hexapdf/layout/box_fitter.rb +1 -1
- data/lib/hexapdf/layout/column_box.rb +1 -1
- data/lib/hexapdf/layout/frame.rb +1 -1
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/inline_box.rb +17 -3
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/list_box.rb +1 -1
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/page_style.rb +144 -0
- data/lib/hexapdf/layout/style.rb +1 -1
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +4 -7
- data/lib/hexapdf/layout/text_shaper.rb +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/layout.rb +2 -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 -1
- 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 +1 -1
- 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 +9 -7
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/test_utils.rb +1 -1
- data/lib/hexapdf/tokenizer.rb +2 -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 +1 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
- 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 +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 +1 -1
- 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 +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 +1 -1
- data/lib/hexapdf/type/object_stream.rb +8 -3
- data/lib/hexapdf/type/outline.rb +2 -2
- data/lib/hexapdf/type/outline_item.rb +11 -2
- data/lib/hexapdf/type/page.rb +36 -9
- 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 +1 -1
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +12 -5
- 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 +1 -1
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +2 -2
- data/lib/hexapdf/xref_section.rb +1 -1
- data/lib/hexapdf.rb +1 -1
- data/test/hexapdf/document/test_layout.rb +80 -17
- data/test/hexapdf/encryption/common.rb +4 -0
- data/test/hexapdf/encryption/test_aes.rb +8 -0
- data/test/hexapdf/encryption/test_security_handler.rb +6 -0
- data/test/hexapdf/filter/test_flate_decode.rb +19 -5
- data/test/hexapdf/layout/test_inline_box.rb +35 -15
- data/test/hexapdf/layout/test_page_style.rb +70 -0
- data/test/hexapdf/layout/test_text_box.rb +5 -2
- data/test/hexapdf/layout/test_text_layouter.rb +6 -11
- data/test/hexapdf/task/test_optimize.rb +11 -9
- data/test/hexapdf/test_composer.rb +49 -11
- data/test/hexapdf/test_tokenizer.rb +5 -0
- data/test/hexapdf/test_writer.rb +5 -5
- data/test/hexapdf/type/test_object_stream.rb +16 -7
- data/test/hexapdf/type/test_outline.rb +3 -1
- data/test/hexapdf/type/test_outline_item.rb +21 -1
- data/test/hexapdf/type/test_page.rb +58 -11
- data/test/hexapdf/type/test_xref_stream.rb +6 -1
- metadata +4 -2
|
@@ -139,12 +139,15 @@ describe HexaPDF::Layout::TextBox do
|
|
|
139
139
|
assert_operators(@canvas.contents, [[:save_graphics_state],
|
|
140
140
|
[:restore_graphics_state],
|
|
141
141
|
[:save_graphics_state],
|
|
142
|
-
[:
|
|
142
|
+
[:concatenate_matrix, [1, 0, 0, 1, 5, 10]],
|
|
143
|
+
[:save_graphics_state],
|
|
144
|
+
[:append_rectangle, [0, 0, 10, 10]],
|
|
143
145
|
[:clip_path_non_zero],
|
|
144
146
|
[:end_path],
|
|
145
|
-
[:append_rectangle, [
|
|
147
|
+
[:append_rectangle, [0.5, 0.5, 9.0, 9.0]],
|
|
146
148
|
[:stroke_path],
|
|
147
149
|
[:restore_graphics_state],
|
|
150
|
+
[:restore_graphics_state],
|
|
148
151
|
[:save_graphics_state],
|
|
149
152
|
[:restore_graphics_state]])
|
|
150
153
|
end
|
|
@@ -7,13 +7,13 @@ require 'hexapdf/document'
|
|
|
7
7
|
module TestTextLayouterHelpers
|
|
8
8
|
def boxes(*dims)
|
|
9
9
|
dims.map do |width, height|
|
|
10
|
-
box = HexaPDF::Layout::InlineBox.create(width: width, height: height ||
|
|
10
|
+
box = HexaPDF::Layout::InlineBox.create(width: width, height: height || 10) {}
|
|
11
11
|
HexaPDF::Layout::TextLayouter::Box.new(box)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def glue(width)
|
|
16
|
-
HexaPDF::Layout::TextLayouter::Glue.new(HexaPDF::Layout::InlineBox.create(width: width) {})
|
|
16
|
+
HexaPDF::Layout::TextLayouter::Glue.new(HexaPDF::Layout::InlineBox.create(width: width, height: 10) {})
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def penalty(penalty, item = nil)
|
|
@@ -136,16 +136,8 @@ describe HexaPDF::Layout::TextLayouter::SimpleTextSegmentation do
|
|
|
136
136
|
[1, 3, 5, 7, 9, 11, 13, 17, 19].each do |index|
|
|
137
137
|
assert_penalty(result[index],
|
|
138
138
|
HexaPDF::Layout::TextLayouter::Penalty::PARAGRAPH_BREAK)
|
|
139
|
-
assert_equal([], result[index].item.items)
|
|
140
|
-
assert(result[index].item.items.frozen?)
|
|
141
|
-
assert_same(frag.style, result[index].item.style)
|
|
142
|
-
assert_equal(frag.properties, result[index].item.properties)
|
|
143
139
|
end
|
|
144
140
|
assert_penalty(result[15], HexaPDF::Layout::TextLayouter::Penalty::LINE_BREAK)
|
|
145
|
-
assert_equal([], result[15].item.items)
|
|
146
|
-
assert(result[15].item.items.frozen?)
|
|
147
|
-
assert_same(frag.style, result[15].item.style)
|
|
148
|
-
assert_equal(frag.properties, result[15].item.properties)
|
|
149
141
|
end
|
|
150
142
|
|
|
151
143
|
it "insert a standard penalty after a hyphen" do
|
|
@@ -624,7 +616,7 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
624
616
|
|
|
625
617
|
describe "horizontal alignment" do
|
|
626
618
|
before do
|
|
627
|
-
@items = boxes(*[[20, 20]] * 4) + [glue(10), penalty(-5000
|
|
619
|
+
@items = boxes(*[[20, 20]] * 4) + [glue(10), penalty(-5000)]
|
|
628
620
|
end
|
|
629
621
|
|
|
630
622
|
it "aligns the contents to the left" do
|
|
@@ -789,8 +781,11 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
789
781
|
[:restore_graphics_state],
|
|
790
782
|
[:save_graphics_state],
|
|
791
783
|
[:concatenate_matrix, [1, 0, 0, 1, 10, -40]],
|
|
784
|
+
[:save_graphics_state],
|
|
785
|
+
[:concatenate_matrix, [1, 0, 0, 1, 0, 0]],
|
|
792
786
|
[:set_line_width, [2]],
|
|
793
787
|
[:restore_graphics_state],
|
|
788
|
+
[:restore_graphics_state],
|
|
794
789
|
[:save_graphics_state],
|
|
795
790
|
[:restore_graphics_state]])
|
|
796
791
|
end
|
|
@@ -81,8 +81,10 @@ describe HexaPDF::Task::Optimize do
|
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
it "compacts and deletes xref streams" do
|
|
84
|
-
@doc.revisions.all[0].add(@doc.wrap({
|
|
85
|
-
|
|
84
|
+
@doc.revisions.all[0].add(@doc.wrap({}, type: HexaPDF::Type::XRefStream,
|
|
85
|
+
oid: @doc.revisions.next_oid))
|
|
86
|
+
@doc.revisions.all[1].add(@doc.wrap({}, type: HexaPDF::Type::XRefStream,
|
|
87
|
+
oid: @doc.revisions.next_oid))
|
|
86
88
|
@doc.task(:optimize, compact: true, xref_streams: :delete)
|
|
87
89
|
assert_no_xrefstms
|
|
88
90
|
assert_default_deleted
|
|
@@ -92,8 +94,8 @@ describe HexaPDF::Task::Optimize do
|
|
|
92
94
|
describe "object_streams" do
|
|
93
95
|
def reload_document_with_objstm_from_io
|
|
94
96
|
io = StringIO.new
|
|
95
|
-
objstm = @doc.add({
|
|
96
|
-
@doc.add({
|
|
97
|
+
objstm = @doc.add({}, type: HexaPDF::Type::ObjectStream)
|
|
98
|
+
@doc.add({}, type: HexaPDF::Type::XRefStream)
|
|
97
99
|
objstm.add_object(@doc.add({Type: :Test}))
|
|
98
100
|
@doc.write(io)
|
|
99
101
|
io.rewind
|
|
@@ -102,7 +104,7 @@ describe HexaPDF::Task::Optimize do
|
|
|
102
104
|
|
|
103
105
|
it "generates object streams" do
|
|
104
106
|
210.times { @doc.add(5) }
|
|
105
|
-
objstm = @doc.add({
|
|
107
|
+
objstm = @doc.add({}, type: HexaPDF::Type::ObjectStream)
|
|
106
108
|
reload_document_with_objstm_from_io
|
|
107
109
|
@doc.task(:optimize, object_streams: :generate)
|
|
108
110
|
assert_objstms_generated
|
|
@@ -122,8 +124,8 @@ describe HexaPDF::Task::Optimize do
|
|
|
122
124
|
end
|
|
123
125
|
|
|
124
126
|
it "deletes object and generates xref streams" do
|
|
125
|
-
@doc.add({
|
|
126
|
-
xref = @doc.add({
|
|
127
|
+
@doc.add({}, type: HexaPDF::Type::ObjectStream)
|
|
128
|
+
xref = @doc.add({}, type: HexaPDF::Type::XRefStream)
|
|
127
129
|
@doc.task(:optimize, object_streams: :delete, xref_streams: :generate)
|
|
128
130
|
assert_no_objstms
|
|
129
131
|
assert_xrefstms_generated
|
|
@@ -140,13 +142,13 @@ describe HexaPDF::Task::Optimize do
|
|
|
140
142
|
end
|
|
141
143
|
|
|
142
144
|
it "reuses an xref stream in generatation mode" do
|
|
143
|
-
@doc.add({
|
|
145
|
+
@doc.add({}, type: HexaPDF::Type::XRefStream)
|
|
144
146
|
@doc.task(:optimize, xref_streams: :generate)
|
|
145
147
|
assert_xrefstms_generated
|
|
146
148
|
end
|
|
147
149
|
|
|
148
150
|
it "deletes xref streams" do
|
|
149
|
-
@doc.add({
|
|
151
|
+
@doc.add({}, type: HexaPDF::Type::XRefStream)
|
|
150
152
|
@doc.task(:optimize, xref_streams: :delete)
|
|
151
153
|
assert_no_xrefstms
|
|
152
154
|
assert_default_deleted
|
|
@@ -39,6 +39,14 @@ describe HexaPDF::Composer do
|
|
|
39
39
|
assert_equal(682, composer.frame.height)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
it "allows skipping the initial page creation" do
|
|
43
|
+
composer = HexaPDF::Composer.new(skip_page_creation: true)
|
|
44
|
+
assert_nil(composer.page)
|
|
45
|
+
assert_nil(composer.canvas)
|
|
46
|
+
assert_nil(composer.frame)
|
|
47
|
+
assert_nil(composer.page_style(:default))
|
|
48
|
+
end
|
|
49
|
+
|
|
42
50
|
it "yields itself" do
|
|
43
51
|
yielded = nil
|
|
44
52
|
composer = HexaPDF::Composer.new {|c| yielded = c }
|
|
@@ -56,7 +64,7 @@ describe HexaPDF::Composer do
|
|
|
56
64
|
end
|
|
57
65
|
|
|
58
66
|
describe "new_page" do
|
|
59
|
-
it "creates a new page
|
|
67
|
+
it "creates a new page" do
|
|
60
68
|
c = HexaPDF::Composer.new(page_size: [0, 0, 50, 100], margin: 10)
|
|
61
69
|
c.new_page
|
|
62
70
|
assert_equal([0, 0, 50, 100], c.page.box.value)
|
|
@@ -64,16 +72,33 @@ describe HexaPDF::Composer do
|
|
|
64
72
|
assert_equal(10, c.frame.bottom)
|
|
65
73
|
end
|
|
66
74
|
|
|
67
|
-
it "uses the
|
|
68
|
-
@composer.
|
|
69
|
-
|
|
70
|
-
assert_equal(
|
|
71
|
-
|
|
75
|
+
it "uses the named page style for the new page" do
|
|
76
|
+
@composer.page_style(:other, page_size: [0, 0, 100, 100])
|
|
77
|
+
@composer.new_page(:other)
|
|
78
|
+
assert_equal([0, 0, 100, 100], @composer.page.box.value)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "sets the next page's style to the next_style value of the used page style" do
|
|
82
|
+
@composer.page_style(:one, page_size: [0, 0, 1, 1]).next_style = :two
|
|
83
|
+
@composer.page_style(:two, page_size: [0, 0, 2, 2]).next_style = :one
|
|
84
|
+
@composer.new_page(:one)
|
|
85
|
+
assert_equal([0, 0, 1, 1], @composer.page.box.value)
|
|
86
|
+
@composer.new_page
|
|
87
|
+
assert_equal([0, 0, 2, 2], @composer.page.box.value)
|
|
72
88
|
@composer.new_page
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
89
|
+
assert_equal([0, 0, 1, 1], @composer.page.box.value)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "uses the current page style for new pages if no next_style value is set" do
|
|
93
|
+
@composer.page_style(:one, page_size: [0, 0, 1, 1])
|
|
94
|
+
@composer.new_page(:one)
|
|
95
|
+
assert_equal([0, 0, 1, 1], @composer.page.box.value)
|
|
96
|
+
@composer.new_page
|
|
97
|
+
assert_equal([0, 0, 1, 1], @composer.page.box.value)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "fails if the specified page style has not been defined" do
|
|
101
|
+
assert_raises(ArgumentError) { @composer.new_page(:unknown) }
|
|
77
102
|
end
|
|
78
103
|
end
|
|
79
104
|
|
|
@@ -94,7 +119,7 @@ describe HexaPDF::Composer do
|
|
|
94
119
|
end
|
|
95
120
|
end
|
|
96
121
|
|
|
97
|
-
describe "text/formatted_text/image/box" do
|
|
122
|
+
describe "text/formatted_text/image/box/method_missing" do
|
|
98
123
|
before do
|
|
99
124
|
test_self = self
|
|
100
125
|
@composer.define_singleton_method(:draw_box) do |arg|
|
|
@@ -133,6 +158,19 @@ describe HexaPDF::Composer do
|
|
|
133
158
|
assert_equal(20, @box.width)
|
|
134
159
|
assert_same(image, @box.children[0].image)
|
|
135
160
|
end
|
|
161
|
+
|
|
162
|
+
it "delegates missing methods to layout if they are box creation methods" do
|
|
163
|
+
@composer.column(width: 10)
|
|
164
|
+
assert_equal(10, @box.width)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "fails for missing methods that can't be delegated to layout" do
|
|
168
|
+
assert_raises(NameError) { @composer.unknown_box }
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "can be asked whether a missing method is supported" do
|
|
172
|
+
assert(@composer.respond_to?(:column))
|
|
173
|
+
end
|
|
136
174
|
end
|
|
137
175
|
|
|
138
176
|
describe "draw_box" do
|
|
@@ -37,6 +37,11 @@ describe HexaPDF::Tokenizer do
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
it "next_token: should not fail for strings due to use of an internal buffer" do
|
|
41
|
+
create_tokenizer("(" << ("a" * 8189) << "\\006)")
|
|
42
|
+
assert_equal("a" * 8189 << "\x06", @tokenizer.next_token)
|
|
43
|
+
end
|
|
44
|
+
|
|
40
45
|
it "has a special token scanning method for use with xref reconstruction" do
|
|
41
46
|
create_tokenizer(<<-EOF.chomp.gsub(/^ {8}/, ''))
|
|
42
47
|
% Comment
|
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.32.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.32.0)>>
|
|
76
76
|
endobj
|
|
77
77
|
2 0 obj
|
|
78
78
|
<</Length 10>>stream
|
|
@@ -171,7 +171,7 @@ describe HexaPDF::Writer do
|
|
|
171
171
|
|
|
172
172
|
it "creates an xref stream if no xref stream is in a revision but object streams are" do
|
|
173
173
|
document = HexaPDF::Document.new
|
|
174
|
-
document.add({
|
|
174
|
+
document.add({}, type: HexaPDF::Type::ObjectStream)
|
|
175
175
|
HexaPDF::Writer.new(document, StringIO.new).write
|
|
176
176
|
assert_equal(:XRef, document.object(4).type)
|
|
177
177
|
end
|
|
@@ -184,7 +184,7 @@ describe HexaPDF::Writer do
|
|
|
184
184
|
|
|
185
185
|
document = HexaPDF::Document.new(io: io)
|
|
186
186
|
document.pages.add
|
|
187
|
-
document.add({
|
|
187
|
+
document.add({}, type: HexaPDF::Type::ObjectStream)
|
|
188
188
|
io2 = StringIO.new
|
|
189
189
|
HexaPDF::Writer.new(document, io2).write_incremental
|
|
190
190
|
|
|
@@ -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.32.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
|
|
@@ -123,12 +123,21 @@ describe HexaPDF::Type::ObjectStream do
|
|
|
123
123
|
end
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
126
|
+
describe "perform_validation" do
|
|
127
|
+
it "fails validation if gen != 0" do
|
|
128
|
+
assert(@obj.validate(auto_correct: false))
|
|
129
|
+
@obj.gen = 1
|
|
130
|
+
refute(@obj.validate(auto_correct: false) do |msg, correctable|
|
|
131
|
+
assert_match(/invalid generation/, msg)
|
|
132
|
+
refute(correctable)
|
|
133
|
+
end)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "sets the /N and /First entries to dummy values so that validation works" do
|
|
137
|
+
@obj = HexaPDF::Type::ObjectStream.new({}, oid: 1, document: @doc)
|
|
138
|
+
assert(@obj.validate(auto_correct: false))
|
|
139
|
+
assert_equal(0, @obj[:N])
|
|
140
|
+
assert_equal(0, @obj[:First])
|
|
141
|
+
end
|
|
133
142
|
end
|
|
134
143
|
end
|
|
@@ -30,11 +30,12 @@ describe HexaPDF::Type::Outline do
|
|
|
30
30
|
|
|
31
31
|
describe "perform_validation" do
|
|
32
32
|
before do
|
|
33
|
-
5.times { @outline.add_item("Test1") }
|
|
33
|
+
@outline_items = 5.times.map { @outline.add_item("Test1") }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it "fixes a missing /First entry" do
|
|
37
37
|
@outline.delete(:First)
|
|
38
|
+
@outline_items[0][:Prev] = HexaPDF::Reference.new(100)
|
|
38
39
|
called = false
|
|
39
40
|
@outline.validate do |msg, correctable, _|
|
|
40
41
|
called = true
|
|
@@ -46,6 +47,7 @@ describe HexaPDF::Type::Outline do
|
|
|
46
47
|
|
|
47
48
|
it "fixes a missing /Last entry" do
|
|
48
49
|
@outline.delete(:Last)
|
|
50
|
+
@outline_items[4][:Next] = HexaPDF::Reference.new(100)
|
|
49
51
|
called = false
|
|
50
52
|
@outline.validate do |msg, correctable, _|
|
|
51
53
|
called = true
|
|
@@ -98,6 +98,24 @@ describe HexaPDF::Type::OutlineItem do
|
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
describe "open?" do
|
|
102
|
+
it "returns true if the outline item is open" do
|
|
103
|
+
refute(@item.open?)
|
|
104
|
+
@item.add_item("test")
|
|
105
|
+
assert_equal(true, @item.open?)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "returns false if the outline item is closed" do
|
|
109
|
+
@item.delete(:Count)
|
|
110
|
+
@item.add_item("test")
|
|
111
|
+
assert_equal(false, @item.open?)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "returns nil if the outline item doesn't have any child items" do
|
|
115
|
+
assert_nil(@item.open?)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
101
119
|
describe "destination_page" do
|
|
102
120
|
it "returns the page of a set destination" do
|
|
103
121
|
@item[:Dest] = [5, :Fit]
|
|
@@ -276,12 +294,13 @@ describe HexaPDF::Type::OutlineItem do
|
|
|
276
294
|
|
|
277
295
|
describe "perform_validation" do
|
|
278
296
|
before do
|
|
279
|
-
5.times { @item.add_item("Test1") }
|
|
297
|
+
@outline_items = 5.times.map { @item.add_item("Test1") }
|
|
280
298
|
@item[:Parent] = @doc.add({})
|
|
281
299
|
end
|
|
282
300
|
|
|
283
301
|
it "fixes a missing /First entry" do
|
|
284
302
|
@item.delete(:First)
|
|
303
|
+
@outline_items[0][:Prev] = HexaPDF::Reference.new(100)
|
|
285
304
|
called = false
|
|
286
305
|
@item.validate do |msg, correctable, _|
|
|
287
306
|
called = true
|
|
@@ -293,6 +312,7 @@ describe HexaPDF::Type::OutlineItem do
|
|
|
293
312
|
|
|
294
313
|
it "fixes a missing /Last entry" do
|
|
295
314
|
@item.delete(:Last)
|
|
315
|
+
@outline_items[4][:Next] = HexaPDF::Reference.new(100)
|
|
296
316
|
called = false
|
|
297
317
|
@item.validate do |msg, correctable, _|
|
|
298
318
|
called = true
|
|
@@ -19,9 +19,21 @@ describe HexaPDF::Type::Page do
|
|
|
19
19
|
assert_equal([0, 0, 842, 595], HexaPDF::Type::Page.media_box(:A4, orientation: :landscape))
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
it "works with a paper size array" do
|
|
23
|
+
assert_equal([0, 0, 842, 595], HexaPDF::Type::Page.media_box([0, 0, 842, 595]))
|
|
24
|
+
end
|
|
25
|
+
|
|
22
26
|
it "fails if the paper size is unknown" do
|
|
23
27
|
assert_raises(HexaPDF::Error) { HexaPDF::Type::Page.media_box(:Unknown) }
|
|
24
28
|
end
|
|
29
|
+
|
|
30
|
+
it "fails if the array doesn't contain four numbers" do
|
|
31
|
+
assert_raises(HexaPDF::Error) { HexaPDF::Type::Page.media_box([0, 1, 2]) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "fails if the array doesn't contain only numbers" do
|
|
35
|
+
assert_raises(HexaPDF::Error) { HexaPDF::Type::Page.media_box([0, 1, 2, 'a']) }
|
|
36
|
+
end
|
|
25
37
|
end
|
|
26
38
|
|
|
27
39
|
# Asserts that the page's contents contains the operators.
|
|
@@ -70,22 +82,41 @@ describe HexaPDF::Type::Page do
|
|
|
70
82
|
end
|
|
71
83
|
end
|
|
72
84
|
|
|
73
|
-
describe "
|
|
85
|
+
describe "perform_validation" do
|
|
74
86
|
it "only does validation if the page is in the document's page tree" do
|
|
75
87
|
page = @doc.add({Type: :Page})
|
|
88
|
+
assert(page.validate(auto_correct: false))
|
|
89
|
+
page[:Parent] = @doc.add({Type: :Pages, Kids: [page], Count: 1})
|
|
90
|
+
assert(page.validate(auto_correct: false))
|
|
91
|
+
@doc.pages.add(page)
|
|
92
|
+
refute(page.validate(auto_correct: false))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "validates that the required inheritable field /Resources is set" do
|
|
96
|
+
page = @doc.pages.add
|
|
97
|
+
page.delete(:Resources)
|
|
98
|
+
refute(page.validate(auto_correct: false))
|
|
76
99
|
assert(page.validate)
|
|
77
|
-
|
|
78
|
-
assert(page.validate)
|
|
79
|
-
page[:Parent] = @doc.catalog.pages
|
|
80
|
-
refute(page.validate)
|
|
100
|
+
assert_kind_of(HexaPDF::Dictionary, page[:Resources])
|
|
81
101
|
end
|
|
82
102
|
|
|
83
|
-
it "
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
103
|
+
it "validates that the required inheritable field /MediaBox is set" do
|
|
104
|
+
page1 = @doc.pages.add(:Letter)
|
|
105
|
+
page2 = @doc.pages.add(:Letter)
|
|
106
|
+
page3 = @doc.pages.add(:Letter)
|
|
107
|
+
|
|
108
|
+
[page1, page2, page3].each do |page|
|
|
109
|
+
page.delete(:MediaBox)
|
|
110
|
+
refute(page.validate(auto_correct: false))
|
|
111
|
+
assert(page.validate)
|
|
112
|
+
assert_equal([0, 0, 612, 792], page[:MediaBox])
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
page2.delete(:MediaBox)
|
|
116
|
+
page1[:MediaBox] = [0, 0, 1, 1]
|
|
117
|
+
refute(page2.validate(auto_correct: false))
|
|
118
|
+
assert(page2.validate)
|
|
119
|
+
assert_equal([0, 0, 595, 842], page2[:MediaBox])
|
|
89
120
|
end
|
|
90
121
|
end
|
|
91
122
|
|
|
@@ -611,6 +642,22 @@ describe HexaPDF::Type::Page do
|
|
|
611
642
|
[:restore_graphics_state]])
|
|
612
643
|
end
|
|
613
644
|
|
|
645
|
+
it "handles degenerate cases when the appearance's bounding box has zero width" do
|
|
646
|
+
@appearance[:BBox] = [10, 10, 10, 20]
|
|
647
|
+
result = @page.flatten_annotations
|
|
648
|
+
assert(result.empty?)
|
|
649
|
+
assert(@annot1.null?)
|
|
650
|
+
assert_operators(@canvas.contents, [])
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
it "handles degenerate cases when the appearance's bounding box has zero height" do
|
|
654
|
+
@appearance[:BBox] = [10, 10, 20, 10]
|
|
655
|
+
result = @page.flatten_annotations
|
|
656
|
+
assert(result.empty?)
|
|
657
|
+
assert(@annot1.null?)
|
|
658
|
+
assert_operators(@canvas.contents, [])
|
|
659
|
+
end
|
|
660
|
+
|
|
614
661
|
it "potentially adjusts the origin so that it is always in (0,0)" do
|
|
615
662
|
@canvas.translate(-15, -15)
|
|
616
663
|
@page.flatten_annotations
|
|
@@ -6,9 +6,10 @@ require 'hexapdf/type/xref_stream'
|
|
|
6
6
|
describe HexaPDF::Type::XRefStream do
|
|
7
7
|
before do
|
|
8
8
|
@doc = Object.new
|
|
9
|
+
@doc.instance_variable_set(:@version, '1.5')
|
|
9
10
|
def (@doc).deref(obj); obj; end
|
|
10
11
|
def (@doc).wrap(obj, **); obj; end
|
|
11
|
-
@obj = HexaPDF::Type::XRefStream.new({}, oid: 1, document: @doc)
|
|
12
|
+
@obj = HexaPDF::Type::XRefStream.new({}, oid: 1, document: @doc, stream: '')
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
describe "xref_section" do
|
|
@@ -141,4 +142,8 @@ describe HexaPDF::Type::XRefStream do
|
|
|
141
142
|
assert_raises(HexaPDF::Error) { @obj.update_with_xref_section_and_trailer(@section, {}) }
|
|
142
143
|
end
|
|
143
144
|
end
|
|
145
|
+
|
|
146
|
+
it "sets /Size and /W to dummy values to make validation work" do
|
|
147
|
+
assert(@obj.validate(auto_correct: false))
|
|
148
|
+
end
|
|
144
149
|
end
|
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.32.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas Leitner
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-03-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cmdparse
|
|
@@ -428,6 +428,7 @@ files:
|
|
|
428
428
|
- lib/hexapdf/layout/line.rb
|
|
429
429
|
- lib/hexapdf/layout/list_box.rb
|
|
430
430
|
- lib/hexapdf/layout/numeric_refinements.rb
|
|
431
|
+
- lib/hexapdf/layout/page_style.rb
|
|
431
432
|
- lib/hexapdf/layout/style.rb
|
|
432
433
|
- lib/hexapdf/layout/text_box.rb
|
|
433
434
|
- lib/hexapdf/layout/text_fragment.rb
|
|
@@ -679,6 +680,7 @@ files:
|
|
|
679
680
|
- test/hexapdf/layout/test_inline_box.rb
|
|
680
681
|
- test/hexapdf/layout/test_line.rb
|
|
681
682
|
- test/hexapdf/layout/test_list_box.rb
|
|
683
|
+
- test/hexapdf/layout/test_page_style.rb
|
|
682
684
|
- test/hexapdf/layout/test_style.rb
|
|
683
685
|
- test/hexapdf/layout/test_text_box.rb
|
|
684
686
|
- test/hexapdf/layout/test_text_fragment.rb
|