pdfrb 0.2.1 → 0.6.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 (406) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +24 -0
  4. data/Gemfile +1 -0
  5. data/PROPOSAL.canvas-clip.md +92 -0
  6. data/PROPOSAL.canvas-draw-image-matrix.md +87 -0
  7. data/PROPOSAL.canvas-rich-text.md +103 -0
  8. data/PROPOSAL.canvas-text-lines.md +77 -0
  9. data/PROPOSAL.canvas-transparency.md +106 -0
  10. data/PROPOSAL.external-font-metrics.md +129 -0
  11. data/PROPOSAL.font-embedding-fontfile2.md +88 -0
  12. data/PROPOSAL.font-resolver-ttc.md +105 -0
  13. data/PROPOSAL.font-resolver.md +96 -0
  14. data/PROPOSAL.font-subsetting.md +98 -0
  15. data/PROPOSAL.gradient-shadings.md +110 -0
  16. data/PROPOSAL.page-mediabox-setter.md +66 -0
  17. data/PROPOSAL.per-glyph-width.md +91 -0
  18. data/PROPOSAL.stringio-require.md +53 -0
  19. data/PROPOSAL.struct-tree-root.md +102 -0
  20. data/PROPOSAL.text-measurement.md +93 -0
  21. data/PROPOSAL.ttf-table-parsing-fix.md +112 -0
  22. data/RELEASE.md +48 -0
  23. data/lib/pdfrb/action/base.rb +21 -0
  24. data/lib/pdfrb/action/types.rb +178 -0
  25. data/lib/pdfrb/action.rb +55 -0
  26. data/lib/pdfrb/annotation/base.rb +79 -0
  27. data/lib/pdfrb/annotation/types.rb +222 -0
  28. data/lib/pdfrb/annotation.rb +78 -0
  29. data/lib/pdfrb/appearance/generator.rb +216 -0
  30. data/lib/pdfrb/appearance.rb +11 -0
  31. data/lib/pdfrb/arlington/object_definition.rb +2 -2
  32. data/lib/pdfrb/arlington/predicate/evaluator.rb +1 -1
  33. data/lib/pdfrb/arlington/predicate/functions.rb +25 -9
  34. data/lib/pdfrb/arlington/predicate.rb +1 -5
  35. data/lib/pdfrb/cli/batch.rb +18 -0
  36. data/lib/pdfrb/cli/debug_info.rb +18 -0
  37. data/lib/pdfrb/cli/files.rb +16 -0
  38. data/lib/pdfrb/cli/fonts.rb +16 -0
  39. data/lib/pdfrb/cli/form.rb +18 -0
  40. data/lib/pdfrb/cli/image2pdf.rb +18 -0
  41. data/lib/pdfrb/cli/images.rb +34 -0
  42. data/lib/pdfrb/cli/info.rb +20 -0
  43. data/lib/pdfrb/cli/inspect.rb +18 -0
  44. data/lib/pdfrb/cli/merge.rb +18 -0
  45. data/lib/pdfrb/cli/modify.rb +18 -0
  46. data/lib/pdfrb/cli/optimize.rb +18 -0
  47. data/lib/pdfrb/cli/split.rb +21 -0
  48. data/lib/pdfrb/cli/watermark.rb +18 -0
  49. data/lib/pdfrb/cli.rb +312 -7
  50. data/lib/pdfrb/color/color_space.rb +259 -0
  51. data/lib/pdfrb/color/icc_profile.rb +90 -0
  52. data/lib/pdfrb/color.rb +12 -0
  53. data/lib/pdfrb/compare/comparator.rb +244 -0
  54. data/lib/pdfrb/compare/report.rb +78 -0
  55. data/lib/pdfrb/compare.rb +42 -0
  56. data/lib/pdfrb/composer.rb +161 -0
  57. data/lib/pdfrb/conformance/pdf_a.rb +317 -56
  58. data/lib/pdfrb/conformance/pdf_ua.rb +186 -29
  59. data/lib/pdfrb/conformance/pdf_x.rb +247 -0
  60. data/lib/pdfrb/conformance/rule.rb +78 -0
  61. data/lib/pdfrb/conformance/structure_elements.rb +174 -0
  62. data/lib/pdfrb/conformance/verapdf_bridge.rb +92 -0
  63. data/lib/pdfrb/conformance.rb +7 -3
  64. data/lib/pdfrb/content/canvas.rb +217 -72
  65. data/lib/pdfrb/content/color_space.rb +157 -0
  66. data/lib/pdfrb/content/hidden_text_detector.rb +167 -0
  67. data/lib/pdfrb/content/operator.rb +21 -1
  68. data/lib/pdfrb/content/operators/clipping.rb +36 -0
  69. data/lib/pdfrb/content/operators/graphics_state_params.rb +15 -0
  70. data/lib/pdfrb/content/operators.rb +21 -0
  71. data/lib/pdfrb/content/shading/base.rb +139 -0
  72. data/lib/pdfrb/content/shading.rb +17 -0
  73. data/lib/pdfrb/content/smart_text_extractor.rb +85 -0
  74. data/lib/pdfrb/content/tiling_pattern.rb +78 -0
  75. data/lib/pdfrb/content/transformation_matrix.rb +61 -0
  76. data/lib/pdfrb/content.rb +7 -26
  77. data/lib/pdfrb/destination/fit.rb +185 -0
  78. data/lib/pdfrb/destination.rb +13 -0
  79. data/lib/pdfrb/digital_signature/cms_handler.rb +22 -0
  80. data/lib/pdfrb/digital_signature/signing.rb +107 -11
  81. data/lib/pdfrb/digital_signature/timestamp_handler.rb +45 -0
  82. data/lib/pdfrb/digital_signature/verification.rb +88 -9
  83. data/lib/pdfrb/digital_signature/verification_result.rb +14 -0
  84. data/lib/pdfrb/digital_signature.rb +26 -2
  85. data/lib/pdfrb/document/annotations.rb +120 -3
  86. data/lib/pdfrb/document/associated_files.rb +104 -0
  87. data/lib/pdfrb/document/colors.rb +95 -0
  88. data/lib/pdfrb/document/destinations.rb +127 -5
  89. data/lib/pdfrb/document/display.rb +84 -0
  90. data/lib/pdfrb/document/fonts.rb +417 -45
  91. data/lib/pdfrb/document/form.rb +338 -0
  92. data/lib/pdfrb/document/form_xobject.rb +68 -0
  93. data/lib/pdfrb/document/graphics_state.rb +91 -0
  94. data/lib/pdfrb/document/images.rb +4 -4
  95. data/lib/pdfrb/document/info.rb +102 -0
  96. data/lib/pdfrb/document/layers.rb +62 -0
  97. data/lib/pdfrb/document/metadata.rb +12 -5
  98. data/lib/pdfrb/document/output_intents.rb +91 -0
  99. data/lib/pdfrb/document/page_labels.rb +80 -0
  100. data/lib/pdfrb/document/pages.rb +68 -19
  101. data/lib/pdfrb/document/portfolio.rb +119 -0
  102. data/lib/pdfrb/document/shadings.rb +159 -0
  103. data/lib/pdfrb/document/stamps.rb +68 -0
  104. data/lib/pdfrb/document/structure.rb +242 -0
  105. data/lib/pdfrb/document.rb +73 -4
  106. data/lib/pdfrb/encryption/identity.rb +13 -0
  107. data/lib/pdfrb/encryption/password_verification.rb +53 -8
  108. data/lib/pdfrb/encryption/security_handler.rb +8 -5
  109. data/lib/pdfrb/encryption/standard_security_handler.rb +154 -81
  110. data/lib/pdfrb/encryption.rb +17 -0
  111. data/lib/pdfrb/error.rb +2 -2
  112. data/lib/pdfrb/filter/brotli_decode.rb +32 -0
  113. data/lib/pdfrb/filter/ccitt_fax_decode.rb +12 -0
  114. data/lib/pdfrb/filter/crypt.rb +2 -2
  115. data/lib/pdfrb/filter/dct_decode.rb +18 -0
  116. data/lib/pdfrb/filter/flate_decode.rb +4 -18
  117. data/lib/pdfrb/filter/jbig2_decode.rb +12 -0
  118. data/lib/pdfrb/filter/jpx_decode.rb +18 -0
  119. data/lib/pdfrb/filter/lzw_decode.rb +3 -2
  120. data/lib/pdfrb/filter/png_predictor.rb +94 -0
  121. data/lib/pdfrb/filter.rb +26 -13
  122. data/lib/pdfrb/font/afm_parser.rb +50 -26
  123. data/lib/pdfrb/font/cmap/writer.rb +9 -0
  124. data/lib/pdfrb/font/encoding/win_ansi_encoding.rb +17 -0
  125. data/lib/pdfrb/font/encoding.rb +32 -3
  126. data/lib/pdfrb/font/metrics_helper.rb +121 -0
  127. data/lib/pdfrb/font/true_type/file.rb +10 -1
  128. data/lib/pdfrb/font/true_type/glyf.rb +82 -0
  129. data/lib/pdfrb/font/true_type/kern.rb +58 -0
  130. data/lib/pdfrb/font/true_type/loca.rb +42 -0
  131. data/lib/pdfrb/font/true_type/maxp.rb +44 -0
  132. data/lib/pdfrb/font/true_type/name.rb +53 -0
  133. data/lib/pdfrb/font/true_type/post.rb +93 -0
  134. data/lib/pdfrb/font/true_type/subsetter.rb +3 -5
  135. data/lib/pdfrb/font/true_type/wrapper.rb +102 -0
  136. data/lib/pdfrb/font/true_type.rb +7 -0
  137. data/lib/pdfrb/font.rb +2 -0
  138. data/lib/pdfrb/font_loader/from_configuration.rb +19 -0
  139. data/lib/pdfrb/font_loader/from_file.rb +20 -0
  140. data/lib/pdfrb/font_loader/standard14.rb +20 -0
  141. data/lib/pdfrb/font_loader/variant_from_name.rb +36 -0
  142. data/lib/pdfrb/font_loader.rb +4 -0
  143. data/lib/pdfrb/font_resolver.rb +138 -0
  144. data/lib/pdfrb/image/audit.rb +94 -0
  145. data/lib/pdfrb/image/downsampler.rb +124 -0
  146. data/lib/pdfrb/image.rb +13 -0
  147. data/lib/pdfrb/image_loader/jpeg.rb +39 -58
  148. data/lib/pdfrb/image_loader/png.rb +31 -257
  149. data/lib/pdfrb/layout/bidi.rb +198 -0
  150. data/lib/pdfrb/layout/box.rb +49 -0
  151. data/lib/pdfrb/layout/box_fitter.rb +54 -0
  152. data/lib/pdfrb/layout/column_box.rb +71 -0
  153. data/lib/pdfrb/layout/container_box.rb +45 -0
  154. data/lib/pdfrb/layout/frame.rb +67 -0
  155. data/lib/pdfrb/layout/image_box.rb +44 -0
  156. data/lib/pdfrb/layout/inline_box.rb +25 -0
  157. data/lib/pdfrb/layout/line.rb +55 -0
  158. data/lib/pdfrb/layout/list_box.rb +87 -0
  159. data/lib/pdfrb/layout/numeric_refinements.rb +43 -0
  160. data/lib/pdfrb/layout/page_style.rb +65 -0
  161. data/lib/pdfrb/layout/style.rb +62 -0
  162. data/lib/pdfrb/layout/table_box.rb +66 -0
  163. data/lib/pdfrb/layout/text_box.rb +38 -0
  164. data/lib/pdfrb/layout/text_fragment.rb +45 -0
  165. data/lib/pdfrb/layout/text_layouter.rb +123 -0
  166. data/lib/pdfrb/layout.rb +28 -0
  167. data/lib/pdfrb/linearization/hint_stream.rb +93 -0
  168. data/lib/pdfrb/linearization/writer.rb +259 -0
  169. data/lib/pdfrb/linearization.rb +21 -0
  170. data/lib/pdfrb/model/cos/dictionary.rb +12 -0
  171. data/lib/pdfrb/model/pdf_array.rb +2 -2
  172. data/lib/pdfrb/model/type/action.rb +42 -0
  173. data/lib/pdfrb/model/type/action_go_to_3d_view.rb +14 -0
  174. data/lib/pdfrb/model/type/action_go_to_dp.rb +16 -0
  175. data/lib/pdfrb/model/type/action_go_to_r.rb +26 -0
  176. data/lib/pdfrb/model/type/action_goto.rb +34 -0
  177. data/lib/pdfrb/model/type/action_hide.rb +26 -0
  178. data/lib/pdfrb/model/type/action_import_data.rb +18 -0
  179. data/lib/pdfrb/model/type/action_java_script.rb +18 -0
  180. data/lib/pdfrb/model/type/action_launch.rb +22 -0
  181. data/lib/pdfrb/model/type/action_movie.rb +22 -0
  182. data/lib/pdfrb/model/type/action_named.rb +23 -0
  183. data/lib/pdfrb/model/type/action_nop.rb +12 -0
  184. data/lib/pdfrb/model/type/action_rendition.rb +28 -0
  185. data/lib/pdfrb/model/type/action_reset_form.rb +22 -0
  186. data/lib/pdfrb/model/type/action_rich_media_execute.rb +17 -0
  187. data/lib/pdfrb/model/type/action_set_ocg_state.rb +32 -0
  188. data/lib/pdfrb/model/type/action_set_state.rb +14 -0
  189. data/lib/pdfrb/model/type/action_sound_action.rb +23 -0
  190. data/lib/pdfrb/model/type/action_submit_form.rb +64 -0
  191. data/lib/pdfrb/model/type/action_thread.rb +23 -0
  192. data/lib/pdfrb/model/type/action_trans.rb +30 -0
  193. data/lib/pdfrb/model/type/action_uri.rb +30 -0
  194. data/lib/pdfrb/model/type/af_embedded_file.rb +11 -0
  195. data/lib/pdfrb/model/type/af_file_specification.rb +34 -0
  196. data/lib/pdfrb/model/type/annotation.rb +49 -10
  197. data/lib/pdfrb/model/type/appearance.rb +41 -0
  198. data/lib/pdfrb/model/type/appearance_characteristics.rb +36 -0
  199. data/lib/pdfrb/model/type/appearance_generator.rb +22 -0
  200. data/lib/pdfrb/model/type/appearance_trap_net.rb +84 -0
  201. data/lib/pdfrb/model/type/border_effect.rb +25 -0
  202. data/lib/pdfrb/model/type/border_styling.rb +38 -0
  203. data/lib/pdfrb/model/type/box_color_info.rb +21 -0
  204. data/lib/pdfrb/model/type/box_style.rb +19 -0
  205. data/lib/pdfrb/model/type/button.rb +17 -0
  206. data/lib/pdfrb/model/type/cal_gray.rb +17 -0
  207. data/lib/pdfrb/model/type/cal_rgb.rb +22 -0
  208. data/lib/pdfrb/model/type/caret_annotation.rb +21 -0
  209. data/lib/pdfrb/model/type/catalog.rb +99 -16
  210. data/lib/pdfrb/model/type/choice.rb +21 -0
  211. data/lib/pdfrb/model/type/cid_font.rb +52 -1
  212. data/lib/pdfrb/model/type/cid_font_descriptor_metrics.rb +28 -0
  213. data/lib/pdfrb/model/type/cid_system_info.rb +28 -0
  214. data/lib/pdfrb/model/type/circle_annotation.rb +20 -0
  215. data/lib/pdfrb/model/type/collection.rb +27 -0
  216. data/lib/pdfrb/model/type/collection_field.rb +24 -0
  217. data/lib/pdfrb/model/type/collection_item.rb +19 -0
  218. data/lib/pdfrb/model/type/collection_schema.rb +25 -0
  219. data/lib/pdfrb/model/type/collection_sort.rb +13 -0
  220. data/lib/pdfrb/model/type/crypt_filter.rb +58 -0
  221. data/lib/pdfrb/model/type/device_n.rb +37 -0
  222. data/lib/pdfrb/model/type/device_n_mixing_hints.rb +17 -0
  223. data/lib/pdfrb/model/type/device_n_process.rb +13 -0
  224. data/lib/pdfrb/model/type/doc_mdp_transform_parameters.rb +21 -0
  225. data/lib/pdfrb/model/type/document_security_store.rb +55 -0
  226. data/lib/pdfrb/model/type/embedded_file.rb +19 -0
  227. data/lib/pdfrb/model/type/embedded_file_parameter.rb +48 -0
  228. data/lib/pdfrb/model/type/encryption_public_key.rb +38 -0
  229. data/lib/pdfrb/model/type/encryption_standard.rb +68 -0
  230. data/lib/pdfrb/model/type/field_mdp_transform_parameters.rb +26 -0
  231. data/lib/pdfrb/model/type/file_attachment_annotation.rb +29 -0
  232. data/lib/pdfrb/model/type/file_spec_ef.rb +22 -0
  233. data/lib/pdfrb/model/type/file_spec_rf.rb +21 -0
  234. data/lib/pdfrb/model/type/file_specification.rb +43 -0
  235. data/lib/pdfrb/model/type/file_trailer.rb +54 -0
  236. data/lib/pdfrb/model/type/font.rb +73 -2
  237. data/lib/pdfrb/model/type/font_cid_type0.rb +17 -0
  238. data/lib/pdfrb/model/type/font_cid_type2.rb +17 -0
  239. data/lib/pdfrb/model/type/font_descriptor.rb +47 -0
  240. data/lib/pdfrb/model/type/font_descriptor_cid_type0.rb +15 -0
  241. data/lib/pdfrb/model/type/font_descriptor_cid_type2.rb +15 -0
  242. data/lib/pdfrb/model/type/font_encoding.rb +47 -0
  243. data/lib/pdfrb/model/type/font_file.rb +28 -0
  244. data/lib/pdfrb/model/type/font_file2.rb +32 -0
  245. data/lib/pdfrb/model/type/font_file3.rb +23 -0
  246. data/lib/pdfrb/model/type/font_multiple_master.rb +60 -0
  247. data/lib/pdfrb/model/type/font_true_type.rb +1 -1
  248. data/lib/pdfrb/model/type/font_type0.rb +1 -1
  249. data/lib/pdfrb/model/type/font_type1.rb +1 -1
  250. data/lib/pdfrb/model/type/font_type3.rb +1 -1
  251. data/lib/pdfrb/model/type/form_field.rb +73 -0
  252. data/lib/pdfrb/model/type/free_text_annotation.rb +37 -0
  253. data/lib/pdfrb/model/type/function.rb +42 -0
  254. data/lib/pdfrb/model/type/function_exponential.rb +31 -0
  255. data/lib/pdfrb/model/type/function_postscript.rb +25 -0
  256. data/lib/pdfrb/model/type/function_sampled.rb +55 -0
  257. data/lib/pdfrb/model/type/function_stitching.rb +33 -0
  258. data/lib/pdfrb/model/type/generic_appearance.rb +40 -0
  259. data/lib/pdfrb/model/type/graphics_state_parameter.rb +69 -0
  260. data/lib/pdfrb/model/type/halftone.rb +21 -0
  261. data/lib/pdfrb/model/type/halftone_type1.rb +17 -0
  262. data/lib/pdfrb/model/type/halftone_type10.rb +16 -0
  263. data/lib/pdfrb/model/type/halftone_type16.rb +11 -0
  264. data/lib/pdfrb/model/type/halftone_type5.rb +24 -0
  265. data/lib/pdfrb/model/type/halftone_type6.rb +16 -0
  266. data/lib/pdfrb/model/type/highlight_annotation.rb +11 -0
  267. data/lib/pdfrb/model/type/icc_based_color_space.rb +24 -0
  268. data/lib/pdfrb/model/type/icon_fit.rb +31 -0
  269. data/lib/pdfrb/model/type/indexed.rb +32 -0
  270. data/lib/pdfrb/model/type/info.rb +44 -0
  271. data/lib/pdfrb/model/type/ink_annotation.rb +29 -0
  272. data/lib/pdfrb/model/type/interactive_form.rb +36 -0
  273. data/lib/pdfrb/model/type/interior_color.rb +12 -0
  274. data/lib/pdfrb/model/type/jbig2_globals.rb +15 -0
  275. data/lib/pdfrb/model/type/lab.rb +27 -0
  276. data/lib/pdfrb/model/type/line_annotation.rb +44 -0
  277. data/lib/pdfrb/model/type/line_ending_styling.rb +39 -0
  278. data/lib/pdfrb/model/type/link_annotation.rb +41 -0
  279. data/lib/pdfrb/model/type/link_appearance.rb +9 -0
  280. data/lib/pdfrb/model/type/mark_information.rb +23 -0
  281. data/lib/pdfrb/model/type/marked_content_reference.rb +24 -0
  282. data/lib/pdfrb/model/type/markup_annotation.rb +36 -0
  283. data/lib/pdfrb/model/type/mdp_dict.rb +28 -0
  284. data/lib/pdfrb/model/type/measure.rb +39 -0
  285. data/lib/pdfrb/model/type/media_clip.rb +28 -0
  286. data/lib/pdfrb/model/type/media_offset.rb +106 -0
  287. data/lib/pdfrb/model/type/metadata.rb +27 -3
  288. data/lib/pdfrb/model/type/misc_helpers.rb +75 -0
  289. data/lib/pdfrb/model/type/movie.rb +28 -0
  290. data/lib/pdfrb/model/type/names.rb +51 -0
  291. data/lib/pdfrb/model/type/namespace.rb +27 -0
  292. data/lib/pdfrb/model/type/object_reference.rb +31 -0
  293. data/lib/pdfrb/model/type/object_stream.rb +38 -0
  294. data/lib/pdfrb/model/type/opt_content_ext.rb +94 -0
  295. data/lib/pdfrb/model/type/opt_content_page_element.rb +18 -0
  296. data/lib/pdfrb/model/type/optional_content_config.rb +56 -0
  297. data/lib/pdfrb/model/type/optional_content_group.rb +35 -10
  298. data/lib/pdfrb/model/type/optional_content_membership.rb +36 -2
  299. data/lib/pdfrb/model/type/optional_content_properties.rb +16 -1
  300. data/lib/pdfrb/model/type/outline.rb +40 -6
  301. data/lib/pdfrb/model/type/outline_item.rb +45 -0
  302. data/lib/pdfrb/model/type/output_intent.rb +30 -0
  303. data/lib/pdfrb/model/type/page.rb +127 -0
  304. data/lib/pdfrb/model/type/page_label.rb +68 -0
  305. data/lib/pdfrb/model/type/page_tree_node.rb +51 -16
  306. data/lib/pdfrb/model/type/page_tree_node_root.rb +15 -0
  307. data/lib/pdfrb/model/type/pattern.rb +16 -0
  308. data/lib/pdfrb/model/type/pattern_shading.rb +25 -0
  309. data/lib/pdfrb/model/type/pattern_tiling.rb +25 -0
  310. data/lib/pdfrb/model/type/polygon_annotation.rb +29 -0
  311. data/lib/pdfrb/model/type/polygon_polyline.rb +14 -0
  312. data/lib/pdfrb/model/type/polyline_annotation.rb +29 -0
  313. data/lib/pdfrb/model/type/popup_annotation.rb +20 -0
  314. data/lib/pdfrb/model/type/printer_mark_annotation.rb +13 -0
  315. data/lib/pdfrb/model/type/redact_annotation.rb +28 -0
  316. data/lib/pdfrb/model/type/rendition.rb +31 -0
  317. data/lib/pdfrb/model/type/resources.rb +59 -14
  318. data/lib/pdfrb/model/type/rich_media_activation.rb +24 -0
  319. data/lib/pdfrb/model/type/rich_media_animation.rb +25 -0
  320. data/lib/pdfrb/model/type/rich_media_annotation.rb +18 -0
  321. data/lib/pdfrb/model/type/rich_media_command.rb +19 -0
  322. data/lib/pdfrb/model/type/rich_media_configuration.rb +32 -0
  323. data/lib/pdfrb/model/type/rich_media_content.rb +28 -0
  324. data/lib/pdfrb/model/type/rich_media_cue_point.rb +18 -0
  325. data/lib/pdfrb/model/type/rich_media_deactivation.rb +17 -0
  326. data/lib/pdfrb/model/type/rich_media_instance.rb +33 -0
  327. data/lib/pdfrb/model/type/rich_media_presentation.rb +29 -0
  328. data/lib/pdfrb/model/type/rich_media_settings.rb +33 -0
  329. data/lib/pdfrb/model/type/rich_media_window.rb +20 -0
  330. data/lib/pdfrb/model/type/screen_annotation.rb +19 -0
  331. data/lib/pdfrb/model/type/separation.rb +25 -0
  332. data/lib/pdfrb/model/type/sig_field_lock.rb +25 -0
  333. data/lib/pdfrb/model/type/sig_field_seed_value.rb +25 -0
  334. data/lib/pdfrb/model/type/signature.rb +65 -0
  335. data/lib/pdfrb/model/type/signature_build.rb +86 -0
  336. data/lib/pdfrb/model/type/signature_field.rb +17 -0
  337. data/lib/pdfrb/model/type/software_identifier.rb +19 -0
  338. data/lib/pdfrb/model/type/sound.rb +38 -0
  339. data/lib/pdfrb/model/type/sound_annotation.rb +21 -0
  340. data/lib/pdfrb/model/type/square_annotation.rb +24 -0
  341. data/lib/pdfrb/model/type/square_circle.rb +13 -0
  342. data/lib/pdfrb/model/type/squiggly_annotation.rb +11 -0
  343. data/lib/pdfrb/model/type/stamp_annotation.rb +19 -0
  344. data/lib/pdfrb/model/type/strikeout_annotation.rb +11 -0
  345. data/lib/pdfrb/model/type/struct_elem.rb +75 -0
  346. data/lib/pdfrb/model/type/struct_tree_root.rb +34 -0
  347. data/lib/pdfrb/model/type/structure_attributes.rb +44 -0
  348. data/lib/pdfrb/model/type/structure_element_kid.rb +33 -0
  349. data/lib/pdfrb/model/type/text_annotation.rb +25 -0
  350. data/lib/pdfrb/model/type/text_appearance.rb +9 -0
  351. data/lib/pdfrb/model/type/text_field.rb +21 -0
  352. data/lib/pdfrb/model/type/text_markup_annotation.rb +30 -0
  353. data/lib/pdfrb/model/type/three_d_activation.rb +32 -0
  354. data/lib/pdfrb/model/type/three_d_animation_style.rb +24 -0
  355. data/lib/pdfrb/model/type/three_d_background.rb +28 -0
  356. data/lib/pdfrb/model/type/three_d_cross_section.rb +25 -0
  357. data/lib/pdfrb/model/type/three_d_lighting_scheme.rb +26 -0
  358. data/lib/pdfrb/model/type/three_d_measure.rb +20 -0
  359. data/lib/pdfrb/model/type/three_d_measure_3dc.rb +23 -0
  360. data/lib/pdfrb/model/type/three_d_measure_ad3.rb +14 -0
  361. data/lib/pdfrb/model/type/three_d_measure_ld3.rb +14 -0
  362. data/lib/pdfrb/model/type/three_d_measure_pd3.rb +20 -0
  363. data/lib/pdfrb/model/type/three_d_measure_rd3.rb +14 -0
  364. data/lib/pdfrb/model/type/three_d_node.rb +37 -0
  365. data/lib/pdfrb/model/type/three_d_reference.rb +21 -0
  366. data/lib/pdfrb/model/type/three_d_render_mode.rb +34 -0
  367. data/lib/pdfrb/model/type/three_d_stream.rb +48 -0
  368. data/lib/pdfrb/model/type/three_d_units.rb +18 -0
  369. data/lib/pdfrb/model/type/three_d_view.rb +40 -0
  370. data/lib/pdfrb/model/type/to_unicode_cmap_stream.rb +23 -0
  371. data/lib/pdfrb/model/type/transition.rb +68 -0
  372. data/lib/pdfrb/model/type/underline_annotation.rb +11 -0
  373. data/lib/pdfrb/model/type/ur_transform_parameters.rb +33 -0
  374. data/lib/pdfrb/model/type/uri_dict.rb +18 -0
  375. data/lib/pdfrb/model/type/url_alias.rb +19 -0
  376. data/lib/pdfrb/model/type/variable_text_field.rb +47 -0
  377. data/lib/pdfrb/model/type/viewer_preferences.rb +42 -0
  378. data/lib/pdfrb/model/type/watermark_annotation.rb +13 -0
  379. data/lib/pdfrb/model/type/widget_annotation.rb +48 -0
  380. data/lib/pdfrb/model/type/widget_appearance.rb +9 -0
  381. data/lib/pdfrb/model/type/xobject_form.rb +41 -0
  382. data/lib/pdfrb/model/type/xobject_image.rb +56 -0
  383. data/lib/pdfrb/model/type/xref_stream.rb +37 -0
  384. data/lib/pdfrb/model/type.rb +286 -6
  385. data/lib/pdfrb/serializer.rb +2 -2
  386. data/lib/pdfrb/source/tokenizer.rb +0 -2
  387. data/lib/pdfrb/task/benchmark.rb +83 -0
  388. data/lib/pdfrb/task/extract_text.rb +1 -1
  389. data/lib/pdfrb/task/generate_corpus.rb +130 -0
  390. data/lib/pdfrb/task/memory_profile.rb +84 -0
  391. data/lib/pdfrb/task/optimize.rb +97 -7
  392. data/lib/pdfrb/task.rb +3 -3
  393. data/lib/pdfrb/test_utils.rb +112 -0
  394. data/lib/pdfrb/validator.rb +82 -0
  395. data/lib/pdfrb/version.rb +1 -1
  396. data/lib/pdfrb/writer.rb +117 -27
  397. data/lib/pdfrb/xmp/packet.rb +122 -0
  398. data/lib/pdfrb/xmp/schemas.rb +96 -0
  399. data/lib/pdfrb/xmp.rb +44 -0
  400. data/lib/pdfrb/xref_section.rb +2 -2
  401. data/lib/pdfrb.rb +25 -53
  402. data/pdfrb.gemspec +45 -0
  403. data/script/apply_fixes.sh +843 -0
  404. data/script/make_jpeg_fixture.rb +53 -0
  405. data/script/make_png_fixture.rb +25 -0
  406. metadata +312 -2
