hexapdf 0.31.0 → 0.32.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (239) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/LICENSE +1 -1
  4. data/examples/020-column_box.rb +10 -11
  5. data/examples/021-list_box.rb +5 -5
  6. data/lib/hexapdf/cli/batch.rb +1 -1
  7. data/lib/hexapdf/cli/command.rb +1 -1
  8. data/lib/hexapdf/cli/files.rb +1 -1
  9. data/lib/hexapdf/cli/fonts.rb +1 -1
  10. data/lib/hexapdf/cli/form.rb +1 -1
  11. data/lib/hexapdf/cli/image2pdf.rb +1 -1
  12. data/lib/hexapdf/cli/images.rb +1 -1
  13. data/lib/hexapdf/cli/info.rb +1 -1
  14. data/lib/hexapdf/cli/inspect.rb +1 -1
  15. data/lib/hexapdf/cli/merge.rb +1 -1
  16. data/lib/hexapdf/cli/modify.rb +1 -1
  17. data/lib/hexapdf/cli/optimize.rb +1 -1
  18. data/lib/hexapdf/cli/split.rb +1 -1
  19. data/lib/hexapdf/cli/watermark.rb +1 -1
  20. data/lib/hexapdf/cli.rb +1 -1
  21. data/lib/hexapdf/composer.rb +21 -1
  22. data/lib/hexapdf/configuration.rb +1 -1
  23. data/lib/hexapdf/content/canvas.rb +2 -1
  24. data/lib/hexapdf/content/color_space.rb +1 -1
  25. data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
  26. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
  27. data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
  28. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  29. data/lib/hexapdf/content/graphic_object.rb +1 -1
  30. data/lib/hexapdf/content/graphics_state.rb +1 -1
  31. data/lib/hexapdf/content/operator.rb +1 -1
  32. data/lib/hexapdf/content/parser.rb +1 -1
  33. data/lib/hexapdf/content/processor.rb +1 -1
  34. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  35. data/lib/hexapdf/content.rb +1 -1
  36. data/lib/hexapdf/data_dir.rb +1 -1
  37. data/lib/hexapdf/dictionary.rb +1 -1
  38. data/lib/hexapdf/dictionary_fields.rb +1 -1
  39. data/lib/hexapdf/digital_signature/cms_handler.rb +1 -1
  40. data/lib/hexapdf/digital_signature/handler.rb +1 -1
  41. data/lib/hexapdf/digital_signature/pkcs1_handler.rb +1 -1
  42. data/lib/hexapdf/digital_signature/signature.rb +1 -1
  43. data/lib/hexapdf/digital_signature/signatures.rb +1 -1
  44. data/lib/hexapdf/digital_signature/signing/default_handler.rb +1 -1
  45. data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +1 -1
  46. data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +1 -1
  47. data/lib/hexapdf/digital_signature/signing.rb +1 -1
  48. data/lib/hexapdf/digital_signature/verification_result.rb +1 -1
  49. data/lib/hexapdf/digital_signature.rb +1 -1
  50. data/lib/hexapdf/document/destinations.rb +1 -1
  51. data/lib/hexapdf/document/files.rb +1 -1
  52. data/lib/hexapdf/document/fonts.rb +1 -1
  53. data/lib/hexapdf/document/images.rb +1 -1
  54. data/lib/hexapdf/document/layout.rb +122 -39
  55. data/lib/hexapdf/document/pages.rb +1 -1
  56. data/lib/hexapdf/document.rb +1 -1
  57. data/lib/hexapdf/encryption/aes.rb +3 -1
  58. data/lib/hexapdf/encryption/arc4.rb +1 -1
  59. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  60. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  61. data/lib/hexapdf/encryption/identity.rb +1 -1
  62. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  63. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  64. data/lib/hexapdf/encryption/security_handler.rb +5 -2
  65. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
  66. data/lib/hexapdf/encryption.rb +1 -1
  67. data/lib/hexapdf/error.rb +12 -2
  68. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  69. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  70. data/lib/hexapdf/filter/crypt.rb +1 -1
  71. data/lib/hexapdf/filter/encryption.rb +1 -1
  72. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  73. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  74. data/lib/hexapdf/filter/pass_through.rb +1 -1
  75. data/lib/hexapdf/filter/predictor.rb +1 -1
  76. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  77. data/lib/hexapdf/filter.rb +1 -1
  78. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  79. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  80. data/lib/hexapdf/font/cmap.rb +1 -1
  81. data/lib/hexapdf/font/encoding/base.rb +1 -1
  82. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  83. data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
  84. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  85. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  86. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  87. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  88. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  89. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  90. data/lib/hexapdf/font/encoding.rb +1 -1
  91. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  92. data/lib/hexapdf/font/true_type/builder.rb +1 -1
  93. data/lib/hexapdf/font/true_type/font.rb +1 -1
  94. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  95. data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
  96. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  97. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  98. data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
  99. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  100. data/lib/hexapdf/font/true_type/table/head.rb +1 -1
  101. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  102. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  103. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  104. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  105. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  106. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  107. data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
  108. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  109. data/lib/hexapdf/font/true_type/table.rb +1 -1
  110. data/lib/hexapdf/font/true_type.rb +1 -1
  111. data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
  112. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  113. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  114. data/lib/hexapdf/font/type1/font.rb +1 -1
  115. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  116. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  117. data/lib/hexapdf/font/type1.rb +1 -1
  118. data/lib/hexapdf/font/type1_wrapper.rb +1 -1
  119. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  120. data/lib/hexapdf/font_loader/from_file.rb +1 -1
  121. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  122. data/lib/hexapdf/font_loader.rb +1 -1
  123. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  124. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  125. data/lib/hexapdf/image_loader/png.rb +1 -1
  126. data/lib/hexapdf/image_loader.rb +1 -1
  127. data/lib/hexapdf/importer.rb +1 -1
  128. data/lib/hexapdf/layout/box.rb +1 -1
  129. data/lib/hexapdf/layout/box_fitter.rb +1 -1
  130. data/lib/hexapdf/layout/column_box.rb +1 -1
  131. data/lib/hexapdf/layout/frame.rb +1 -1
  132. data/lib/hexapdf/layout/image_box.rb +1 -1
  133. data/lib/hexapdf/layout/inline_box.rb +17 -3
  134. data/lib/hexapdf/layout/line.rb +1 -1
  135. data/lib/hexapdf/layout/list_box.rb +1 -1
  136. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  137. data/lib/hexapdf/layout/style.rb +8 -2
  138. data/lib/hexapdf/layout/text_box.rb +1 -1
  139. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  140. data/lib/hexapdf/layout/text_layouter.rb +4 -7
  141. data/lib/hexapdf/layout/text_shaper.rb +1 -1
  142. data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
  143. data/lib/hexapdf/layout.rb +1 -1
  144. data/lib/hexapdf/name_tree_node.rb +1 -1
  145. data/lib/hexapdf/number_tree_node.rb +1 -1
  146. data/lib/hexapdf/object.rb +1 -1
  147. data/lib/hexapdf/parser.rb +1 -1
  148. data/lib/hexapdf/pdf_array.rb +1 -1
  149. data/lib/hexapdf/rectangle.rb +1 -1
  150. data/lib/hexapdf/reference.rb +1 -1
  151. data/lib/hexapdf/revision.rb +1 -1
  152. data/lib/hexapdf/revisions.rb +1 -1
  153. data/lib/hexapdf/serializer.rb +1 -1
  154. data/lib/hexapdf/stream.rb +1 -1
  155. data/lib/hexapdf/task/dereference.rb +1 -1
  156. data/lib/hexapdf/task/optimize.rb +1 -1
  157. data/lib/hexapdf/task.rb +1 -1
  158. data/lib/hexapdf/test_utils.rb +1 -1
  159. data/lib/hexapdf/tokenizer.rb +2 -1
  160. data/lib/hexapdf/type/acro_form/appearance_generator.rb +4 -2
  161. data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
  162. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  163. data/lib/hexapdf/type/acro_form/field.rb +1 -1
  164. data/lib/hexapdf/type/acro_form/form.rb +1 -1
  165. data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
  166. data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
  167. data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
  168. data/lib/hexapdf/type/acro_form.rb +1 -1
  169. data/lib/hexapdf/type/action.rb +1 -1
  170. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  171. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  172. data/lib/hexapdf/type/actions/launch.rb +1 -1
  173. data/lib/hexapdf/type/actions/uri.rb +1 -1
  174. data/lib/hexapdf/type/actions.rb +1 -1
  175. data/lib/hexapdf/type/annotation.rb +1 -1
  176. data/lib/hexapdf/type/annotations/link.rb +1 -1
  177. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  178. data/lib/hexapdf/type/annotations/text.rb +1 -1
  179. data/lib/hexapdf/type/annotations/widget.rb +1 -1
  180. data/lib/hexapdf/type/annotations.rb +1 -1
  181. data/lib/hexapdf/type/catalog.rb +1 -1
  182. data/lib/hexapdf/type/cid_font.rb +1 -1
  183. data/lib/hexapdf/type/embedded_file.rb +1 -1
  184. data/lib/hexapdf/type/file_specification.rb +1 -1
  185. data/lib/hexapdf/type/font.rb +1 -1
  186. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  187. data/lib/hexapdf/type/font_simple.rb +8 -1
  188. data/lib/hexapdf/type/font_true_type.rb +1 -1
  189. data/lib/hexapdf/type/font_type0.rb +6 -1
  190. data/lib/hexapdf/type/font_type1.rb +1 -1
  191. data/lib/hexapdf/type/font_type3.rb +1 -1
  192. data/lib/hexapdf/type/form.rb +1 -1
  193. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  194. data/lib/hexapdf/type/icon_fit.rb +1 -1
  195. data/lib/hexapdf/type/image.rb +1 -1
  196. data/lib/hexapdf/type/info.rb +1 -1
  197. data/lib/hexapdf/type/mark_information.rb +1 -1
  198. data/lib/hexapdf/type/names.rb +1 -1
  199. data/lib/hexapdf/type/object_stream.rb +1 -1
  200. data/lib/hexapdf/type/outline.rb +1 -1
  201. data/lib/hexapdf/type/outline_item.rb +10 -1
  202. data/lib/hexapdf/type/page.rb +7 -1
  203. data/lib/hexapdf/type/page_label.rb +1 -1
  204. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  205. data/lib/hexapdf/type/resources.rb +1 -1
  206. data/lib/hexapdf/type/trailer.rb +1 -1
  207. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  208. data/lib/hexapdf/type/xref_stream.rb +1 -1
  209. data/lib/hexapdf/type.rb +1 -1
  210. data/lib/hexapdf/utils/bit_field.rb +1 -1
  211. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  212. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  213. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  214. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  215. data/lib/hexapdf/utils/object_hash.rb +1 -1
  216. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  217. data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
  218. data/lib/hexapdf/version.rb +2 -2
  219. data/lib/hexapdf/writer.rb +1 -1
  220. data/lib/hexapdf/xref_section.rb +1 -1
  221. data/lib/hexapdf.rb +1 -1
  222. data/test/hexapdf/content/test_canvas.rb +26 -0
  223. data/test/hexapdf/document/test_layout.rb +80 -17
  224. data/test/hexapdf/encryption/common.rb +4 -0
  225. data/test/hexapdf/encryption/test_aes.rb +8 -0
  226. data/test/hexapdf/encryption/test_security_handler.rb +11 -0
  227. data/test/hexapdf/layout/test_inline_box.rb +35 -15
  228. data/test/hexapdf/layout/test_style.rb +12 -3
  229. data/test/hexapdf/layout/test_text_box.rb +5 -2
  230. data/test/hexapdf/layout/test_text_layouter.rb +6 -11
  231. data/test/hexapdf/test_composer.rb +14 -1
  232. data/test/hexapdf/test_tokenizer.rb +5 -0
  233. data/test/hexapdf/test_writer.rb +3 -3
  234. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +13 -0
  235. data/test/hexapdf/type/test_font_simple.rb +8 -4
  236. data/test/hexapdf/type/test_font_type0.rb +6 -2
  237. data/test/hexapdf/type/test_outline_item.rb +18 -0
  238. data/test/hexapdf/type/test_page.rb +16 -0
  239. metadata +2 -2
