hexapdf 0.21.1 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +137 -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 +20 -37
- data/examples/021-list_box.rb +26 -0
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +1 -1
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +31 -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 +19 -6
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +24 -4
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/cli.rb +1 -1
- data/lib/hexapdf/composer.rb +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 +2 -2
- data/lib/hexapdf/document/destinations.rb +396 -0
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/layout.rb +397 -0
- data/lib/hexapdf/document/pages.rb +17 -1
- data/lib/hexapdf/document/signatures.rb +5 -4
- data/lib/hexapdf/document.rb +46 -90
- 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 +168 -89
- 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 +1 -1
- data/lib/hexapdf/parser.rb +1 -8
- 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 +152 -51
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +22 -12
- data/lib/hexapdf/task.rb +1 -1
- 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 +12 -6
- 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 +48 -4
- 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 -1
- 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_security_handler.rb +3 -3
- data/test/hexapdf/font/encoding/test_glyph_list.rb +4 -0
- data/test/hexapdf/layout/test_box.rb +53 -3
- data/test/hexapdf/layout/test_box_fitter.rb +62 -0
- data/test/hexapdf/layout/test_column_box.rb +159 -0
- data/test/hexapdf/layout/test_frame.rb +114 -39
- data/test/hexapdf/layout/test_image_box.rb +1 -1
- data/test/hexapdf/layout/test_list_box.rb +249 -0
- data/test/hexapdf/layout/test_text_box.rb +33 -2
- data/test/hexapdf/layout/test_text_fragment.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +49 -17
- 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 -1
- data/test/hexapdf/test_dictionary_fields.rb +10 -10
- data/test/hexapdf/test_document.rb +33 -136
- data/test/hexapdf/test_filter.rb +1 -1
- data/test/hexapdf/test_parser.rb +1 -3
- 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_writer.rb +99 -15
- data/test/hexapdf/type/acro_form/test_form.rb +2 -1
- data/test/hexapdf/type/acro_form/test_text_field.rb +17 -0
- data/test/hexapdf/type/test_catalog.rb +8 -0
- data/test/hexapdf/type/test_image.rb +45 -9
- data/test/hexapdf/type/test_names.rb +20 -0
- 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 -1
- metadata +29 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9be9871c8033a23eb240dc0b6300bcb33ba8ccef107f35189cb8af3faf308a61
|
4
|
+
data.tar.gz: 875797999dc46cefdb39dd31f1649525a11716915af5a83a6c38c0dc100cca2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8700678297a316b14a604045ab7da8c371d7cbcebb771d8c878fff4306e36ff7e72b898fb4c63e98599493a7b93480a34bd099dc102ef0e431d825fe1e11ae41
|
7
|
+
data.tar.gz: 4892bb8868475b4bfe65c5938097589f9544bb4b7b9bef568b1ac60a7932eced09f2eee53edc38212654e522c4cc4e5edd8fde7cb6b6078e27ccf18e131e96aa
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,140 @@
|
|
1
|
+
## 0.24.0 - 2022-08-01
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* [HexaPDF::Layout::ListBox] for rendering ordered and unordered lists
|
6
|
+
* [HexaPDF::Layout::ColumnBox] for rendering content inside columns
|
7
|
+
* [HexaPDF::Layout::BoxFitter] for placing boxes into multiple frames
|
8
|
+
* New configuration option 'debug' for enabling debug output
|
9
|
+
* [HexaPDF::Document::Pages#move] for moving pages around the same document
|
10
|
+
* [HexaPDF::Composer#box] for drawing arbitrary, registered boxes
|
11
|
+
* [HexaPDF::Layout::Box#split_box?] for determining whether a box is a split
|
12
|
+
box, i.e. the continuation of another box
|
13
|
+
* [HexaPDF::Document::Layout::ChildrenCollector] to provide an easy method for
|
14
|
+
defining children boxes of a container box
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
* **Breaking change**: Refactored [HexaPDF::Layout::Frame] and associated data
|
19
|
+
structures so that the complete result of fitting a box is returned
|
20
|
+
* [HexaPDF::Layout::Frame] to use a better algorithm for trimming the shape
|
21
|
+
* [HexaPDF::Layout::Frame::new] to allow setting the initial shape
|
22
|
+
* **Breaking change**: Removed contour line from [HexaPDF::Layout::Frame]
|
23
|
+
* **Breaking change**: Changed positional arguments of
|
24
|
+
[HexaPDF::Layout::TextBox::new] and [HexaPDF::Layout::ImageBox::new] to
|
25
|
+
keyword arguments for a consistent box initialization interface
|
26
|
+
* [HexaPDF::Layout::Box#split] to provide a default implementation that is
|
27
|
+
useful for most subclasses
|
28
|
+
* Layout box implementations to provide a `#supports_position_flow?` method that
|
29
|
+
indicates whether the box supports flowing its content around other content.
|
30
|
+
* `hexapdf info --check` to only check the current version of each object
|
31
|
+
* [HexaPDF::Writer] to make sure the producer information is written when
|
32
|
+
writing the file incrementally
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
|
36
|
+
* [HexaPDF::Layout::TextLayouter] to freeze the new items when a text fragment
|
37
|
+
needs to be split
|
38
|
+
* [HexaPDF::Layout::TextLayouter] to avoid the possible splitting of a text
|
39
|
+
fragment if there would not be enough height left anyway
|
40
|
+
* [HexaPDF::Layout::WidthFromPolygon] to work correctly in case of very small
|
41
|
+
floating point errors
|
42
|
+
* HexaPDF::Layout::TextFragment#inspect to work in case of interspersed
|
43
|
+
numbers
|
44
|
+
* [HexaPDF::Layout::TextBox#split] to work for position :flow when box is wider
|
45
|
+
than the initial available width
|
46
|
+
* [HexaPDF::Layout::Frame#fit] to create minimally sized mask rectangles
|
47
|
+
* [HexaPDF::Content::GraphicObject::Geom2D] to close the path when drawing
|
48
|
+
polygons
|
49
|
+
* [HexaPDF::Layout::WidthFromPolygon] to work for all counterclockwise polygons
|
50
|
+
* [HexaPDF::Type::PageTreeNode#move_page] to work in case the parent node of the
|
51
|
+
moved node doesn't change
|
52
|
+
* [HexaPDF::Type::PageTreeNode#move_page] to use the correct target position
|
53
|
+
when the moved node is before the target position
|
54
|
+
* [HexaPDF::Document::Signatures#add] to work in case the signature object is
|
55
|
+
the last object written
|
56
|
+
* CLI command `hexapdf inspect` to show correct byte range of the last revision
|
57
|
+
* [HexaPDF::Writer#write_incremental] to only use a cross-reference stream if a
|
58
|
+
revision directly used one and not through an `/XRefStm` entry
|
59
|
+
* [HexaPDF::Encryption::FastARC4] to use RubyARC4 as fallback if OpenSSL has RC4
|
60
|
+
disabled
|
61
|
+
* [HexaPDF::Font::Encoding::GlyphList] to use binary reading to avoid problems
|
62
|
+
on Windows
|
63
|
+
* [HexaPDF::Document::Signatures#add] to use binary writing to avoid problems on
|
64
|
+
Windows
|
65
|
+
|
66
|
+
|
67
|
+
## 0.23.0 - 2022-05-26
|
68
|
+
|
69
|
+
### Added
|
70
|
+
|
71
|
+
- [HexaPDF::Composer#create_stamp] for creating a form Xobject
|
72
|
+
- [HexaPDF::Revision#reset_objects] for deleting all live loaded and added
|
73
|
+
objects
|
74
|
+
- Support for removing or flattening annotations to the `hexapdf modify` command
|
75
|
+
- Option to CLI command `hexapdf form` to allow generation of a template file
|
76
|
+
- Support for centering a floating box in [HexaPDF::Layout::Frame]
|
77
|
+
- [HexaPDF::Type::Catalog#names] for easier access to the name dictionary
|
78
|
+
- [HexaPDF::Type::Names#destinations] for easier access to the destinations name
|
79
|
+
tree
|
80
|
+
- [HexaPDF::Document::Destinations], accessible via
|
81
|
+
[HexaPDF::Document#destinations], as convenience interface for working with
|
82
|
+
destination arrays
|
83
|
+
|
84
|
+
### Changed
|
85
|
+
|
86
|
+
- **Breaking change**: Refactored the [HexaPDF::Document] interface for working
|
87
|
+
with objects and move parts into [HexaPDF::Revisions]
|
88
|
+
- **Breaking change**: [HexaPDF::Layout::TextBox] to use whole available width
|
89
|
+
when aligning to the center or right
|
90
|
+
- **Breaking change**: [HexaPDF::Layout::TextBox] to use whole available height
|
91
|
+
when vertically aligning to the center or bottom
|
92
|
+
- CLI command `hexapdf inspect` to show the type of revisions, as well as the
|
93
|
+
number of objects per revision
|
94
|
+
- [HexaPDF::Task::Optimize] to allow skipping invalid content stream operations
|
95
|
+
- [HexaPDF::Composer#image] to allow using a form xobject in place of the image
|
96
|
+
|
97
|
+
### Fixed
|
98
|
+
|
99
|
+
- [HexaPDF::Writer#write] to write modified objects into the correct revision
|
100
|
+
- [HexaPDF::Revisions::from_io] to correctly handle hybrid-reference files
|
101
|
+
- [HexaPDF::Writer] to assign a valid object number to a created cross-reference
|
102
|
+
stream in all cases
|
103
|
+
* [HexaPDF::Type::AcroForm::TextField] to validate the existence of a /MaxLen
|
104
|
+
value for comb text fields
|
105
|
+
* [HexaPDF::Type::AcroForm::TextField#field_value=] to check for the existence
|
106
|
+
of /MaxLen when setting a value for a comb text field
|
107
|
+
* [HexaPDF::Type::AcroForm::TextField#field_value=] to check the value against
|
108
|
+
/MaxLen
|
109
|
+
* [HexaPDF::Layout::TextLayouter#fit] to not use style valign when doing
|
110
|
+
variable width layouting
|
111
|
+
* [HexaPDF::Utils::SortedTreeNode#find_entry] to work in case of a node without
|
112
|
+
a container name or kids key
|
113
|
+
* CLI command `hexapdf form` to allow setting array values when using a template
|
114
|
+
* CLI command `hexapdf form` to allow setting file select fields
|
115
|
+
|
116
|
+
|
117
|
+
## 0.22.0 - 2022-03-26
|
118
|
+
|
119
|
+
### Added
|
120
|
+
|
121
|
+
- Support for writing images with an ICCBased color space
|
122
|
+
- Support for writing images with soft masks
|
123
|
+
|
124
|
+
### Changed
|
125
|
+
|
126
|
+
- CLI command `hexapdf form` to show a warning when working with a file
|
127
|
+
containing an XFA form
|
128
|
+
|
129
|
+
### Fixed
|
130
|
+
|
131
|
+
- [HexaPDF::Type::AcroForm::Form#field_by_name] to work correctly when field
|
132
|
+
name parts are UTF-16BE encoded
|
133
|
+
- `hexapdf inspect` command 'revision' to correctly detect the end of revisions
|
134
|
+
- [HexaPDF::DictionaryFields::StringConverter] to use correct method name
|
135
|
+
`HexaPDF::Document#config`
|
136
|
+
|
137
|
+
|
1
138
|
## 0.21.1 - 2022-03-12
|
2
139
|
|
3
140
|
### Fixed
|
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
|
data/examples/020-column_box.rb
CHANGED
@@ -1,57 +1,40 @@
|
|
1
|
-
#
|
1
|
+
# # Column Box
|
2
2
|
#
|
3
|
-
# This example shows how [HexaPDF::Layout::
|
4
|
-
#
|
3
|
+
# This example shows how [HexaPDF::Layout::ColumnBox] can be used to place
|
4
|
+
# contents into columns.
|
5
5
|
#
|
6
6
|
# Three boxes are placed repeatedly onto the frame until it is filled: two
|
7
7
|
# floating boxes (one left, one right) and a text box. The text box is styled to
|
8
8
|
# flow its content around the other two boxes.
|
9
9
|
#
|
10
10
|
# Usage:
|
11
|
-
# : `ruby
|
11
|
+
# : `ruby column_box.rb`
|
12
12
|
#
|
13
13
|
|
14
14
|
require 'hexapdf'
|
15
|
-
require 'hexapdf/utils/graphics_helpers'
|
16
|
-
|
17
|
-
include HexaPDF::Layout
|
18
|
-
include HexaPDF::Utils::GraphicsHelpers
|
19
15
|
|
20
16
|
doc = HexaPDF::Document.new
|
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", ' ') * 5
|
27
|
-
items = [TextFragment.create(sample_text, font: doc.fonts.add("Times"))]
|
28
|
-
|
29
17
|
page = doc.pages.add
|
30
18
|
media_box = page.box(:media)
|
31
|
-
|
32
|
-
|
33
|
-
media_box.width - 40, media_box.height - 40)
|
34
|
-
|
35
|
-
image = doc.images.add(File.join(__dir__, 'machupicchu.jpg'))
|
36
|
-
iw, ih = calculate_dimensions(image.width, image.height, rwidth: 100)
|
19
|
+
frame = HexaPDF::Layout::Frame.new(media_box.left + 20, media_box.bottom + 20,
|
20
|
+
media_box.width - 40, media_box.height - 40)
|
37
21
|
|
38
22
|
boxes = []
|
39
|
-
|
40
|
-
boxes <<
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
border: {width: 1, color: [[255, 0, 0]]})
|
47
|
-
boxes << TextBox.new(items, style: {position: :flow, align: :justify})
|
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)
|
48
30
|
end
|
49
|
-
|
50
|
-
polygon = Geom2D::Polygon([
|
51
|
-
|
52
|
-
|
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})
|
53
37
|
result = frame.fit(columns)
|
54
|
-
|
55
|
-
frame.draw(canvas, result)
|
38
|
+
frame.draw(page.canvas, result)
|
56
39
|
|
57
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
|
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
|
@@ -97,6 +101,10 @@ module HexaPDF
|
|
97
101
|
end
|
98
102
|
with_document(in_file, password: @password, out_file: out_file,
|
99
103
|
incremental: @incremental) do |doc|
|
104
|
+
if doc.acro_form[:XFA]
|
105
|
+
$stderr.puts "Warning: Unsupported XFA form detected, some things may not work correctly"
|
106
|
+
end
|
107
|
+
|
100
108
|
if !doc.acro_form
|
101
109
|
raise "This PDF doesn't contain an interactive form"
|
102
110
|
elsif out_file
|
@@ -113,6 +121,15 @@ module HexaPDF
|
|
113
121
|
doc.catalog.delete(:AcroForm)
|
114
122
|
doc.delete(doc.acro_form)
|
115
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
|
116
133
|
else
|
117
134
|
list_form_fields(doc)
|
118
135
|
end
|
@@ -216,8 +233,16 @@ module HexaPDF
|
|
216
233
|
field_name = scanner.scan(/(\\:|[^:])*?:/)
|
217
234
|
break unless field_name
|
218
235
|
field_name.gsub!(/\\:/, ':')
|
236
|
+
field_name.chop!
|
219
237
|
field_value = scanner.scan(/.*?(?=^\S|\z)/m)
|
220
|
-
|
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
|
221
246
|
end
|
222
247
|
if !scanner.eos? && command_parser.verbosity_warning?
|
223
248
|
$stderr.puts "Warning: Some template could not be parsed"
|
@@ -228,8 +253,8 @@ module HexaPDF
|
|
228
253
|
# Applies the given value to the field.
|
229
254
|
def apply_field_value(field, value)
|
230
255
|
case field.concrete_field_type
|
231
|
-
when :single_line_text_field, :multiline_text_field, :comb_text_field, :
|
232
|
-
: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
|
233
258
|
field.field_value = value
|
234
259
|
when :check_box
|
235
260
|
field.field_value = case value
|
@@ -245,6 +270,8 @@ module HexaPDF
|
|
245
270
|
else
|
246
271
|
raise "Field type #{field.concrete_field_type} not yet supported"
|
247
272
|
end
|
273
|
+
rescue StandardError
|
274
|
+
raise "Error while setting '#{field.full_field_name}': #{$!.message}"
|
248
275
|
end
|
249
276
|
|
250
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(only_current:
|
106
|
+
doc.each(only_current: true, 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
|
@@ -342,13 +351,17 @@ module HexaPDF
|
|
342
351
|
end_index = sig[:ByteRange][-2] + sig[:ByteRange][-1]
|
343
352
|
else
|
344
353
|
io.seek(startxrefs[index], IO::SEEK_SET)
|
354
|
+
buffer = ''.b
|
345
355
|
while io.pos < startxrefs[index + 1]
|
346
|
-
|
347
|
-
|
356
|
+
buffer << io.read(1_000)
|
357
|
+
if (buffer_index = buffer.index(/(?:\n|\r\n?)\s*%%EOF\s*(?:\n|\r\n?)?/))
|
358
|
+
end_index = io.pos - buffer.size + buffer_index + $~[0].size
|
359
|
+
break
|
348
360
|
end
|
361
|
+
buffer = buffer[-20..-1]
|
349
362
|
end
|
350
363
|
end
|
351
|
-
yield(rev, index, rev.
|
364
|
+
yield(rev, index, rev.each.count, sig, end_index)
|
352
365
|
end
|
353
366
|
end
|
354
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
|
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
|