@@ -0,0 +1,259 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+ require "zlib"
5
+
6
+ module Pdfrb
7
+ module Linearization
8
+ # Writes a PDF in linearized format (ISO 32000-2 §7.6.2, Annex F).
9
+ #
10
+ # Approach: serialize all objects to a temp buffer, compute final
11
+ # offsets, then assemble the file with the linearization parameter
12
+ # dict as the first indirect object. The lin dict values (/L, /H,
13
+ # /O, /E, /N, /T) are filled from the computed layout.
14
+ #
15
+ # This produces a structurally valid linearized PDF with page-offset
16
+ # hints. Full optimization (shared-object tables, minimal-download
17
+ # ordering) is future work.
18
+ class Writer
19
+ # Internal value object carrying computed offsets through assembly.
20
+ Layout = Struct.new(
21
+ :lin_dict_offset, :lin_dict_size,
22
+ :hint_offset, :hint_length,
23
+ :first_page_oid, :first_page_end,
24
+ :xref_offset, :total_size, :num_pages,
25
+ :ordered_objects, :hint_oid,
26
+ :hint_dict, :hint_compressed,
27
+ :xref_bytes, :trailer_bytes,
28
+ keyword_init: true
29
+ )
30
+
31
+ def initialize(document)
32
+ @document = document
33
+ @serializer = Pdfrb::Serializer.new
34
+ end
35
+
36
+ # @param io [IO] target output.
37
+ # @return [void]
38
+ def write(io)
39
+ io.binmode
40
+
41
+ pages = collect_pages
42
+ return write_non_linearized(io) if pages.length < 2
43
+
44
+ layout = compute_layout(pages)
45
+ assembled = assemble_file(pages, layout)
46
+ io.write(assembled)
47
+ end
48
+
49
+ private
50
+
51
+ def collect_pages
52
+ @document.pages.each.to_a
53
+ end
54
+
55
+ def compute_layout(pages) # rubocop:disable Metrics/MethodLength
56
+ all_objects = @document.each_indirect_object.to_a
57
+ first_page_closure = object_closure(pages.first)
58
+ first_page_objects, rest_objects = all_objects.partition { |o| first_page_closure.include?(o.oid) }
59
+
60
+ ordered = first_page_objects + rest_objects
61
+ hint_oid = @document.next_oid || 1
62
+
63
+ offsets = {}
64
+ temp = StringIO.new
65
+ temp.binmode
66
+ temp << header_bytes
67
+ lin_dict_size = estimate_lin_dict_size(pages.length)
68
+ lin_dict_offset = temp.pos
69
+ temp.write("X" * lin_dict_size)
70
+
71
+ ordered.each do |obj|
72
+ offsets[obj.oid] = temp.pos
73
+ temp << @serializer.serialize_indirect(obj)
74
+ end
75
+ first_page_end = temp.pos if first_page_objects.any?
76
+
77
+ hint = build_hint_stream(pages, offsets)
78
+ hint_data = hint.encode
79
+ hint_compressed = ::Zlib::Deflate.deflate(hint_data)
80
+ hint_offset = temp.pos
81
+ hint_dict = @serializer.serialize(
82
+ Type: :XRef,
83
+ S: HintStream::DEFAULT_ITEM_BITS,
84
+ Filter: :FlateDecode,
85
+ Length: hint_compressed.bytesize
86
+ )
87
+ temp << "#{hint_oid} 0 obj\n"
88
+ temp << hint_dict
89
+ temp << "\nstream\n"
90
+ temp << hint_compressed
91
+ temp << "\nendstream\nendobj\n"
92
+ offsets[hint_oid] = hint_offset
93
+
94
+ xref_offset = temp.pos
95
+ xref_bytes = build_xref(offsets)
96
+ temp << xref_bytes
97
+ temp << build_trailer(xref_offset)
98
+
99
+ Layout.new(
100
+ lin_dict_offset: lin_dict_offset,
101
+ lin_dict_size: lin_dict_size,
102
+ hint_offset: hint_offset,
103
+ hint_length: hint_compressed.bytesize,
104
+ first_page_oid: pages.first.oid,
105
+ first_page_end: first_page_end || temp.pos,
106
+ xref_offset: xref_offset,
107
+ total_size: temp.pos,
108
+ num_pages: pages.length,
109
+ ordered_objects: ordered,
110
+ hint_oid: hint_oid,
111
+ hint_dict: hint_dict,
112
+ hint_compressed: hint_compressed,
113
+ xref_bytes: xref_bytes,
114
+ trailer_bytes: build_trailer(xref_offset)
115
+ )
116
+ end
117
+
118
+ def assemble_file(_pages, layout)
119
+ buf = String.new(encoding: Encoding::BINARY)
120
+ buf << header_bytes.b
121
+
122
+ lin_dict = serialize_lin_dict(
123
+ total_size: layout.total_size,
124
+ hint_offset: layout.hint_offset,
125
+ hint_length: layout.hint_length,
126
+ first_page_oid: layout.first_page_oid,
127
+ first_page_end: layout.first_page_end,
128
+ num_pages: layout.num_pages,
129
+ xref_offset: layout.xref_offset
130
+ )
131
+ lin_padded = pad_to_size(lin_dict, layout.lin_dict_size)
132
+ buf << lin_padded
133
+
134
+ layout.ordered_objects.each do |obj|
135
+ buf << @serializer.serialize_indirect(obj)
136
+ end
137
+
138
+ buf << "#{layout.hint_oid} 0 obj\n"
139
+ buf << layout.hint_dict
140
+ buf << "\nstream\n"
141
+ buf << layout.hint_compressed
142
+ buf << "\nendstream\nendobj\n"
143
+
144
+ buf << layout.xref_bytes
145
+ buf << layout.trailer_bytes
146
+
147
+ buf.force_encoding(Encoding::BINARY)
148
+ end
149
+
150
+ def serialize_lin_dict(total_size:, hint_offset:, hint_length:,
151
+ first_page_oid:, first_page_end:, num_pages:, xref_offset:)
152
+ dict_str = @serializer.serialize(
153
+ Linearized: 1,
154
+ L: total_size,
155
+ H: Pdfrb::Model::PdfArray.new([hint_offset, hint_length]),
156
+ O: first_page_oid,
157
+ E: first_page_end,
158
+ N: num_pages,
159
+ T: xref_offset
160
+ )
161
+ "1 0 obj\n#{dict_str}\nendobj\n"
162
+ end
163
+
164
+ def pad_to_size(str, target_size)
165
+ return str if str.bytesize >= target_size
166
+
167
+ str + ("\n" * (target_size - str.bytesize))
168
+ end
169
+
170
+ def estimate_lin_dict_size(_num_pages)
171
+ 300
172
+ end
173
+
174
+ def build_hint_stream(pages, offsets)
175
+ hint = HintStream.new
176
+ base_offset = offsets[pages.first.oid] || 0
177
+
178
+ pages.each do |page|
179
+ offset = offsets[page.oid] || 0
180
+ hint.add_page(
181
+ offset_delta: offset - base_offset,
182
+ page_length: 200,
183
+ num_objects: 1,
184
+ page_obj_num: page.oid
185
+ )
186
+ end
187
+ hint
188
+ end
189
+
190
+ def object_closure(root)
191
+ seen = Set.new
192
+ queue = [root]
193
+
194
+ until queue.empty?
195
+ obj = queue.shift
196
+ next if seen.include?(obj.oid)
197
+
198
+ seen << obj.oid
199
+
200
+ value = obj.is_a?(Pdfrb::Model::Object) ? obj.value : obj
201
+ walk_for_refs(value) do |ref|
202
+ child = @document.object(ref)
203
+ queue << child if child && !seen.include?(child.oid)
204
+ end
205
+ end
206
+
207
+ seen
208
+ end
209
+
210
+ def walk_for_refs(value, &block)
211
+ case value
212
+ when ::Hash
213
+ value.each_value { |v| walk_for_refs(v, &block) }
214
+ when ::Array, Pdfrb::Model::PdfArray
215
+ value.each { |v| walk_for_refs(v, &block) }
216
+ when Pdfrb::Model::Reference
217
+ yield value
218
+ end
219
+ end
220
+
221
+ def build_xref(offsets)
222
+ buf = +""
223
+ oids = offsets.keys.sort
224
+ max_oid = oids.max || 0
225
+ buf << "xref\n"
226
+ buf << "0 #{max_oid + 1}\n"
227
+ buf << "0000000000 65535 f \r\n"
228
+ (1..max_oid).each do |oid|
229
+ off = offsets[oid]
230
+ buf << if off
231
+ sprintf("%010d %05d n \r\n", off, 0)
232
+ else
233
+ "0000000000 00000 f \r\n"
234
+ end
235
+ end
236
+ buf
237
+ end
238
+
239
+ def build_trailer(xref_offset)
240
+ root = @document.catalog
241
+ root_ref = if root.is_a?(Pdfrb::Model::Object) && root.indirect?
242
+ Pdfrb::Model::Reference.new(root.oid, root.gen)
243
+ end
244
+ size = [@document.next_oid || 1, 2].max
245
+
246
+ trailer_str = @serializer.serialize(Size: size, Root: root_ref)
247
+ "trailer\n#{trailer_str}\nstartxref\n#{xref_offset}\n%%EOF\n"
248
+ end
249
+
250
+ def header_bytes
251
+ "%PDF-1.7\n%\xE2\xE3\xCF\xD3\n"
252
+ end
253
+
254
+ def write_non_linearized(io)
255
+ Pdfrb::Writer.write(@document, io)
256
+ end
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ # Linearization (PDF 1.2+ fast-web-view, ISO 32000-2 §7.6.2 + Annex F).
5
+ #
6
+ # A linearized PDF is structured so the first page's data appears near
7
+ # the front of the file, enabling incremental download and display.
8
+ # The structure has:
9
+ # Part 1: Linearization parameter dict + first-page xref
10
+ # Part 2: First page's document objects
11
+ # Part 3: Remaining pages' objects
12
+ # Part 4: Hint stream (page-offset + shared-object tables)
13
+ # Part 5: Main xref + trailer
14
+ #
15
+ # Detection: see Pdfrb::Source::LinearizationDetection.
16
+ # Writing: see Pdfrb::Linearization::Writer.
17
+ module Linearization
18
+ autoload :Writer, "pdfrb/linearization/writer"
19
+ autoload :HintStream, "pdfrb/linearization/hint_stream"
20
+ end
21
+ end
@@ -271,6 +271,18 @@ module Pdfrb
271
271
  data.deref(document)