@@ -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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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
@@ -224,6 +224,15 @@ module HexaPDF
224
224
  count
225
225
  end
226
226
 
227
+ # Returns the open state of the item.
228
+ #
229
+ # +true+:: If this item is open, i.e. showing its child items.
230
+ # +false+:: If this item is closed, i.e. not showing its child items.
231
+ # +nil+:: If this item doesn't (yet) have any child items.
232
+ def open?
233
+ self[:First] && key?(:Count) && self[:Count] >= 0
234
+ end
235
+
227
236
  # Returns the destination page if there is any.
228
237
  #
229
238
  # * If a destination is set, the associated page is returned.
@@ -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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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
@@ -576,6 +576,12 @@ module HexaPDF
576
576
  left, right = [llx, ulx, lrx, lrx + (ulx - llx)].minmax
577
577
  bottom, top = [lly, uly, lry, lry + (uly - lly)].minmax
578
578
 
579
+ # Handle degenerate case of the transformed bounding box being a line or point
580
+ if right - left == 0 || top - bottom == 0
581
+ to_delete << annotation
582
+ next
583
+ end
584
+
579
585
  # Step b) Fit calculated rectangle to annotation rectangle by translating/scaling
580
586
  a = HexaPDF::Content::TransformationMatrix.new
581
587
  a.translate(rect.left - left, rect.bottom - bottom)
