hexapdf 0.21.1 → 0.24.0

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