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
@@ -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
@@ -394,11 +394,12 @@ module HexaPDF
394
394
  # :call-seq:
395
395
  # document.unwrap(obj) -> unwrapped_obj
396
396
  #
397
- # Recursively unwraps the object to get native Ruby objects (i.e. Hash, Array, Integer, ...
398
- # instead of HexaPDF::Reference and HexaPDF::Object).
397
+ # Recursively unwraps the object to get native Ruby objects (i.e. Hash, Array, Integer, ...)
398
+ # instead of HexaPDF::Reference and HexaPDF::Object. Only HexaPDF::Stream objects are retained
399
+ # as they are not representable by native Ruby objects.
399
400
  def unwrap(object, seen = {})
400
401
  object = deref(object)
401
- object = object.data if object.kind_of?(HexaPDF::Object)
402
+ object = object.data if object.kind_of?(HexaPDF::Object) && !object.kind_of?(HexaPDF::Stream)
402
403
  if seen.key?(object)
403
404
  raise HexaPDF::Error, "Can't unwrap a recursive structure"
404
405
  end
@@ -413,6 +414,8 @@ module HexaPDF
413
414
  when HexaPDF::PDFData
414
415
  seen[object] = true
415
416
  unwrap(object.value, seen.dup)
417
+ when HexaPDF::Stream
418
+ object
416
419
  else
417
420
  object
418
421
  end
@@ -790,6 +793,7 @@ module HexaPDF
790
793
  if @metadata
791
794
  metadata.modification_date(Time.now)
792
795
  else
796
+ trailer.delete(:Info) unless trailer.info.kind_of?(HexaPDF::Dictionary)
793
797
  trailer.info[:ModDate] = Time.now
794
798
  end
795
799
  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
@@ -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
data/lib/hexapdf/error.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
@@ -0,0 +1,88 @@
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2026 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #
33
+ # If the GNU Affero General Public License doesn't fit your need,
34
+ # commercial licenses are available at <https://gettalong.at/hexapdf/>.
35
+ #++
36
+
37
+ require 'fiber'
38
+ require 'brotli'
39
+ require 'hexapdf/filter/predictor'
40
+ require 'hexapdf/configuration'
41
+
42
+ module HexaPDF
43
+ module Filter
44
+
45
+ # Implements the Brotli filter using the brotli library which must be installed manually.
46
+ #
47
+ # The BrotliDecode specification is not yet available as a standard but will be in the near
48
+ # future. Therefore it is recommended to wait using it for encoding streams until most of the
49
+ # PDF ecosystem has support for it.
50
+ #
51
+ # See: HexaPDF::Filter
52
+ module BrotliDecode
53
+
54
+ # See HexaPDF::Filter
55
+ #
56
+ # Note that the brotli gem currently doesn't support a streaming decoder. This means that the
57
+ # whole source must be read and decoded at once.
58
+ def self.decoder(source, options = nil)
59
+ fib = Fiber.new do
60
+ data = Filter.string_from_source(source)
61
+ data.empty? ? data: Brotli.inflate(data)
62
+ end
63
+
64
+ if options && options[:Predictor]
65
+ Predictor.decoder(fib, options)
66
+ else
67
+ fib
68
+ end
69
+ end
70
+
71
+ # See HexaPDF::Filter
72
+ #
73
+ # As with ::decoder a usable streaming encoder is not available.
74
+ def self.encoder(source, options = nil)
75
+ if options && options[:Predictor]
76
+ source = Predictor.encoder(source, options)
77
+ end
78
+
79
+ Fiber.new do
80
+ Brotli.deflate(Filter.string_from_source(source),
81
+ quality: HexaPDF::GlobalConfiguration['filter.brotli.compression'])
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+ 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
@@ -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
@@ -134,6 +134,7 @@ module HexaPDF
134
134
  autoload(:FlateDecode, 'hexapdf/filter/flate_decode')
135
135
  autoload(:LZWDecode, 'hexapdf/filter/lzw_decode')
