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
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -85,7 +85,7 @@ module HexaPDF
|
|
|
85
85
|
|
|
86
86
|
# Converts the given string to UTF-8, assuming it contains bytes in PDFDocEncoding.
|
|
87
87
|
def self.convert_to_utf8(str)
|
|
88
|
-
str.each_byte.with_object('') {|byte, result| result << CHARACTER_MAP[byte]}
|
|
88
|
+
str.each_byte.with_object(+'') {|byte, result| result << CHARACTER_MAP[byte] }
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -51,6 +51,8 @@ module HexaPDF
|
|
|
51
51
|
#
|
|
52
52
|
# For example, for name trees this would be String.
|
|
53
53
|
#
|
|
54
|
+
# Note: Like with HexaPDF::Dictionary, the keys are assumed to always be direct objects!
|
|
55
|
+
#
|
|
54
56
|
# See: HexaPDF::NameTreeNode, HexaPDF::NumberTreeNode
|
|
55
57
|
module SortedTreeNode
|
|
56
58
|
|
|
@@ -130,8 +132,7 @@ module HexaPDF
|
|
|
130
132
|
index = find_in_leaf_node(stack.last[container_name], key)
|
|
131
133
|
return unless stack.last[container_name][index] == key
|
|
132
134
|
|
|
133
|
-
|
|
134
|
-
document.delete(value) if value.kind_of?(HexaPDF::Object)
|
|
135
|
+
stack.last[container_name].delete_at(index) # deletes key
|
|
135
136
|
value = stack.last[container_name].delete_at(index)
|
|
136
137
|
|
|
137
138
|
stack.last[:Limits] = stack.last[container_name].values_at(0, -2) if stack.last[:Limits]
|
|
@@ -139,10 +140,10 @@ module HexaPDF
|
|
|
139
140
|
stack.reverse_each.inject do |nested_node, node|
|
|
140
141
|
if (!nested_node[container_name] || nested_node[container_name].empty?) &&
|
|
141
142
|
(!nested_node[:Kids] || nested_node[:Kids].empty?)
|
|
142
|
-
node[:Kids].delete_at(node[:Kids].index {|n| document.deref(n) == nested_node})
|
|
143
|
+
node[:Kids].delete_at(node[:Kids].index {|n| document.deref(n) == nested_node })
|
|
143
144
|
document.delete(nested_node)
|
|
144
145
|
end
|
|
145
|
-
if node[:Kids].
|
|
146
|
+
if !node[:Kids].empty? && node[:Limits]
|
|
146
147
|
node[:Limits][0] = document.deref(node[:Kids][0])[:Limits][0]
|
|
147
148
|
node[:Limits][1] = document.deref(node[:Kids][-1])[:Limits][1]
|
|
148
149
|
end
|
|
@@ -287,12 +288,12 @@ module HexaPDF
|
|
|
287
288
|
parent.delete(container_name)
|
|
288
289
|
parent[:Kids] = [node1, node2]
|
|
289
290
|
else
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
291
|
+
node = document.add(document.wrap({}, type: self.class))
|
|
292
|
+
node[container_name] = leaf_node[container_name].slice!(split_point..-1)
|
|
293
|
+
node[:Limits] = node[container_name].values_at(0, -2)
|
|
293
294
|
leaf_node[:Limits][1] = leaf_node[container_name][-2]
|
|
294
|
-
index = 1 + parent[:Kids].index {|o| document.deref(o) == leaf_node}
|
|
295
|
-
parent[:Kids].insert(index,
|
|
295
|
+
index = 1 + parent[:Kids].index {|o| document.deref(o) == leaf_node }
|
|
296
|
+
parent[:Kids].insert(index, node)
|
|
296
297
|
end
|
|
297
298
|
end
|
|
298
299
|
|
data/lib/hexapdf/version.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -34,6 +34,6 @@
|
|
|
34
34
|
module HexaPDF
|
|
35
35
|
|
|
36
36
|
# The version of HexaPDF.
|
|
37
|
-
VERSION = '0.
|
|
37
|
+
VERSION = '0.7.0'
|
|
38
38
|
|
|
39
39
|
end
|
data/lib/hexapdf/writer.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -87,7 +87,7 @@ module HexaPDF
|
|
|
87
87
|
# cross-reference section or stream if applicable.
|
|
88
88
|
def write_revision(rev, previous_xref_pos = nil)
|
|
89
89
|
xref_stream, object_streams = xref_and_object_streams(rev)
|
|
90
|
-
obj_to_stm = object_streams.each_with_object({}) {|stm, m| m.update(stm.write_objects(rev))}
|
|
90
|
+
obj_to_stm = object_streams.each_with_object({}) {|stm, m| m.update(stm.write_objects(rev)) }
|
|
91
91
|
|
|
92
92
|
xref_section = XRefSection.new
|
|
93
93
|
xref_section.add_free_entry(0, 65535) if previous_xref_pos.nil?
|
|
@@ -147,7 +147,7 @@ module HexaPDF
|
|
|
147
147
|
end
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
if object_streams.
|
|
150
|
+
if !object_streams.empty? && xref_stream.nil?
|
|
151
151
|
raise HexaPDF::Error, "Cannot use object streams when there is no xref stream"
|
|
152
152
|
end
|
|
153
153
|
|
|
@@ -156,9 +156,9 @@ module HexaPDF
|
|
|
156
156
|
|
|
157
157
|
# Writes the single indirect object which may be a stream object or another object.
|
|
158
158
|
def write_indirect_object(obj)
|
|
159
|
-
@io << "#{obj.oid} #{obj.gen} obj\n"
|
|
159
|
+
@io << "#{obj.oid} #{obj.gen} obj\n"
|
|
160
160
|
@serializer.serialize_to_io(obj, @io)
|
|
161
|
-
@io << "\nendobj\n"
|
|
161
|
+
@io << "\nendobj\n"
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
# Writes the cross-reference section.
|
|
@@ -170,9 +170,9 @@ module HexaPDF
|
|
|
170
170
|
@io << "#{entries.empty? ? 0 : entries.first.oid} #{entries.size}\n"
|
|
171
171
|
entries.each do |entry|
|
|
172
172
|
if entry.in_use?
|
|
173
|
-
@io << sprintf("%010d %05d n \n"
|
|
173
|
+
@io << sprintf("%010d %05d n \n", entry.pos, entry.gen).freeze
|
|
174
174
|
elsif entry.free?
|
|
175
|
-
@io << "0000000000 65535 f \n"
|
|
175
|
+
@io << "0000000000 65535 f \n"
|
|
176
176
|
else
|
|
177
177
|
# Should never occur since we create the xref section!
|
|
178
178
|
raise HexaPDF::Error, "Cannot use xref type #{entry.type} in cross-reference section"
|
data/lib/hexapdf/xref_section.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -123,7 +123,7 @@ module HexaPDF
|
|
|
123
123
|
|
|
124
124
|
# Merges the entries from the given cross-reference section into this one.
|
|
125
125
|
def merge!(xref_section)
|
|
126
|
-
xref_section.each {|oid, gen, data| self[oid, gen] = data}
|
|
126
|
+
xref_section.each {|oid, gen, data| self[oid, gen] = data }
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
# :call-seq:
|
|
@@ -8,8 +8,7 @@ module CommonTokenizerTests
|
|
|
8
8
|
it "next_token: returns all available kinds of tokens on next_token" do
|
|
9
9
|
create_tokenizer(<<-EOF.chomp.gsub(/^ {8}/, ''))
|
|
10
10
|
% Regular tokens
|
|
11
|
-
|
|
12
|
-
true false
|
|
11
|
+
true false
|
|
13
12
|
123 +17 -98 0 0059
|
|
14
13
|
34.5 -3.62 +123.6 4. -.002 .002 0.0
|
|
15
14
|
|
|
@@ -66,9 +65,9 @@ module CommonTokenizerTests
|
|
|
66
65
|
:"The_Key_of_F#_Minor", :AB, :"",
|
|
67
66
|
'[', 5, 6, :Name, ']', '[', 5, 6, :Name, ']',
|
|
68
67
|
'<<', :Name, 5, '>>'
|
|
69
|
-
].each {|t| t.force_encoding('BINARY') if t.respond_to?(:force_encoding)}
|
|
68
|
+
].each {|t| t.force_encoding('BINARY') if t.respond_to?(:force_encoding) }
|
|
70
69
|
|
|
71
|
-
|
|
70
|
+
until expected_tokens.empty?
|
|
72
71
|
expected_token = expected_tokens.shift
|
|
73
72
|
token = @tokenizer.next_token
|
|
74
73
|
assert_equal(expected_token, token)
|
|
@@ -125,7 +124,7 @@ module CommonTokenizerTests
|
|
|
125
124
|
it "next_object: works for all PDF object types, including array and dictionary" do
|
|
126
125
|
create_tokenizer(<<-EOF.chomp.gsub(/^ {8}/, ''))
|
|
127
126
|
true false null 123 34.5 (string) <4E6F76> /Name
|
|
128
|
-
[5 6 /Name] <</Name 5>>
|
|
127
|
+
[5 6 /Name] <</Name 5/Null null>>
|
|
129
128
|
EOF
|
|
130
129
|
assert_equal(true, @tokenizer.next_object)
|
|
131
130
|
assert_equal(false, @tokenizer.next_object)
|
|
@@ -206,8 +205,8 @@ module CommonTokenizerTests
|
|
|
206
205
|
|
|
207
206
|
it "next_xref_entry: fails on invalidly formatted entries" do
|
|
208
207
|
create_tokenizer("0000000001 00001 g \n")
|
|
209
|
-
assert_raises(RuntimeError) { @tokenizer.next_xref_entry { raise }}
|
|
208
|
+
assert_raises(RuntimeError) { @tokenizer.next_xref_entry { raise } }
|
|
210
209
|
create_tokenizer("0000000001 00001 n\n")
|
|
211
|
-
assert_raises(RuntimeError) { @tokenizer.next_xref_entry { raise }}
|
|
210
|
+
assert_raises(RuntimeError) { @tokenizer.next_xref_entry { raise } }
|
|
212
211
|
end
|
|
213
212
|
end
|
|
@@ -83,7 +83,7 @@ describe HexaPDF::Content::Canvas do
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
it "is serialized correctly when a block is used" do
|
|
86
|
-
@canvas.save_graphics_state {
|
|
86
|
+
@canvas.save_graphics_state {}
|
|
87
87
|
assert_operators(@canvas.contents, [[:save_graphics_state], [:restore_graphics_state]])
|
|
88
88
|
end
|
|
89
89
|
|
|
@@ -714,8 +714,8 @@ describe HexaPDF::Content::Canvas do
|
|
|
714
714
|
it "draws the, optionally configured, graphic object onto the canvas" do
|
|
715
715
|
obj = Object.new
|
|
716
716
|
obj.define_singleton_method(:options) { @options }
|
|
717
|
-
obj.define_singleton_method(:configure) {|**kwargs| @options = kwargs; self}
|
|
718
|
-
obj.define_singleton_method(:draw) {|canvas| canvas.move_to(@options[:x], @options[:y])}
|
|
717
|
+
obj.define_singleton_method(:configure) {|**kwargs| @options = kwargs; self }
|
|
718
|
+
obj.define_singleton_method(:draw) {|canvas| canvas.move_to(@options[:x], @options[:y]) }
|
|
719
719
|
@canvas.draw(obj, x: 5, y: 6)
|
|
720
720
|
assert_operators(@canvas.contents, [[:move_to, [5, 6]]])
|
|
721
721
|
end
|
|
@@ -961,7 +961,7 @@ describe HexaPDF::Content::Canvas do
|
|
|
961
961
|
it "invokes the operator implementation" do
|
|
962
962
|
@canvas.text_matrix(1, 2, 3, 4, 5, 6)
|
|
963
963
|
assert_operators(@canvas.contents, [[:begin_text],
|
|
964
|
-
[:set_text_matrix, [1, 2, 3, 4, 5,6]]])
|
|
964
|
+
[:set_text_matrix, [1, 2, 3, 4, 5, 6]]])
|
|
965
965
|
end
|
|
966
966
|
|
|
967
967
|
it "returns the canvas object" do
|
|
@@ -1002,7 +1002,7 @@ describe HexaPDF::Content::Canvas do
|
|
|
1002
1002
|
end
|
|
1003
1003
|
|
|
1004
1004
|
it "fails if invoked outside a text object" do
|
|
1005
|
-
assert_raises_in_graphics_object(:none, :path, :clipping_path)
|
|
1005
|
+
assert_raises_in_graphics_object(:none, :path, :clipping_path) { @canvas.text_cursor }
|
|
1006
1006
|
end
|
|
1007
1007
|
end
|
|
1008
1008
|
|
|
@@ -1015,7 +1015,6 @@ describe HexaPDF::Content::Canvas do
|
|
|
1015
1015
|
assert_same(@doc.fonts.add("Times"), @canvas.font)
|
|
1016
1016
|
@canvas.font("Helvetica", size: 10)
|
|
1017
1017
|
assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 10]],
|
|
1018
|
-
[:set_leading, [12.0]],
|
|
1019
1018
|
[:set_font_and_size, [:F2, 10]]])
|
|
1020
1019
|
end
|
|
1021
1020
|
|
|
@@ -1035,16 +1034,9 @@ describe HexaPDF::Content::Canvas do
|
|
|
1035
1034
|
assert_equal(10, @canvas.font_size)
|
|
1036
1035
|
end
|
|
1037
1036
|
|
|
1038
|
-
it "sets the font size
|
|
1037
|
+
it "sets the font size" do
|
|
1039
1038
|
@canvas.font("Times", size: 10)
|
|
1040
1039
|
assert_equal(10, @canvas.font_size)
|
|
1041
|
-
assert_equal(12, @canvas.leading)
|
|
1042
|
-
@canvas.font_size(10, leading: 20)
|
|
1043
|
-
assert_equal(10, @canvas.font_size)
|
|
1044
|
-
assert_equal(20, @canvas.leading)
|
|
1045
|
-
@canvas.font_size(10, leading: nil)
|
|
1046
|
-
assert_equal(10, @canvas.font_size)
|
|
1047
|
-
assert_equal(20, @canvas.leading)
|
|
1048
1040
|
end
|
|
1049
1041
|
|
|
1050
1042
|
it "fails if no valid font is already set" do
|
|
@@ -1066,41 +1058,45 @@ describe HexaPDF::Content::Canvas do
|
|
|
1066
1058
|
@canvas.font_size(10)
|
|
1067
1059
|
@canvas.show_glyphs(font.decode_utf8("Hal"))
|
|
1068
1060
|
assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 20]],
|
|
1069
|
-
[:set_leading, [24]],
|
|
1070
1061
|
[:set_horizontal_scaling, [200]],
|
|
1071
1062
|
[:set_character_spacing, [1]],
|
|
1072
1063
|
[:set_word_spacing, [2]],
|
|
1073
1064
|
[:begin_text],
|
|
1074
1065
|
[:show_text_with_positioning, [['', -10, "Ha", -35, "l lo"]]],
|
|
1075
1066
|
[:set_font_and_size, [:F1, 10]],
|
|
1076
|
-
[:
|
|
1077
|
-
[:show_text_with_positioning, [["Hal"]]],
|
|
1078
|
-
])
|
|
1067
|
+
[:show_text_with_positioning, [["Hal"]]]])
|
|
1079
1068
|
end
|
|
1080
1069
|
|
|
1081
|
-
it "
|
|
1082
|
-
|
|
1083
|
-
|
|
1070
|
+
it "does nothing if there are no glyphs" do
|
|
1071
|
+
@canvas.show_glyphs_only([])
|
|
1072
|
+
assert_operators(@canvas.contents, [])
|
|
1084
1073
|
end
|
|
1085
1074
|
end
|
|
1086
1075
|
|
|
1087
1076
|
describe "show_glyphs_only" do
|
|
1088
|
-
it "serializes correctly" do
|
|
1077
|
+
it "serializes positioned glyphs correctly" do
|
|
1089
1078
|
@canvas.font("Times", size: 20)
|
|
1090
1079
|
font = @canvas.font
|
|
1091
1080
|
@canvas.show_glyphs_only(font.decode_utf8("Hal lo").insert(2, -35))
|
|
1092
1081
|
assert_equal(0, @canvas.text_cursor[0])
|
|
1093
1082
|
assert_equal(0, @canvas.text_cursor[1])
|
|
1094
1083
|
assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 20]],
|
|
1095
|
-
[:set_leading, [24]],
|
|
1096
1084
|
[:begin_text],
|
|
1097
|
-
[:show_text_with_positioning, [["Ha", -35, "l lo"]]]
|
|
1098
|
-
])
|
|
1085
|
+
[:show_text_with_positioning, [["Ha", -35, "l lo"]]]])
|
|
1099
1086
|
end
|
|
1100
1087
|
|
|
1101
|
-
it "
|
|
1102
|
-
|
|
1103
|
-
|
|
1088
|
+
it "serializes unpositioned glyphs correctly" do
|
|
1089
|
+
@canvas.font("Times", size: 20)
|
|
1090
|
+
font = @canvas.font
|
|
1091
|
+
@canvas.show_glyphs_only(font.decode_utf8("Hallo"))
|
|
1092
|
+
assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 20]],
|
|
1093
|
+
[:begin_text],
|
|
1094
|
+
[:show_text, ["Hallo"]]])
|
|
1095
|
+
end
|
|
1096
|
+
|
|
1097
|
+
it "does nothing if there are no glyphs" do
|
|
1098
|
+
@canvas.show_glyphs_only([])
|
|
1099
|
+
assert_operators(@canvas.contents, [])
|
|
1104
1100
|
end
|
|
1105
1101
|
end
|
|
1106
1102
|
|
|
@@ -1109,18 +1105,15 @@ describe HexaPDF::Content::Canvas do
|
|
|
1109
1105
|
@canvas.font("Times", size: 10)
|
|
1110
1106
|
@canvas.text("Hallo", at: [100, 100])
|
|
1111
1107
|
assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 10]],
|
|
1112
|
-
[:set_leading, [12]],
|
|
1113
1108
|
[:begin_text],
|
|
1114
1109
|
[:set_text_matrix, [1, 0, 0, 1, 100, 100]],
|
|
1115
|
-
[:show_text_with_positioning, [["Hallo"]]]
|
|
1116
|
-
])
|
|
1110
|
+
[:show_text_with_positioning, [["Hallo"]]]])
|
|
1117
1111
|
end
|
|
1118
1112
|
|
|
1119
1113
|
it "shows text, possibly split over multiple lines" do
|
|
1120
1114
|
@canvas.font("Times", size: 10)
|
|
1121
1115
|
@canvas.text("H\u{D A}H\u{A}H\u{B}H\u{c}H\u{D}H\u{85}H\u{2028}H\u{2029}H")
|
|
1122
1116
|
assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 10]],
|
|
1123
|
-
[:set_leading, [12]],
|
|
1124
1117
|
[:begin_text],
|
|
1125
1118
|
[:show_text_with_positioning, [["H"]]], [:move_text_next_line],
|
|
1126
1119
|
[:show_text_with_positioning, [["H"]]], [:move_text_next_line],
|
|
@@ -1130,12 +1123,11 @@ describe HexaPDF::Content::Canvas do
|
|
|
1130
1123
|
[:show_text_with_positioning, [["H"]]], [:move_text_next_line],
|
|
1131
1124
|
[:show_text_with_positioning, [["H"]]], [:move_text_next_line],
|
|
1132
1125
|
[:show_text_with_positioning, [["H"]]], [:move_text_next_line],
|
|
1133
|
-
[:show_text_with_positioning, [["H"]]]
|
|
1134
|
-
])
|
|
1126
|
+
[:show_text_with_positioning, [["H"]]]])
|
|
1135
1127
|
end
|
|
1136
1128
|
|
|
1137
1129
|
it "fails if no valid font is set" do
|
|
1138
|
-
error = assert_raises(HexaPDF::Error) { @canvas.
|
|
1130
|
+
error = assert_raises(HexaPDF::Error) { @canvas.text("test") }
|
|
1139
1131
|
assert_match(/if a font is set/, error.message)
|
|
1140
1132
|
end
|
|
1141
1133
|
end
|
|
@@ -1172,7 +1164,7 @@ describe HexaPDF::Content::Canvas do
|
|
|
1172
1164
|
end
|
|
1173
1165
|
|
|
1174
1166
|
it "is serialized correctly when a block is used" do
|
|
1175
|
-
@canvas.marked_content_sequence(:tag, property_list: {key: 5}) {
|
|
1167
|
+
@canvas.marked_content_sequence(:tag, property_list: {key: 5}) {}
|
|
1176
1168
|
assert_operators(@canvas.contents, [[:begin_marked_content_with_property_list, [:tag, :P1]],
|
|
1177
1169
|
[:end_marked_content]])
|
|
1178
1170
|
end
|
|
@@ -10,6 +10,10 @@ module CommonColorSpaceTests
|
|
|
10
10
|
assert_equal(@color_space, @color.color_space)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
it "the color space class accepts the color space definition as argument to ::new" do
|
|
14
|
+
assert_equal(1, @color_space.class.method(:new).arity.abs)
|
|
15
|
+
end
|
|
16
|
+
|
|
13
17
|
it "the color space responds to :default_color" do
|
|
14
18
|
assert(@color_space.respond_to?(:default_color))
|
|
15
19
|
assert_equal(0, @color_space.method(:default_color).arity)
|
|
@@ -5,6 +5,7 @@ require 'hexapdf/content/graphics_state'
|
|
|
5
5
|
|
|
6
6
|
# Dummy class used as wrapper so that constant lookup works correctly
|
|
7
7
|
class GraphicsStateWrapper < Minitest::Spec
|
|
8
|
+
|
|
8
9
|
include HexaPDF::Content
|
|
9
10
|
|
|
10
11
|
describe NamedValue do
|
|
@@ -146,4 +147,5 @@ class GraphicsStateWrapper < Minitest::Spec
|
|
|
146
147
|
assert_raises(HexaPDF::Error) { @gs.restore }
|
|
147
148
|
end
|
|
148
149
|
end
|
|
150
|
+
|
|
149
151
|
end
|
|
@@ -41,7 +41,6 @@ describe HexaPDF::Content::Operator::SingleNumericArgumentOperator do
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
|
|
45
44
|
module CommonOperatorTests
|
|
46
45
|
extend Minitest::Spec::DSL
|
|
47
46
|
|
|
@@ -98,7 +97,6 @@ def describe_operator(name, symbol, &block)
|
|
|
98
97
|
klass
|
|
99
98
|
end
|
|
100
99
|
|
|
101
|
-
|
|
102
100
|
describe_operator :SaveGraphicsState, :q do
|
|
103
101
|
it "saves the graphics state" do
|
|
104
102
|
width = @processor.graphics_state.line_width
|
|
@@ -196,7 +194,7 @@ describe_operator :SetGraphicsStateParameters, :gs do
|
|
|
196
194
|
RI: 2, SA: true, BM: :Multiply, CA: 0.5, ca: 0.5,
|
|
197
195
|
AIS: true, TK: false, Font: [:Test, 10]}}
|
|
198
196
|
@processor.resources.define_singleton_method(:document) do
|
|
199
|
-
Object.new.tap {|obj| obj.define_singleton_method(:deref) {|o| o}}
|
|
197
|
+
Object.new.tap {|obj| obj.define_singleton_method(:deref) {|o| o } }
|
|
200
198
|
end
|
|
201
199
|
|
|
202
200
|
invoke(:Name)
|
|
@@ -561,7 +559,7 @@ end
|
|
|
561
559
|
|
|
562
560
|
describe_operator :ShowText, :Tj do
|
|
563
561
|
it "serializes correctly" do
|
|
564
|
-
|
|
562
|
+
assert_equal("(Some Text)Tj\n", call(:serialize, @serializer, "Some Text"))
|
|
565
563
|
end
|
|
566
564
|
end
|
|
567
565
|
|
|
@@ -582,7 +580,7 @@ describe_operator :MoveTextNextLineAndShowText, :"'" do
|
|
|
582
580
|
end
|
|
583
581
|
|
|
584
582
|
it "serializes correctly" do
|
|
585
|
-
|
|
583
|
+
assert_equal("(Some Text)'\n", call(:serialize, @serializer, "Some Text"))
|
|
586
584
|
end
|
|
587
585
|
end
|
|
588
586
|
|
|
@@ -609,12 +607,13 @@ describe_operator :SetSpacingMoveTextNextLineAndShowText, :'"' do
|
|
|
609
607
|
end
|
|
610
608
|
|
|
611
609
|
it "serializes correctly" do
|
|
612
|
-
|
|
610
|
+
assert_equal("10 15 (Some Text)\"\n", call(:serialize, @serializer, 10, 15, "Some Text"))
|
|
613
611
|
end
|
|
614
612
|
end
|
|
615
613
|
|
|
616
614
|
describe_operator :ShowTextWithPositioning, :TJ do
|
|
617
615
|
it "serializes correctly" do
|
|
618
|
-
|
|
616
|
+
assert_equal("[(Some Text)15(other text)20(final text)]TJ\n",
|
|
617
|
+
call(:serialize, @serializer, ["Some Text", 15, "other text", 20, "final text"]))
|
|
619
618
|
end
|
|
620
619
|
end
|