hexapdf 0.32.2 → 0.33.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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -1
  3. data/README.md +9 -0
  4. data/examples/002-graphics.rb +15 -17
  5. data/examples/003-arcs.rb +9 -9
  6. data/examples/009-text_layouter_alignment.rb +1 -1
  7. data/examples/010-text_layouter_inline_boxes.rb +2 -2
  8. data/examples/011-text_layouter_line_wrapping.rb +1 -1
  9. data/examples/012-text_layouter_styling.rb +7 -7
  10. data/examples/013-text_layouter_shapes.rb +1 -1
  11. data/examples/014-text_in_polygon.rb +1 -1
  12. data/examples/015-boxes.rb +8 -7
  13. data/examples/016-frame_automatic_box_placement.rb +2 -2
  14. data/examples/017-frame_text_flow.rb +2 -1
  15. data/examples/018-composer.rb +1 -1
  16. data/examples/020-column_box.rb +2 -1
  17. data/examples/025-table_box.rb +46 -0
  18. data/lib/hexapdf/cli/command.rb +5 -2
  19. data/lib/hexapdf/cli/form.rb +5 -5
  20. data/lib/hexapdf/cli/inspect.rb +3 -3
  21. data/lib/hexapdf/composer.rb +104 -52
  22. data/lib/hexapdf/configuration.rb +44 -39
  23. data/lib/hexapdf/content/canvas.rb +393 -267
  24. data/lib/hexapdf/content/color_space.rb +72 -25
  25. data/lib/hexapdf/content/graphic_object/arc.rb +57 -24
  26. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -23
  27. data/lib/hexapdf/content/graphic_object/geom2d.rb +47 -6
  28. data/lib/hexapdf/content/graphic_object/solid_arc.rb +58 -36
  29. data/lib/hexapdf/content/graphic_object.rb +6 -7
  30. data/lib/hexapdf/content/graphics_state.rb +54 -45
  31. data/lib/hexapdf/content/operator.rb +52 -54
  32. data/lib/hexapdf/content/parser.rb +2 -2
  33. data/lib/hexapdf/content/processor.rb +15 -15
  34. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  35. data/lib/hexapdf/content.rb +5 -0
  36. data/lib/hexapdf/dictionary.rb +6 -5
  37. data/lib/hexapdf/dictionary_fields.rb +42 -14
  38. data/lib/hexapdf/digital_signature/cms_handler.rb +2 -2
  39. data/lib/hexapdf/digital_signature/handler.rb +1 -1
  40. data/lib/hexapdf/digital_signature/pkcs1_handler.rb +2 -3
  41. data/lib/hexapdf/digital_signature/signature.rb +6 -6
  42. data/lib/hexapdf/digital_signature/signatures.rb +13 -12
  43. data/lib/hexapdf/digital_signature/signing/default_handler.rb +14 -5
  44. data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +2 -4
  45. data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +4 -4
  46. data/lib/hexapdf/digital_signature/signing.rb +4 -0
  47. data/lib/hexapdf/digital_signature/verification_result.rb +2 -2
  48. data/lib/hexapdf/digital_signature.rb +7 -2
  49. data/lib/hexapdf/document/destinations.rb +12 -11
  50. data/lib/hexapdf/document/files.rb +1 -1
  51. data/lib/hexapdf/document/fonts.rb +1 -1
  52. data/lib/hexapdf/document/layout.rb +167 -39
  53. data/lib/hexapdf/document/pages.rb +3 -2
  54. data/lib/hexapdf/document.rb +89 -55
  55. data/lib/hexapdf/encryption/aes.rb +5 -5
  56. data/lib/hexapdf/encryption/arc4.rb +1 -1
  57. data/lib/hexapdf/encryption/fast_aes.rb +2 -2
  58. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  59. data/lib/hexapdf/encryption/identity.rb +1 -1
  60. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  61. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  62. data/lib/hexapdf/encryption/security_handler.rb +31 -24
  63. data/lib/hexapdf/encryption/standard_security_handler.rb +45 -36
  64. data/lib/hexapdf/encryption.rb +7 -2
  65. data/lib/hexapdf/error.rb +18 -0
  66. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  67. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  68. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  69. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  70. data/lib/hexapdf/filter/pass_through.rb +1 -1
  71. data/lib/hexapdf/filter/predictor.rb +1 -1
  72. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  73. data/lib/hexapdf/filter.rb +55 -6
  74. data/lib/hexapdf/font/cmap/parser.rb +2 -2
  75. data/lib/hexapdf/font/cmap.rb +1 -1
  76. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  77. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  78. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
  79. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  80. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  81. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +3 -3
  82. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  83. data/lib/hexapdf/font/invalid_glyph.rb +3 -0
  84. data/lib/hexapdf/font/true_type_wrapper.rb +17 -4
  85. data/lib/hexapdf/font/type1_wrapper.rb +19 -4
  86. data/lib/hexapdf/font_loader/from_configuration.rb +5 -2
  87. data/lib/hexapdf/font_loader/from_file.rb +5 -5
  88. data/lib/hexapdf/font_loader/standard14.rb +3 -3
  89. data/lib/hexapdf/font_loader.rb +3 -0
  90. data/lib/hexapdf/image_loader/jpeg.rb +2 -2
  91. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  92. data/lib/hexapdf/image_loader/png.rb +2 -2
  93. data/lib/hexapdf/image_loader.rb +1 -1
  94. data/lib/hexapdf/importer.rb +13 -0
  95. data/lib/hexapdf/layout/box.rb +9 -2
  96. data/lib/hexapdf/layout/box_fitter.rb +2 -2
  97. data/lib/hexapdf/layout/column_box.rb +18 -4
  98. data/lib/hexapdf/layout/frame.rb +30 -12
  99. data/lib/hexapdf/layout/image_box.rb +5 -0
  100. data/lib/hexapdf/layout/inline_box.rb +1 -0
  101. data/lib/hexapdf/layout/list_box.rb +17 -1
  102. data/lib/hexapdf/layout/page_style.rb +4 -4
  103. data/lib/hexapdf/layout/style.rb +18 -3
  104. data/lib/hexapdf/layout/table_box.rb +682 -0
  105. data/lib/hexapdf/layout/text_box.rb +5 -3
  106. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  107. data/lib/hexapdf/layout/text_layouter.rb +12 -4
  108. data/lib/hexapdf/layout.rb +1 -0
  109. data/lib/hexapdf/name_tree_node.rb +1 -1
  110. data/lib/hexapdf/number_tree_node.rb +1 -1
  111. data/lib/hexapdf/object.rb +18 -7
  112. data/lib/hexapdf/parser.rb +7 -7
  113. data/lib/hexapdf/pdf_array.rb +1 -1
  114. data/lib/hexapdf/rectangle.rb +1 -1
  115. data/lib/hexapdf/reference.rb +1 -1
  116. data/lib/hexapdf/revision.rb +1 -1
  117. data/lib/hexapdf/revisions.rb +3 -3
  118. data/lib/hexapdf/serializer.rb +15 -15
  119. data/lib/hexapdf/stream.rb +4 -2
  120. data/lib/hexapdf/tokenizer.rb +14 -14
  121. data/lib/hexapdf/type/acro_form/appearance_generator.rb +22 -22
  122. data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
  123. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  124. data/lib/hexapdf/type/acro_form/field.rb +2 -2
  125. data/lib/hexapdf/type/acro_form/form.rb +1 -1
  126. data/lib/hexapdf/type/acro_form/signature_field.rb +4 -4
  127. data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
  128. data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
  129. data/lib/hexapdf/type/acro_form.rb +1 -1
  130. data/lib/hexapdf/type/action.rb +1 -1
  131. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  132. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  133. data/lib/hexapdf/type/actions/launch.rb +1 -1
  134. data/lib/hexapdf/type/actions/uri.rb +1 -1
  135. data/lib/hexapdf/type/actions.rb +1 -1
  136. data/lib/hexapdf/type/annotation.rb +3 -3
  137. data/lib/hexapdf/type/annotations/link.rb +1 -1
  138. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  139. data/lib/hexapdf/type/annotations/text.rb +1 -1
  140. data/lib/hexapdf/type/annotations/widget.rb +2 -2
  141. data/lib/hexapdf/type/annotations.rb +1 -1
  142. data/lib/hexapdf/type/catalog.rb +1 -1
  143. data/lib/hexapdf/type/cid_font.rb +3 -3
  144. data/lib/hexapdf/type/embedded_file.rb +1 -1
  145. data/lib/hexapdf/type/file_specification.rb +2 -2
  146. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  147. data/lib/hexapdf/type/font_simple.rb +2 -2
  148. data/lib/hexapdf/type/font_type0.rb +3 -3
  149. data/lib/hexapdf/type/font_type3.rb +1 -1
  150. data/lib/hexapdf/type/form.rb +1 -1
  151. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  152. data/lib/hexapdf/type/icon_fit.rb +1 -1
  153. data/lib/hexapdf/type/image.rb +1 -1
  154. data/lib/hexapdf/type/info.rb +1 -1
  155. data/lib/hexapdf/type/mark_information.rb +1 -1
  156. data/lib/hexapdf/type/names.rb +2 -2
  157. data/lib/hexapdf/type/object_stream.rb +2 -1
  158. data/lib/hexapdf/type/outline.rb +1 -1
  159. data/lib/hexapdf/type/outline_item.rb +1 -1
  160. data/lib/hexapdf/type/page.rb +19 -10
  161. data/lib/hexapdf/type/page_label.rb +1 -1
  162. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  163. data/lib/hexapdf/type/resources.rb +1 -1
  164. data/lib/hexapdf/type/trailer.rb +2 -2
  165. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  166. data/lib/hexapdf/type/xref_stream.rb +2 -2
  167. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  168. data/lib/hexapdf/version.rb +1 -1
  169. data/lib/hexapdf/writer.rb +4 -4
  170. data/lib/hexapdf/xref_section.rb +2 -2
  171. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +11 -1
  172. data/test/hexapdf/content/graphic_object/test_geom2d.rb +7 -0
  173. data/test/hexapdf/content/test_canvas.rb +0 -1
  174. data/test/hexapdf/digital_signature/test_signatures.rb +22 -0
  175. data/test/hexapdf/document/test_files.rb +2 -2
  176. data/test/hexapdf/document/test_layout.rb +98 -0
  177. data/test/hexapdf/encryption/test_security_handler.rb +12 -11
  178. data/test/hexapdf/encryption/test_standard_security_handler.rb +35 -23
  179. data/test/hexapdf/font/test_true_type_wrapper.rb +18 -1
  180. data/test/hexapdf/font/test_type1_wrapper.rb +15 -1
  181. data/test/hexapdf/layout/test_box.rb +1 -1
  182. data/test/hexapdf/layout/test_column_box.rb +65 -21
  183. data/test/hexapdf/layout/test_frame.rb +14 -14
  184. data/test/hexapdf/layout/test_image_box.rb +4 -0
  185. data/test/hexapdf/layout/test_inline_box.rb +5 -0
  186. data/test/hexapdf/layout/test_list_box.rb +40 -6
  187. data/test/hexapdf/layout/test_page_style.rb +3 -2
  188. data/test/hexapdf/layout/test_style.rb +50 -0
  189. data/test/hexapdf/layout/test_table_box.rb +722 -0
  190. data/test/hexapdf/layout/test_text_box.rb +18 -0
  191. data/test/hexapdf/layout/test_text_layouter.rb +4 -0
  192. data/test/hexapdf/test_dictionary_fields.rb +4 -1
  193. data/test/hexapdf/test_document.rb +1 -0
  194. data/test/hexapdf/test_filter.rb +8 -0
  195. data/test/hexapdf/test_importer.rb +9 -0
  196. data/test/hexapdf/test_object.rb +16 -5
  197. data/test/hexapdf/test_stream.rb +7 -0
  198. data/test/hexapdf/test_writer.rb +3 -3
  199. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +13 -5
  200. data/test/hexapdf/type/acro_form/test_form.rb +4 -3
  201. data/test/hexapdf/type/test_page.rb +18 -4
  202. metadata +17 -8
