hexapdf 0.22.0 → 0.24.1
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 +136 -0
- data/LICENSE +1 -1
- data/Rakefile +1 -1
- data/examples/016-frame_automatic_box_placement.rb +7 -2
- data/examples/017-frame_text_flow.rb +10 -18
- data/examples/020-column_box.rb +40 -0
- data/examples/021-list_box.rb +26 -0
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +3 -3
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +27 -4
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +2 -2
- data/lib/hexapdf/cli/inspect.rb +14 -5
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +24 -4
- data/lib/hexapdf/cli/optimize.rb +2 -2
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/cli.rb +1 -1
- data/lib/hexapdf/composer.rb +66 -125
- data/lib/hexapdf/configuration.rb +17 -1
- data/lib/hexapdf/content/canvas.rb +1 -1
- data/lib/hexapdf/content/color_space.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/geom2d.rb +2 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +1 -1
- data/lib/hexapdf/content/parser.rb +1 -1
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +1 -1
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/document/destinations.rb +396 -0
- data/lib/hexapdf/document/files.rb +2 -2
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +2 -2
- data/lib/hexapdf/document/layout.rb +397 -0
- data/lib/hexapdf/document/pages.rb +17 -1
- data/lib/hexapdf/document/signatures.rb +5 -4
- data/lib/hexapdf/document.rb +51 -93
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +1 -1
- data/lib/hexapdf/encryption/fast_arc4.rb +30 -21
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +1 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/crypt.rb +1 -1
- data/lib/hexapdf/filter/encryption.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/pass_through.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/filter.rb +1 -1
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/glyph_list.rb +2 -2
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +1 -1
- data/lib/hexapdf/font/true_type/font.rb +1 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
- data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
- data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
- data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
- data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
- data/lib/hexapdf/font/true_type/table/name.rb +1 -1
- data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +1 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font.rb +1 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
- data/lib/hexapdf/font/type1.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +1 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/font_loader.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +1 -1
- data/lib/hexapdf/layout/box.rb +121 -22
- data/lib/hexapdf/layout/box_fitter.rb +136 -0
- data/lib/hexapdf/layout/column_box.rb +247 -0
- data/lib/hexapdf/layout/frame.rb +155 -140
- data/lib/hexapdf/layout/image_box.rb +19 -4
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/list_box.rb +355 -0
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.rb +285 -8
- data/lib/hexapdf/layout/text_box.rb +30 -11
- data/lib/hexapdf/layout/text_fragment.rb +3 -2
- data/lib/hexapdf/layout/text_layouter.rb +23 -3
- data/lib/hexapdf/layout/text_shaper.rb +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +12 -7
- data/lib/hexapdf/layout.rb +4 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +8 -5
- data/lib/hexapdf/parser.rb +2 -9
- data/lib/hexapdf/pdf_array.rb +1 -1
- data/lib/hexapdf/rectangle.rb +1 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +9 -2
- data/lib/hexapdf/revisions.rb +155 -51
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +2 -2
- data/lib/hexapdf/task/optimize.rb +24 -14
- data/lib/hexapdf/task.rb +2 -2
- data/lib/hexapdf/test_utils.rb +114 -0
- data/lib/hexapdf/tokenizer.rb +1 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +1 -1
- data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/field.rb +1 -1
- data/lib/hexapdf/type/acro_form/form.rb +1 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/text_field.rb +9 -1
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +1 -1
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/link.rb +1 -1
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +1 -1
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +10 -2
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +1 -1
- data/lib/hexapdf/type/font.rb +1 -1
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_true_type.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +1 -1
- data/lib/hexapdf/type/font_type1.rb +1 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +1 -1
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +1 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +14 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/page.rb +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +19 -2
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +1 -1
- data/lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb +1 -1
- data/lib/hexapdf/type/signature/handler.rb +1 -1
- data/lib/hexapdf/type/signature/verification_result.rb +1 -1
- data/lib/hexapdf/type/signature.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +2 -2
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +3 -2
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +1 -1
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
- data/lib/hexapdf/utils/lru_cache.rb +1 -1
- data/lib/hexapdf/utils/math_helpers.rb +1 -1
- data/lib/hexapdf/utils/object_hash.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +4 -2
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +23 -8
- data/lib/hexapdf/xref_section.rb +1 -1
- data/lib/hexapdf.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +1 -2
- data/test/hexapdf/content/graphic_object/test_solid_arc.rb +11 -21
- data/test/hexapdf/content/test_canvas.rb +0 -1
- data/test/hexapdf/content/test_parser.rb +1 -2
- data/test/hexapdf/document/test_destinations.rb +338 -0
- data/test/hexapdf/document/test_images.rb +1 -1
- data/test/hexapdf/document/test_layout.rb +264 -0
- data/test/hexapdf/document/test_pages.rb +9 -0
- data/test/hexapdf/document/test_signatures.rb +10 -3
- data/test/hexapdf/encryption/test_aes.rb +9 -9
- data/test/hexapdf/encryption/test_arc4.rb +2 -2
- data/test/hexapdf/encryption/test_security_handler.rb +4 -4
- data/test/hexapdf/filter/common.rb +0 -1
- data/test/hexapdf/filter/test_predictor.rb +0 -1
- data/test/hexapdf/font/encoding/test_glyph_list.rb +4 -0
- data/test/hexapdf/font/true_type/common.rb +4 -8
- data/test/hexapdf/font/true_type/table/common.rb +18 -16
- data/test/hexapdf/font/true_type/test_font.rb +1 -1
- data/test/hexapdf/font/true_type/test_table.rb +4 -4
- data/test/hexapdf/layout/test_box.rb +53 -4
- data/test/hexapdf/layout/test_box_fitter.rb +62 -0
- data/test/hexapdf/layout/test_column_box.rb +158 -0
- data/test/hexapdf/layout/test_frame.rb +114 -39
- data/test/hexapdf/layout/test_image_box.rb +1 -2
- data/test/hexapdf/layout/test_list_box.rb +248 -0
- data/test/hexapdf/layout/test_style.rb +0 -1
- data/test/hexapdf/layout/test_text_box.rb +33 -3
- data/test/hexapdf/layout/test_text_fragment.rb +1 -2
- data/test/hexapdf/layout/test_text_layouter.rb +50 -19
- data/test/hexapdf/layout/test_width_from_polygon.rb +13 -0
- data/test/hexapdf/task/test_optimize.rb +17 -4
- data/test/hexapdf/test_composer.rb +35 -2
- data/test/hexapdf/test_dictionary_fields.rb +9 -9
- data/test/hexapdf/test_document.rb +33 -136
- data/test/hexapdf/test_filter.rb +1 -1
- data/test/hexapdf/test_object.rb +1 -1
- data/test/hexapdf/test_parser.rb +13 -8
- data/test/hexapdf/test_revision.rb +14 -0
- data/test/hexapdf/test_revisions.rb +137 -29
- data/test/hexapdf/test_serializer.rb +1 -5
- data/test/hexapdf/test_stream.rb +0 -2
- data/test/hexapdf/test_writer.rb +99 -15
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +0 -1
- data/test/hexapdf/type/acro_form/test_button_field.rb +0 -1
- data/test/hexapdf/type/acro_form/test_text_field.rb +17 -1
- data/test/hexapdf/type/signature/common.rb +55 -53
- data/test/hexapdf/type/test_catalog.rb +8 -0
- data/test/hexapdf/type/test_form.rb +3 -4
- data/test/hexapdf/type/test_names.rb +20 -0
- data/test/hexapdf/type/test_page.rb +1 -2
- data/test/hexapdf/type/test_page_tree_node.rb +21 -1
- data/test/hexapdf/type/test_trailer.rb +3 -3
- data/test/hexapdf/type/test_xref_stream.rb +2 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +11 -1
- data/test/test_helper.rb +5 -39
- metadata +30 -3
- data/test/hexapdf/content/common.rb +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d7da895c4baff0d0e5114a6c423f3f6ca3de02004807d7f5a81c19e404edff1
|
|
4
|
+
data.tar.gz: 89c6dd4709077bf6c6ccb710addeccfdf23a4a75d37dda4357f36c25d5f8865d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5400d99a41fec977ba734bf487af5ce847bdea1f762a0f2df98b45f20952ee4059b08b75ff76ddb3e87db2191f1f7d18b01d9c1d8911b44fbdfc54ea2faa478
|
|
7
|
+
data.tar.gz: f70679b7844a27d2da4f208900309b1820c39174923ab7d0645edbeddaa60455bd359a6e355c254e8764de013078d199846ec5ac443de3d39dd1abc4ad93c890
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,139 @@
|
|
|
1
|
+
## 0.24.1 - 2022-08-11
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
* [HexaPDF::TestUtils] module that contains helper methods useful for testing
|
|
6
|
+
various parts of HexaPDF
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
* All applicable places to only load the current version of PDF objects, to
|
|
11
|
+
avoid possible inconsistencies when working with files containing multiple
|
|
12
|
+
revisions
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
* Parsing of streams with an invalid length value that led to a parsing error
|
|
17
|
+
* [HexaPDF::Object#==] to only allow comparing simple values to non-indirect
|
|
18
|
+
objects and not also other HexaPDF::Object instances
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## 0.24.0 - 2022-08-01
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
* [HexaPDF::Layout::ListBox] for rendering ordered and unordered lists
|
|
26
|
+
* [HexaPDF::Layout::ColumnBox] for rendering content inside columns
|
|
27
|
+
* [HexaPDF::Layout::BoxFitter] for placing boxes into multiple frames
|
|
28
|
+
* New configuration option 'debug' for enabling debug output
|
|
29
|
+
* [HexaPDF::Document::Pages#move] for moving pages around the same document
|
|
30
|
+
* [HexaPDF::Composer#box] for drawing arbitrary, registered boxes
|
|
31
|
+
* [HexaPDF::Layout::Box#split_box?] for determining whether a box is a split
|
|
32
|
+
box, i.e. the continuation of another box
|
|
33
|
+
* [HexaPDF::Document::Layout::ChildrenCollector] to provide an easy method for
|
|
34
|
+
defining children boxes of a container box
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
* **Breaking change**: Refactored [HexaPDF::Layout::Frame] and associated data
|
|
39
|
+
structures so that the complete result of fitting a box is returned
|
|
40
|
+
* [HexaPDF::Layout::Frame] to use a better algorithm for trimming the shape
|
|
41
|
+
* [HexaPDF::Layout::Frame::new] to allow setting the initial shape
|
|
42
|
+
* **Breaking change**: Removed contour line from [HexaPDF::Layout::Frame]
|
|
43
|
+
* **Breaking change**: Changed positional arguments of
|
|
44
|
+
[HexaPDF::Layout::TextBox::new] and [HexaPDF::Layout::ImageBox::new] to
|
|
45
|
+
keyword arguments for a consistent box initialization interface
|
|
46
|
+
* [HexaPDF::Layout::Box#split] to provide a default implementation that is
|
|
47
|
+
useful for most subclasses
|
|
48
|
+
* Layout box implementations to provide a `#supports_position_flow?` method that
|
|
49
|
+
indicates whether the box supports flowing its content around other content.
|
|
50
|
+
* `hexapdf info --check` to only check the current version of each object
|
|
51
|
+
* [HexaPDF::Writer] to make sure the producer information is written when
|
|
52
|
+
writing the file incrementally
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
* [HexaPDF::Layout::TextLayouter] to freeze the new items when a text fragment
|
|
57
|
+
needs to be split
|
|
58
|
+
* [HexaPDF::Layout::TextLayouter] to avoid the possible splitting of a text
|
|
59
|
+
fragment if there would not be enough height left anyway
|
|
60
|
+
* [HexaPDF::Layout::WidthFromPolygon] to work correctly in case of very small
|
|
61
|
+
floating point errors
|
|
62
|
+
* HexaPDF::Layout::TextFragment#inspect to work in case of interspersed
|
|
63
|
+
numbers
|
|
64
|
+
* [HexaPDF::Layout::TextBox#split] to work for position :flow when box is wider
|
|
65
|
+
than the initial available width
|
|
66
|
+
* [HexaPDF::Layout::Frame#fit] to create minimally sized mask rectangles
|
|
67
|
+
* [HexaPDF::Content::GraphicObject::Geom2D] to close the path when drawing
|
|
68
|
+
polygons
|
|
69
|
+
* [HexaPDF::Layout::WidthFromPolygon] to work for all counterclockwise polygons
|
|
70
|
+
* [HexaPDF::Type::PageTreeNode#move_page] to work in case the parent node of the
|
|
71
|
+
moved node doesn't change
|
|
72
|
+
* [HexaPDF::Type::PageTreeNode#move_page] to use the correct target position
|
|
73
|
+
when the moved node is before the target position
|
|
74
|
+
* [HexaPDF::Document::Signatures#add] to work in case the signature object is
|
|
75
|
+
the last object written
|
|
76
|
+
* CLI command `hexapdf inspect` to show correct byte range of the last revision
|
|
77
|
+
* [HexaPDF::Writer#write_incremental] to only use a cross-reference stream if a
|
|
78
|
+
revision directly used one and not through an `/XRefStm` entry
|
|
79
|
+
* [HexaPDF::Encryption::FastARC4] to use RubyARC4 as fallback if OpenSSL has RC4
|
|
80
|
+
disabled
|
|
81
|
+
* [HexaPDF::Font::Encoding::GlyphList] to use binary reading to avoid problems
|
|
82
|
+
on Windows
|
|
83
|
+
* [HexaPDF::Document::Signatures#add] to use binary writing to avoid problems on
|
|
84
|
+
Windows
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
## 0.23.0 - 2022-05-26
|
|
88
|
+
|
|
89
|
+
### Added
|
|
90
|
+
|
|
91
|
+
- [HexaPDF::Composer#create_stamp] for creating a form Xobject
|
|
92
|
+
- [HexaPDF::Revision#reset_objects] for deleting all live loaded and added
|
|
93
|
+
objects
|
|
94
|
+
- Support for removing or flattening annotations to the `hexapdf modify` command
|
|
95
|
+
- Option to CLI command `hexapdf form` to allow generation of a template file
|
|
96
|
+
- Support for centering a floating box in [HexaPDF::Layout::Frame]
|
|
97
|
+
- [HexaPDF::Type::Catalog#names] for easier access to the name dictionary
|
|
98
|
+
- [HexaPDF::Type::Names#destinations] for easier access to the destinations name
|
|
99
|
+
tree
|
|
100
|
+
- [HexaPDF::Document::Destinations], accessible via
|
|
101
|
+
[HexaPDF::Document#destinations], as convenience interface for working with
|
|
102
|
+
destination arrays
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
- **Breaking change**: Refactored the [HexaPDF::Document] interface for working
|
|
107
|
+
with objects and move parts into [HexaPDF::Revisions]
|
|
108
|
+
- **Breaking change**: [HexaPDF::Layout::TextBox] to use whole available width
|
|
109
|
+
when aligning to the center or right
|
|
110
|
+
- **Breaking change**: [HexaPDF::Layout::TextBox] to use whole available height
|
|
111
|
+
when vertically aligning to the center or bottom
|
|
112
|
+
- CLI command `hexapdf inspect` to show the type of revisions, as well as the
|
|
113
|
+
number of objects per revision
|
|
114
|
+
- [HexaPDF::Task::Optimize] to allow skipping invalid content stream operations
|
|
115
|
+
- [HexaPDF::Composer#image] to allow using a form xobject in place of the image
|
|
116
|
+
|
|
117
|
+
### Fixed
|
|
118
|
+
|
|
119
|
+
- [HexaPDF::Writer#write] to write modified objects into the correct revision
|
|
120
|
+
- [HexaPDF::Revisions::from_io] to correctly handle hybrid-reference files
|
|
121
|
+
- [HexaPDF::Writer] to assign a valid object number to a created cross-reference
|
|
122
|
+
stream in all cases
|
|
123
|
+
* [HexaPDF::Type::AcroForm::TextField] to validate the existence of a /MaxLen
|
|
124
|
+
value for comb text fields
|
|
125
|
+
* [HexaPDF::Type::AcroForm::TextField#field_value=] to check for the existence
|
|
126
|
+
of /MaxLen when setting a value for a comb text field
|
|
127
|
+
* [HexaPDF::Type::AcroForm::TextField#field_value=] to check the value against
|
|
128
|
+
/MaxLen
|
|
129
|
+
* [HexaPDF::Layout::TextLayouter#fit] to not use style valign when doing
|
|
130
|
+
variable width layouting
|
|
131
|
+
* [HexaPDF::Utils::SortedTreeNode#find_entry] to work in case of a node without
|
|
132
|
+
a container name or kids key
|
|
133
|
+
* CLI command `hexapdf form` to allow setting array values when using a template
|
|
134
|
+
* CLI command `hexapdf form` to allow setting file select fields
|
|
135
|
+
|
|
136
|
+
|
|
1
137
|
## 0.22.0 - 2022-03-26
|
|
2
138
|
|
|
3
139
|
### Added
|
data/LICENSE
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
2
|
-
Copyright (C) 2014-
|
|
2
|
+
Copyright (C) 2014-2022 Thomas Leitner
|
|
3
3
|
|
|
4
4
|
HexaPDF is free software: you can redistribute it and/or modify it
|
|
5
5
|
under the terms of the GNU Affero General Public License version 3 as
|
data/Rakefile
CHANGED
|
@@ -47,7 +47,7 @@ namespace :dev do
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
task :test_all do
|
|
50
|
-
versions = `rbenv versions --bare | grep -i 2.[
|
|
50
|
+
versions = `rbenv versions --bare | grep -i 2.[67]\\\\\\|3.`.split("\n")
|
|
51
51
|
versions.each do |version|
|
|
52
52
|
sh "eval \"$(rbenv init -)\"; rbenv shell #{version} && ruby -v && rake test"
|
|
53
53
|
end
|
|
@@ -43,8 +43,13 @@ draw_box = lambda do |**args|
|
|
|
43
43
|
|
|
44
44
|
drawn = false
|
|
45
45
|
until drawn
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
result = frame.fit(b)
|
|
47
|
+
if result.success?
|
|
48
|
+
frame.draw(canvas, result)
|
|
49
|
+
drawn = true
|
|
50
|
+
else
|
|
51
|
+
frame.find_next_region
|
|
52
|
+
end
|
|
48
53
|
end
|
|
49
54
|
|
|
50
55
|
canvas.line_width(3).draw(:geom2d, object: frame.shape)
|
|
@@ -19,31 +19,18 @@ include HexaPDF::Utils::GraphicsHelpers
|
|
|
19
19
|
|
|
20
20
|
doc = HexaPDF::Document.new
|
|
21
21
|
|
|
22
|
-
sample_text = "Lorem ipsum dolor sit amet, con\u{00AD}sectetur
|
|
23
|
-
adipis\u{00AD}cing elit, sed do eiusmod tempor incididunt ut labore et
|
|
24
|
-
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
|
|
25
|
-
ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
26
|
-
".tr("\n", ' ') * 10
|
|
27
|
-
items = [TextFragment.create(sample_text, font: doc.fonts.add("Times"))]
|
|
28
|
-
|
|
29
22
|
page = doc.pages.add
|
|
30
23
|
media_box = page.box(:media)
|
|
31
|
-
canvas = page.canvas
|
|
32
24
|
frame = Frame.new(media_box.left + 20, media_box.bottom + 20,
|
|
33
25
|
media_box.width - 40, media_box.height - 40)
|
|
34
26
|
|
|
35
|
-
image = doc.images.add(File.join(__dir__, 'machupicchu.jpg'))
|
|
36
|
-
iw, ih = calculate_dimensions(image.width, image.height, rwidth: 100)
|
|
37
|
-
|
|
38
27
|
boxes = []
|
|
39
|
-
boxes <<
|
|
40
|
-
|
|
41
|
-
canv.image(image, at: [0, 0], width: 100)
|
|
42
|
-
end
|
|
28
|
+
boxes << doc.layout.image_box(File.join(__dir__, 'machupicchu.jpg'),
|
|
29
|
+
width: 100, margin: [10, 30], position: :float)
|
|
43
30
|
boxes << Box.create(width: 50, height: 50, margin: 20,
|
|
44
31
|
position: :float, position_hint: :right,
|
|
45
32
|
border: {width: 1, color: [[255, 0, 0]]})
|
|
46
|
-
boxes <<
|
|
33
|
+
boxes << doc.layout.lorem_ipsum_box(count: 3, position: :flow, align: :justify)
|
|
47
34
|
|
|
48
35
|
i = 0
|
|
49
36
|
frame_filled = false
|
|
@@ -51,8 +38,13 @@ until frame_filled
|
|
|
51
38
|
box = boxes[i]
|
|
52
39
|
drawn = false
|
|
53
40
|
until drawn || frame_filled
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
result = frame.fit(box)
|
|
42
|
+
if result.success?
|
|
43
|
+
frame.draw(page.canvas, result)
|
|
44
|
+
drawn = true
|
|
45
|
+
else
|
|
46
|
+
frame_filled = !frame.find_next_region
|
|
47
|
+
end
|
|
56
48
|
end
|
|
57
49
|
i = (i + 1) % boxes.length
|
|
58
50
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# # Column Box
|
|
2
|
+
#
|
|
3
|
+
# This example shows how [HexaPDF::Layout::ColumnBox] can be used to place
|
|
4
|
+
# contents into columns.
|
|
5
|
+
#
|
|
6
|
+
# Three boxes are placed repeatedly onto the frame until it is filled: two
|
|
7
|
+
# floating boxes (one left, one right) and a text box. The text box is styled to
|
|
8
|
+
# flow its content around the other two boxes.
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# : `ruby column_box.rb`
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
require 'hexapdf'
|
|
15
|
+
|
|
16
|
+
doc = HexaPDF::Document.new
|
|
17
|
+
page = doc.pages.add
|
|
18
|
+
media_box = page.box(:media)
|
|
19
|
+
frame = HexaPDF::Layout::Frame.new(media_box.left + 20, media_box.bottom + 20,
|
|
20
|
+
media_box.width - 40, media_box.height - 40)
|
|
21
|
+
|
|
22
|
+
boxes = []
|
|
23
|
+
5.times do
|
|
24
|
+
boxes << doc.layout.image_box(File.join(__dir__, 'machupicchu.jpg'), width: 100,
|
|
25
|
+
style: {margin: [10, 30], position: :float})
|
|
26
|
+
boxes << HexaPDF::Layout::Box.create(width: 50, height: 50, margin: 20,
|
|
27
|
+
position: :float, position_hint: :right,
|
|
28
|
+
border: {width: 1, color: [[255, 0, 0]]})
|
|
29
|
+
boxes << doc.layout.lorem_ipsum_box(count: 2, position: :flow, align: :justify)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
polygon = Geom2D::Polygon([200, 350], [400, 350], [400, 450], [200, 450])
|
|
33
|
+
frame.remove_area(polygon)
|
|
34
|
+
page.canvas.draw(:geom2d, object: polygon)
|
|
35
|
+
|
|
36
|
+
columns = doc.layout.box(:column, children: boxes, columns: 2, style: {position: :flow})
|
|
37
|
+
result = frame.fit(columns)
|
|
38
|
+
frame.draw(page.canvas, result)
|
|
39
|
+
|
|
40
|
+
doc.write("column_box.pdf", optimize: true)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# # List Box
|
|
2
|
+
#
|
|
3
|
+
# This example shows how [HexaPDF::Layout::ListBox] can be used to place
|
|
4
|
+
# contents into lists.
|
|
5
|
+
#
|
|
6
|
+
# The list box class provides several options to style the item marker
|
|
7
|
+
# and its general appearance.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# : `ruby list_box.rb`
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
require 'hexapdf'
|
|
14
|
+
|
|
15
|
+
HexaPDF::Composer.create("list_box.pdf") do |composer|
|
|
16
|
+
composer.box(:list, content_indentation: 40, item_spacing: 20) do |list|
|
|
17
|
+
list.lorem_ipsum_box
|
|
18
|
+
list.image(File.join(__dir__, 'machupicchu.jpg'), height: 100)
|
|
19
|
+
list.box(:list, item_type: :decimal) do |sub_list|
|
|
20
|
+
1.upto(10) {|i| sub_list.text("Item #{i}") }
|
|
21
|
+
end
|
|
22
|
+
list.box(:column) do |column|
|
|
23
|
+
column.lorem_ipsum_box(count: 3)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/hexapdf/cli/batch.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
data/lib/hexapdf/cli/command.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
|
@@ -244,7 +244,7 @@ module HexaPDF
|
|
|
244
244
|
compress_pages: @out_options.compress_pages,
|
|
245
245
|
prune_page_resources: @out_options.prune_page_resources)
|
|
246
246
|
if @out_options.streams != :preserve || @out_options.optimize_fonts
|
|
247
|
-
doc.each
|
|
247
|
+
doc.each do |obj|
|
|
248
248
|
optimize_stream(obj)
|
|
249
249
|
optimize_font(obj)
|
|
250
250
|
end
|
|
@@ -352,7 +352,7 @@ module HexaPDF
|
|
|
352
352
|
def remove_unused_pages(doc)
|
|
353
353
|
retained = doc.pages.each_with_object({}) {|page, h| h[page.data] = true }
|
|
354
354
|
retained[doc.pages.root.data] = true
|
|
355
|
-
doc.each
|
|
355
|
+
doc.each do |obj|
|
|
356
356
|
next unless obj.kind_of?(HexaPDF::Dictionary)
|
|
357
357
|
if (obj.type == :Pages || obj.type == :Page) && !retained.key?(obj.data)
|
|
358
358
|
doc.delete(obj)
|
data/lib/hexapdf/cli/files.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
data/lib/hexapdf/cli/fonts.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
data/lib/hexapdf/cli/form.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
|
@@ -70,6 +70,9 @@ module HexaPDF
|
|
|
70
70
|
@template = template
|
|
71
71
|
@fill = true
|
|
72
72
|
end
|
|
73
|
+
options.on('--generate-template', 'Print a template for use with --template') do
|
|
74
|
+
@generate_template = true
|
|
75
|
+
end
|
|
73
76
|
options.on('--flatten', 'Flatten the form fields') do
|
|
74
77
|
@flatten = true
|
|
75
78
|
end
|
|
@@ -85,6 +88,7 @@ module HexaPDF
|
|
|
85
88
|
@password = nil
|
|
86
89
|
@fill = false
|
|
87
90
|
@flatten = false
|
|
91
|
+
@generate_template = false
|
|
88
92
|
@template = nil
|
|
89
93
|
@need_appearances = nil
|
|
90
94
|
@incremental = true
|
|
@@ -117,6 +121,15 @@ module HexaPDF
|
|
|
117
121
|
doc.catalog.delete(:AcroForm)
|
|
118
122
|
doc.delete(doc.acro_form)
|
|
119
123
|
end
|
|
124
|
+
elsif @generate_template
|
|
125
|
+
unsupported_fields = [:signature_field, :password_field]
|
|
126
|
+
each_field(doc) do |_, _, field, _|
|
|
127
|
+
next if unsupported_fields.include?(field.concrete_field_type)
|
|
128
|
+
name = field.full_field_name.gsub(':', "\\:")
|
|
129
|
+
Array(field.field_value).each do |val|
|
|
130
|
+
puts "#{name}: #{val.to_s.gsub(/(\r|\r\n|\n)/, '\1 ')}"
|
|
131
|
+
end
|
|
132
|
+
end
|
|
120
133
|
else
|
|
121
134
|
list_form_fields(doc)
|
|
122
135
|
end
|
|
@@ -220,8 +233,16 @@ module HexaPDF
|
|
|
220
233
|
field_name = scanner.scan(/(\\:|[^:])*?:/)
|
|
221
234
|
break unless field_name
|
|
222
235
|
field_name.gsub!(/\\:/, ':')
|
|
236
|
+
field_name.chop!
|
|
223
237
|
field_value = scanner.scan(/.*?(?=^\S|\z)/m)
|
|
224
|
-
|
|
238
|
+
next unless field_value
|
|
239
|
+
field_value = field_value.strip.gsub(/^\s*/, '')
|
|
240
|
+
if data.key?(field_name)
|
|
241
|
+
data[field_name] = [data[field_name]] unless data[field_name].kind_of?(Array)
|
|
242
|
+
data[field_name] << field_value
|
|
243
|
+
else
|
|
244
|
+
data[field_name] = field_value
|
|
245
|
+
end
|
|
225
246
|
end
|
|
226
247
|
if !scanner.eos? && command_parser.verbosity_warning?
|
|
227
248
|
$stderr.puts "Warning: Some template could not be parsed"
|
|
@@ -232,8 +253,8 @@ module HexaPDF
|
|
|
232
253
|
# Applies the given value to the field.
|
|
233
254
|
def apply_field_value(field, value)
|
|
234
255
|
case field.concrete_field_type
|
|
235
|
-
when :single_line_text_field, :multiline_text_field, :comb_text_field, :
|
|
236
|
-
:list_box, :editable_combo_box
|
|
256
|
+
when :single_line_text_field, :multiline_text_field, :comb_text_field, :file_select_field,
|
|
257
|
+
:combo_box, :list_box, :editable_combo_box
|
|
237
258
|
field.field_value = value
|
|
238
259
|
when :check_box
|
|
239
260
|
field.field_value = case value
|
|
@@ -249,6 +270,8 @@ module HexaPDF
|
|
|
249
270
|
else
|
|
250
271
|
raise "Field type #{field.concrete_field_type} not yet supported"
|
|
251
272
|
end
|
|
273
|
+
rescue StandardError
|
|
274
|
+
raise "Error while setting '#{field.full_field_name}': #{$!.message}"
|
|
252
275
|
end
|
|
253
276
|
|
|
254
277
|
# Iterates over all non-push button fields in page order. If a field appears on multiple
|
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
data/lib/hexapdf/cli/images.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
data/lib/hexapdf/cli/info.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
|
@@ -103,7 +103,7 @@ module HexaPDF
|
|
|
103
103
|
"#{correctable ? '(correctable)' : ''}"
|
|
104
104
|
end
|
|
105
105
|
doc.trailer.validate(auto_correct: true, &validation_block)
|
|
106
|
-
doc.each(
|
|
106
|
+
doc.each(only_loaded: false) do |obj|
|
|
107
107
|
indirect_object = obj
|
|
108
108
|
obj.validate(auto_correct: true, &validation_block)
|
|
109
109
|
end
|
data/lib/hexapdf/cli/inspect.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
|
@@ -229,10 +229,19 @@ module HexaPDF
|
|
|
229
229
|
end
|
|
230
230
|
IO.copy_stream(@doc.revisions.parser.io, $stdout, length, 0)
|
|
231
231
|
else
|
|
232
|
-
puts "Document has #{@doc.revisions.
|
|
233
|
-
revision_information do |
|
|
232
|
+
puts "Document has #{@doc.revisions.count} revision#{@doc.revisions.count == 1 ? '' : 's'}"
|
|
233
|
+
revision_information do |rev, index, count, signature, end_offset|
|
|
234
|
+
type = if rev.trailer[:XRefStm]
|
|
235
|
+
"xref table + stream"
|
|
236
|
+
elsif rev.trailer[:Type] == :XRef
|
|
237
|
+
"xref stream"
|
|
238
|
+
else
|
|
239
|
+
"xref table"
|
|
240
|
+
end
|
|
234
241
|
puts "Revision #{index + 1}"
|
|
242
|
+
puts " Type : #{type}"
|
|
235
243
|
puts " Objects : #{count}"
|
|
244
|
+
puts " Size : #{rev.trailer[:Size]}"
|
|
236
245
|
puts " Signed : yes" if signature
|
|
237
246
|
puts " Byte range: 0-#{end_offset}"
|
|
238
247
|
end
|
|
@@ -345,14 +354,14 @@ module HexaPDF
|
|
|
345
354
|
buffer = ''.b
|
|
346
355
|
while io.pos < startxrefs[index + 1]
|
|
347
356
|
buffer << io.read(1_000)
|
|
348
|
-
if (buffer_index = buffer.index(/(?:\n|\r\n?)\s*%%EOF\s*(?:\n|\r\n?)
|
|
357
|
+
if (buffer_index = buffer.index(/(?:\n|\r\n?)\s*%%EOF\s*(?:\n|\r\n?)?/))
|
|
349
358
|
end_index = io.pos - buffer.size + buffer_index + $~[0].size
|
|
350
359
|
break
|
|
351
360
|
end
|
|
352
361
|
buffer = buffer[-20..-1]
|
|
353
362
|
end
|
|
354
363
|
end
|
|
355
|
-
yield(rev, index, rev.
|
|
364
|
+
yield(rev, index, rev.each.count, sig, end_index)
|
|
356
365
|
end
|
|
357
366
|
end
|
|
358
367
|
|
data/lib/hexapdf/cli/merge.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
data/lib/hexapdf/cli/modify.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
|
@@ -53,14 +53,15 @@ module HexaPDF
|
|
|
53
53
|
super('modify', takes_commands: false)
|
|
54
54
|
short_desc("Modify a PDF file")
|
|
55
55
|
long_desc(<<~EOF)
|
|
56
|
-
This command modifies a PDF file. It can be used to select pages that should
|
|
57
|
-
the output file and/or rotate them. The output file can also be
|
|
58
|
-
optimized in various ways.
|
|
56
|
+
This command modifies a PDF file. It can be used, for example, to select pages that should
|
|
57
|
+
appear in the output file and/or rotate them. The output file can also be
|
|
58
|
+
encrypted/decrypted and optimized in various ways.
|
|
59
59
|
EOF
|
|
60
60
|
|
|
61
61
|
@password = nil
|
|
62
62
|
@pages = '1-e'
|
|
63
63
|
@embed_files = []
|
|
64
|
+
@annotation_mode = nil
|
|
64
65
|
|
|
65
66
|
options.on("--password PASSWORD", "-p", String,
|
|
66
67
|
"The password for decryption. Use - for reading from standard input.") do |pwd|
|
|
@@ -74,6 +75,10 @@ module HexaPDF
|
|
|
74
75
|
"used multiple times)") do |file|
|
|
75
76
|
@embed_files << file
|
|
76
77
|
end
|
|
78
|
+
options.on("--annotations MODE", [:remove, :flatten], "Handling of annotations (either " \
|
|
79
|
+
"remove or flatten)") do |mode|
|
|
80
|
+
@annotation_mode = mode
|
|
81
|
+
end
|
|
77
82
|
define_optimization_options
|
|
78
83
|
define_encryption_options
|
|
79
84
|
end
|
|
@@ -82,6 +87,7 @@ module HexaPDF
|
|
|
82
87
|
maybe_raise_on_existing_file(out_file)
|
|
83
88
|
with_document(in_file, password: @password, out_file: out_file) do |doc|
|
|
84
89
|
arrange_pages(doc) unless @pages == '1-e'
|
|
90
|
+
handle_annotations(doc)
|
|
85
91
|
@embed_files.each {|file| doc.files.add(file, embed: true) }
|
|
86
92
|
apply_encryption_options(doc)
|
|
87
93
|
apply_optimization_options(doc)
|
|
@@ -109,6 +115,20 @@ module HexaPDF
|
|
|
109
115
|
doc.pages.add unless doc.pages.count > 0
|
|
110
116
|
end
|
|
111
117
|
|
|
118
|
+
# Handles the annotations of all selected pages by doing nothing, removing them or flattening
|
|
119
|
+
# them.
|
|
120
|
+
def handle_annotations(doc)
|
|
121
|
+
return unless @annotation_mode
|
|
122
|
+
|
|
123
|
+
doc.pages.each do |page|
|
|
124
|
+
if @annotation_mode == :remove
|
|
125
|
+
page.delete(:Annots)
|
|
126
|
+
else
|
|
127
|
+
page.flatten_annotations
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
112
132
|
end
|
|
113
133
|
|
|
114
134
|
end
|
data/lib/hexapdf/cli/optimize.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
|
@@ -90,7 +90,7 @@ module HexaPDF
|
|
|
90
90
|
end
|
|
91
91
|
doc.catalog[:Pages] = page_tree
|
|
92
92
|
|
|
93
|
-
doc.each
|
|
93
|
+
doc.each do |obj, revision|
|
|
94
94
|
next unless obj.kind_of?(HexaPDF::Dictionary)
|
|
95
95
|
if (obj.type == :Pages || obj.type == :Page) && !retained.key?(obj.data)
|
|
96
96
|
revision.delete(obj)
|
data/lib/hexapdf/cli/split.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|
data/lib/hexapdf/cli.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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-2022 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
|