hexapdf 0.11.9 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +157 -0
  3. data/LICENSE +1 -1
  4. data/examples/001-hello_world.rb +1 -1
  5. data/examples/002-graphics.rb +1 -1
  6. data/examples/003-arcs.rb +1 -1
  7. data/examples/004-optimizing.rb +1 -1
  8. data/examples/005-merging.rb +1 -1
  9. data/examples/006-standard_pdf_fonts.rb +1 -1
  10. data/examples/007-truetype.rb +1 -1
  11. data/examples/008-show_char_bboxes.rb +1 -1
  12. data/examples/009-text_layouter_alignment.rb +1 -1
  13. data/examples/010-text_layouter_inline_boxes.rb +1 -1
  14. data/examples/011-text_layouter_line_wrapping.rb +1 -1
  15. data/examples/012-text_layouter_styling.rb +1 -1
  16. data/examples/013-text_layouter_shapes.rb +1 -1
  17. data/examples/014-text_in_polygon.rb +1 -1
  18. data/examples/015-boxes.rb +1 -1
  19. data/examples/016-frame_automatic_box_placement.rb +1 -1
  20. data/examples/017-frame_text_flow.rb +1 -1
  21. data/examples/018-composer.rb +1 -1
  22. data/examples/019-acro_form.rb +51 -0
  23. data/lib/hexapdf.rb +1 -1
  24. data/lib/hexapdf/cli.rb +3 -1
  25. data/lib/hexapdf/cli/batch.rb +1 -1
  26. data/lib/hexapdf/cli/command.rb +22 -11
  27. data/lib/hexapdf/cli/files.rb +1 -1
  28. data/lib/hexapdf/cli/form.rb +240 -0
  29. data/lib/hexapdf/cli/image2pdf.rb +3 -2
  30. data/lib/hexapdf/cli/images.rb +1 -1
  31. data/lib/hexapdf/cli/info.rb +52 -3
  32. data/lib/hexapdf/cli/inspect.rb +31 -9
  33. data/lib/hexapdf/cli/merge.rb +2 -2
  34. data/lib/hexapdf/cli/modify.rb +1 -1
  35. data/lib/hexapdf/cli/optimize.rb +1 -1
  36. data/lib/hexapdf/cli/split.rb +1 -1
  37. data/lib/hexapdf/cli/watermark.rb +1 -1
  38. data/lib/hexapdf/composer.rb +2 -2
  39. data/lib/hexapdf/configuration.rb +81 -11
  40. data/lib/hexapdf/content.rb +3 -1
  41. data/lib/hexapdf/content/canvas.rb +5 -18
  42. data/lib/hexapdf/content/color_space.rb +111 -32
  43. data/lib/hexapdf/content/graphic_object.rb +1 -1
  44. data/lib/hexapdf/content/graphic_object/arc.rb +4 -4
  45. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
  46. data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
  47. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  48. data/lib/hexapdf/content/graphics_state.rb +1 -1
  49. data/lib/hexapdf/content/operator.rb +9 -9
  50. data/lib/hexapdf/content/parser.rb +18 -5
  51. data/lib/hexapdf/content/processor.rb +1 -1
  52. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  53. data/lib/hexapdf/data_dir.rb +1 -1
  54. data/lib/hexapdf/dictionary.rb +5 -5
  55. data/lib/hexapdf/dictionary_fields.rb +2 -10
  56. data/lib/hexapdf/document.rb +45 -17
  57. data/lib/hexapdf/document/files.rb +1 -2
  58. data/lib/hexapdf/document/fonts.rb +1 -1
  59. data/lib/hexapdf/document/images.rb +1 -1
  60. data/lib/hexapdf/document/pages.rb +3 -14
  61. data/lib/hexapdf/encryption.rb +1 -1
  62. data/lib/hexapdf/encryption/aes.rb +1 -1
  63. data/lib/hexapdf/encryption/arc4.rb +1 -1
  64. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  65. data/lib/hexapdf/encryption/fast_arc4.rb +2 -2
  66. data/lib/hexapdf/encryption/identity.rb +1 -1
  67. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  68. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  69. data/lib/hexapdf/encryption/security_handler.rb +2 -1
  70. data/lib/hexapdf/encryption/standard_security_handler.rb +2 -1
  71. data/lib/hexapdf/error.rb +1 -1
  72. data/lib/hexapdf/filter.rb +3 -3
  73. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  74. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  75. data/lib/hexapdf/filter/encryption.rb +1 -1
  76. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  77. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  78. data/lib/hexapdf/filter/{jpx_decode.rb → pass_through.rb} +5 -5
  79. data/lib/hexapdf/filter/predictor.rb +1 -1
  80. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  81. data/lib/hexapdf/font/cmap.rb +2 -5
  82. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  83. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  84. data/lib/hexapdf/font/encoding.rb +1 -1
  85. data/lib/hexapdf/font/encoding/base.rb +9 -1
  86. data/lib/hexapdf/font/encoding/difference_encoding.rb +7 -1
  87. data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
  88. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  89. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  90. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  91. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  92. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  93. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  94. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  95. data/lib/hexapdf/font/true_type.rb +1 -1
  96. data/lib/hexapdf/font/true_type/builder.rb +1 -1
  97. data/lib/hexapdf/font/true_type/font.rb +1 -1
  98. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  99. data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
  100. data/lib/hexapdf/font/true_type/table.rb +1 -1
  101. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  102. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  103. data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
  104. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  105. data/lib/hexapdf/font/true_type/table/head.rb +2 -1
  106. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  107. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  108. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  109. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  110. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  111. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  112. data/lib/hexapdf/font/true_type/table/os2.rb +3 -1
  113. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  114. data/lib/hexapdf/font/true_type_wrapper.rb +54 -51
  115. data/lib/hexapdf/font/type1.rb +1 -1
  116. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  117. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  118. data/lib/hexapdf/font/type1/font.rb +1 -1
  119. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  120. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  121. data/lib/hexapdf/font/type1_wrapper.rb +68 -52
  122. data/lib/hexapdf/font_loader.rb +1 -1
  123. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  124. data/lib/hexapdf/font_loader/from_file.rb +1 -1
  125. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  126. data/lib/hexapdf/image_loader.rb +1 -1
  127. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  128. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  129. data/lib/hexapdf/image_loader/png.rb +4 -3
  130. data/lib/hexapdf/importer.rb +2 -4
  131. data/lib/hexapdf/layout.rb +1 -1
  132. data/lib/hexapdf/layout/box.rb +1 -1
  133. data/lib/hexapdf/layout/frame.rb +1 -1
  134. data/lib/hexapdf/layout/image_box.rb +1 -1
  135. data/lib/hexapdf/layout/inline_box.rb +1 -1
  136. data/lib/hexapdf/layout/line.rb +2 -2
  137. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  138. data/lib/hexapdf/layout/style.rb +24 -24
  139. data/lib/hexapdf/layout/text_box.rb +1 -1
  140. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  141. data/lib/hexapdf/layout/text_layouter.rb +1 -1
  142. data/lib/hexapdf/layout/text_shaper.rb +4 -3
  143. data/lib/hexapdf/layout/width_from_polygon.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 +32 -27
  147. data/lib/hexapdf/parser.rb +69 -6
  148. data/lib/hexapdf/pdf_array.rb +10 -3
  149. data/lib/hexapdf/rectangle.rb +31 -1
  150. data/lib/hexapdf/reference.rb +1 -1
  151. data/lib/hexapdf/revision.rb +2 -1
  152. data/lib/hexapdf/revisions.rb +30 -22
  153. data/lib/hexapdf/serializer.rb +2 -2
  154. data/lib/hexapdf/stream.rb +1 -1
  155. data/lib/hexapdf/task.rb +1 -1
  156. data/lib/hexapdf/task/dereference.rb +1 -1
  157. data/lib/hexapdf/task/optimize.rb +7 -5
  158. data/lib/hexapdf/tokenizer.rb +5 -4
  159. data/lib/hexapdf/type.rb +1 -1
  160. data/lib/hexapdf/type/acro_form.rb +7 -1
  161. data/lib/hexapdf/type/acro_form/appearance_generator.rb +405 -0
  162. data/lib/hexapdf/type/acro_form/button_field.rb +305 -0
  163. data/lib/hexapdf/type/acro_form/choice_field.rb +220 -0
  164. data/lib/hexapdf/type/acro_form/field.rb +250 -17
  165. data/lib/hexapdf/type/acro_form/form.rb +159 -7
  166. data/lib/hexapdf/type/acro_form/text_field.rb +187 -0
  167. data/lib/hexapdf/type/acro_form/variable_text_field.rb +122 -0
  168. data/lib/hexapdf/type/action.rb +1 -1
  169. data/lib/hexapdf/type/actions.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 +4 -3
  174. data/lib/hexapdf/type/annotation.rb +73 -3
  175. data/lib/hexapdf/type/annotations.rb +1 -1
  176. data/lib/hexapdf/type/annotations/link.rb +2 -2
  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 +238 -2
  180. data/lib/hexapdf/type/catalog.rb +23 -3
  181. data/lib/hexapdf/type/cid_font.rb +1 -1
  182. data/lib/hexapdf/type/embedded_file.rb +1 -1
  183. data/lib/hexapdf/type/file_specification.rb +2 -2
  184. data/lib/hexapdf/type/font.rb +18 -1
  185. data/lib/hexapdf/type/font_descriptor.rb +2 -2
  186. data/lib/hexapdf/type/font_simple.rb +4 -2
  187. data/lib/hexapdf/type/font_true_type.rb +7 -3
  188. data/lib/hexapdf/type/font_type0.rb +2 -2
  189. data/lib/hexapdf/type/font_type1.rb +16 -1
  190. data/lib/hexapdf/type/font_type3.rb +1 -1
  191. data/lib/hexapdf/type/form.rb +12 -2
  192. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  193. data/lib/hexapdf/type/icon_fit.rb +1 -1
  194. data/lib/hexapdf/type/image.rb +5 -3
  195. data/lib/hexapdf/type/info.rb +1 -1
  196. data/lib/hexapdf/type/names.rb +1 -1
  197. data/lib/hexapdf/type/object_stream.rb +1 -1
  198. data/lib/hexapdf/type/page.rb +36 -12
  199. data/lib/hexapdf/type/page_tree_node.rb +37 -16
  200. data/lib/hexapdf/type/resources.rb +17 -3
  201. data/lib/hexapdf/type/trailer.rb +4 -6
  202. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  203. data/lib/hexapdf/type/xref_stream.rb +1 -1
  204. data/lib/hexapdf/utils/bit_field.rb +38 -24
  205. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  206. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  207. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  208. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  209. data/lib/hexapdf/utils/object_hash.rb +1 -1
  210. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  211. data/lib/hexapdf/utils/sorted_tree_node.rb +19 -16
  212. data/lib/hexapdf/version.rb +2 -2
  213. data/lib/hexapdf/writer.rb +1 -1
  214. data/lib/hexapdf/xref_section.rb +1 -1
  215. data/test/hexapdf/common_tokenizer_tests.rb +6 -1
  216. data/test/hexapdf/content/common.rb +2 -2
  217. data/test/hexapdf/content/graphic_object/test_arc.rb +4 -4
  218. data/test/hexapdf/content/test_canvas.rb +3 -3
  219. data/test/hexapdf/content/test_color_space.rb +71 -8
  220. data/test/hexapdf/content/test_operator.rb +22 -22
  221. data/test/hexapdf/content/test_parser.rb +14 -0
  222. data/test/hexapdf/document/test_fonts.rb +1 -1
  223. data/test/hexapdf/document/test_pages.rb +6 -6
  224. data/test/hexapdf/encryption/test_aes.rb +4 -4
  225. data/test/hexapdf/encryption/test_standard_security_handler.rb +11 -11
  226. data/test/hexapdf/filter/test_ascii85_decode.rb +1 -1
  227. data/test/hexapdf/filter/test_ascii_hex_decode.rb +1 -1
  228. data/test/hexapdf/font/encoding/test_base.rb +10 -0
  229. data/test/hexapdf/font/encoding/test_difference_encoding.rb +8 -0
  230. data/test/hexapdf/font/test_true_type_wrapper.rb +10 -7
  231. data/test/hexapdf/font/test_type1_wrapper.rb +33 -8
  232. data/test/hexapdf/layout/test_style.rb +1 -1
  233. data/test/hexapdf/layout/test_text_layouter.rb +3 -4
  234. data/test/hexapdf/test_configuration.rb +2 -2
  235. data/test/hexapdf/test_dictionary.rb +3 -1
  236. data/test/hexapdf/test_dictionary_fields.rb +2 -2
  237. data/test/hexapdf/test_document.rb +16 -4
  238. data/test/hexapdf/test_object.rb +44 -26
  239. data/test/hexapdf/test_parser.rb +125 -55
  240. data/test/hexapdf/test_pdf_array.rb +7 -0
  241. data/test/hexapdf/test_rectangle.rb +14 -0
  242. data/test/hexapdf/test_revision.rb +3 -0
  243. data/test/hexapdf/test_revisions.rb +35 -0
  244. data/test/hexapdf/test_writer.rb +2 -2
  245. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +521 -0
  246. data/test/hexapdf/type/acro_form/test_button_field.rb +281 -0
  247. data/test/hexapdf/type/acro_form/test_choice_field.rb +137 -0
  248. data/test/hexapdf/type/acro_form/test_field.rb +163 -6
  249. data/test/hexapdf/type/acro_form/test_form.rb +189 -22
  250. data/test/hexapdf/type/acro_form/test_text_field.rb +121 -0
  251. data/test/hexapdf/type/acro_form/test_variable_text_field.rb +77 -0
  252. data/test/hexapdf/type/annotations/test_text.rb +1 -1
  253. data/test/hexapdf/type/annotations/test_widget.rb +199 -0
  254. data/test/hexapdf/type/test_annotation.rb +45 -0
  255. data/test/hexapdf/type/test_catalog.rb +18 -0
  256. data/test/hexapdf/type/test_font.rb +5 -0
  257. data/test/hexapdf/type/test_font_simple.rb +2 -1
  258. data/test/hexapdf/type/test_font_true_type.rb +6 -0
  259. data/test/hexapdf/type/test_font_type1.rb +8 -0
  260. data/test/hexapdf/type/test_form.rb +19 -1
  261. data/test/hexapdf/type/test_image.rb +7 -0
  262. data/test/hexapdf/type/test_page.rb +45 -7
  263. data/test/hexapdf/type/test_page_tree_node.rb +62 -12
  264. data/test/hexapdf/type/test_resources.rb +20 -0
  265. data/test/hexapdf/type/test_trailer.rb +4 -0
  266. data/test/hexapdf/utils/test_bit_field.rb +15 -1
  267. data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -9
  268. data/test/test_helper.rb +1 -1
  269. metadata +34 -21
  270. data/lib/hexapdf/filter/dct_decode.rb +0 -60