@@ -86,7 +86,7 @@ module HexaPDF
86
86
  # to combination of the superclass value of the constant and the mapping of flag names to bit
87
87
  # indices.
88
88
  #
89
- # See: PDF1.7 s12.7.3.1
89
+ # See: PDF2.0 s12.7.4.1
90
90
  class Field < Dictionary
91
91
 
92
92
  # Provides a #value method for hash that returns self so that a Hash can be used
@@ -367,7 +367,7 @@ module HexaPDF
367
367
  document.pages.each do |page|
368
368
  if page.key?(:Annots) && (index = page[:Annots].index(self))
369
369
  page[:Annots][index] = widget
370
- break # Each annotation dictionary may only appear on one page, see PDF1.7 12.5.2
370
+ break # Each annotation dictionary may only appear on one page, see PDF2.0 12.5.2
371
371
  end
372
372
  end
373
373
  widget
@@ -68,7 +68,7 @@ module HexaPDF
68
68
  # HexaPDF uses the configuration option +acro_form.create_appearance_streams+ to determine
69
69
  # whether appearances should automatically be generated.
70
70
  #
71
- # See: PDF1.7 s12.7.2, Field, HexaPDF::Type::Annotations::Widget
71
+ # See: PDF2.0 s12.7.3, Field, HexaPDF::Type::Annotations::Widget
72
72
  class Form < Dictionary