272
272
  end
273
273
 
274
+ # PDF Boolean values can come back as Ruby +true+/+false+, as the
275
+ # strings +"true"+/+"false"+ (from arlington defaults), or as
276
+ # +nil+ when absent. Normalise to a Ruby boolean.
277
+ def truthy?(value)
278
+ return false if value.nil? || value == false
279
+ return true if value == true
280
+ return false if value.to_s.downcase == "false"
281
+ return false if value.to_s.downcase == "no"
282
+
283
+ !!value
284
+ end
285
+
274
286
  private
275
287
 
276
288
  def unbox_object?(obj)
@@ -13,8 +13,8 @@ module Pdfrb
13
13
  super(Array(arr), oid: oid, gen: gen, document: document)
14
14
  end
15
15
 
16
- def each(&block)
17
- @value.each(&block)
16
+ def each(&)
17
+ @value.each(&)
18
18
  self
19
19
  end
20
20
 
@@ -13,6 +13,48 @@ module Pdfrb
13
13
 
14
14
  register_type :Action
15
15
 
16
+ def subtype; self[:S]; end
17
+ def next_action; self[:Next]; end
18
+
19
+ def next_actions
20
+ value = self[:Next]
21
+ return [] unless value
22
+
23
+ value.is_a?(Pdfrb::Model::PdfArray) ? value.to_a : value
24
+ end
25
+
26
+ def goto?
27
+ subtype&.to_sym == :GoTo
28
+ end
29
+
30
+ def uri?
31
+ subtype&.to_sym == :URI
32
+ end
33
+
34
+ def launch?
35
+ subtype&.to_sym == :Launch
36
+ end
37
+
38
+ def javascript?
39
+ subtype&.to_sym == :JavaScript
40
+ end
41
+
42
+ def named?
43
+ subtype&.to_sym == :Named
44
+ end
45
+
46
+ def uri
47
+ return nil unless uri?
48
+
49
+ self[:URI]
50
+ end
51
+
52
+ def d
53
+ return nil unless goto?
54
+
55
+ self[:D]
56
+ end
57
+
16
58
  class << self
