hexapdf 0.21.1 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +137 -0
  3. data/LICENSE +1 -1
  4. data/Rakefile +1 -1
  5. data/examples/016-frame_automatic_box_placement.rb +7 -2
  6. data/examples/017-frame_text_flow.rb +10 -18
  7. data/examples/020-column_box.rb +20 -37
  8. data/examples/021-list_box.rb +26 -0
  9. data/lib/hexapdf/cli/batch.rb +1 -1
  10. data/lib/hexapdf/cli/command.rb +1 -1
  11. data/lib/hexapdf/cli/files.rb +1 -1
  12. data/lib/hexapdf/cli/fonts.rb +1 -1
  13. data/lib/hexapdf/cli/form.rb +31 -4
  14. data/lib/hexapdf/cli/image2pdf.rb +1 -1
  15. data/lib/hexapdf/cli/images.rb +1 -1
  16. data/lib/hexapdf/cli/info.rb +2 -2
  17. data/lib/hexapdf/cli/inspect.rb +19 -6
  18. data/lib/hexapdf/cli/merge.rb +1 -1
  19. data/lib/hexapdf/cli/modify.rb +24 -4
  20. data/lib/hexapdf/cli/optimize.rb +1 -1
  21. data/lib/hexapdf/cli/split.rb +1 -1
  22. data/lib/hexapdf/cli/watermark.rb +1 -1
  23. data/lib/hexapdf/cli.rb +1 -1
  24. data/lib/hexapdf/composer.rb +66 -125
  25. data/lib/hexapdf/configuration.rb +17 -1
  26. data/lib/hexapdf/content/canvas.rb +1 -1
  27. data/lib/hexapdf/content/color_space.rb +1 -1
  28. data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
  29. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
  30. data/lib/hexapdf/content/graphic_object/geom2d.rb +2 -1
  31. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  32. data/lib/hexapdf/content/graphic_object.rb +1 -1
  33. data/lib/hexapdf/content/graphics_state.rb +1 -1
  34. data/lib/hexapdf/content/operator.rb +1 -1
  35. data/lib/hexapdf/content/parser.rb +1 -1
  36. data/lib/hexapdf/content/processor.rb +1 -1
  37. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  38. data/lib/hexapdf/content.rb +1 -1
  39. data/lib/hexapdf/data_dir.rb +1 -1
  40. data/lib/hexapdf/dictionary.rb +1 -1
  41. data/lib/hexapdf/dictionary_fields.rb +2 -2
  42. data/lib/hexapdf/document/destinations.rb +396 -0
  43. data/lib/hexapdf/document/files.rb +1 -1
  44. data/lib/hexapdf/document/fonts.rb +1 -1
  45. data/lib/hexapdf/document/images.rb +1 -1
  46. data/lib/hexapdf/document/layout.rb +397 -0
  47. data/lib/hexapdf/document/pages.rb +17 -1
  48. data/lib/hexapdf/document/signatures.rb +5 -4
  49. data/lib/hexapdf/document.rb +46 -90
  50. data/lib/hexapdf/encryption/aes.rb +1 -1
  51. data/lib/hexapdf/encryption/arc4.rb +1 -1
  52. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  53. data/lib/hexapdf/encryption/fast_arc4.rb +30 -21
  54. data/lib/hexapdf/encryption/identity.rb +1 -1
  55. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  56. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  57. data/lib/hexapdf/encryption/security_handler.rb +1 -1
  58. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
  59. data/lib/hexapdf/encryption.rb +1 -1
  60. data/lib/hexapdf/error.rb +1 -1
  61. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  62. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  63. data/lib/hexapdf/filter/crypt.rb +1 -1
  64. data/lib/hexapdf/filter/encryption.rb +1 -1
  65. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  66. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  67. data/lib/hexapdf/filter/pass_through.rb +1 -1
  68. data/lib/hexapdf/filter/predictor.rb +1 -1
  69. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  70. data/lib/hexapdf/filter.rb +1 -1
  71. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  72. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  73. data/lib/hexapdf/font/cmap.rb +1 -1
  74. data/lib/hexapdf/font/encoding/base.rb +1 -1
  75. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  76. data/lib/hexapdf/font/encoding/glyph_list.rb +2 -2
  77. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  78. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  79. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  80. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  81. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  82. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  83. data/lib/hexapdf/font/encoding.rb +1 -1
  84. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  85. data/lib/hexapdf/font/true_type/builder.rb +1 -1
  86. data/lib/hexapdf/font/true_type/font.rb +1 -1
  87. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  88. data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
  89. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  90. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  91. data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
  92. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  93. data/lib/hexapdf/font/true_type/table/head.rb +1 -1
  94. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  95. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  96. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  97. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  98. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  99. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  100. data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
  101. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  102. data/lib/hexapdf/font/true_type/table.rb +1 -1
  103. data/lib/hexapdf/font/true_type.rb +1 -1
  104. data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
  105. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  106. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  107. data/lib/hexapdf/font/type1/font.rb +1 -1
  108. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  109. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  110. data/lib/hexapdf/font/type1.rb +1 -1
  111. data/lib/hexapdf/font/type1_wrapper.rb +1 -1
  112. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  113. data/lib/hexapdf/font_loader/from_file.rb +1 -1
  114. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  115. data/lib/hexapdf/font_loader.rb +1 -1
  116. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  117. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  118. data/lib/hexapdf/image_loader/png.rb +1 -1
  119. data/lib/hexapdf/image_loader.rb +1 -1
  120. data/lib/hexapdf/importer.rb +1 -1
  121. data/lib/hexapdf/layout/box.rb +121 -22
  122. data/lib/hexapdf/layout/box_fitter.rb +136 -0
  123. data/lib/hexapdf/layout/column_box.rb +168 -89
  124. data/lib/hexapdf/layout/frame.rb +155 -140
  125. data/lib/hexapdf/layout/image_box.rb +19 -4
  126. data/lib/hexapdf/layout/inline_box.rb +1 -1
  127. data/lib/hexapdf/layout/line.rb +1 -1
  128. data/lib/hexapdf/layout/list_box.rb +355 -0
  129. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  130. data/lib/hexapdf/layout/style.rb +285 -8
  131. data/lib/hexapdf/layout/text_box.rb +30 -11
  132. data/lib/hexapdf/layout/text_fragment.rb +3 -2
  133. data/lib/hexapdf/layout/text_layouter.rb +23 -3
  134. data/lib/hexapdf/layout/text_shaper.rb +1 -1
  135. data/lib/hexapdf/layout/width_from_polygon.rb +12 -7
  136. data/lib/hexapdf/layout.rb +4 -1
  137. data/lib/hexapdf/name_tree_node.rb +1 -1
  138. data/lib/hexapdf/number_tree_node.rb +1 -1
  139. data/lib/hexapdf/object.rb +1 -1
  140. data/lib/hexapdf/parser.rb +1 -8
  141. data/lib/hexapdf/pdf_array.rb +1 -1
  142. data/lib/hexapdf/rectangle.rb +1 -1
  143. data/lib/hexapdf/reference.rb +1 -1
  144. data/lib/hexapdf/revision.rb +9 -2
  145. data/lib/hexapdf/revisions.rb +152 -51
  146. data/lib/hexapdf/serializer.rb +1 -1
  147. data/lib/hexapdf/stream.rb +1 -1
  148. data/lib/hexapdf/task/dereference.rb +1 -1
  149. data/lib/hexapdf/task/optimize.rb +22 -12
  150. data/lib/hexapdf/task.rb +1 -1
  151. data/lib/hexapdf/tokenizer.rb +1 -1
  152. data/lib/hexapdf/type/acro_form/appearance_generator.rb +1 -1
  153. data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
  154. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  155. data/lib/hexapdf/type/acro_form/field.rb +1 -1
  156. data/lib/hexapdf/type/acro_form/form.rb +12 -6
  157. data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
  158. data/lib/hexapdf/type/acro_form/text_field.rb +9 -1
  159. data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
  160. data/lib/hexapdf/type/acro_form.rb +1 -1
  161. data/lib/hexapdf/type/action.rb +1 -1
  162. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  163. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  164. data/lib/hexapdf/type/actions/launch.rb +1 -1
  165. data/lib/hexapdf/type/actions/uri.rb +1 -1
  166. data/lib/hexapdf/type/actions.rb +1 -1
  167. data/lib/hexapdf/type/annotation.rb +1 -1
  168. data/lib/hexapdf/type/annotations/link.rb +1 -1
  169. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  170. data/lib/hexapdf/type/annotations/text.rb +1 -1
  171. data/lib/hexapdf/type/annotations/widget.rb +1 -1
  172. data/lib/hexapdf/type/annotations.rb +1 -1
  173. data/lib/hexapdf/type/catalog.rb +10 -2
  174. data/lib/hexapdf/type/cid_font.rb +1 -1
  175. data/lib/hexapdf/type/embedded_file.rb +1 -1
  176. data/lib/hexapdf/type/file_specification.rb +1 -1
  177. data/lib/hexapdf/type/font.rb +1 -1
  178. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  179. data/lib/hexapdf/type/font_simple.rb +1 -1
  180. data/lib/hexapdf/type/font_true_type.rb +1 -1
  181. data/lib/hexapdf/type/font_type0.rb +1 -1
  182. data/lib/hexapdf/type/font_type1.rb +1 -1
  183. data/lib/hexapdf/type/font_type3.rb +1 -1
  184. data/lib/hexapdf/type/form.rb +1 -1
  185. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  186. data/lib/hexapdf/type/icon_fit.rb +1 -1
  187. data/lib/hexapdf/type/image.rb +48 -4
  188. data/lib/hexapdf/type/info.rb +1 -1
  189. data/lib/hexapdf/type/names.rb +14 -1
  190. data/lib/hexapdf/type/object_stream.rb +1 -1
  191. data/lib/hexapdf/type/page.rb +1 -1
  192. data/lib/hexapdf/type/page_tree_node.rb +19 -2
  193. data/lib/hexapdf/type/resources.rb +1 -1
  194. data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +1 -1
  195. data/lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb +1 -1
  196. data/lib/hexapdf/type/signature/handler.rb +1 -1
  197. data/lib/hexapdf/type/signature/verification_result.rb +1 -1
  198. data/lib/hexapdf/type/signature.rb +1 -1
  199. data/lib/hexapdf/type/trailer.rb +2 -2
  200. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  201. data/lib/hexapdf/type/xref_stream.rb +3 -2
  202. data/lib/hexapdf/type.rb +1 -1
  203. data/lib/hexapdf/utils/bit_field.rb +1 -1
  204. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  205. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  206. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  207. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  208. data/lib/hexapdf/utils/object_hash.rb +1 -1
  209. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  210. data/lib/hexapdf/utils/sorted_tree_node.rb +4 -2
  211. data/lib/hexapdf/version.rb +2 -2
  212. data/lib/hexapdf/writer.rb +23 -8
  213. data/lib/hexapdf/xref_section.rb +1 -1
  214. data/lib/hexapdf.rb +1 -1
  215. data/test/hexapdf/content/graphic_object/test_geom2d.rb +1 -1
  216. data/test/hexapdf/document/test_destinations.rb +338 -0
  217. data/test/hexapdf/document/test_images.rb +1 -1
  218. data/test/hexapdf/document/test_layout.rb +264 -0
  219. data/test/hexapdf/document/test_pages.rb +9 -0
  220. data/test/hexapdf/document/test_signatures.rb +10 -3
  221. data/test/hexapdf/encryption/test_security_handler.rb +3 -3
  222. data/test/hexapdf/font/encoding/test_glyph_list.rb +4 -0
  223. data/test/hexapdf/layout/test_box.rb +53 -3
  224. data/test/hexapdf/layout/test_box_fitter.rb +62 -0
  225. data/test/hexapdf/layout/test_column_box.rb +159 -0
  226. data/test/hexapdf/layout/test_frame.rb +114 -39
  227. data/test/hexapdf/layout/test_image_box.rb +1 -1
  228. data/test/hexapdf/layout/test_list_box.rb +249 -0
  229. data/test/hexapdf/layout/test_text_box.rb +33 -2
  230. data/test/hexapdf/layout/test_text_fragment.rb +1 -1
  231. data/test/hexapdf/layout/test_text_layouter.rb +49 -17
  232. data/test/hexapdf/layout/test_width_from_polygon.rb +13 -0
  233. data/test/hexapdf/task/test_optimize.rb +17 -4
  234. data/test/hexapdf/test_composer.rb +35 -1
  235. data/test/hexapdf/test_dictionary_fields.rb +10 -10
  236. data/test/hexapdf/test_document.rb +33 -136
  237. data/test/hexapdf/test_filter.rb +1 -1
  238. data/test/hexapdf/test_parser.rb +1 -3
  239. data/test/hexapdf/test_revision.rb +14 -0
  240. data/test/hexapdf/test_revisions.rb +137 -29
  241. data/test/hexapdf/test_serializer.rb +1 -5
  242. data/test/hexapdf/test_writer.rb +99 -15
  243. data/test/hexapdf/type/acro_form/test_form.rb +2 -1
  244. data/test/hexapdf/type/acro_form/test_text_field.rb +17 -0
  245. data/test/hexapdf/type/test_catalog.rb +8 -0
  246. data/test/hexapdf/type/test_image.rb +45 -9
  247. data/test/hexapdf/type/test_names.rb +20 -0
  248. data/test/hexapdf/type/test_page_tree_node.rb +21 -1
  249. data/test/hexapdf/type/test_trailer.rb +3 -3
  250. data/test/hexapdf/type/test_xref_stream.rb +2 -1
  251. data/test/hexapdf/utils/test_sorted_tree_node.rb +11 -1
  252. data/test/test_helper.rb +5 -1
  253. metadata +29 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9792b3c8be5fd3c3521aa5fe1a66e1315f677494f199e3e8b0e1eb85c9b967c7