73
73
 
74
74
  extend Utils::BitField
@@ -49,13 +49,13 @@ module HexaPDF
49
49
  # If the signature should not be visible, the associated widget annotation should have zero
50
50
  # width and height; and/or the 'hidden' or 'no_view' flags of the annotation should be set.
51
51
  #
52
- # See: PDF1.7 s12.7.4.5
52
+ # See: PDF2.0 s12.7.5.5
53
53
  class SignatureField < Field
54
54
 
55
55
  # A signature field lock dictionary specifies a set of form fields that should be locked
56
56
  # once the associated signature field is signed.
57
57
  #
58
- # See: PDF1.7 s12.7.4.5
58
+ # See: PDF2.0 s12.7.5.5
59
59
  class LockDictionary < Dictionary
60
60
 
61
61
  define_type :SigFieldLock
@@ -86,7 +86,7 @@ module HexaPDF
86
86
  # The available flags are: filter, sub_filter, v, reasons, legal_attestation, add_rev_info
87
87
  # and digest_method.
88
88
  #
89
- # See: PDF1.7 s12.7.4.5
89
+ # See: PDF2.0 s12.7.5.5
90
90
  class SeedValueDictionary < Dictionary
91
91
 
92
92
  extend Utils::BitField
@@ -145,7 +145,7 @@ module HexaPDF
145
145
  #
146
146
  # The available flags are: subject, issuer, oid, subject_dn, reserved, key_usage and url.
147
147
  #
148
- # See: PDF1.7 s12.7.4.5
148
+ # See: PDF2.0 s12.7.5.5
149
149
  class CertificateSeedValueDictionary < Dictionary
150
150
 
151
151
  extend Utils::BitField