@@ -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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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
@@ -122,7 +122,7 @@ module HexaPDF
122
122
 
123
123
  # Assemble pages
124
124
  target = (@initial_empty ? HexaPDF::Document.new : @files.first.file)
125
- page_tree = target.add(Type: :Pages)
125
+ page_tree = target.add({Type: :Pages})
126
126
  import_pages(page_tree)
127
127
  target.catalog[:Pages] = page_tree
128
128
  remove_unused_pages(target)
@@ -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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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
@@ -297,7 +297,7 @@ module HexaPDF
297
297
  style ||= base_style
298
298
  style = style.dup.update(**options) unless options.empty?
299
299
  style.font(base_style.font) unless style.font?
300
- style.font(@document.fonts.add(style.font)) unless style.font.respond_to?(:dict)
300
+ style.font(@document.fonts.add(style.font)) unless style.font.respond_to?(:pdf_object)
301
301
  style
302
302
  end
303
303
 
@@ -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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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,8 +48,9 @@ module HexaPDF
48
48
  # easily be changed.
49
49
  #
50
50
  # Some options are defined as global options because they are needed on the class level - see
51
- # HexaPDF::GlobalConfiguration. Other options can be configured for individual documents as they
52
- # allow to fine-tune some behavior - see HexaPDF::DefaultDocumentConfiguration.
51
+ # HexaPDF::GlobalConfiguration[index.html#GlobalConfiguration]. Other options can be configured for
52
+ # individual documents as they allow to fine-tune some behavior - see
53
+ # HexaPDF::DefaultDocumentConfiguration[index.html#DefaultDocumentConfiguration].
53
54
  #