@@ -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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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/type.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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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
@@ -37,6 +37,6 @@
37
37
  module HexaPDF
38
38
 
39
39
  # The version of HexaPDF.
40
- VERSION = '0.31.0'
40
+ VERSION = '0.32.1'
41
41
 
42
42
  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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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.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-2022 Thomas Leitner
7
+ # Copyright (C) 2014-2023 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
@@ -1280,4 +1280,30 @@ describe HexaPDF::Content::Canvas do
1280
1280
  end
1281
1281
  end
1282
1282
  end
1283
+
1284
+ describe "color_from_specification "do
1285
+ it "accepts a color string" do
1286
+ assert_equal([1, 0, 0], @canvas.color_from_specification("red").components)
1287
+ end
1288
+
1289
+ it "accepts a color string wrapped in an array" do
1290
+ assert_equal([1, 0, 0], @canvas.color_from_specification(["red"]).components)
1291
+ end
1292
+
1293
+ it "accepts a color object" do
1294
+ color = @canvas.color_from_specification("red")
1295
+ assert_equal(color, @canvas.color_from_specification(color))
1296
+ end
1297
+
1298
+ it "accepts a color object wrapped in an array" do
1299
+ color = @canvas.color_from_specification("red")
1300
+ assert_equal(color, @canvas.color_from_specification([color]))
1301
+ end
1302
+
1303
+ it "accepts an array with 1, 3, or 4 color values" do
1304
+ assert_equal([1], @canvas.color_from_specification([255]).components)
1305
+ assert_equal([1, 0, 0], @canvas.color_from_specification([255, 0, 0]).components)
1306
+ assert_equal([1, 0, 0, 0], @canvas.color_from_specification([100, 0, 0, 0]).components)
1307
+ end
1308
+ end
1283
1309
  end
@@ -34,29 +34,24 @@ describe HexaPDF::Document::Layout::ChildrenCollector do
34
34
  assert_equal(2, @collector.children[0].size)
35
35
  end
36
36
 
37
- it "allows appending boxes through method names of the Layout class" do
38
- @collector.lorem_ipsum_box
39
- assert_equal(1, @collector.children.size)
40
- assert_kind_of(HexaPDF::Layout::TextBox, @collector.children[0])
41
- end
42
-
43
- it "allows appending boxes through method names without the _box suffix of the Layout class" do
37
+ it "allows appending boxes created by the Layout class" do
44
38
  @collector.lorem_ipsum
45
- assert_equal(1, @collector.children.size)
39
+ @collector.lorem_ipsum_box
40
+ @collector.column
41
+ @collector.column_box
42
+ assert_equal(4, @collector.children.size)
46
43
  assert_kind_of(HexaPDF::Layout::TextBox, @collector.children[0])
44
+ assert_kind_of(HexaPDF::Layout::TextBox, @collector.children[1])
45
+ assert_kind_of(HexaPDF::Layout::ColumnBox, @collector.children[2])
46
+ assert_kind_of(HexaPDF::Layout::ColumnBox, @collector.children[3])
47
47
  end
48
48
 
49
- it "allows appending boxes through their registered names" do
50
- @collector.column
51
- assert_equal(1, @collector.children.size)
52
- assert_kind_of(HexaPDF::Layout::ColumnBox, @collector.children[0])
49
+ it "can be asked which methods it supports" do
50
+ assert(@collector.respond_to?(:lorem_ipsum))
53
51
  end
54
52
 
55
- it "can be asked which methods it supports" do
56
- assert(@collector.respond_to?(:text_box))
57
- assert(@collector.respond_to?(:text))
58
- assert(@collector.respond_to?(:column))
59
- refute(@collector.respond_to?(:unknown))
53
+ it "only allows using box creation methods from the Layout class" do
54
+ assert_raises(NameError) { @collector.style }
60
55
  end
61
56
 
62
57
  it "raises an error on an unknown method name" do
@@ -88,6 +83,27 @@ describe HexaPDF::Document::Layout do
88
83
  end
89
84
  end
90
85
 
86
+ describe "inline_box" do
87
+ it "takes a box as argument" do
88
+ box = HexaPDF::Layout::Box.create(width: 10, height: 10)
89
+ ibox = @layout.inline_box(box)
90
+ assert_same(box, ibox.box)
91
+ end
92
+
93
+ it "correctly passes on the valign argument" do
94
+ box = HexaPDF::Layout::Box.create(width: 10, height: 10)
95
+ ibox = @layout.inline_box(box, valign: :top)
96
+ assert_equal(:top, ibox.valign)
97
+ end
98
+
99
+ it "can create a box using any box creation method of the Layout class" do
100
+ ibox = @layout.inline_box(:text, "Some text", valign: :bottom, width: 10, background_color: "red")
101
+ assert_equal(:bottom, ibox.valign)
102
+ assert_equal(10, ibox.width)
103
+ assert_equal("red", ibox.box.style.background_color)
104
+ end
105
+ end
106
+
91
107
  describe "box" do
92
108
  it "creates the request box" do
93
109
  box = @layout.box(:column, columns: 3, gaps: 20, width: 15, height: 30, style: {font_size: 10},
@@ -232,6 +248,24 @@ describe HexaPDF::Document::Layout do
232
248
  items = box.instance_variable_get(:@items)
233
249
  assert_equal({named_dest: 'test'}, items[0].properties)
234
250
  end
251
+
252
+ it "allows adding an inline box" do
253
+ ibox = @layout.inline_box(:base, width: 10, height: 10)
254
+ box = @layout.formatted_text_box([ibox])
255
+ assert_equal(ibox, box.instance_variable_get(:@items).first)
256
+ end
257
+
258
+ it "allows creating an inline box through a hash with a :box key" do
259
+ block = lambda {|item| item.box(:base, width: 5, height: 15) }
260
+ box = @layout.formatted_text_box([{box: :list, width: 10, block: block}])
261
+ ibox = box.instance_variable_get(:@items).first
262
+ assert_equal(10, ibox.width)
263
+ assert_equal(15, ibox.height)
264
+ end
265
+
266
+ it "fails if the data array contains unsupported items" do
267
+ assert_raises(ArgumentError) { @layout.formatted_text_box([5]) }
268
+ end
235
269
  end
236
270
 
237
271
  describe "image_box" do
@@ -277,4 +311,33 @@ describe HexaPDF::Document::Layout do
277
311
  assert_equal(HexaPDF::Document::Layout::LOREM_IPSUM[0, 2].join(" ").size * 2 + 2, items[0].items.length)
278
312
  end
279
313
  end
314
+
315
+ describe "method_missing" do
316
+ it "resolves to internal methods with the _box suffix, e.g. text_box" do
317
+ box = @layout.text("Test", width: 10, height: 15, properties: {key: :value})
318
+ assert_kind_of(HexaPDF::Layout::TextBox, box)
319
+ assert_equal(10, box.width)
320
+ assert_equal(15, box.height)
321
+ assert_equal({key: :value}, box.properties)
322
+ end
323
+
324
+ it "resolves to the box method when a configured name is used" do
325
+ box = @layout.column
326
+ assert_kind_of(HexaPDF::Layout::ColumnBox, box)
327
+ box = @layout.column_box
328
+ assert_kind_of(HexaPDF::Layout::ColumnBox, box)
329
+ end
330
+
331
+ it "fails if nothing could be resolved" do
332
+ assert_raises(NameError) { @layout.unknown }
333
+ end
334
+ end
335
+
336
+ describe "respond_to_missing?" do
337
+ it "can be asked which methods it supports" do
338
+ assert(@layout.respond_to?(:text))
339
+ assert(@layout.respond_to?(:column))
340
+ refute(@layout.respond_to?(:unknown))
341
+ end
342
+ end
280
343
  end
@@ -84,4 +84,8 @@ module ARC4EncryptionTests
84
84
  small.process('some') << small.process(' big') << small.process(' data chunk'))
85
85
  end
86
86
 
87
+ def test_works_with_empty_strings
88
+ assert_equal('', @algorithm_class.new('key').process(''))
89
+ end
90
+
87
91
  end
@@ -48,6 +48,10 @@ describe HexaPDF::Encryption::AES do
48
48
  end
49
49
  end
50
50
 
51
+ it "handles invalid files with empty strings" do
52
+ assert_equal('', @algorithm_class.decrypt('key', ''))
53
+ end
54
+
51
55
  it "handles invalid files with missing 16 byte padding" do
52
56
  assert_equal('', @algorithm_class.decrypt('some key' * 2, 'iv' * 8))
53
57
  end
@@ -118,6 +122,10 @@ describe HexaPDF::Encryption::AES do
118
122
  assert_equal('a' * 13 << "\x00\x01\x03", result)
119
123
  end
120
124
 
125
+ it "handles invalid files with empty streams" do
126
+ assert_equal('', collector(@algorithm_class.decryption_fiber('key', Fiber.new { '' })))
127
+ end
128
+
121
129
  it "fails on decryption if not enough bytes are provided" do
122
130
  [4, 20, 40].each do |length|
123
131
  assert_raises(HexaPDF::EncryptionError) do
@@ -141,6 +141,11 @@ describe HexaPDF::Encryption::SecurityHandler do
141
141
  @handler.set_up_encryption(key_length: key_length, algorithm: algorithm)
142
142
  assert(result == @handler.dict[:Length])
143
143
  end
144
+
145
+ # Work-around buggy software
146
+ @handler.set_up_encryption(key_length: 128, algorithm: :aes)
147
+ assert_equal(4, @handler.dict[:V])
148
+ assert_equal(128, @handler.dict[:Length])
144
149
  end
145
150
 
146
151
  it "calls the prepare_encryption method" do
@@ -325,6 +330,12 @@ describe HexaPDF::Encryption::SecurityHandler do
325
330
  assert_equal("test", @handler.decrypt(@obj)[:Contents])
326
331
  end
327
332
 
333
+ it "enhances a thrown EncryptionError by setting the PDF object" do
334
+ @handler.set_up_encryption(key_length: 256)
335
+ error = assert_raises(HexaPDF::EncryptionError) { @handler.decrypt(@obj) }
336
+ assert_match(/Object \(1,0\):/, error.message)
337
+ end
338
+
328
339
  it "fails if V < 5 and the object number changes" do
329
340
  @obj.oid = 55
330
341
  @handler.decrypt(@obj)
@@ -2,31 +2,51 @@
2
2
 
3
3
  require 'test_helper'
4
4
  require 'hexapdf/layout/inline_box'
5
+ require 'hexapdf/document'
5
6
 
6
7
  describe HexaPDF::Layout::InlineBox do
8
+ def inline_box(box, valign: :baseline)
9
+ HexaPDF::Layout::InlineBox.new(box, valign: valign)
10
+ end
11
+
7
12
  before do
8
13
  @box = HexaPDF::Layout::InlineBox.create(width: 10, height: 15, margin: [15, 10])
9
14
  end
10
15
 
11
- it "needs a box to wrap and an optional alignment on initialization" do
12
- ibox = HexaPDF::Layout::InlineBox.new(@box)
13
- assert_equal(@box, ibox.box)
14
- assert_equal(:baseline, ibox.valign)
16
+ describe "initialize" do
17
+ it "needs a box to wrap and an optional alignment on initialization" do
18
+ box = HexaPDF::Layout::Box.create(width: 10, height: 15)
19
+ ibox = inline_box(box)
20
+ assert_equal(box, ibox.box)
21
+ assert_equal(:baseline, ibox.valign)
15
22
 
16
- ibox = HexaPDF::Layout::InlineBox.new(@box, valign: :top)
17
- assert_equal(:top, ibox.valign)
18
- end
23
+ ibox = inline_box(box, valign: :top)
24
+ assert_equal(:top, ibox.valign)
25
+ end
19
26
 
20
- it "draws the wrapped box at the correct position" do
21
- canvas = Object.new
22
- block = lambda do |c, x, y|
23
- assert_equal(canvas, c)
24
- assert_equal(10, x)
25
- assert_equal(15, y)
27
+ it "automatically fits the provided box into a frame" do
28
+ ibox = inline_box(HexaPDF::Document.new.layout.text("test is going good", width: 20))
29
+ assert_equal(20, ibox.width)
30
+ assert_equal(45, ibox.height)
26
31
  end
27
- @box.box.stub(:draw, block) do
28
- @box.draw(canvas, 0, 0)
32
+
33
+ it "fails if the wrapped box could not be fit" do
34
+ box = HexaPDF::Document.new.layout.text("test is not going good", width: 1)
35
+ assert_raises(HexaPDF::Error) { inline_box(box) }
29
36
  end
37
+
38
+ it "fails if the height is not set explicitly and during fitting" do
39
+ assert_raises(HexaPDF::Error) do
40
+ inline_box(HexaPDF::Layout::Box.create(width: 10))
41
+ end
42
+ end
43
+ end
44
+
45
+ it "draws the wrapped box at the correct position" do
46
+ doc = HexaPDF::Document.new
47
+ canvas = doc.pages.add.canvas
48
+ inline_box(doc.layout.text("", width: 20, margin: [15, 10])).draw(canvas, 100, 200)
49
+ assert_equal("q\n1 0 0 1 110 -99785 cm\nQ\n", canvas.contents)
30
50
  end
31
51
 
32
52
  it "returns true if the inline box is empty with no drawing operations" do
@@ -573,10 +573,19 @@ describe HexaPDF::Layout::Style::LinkLayer do
573
573
  assert_equal([0, 0, 1], annot[:Border].value)
574
574
  end
575
575
 
576
- it "uses the specified border and border color" do
577
- annot = call_link(dest: true, border: [10, 10, 2], border_color: [255])
576
+ it "uses the specified border" do
577
+ annot = call_link(dest: true, border: [10, 10, 2])
578
578
  assert_equal([10, 10, 2], annot[:Border].value)
579
- assert_equal([1.0], annot[:C].value)
579
+ end
580
+
581
+ it "uses the specified border color" do
582
+ annot = call_link(dest: true, border_color: "red")
583
+ assert_equal([1.0, 0, 0], annot[:C].value)
584
+ end
585
+
586
+ it "works when the border color is transparent" do
587
+ annot = call_link(dest: true, border_color: [])
588
+ assert_equal([], annot[:C].value)
580
589
  end
581
590
 
582
591
  it "works for simple destinations" do
@@ -139,12 +139,15 @@ describe HexaPDF::Layout::TextBox do
139
139
  assert_operators(@canvas.contents, [[:save_graphics_state],
140
140
  [:restore_graphics_state],
141
141
  [:save_graphics_state],
142
- [:append_rectangle, [5, 10, 10, 10]],
142
+ [:concatenate_matrix, [1, 0, 0, 1, 5, 10]],
143
+ [:save_graphics_state],
144
+ [:append_rectangle, [0, 0, 10, 10]],
143
145
  [:clip_path_non_zero],
144
146
  [:end_path],
145
- [:append_rectangle, [5.5, 10.5, 9, 9]],
147
+ [:append_rectangle, [0.5, 0.5, 9.0, 9.0]],
146
148
  [:stroke_path],
147
149
  [:restore_graphics_state],
150
+ [:restore_graphics_state],
148
151
  [:save_graphics_state],
149
152
  [:restore_graphics_state]])
150
153
  end
@@ -7,13 +7,13 @@ require 'hexapdf/document'
7
7
  module TestTextLayouterHelpers
8
8
  def boxes(*dims)
9
9
  dims.map do |width, height|
10
- box = HexaPDF::Layout::InlineBox.create(width: width, height: height || 0) {}
10
+ box = HexaPDF::Layout::InlineBox.create(width: width, height: height || 10) {}
11
11
  HexaPDF::Layout::TextLayouter::Box.new(box)
12
12
  end
13
13
  end
14
14
 
15
15
  def glue(width)
16
- HexaPDF::Layout::TextLayouter::Glue.new(HexaPDF::Layout::InlineBox.create(width: width) {})
16
+ HexaPDF::Layout::TextLayouter::Glue.new(HexaPDF::Layout::InlineBox.create(width: width, height: 10) {})
17
17
  end
18
18
 
19
19
  def penalty(penalty, item = nil)
@@ -136,16 +136,8 @@ describe HexaPDF::Layout::TextLayouter::SimpleTextSegmentation do
136
136
  [1, 3, 5, 7, 9, 11, 13, 17, 19].each do |index|
137
137
  assert_penalty(result[index],
138
138
  HexaPDF::Layout::TextLayouter::Penalty::PARAGRAPH_BREAK)
139
- assert_equal([], result[index].item.items)
140
- assert(result[index].item.items.frozen?)
141
- assert_same(frag.style, result[index].item.style)
142
- assert_equal(frag.properties, result[index].item.properties)
143
139
  end
144
140
  assert_penalty(result[15], HexaPDF::Layout::TextLayouter::Penalty::LINE_BREAK)
145
- assert_equal([], result[15].item.items)
146
- assert(result[15].item.items.frozen?)
147
- assert_same(frag.style, result[15].item.style)
148
- assert_equal(frag.properties, result[15].item.properties)
149
141
  end
150
142
 
151
143
  it "insert a standard penalty after a hyphen" do
@@ -624,7 +616,7 @@ describe HexaPDF::Layout::TextLayouter do
624
616
 
625
617
  describe "horizontal alignment" do
626
618
  before do
627
- @items = boxes(*[[20, 20]] * 4) + [glue(10), penalty(-5000, boxes(0).first.item)]
619
+ @items = boxes(*[[20, 20]] * 4) + [glue(10), penalty(-5000)]
628
620
  end
629
621
 
630
622
  it "aligns the contents to the left" do
@@ -789,8 +781,11 @@ describe HexaPDF::Layout::TextLayouter do
789
781
  [:restore_graphics_state],
790
782
  [:save_graphics_state],
791
783
  [:concatenate_matrix, [1, 0, 0, 1, 10, -40]],
784
+ [:save_graphics_state],
785
+ [:concatenate_matrix, [1, 0, 0, 1, 0, 0]],
792
786
  [:set_line_width, [2]],
793
787
  [:restore_graphics_state],
788
+ [:restore_graphics_state],
794
789
  [:save_graphics_state],
795
790
  [:restore_graphics_state]])
796
791
  end