@@ -70,7 +70,7 @@ module HexaPDF
70
70
  #
71
71
  # :rich_text:: The field is a rich text field.
72
72
  #
73
- # See: PDF1.7 s12.7.4.3
73
+ # See: PDF2.0 s12.7.5.3
74
74
  class TextField < VariableTextField
75
75
 
76
76
  define_type :XXAcroFormField
@@ -48,7 +48,7 @@ module HexaPDF
48
48
  # value; the value is entered by the user and needs to be rendered correctly by the PDF
49
49
  # reader.
50
50
  #
51
- # See: PDF1.7 s12.7.3.3
51
+ # See: PDF2.0 s12.7.4.3
52
52
  class VariableTextField < Field
53
53
 
54
54
  define_field :DA, type: String
@@ -39,7 +39,7 @@ module HexaPDF
39
39
 
40
40
  # Namespace module for all AcroForm related dictionary types.
41
41
  #
42
- # See: PDF1.7 s12.7
42
+ # See: PDF2.0 s12.7
43
43
  module AcroForm
44
44
 
45
45
  autoload(:Form, 'hexapdf/type/acro_form/form')
@@ -44,7 +44,7 @@ module HexaPDF
44
44
  # Action dictionaries are used, for example, by annotations or outline items to specify the
45
45
  # action that should be performed. Each action class should be defined under the Actions module.
46
46
  #
47
- # See: PDF1.7 s12.6
47
+ # See: PDF2.0 s12.6
48
48
  class Action < Dictionary
49
49
 
50
50
  define_type :Action
@@ -42,7 +42,7 @@ module HexaPDF
42
42
 
43
43
  # A Go-To action changes the view to a specific destination.
44
44
  #
45
- # See: PDF1.7 s12.6.4.2
45
+ # See: PDF2.0 s12.6.4.2
46
46
  class GoTo < Action
47
47
 
48
48
  define_field :S, type: Symbol, required: true, default: :GoTo
@@ -42,7 +42,7 @@ module HexaPDF
42
42
 
43
43
  # A remote Go-To action dictionary jumps to a destination in a different PDF file.
44
44
  #
45
- # See: PDF1.7 s12.6.4.3
45
+ # See: PDF2.0 s12.6.4.3
46
46
  class GoToR < Action
47
47
 
48
48
  define_field :S, type: Symbol, required: true, default: :GoToR
@@ -42,7 +42,7 @@ module HexaPDF
42
42
 
43
43
  # A Launch action dictionary launches an application, opens a document or prints a document.
44
44
  #
45
- # See: PDF1.7 s12.6.4.5
45
+ # See: PDF2.0 s12.6.4.6
46
46
  class Launch < Action
47
47
 
48
48
  # The type used for the /Win field of a Launch action dictionary.
@@ -42,7 +42,7 @@ module HexaPDF
42
42
 
43
43
  # Represents an URI action dictionary, mostly used for opening Internet pages.
44
44
  #
45
- # See: PDF1.7 s12.6.4.7
45
+ # See: PDF2.0 s12.6.4.8
46
46
  class URI < Action
47
47
 
48
48
  define_field :S, type: Symbol, required: true, default: :URI
@@ -41,7 +41,7 @@ module HexaPDF
41
41
 
42
42
  # Namespace module for all PDF action dictionary types.
43
43
  #
44
- # See: PDF1.7 s12.6.4, Action
44
+ # See: PDF2.0 s12.6.4, Action
45
45
  module Actions
46
46
 
47
47
  autoload(:GoTo, 'hexapdf/type/actions/go_to')
@@ -43,7 +43,7 @@ module HexaPDF
43
43
  # Annotations are used to associate objects like notes, sounds or movies with a location on a
44
44
  # PDF page or allow the user to interact with a PDF document using a keyboard or mouse.
45
45
  #
46
- # See: PDF1.7 s12.5
46
+ # See: PDF2.0 s12.5
47
47
  class Annotation < Dictionary
48
48
 
49
49
  # The appearance dictionary references appearance streams for various use cases.
@@ -52,7 +52,7 @@ module HexaPDF
52
52
  # latter is used when the appearance depends on the state of the annotation, e.g. a check box
53
53
  # widget that can be checked or unchecked.
54
54
  #
55
- # See: PDF1.7 s12.5.5
55
+ # See: PDF2.0 s12.5.5
56
56
  class AppearanceDictionary < Dictionary
57
57
 
58
58
  define_type :XXAppearanceDictionary
@@ -101,7 +101,7 @@ module HexaPDF
101
101
 
102
102
  # Border style dictionary used by various annotation types.
103
103
  #
104
- # See: PDF1.7 s12.5.4
104
+ # See: PDF2.0 s12.5.4
105
105
  class Border < Dictionary
106
106
 
107
107
  define_type :Border
@@ -43,7 +43,7 @@ module HexaPDF
43
43
  # Link annotations represent a link to a destination elsewhere in the PDF document or an
44
44
  # action to be performed.
45
45
  #
46
- # See: PDF1.7 s12.5.6.5, HexaPDF::Type::Annotation
46
+ # See: PDF2.0 s12.5.6.5, HexaPDF::Type::Annotation
47
47
  class Link < Annotation