136
136
  autoload(:RunLengthDecode, 'hexapdf/filter/run_length_decode')
137
+ autoload(:BrotliDecode, 'hexapdf/filter/brotli_decode')
137
138
 
138
139
  autoload(:Predictor, 'hexapdf/filter/predictor')
139
140
 
@@ -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
@@ -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
@@ -48,7 +48,7 @@ module HexaPDF
48
48
  entry_selector = tables.length.bit_length - 1
49
49
  range_shift = tables.length * 16 - search_range
50
50
 
51
- font_data = "\x0\x1\x0\x0".b +
51
+ font_data = (tables.key?('glyf') ? "\x0\x1\x0\x0" : "OTTO").b +
52
52
  [tables.length, search_range, entry_selector, range_shift].pack('n4')
53
53
 
54
54
  offset = font_data.length + tables.length * 16
@@ -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
@@ -35,6 +35,7 @@
35
35
  #++
36
36
 
37
37
  require 'hexapdf/font/true_type/table'
38
+ require 'hexapdf/font/true_type/builder'
38
39
  require 'set'
39
40
 
40
41
  module HexaPDF
@@ -84,6 +85,18 @@ module HexaPDF
84
85
  @tables = {}
85
86
  end
86
87
 
88
+ # Uses Builder to build a font file for this font.
89
+ #
90
+ # The +table_overrides+ argument can be used to supply mappings from table names (in string
91
+ # form) to raw table data that should override the respective font's tables.
92
+ def build(table_overrides = {})
93
+ tables = directory.table_names.each_with_object({}) do |name, hash|
94
+ hash[name] = self[name.to_sym].raw_data
95
+ end
96
+ tables.merge!(table_overrides)
97
+ Builder.build(tables)
98
+ end
99
+
87
100
  # Returns the table instance for the given tag (a symbol), or +nil+ if no such table exists.
88
101
  def [](tag)
89
102
  return @tables[tag] if @tables.key?(tag)
@@ -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
@@ -63,9 +63,9 @@ module HexaPDF
63
63
  def use_glyph(glyph_id)
64
64
  return @glyph_map[glyph_id] if @glyph_map.key?(glyph_id)
65
65
  @last_id += 1
66
- # Handle codes for ASCII characters \r (13), (, ) (40, 41) and \ (92) specially so that
67
- # they never appear in the output (PDF serialization would need to escape them)
68
- if @last_id == 13 || @last_id == 40 || @last_id == 92
66
+ # Handle codes for ASCII characters \n (10), \r (13), (, ) (40, 41) and \ (92) specially
67
+ # so that they never appear in the output (PDF serialization would need to escape them)
68
+ if @last_id == 10 || @last_id == 13 || @last_id == 40 || @last_id == 92
69
69
  @glyph_map[:"s#{@last_id}"] = @last_id
70
70
  if @last_id == 40
71
71
  @last_id += 1
@@ -176,9 +176,14 @@ module HexaPDF
176
176
  # Adds the components of compound glyphs to the subset.
177
177
  def add_glyph_components
178
178
  glyf = @font[:glyf]
179
+ process_glyph_components = lambda do |gid|
180
+ glyf[gid].components&.each do |cgid|
181
+ use_glyph(cgid)
182
+ process_glyph_components.call(cgid) if glyf[cgid].compound?
183
+ end
184
+ end
179
185
  @glyph_map.keys.each do |gid|
180
- next if gid.kind_of?(Symbol)
181
- glyf[gid].components&.each {|cgid| use_glyph(cgid) }
186
+ process_glyph_components.call(gid) unless gid.kind_of?(Symbol)
182
187
  end
183
188
  end
184
189
 
@@ -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
@@ -69,6 +69,11 @@ module HexaPDF
69
69
  @tables[tag]
70
70
  end
71
71
 
72
+ # Returns an array with all the table names (in string form) in the directory.
73
+ def table_names
74
+ @tables.keys
75
+ end
76
+
72
77
  private
73
78
 
74
79
  def load_from_io #:nodoc: