hexapdf 0.22.0 → 0.24.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|