48
48
 
49
49
  define_field :Subtype, type: Symbol, required: true, default: :Link
@@ -43,7 +43,7 @@ module HexaPDF
43
43
  # Markup annotations are used to "mark up" a PDF document, most of the available PDF
44
44
  # annotations are actually markup annotations.
45
45
  #
46
- # See: PDF1.7 s12.5.6.2, HexaPDF::Type::Annotation
46
+ # See: PDF2.0 s12.5.6.2, HexaPDF::Type::Annotation
47
47
  class MarkupAnnotation < Annotation
48
48
 
49
49
  define_field :T, type: String, version: '1.1'
@@ -43,7 +43,7 @@ module HexaPDF
43
43
  # Text annotations are "sticky notes" attached to a point in a PDF document. They act as if
44
44
  # the NoZoom and NoRotate flags were always set.
45
45
  #
46
- # See: PDF1.7 s12.5.6.4, HexaPDF::Type::MarkupAnnotation
46
+ # See: PDF2.0 s12.5.6.4, HexaPDF::Type::MarkupAnnotation
47
47
  class Text < MarkupAnnotation
48
48
 
49
49
  define_field :Subtype, type: Symbol, required: true, default: :Text
@@ -45,7 +45,7 @@ module HexaPDF
45
45
  # Widget annotations are used by interactive forms to represent the appearance of fields and
46
46
  # to manage user interactions.
47
47
  #
48
- # See: PDF1.7 s12.5.6.19, HexaPDF::Type::Annotation
48
+ # See: PDF2.0 s12.5.6.19, HexaPDF::Type::Annotation
49
49
  class Widget < Annotation
50
50
 
51
51
  # The dictionary used by the /MK key of the widget annotation.
@@ -264,7 +264,7 @@ module HexaPDF
264
264
  # the /DA key on the widget (although /DA is not defined for widget, this is how Acrobat
265
265
  # does it).
266
266
  #
267
- # See: PDF1.7 s12.5.6.19 and s17.7.3.3
267
+ # See: PDF2.0 s12.5.6.19 and s12.7.4.3
268
268
  def marker_style(style: nil, size: nil, color: nil)
269
269
  field = form_field
270
270
  if style || size || color
@@ -41,7 +41,7 @@ module HexaPDF
41
41
 
42
42
  # Namespace module for all PDF annotation dictionary types.
43
43
  #
44
- # See: PDF1.7 s12.5.6, Annotation
44
+ # See: PDF2.0 s12.5.6, Annotation
45
45
  module Annotations
46
46
 
47
47
  autoload(:MarkupAnnotation, 'hexapdf/type/annotations/markup_annotation')
@@ -46,7 +46,7 @@ module HexaPDF
46
46
  #
47
47
  # The catalog dictionary is linked via the /Root entry from the Trailer.
48
48
  #
49
- # See: PDF1.7 s7.7.2, Trailer
49
+ # See: PDF2.0 s7.7.2, Trailer
50
50
  class Catalog < Dictionary
51
51
 
52
52
  define_type :Catalog
@@ -42,7 +42,7 @@ module HexaPDF
42
42
  # Represents a generic CIDFont which can only be used as a descendant font of a composite PDF
43
43
  # font.
44
44
  #
45
- # See: PDF1.7 s9.7.4
45
+ # See: PDF2.0 s9.7.4
46
46
  class CIDFont < Font
47
47
 
48
48
  DEFAULT_WIDTH = 1000 # :nodoc:
@@ -66,7 +66,7 @@ module HexaPDF
66
66
  # Sets the /W and /DW keys using the given array of [CID, width] pairs and an optional default
67
67
  # width.
68
68
  #
69
- # See: PDF1.7 s9.7.4.3
69
+ # See: PDF2.0 s9.7.4.3
70
70
  def set_widths(widths, default_width: DEFAULT_WIDTH)
71
71
  if widths.empty?
72
72
  (default_width == DEFAULT_WIDTH ? delete(:DW) : self[:DW] = default_width)
@@ -93,7 +93,7 @@ module HexaPDF
93
93
  #
94
94
  # Note that the hash is cached internally when accessed the first time.
95
95
  #
96
- # See: PDF1.7 s9.7.4.3
96
+ # See: PDF2.0 s9.7.4.3
97
97
  def widths
98
98
  cache(:widths) do
99
99
  result = {}
@@ -46,7 +46,7 @@ module HexaPDF
46
46
  # Type::FileSpecification dictionary or with the document as a whole through the /EmbeddedFiles
47
47
  # entry in the document catalog's /Names dictionary.
48
48
  #
49
- # See: PDF1.7 s7.11.4, FileSpecification
49
+ # See: PDF2.0 s7.11.4, FileSpecification
50
50
  class EmbeddedFile < Stream
51
51
 
52
52
  # The type used for the /Mac field of an EmbeddedFile::Parameters dictionary.
@@ -60,7 +60,7 @@ module HexaPDF
60
60
  # is useful to provide embedding/unembedding operations in this class, see #embed and
61
61
  # #unembed.
62
62
  #
63
- # See: PDF1.7 s7.11
63
+ # See: PDF2.0 s7.11
64
64
  class FileSpecification < Dictionary
65
65
 
66
66
  # The type used for the /EF field of a FileSpecification
@@ -107,7 +107,7 @@ module HexaPDF
107
107
  # /Unix, /Mac and /DOS).
108
108
  def path
109
109
  tmp = (self[:UF] || self[:F] || self[:Unix] || self[:Mac] || self[:DOS] || '').dup
110
- tmp.gsub!(/\\\//, "/") # PDF1.7 s7.11.2.1 but / in filename is interpreted as separator!
110
+ tmp.gsub!(/\\\//, "/") # PDF2.0 s7.11.2.1 but / in filename is interpreted as separator!
111
111
  tmp.tr!("\\", "/") # always use slashes instead of back-slashes!
112
112
  tmp
113
113
  end
@@ -44,7 +44,7 @@ module HexaPDF
44
44
  # This class specifies metrics and other attributes of a simple font or a CID font as a
45
45
  # whole.
46
46
  #
47
- # See: PDF1.7 s9.8
47
+ # See: PDF2.0 s9.8
48
48
  class FontDescriptor < Dictionary
49
49
 
50
50
  extend Utils::BitField
@@ -44,7 +44,7 @@ module HexaPDF
44
44
  #
45
45
  # A simple font has only single-byte character codes and only supports horizontal metrics.
46
46
  #
47
- # See: PDF1.7 s9.6
47
+ # See: PDF2.0 s9.6
48
48
  class FontSimple < Font
49
49
 
50
50
  define_field :FirstChar, type: Integer
@@ -129,7 +129,7 @@ module HexaPDF
129
129
  #
130
130
  # Always returns +true+ for simple fonts.
131
131
  #
132
- # See: PDF1.7 s9.3.3
132
+ # See: PDF2.0 s9.3.3
133
133
  def word_spacing_applicable?
134
134
  true
135
135
  end
@@ -48,7 +48,7 @@ module HexaPDF
48
48
  # Composite fonts also allow for vertical writing mode and support TrueType as well as OpenType
49
49
  # fonts.
50
50
  #
51
- # See: PDF1.7 s9.7
51
+ # See: PDF2.0 s9.7
52
52
  class FontType0 < Font
53
53
 
54
54
  define_field :Subtype, type: Symbol, required: true, default: :Type0
@@ -110,7 +110,7 @@ module HexaPDF
110
110
  #
111
111
  # Note that the return value is cached when accessed the first time.
112
112
  #
113
- # See: PDF1.7 s9.3.3
113
+ # See: PDF2.0 s9.3.3
114
114
  def word_spacing_applicable?
115
115
  @word_spacing_applicable ||= ((cmap.read_codes("\x20") && true) rescue false)
116
116
  end
@@ -138,7 +138,7 @@ module HexaPDF
138
138
  #
139
139
  # Note that the CMap is cached internally when accessed the first time.
140
140
  #
141
- # See: PDF1.7 s9.10.2
141
+ # See: PDF2.0 s9.10.2
142
142
  def ucs2_cmap
143
143
  cache(:ucs2_cmap) do
144
144
  encoding = self[:Encoding]
@@ -45,7 +45,7 @@ module HexaPDF
45
45
  # If it is of a different form, things won't work correctly. This will be handled once such a
46
46
  # case is found.
47
47
  #
48
- # See: PDF1.7 s9.6.5
48
+ # See: PDF2.0 s9.6.4
49
49
  class FontType3 < FontSimple
50
50
 
51
51
  define_field :Subtype, type: Symbol, required: true, default: :Type3
@@ -42,7 +42,7 @@ module HexaPDF
42
42
 
43
43
  # Represents a form XObject of a PDF document.
44
44
  #
45
- # See: PDF1.7 s8.10
45
+ # See: PDF2.0 s8.10
46
46
  class Form < Stream
47
47
 
48
48
  define_type :XObject
@@ -46,7 +46,7 @@ module HexaPDF
46
46
  # Some parameters can only be set by an operator, some only by the dictionary but most by
47
47
  # both.
48
48
  #
49
- # See: PDF1.7 s8.4.5, s8.1
49
+ # See: PDF2.0 s8.4.5, s8.1
50
50
  class GraphicsStateParameter < Dictionary
51
51
 
52
52
  define_type :ExtGState
@@ -42,7 +42,7 @@ module HexaPDF
42
42
  # An IconFit dictionary specifies how an icon should be displayed inside an annotation
43
43
  # rectangle.
44
44
  #
45
- # See: PDF1.7 s12.7.7.3.2
45
+ # See: PDF2.0 s12.7.8.3.2
46
46
  class IconFit < Annotation
47
47
 
48
48
  define_type :XXIconFit
@@ -45,7 +45,7 @@ module HexaPDF
45
45
 
46
46
  # Represents an image XObject of a PDF document.
47
47
  #
48
- # See: PDF1.7 s8.8
48
+ # See: PDF2.0 s8.8
49
49
  class Image < Stream
50
50
 
51
51
  # The structure that is returned by the Image#info method.
@@ -44,7 +44,7 @@ module HexaPDF
44
44
  # The info dictionary is linked via the /Info entry from the Trailer and contains metadata for
45
45
  # the document.
46
46
  #
47
- # See: PDF1.7 s14.3.3, Trailer
47
+ # See: PDF2.0 s14.3.3, Trailer
48
48
  class Info < Dictionary
49
49
 
50
50
  define_type :XXInfo
@@ -42,7 +42,7 @@ module HexaPDF
42
42
  # Represents the mark information dictionary which provides some general information related to
43
43
  # structured PDF documents.
44
44
  #
45
- # See: PDF1.7 s14.7.1
45
+ # See: PDF2.0 s14.7.1
46
46
  class MarkInformation < Dictionary
47
47
 
48
48
  define_type :XXMarkInformation
@@ -47,7 +47,7 @@ module HexaPDF
47
47
  #
48
48
  # This dictionary is linked via the /Names entry from the HexaPDF::Catalog.
49
49
  #
50
- # See: PDF1.7 s7.7.4, HexaPDF::Catalog, HexaPDF::NameTreeNode
50
+ # See: PDF2.0 s7.7.4, HexaPDF::Catalog, HexaPDF::NameTreeNode
51
51
  class Names < Dictionary
52
52
 
53
53
  define_type :XXNames
@@ -71,7 +71,7 @@ module HexaPDF
71
71
  # provides a much easier to work with convenience interface for working with destination
72
72
  # objects.
73
73
  #
74
- # See: PDF1.7 s12.3.2
74
+ # See: PDF2.0 s12.3.2
75
75
  def destinations
76
76
  self[:Dests] ||= document.add({}, type: NameTreeNode)
77
77
  end
@@ -70,7 +70,7 @@ module HexaPDF
70
70
  # However, only objects that can be written to the object stream are actually written. The
71
71
  # other objects are deleted from the object stream (#delete_object) and written normally.
72
72
  #
73
- # See PDF1.7 s7.5.7
73
+ # See PDF2.0 s7.5.7
74
74
  class ObjectStream < HexaPDF::Stream
75
75
 
76
76
  # Holds all necessary information to load objects for an object stream.
@@ -114,6 +114,7 @@ module HexaPDF
114
114
  return @stream_data if defined?(@stream_data)
115
115
  data = stream
116
116
  oids, offsets = parse_oids_and_offsets(data)
117
+ @objects ||= {}
117
118
  oids.each {|oid| add_object(Reference.new(oid, 0)) }
118
119
  @stream_data = Data.new(data, oids, offsets)
119
120
  end
@@ -80,7 +80,7 @@ module HexaPDF
80
80
  # # Copying all the pages so that the references work.
81
81
  # doc.pages.each {|page| target.pages << target.import(page) }
82
82
  #
83
- # See: PDF1.7 s12.3.3
83
+ # See: PDF2.0 s12.3.3
84
84
  class Outline < Dictionary
85
85
 
86
86
  define_type :Outlines
@@ -60,7 +60,7 @@ module HexaPDF
60
60
  # Since many dictionary keys need to be kept up-to-date when manipulating the outline item tree,
61
61
  # it is not recommended to manually do this but to rely on the provided convenience methods.
62
62
  #
63
- # See: PDF1.7 s12.3.3
63
+ # See: PDF2.0 s12.3.3
64
64
  class OutlineItem < Dictionary
65
65
 
66
66
  extend Utils::BitField
@@ -54,7 +54,7 @@ module HexaPDF
54
54
  # Field inheritance means that if a field is not set on the page object itself, the value is
55
55
  # taken from the nearest page tree ancestor that has this value set.
56
56
  #
57
- # See: PDF1.7 s7.7.3.3, s7.7.3.4, Pages
57
+ # See: PDF2.0 s7.7.3.3, s7.7.3.4, Pages
58
58
  class Page < Dictionary
59
59
 
60
60
  # The predefined paper sizes in points (1/72 inch):
@@ -223,7 +223,7 @@ module HexaPDF
223
223
  # The art box defines the region of the page's meaningful content as intended by the
224
224
  # author. The default is the crop box.
225
225
  #
226
- # See: PDF1.7 s14.11.2
226
+ # See: PDF2.0 s14.11.2
227
227
  def box(type = :crop, rectangle = nil)
228
228
  if rectangle
229
229
  case type
@@ -522,8 +522,8 @@ module HexaPDF
522
522
  # Yields each annotation of this page.
523
523
  def each_annotation
524
524
  return to_enum(__method__) unless block_given?
525
- self[:Annots]&.each do |annotation|
526
- next unless annotation
525
+ Array(self[:Annots]).each do |annotation|
526
+ next unless annotation&.key?(:Subtype) && annotation&.key?(:Rect)
527
527
  yield(document.wrap(annotation, type: :Annot))
528
528
  end
529
529
  self
@@ -539,10 +539,14 @@ module HexaPDF
539
539
  # If an annotation is a form field widget, only the widget will be deleted but not the form
540
540
  # field itself.
541
541
  def flatten_annotations(annotations = self[:Annots])
542
- not_flattened = (annotations || []).to_ary
542
+ not_flattened = Array(annotations) || []
543
543
  return not_flattened unless key?(:Annots)
544
544
 
545
- annotations = not_flattened & self[:Annots] if annotations != self[:Annots]
545
+ annotations = if annotations == self[:Annots]
546
+ not_flattened
547
+ else
548
+ not_flattened & Array(self[:Annots])
549
+ end
546
550
  return not_flattened if annotations.empty?
547
551
 
548
552
  canvas = self.canvas(type: :overlay)
@@ -554,6 +558,11 @@ module HexaPDF
554
558
  to_delete = []
555
559
  not_flattened -= annotations
556
560
  annotations.each do |annotation|
561
+ unless annotation&.key?(:Subtype) && annotation&.key?(:Rect)
562
+ to_delete << annotation if annotation
563
+ next
564
+ end
565
+
557
566
  annotation = document.wrap(annotation, type: :Annot)
558
567
  appearance = annotation.appearance
559
568
  if annotation.flagged?(:hidden) || annotation.flagged?(:invisible)
@@ -567,8 +576,8 @@ module HexaPDF
567
576
  rect = annotation[:Rect]
568
577
  box = appearance.box
569
578
 
570
- # PDF1.7 12.5.5 algorithm
571
- # Step a) Calculate smallest rectangle containing transformed bounding box
579
+ # PDF2.0 12.5.5 algorithm
580
+ # Step 1) Calculate smallest rectangle containing transformed bounding box
572
581
  matrix = HexaPDF::Content::TransformationMatrix.new(*appearance[:Matrix].value)
573
582
  llx, lly = matrix.evaluate(box.left, box.bottom)
574
583
  ulx, uly = matrix.evaluate(box.left, box.top)
@@ -582,12 +591,12 @@ module HexaPDF
582
591
  next
583
592
  end
584
593
 
585
- # Step b) Fit calculated rectangle to annotation rectangle by translating/scaling
594
+ # Step 2) Fit calculated rectangle to annotation rectangle by translating/scaling
586
595
  a = HexaPDF::Content::TransformationMatrix.new
587
596
  a.translate(rect.left - left, rect.bottom - bottom)
588
597
  a.scale(rect.width.fdiv(right - left), rect.height.fdiv(top - bottom))
589
598
 
590
- # Step c) Premultiply form matrix - done implicitly when drawing the XObject
599
+ # Step 3) Premultiply form matrix - done implicitly when drawing the XObject
591
600
 
592
601
  canvas.transform(*a) do
593
602
  # Use [box.left, box.bottom] to counter default translation in #xobject since that
@@ -70,7 +70,7 @@ module HexaPDF
70
70
  #
71
71
  # "", "", "", ... (i.e. always the empty string)
72
72
  #
73
- # See: PDF1.7 s12.4.2, HexaPDF::Document::Pages, HexaPDF::Type::Catalog
73
+ # See: PDF2.0 s12.4.2, HexaPDF::Document::Pages, HexaPDF::Type::Catalog
74
74
  class PageLabel < Dictionary
75
75
 
76
76
  define_type :PageLabel
@@ -60,7 +60,7 @@ module HexaPDF
60
60
  # value. If an inherited /Resources dictionary does *not* exist, an empty one is created for
61
61
  # the page.
62
62
  #
63
- # See: PDF1.7 s7.7.3.2, Page
63
+ # See: PDF2.0 s7.7.3.2, Page
64
64
  class PageTreeNode < Dictionary
65
65
 
66
66
  define_type :Pages
@@ -44,7 +44,7 @@ module HexaPDF
44
44
 
45
45
  # Represents the resources needed by a content stream.
46
46
  #
47
- # See: PDF1.7 s7.8.3
47
+ # See: PDF2.0 s7.8.3
48
48
  class Resources < Dictionary
49
49
 
50
50
  define_type :XXResources
@@ -54,7 +54,7 @@ module HexaPDF
54
54
  # HexaPDF::Revision object's trailer dictionary is always of this type. Only when a
55
55
  # cross-reference stream is written is the trailer integrated into the stream's dictionary.
56
56
  #
57
- # See: PDF1.7 s7.5.5, s14.4; XRefStream
57
+ # See: PDF2.0 s7.5.5, s14.4; XRefStream
58
58
  class Trailer < Dictionary
59
59
 
60
60
  define_type :XXTrailer
@@ -79,7 +79,7 @@ module HexaPDF
79
79
 
80
80
  # Sets the /ID field to an array of two copies of a random string and returns this array.
81
81
  #
82
- # See: PDF1.7 14.4
82
+ # See: PDF2.0 14.4
83
83
  def set_random_id
84
84
  value[:ID] = [Digest::MD5.digest(rand.to_s)] * 2
85
85
  end
@@ -44,7 +44,7 @@ module HexaPDF
44
44
  #
45
45
  # This dictionary is linked via the /ViewerPreferences entry from the Type::Catalog.
46
46
  #
47
- # See: PDF1.7 s12.2, Catalog
47
+ # See: PDF2.0 s12.2, Catalog
48
48
  class ViewerPreferences < Dictionary
49
49
 
50
50
  define_type :XXViewerPreferences