17
59
  def subtype_map
18
60
  @subtype_map ||= {}
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # GoTo3DView action (s12.6.4.12, PDF 1.6+). Navigate within a 3D stream.
7
+ class ActionGoTo3DView < Action
8
+ register_subtype :GoTo3DView
9
+
10
+ def target_view; self[:TA]; end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # GoToDp action (s12.6.4.2, PDF 2.0). Destination pointer variant
7
+ # of GoTo that supports /DP (destination page) over a /D array.
8
+ class ActionGoToDp < Action
9
+ register_subtype :GoToDp
10
+
11
+ def destination_page; self[:DP]; end
12
+ def destination; self[:D]; end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Remote GoTo action (s12.6.4.3). Navigate to a destination in
7
+ # another PDF file.
8
+ class ActionGoToR < Action
9
+ register_subtype :GoToR
10
+
11
+ def file_spec; self[:F]; end
12
+ def destination; self[:D]; end
13
+ def new_window?; self[:NewWindow] == true; end
14
+ def open_in_new_window?; new_window?; end
15
+
16
+ def named_destination?
17
+ destination.is_a?(String) || destination.is_a?(Symbol)
18
+ end
19
+
20
+ def page_index_destination?
21
+ destination.is_a?(Array) && destination.first.is_a?(Integer)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # GoTo action (s12.6.4.2). Navigate to a destination.
7
+ class ActionGoTo < Action
8
+ register_subtype :GoTo
9
+
10
+ def destination; self[:D]; end
11
+
12
+ def page_index_destination?
13
+ destination.is_a?(Array) && destination.first.is_a?(Integer)
14
+ end
15
+
16
+ def named_destination?
17
+ destination.is_a?(Symbol) || destination.is_a?(String)
18
+ end
19
+
20
+ def target_page_number
21
+ return nil unless page_index_destination?
22
+
23
+ destination.first
24
+ end
25
+
26
+ def display_option
27
+ return nil unless page_index_destination?
28
+
29
+ destination[1..]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Hide action (s12.6.4.10). Show/hide annotations.
7
+ class ActionHide < Action
8
+ register_subtype :Hide
9
+
10
+ def targets; self[:T]; end
11
+ def hide?; self[:H] != false; end
12
+
13
+ def each_target
14
+ return enum_for(:each_target) unless block_given?
15
+ return unless targets && document
16
+
17
+ arr = targets.is_a?(Array) ? targets : [targets]
18
+ arr.each do |ref|
19
+ obj = ref.is_a?(Pdfrb::Model::Reference) ? document.object(ref) : ref
20
+ yield obj if obj
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Import-data action (s12.7.6.4). Imports form data from an FDF/XFDF file.
7
+ class ActionImportData < Action
8
+ register_subtype :ImportData
9
+
10
+ def file_spec; self[:F]; end
11
+
12
+ def has_file?
13
+ !!file_spec
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # JavaScript action (s12.6.4.16). Execute JavaScript code.
7
+ class ActionJavaScript < Action
8
+ register_subtype :JavaScript
9
+
10
+ def script; self[:JS]; end
11
+
12
+ def has_script?
13
+ !!script && (!script.is_a?(String) || !script.empty?)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Launch action (s12.6.4.5). Launch an external application.
7
+ class ActionLaunch < Action
8
+ register_subtype :Launch
9
+
10
+ def file_spec; self[:F]; end
11
+ def new_window?; self[:NewWindow] == true; end
12
+ def win_target; self[:Win]; end
13
+ def mac_target; self[:Mac]; end
14
+ def unix_target; self[:Unix]; end
15
+
16
+ def has_platform_target?
17
+ !!win_target || !!mac_target || !!unix_target
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Movie action (s12.6.4.8). Deprecated in PDF 2.0 but still
7
+ # appears in legacy PDFs. Plays/stops a Movie annotation.
8
+ class ActionMovie < Action
9
+ register_subtype :Movie
10
+
11
+ def annotation; self[:Annotation]; end
12
+ def title; self[:T]; end
13
+ def operation; self[:Operation]&.to_sym || :Play; end
14
+
15
+ def play?; operation == :Play; end
16
+ def stop?; operation == :Stop; end
17
+ def pause?; operation == :Pause; end
18
+ def resume?; operation == :Resume; end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Named action (s12.6.4.19). Pre-defined action by name (NextPage,
7
+ # PrevPage, FirstPage, LastPage, Print, etc.).
8
+ class ActionNamed < Action
9
+ register_subtype :Named
10
+
11
+ def action_name; self[:N]; end
12
+
13
+ def next_page?; action_name&.to_sym == :NextPage; end
14
+ def prev_page?; action_name&.to_sym == :PrevPage; end
15
+ def first_page?; action_name&.to_sym == :FirstPage; end
16
+ def last_page?; action_name&.to_sym == :LastPage; end
17
+ def print?; action_name&.to_sym == :Print; end
18
+ def save?; action_name&.to_sym == :Save; end
19
+ def find?; action_name&.to_sym == :Find; end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # NOP action (PDF 1.2 deprecated). No-op placeholder.
7
+ class ActionNOP < Action
8
+ register_subtype :NOP
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Rendition action (s12.6.4.12). Controls multimedia rendition
7
+ # on screen annotations.
8
+ class ActionRendition < Action
9
+ register_subtype :Rendition
10
+
11
+ def rendition; self[:R]; end
12
+ def screen_annotation; self[:AN]; end
13
+ def operation; self[:OP]; end
14
+ def javascript; self[:JS]; end
15
+
16
+ def play?; operation.zero?; end
17
+ def stop?; operation == 1; end
18
+ def pause?; operation == 2; end
19
+ def resume?; operation == 3; end
20
+ def play_resume?; operation == 4; end
21
+
22
+ def has_javascript?
23
+ !!javascript
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Reset-form action (s12.7.6.3). Resets form fields to defaults.
7
+ class ActionResetForm < Action
8
+ register_subtype :ResetForm
9
+
10
+ def fields; self[:Fields]; end
11
+
12
+ def include_exclude?
13
+ !!self[:Flags] && self[:Flags].anybits?(1)
14
+ end
15
+
16
+ def has_field_list?
17
+ !!fields && (!fields.is_a?(Array) || !fields.empty?)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # RichMediaExecute action (s12.6.4.12, PDF 2.0). Execute a
7
+ # command on a RichMedia annotation.
8
+ class ActionRichMediaExecute < Action
9
+ register_subtype :RichMediaExecute
10
+
11
+ def target; self[:TA]; end
12
+ def instance; self[:Instance]; end
13
+ def arguments; self[:Args]; end
14
+ end
15
+ end
16
+ end
17
+ end