54
55
  # A configuration option name is dot-separted to provide a hierarchy of option names. For
55
56
  # example, io.chunk_size.
@@ -144,6 +145,43 @@ module HexaPDF
144
145
  #
145
146
  # The following options are provided:
146
147
  #
148
+ # acro_form.appearance_generator::
149
+ # The class that should be used for generating appearances for AcroForm fields. If the value is
150
+ # a String, it should contain the name of a constant to such a class.
151
+ #
152
+ # See HexaPDF::Type::AcroForm::AppearanceGenerator
153
+ #
154
+ # acro_form.create_appearances::
155
+ # A boolean specifying whether an AcroForm field's appearances should automatically be
156
+ # generated if they are missing.
157
+ #
158
+ # acro_form.text_field.default_width::
159
+ # A number specifying the default width of AcroForm text fields which should be auto-sized.
160
+ #
161
+ # acro_form.default_font_size::
162
+ # A number specifying the default font size of AcroForm text fields which should be auto-sized.
163
+ #
164
+ # acro_form.fallback_font::
165
+ # The font that should be used when a variable text field references a font that cannot be used.
166
+ #
167
+ # Can either be the name of a font, like 'Helvetica', or an array consisting of the font name
168
+ # and a hash of font options, like ['Helvetica', variant: :italic]. If set to +nil+, the use of
169
+ # the fallback font is disabled.
170
+ #
171
+ # Default is 'Helvetica'.
172
+ #
173
+ # acro_form.on_invalid_value::
174
+ # Callback hook when an invalid value is set for certain types of AcroForm fields.
175
+ #
176
+ # The value needs to be an object that responds to \#call(field, value) where +field+ is the
177
+ # AcroForm field on which the value is set and +value+ is the invalid value. The returned value
178
+ # is used instead of the invalid value.
179
+ #
180
+ # The default implementation raises an error.
181
+ #
182
+ # acro_form.text_field.default_width::
183
+ # A number specifying the default width of AcroForm text fields which should be auto-sized.
184
+ #
147
185
  # document.auto_decrypt::
148
186
  # A boolean determining whether the document should be decrypted automatically when parsed.
149
187
  #
@@ -296,6 +334,20 @@ module HexaPDF
296
334
  # The value needs to be an object that responds to \#call(document, message, position) and
297
335
  # returns +true+ if an error should be raised.
298
336
  #
337
+ # parser.try_xref_reconstruction::
338
+ # A boolean specifying whether non-recoverable parsing errors should lead to reconstructing the
339
+ # main cross-reference table.
340
+ #
341
+ # The reconstructed cross-reference table might make damaged files usable but there is no way
342
+ # to ensure that the reconstructed file is equal to the undamaged original file (though
343
+ # generally it works out).
344
+ #
345
+ # There is also the possibility that reconstructing doesn't work because the algorithm has to
346
+ # assume that the PDF was written in a certain way (which is recommended by the PDF
347
+ # specification).
348
+ #
349
+ # Defaults to +true+.
350
+ #
299
351
  # sorted_tree.max_leaf_node_size::
300
352
  # The maximum number of nodes that should be in a leaf node of a node tree.
301
353
  #
@@ -307,7 +359,16 @@ module HexaPDF
307
359
  # task.map::
308
360
  # A mapping from task names to callable task objects. See HexaPDF::Task for more information.
309
361
  DefaultDocumentConfiguration =