4
- data.tar.gz: a66f1d6751cac4ca2fc6a35bf493ba60eefee96edca090ae92ed810b756d8761
3
+ metadata.gz: 9be9871c8033a23eb240dc0b6300bcb33ba8ccef107f35189cb8af3faf308a61
4
+ data.tar.gz: 875797999dc46cefdb39dd31f1649525a11716915af5a83a6c38c0dc100cca2e
5
5
  SHA512:
6
- metadata.gz: 111570ec411684ffe5214833419128b697721c4e5fdd16b61578c3d459a8ab9dde411780dd582e06620d52a260062df30a116b7c3c8544647f5e61f131c6bdc5
7
- data.tar.gz: 3d098cb4098f6a02bc832cbe70aebc0b28a40a21b33b53c8e8e055f240fd513a5d96f53846c62ebbc2a00d17d6f99271dd3850e98a70cebb6f32e1a7e279cc87
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-2021 Thomas Leitner
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.[567]\\\\\\|3.`.split("\n")
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
- drawn = frame.draw(canvas, b)
47
- frame.find_next_region unless drawn
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 << Box.create(width: iw, height: ih,
40
- margin: [10, 30], position: :float) do |canv, box|
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 << TextBox.new(items, style: {position: :flow, align: :justify})
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
- drawn = frame.draw(canvas, box)
55
- frame_filled = !frame.find_next_region unless drawn
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
@@ -1,57 +1,40 @@
1
- # ## Column Box
1
+ # # Column Box
2
2
  #
3
- # This example shows how [HexaPDF::Layout::Frame] and [HexaPDF::Layout::TextBox]
4
- # can be used to flow text around objects.
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 frame_text_flow.rb`
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
- canvas = page.canvas
32
- frame = Frame.new(media_box.left + 20, media_box.bottom + 20,
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
- 3.times do
40
- boxes << Box.create(width: iw, height: ih,
41
- margin: [10, 30], position: :float) do |canv, box|
42
- canv.image(image, at: [0, 0], width: 100)
43
- end
44
- boxes << Box.create(width: 50, height: 50, margin: 20,
45
- position: :float, position_hint: :right,
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
- columns = ColumnBox.new(boxes) #, style: {position: :flow})
50
- polygon = Geom2D::Polygon([250, 350], [350, 350], [350, 500], [250, 500])
51
- #frame.remove_area(polygon)
52
- #canvas.draw(:geom2d, object: polygon)
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
- p result.success?
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
@@ -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-2021 Thomas Leitner
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-2021 Thomas Leitner
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-2021 Thomas Leitner
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-2021 Thomas Leitner
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-2021 Thomas Leitner
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
- data[field_name.chop] = field_value.strip.gsub(/^\s*/, '') if field_value
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, :combo_box,
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-2021 Thomas Leitner
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-2021 Thomas Leitner
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-2021 Thomas Leitner
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: false, only_loaded: false) do |obj|
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
@@ -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-2021 Thomas Leitner
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.size} revision#{@doc.revisions.size == 1 ? '' : 's'}"
233
- revision_information do |_, index, count, signature, end_offset|
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
- if io.gets =~ /^\s*%%EOF\s*$/
347
- end_index = io.pos
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.next_free_oid - 1, sig, end_index)
364
+ yield(rev, index, rev.each.count, sig, end_index)
352
365
  end
353
366
  end
354
367
 
@@ -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-2021 Thomas Leitner
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-2021 Thomas Leitner
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 appear in
57
- the output file and/or rotate them. The output file can also be encrypted/decrypted and
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
@@ -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-2021 Thomas Leitner
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-2021 Thomas Leitner
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