hexapdf 1.6.0 → 1.8.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 (287) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -0
  3. data/LICENSE +1 -1
  4. data/examples/005-merging.rb +2 -1
  5. data/examples/032-acro_form_list_and_fill.rb +47 -0
  6. data/examples/033-text_extraction.rb +34 -0
  7. data/lib/hexapdf/cli/batch.rb +1 -1
  8. data/lib/hexapdf/cli/command.rb +1 -1
  9. data/lib/hexapdf/cli/debug_info.rb +1 -1
  10. data/lib/hexapdf/cli/files.rb +1 -1
  11. data/lib/hexapdf/cli/fonts.rb +6 -4
  12. data/lib/hexapdf/cli/form.rb +1 -1
  13. data/lib/hexapdf/cli/image2pdf.rb +1 -1
  14. data/lib/hexapdf/cli/images.rb +17 -17
  15. data/lib/hexapdf/cli/info.rb +3 -1
  16. data/lib/hexapdf/cli/inspect.rb +1 -1
  17. data/lib/hexapdf/cli/merge.rb +14 -2
  18. data/lib/hexapdf/cli/modify.rb +1 -1
  19. data/lib/hexapdf/cli/optimize.rb +1 -1
  20. data/lib/hexapdf/cli/split.rb +1 -1
  21. data/lib/hexapdf/cli/usage.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 +1 -1
  25. data/lib/hexapdf/configuration.rb +10 -1
  26. data/lib/hexapdf/content/canvas.rb +2 -2
  27. data/lib/hexapdf/content/canvas_composer.rb +1 -1
  28. data/lib/hexapdf/content/color_space.rb +1 -1
  29. data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
  30. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
  31. data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
  32. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  33. data/lib/hexapdf/content/graphic_object.rb +1 -1
  34. data/lib/hexapdf/content/graphics_state.rb +1 -1
  35. data/lib/hexapdf/content/operator.rb +1 -1
  36. data/lib/hexapdf/content/parser.rb +1 -1
  37. data/lib/hexapdf/content/processor.rb +1 -1
  38. data/lib/hexapdf/content/smart_text_extractor.rb +311 -0
  39. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  40. data/lib/hexapdf/content.rb +3 -1
  41. data/lib/hexapdf/data_dir.rb +1 -1
  42. data/lib/hexapdf/dictionary.rb +1 -1
  43. data/lib/hexapdf/dictionary_fields.rb +1 -1
  44. data/lib/hexapdf/digital_signature/cms_handler.rb +1 -1
  45. data/lib/hexapdf/digital_signature/handler.rb +1 -1
  46. data/lib/hexapdf/digital_signature/pkcs1_handler.rb +1 -1
  47. data/lib/hexapdf/digital_signature/signature.rb +1 -1
  48. data/lib/hexapdf/digital_signature/signatures.rb +1 -1
  49. data/lib/hexapdf/digital_signature/signing/default_handler.rb +2 -16
  50. data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +22 -9
  51. data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +1 -1
  52. data/lib/hexapdf/digital_signature/signing.rb +1 -1
  53. data/lib/hexapdf/digital_signature/verification_result.rb +1 -1
  54. data/lib/hexapdf/digital_signature.rb +1 -1
  55. data/lib/hexapdf/document/annotations.rb +1 -1
  56. data/lib/hexapdf/document/destinations.rb +1 -1
  57. data/lib/hexapdf/document/files.rb +1 -1
  58. data/lib/hexapdf/document/fonts.rb +1 -1
  59. data/lib/hexapdf/document/images.rb +1 -1
  60. data/lib/hexapdf/document/layout.rb +1 -1
  61. data/lib/hexapdf/document/metadata.rb +1 -1
  62. data/lib/hexapdf/document/pages.rb +1 -1
  63. data/lib/hexapdf/document.rb +8 -4
  64. data/lib/hexapdf/encryption/aes.rb +1 -1
  65. data/lib/hexapdf/encryption/arc4.rb +1 -1
  66. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  67. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  68. data/lib/hexapdf/encryption/identity.rb +1 -1
  69. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  70. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  71. data/lib/hexapdf/encryption/security_handler.rb +1 -1
  72. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
  73. data/lib/hexapdf/encryption.rb +1 -1
  74. data/lib/hexapdf/error.rb +1 -1
  75. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  76. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  77. data/lib/hexapdf/filter/brotli_decode.rb +88 -0
  78. data/lib/hexapdf/filter/crypt.rb +1 -1
  79. data/lib/hexapdf/filter/encryption.rb +1 -1
  80. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  81. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  82. data/lib/hexapdf/filter/pass_through.rb +1 -1
  83. data/lib/hexapdf/filter/predictor.rb +1 -1
  84. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  85. data/lib/hexapdf/filter.rb +2 -1
  86. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  87. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  88. data/lib/hexapdf/font/cmap.rb +1 -1
  89. data/lib/hexapdf/font/encoding/base.rb +1 -1
  90. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  91. data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
  92. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  93. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  94. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  95. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  96. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  97. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  98. data/lib/hexapdf/font/encoding.rb +1 -1
  99. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  100. data/lib/hexapdf/font/true_type/builder.rb +2 -2
  101. data/lib/hexapdf/font/true_type/font.rb +14 -1
  102. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  103. data/lib/hexapdf/font/true_type/subsetter.rb +11 -6
  104. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  105. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  106. data/lib/hexapdf/font/true_type/table/directory.rb +6 -1
  107. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  108. data/lib/hexapdf/font/true_type/table/head.rb +1 -1
  109. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  110. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  111. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  112. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  113. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  114. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  115. data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
  116. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  117. data/lib/hexapdf/font/true_type/table.rb +1 -1
  118. data/lib/hexapdf/font/true_type.rb +2 -1
  119. data/lib/hexapdf/font/true_type_wrapper.rb +3 -3
  120. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  121. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  122. data/lib/hexapdf/font/type1/font.rb +1 -1
  123. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  124. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  125. data/lib/hexapdf/font/type1.rb +1 -1
  126. data/lib/hexapdf/font/type1_wrapper.rb +1 -1
  127. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  128. data/lib/hexapdf/font_loader/from_file.rb +5 -1
  129. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  130. data/lib/hexapdf/font_loader/variant_from_name.rb +1 -1
  131. data/lib/hexapdf/font_loader.rb +1 -1
  132. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  133. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  134. data/lib/hexapdf/image_loader/png.rb +1 -1
  135. data/lib/hexapdf/image_loader.rb +1 -1
  136. data/lib/hexapdf/importer.rb +1 -1
  137. data/lib/hexapdf/layout/box.rb +1 -1
  138. data/lib/hexapdf/layout/box_fitter.rb +1 -1
  139. data/lib/hexapdf/layout/column_box.rb +1 -1
  140. data/lib/hexapdf/layout/container_box.rb +1 -1
  141. data/lib/hexapdf/layout/frame.rb +1 -1
  142. data/lib/hexapdf/layout/image_box.rb +1 -1
  143. data/lib/hexapdf/layout/inline_box.rb +1 -1
  144. data/lib/hexapdf/layout/line.rb +1 -1
  145. data/lib/hexapdf/layout/list_box.rb +1 -1
  146. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  147. data/lib/hexapdf/layout/page_style.rb +1 -1
  148. data/lib/hexapdf/layout/style.rb +7 -3
  149. data/lib/hexapdf/layout/table_box.rb +1 -1
  150. data/lib/hexapdf/layout/text_box.rb +1 -1
  151. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  152. data/lib/hexapdf/layout/text_layouter.rb +1 -1
  153. data/lib/hexapdf/layout/text_shaper.rb +1 -1
  154. data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
  155. data/lib/hexapdf/layout.rb +1 -1
  156. data/lib/hexapdf/name_tree_node.rb +1 -1
  157. data/lib/hexapdf/number_tree_node.rb +1 -1
  158. data/lib/hexapdf/object.rb +1 -1
  159. data/lib/hexapdf/parser.rb +1 -1
  160. data/lib/hexapdf/pdf_array.rb +1 -1
  161. data/lib/hexapdf/rectangle.rb +1 -1
  162. data/lib/hexapdf/reference.rb +1 -1
  163. data/lib/hexapdf/revision.rb +1 -1
  164. data/lib/hexapdf/revisions.rb +1 -1
  165. data/lib/hexapdf/serializer.rb +3 -3
  166. data/lib/hexapdf/stream.rb +1 -1
  167. data/lib/hexapdf/task/dereference.rb +1 -1
  168. data/lib/hexapdf/task/import_pages.rb +185 -0
  169. data/lib/hexapdf/task/merge_acro_form.rb +1 -1
  170. data/lib/hexapdf/task/optimize.rb +1 -1
  171. data/lib/hexapdf/task/pdfa.rb +109 -2
  172. data/lib/hexapdf/task.rb +2 -1
  173. data/lib/hexapdf/test_utils.rb +1 -1
  174. data/lib/hexapdf/tokenizer.rb +1 -1
  175. data/lib/hexapdf/type/acro_form/appearance_generator.rb +1 -1
  176. data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
  177. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  178. data/lib/hexapdf/type/acro_form/field.rb +1 -1
  179. data/lib/hexapdf/type/acro_form/form.rb +5 -1
  180. data/lib/hexapdf/type/acro_form/java_script_actions.rb +1 -1
  181. data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
  182. data/lib/hexapdf/type/acro_form/text_field.rb +5 -3
  183. data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
  184. data/lib/hexapdf/type/acro_form.rb +1 -1
  185. data/lib/hexapdf/type/action.rb +1 -1
  186. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  187. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  188. data/lib/hexapdf/type/actions/launch.rb +1 -1
  189. data/lib/hexapdf/type/actions/set_ocg_state.rb +1 -1
  190. data/lib/hexapdf/type/actions/uri.rb +1 -1
  191. data/lib/hexapdf/type/actions.rb +1 -1
  192. data/lib/hexapdf/type/annotation.rb +1 -1
  193. data/lib/hexapdf/type/annotations/appearance_generator.rb +1 -1
  194. data/lib/hexapdf/type/annotations/border_effect.rb +1 -1
  195. data/lib/hexapdf/type/annotations/border_styling.rb +1 -1
  196. data/lib/hexapdf/type/annotations/circle.rb +1 -1
  197. data/lib/hexapdf/type/annotations/interior_color.rb +1 -1
  198. data/lib/hexapdf/type/annotations/line.rb +1 -1
  199. data/lib/hexapdf/type/annotations/line_ending_styling.rb +1 -1
  200. data/lib/hexapdf/type/annotations/link.rb +1 -1
  201. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  202. data/lib/hexapdf/type/annotations/polygon.rb +1 -1
  203. data/lib/hexapdf/type/annotations/polygon_polyline.rb +1 -1
  204. data/lib/hexapdf/type/annotations/polyline.rb +1 -1
  205. data/lib/hexapdf/type/annotations/square.rb +1 -1
  206. data/lib/hexapdf/type/annotations/square_circle.rb +1 -1
  207. data/lib/hexapdf/type/annotations/text.rb +1 -1
  208. data/lib/hexapdf/type/annotations/widget.rb +10 -1
  209. data/lib/hexapdf/type/annotations.rb +1 -1
  210. data/lib/hexapdf/type/catalog.rb +1 -1
  211. data/lib/hexapdf/type/cid_font.rb +1 -1
  212. data/lib/hexapdf/type/cmap.rb +1 -1
  213. data/lib/hexapdf/type/document_security_store.rb +80 -0
  214. data/lib/hexapdf/type/embedded_file.rb +1 -1
  215. data/lib/hexapdf/type/file_specification.rb +1 -1
  216. data/lib/hexapdf/type/font.rb +4 -4
  217. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  218. data/lib/hexapdf/type/font_simple.rb +1 -1
  219. data/lib/hexapdf/type/font_true_type.rb +1 -1
  220. data/lib/hexapdf/type/font_type0.rb +1 -1
  221. data/lib/hexapdf/type/font_type1.rb +1 -1
  222. data/lib/hexapdf/type/font_type3.rb +6 -1
  223. data/lib/hexapdf/type/form.rb +1 -1
  224. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  225. data/lib/hexapdf/type/icon_fit.rb +1 -1
  226. data/lib/hexapdf/type/image.rb +1 -1
  227. data/lib/hexapdf/type/info.rb +1 -1
  228. data/lib/hexapdf/type/mark_information.rb +1 -1
  229. data/lib/hexapdf/type/marked_content_reference.rb +1 -1
  230. data/lib/hexapdf/type/measure.rb +1 -1
  231. data/lib/hexapdf/type/metadata.rb +1 -1
  232. data/lib/hexapdf/type/names.rb +1 -1
  233. data/lib/hexapdf/type/namespace.rb +1 -1
  234. data/lib/hexapdf/type/object_reference.rb +1 -1
  235. data/lib/hexapdf/type/object_stream.rb +1 -1
  236. data/lib/hexapdf/type/optional_content_configuration.rb +1 -1
  237. data/lib/hexapdf/type/optional_content_group.rb +1 -1
  238. data/lib/hexapdf/type/optional_content_membership.rb +1 -1
  239. data/lib/hexapdf/type/optional_content_properties.rb +1 -1
  240. data/lib/hexapdf/type/outline.rb +1 -1
  241. data/lib/hexapdf/type/outline_item.rb +1 -1
  242. data/lib/hexapdf/type/output_intent.rb +1 -1
  243. data/lib/hexapdf/type/page.rb +12 -1
  244. data/lib/hexapdf/type/page_label.rb +1 -1
  245. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  246. data/lib/hexapdf/type/resources.rb +1 -1
  247. data/lib/hexapdf/type/struct_elem.rb +1 -1
  248. data/lib/hexapdf/type/struct_tree_root.rb +1 -1
  249. data/lib/hexapdf/type/trailer.rb +1 -1
  250. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  251. data/lib/hexapdf/type/xref_stream.rb +1 -1
  252. data/lib/hexapdf/type.rb +2 -1
  253. data/lib/hexapdf/utils/bit_field.rb +1 -1
  254. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  255. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  256. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  257. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  258. data/lib/hexapdf/utils/object_hash.rb +1 -1
  259. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  260. data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
  261. data/lib/hexapdf/utils.rb +1 -1
  262. data/lib/hexapdf/version.rb +2 -2
  263. data/lib/hexapdf/writer.rb +1 -1
  264. data/lib/hexapdf/xref_section.rb +1 -1
  265. data/lib/hexapdf.rb +1 -1
  266. data/test/data/pdfa/mismatching_glyph_widths_cidfont_type2.pdf +0 -0
  267. data/test/hexapdf/content/test_smart_text_extractor.rb +129 -0
  268. data/test/hexapdf/digital_signature/common.rb +19 -5
  269. data/test/hexapdf/digital_signature/signing/test_signed_data_creator.rb +29 -4
  270. data/test/hexapdf/digital_signature/test_signatures.rb +3 -3
  271. data/test/hexapdf/filter/test_brotli_decode.rb +34 -0
  272. data/test/hexapdf/font/test_true_type_wrapper.rb +2 -2
  273. data/test/hexapdf/font/true_type/table/test_directory.rb +5 -3
  274. data/test/hexapdf/font/true_type/test_builder.rb +9 -0
  275. data/test/hexapdf/font/true_type/test_font.rb +17 -3
  276. data/test/hexapdf/font/true_type/test_subsetter.rb +11 -9
  277. data/test/hexapdf/font_loader/test_from_file.rb +7 -0
  278. data/test/hexapdf/task/test_import_pages.rb +126 -0
  279. data/test/hexapdf/task/test_pdfa.rb +72 -0
  280. data/test/hexapdf/test_document.rb +13 -0
  281. data/test/hexapdf/test_serializer.rb +1 -1
  282. data/test/hexapdf/type/acro_form/test_form.rb +6 -0
  283. data/test/hexapdf/type/acro_form/test_text_field.rb +7 -1
  284. data/test/hexapdf/type/annotations/test_widget.rb +11 -0
  285. data/test/hexapdf/type/test_font_type3.rb +4 -0
  286. data/test/hexapdf/type/test_page.rb +8 -0
  287. metadata +25 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35bbb5d1780d07ecf6098cc40359ff2cc02cd89231a124b6ff1a0a13c760d116