310
- Configuration.new('document.auto_decrypt' => true,
362
+ Configuration.new('acro_form.appearance_generator' => 'HexaPDF::Type::AcroForm::AppearanceGenerator',
363
+ 'acro_form.create_appearances' => true,
364
+ 'acro_form.default_font_size' => 10,
365
+ 'acro_form.fallback_font' => 'Helvetica',
366
+ 'acro_form.on_invalid_value' => proc do |field, value|
367
+ raise HexaPDF::Error, "Invalid value #{value.inspect} for " \
368
+ "#{field.concrete_field_type} field #{field.full_field_name}"
369
+ end,
370
+ 'acro_form.text_field.default_width' => 100,
371
+ 'document.auto_decrypt' => true,
311
372
  'encryption.aes' => 'HexaPDF::Encryption::FastAES',
312
373
  'encryption.arc4' => 'HexaPDF::Encryption::FastARC4',
313
374
  'encryption.filter_map' => {
@@ -326,12 +387,12 @@ module HexaPDF
326
387
  Fl: 'HexaPDF::Filter::FlateDecode',
327
388
  RunLengthDecode: 'HexaPDF::Filter::RunLengthDecode',
328
389
  RL: 'HexaPDF::Filter::RunLengthDecode',
329
- CCITTFaxDecode: nil,
330
- CCF: nil,
331
- JBIG2Decode: nil,
332
- DCTDecode: 'HexaPDF::Filter::DCTDecode',
333
- DCT: 'HexaPDF::Filter::DCTDecode',
334
- JPXDecode: 'HexaPDF::Filter::JPXDecode',
390
+ CCITTFaxDecode: 'HexaPDF::Filter::PassThrough',
391
+ CCF: 'HexaPDF::Filter::PassThrough',
392
+ JBIG2Decode: 'HexaPDF::Filter::PassThrough',
393
+ DCTDecode: 'HexaPDF::Filter::PassThrough',
394
+ DCT: 'HexaPDF::Filter::PassThrough',
395
+ JPXDecode: 'HexaPDF::Filter::PassThrough',
335
396
  Crypt: nil,
336
397
  Encryption: 'HexaPDF::Filter::Encryption',
337
398
  },
@@ -365,6 +426,7 @@ module HexaPDF
365
426
  'page.default_media_box' => :A4,
366
427
  'page.default_media_orientation' => :portrait,
367
428
  'parser.on_correctable_error' => proc { false },
429
+ 'parser.try_xref_reconstruction' => true,
368
430
  'sorted_tree.max_leaf_node_size' => 64,
369
431
  'style.layers_map' => {
370
432
  link: 'HexaPDF::Layout::Style::LinkLayer',
@@ -447,10 +509,13 @@ module HexaPDF
447
509
  Action: 'HexaPDF::Type::Action',
448
510
  XXLaunchActionWinParameters: 'HexaPDF::Type::Actions::Launch::WinParameters',
449
511
  Annot: 'HexaPDF::Type::Annotation',
450
- XXAppearanceCharacteristics: 'HexaPDF::Type::Annotations::Widget::AppearanceCharacteristics',
512
+ XXAppearanceCharacteristics: \
513
+ 'HexaPDF::Type::Annotations::Widget::AppearanceCharacteristics',
451
514
  XXIconFit: 'HexaPDF::Type::IconFit',
452
515
  XXAcroForm: 'HexaPDF::Type::AcroForm::Form',
453
516
  XXAcroFormField: 'HexaPDF::Type::AcroForm::Field',
517
+ XXAppearanceDictionary: 'HexaPDF::Type::Annotation::AppearanceDictionary',
518
+ Border: 'HexaPDF::Type::Annotation::Border',
454
519
  },
455
520
  'object.subtype_map' => {
456
521
  nil => {
@@ -492,6 +557,11 @@ module HexaPDF
492
557
  Link: 'HexaPDF::Type::Annotations::Link',
493
558
  Widget: 'HexaPDF::Type::Annotations::Widget',
494
559
  },
560
+ XXAcroFormField: {
561
+ Tx: 'HexaPDF::Type::AcroForm::TextField',
562
+ Btn: 'HexaPDF::Type::AcroForm::ButtonField',
563
+ Ch: 'HexaPDF::Type::AcroForm::ChoiceField',
564
+ },
495
565
  })
496
566
 
497
567
  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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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
@@ -44,6 +44,8 @@ module HexaPDF
44
44
  autoload(:Canvas, 'hexapdf/content/canvas')
45
45
  autoload(:Parser, 'hexapdf/content/parser')
46
46
  autoload(:Processor, 'hexapdf/content/processor')
47
+ autoload(:ColorSpace, 'hexapdf/content/color_space')
48
+ autoload(:Operator, 'hexapdf/content/operator')
47
49
 
48
50
  end
49
51
 
@@ -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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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
@@ -1607,13 +1607,13 @@ module HexaPDF
1607
1607
  # See: PDF1.7 s9.2.2
1608
1608
  def font(name = nil, size: nil, **options)
1609
1609
  if name
1610
- @font = (name.respond_to?(:dict) ? name : context.document.fonts.add(name, **options))
1610
+ @font = (name.respond_to?(:pdf_object) ? name : context.document.fonts.add(name, **options))
1611
1611
  if size
1612
1612
  font_size(size)
1613
1613
  else
1614
1614
  size = font_size
1615
1615
  raise HexaPDF::Error, "No valid font size set" if size <= 0
1616
- invoke_font_operator(@font.dict, size)
1616
+ invoke_font_operator(@font.pdf_object, size)
1617
1617
  end
1618
1618
  self
1619
1619
  else
@@ -1644,7 +1644,7 @@ module HexaPDF
1644
1644
  unless @font
1645
1645
  raise HexaPDF::Error, "A font needs to be set before the font size can be set"
1646
1646
  end
1647
- invoke_font_operator(@font.dict, size)
1647
+ invoke_font_operator(@font.pdf_object, size)
1648
1648
  self
1649
1649
  else
1650
1650
  graphics_state.font_size
@@ -1855,7 +1855,7 @@ module HexaPDF
1855
1855
  elsif spec.length == 1 && spec[0].respond_to?(:color_space)
1856
1856
  spec[0]
1857
1857
  else
1858
- resources.color_space(color_space_for_components(spec)).color(*spec)
1858
+ resources.color_space(ColorSpace.for_components(spec)).color(*spec)
1859
1859
  end
1860
1860
  end
1861
1861
 
@@ -1993,19 +1993,6 @@ module HexaPDF
1993
1993
  end
1994
1994
  end
1995
1995
 
1996
- # Returns the name of the device color space that should be used for creating a color object
1997
- # from the components array.
1998
- def color_space_for_components(components)
1999
- case components.length
2000
- when 1 then :DeviceGray
2001
- when 3 then :DeviceRGB
2002
- when 4 then :DeviceCMYK
2003
- else
2004
- raise ArgumentError, "Invalid number of color components, 1|3|4 expected, " \
2005
- "#{components.length} given"
2006
- end
2007
- end
2008
-
2009
1996
  # Utility method that abstracts the implementation of a graphics state parameter
2010
1997
  # getter/setter method with a call sequence of:
2011
1998
  #
@@ -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-2019 Thomas Leitner
7
+ # Copyright (C) 2014-2020 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/error'
38
+ require 'hexapdf/configuration'
38
39
 
39
40
  module HexaPDF
40
41
  module Content
@@ -71,14 +72,18 @@ module HexaPDF
71
72
  # Returns the PDF name of the color space family this color space belongs to.
72
73
  #
73
74
  # #definition::
74
- # Returns the color space definition as array.
75
+ # Returns the color space definition as array or symbol.
75
76
  #
76
77
  # #default_color::
77
78
  # Returns the default color for this color space.
78
79
  #
79
80
  # #color(*args)::
80
- # Returns the color corresponding to the given arguments. The number and types of the
81
- # arguments differ from one color space to another.
81
+ # Returns the color corresponding to the given arguments which may be normalized to conform to
82
+ # the PDF spec. The number and types of the arguments differ from one color space to another.
83
+ #
84
+ # #prenormalized_color(*args)::
85
+ # Returns the color corresponding to the given arguments without applying value normalization.
86
+ # The number and types of the arguments differ from one color space to another.
82
87
  #
83
88
  # The class representing a color in the color space needs to respond to the following methods:
84
89
  #
@@ -91,6 +96,52 @@ module HexaPDF
91
96
  # See: PDF1.7 s8.6
92
97
  module ColorSpace
93
98
 
99
+ # :call-seq:
100
+ # ColorSpace.device_color_from_specification(gray) => color
101
+ # ColorSpace.device_color_from_specification(r, g, b) => color
102
+ # ColorSpace.device_color_from_specification(c, m, y, k) => color
103
+ # ColorSpace.device_color_from_specification(string) => color
104
+ # ColorSpace.device_color_from_specification(array) => color
105
+ #
106
+ # Creates a device color object from the given color specification.
107
+ #
108
+ # There are several ways to define the color that should be used:
109
+ #
110
+ # * A single numeric argument specifies a gray color (see DeviceGray::Color).
111
+ # * Three numeric arguments specify an RGB color (see DeviceRGB::Color).
112
+ # * A string in the format "RRGGBB" where "RR" is the hexadecimal number for the red, "GG"
113
+ # for the green and "BB" for the blue color value also specifies an RGB color.
114
+ # * Four numeric arguments specify a CMYK color (see DeviceCMYK::Color).
115
+ # * An array is treated as if its items were specified separately as arguments.
116
+ #
117
+ # Note that it makes a difference whether integer or float values are used because the given
118
+ # values are first normalized - see DeviceGray#color, DeviceRGB#color and DeviceCMYK#color.
119
+ def self.device_color_from_specification(*spec)
120
+ spec.flatten!
121
+ spec = spec[0].scan(/../).map!(&:hex) if spec.length == 1 && spec[0].kind_of?(String)
122
+ GlobalConfiguration.constantize('color_space.map', for_components(spec)).new.color(*spec)
123
+ end
124
+
125
+ # Returns a device color object for the given components array without applying value
126
+ # normalization.
127
+ def self.prenormalized_device_color(components)
128
+ GlobalConfiguration.constantize('color_space.map', for_components(components)).new.
129
+ prenormalized_color(*components)
130
+ end
131
+
132
+ # Returns the name of the device color space that should be used for creating a color object
133
+ # from the components array.
134
+ def self.for_components(components)
135
+ case components.length
136
+ when 1 then :DeviceGray
137
+ when 3 then :DeviceRGB
138
+ when 4 then :DeviceCMYK
139
+ else
140
+ raise ArgumentError, "Invalid number of color components, 1|3|4 expected, " \
141
+ "#{components.length} given"
142
+ end
143
+ end
144
+
94
145
  # This module includes utility functions that are useful for all color classes.
95
146
  module ColorUtils
96
147
 
@@ -103,9 +154,10 @@ module HexaPDF
103
154
  # * If the color value is less than 0.0, it is set to 0.0.
104
155
  def normalize_value(value, upper)
105
156
  value = value.to_f / upper if value.kind_of?(Integer)
106
- (value < 0 ? 0.0 : (value > 1 ? 1.0 : value))
157
+ value.clamp(0, 1)
107
158
  end
108
159
  private :normalize_value
160
+ module_function :normalize_value
109
161
 
110
162
  # Compares this color to another one by looking at their associated color spaces and their
111
163
  # components.
@@ -137,6 +189,7 @@ module HexaPDF
137
189
  def color(*args)
138
190
  Color.new(self, *args)
139
191
  end
192
+ alias prenormalized_color color
140
193
 
141
194
  # Returns the PDF color space family this color space belongs to.
142
195
  def family
@@ -189,8 +242,22 @@ module HexaPDF
189
242
  Color.new(0.0, 0.0, 0.0)
190
243
  end
191
244
 
192
- # Returns the color object for the given red, green and blue components.
245
+ # Returns the color object for the red, green and blue components.
246
+ #
247
+ # Color values can either be integers in the range from 0 to 255 or floating point numbers
248
+ # between 0.0 and 1.0. The integer color values are automatically normalized to the
249
+ # DeviceRGB color value range of 0.0 to 1.0.
193
250
  def color(r, g, b)
251
+ Color.new(ColorUtils.normalize_value(r, 255),
252
+ ColorUtils.normalize_value(g, 255),
253
+ ColorUtils.normalize_value(b, 255))
254
+ end
255
+
256
+ # Returns the color object for the red, green and blue components without applying value
257
+ # normalization.
258
+ #
259
+ # See: #color
260
+ def prenormalized_color(r, g, b)
194
261
  Color.new(r, g, b)
195
262
  end
196
263
 
@@ -198,13 +265,10 @@ module HexaPDF
198
265
  def family
199
266
  :DeviceRGB
200
267
  end
268
+ alias definition family
201
269
 
202
270
  # A color in the DeviceRGB color space.
203
271
  #
204
- # Color values can either be integers in the range from 0 to 255 or floating point numbers
205
- # between 0.0 and 1.0. The integer color values are automatically normalized to the
206
- # DeviceRGB color value range of 0.0 to 1.0.
207
- #
208
272
  # See: PDF1.7 s8.6.4.3
209
273
  class Color
210
274
 
@@ -212,12 +276,11 @@ module HexaPDF
212
276
 
213
277
  # Initializes the color with the +r+ (red), +g+ (green) and +b+ (blue) components.
214
278
  #
215
- # Each argument has to be either an integer between 0 and 255 or a float between 0.0 and
216
- # 1.0.
279
+ # Each argument has to be a float between 0.0 and 1.0.
217
280
  def initialize(r, g, b)
218
- @r = normalize_value(r, 255)
219
- @g = normalize_value(g, 255)
220
- @b = normalize_value(b, 255)
281
+ @r = r
282
+ @g = g
283
+ @b = b
221
284
  end
222
285
 
223
286
  # Returns the DeviceRGB color space module.
@@ -251,7 +314,20 @@ module HexaPDF
251
314
  end
252
315
 
253
316
  # Returns the color object for the given cyan, magenta, yellow and black components.
317
+ #
318
+ # Color values can either be integers in the range from 0 to 100 or floating point numbers
319
+ # between 0.0 and 1.0. The integer color values are automatically normalized to the
320
+ # DeviceCMYK color value range of 0.0 to 1.0.
254
321
  def color(c, m, y, k)
322
+ Color.new(ColorUtils.normalize_value(c, 100), ColorUtils.normalize_value(m, 100),
323
+ ColorUtils.normalize_value(y, 100), ColorUtils.normalize_value(k, 100))
324
+ end
325
+
326
+ # Returns the color object for the cyan, magenta, yellow and black components without
327
+ # applying value normalization.
328
+ #
329
+ # See: #color
330
+ def prenormalized_color(c, m, y, k)
255
331
  Color.new(c, m, y, k)
256
332
  end
257
333
 
@@ -259,13 +335,10 @@ module HexaPDF
259
335
  def family
260
336
  :DeviceCMYK
261
337
  end
338
+ alias definition family
262
339
 
263
340
  # A color in the DeviceCMYK color space.
264
341
  #
265
- # Color values can either be integers in the range from 0 to 100 or floating point numbers
266
- # between 0.0 and 1.0. The integer color values are automatically normalized to the
267
- # DeviceCMYK color value range of 0.0 to 1.0.
268
- #
269
342
  # See: PDF1.7 s8.6.4.4
270
343
  class Color
271
344
 
@@ -274,13 +347,12 @@ module HexaPDF
274
347
  # Initializes the color with the +c+ (cyan), +m+ (magenta), +y+ (yellow) and +k+ (black)
275
348
  # components.
276
349
  #
277
- # Each argument has to be either an integer between 0 and 100 or a float between 0.0 and
278
- # 1.0.
350
+ # Each argument has to be a float between 0.0 and 1.0.
279
351
  def initialize(c, m, y, k)
280
- @c = normalize_value(c, 100)
281
- @m = normalize_value(m, 100)
282
- @y = normalize_value(y, 100)
283
- @k = normalize_value(k, 100)
352
+ @c = c
353
+ @m = m
354
+ @y = y
355
+ @k = k
284
356
  end
285
357
 
286
358
  # Returns the DeviceCMYK color space module.
@@ -314,7 +386,18 @@ module HexaPDF
314
386
  end
315
387
 
316
388
  # Returns the color object for the given gray component.
389
+ #
390
+ # Color values can either be integers in the range from 0 to 255 or floating point numbers
391
+ # between 0.0 and 1.0. The integer color values are automatically normalized to the
392
+ # DeviceGray color value range of 0.0 to 1.0.
317
393
  def color(gray)
394
+ Color.new(ColorUtils.normalize_value(gray, 255))
395
+ end
396
+
397
+ # Returns the color object for the gray component without applying value normalization.
398
+ #
399
+ # See: #color
400
+ def prenormalized_color(gray)
318
401
  Color.new(gray)
319
402
  end
320
403
 
@@ -322,13 +405,10 @@ module HexaPDF
322
405
  def family
323
406
  :DeviceGray
324
407
  end
408
+ alias definition family
325
409
 
326
410
  # A color in the DeviceGray color space.
327
411
  #
328
- # Color values can either be integers in the range from 0 to 255 or floating point numbers
329
- # between 0.0 and 1.0. The integer color values are automatically normalized to the
330
- # DeviceGray color value range of 0.0 to 1.0.
331
- #
332
412
  # See: PDF1.7 s8.6.4.2
333
413
  class Color
334
414
 
@@ -336,10 +416,9 @@ module HexaPDF
336
416
 
337
417
  # Initializes the color with the +gray+ component.
338
418
  #
339
- # The argument +gray+ has to be either an integer between 0 and 255 or a float between
340
- # 0.0 and 1.0.
419
+ # The argument +gray+ has to be a float between 0.0 and 1.0.
341
420
  def initialize(gray)
342
- @gray = normalize_value(gray, 255)
421
+ @gray = gray
343
422
  end
344
423
 
345
424
  # Returns the DeviceGray color space module.