4
- data.tar.gz: 8664f2ac8a6651ee83e7292d005ea10d89b7ea738de47cc62dbf219f4eae0cb4
3
+ metadata.gz: 0e9f612a2b916386baa8a689c47463faf4fff424732101ea75f3bb221c4cf824
4
+ data.tar.gz: 60384753e3b5ac2da147631c567933e94342115e8423f4fc718a55aac3bc986c
5
5
  SHA512:
6
- metadata.gz: 232aefc90eb4f9f9a913d27affa95a0c9eff43a72e04eeb1adc0fbe11e865033c6fd0b7779930b15a982afdd909d6ffa98640db6db668f95ce0c26332749cfae
7
- data.tar.gz: e1b836a23d58e92ceb70f5b892d023edcf585288583f2254d35394688204bfdbf4401edea6562a96d1583a71a302d8d50e8a175262ff5077a3b4a2200ec922a4
6
+ metadata.gz: c9dff3546d3a3636ea4d9a0f9a3d9e649c20c642b6bebb53b8c98adf49a46f6cce11a8cf2d8a0761766ad98fec360c54a52333ecad027ea0694941599266c648
7
+ data.tar.gz: bbc5c0d5af26c6369009a0ddf8d652b1a562c0d89c64e007f2e294af4f34032fa4524814e1dc19f20213148453f88f79de8def53121bb1fda4e44093458987c7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,53 @@
1
+ ## 1.8.0 - 2026-05-14
2
+
3
+ ### Added
4
+
5
+ * [HexaPDF::Task::ImportPages] for importing pages while preserving the optional
6
+ content configuration and interactive form fields
7
+ * [HexaPDF::Type::FontType3#embedded?] as Type 3 fonts are always embedded
8
+ * CLI options `--acro-form` and `--optional-content` to `hexapdf merge` for
9
+ specifying how interactive form fields and optional content are handled
10
+
11
+ ### Changed
12
+
13
+ * Serialization of strings to avoid problems with buggy Ghostscript versions
14
+ * [HexaPDF::FontLoader::FromFile] to raise an error when loading a non-TrueType
15
+ font
16
+
17
+ ### Fixed
18
+
19
+ * CLI command `hexapdf fonts` to work for Type 3 fonts
20
+ * CLI command `hexapdf images` to correctly show images nested in Form XObjects
21
+
22
+
23
+ ## 1.7.0 - 2026-04-13
24
+
25
+ ### Added
26
+
27
+ * Smart text extraction for retrieving layouted text from pages
28
+ * Support for digitally signing with ECDSA keys
29
+ * Support for digitally signing with DSA keys
30
+ * Support for BrotliDecode filter
31
+ * [HexaPDF::Type::DocumentSecurityStore] and
32
+ [HexaPDF::Type::DocumentSecurityStore::ValidationRelatedInformation]
33
+
34
+ ### Changed
35
+
36
+ * **Breaking change**: [HexaPDF::Document#unwrap] to not unwrap streams
37
+ * Automatic detection of digital signature size to account for small deviations
38
+ * [HexaPDF::Type::AcroForm::Form#fill] to ignore password fields
39
+ * [HexaPDF::Type::AcroForm::TextField] validation to convert invalid Symbol
40
+ values to String
41
+ * [HexaPDF::Type::Annotations::Widget] validation to also validate a widget as a
42
+ field if necessary
43
+ * PDF/A task to include a fix for mismatching glyph widths for Type 2 CID fonts
44
+
45
+ ### Fixed
46
+
47
+ * Writing of PDF documents with an invalid value for the /Info dictionary
48
+ * Subsetting of TrueType fonts in case compound glyphs are themselves compound
49
+
50
+
1
51
  ## 1.6.0 - 2026-02-10
2
52
 
3
53
  ### Added
data/LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
2
- Copyright (C) 2014-2025 Thomas Leitner
2
+ Copyright (C) 2014-2026 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
@@ -8,7 +8,8 @@
8
8
  #
9
9
  # For example, named destinations are not properly handled by the code.
10
10
  # Sometimes other things like attached files or a document outline
11
- # should also be preserved.
11
+ # should also be preserved. For more advanced importing of pages see
12
+ # [HexaPDF::Task::ImportPages].
12
13
  #
13
14
  # The hexapdf binary provides a command for merging files which does
14
15
  # the merging in a more sophisticated way.
@@ -0,0 +1,47 @@
1
+ # # PDF Forms - List and fill fields
2
+ #
3
+ # This example shows how to list the form fields of an interactive PDF form and
4
+ # how to fill out the form.
5
+ #
6
+ # The output file from the [PDF forms](acro_form.html) example can be used as
7
+ # input.
8
+ #
9
+ # One way to list and fill a PDF form is to use the [HexaPDF CLI with the 'form'
10
+ # command](/documentation/hexapdf.1.html#form). Here, however, we are doing it
11
+ # with the HexaPDF API.
12
+ #
13
+ # Usage:
14
+ # : `ruby acro_form_list_and_fill.rb [INPUT.PDF]`
15
+ #
16
+
17
+ require 'base64'
18
+ require 'hexapdf'
19
+
20
+ doc = HexaPDF::Document.open(ARGV[0] || 'acro_form.pdf')
21
+ exit unless doc.acro_form
22
+
23
+ puts "Listing all form fields:"
24
+ doc.acro_form.each_field do |field|
25
+ puts "#{field.full_field_name} (#{field.concrete_field_type})"
26
+ end
27
+
28
+ # We are using this to generate some values for existing text fields. In the
29
+ # real world one would be getting the values from the user.
30
+ puts "\nFilling in the text fields with random values:"
31
+ values = {}
32
+ doc.acro_form.each_field do |field|
33
+ next unless field.field_type == :Tx
34
+ value = Base64.encode64(field.full_field_name).strip
35
+ value = if field.key?(:MaxLen)
36
+ value[0, field[:MaxLen]]
37
+ else
38
+ "Value #{field.field_type} #{value}"
39
+ end
40
+ values[field.full_field_name] = value
41
+ puts "#{field.full_field_name}: #{value}"
42
+ end
43
+
44
+ # Now actually fill out the form the values
45
+ doc.acro_form.fill(values)
46
+
47
+ doc.write('acro_form_list_and_fill.pdf', optimize: true)
@@ -0,0 +1,34 @@
1
+ # # Text Extraction
2
+ #
3
+ # This example shows how to extract layouted text from a page.
4
+ #
5
+ # It uses the provided input PDF or creates a small sample PDF as input. Then it
6
+ # extracts the text for each page and creates new pages with the extracted text
7
+ # in a fixed-width font.
8
+ #
9
+ # Usage:
10
+ # : `ruby text_extraction.rb [INPUT.PDF]`
11
+ #
12
+
13
+ require 'hexapdf'
14
+
15
+ # Use the input PDF or create a sample PDF.
16
+ if ARGV.length > 0
17
+ doc = HexaPDF::Document.open(ARGV[0])
18
+ else
19
+ composer = HexaPDF::Composer.new do |pdf|
20
+ pdf.lorem_ipsum(count: 3, padding: [0, 0, 20])
21
+ pdf.lorem_ipsum(padding: [0, 50, 20], text_indent: 40)
22
+ pdf.lorem_ipsum(count: 2)
23
+ end
24
+ doc = composer.document
25
+ end
26
+
27
+ # Extract the existing pages and add new ones with the extracted text
28
+ doc.pages.count.times do |index|
29
+ text = doc.pages[index].extract_text
30
+ doc.pages.add.canvas.font('/usr/share/fonts/truetype/freefont/FreeMono.ttf', size: 6).
31
+ text(text, at: [10, 820])
32
+ end
33
+
34
+ doc.write('text_extraction.pdf', optimize: true)
@@ -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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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
@@ -96,11 +96,13 @@ module HexaPDF
96
96
  else
97
97
  "Built-in"
98
98
  end
99
- size = human_readable_file_size(font.embedded? ? font.font_file[:Length] : 0)
99
+ size = human_readable_file_size(font.embedded? && font_type != 'Type 3' ?
100
+ font.font_file[:Length] : 0)
101
+ font_name = font[:BaseFont] || font[:FontDescriptor][:FontName]
100
102
  embedded = (font.embedded? ? "yes" : "no")
101
- subset = (font[:BaseFont].match?(/\A[A-Z]{6}\+/) ? "yes" : "no")
103
+ subset = font_name.match?(/\A[A-Z]{6}\+/) ? "yes" : "no"
102
104
  printf("%5s %-40s %-12s %-10s %-3s %-3s %8s %9s\n",
103
- pindex, font[:BaseFont], font_type, encoding,
105
+ pindex, font_name, font_type, encoding,
104
106
  embedded, subset, size, "#{font.oid},#{font.gen}")
105
107
  end
106
108
  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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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
@@ -52,11 +52,10 @@ module HexaPDF
52
52
  # The mapping of XObject name to [x_ppi, y_ppi].
53
53
  attr_reader :result
54
54
 
55
- # Initialize the processor with the names of the images for which the PPI should be
56
- # determined.
57
- def initialize(names, user_unit)
55
+ # Initialize the processor with the image XObjects for which the PPI should be determined.
56
+ def initialize(images, user_unit)
58
57
  super()
59
- @names = names
58
+ @images = images
60
59
  @user_unit = user_unit
61
60
  @result = {}
62
61
  end
@@ -64,9 +63,8 @@ module HexaPDF
64
63
  # Determine the PPI in x- and y-directions of the specified images.
65
64
  def paint_xobject(name)
66
65
  super
67
- return unless @names.delete(name)
68
66
  xobject = resources.xobject(name)
69
- return unless xobject[:Subtype] == :Image
67
+ return unless @images.delete(xobject) && xobject[:Subtype] == :Image
70
68
 
71
69
  w, h = xobject.width, xobject.height
72
70
  llx, lly = graphics_state.ctm.evaluate(0, 0).map {|i| i * @user_unit }
@@ -75,8 +73,8 @@ module HexaPDF
75
73
 
76
74
  x_ppi = 72.0 * w / Math.sqrt((lrx - llx)**2 + (lry - lly)**2)
77
75
  y_ppi = 72.0 * h / Math.sqrt((ulx - llx)**2 + (uly - lly)**2)
78
- @result[name] = [x_ppi.round, y_ppi.round]
79
- raise StopIteration if @names.empty?
76
+ @result[xobject] = [x_ppi.round, y_ppi.round]
77
+ raise StopIteration if @images.empty?
80
78
  end
81
79
 
82
80
  end
@@ -182,17 +180,19 @@ module HexaPDF
182
180
  seen = {}
183
181
 
184
182
  doc.pages.each_with_index do |page, pindex|
185
- image_names = []
186
- xobjects = page.resources[:XObject]
187
-
188
- xobjects&.each&.map do |name, xobject|
189
- image_names << name if xobject[:Subtype] == :Image && !xobject[:ImageMask]
183
+ images = []
184
+ process_xobject_entry = lambda do |name, xobject|
185
+ if xobject[:Subtype] == :Image && !xobject[:ImageMask]
186
+ images << xobject
187
+ elsif xobject[:Subtype] == :Form
188
+ xobject.resources[:XObject]&.each(&process_xobject_entry)
189
+ end
190
190
  end
191
+ page.resources[:XObject]&.each(&process_xobject_entry)
191
192
 
192
- processor = ImageLocationProcessor.new(image_names, page[:UserUnit] || 1)
193
+ processor = ImageLocationProcessor.new(images, page[:UserUnit] || 1)
193
194
  page.process_contents(processor)
194
- processor.result.each do |name, ppi|
195
- xobject = xobjects[name]
195
+ processor.result.each do |xobject, ppi|
196
196
  if seen[xobject]
197
197
  yield(xobject, seen[xobject], pindex + 1, ppi)
198
198
  else
@@ -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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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
@@ -137,6 +137,8 @@ module HexaPDF
137
137
  end
138
138
  elsif doc.encrypted?
139
139
  output_line("Encrypted", "yes (no or wrong password given)")
140
+ else
141
+ output_line("Encrypted", "no")
140
142
  end
141
143
 
142
144
  if doc.revisions.parser.linearized?
@@ -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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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
@@ -80,6 +80,14 @@ module HexaPDF
80
80
  "false)") do |c|
81
81
  @interleave = c
82
82
  end
83
+ options.on("--acro-form MODE", [:merge, :ignore], "Handling of interactive forms (either " \
84
+ "merge or ignore; default: merge)") do |mode|
85
+ @acro_form_mode = mode
86
+ end
87
+ options.on("--optional-content MODE", [:preserve, :ignore], "Handling of optional " \
88
+ "content (either preserve or ignore; default: preserve)") do |mode|
89
+ @optional_content_mode = mode
90
+ end
83
91
 
84
92
  options.separator("")
85
93
  options.separator("Output related options")
@@ -89,6 +97,8 @@ module HexaPDF
89
97
  @files = []
90
98
  @initial_empty = false
91
99
  @interleave = false
100
+ @acro_form_mode = :merge
101
+ @optional_content_mode = :preserve
92
102
  end
93
103
 
94
104
  def execute #:nodoc:
@@ -179,7 +189,9 @@ module HexaPDF
179
189
  page.value.update(page.copy_inherited_values)
180
190
  page = page.deep_copy unless source_index == 0
181
191
  else
182
- page = page_tree.document.import(page).deep_copy
192
+ page = page_tree.document.task(:import_pages, source: page.document, append: false,
193
+ pages: [page], ocgs: @optional_content_mode,
194
+ acro_form: @acro_form_mode)[0].deep_copy
183
195
  end
184
196
  if rotation == :none
185
197
  page.delete(:Rotate)
@@ -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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
data/lib/hexapdf/cli.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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
@@ -559,6 +559,7 @@ module HexaPDF
559
559
  JPXDecode: 'HexaPDF::Filter::PassThrough',
560
560
  Crypt: 'HexaPDF::Filter::Crypt',
561
561
  Encryption: 'HexaPDF::Filter::Encryption',
562
+ BrotliDecode: 'HexaPDF::Filter::BrotliDecode',
562
563
  },
563
564
  'font.default' => 'Times',
564
565
  'font.fallback' => ['ZapfDingbats', 'Symbol'],
@@ -623,6 +624,7 @@ module HexaPDF
623
624
  dereference: 'HexaPDF::Task::Dereference',
624
625
  pdfa: 'HexaPDF::Task::PDFA',
625
626
  merge_acro_form: 'HexaPDF::Task::MergeAcroForm',
627
+ import_pages: 'HexaPDF::Task::ImportPages',
626
628
  })
627
629
 
628
630
  # The global configuration object, providing the following options:
@@ -636,6 +638,11 @@ module HexaPDF
636
638
  #
637
639
  # See PDF2.0 s8.6
638
640
  #
641
+ # filter.brotli.compression::
642
+ # Specifies the compression level that should be used with the BrotliDecode filter. The level
643
+ # can range from 0 (no compression), 1 (best speed) to 11 (best compression). The default
644
+ # value is 8 which is a good compromise between speed and resulting size.
645
+ #
639
646
  # filter.flate.compression::
640
647
  # Specifies the compression level that should be used with the FlateDecode filter. The level
641
648
  # can range from 0 (no compression), 1 (best speed) to 9 (best compression, default).
@@ -754,6 +761,8 @@ module HexaPDF
754
761
  MCR: 'HexaPDF::Type::MarkedContentReference',
755
762
  OBJR: 'HexaPDF::Type::ObjectReference',
756
763
  Measure: 'HexaPDF::Type::Measure',
764
+ DSS: 'HexaPDF::Type::DocumentSecurityStore',
765
+ VRI: 'HexaPDF::Type::DocumentSecurityStore::ValidationRelatedInformation',
757
766
  },
758
767
  'object.subtype_map' => {
759
768
  nil => {
@@ -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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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
@@ -895,7 +895,7 @@ module HexaPDF
895
895
  #
896
896
  # * Any other string is treated as a color name. HexaPDF supports CSS Color Module Level 3
897
897
  # color names (see https://www.w3.org/TR/css-color-3/#svg-color) as well as HexaPDF design
898
- # colors.
898
+ # colors. See ColorSpace::COLOR_NAMES for the list of supported names.
899
899
  #
900
900
  # * Four numeric arguments specify a CMYK color (see ColorSpace::DeviceCMYK::Color).
901
901
  #
@@ -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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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-2025 Thomas Leitner
7
+ # Copyright (C) 2014-2026 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