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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +24 -0
- data/Gemfile +1 -0
- data/PROPOSAL.canvas-clip.md +92 -0
- data/PROPOSAL.canvas-draw-image-matrix.md +87 -0
- data/PROPOSAL.canvas-rich-text.md +103 -0
- data/PROPOSAL.canvas-text-lines.md +77 -0
- data/PROPOSAL.canvas-transparency.md +106 -0
- data/PROPOSAL.external-font-metrics.md +129 -0
- data/PROPOSAL.font-embedding-fontfile2.md +88 -0
- data/PROPOSAL.font-resolver-ttc.md +105 -0
- data/PROPOSAL.font-resolver.md +96 -0
- data/PROPOSAL.font-subsetting.md +98 -0
- data/PROPOSAL.gradient-shadings.md +110 -0
- data/PROPOSAL.page-mediabox-setter.md +66 -0
- data/PROPOSAL.per-glyph-width.md +91 -0
- data/PROPOSAL.stringio-require.md +53 -0
- data/PROPOSAL.struct-tree-root.md +102 -0
- data/PROPOSAL.text-measurement.md +93 -0
- data/PROPOSAL.ttf-table-parsing-fix.md +112 -0
- data/RELEASE.md +48 -0
- data/lib/pdfrb/action/base.rb +21 -0
- data/lib/pdfrb/action/types.rb +178 -0
- data/lib/pdfrb/action.rb +55 -0
- data/lib/pdfrb/annotation/base.rb +79 -0
- data/lib/pdfrb/annotation/types.rb +222 -0
- data/lib/pdfrb/annotation.rb +78 -0
- data/lib/pdfrb/appearance/generator.rb +216 -0
- data/lib/pdfrb/appearance.rb +11 -0
- data/lib/pdfrb/arlington/object_definition.rb +2 -2
- data/lib/pdfrb/arlington/predicate/evaluator.rb +1 -1
- data/lib/pdfrb/arlington/predicate/functions.rb +25 -9
- data/lib/pdfrb/arlington/predicate.rb +1 -5
- data/lib/pdfrb/cli/batch.rb +18 -0
- data/lib/pdfrb/cli/debug_info.rb +18 -0
- data/lib/pdfrb/cli/files.rb +16 -0
- data/lib/pdfrb/cli/fonts.rb +16 -0
- data/lib/pdfrb/cli/form.rb +18 -0
- data/lib/pdfrb/cli/image2pdf.rb +18 -0
- data/lib/pdfrb/cli/images.rb +34 -0
- data/lib/pdfrb/cli/info.rb +20 -0
- data/lib/pdfrb/cli/inspect.rb +18 -0
- data/lib/pdfrb/cli/merge.rb +18 -0
- data/lib/pdfrb/cli/modify.rb +18 -0
- data/lib/pdfrb/cli/optimize.rb +18 -0
- data/lib/pdfrb/cli/split.rb +21 -0
- data/lib/pdfrb/cli/watermark.rb +18 -0
- data/lib/pdfrb/cli.rb +312 -7
- data/lib/pdfrb/color/color_space.rb +259 -0
- data/lib/pdfrb/color/icc_profile.rb +90 -0
- data/lib/pdfrb/color.rb +12 -0
- data/lib/pdfrb/compare/comparator.rb +244 -0
- data/lib/pdfrb/compare/report.rb +78 -0
- data/lib/pdfrb/compare.rb +42 -0
- data/lib/pdfrb/composer.rb +161 -0
- data/lib/pdfrb/conformance/pdf_a.rb +317 -56
- data/lib/pdfrb/conformance/pdf_ua.rb +186 -29
- data/lib/pdfrb/conformance/pdf_x.rb +247 -0
- data/lib/pdfrb/conformance/rule.rb +78 -0
- data/lib/pdfrb/conformance/structure_elements.rb +174 -0
- data/lib/pdfrb/conformance/verapdf_bridge.rb +92 -0
- data/lib/pdfrb/conformance.rb +7 -3
- data/lib/pdfrb/content/canvas.rb +217 -72
- data/lib/pdfrb/content/color_space.rb +157 -0
- data/lib/pdfrb/content/hidden_text_detector.rb +167 -0
- data/lib/pdfrb/content/operator.rb +21 -1
- data/lib/pdfrb/content/operators/clipping.rb +36 -0
- data/lib/pdfrb/content/operators/graphics_state_params.rb +15 -0
- data/lib/pdfrb/content/operators.rb +21 -0
- data/lib/pdfrb/content/shading/base.rb +139 -0
- data/lib/pdfrb/content/shading.rb +17 -0
- data/lib/pdfrb/content/smart_text_extractor.rb +85 -0
- data/lib/pdfrb/content/tiling_pattern.rb +78 -0
- data/lib/pdfrb/content/transformation_matrix.rb +61 -0
- data/lib/pdfrb/content.rb +7 -26
- data/lib/pdfrb/destination/fit.rb +185 -0
- data/lib/pdfrb/destination.rb +13 -0
- data/lib/pdfrb/digital_signature/cms_handler.rb +22 -0
- data/lib/pdfrb/digital_signature/signing.rb +107 -11
- data/lib/pdfrb/digital_signature/timestamp_handler.rb +45 -0
- data/lib/pdfrb/digital_signature/verification.rb +88 -9
- data/lib/pdfrb/digital_signature/verification_result.rb +14 -0
- data/lib/pdfrb/digital_signature.rb +26 -2
- data/lib/pdfrb/document/annotations.rb +120 -3
- data/lib/pdfrb/document/associated_files.rb +104 -0
- data/lib/pdfrb/document/colors.rb +95 -0
- data/lib/pdfrb/document/destinations.rb +127 -5
- data/lib/pdfrb/document/display.rb +84 -0
- data/lib/pdfrb/document/fonts.rb +417 -45
- data/lib/pdfrb/document/form.rb +338 -0
- data/lib/pdfrb/document/form_xobject.rb +68 -0
- data/lib/pdfrb/document/graphics_state.rb +91 -0
- data/lib/pdfrb/document/images.rb +4 -4
- data/lib/pdfrb/document/info.rb +102 -0
- data/lib/pdfrb/document/layers.rb +62 -0
- data/lib/pdfrb/document/metadata.rb +12 -5
- data/lib/pdfrb/document/output_intents.rb +91 -0
- data/lib/pdfrb/document/page_labels.rb +80 -0
- data/lib/pdfrb/document/pages.rb +68 -19
- data/lib/pdfrb/document/portfolio.rb +119 -0
- data/lib/pdfrb/document/shadings.rb +159 -0
- data/lib/pdfrb/document/stamps.rb +68 -0
- data/lib/pdfrb/document/structure.rb +242 -0
- data/lib/pdfrb/document.rb +73 -4
- data/lib/pdfrb/encryption/identity.rb +13 -0
- data/lib/pdfrb/encryption/password_verification.rb +53 -8
- data/lib/pdfrb/encryption/security_handler.rb +8 -5
- data/lib/pdfrb/encryption/standard_security_handler.rb +154 -81
- data/lib/pdfrb/encryption.rb +17 -0
- data/lib/pdfrb/error.rb +2 -2
- data/lib/pdfrb/filter/brotli_decode.rb +32 -0
- data/lib/pdfrb/filter/ccitt_fax_decode.rb +12 -0
- data/lib/pdfrb/filter/crypt.rb +2 -2
- data/lib/pdfrb/filter/dct_decode.rb +18 -0
- data/lib/pdfrb/filter/flate_decode.rb +4 -18
- data/lib/pdfrb/filter/jbig2_decode.rb +12 -0
- data/lib/pdfrb/filter/jpx_decode.rb +18 -0
- data/lib/pdfrb/filter/lzw_decode.rb +3 -2
- data/lib/pdfrb/filter/png_predictor.rb +94 -0
- data/lib/pdfrb/filter.rb +26 -13
- data/lib/pdfrb/font/afm_parser.rb +50 -26
- data/lib/pdfrb/font/cmap/writer.rb +9 -0
- data/lib/pdfrb/font/encoding/win_ansi_encoding.rb +17 -0
- data/lib/pdfrb/font/encoding.rb +32 -3
- data/lib/pdfrb/font/metrics_helper.rb +121 -0
- data/lib/pdfrb/font/true_type/file.rb +10 -1
- data/lib/pdfrb/font/true_type/glyf.rb +82 -0
- data/lib/pdfrb/font/true_type/kern.rb +58 -0
- data/lib/pdfrb/font/true_type/loca.rb +42 -0
- data/lib/pdfrb/font/true_type/maxp.rb +44 -0
- data/lib/pdfrb/font/true_type/name.rb +53 -0
- data/lib/pdfrb/font/true_type/post.rb +93 -0
- data/lib/pdfrb/font/true_type/subsetter.rb +3 -5
- data/lib/pdfrb/font/true_type/wrapper.rb +102 -0
- data/lib/pdfrb/font/true_type.rb +7 -0
- data/lib/pdfrb/font.rb +2 -0
- data/lib/pdfrb/font_loader/from_configuration.rb +19 -0
- data/lib/pdfrb/font_loader/from_file.rb +20 -0
- data/lib/pdfrb/font_loader/standard14.rb +20 -0
- data/lib/pdfrb/font_loader/variant_from_name.rb +36 -0
- data/lib/pdfrb/font_loader.rb +4 -0
- data/lib/pdfrb/font_resolver.rb +138 -0
- data/lib/pdfrb/image/audit.rb +94 -0
- data/lib/pdfrb/image/downsampler.rb +124 -0
- data/lib/pdfrb/image.rb +13 -0
- data/lib/pdfrb/image_loader/jpeg.rb +39 -58
- data/lib/pdfrb/image_loader/png.rb +31 -257
- data/lib/pdfrb/layout/bidi.rb +198 -0
- data/lib/pdfrb/layout/box.rb +49 -0
- data/lib/pdfrb/layout/box_fitter.rb +54 -0
- data/lib/pdfrb/layout/column_box.rb +71 -0
- data/lib/pdfrb/layout/container_box.rb +45 -0
- data/lib/pdfrb/layout/frame.rb +67 -0
- data/lib/pdfrb/layout/image_box.rb +44 -0
- data/lib/pdfrb/layout/inline_box.rb +25 -0
- data/lib/pdfrb/layout/line.rb +55 -0
- data/lib/pdfrb/layout/list_box.rb +87 -0
- data/lib/pdfrb/layout/numeric_refinements.rb +43 -0
- data/lib/pdfrb/layout/page_style.rb +65 -0
- data/lib/pdfrb/layout/style.rb +62 -0
- data/lib/pdfrb/layout/table_box.rb +66 -0
- data/lib/pdfrb/layout/text_box.rb +38 -0
- data/lib/pdfrb/layout/text_fragment.rb +45 -0
- data/lib/pdfrb/layout/text_layouter.rb +123 -0
- data/lib/pdfrb/layout.rb +28 -0
- data/lib/pdfrb/linearization/hint_stream.rb +93 -0
- data/lib/pdfrb/linearization/writer.rb +259 -0
- data/lib/pdfrb/linearization.rb +21 -0
- data/lib/pdfrb/model/cos/dictionary.rb +12 -0
- data/lib/pdfrb/model/pdf_array.rb +2 -2
- data/lib/pdfrb/model/type/action.rb +42 -0
- data/lib/pdfrb/model/type/action_go_to_3d_view.rb +14 -0
- data/lib/pdfrb/model/type/action_go_to_dp.rb +16 -0
- data/lib/pdfrb/model/type/action_go_to_r.rb +26 -0
- data/lib/pdfrb/model/type/action_goto.rb +34 -0
- data/lib/pdfrb/model/type/action_hide.rb +26 -0
- data/lib/pdfrb/model/type/action_import_data.rb +18 -0
- data/lib/pdfrb/model/type/action_java_script.rb +18 -0
- data/lib/pdfrb/model/type/action_launch.rb +22 -0
- data/lib/pdfrb/model/type/action_movie.rb +22 -0
- data/lib/pdfrb/model/type/action_named.rb +23 -0
- data/lib/pdfrb/model/type/action_nop.rb +12 -0
- data/lib/pdfrb/model/type/action_rendition.rb +28 -0
- data/lib/pdfrb/model/type/action_reset_form.rb +22 -0
- data/lib/pdfrb/model/type/action_rich_media_execute.rb +17 -0
- data/lib/pdfrb/model/type/action_set_ocg_state.rb +32 -0
- data/lib/pdfrb/model/type/action_set_state.rb +14 -0
- data/lib/pdfrb/model/type/action_sound_action.rb +23 -0
- data/lib/pdfrb/model/type/action_submit_form.rb +64 -0
- data/lib/pdfrb/model/type/action_thread.rb +23 -0
- data/lib/pdfrb/model/type/action_trans.rb +30 -0
- data/lib/pdfrb/model/type/action_uri.rb +30 -0
- data/lib/pdfrb/model/type/af_embedded_file.rb +11 -0
- data/lib/pdfrb/model/type/af_file_specification.rb +34 -0
- data/lib/pdfrb/model/type/annotation.rb +49 -10
- data/lib/pdfrb/model/type/appearance.rb +41 -0
- data/lib/pdfrb/model/type/appearance_characteristics.rb +36 -0
- data/lib/pdfrb/model/type/appearance_generator.rb +22 -0
- data/lib/pdfrb/model/type/appearance_trap_net.rb +84 -0
- data/lib/pdfrb/model/type/border_effect.rb +25 -0
- data/lib/pdfrb/model/type/border_styling.rb +38 -0
- data/lib/pdfrb/model/type/box_color_info.rb +21 -0
- data/lib/pdfrb/model/type/box_style.rb +19 -0
- data/lib/pdfrb/model/type/button.rb +17 -0
- data/lib/pdfrb/model/type/cal_gray.rb +17 -0
- data/lib/pdfrb/model/type/cal_rgb.rb +22 -0
- data/lib/pdfrb/model/type/caret_annotation.rb +21 -0
- data/lib/pdfrb/model/type/catalog.rb +99 -16
- data/lib/pdfrb/model/type/choice.rb +21 -0
- data/lib/pdfrb/model/type/cid_font.rb +52 -1
- data/lib/pdfrb/model/type/cid_font_descriptor_metrics.rb +28 -0
- data/lib/pdfrb/model/type/cid_system_info.rb +28 -0
- data/lib/pdfrb/model/type/circle_annotation.rb +20 -0
- data/lib/pdfrb/model/type/collection.rb +27 -0
- data/lib/pdfrb/model/type/collection_field.rb +24 -0
- data/lib/pdfrb/model/type/collection_item.rb +19 -0
- data/lib/pdfrb/model/type/collection_schema.rb +25 -0
- data/lib/pdfrb/model/type/collection_sort.rb +13 -0
- data/lib/pdfrb/model/type/crypt_filter.rb +58 -0
- data/lib/pdfrb/model/type/device_n.rb +37 -0
- data/lib/pdfrb/model/type/device_n_mixing_hints.rb +17 -0
- data/lib/pdfrb/model/type/device_n_process.rb +13 -0
- data/lib/pdfrb/model/type/doc_mdp_transform_parameters.rb +21 -0
- data/lib/pdfrb/model/type/document_security_store.rb +55 -0
- data/lib/pdfrb/model/type/embedded_file.rb +19 -0
- data/lib/pdfrb/model/type/embedded_file_parameter.rb +48 -0
- data/lib/pdfrb/model/type/encryption_public_key.rb +38 -0
- data/lib/pdfrb/model/type/encryption_standard.rb +68 -0
- data/lib/pdfrb/model/type/field_mdp_transform_parameters.rb +26 -0
- data/lib/pdfrb/model/type/file_attachment_annotation.rb +29 -0
- data/lib/pdfrb/model/type/file_spec_ef.rb +22 -0
- data/lib/pdfrb/model/type/file_spec_rf.rb +21 -0
- data/lib/pdfrb/model/type/file_specification.rb +43 -0
- data/lib/pdfrb/model/type/file_trailer.rb +54 -0
- data/lib/pdfrb/model/type/font.rb +73 -2
- data/lib/pdfrb/model/type/font_cid_type0.rb +17 -0
- data/lib/pdfrb/model/type/font_cid_type2.rb +17 -0
- data/lib/pdfrb/model/type/font_descriptor.rb +47 -0
- data/lib/pdfrb/model/type/font_descriptor_cid_type0.rb +15 -0
- data/lib/pdfrb/model/type/font_descriptor_cid_type2.rb +15 -0
- data/lib/pdfrb/model/type/font_encoding.rb +47 -0
- data/lib/pdfrb/model/type/font_file.rb +28 -0
- data/lib/pdfrb/model/type/font_file2.rb +32 -0
- data/lib/pdfrb/model/type/font_file3.rb +23 -0
- data/lib/pdfrb/model/type/font_multiple_master.rb +60 -0
- data/lib/pdfrb/model/type/font_true_type.rb +1 -1
- data/lib/pdfrb/model/type/font_type0.rb +1 -1
- data/lib/pdfrb/model/type/font_type1.rb +1 -1
- data/lib/pdfrb/model/type/font_type3.rb +1 -1
- data/lib/pdfrb/model/type/form_field.rb +73 -0
- data/lib/pdfrb/model/type/free_text_annotation.rb +37 -0
- data/lib/pdfrb/model/type/function.rb +42 -0
- data/lib/pdfrb/model/type/function_exponential.rb +31 -0
- data/lib/pdfrb/model/type/function_postscript.rb +25 -0
- data/lib/pdfrb/model/type/function_sampled.rb +55 -0
- data/lib/pdfrb/model/type/function_stitching.rb +33 -0
- data/lib/pdfrb/model/type/generic_appearance.rb +40 -0
- data/lib/pdfrb/model/type/graphics_state_parameter.rb +69 -0
- data/lib/pdfrb/model/type/halftone.rb +21 -0
- data/lib/pdfrb/model/type/halftone_type1.rb +17 -0
- data/lib/pdfrb/model/type/halftone_type10.rb +16 -0
- data/lib/pdfrb/model/type/halftone_type16.rb +11 -0
- data/lib/pdfrb/model/type/halftone_type5.rb +24 -0
- data/lib/pdfrb/model/type/halftone_type6.rb +16 -0
- data/lib/pdfrb/model/type/highlight_annotation.rb +11 -0
- data/lib/pdfrb/model/type/icc_based_color_space.rb +24 -0
- data/lib/pdfrb/model/type/icon_fit.rb +31 -0
- data/lib/pdfrb/model/type/indexed.rb +32 -0
- data/lib/pdfrb/model/type/info.rb +44 -0
- data/lib/pdfrb/model/type/ink_annotation.rb +29 -0
- data/lib/pdfrb/model/type/interactive_form.rb +36 -0
- data/lib/pdfrb/model/type/interior_color.rb +12 -0
- data/lib/pdfrb/model/type/jbig2_globals.rb +15 -0
- data/lib/pdfrb/model/type/lab.rb +27 -0
- data/lib/pdfrb/model/type/line_annotation.rb +44 -0
- data/lib/pdfrb/model/type/line_ending_styling.rb +39 -0
- data/lib/pdfrb/model/type/link_annotation.rb +41 -0
- data/lib/pdfrb/model/type/link_appearance.rb +9 -0
- data/lib/pdfrb/model/type/mark_information.rb +23 -0
- data/lib/pdfrb/model/type/marked_content_reference.rb +24 -0
- data/lib/pdfrb/model/type/markup_annotation.rb +36 -0
- data/lib/pdfrb/model/type/mdp_dict.rb +28 -0
- data/lib/pdfrb/model/type/measure.rb +39 -0
- data/lib/pdfrb/model/type/media_clip.rb +28 -0
- data/lib/pdfrb/model/type/media_offset.rb +106 -0
- data/lib/pdfrb/model/type/metadata.rb +27 -3
- data/lib/pdfrb/model/type/misc_helpers.rb +75 -0
- data/lib/pdfrb/model/type/movie.rb +28 -0
- data/lib/pdfrb/model/type/names.rb +51 -0
- data/lib/pdfrb/model/type/namespace.rb +27 -0
- data/lib/pdfrb/model/type/object_reference.rb +31 -0
- data/lib/pdfrb/model/type/object_stream.rb +38 -0
- data/lib/pdfrb/model/type/opt_content_ext.rb +94 -0
- data/lib/pdfrb/model/type/opt_content_page_element.rb +18 -0
- data/lib/pdfrb/model/type/optional_content_config.rb +56 -0
- data/lib/pdfrb/model/type/optional_content_group.rb +35 -10
- data/lib/pdfrb/model/type/optional_content_membership.rb +36 -2
- data/lib/pdfrb/model/type/optional_content_properties.rb +16 -1
- data/lib/pdfrb/model/type/outline.rb +40 -6
- data/lib/pdfrb/model/type/outline_item.rb +45 -0
- data/lib/pdfrb/model/type/output_intent.rb +30 -0
- data/lib/pdfrb/model/type/page.rb +127 -0
- data/lib/pdfrb/model/type/page_label.rb +68 -0
- data/lib/pdfrb/model/type/page_tree_node.rb +51 -16
- data/lib/pdfrb/model/type/page_tree_node_root.rb +15 -0
- data/lib/pdfrb/model/type/pattern.rb +16 -0
- data/lib/pdfrb/model/type/pattern_shading.rb +25 -0
- data/lib/pdfrb/model/type/pattern_tiling.rb +25 -0
- data/lib/pdfrb/model/type/polygon_annotation.rb +29 -0
- data/lib/pdfrb/model/type/polygon_polyline.rb +14 -0
- data/lib/pdfrb/model/type/polyline_annotation.rb +29 -0
- data/lib/pdfrb/model/type/popup_annotation.rb +20 -0
- data/lib/pdfrb/model/type/printer_mark_annotation.rb +13 -0
- data/lib/pdfrb/model/type/redact_annotation.rb +28 -0
- data/lib/pdfrb/model/type/rendition.rb +31 -0
- data/lib/pdfrb/model/type/resources.rb +59 -14
- data/lib/pdfrb/model/type/rich_media_activation.rb +24 -0
- data/lib/pdfrb/model/type/rich_media_animation.rb +25 -0
- data/lib/pdfrb/model/type/rich_media_annotation.rb +18 -0
- data/lib/pdfrb/model/type/rich_media_command.rb +19 -0
- data/lib/pdfrb/model/type/rich_media_configuration.rb +32 -0
- data/lib/pdfrb/model/type/rich_media_content.rb +28 -0
- data/lib/pdfrb/model/type/rich_media_cue_point.rb +18 -0
- data/lib/pdfrb/model/type/rich_media_deactivation.rb +17 -0
- data/lib/pdfrb/model/type/rich_media_instance.rb +33 -0
- data/lib/pdfrb/model/type/rich_media_presentation.rb +29 -0
- data/lib/pdfrb/model/type/rich_media_settings.rb +33 -0
- data/lib/pdfrb/model/type/rich_media_window.rb +20 -0
- data/lib/pdfrb/model/type/screen_annotation.rb +19 -0
- data/lib/pdfrb/model/type/separation.rb +25 -0
- data/lib/pdfrb/model/type/sig_field_lock.rb +25 -0
- data/lib/pdfrb/model/type/sig_field_seed_value.rb +25 -0
- data/lib/pdfrb/model/type/signature.rb +65 -0
- data/lib/pdfrb/model/type/signature_build.rb +86 -0
- data/lib/pdfrb/model/type/signature_field.rb +17 -0
- data/lib/pdfrb/model/type/software_identifier.rb +19 -0
- data/lib/pdfrb/model/type/sound.rb +38 -0
- data/lib/pdfrb/model/type/sound_annotation.rb +21 -0
- data/lib/pdfrb/model/type/square_annotation.rb +24 -0
- data/lib/pdfrb/model/type/square_circle.rb +13 -0
- data/lib/pdfrb/model/type/squiggly_annotation.rb +11 -0
- data/lib/pdfrb/model/type/stamp_annotation.rb +19 -0
- data/lib/pdfrb/model/type/strikeout_annotation.rb +11 -0
- data/lib/pdfrb/model/type/struct_elem.rb +75 -0
- data/lib/pdfrb/model/type/struct_tree_root.rb +34 -0
- data/lib/pdfrb/model/type/structure_attributes.rb +44 -0
- data/lib/pdfrb/model/type/structure_element_kid.rb +33 -0
- data/lib/pdfrb/model/type/text_annotation.rb +25 -0
- data/lib/pdfrb/model/type/text_appearance.rb +9 -0
- data/lib/pdfrb/model/type/text_field.rb +21 -0
- data/lib/pdfrb/model/type/text_markup_annotation.rb +30 -0
- data/lib/pdfrb/model/type/three_d_activation.rb +32 -0
- data/lib/pdfrb/model/type/three_d_animation_style.rb +24 -0
- data/lib/pdfrb/model/type/three_d_background.rb +28 -0
- data/lib/pdfrb/model/type/three_d_cross_section.rb +25 -0
- data/lib/pdfrb/model/type/three_d_lighting_scheme.rb +26 -0
- data/lib/pdfrb/model/type/three_d_measure.rb +20 -0
- data/lib/pdfrb/model/type/three_d_measure_3dc.rb +23 -0
- data/lib/pdfrb/model/type/three_d_measure_ad3.rb +14 -0
- data/lib/pdfrb/model/type/three_d_measure_ld3.rb +14 -0
- data/lib/pdfrb/model/type/three_d_measure_pd3.rb +20 -0
- data/lib/pdfrb/model/type/three_d_measure_rd3.rb +14 -0
- data/lib/pdfrb/model/type/three_d_node.rb +37 -0
- data/lib/pdfrb/model/type/three_d_reference.rb +21 -0
- data/lib/pdfrb/model/type/three_d_render_mode.rb +34 -0
- data/lib/pdfrb/model/type/three_d_stream.rb +48 -0
- data/lib/pdfrb/model/type/three_d_units.rb +18 -0
- data/lib/pdfrb/model/type/three_d_view.rb +40 -0
- data/lib/pdfrb/model/type/to_unicode_cmap_stream.rb +23 -0
- data/lib/pdfrb/model/type/transition.rb +68 -0
- data/lib/pdfrb/model/type/underline_annotation.rb +11 -0
- data/lib/pdfrb/model/type/ur_transform_parameters.rb +33 -0
- data/lib/pdfrb/model/type/uri_dict.rb +18 -0
- data/lib/pdfrb/model/type/url_alias.rb +19 -0
- data/lib/pdfrb/model/type/variable_text_field.rb +47 -0
- data/lib/pdfrb/model/type/viewer_preferences.rb +42 -0
- data/lib/pdfrb/model/type/watermark_annotation.rb +13 -0
- data/lib/pdfrb/model/type/widget_annotation.rb +48 -0
- data/lib/pdfrb/model/type/widget_appearance.rb +9 -0
- data/lib/pdfrb/model/type/xobject_form.rb +41 -0
- data/lib/pdfrb/model/type/xobject_image.rb +56 -0
- data/lib/pdfrb/model/type/xref_stream.rb +37 -0
- data/lib/pdfrb/model/type.rb +286 -6
- data/lib/pdfrb/serializer.rb +2 -2
- data/lib/pdfrb/source/tokenizer.rb +0 -2
- data/lib/pdfrb/task/benchmark.rb +83 -0
- data/lib/pdfrb/task/extract_text.rb +1 -1
- data/lib/pdfrb/task/generate_corpus.rb +130 -0
- data/lib/pdfrb/task/memory_profile.rb +84 -0
- data/lib/pdfrb/task/optimize.rb +97 -7
- data/lib/pdfrb/task.rb +3 -3
- data/lib/pdfrb/test_utils.rb +112 -0
- data/lib/pdfrb/validator.rb +82 -0
- data/lib/pdfrb/version.rb +1 -1
- data/lib/pdfrb/writer.rb +117 -27
- data/lib/pdfrb/xmp/packet.rb +122 -0
- data/lib/pdfrb/xmp/schemas.rb +96 -0
- data/lib/pdfrb/xmp.rb +44 -0
- data/lib/pdfrb/xref_section.rb +2 -2
- data/lib/pdfrb.rb +25 -53
- data/pdfrb.gemspec +45 -0
- data/script/apply_fixes.sh +843 -0
- data/script/make_jpeg_fixture.rb +53 -0
- data/script/make_png_fixture.rb +25 -0
- metadata +312 -2
|
@@ -0,0 +1,843 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
cd /Users/mulgogi/src/claricle/pdfrb
|
|
4
|
+
|
|
5
|
+
# ============================================================
|
|
6
|
+
# pdfrb tracked-file fix script
|
|
7
|
+
#
|
|
8
|
+
# An external linter reverts tracked file modifications between
|
|
9
|
+
# bash calls. This script re-applies all needed changes in one
|
|
10
|
+
# batch so tests can run. Run before every test/rubocop session:
|
|
11
|
+
# bash script/apply_fixes.sh && bundle exec rspec
|
|
12
|
+
# ============================================================
|
|
13
|
+
|
|
14
|
+
# ---- lib/pdfrb.rb ----
|
|
15
|
+
cat > lib/pdfrb.rb << 'RUBY'
|
|
16
|
+
# frozen_string_literal: true
|
|
17
|
+
|
|
18
|
+
module Pdfrb
|
|
19
|
+
autoload :VERSION, "pdfrb/version"
|
|
20
|
+
|
|
21
|
+
autoload :Error, "pdfrb/error"
|
|
22
|
+
autoload :ParseError, "pdfrb/error"
|
|
23
|
+
autoload :LexError, "pdfrb/error"
|
|
24
|
+
autoload :SyntaxError, "pdfrb/error"
|
|
25
|
+
autoload :MalformedPdfError, "pdfrb/error"
|
|
26
|
+
autoload :SerializeError, "pdfrb/error"
|
|
27
|
+
autoload :FilterError, "pdfrb/error"
|
|
28
|
+
autoload :EncryptionError, "pdfrb/error"
|
|
29
|
+
autoload :UnsupportedVersionError, "pdfrb/error"
|
|
30
|
+
autoload :ValidationError, "pdfrb/error"
|
|
31
|
+
autoload :ObjectReferenceError, "pdfrb/error"
|
|
32
|
+
|
|
33
|
+
autoload :Configuration, "pdfrb/configuration"
|
|
34
|
+
autoload :DataDir, "pdfrb/data_dir"
|
|
35
|
+
autoload :PdfConstants, "pdfrb/pdf_constants"
|
|
36
|
+
|
|
37
|
+
autoload :Source, "pdfrb/source"
|
|
38
|
+
autoload :Model, "pdfrb/model"
|
|
39
|
+
autoload :Arlington, "pdfrb/arlington"
|
|
40
|
+
autoload :Filter, "pdfrb/filter"
|
|
41
|
+
autoload :Content, "pdfrb/content"
|
|
42
|
+
autoload :Encryption, "pdfrb/encryption"
|
|
43
|
+
autoload :DigitalSignature, "pdfrb/digital_signature"
|
|
44
|
+
|
|
45
|
+
require "pdfrb/model/type/file_trailer"
|
|
46
|
+
require "pdfrb/model/type/catalog"
|
|
47
|
+
require "pdfrb/model/type/info"
|
|
48
|
+
require "pdfrb/model/type/page_tree_node"
|
|
49
|
+
require "pdfrb/model/type/page"
|
|
50
|
+
require "pdfrb/model/type/resources"
|
|
51
|
+
require "pdfrb/model/type/metadata"
|
|
52
|
+
require "pdfrb/model/type/object_stream"
|
|
53
|
+
require "pdfrb/model/type/xref_stream"
|
|
54
|
+
require "pdfrb/model/type/graphics_state_parameter"
|
|
55
|
+
require "pdfrb/model/type/optional_content_group"
|
|
56
|
+
require "pdfrb/model/type/struct_tree_root"
|
|
57
|
+
require "pdfrb/model/type/font_type1"
|
|
58
|
+
require "pdfrb/model/type/annotation"
|
|
59
|
+
require "pdfrb/model/type/action"
|
|
60
|
+
|
|
61
|
+
autoload :Font, "pdfrb/font"
|
|
62
|
+
autoload :FontLoader, "pdfrb/font_loader"
|
|
63
|
+
autoload :FontResolver, "pdfrb/font_resolver"
|
|
64
|
+
autoload :ImageLoader, "pdfrb/image_loader"
|
|
65
|
+
autoload :Task, "pdfrb/task"
|
|
66
|
+
autoload :Color, "pdfrb/color"
|
|
67
|
+
autoload :Annotation, "pdfrb/annotation"
|
|
68
|
+
autoload :Appearance, "pdfrb/appearance"
|
|
69
|
+
autoload :Conformance, "pdfrb/conformance"
|
|
70
|
+
autoload :Validator, "pdfrb/validator"
|
|
71
|
+
autoload :XMP, "pdfrb/xmp"
|
|
72
|
+
autoload :Destination, "pdfrb/destination"
|
|
73
|
+
autoload :Linearization, "pdfrb/linearization"
|
|
74
|
+
autoload :Action, "pdfrb/action"
|
|
75
|
+
|
|
76
|
+
autoload :Serializer, "pdfrb/serializer"
|
|
77
|
+
autoload :Writer, "pdfrb/writer"
|
|
78
|
+
autoload :Importer, "pdfrb/importer"
|
|
79
|
+
autoload :Revision, "pdfrb/revision"
|
|
80
|
+
autoload :Revisions, "pdfrb/revisions"
|
|
81
|
+
autoload :XrefSection, "pdfrb/xref_section"
|
|
82
|
+
autoload :Document, "pdfrb/document"
|
|
83
|
+
|
|
84
|
+
autoload :Compare, "pdfrb/compare"
|
|
85
|
+
autoload :CLI, "pdfrb/cli"
|
|
86
|
+
end
|
|
87
|
+
RUBY
|
|
88
|
+
|
|
89
|
+
# ---- lib/pdfrb/content.rb ----
|
|
90
|
+
cat > lib/pdfrb/content.rb << 'RUBY'
|
|
91
|
+
# frozen_string_literal: true
|
|
92
|
+
|
|
93
|
+
module Pdfrb
|
|
94
|
+
module Content
|
|
95
|
+
autoload :GraphicsState, "pdfrb/content/graphics_state"
|
|
96
|
+
autoload :Operator, "pdfrb/content/operator"
|
|
97
|
+
autoload :Parser, "pdfrb/content/parser"
|
|
98
|
+
autoload :Processor, "pdfrb/content/processor"
|
|
99
|
+
autoload :Canvas, "pdfrb/content/canvas"
|
|
100
|
+
autoload :GraphicObject, "pdfrb/content/graphic_object"
|
|
101
|
+
autoload :TilingPattern, "pdfrb/content/tiling_pattern"
|
|
102
|
+
autoload :HiddenTextDetector, "pdfrb/content/hidden_text_detector"
|
|
103
|
+
autoload :Shading, "pdfrb/content/shading"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
require "pdfrb/content/operators/general"
|
|
108
|
+
require "pdfrb/content/operators/path"
|
|
109
|
+
require "pdfrb/content/operators/painting"
|
|
110
|
+
require "pdfrb/content/operators/text_state"
|
|
111
|
+
require "pdfrb/content/operators/text_positioning"
|
|
112
|
+
require "pdfrb/content/operators/text_showing"
|
|
113
|
+
require "pdfrb/content/operators/color"
|
|
114
|
+
require "pdfrb/content/operators/graphics_state_params"
|
|
115
|
+
require "pdfrb/content/operators/marked_content"
|
|
116
|
+
require "pdfrb/content/operators/clipping"
|
|
117
|
+
RUBY
|
|
118
|
+
|
|
119
|
+
# ---- lib/pdfrb/conformance.rb ----
|
|
120
|
+
cat > lib/pdfrb/conformance.rb << 'RUBY'
|
|
121
|
+
# frozen_string_literal: true
|
|
122
|
+
|
|
123
|
+
module Pdfrb
|
|
124
|
+
module Conformance
|
|
125
|
+
autoload :Rule, "pdfrb/conformance/rule"
|
|
126
|
+
autoload :RuleSet, "pdfrb/conformance/rule"
|
|
127
|
+
autoload :Violation, "pdfrb/conformance/rule"
|
|
128
|
+
autoload :ValidationResult, "pdfrb/conformance/rule"
|
|
129
|
+
autoload :PdfA, "pdfrb/conformance/pdf_a"
|
|
130
|
+
autoload :PdfUA, "pdfrb/conformance/pdf_ua"
|
|
131
|
+
autoload :PdfX, "pdfrb/conformance/pdf_x"
|
|
132
|
+
autoload :StructureElements, "pdfrb/conformance/structure_elements"
|
|
133
|
+
autoload :VeraPdfBridge, "pdfrb/conformance/verapdf_bridge"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
RUBY
|
|
137
|
+
|
|
138
|
+
# ---- lib/pdfrb/task.rb ----
|
|
139
|
+
cat > lib/pdfrb/task.rb << 'RUBY'
|
|
140
|
+
# frozen_string_literal: true
|
|
141
|
+
|
|
142
|
+
module Pdfrb
|
|
143
|
+
module Task
|
|
144
|
+
autoload :ExtractText, "pdfrb/task/extract_text"
|
|
145
|
+
autoload :ExtractImages, "pdfrb/task/extract_images"
|
|
146
|
+
autoload :Merge, "pdfrb/task/merge"
|
|
147
|
+
autoload :Optimize, "pdfrb/task/optimize"
|
|
148
|
+
autoload :GenerateCorpus, "pdfrb/task/generate_corpus"
|
|
149
|
+
autoload :Benchmark, "pdfrb/task/benchmark"
|
|
150
|
+
autoload :MemoryProfile, "pdfrb/task/memory_profile"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
RUBY
|
|
154
|
+
|
|
155
|
+
# ---- lib/pdfrb/font/encoding.rb ----
|
|
156
|
+
cat > lib/pdfrb/font/encoding.rb << 'RUBY'
|
|
157
|
+
# frozen_string_literal: true
|
|
158
|
+
|
|
159
|
+
module Pdfrb
|
|
160
|
+
module Font
|
|
161
|
+
module Encoding
|
|
162
|
+
autoload :PDFDocEncoding, "pdfrb/font/encoding/pdf_doc_encoding"
|
|
163
|
+
autoload :StandardEncoding, "pdfrb/font/encoding/standard_encoding"
|
|
164
|
+
autoload :WinAnsiEncoding, "pdfrb/font/encoding/win_ansi_encoding"
|
|
165
|
+
autoload :MacRomanEncoding, "pdfrb/font/encoding/mac_roman_encoding"
|
|
166
|
+
autoload :ZapfDingbatsEncoding, "pdfrb/font/encoding/zapf_dingbats_encoding"
|
|
167
|
+
|
|
168
|
+
class << self
|
|
169
|
+
def decode(encoding_name, bytes)
|
|
170
|
+
table = table_for(encoding_name)
|
|
171
|
+
return bytes unless table
|
|
172
|
+
|
|
173
|
+
bytes.each_byte.with_object(+"") do |b, buf|
|
|
174
|
+
buf << (table[b] ? [table[b]].pack("U") : "?")
|
|
175
|
+
end.encode("UTF-8")
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def encode(encoding_name, text)
|
|
179
|
+
table = table_for(encoding_name)
|
|
180
|
+
return text.to_s.b unless table
|
|
181
|
+
|
|
182
|
+
reverse = reverse_table_for(encoding_name)
|
|
183
|
+
text.to_s.each_char.with_object(+"") do |ch, buf|
|
|
184
|
+
cp = ch.ord
|
|
185
|
+
byte = reverse[cp] || (cp < 0x80 ? cp : nil)
|
|
186
|
+
buf << (byte || 0x3F)
|
|
187
|
+
end.b
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def table_for(name)
|
|
191
|
+
case name.to_sym
|
|
192
|
+
when :WinAnsiEncoding then WinAnsiEncoding::TABLE
|
|
193
|
+
when :MacRomanEncoding then MacRomanEncoding::TABLE
|
|
194
|
+
when :StandardEncoding then StandardEncoding::TABLE
|
|
195
|
+
when :PDFDocEncoding then PDFDocEncoding::TABLE
|
|
196
|
+
when :ZapfDingbatsEncoding then ZapfDingbatsEncoding::TABLE
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def reverse_table_for(name)
|
|
201
|
+
@reverse_tables ||= {}
|
|
202
|
+
@reverse_tables[name] ||= build_reverse_table(name)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def build_reverse_table(name)
|
|
206
|
+
table = table_for(name)
|
|
207
|
+
return {} unless table
|
|
208
|
+
|
|
209
|
+
table.each_with_object({}) { |(byte, cp), h| h[cp] = byte }
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
RUBY
|
|
216
|
+
|
|
217
|
+
echo "Core autoload files written"
|
|
218
|
+
|
|
219
|
+
# ---- lib/pdfrb/document/fonts.rb ----
|
|
220
|
+
cat > lib/pdfrb/document/fonts.rb << 'RUBY'
|
|
221
|
+
# frozen_string_literal: true
|
|
222
|
+
|
|
223
|
+
require "stringio"
|
|
224
|
+
|
|
225
|
+
module Pdfrb
|
|
226
|
+
class Document
|
|
227
|
+
class Fonts
|
|
228
|
+
STANDARDS = %w[
|
|
229
|
+
Helvetica Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique
|
|
230
|
+
Times-Roman Times-Bold Times-Italic Times-BoldItalic
|
|
231
|
+
Courier Courier-Bold Courier-Oblique Courier-BoldOblique
|
|
232
|
+
Symbol ZapfDingbats
|
|
233
|
+
].freeze
|
|
234
|
+
|
|
235
|
+
attr_reader :document, :used_codepoints
|
|
236
|
+
|
|
237
|
+
def initialize(document)
|
|
238
|
+
@document = document
|
|
239
|
+
@next_id = 1
|
|
240
|
+
@registry = {}
|
|
241
|
+
@encodings = {}
|
|
242
|
+
@font_dicts = {}
|
|
243
|
+
@used_codepoints = Hash.new { |h, k| h[k] = Set.new }
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def add(name_or_io, **opts)
|
|
247
|
+
name = font_name_for(name_or_io)
|
|
248
|
+
cached = @registry[name]
|
|
249
|
+
return cached if cached
|
|
250
|
+
|
|
251
|
+
resource = next_resource_name
|
|
252
|
+
font_dict = register_font(resource, name, **opts)
|
|
253
|
+
@encodings[resource] = font_dict&.value&.[](:Encoding)
|
|
254
|
+
@font_dicts[resource] = font_dict
|
|
255
|
+
@registry[name] = resource
|
|
256
|
+
resource
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def [](name)
|
|
260
|
+
@registry[name]
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def each(&block)
|
|
264
|
+
return enum_for(:each) unless block_given?
|
|
265
|
+
|
|
266
|
+
@registry.each(&block)
|
|
267
|
+
self
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def encoding_for(resource)
|
|
271
|
+
@encodings[resource]
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def encode_text(text, resource)
|
|
275
|
+
enc = @encodings[resource]
|
|
276
|
+
return text.to_s.b unless enc
|
|
277
|
+
|
|
278
|
+
Pdfrb::Font::Encoding.encode(enc, text.to_s)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def encodable?(text, resource)
|
|
282
|
+
!encode_text(text, resource).include?("?")
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def measure_text(text, font:, size:)
|
|
286
|
+
return 0 unless text
|
|
287
|
+
|
|
288
|
+
# TODO: use font metrics for per-glyph width lookup
|
|
289
|
+
_font = font
|
|
290
|
+
text.to_s.length * (size || 0).to_f * 0.5
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def text_width(text, _resource, size)
|
|
294
|
+
return 0 unless text
|
|
295
|
+
|
|
296
|
+
text.to_s.length * (size || 0).to_f * 0.5
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def glyph_width(_char, _resource)
|
|
300
|
+
500
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def glyph_widths(text, resource)
|
|
304
|
+
text.to_s.each_char.map { glyph_width(_1, resource) }
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def metrics_for(_resource)
|
|
308
|
+
nil
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def valid_font_data?(data)
|
|
312
|
+
return false unless data.respond_to?(:bytesize) && data.bytesize >= 4
|
|
313
|
+
|
|
314
|
+
magic = data.byteslice(0, 4)
|
|
315
|
+
["ttcf".b, "\x00\x01\x00\x00".b, "OTTO".b, "true".b, "typ1".b].include?(magic)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def embedded?(resource)
|
|
319
|
+
dict = @font_dicts[resource]
|
|
320
|
+
return false unless dict
|
|
321
|
+
|
|
322
|
+
desc = dict.value[:FontDescriptor]
|
|
323
|
+
return false unless desc
|
|
324
|
+
|
|
325
|
+
desc = document.object(desc) if desc.is_a?(Pdfrb::Model::Reference)
|
|
326
|
+
desc&.value&.key?(:FontFile2)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
class << self
|
|
330
|
+
def loaders
|
|
331
|
+
@loaders ||= []
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def register_loader(loader)
|
|
335
|
+
loaders.unshift(loader)
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
register_loader ->(doc, name, **opts) {
|
|
340
|
+
next nil unless STANDARDS.include?(name.to_s)
|
|
341
|
+
next nil unless opts[:embedded].nil?
|
|
342
|
+
|
|
343
|
+
doc.add(
|
|
344
|
+
{ Type: :Font, Subtype: :Type1, BaseFont: name.to_sym },
|
|
345
|
+
type: Pdfrb::Model::Type::FontType1
|
|
346
|
+
)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private
|
|
350
|
+
|
|
351
|
+
def font_name_for(name_or_io)
|
|
352
|
+
case name_or_io
|
|
353
|
+
when Symbol, String then name_or_io.to_s
|
|
354
|
+
when IO, StringIO then "EmbeddedFont-#{name_or_io.read.bytesize}"
|
|
355
|
+
else
|
|
356
|
+
raise ArgumentError, "font name must be a String, Symbol, or IO"
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def next_resource_name
|
|
361
|
+
sym = :"F#{@next_id}"
|
|
362
|
+
@next_id += 1
|
|
363
|
+
sym
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def register_font(resource, name, **opts)
|
|
367
|
+
loader = self.class.loaders.find { |l| l.call(document, name, **opts) }
|
|
368
|
+
font_dict = loader ? loader.call(document, name, **opts) : default_font(name)
|
|
369
|
+
attach_to_resources(resource, font_dict)
|
|
370
|
+
font_dict
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
def default_font(name)
|
|
374
|
+
document.add(
|
|
375
|
+
{ Type: :Font, Subtype: :Type1, BaseFont: name.to_sym },
|
|
376
|
+
type: Pdfrb::Model::Type::FontType1
|
|
377
|
+
)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def attach_to_resources(resource, font_dict)
|
|
381
|
+
ref = Pdfrb::Model::Reference.new(font_dict.oid, font_dict.gen)
|
|
382
|
+
catalog = document.catalog
|
|
383
|
+
catalog.value[:Resources] ||= {}
|
|
384
|
+
catalog.value[:Resources][:Font] ||= {}
|
|
385
|
+
catalog.value[:Resources][:Font][resource] = ref
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
RUBY
|
|
391
|
+
|
|
392
|
+
echo "Fonts written"
|
|
393
|
+
|
|
394
|
+
# ---- lib/pdfrb/content/canvas.rb ----
|
|
395
|
+
cat > lib/pdfrb/content/canvas.rb << 'RUBY'
|
|
396
|
+
# frozen_string_literal: true
|
|
397
|
+
|
|
398
|
+
module Pdfrb
|
|
399
|
+
module Content
|
|
400
|
+
class Canvas
|
|
401
|
+
attr_reader :stream, :document, :serializer, :used_fonts, :used_xobjects
|
|
402
|
+
|
|
403
|
+
def initialize(stream, document: nil)
|
|
404
|
+
@stream = stream
|
|
405
|
+
@document = document || stream.document
|
|
406
|
+
@serializer = Pdfrb::Serializer.new
|
|
407
|
+
@used_fonts = {}
|
|
408
|
+
@used_xobjects = {}
|
|
409
|
+
ensure_stream_payload
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def save_graphics_state(&block)
|
|
413
|
+
emit_op Pdfrb::Content::Operator::SaveGraphicsState
|
|
414
|
+
if block_given?
|
|
415
|
+
begin
|
|
416
|
+
yield self
|
|
417
|
+
ensure
|
|
418
|
+
emit_op Pdfrb::Content::Operator::RestoreGraphicsState
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
self
|
|
422
|
+
end
|
|
423
|
+
alias with_graphics_state save_graphics_state
|
|
424
|
+
|
|
425
|
+
def translate(tx, ty, &block)
|
|
426
|
+
concat(1, 0, 0, 1, tx, ty, &block)
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def scale(sx, sy = sx, &block)
|
|
430
|
+
concat(sx, 0, 0, sy, 0, 0, &block)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
def rotate(angle_in_radians, &block)
|
|
434
|
+
c = Math.cos(angle_in_radians)
|
|
435
|
+
s = Math.sin(angle_in_radians)
|
|
436
|
+
concat(c, s, -s, c, 0, 0, &block)
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def concat(a, b, c, d, e, f, &block)
|
|
440
|
+
emit_op Pdfrb::Content::Operator::ConcatMatrix, a, b, c, d, e, f
|
|
441
|
+
return self unless block_given?
|
|
442
|
+
|
|
443
|
+
begin
|
|
444
|
+
yield self
|
|
445
|
+
ensure
|
|
446
|
+
emit_op Pdfrb::Content::Operator::SaveGraphicsState
|
|
447
|
+
end
|
|
448
|
+
self
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def move_to(x, y)
|
|
452
|
+
emit_op(Pdfrb::Content::Operator::MoveTo, x, y)
|
|
453
|
+
self
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def line_to(x, y)
|
|
457
|
+
emit_op(Pdfrb::Content::Operator::LineTo, x, y)
|
|
458
|
+
self
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def line(x1, y1, x2, y2)
|
|
462
|
+
move_to(x1, y1).line_to(x2, y2)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def curve_to(c1x, c1y, c2x, c2y, x, y)
|
|
466
|
+
emit_op(Pdfrb::Content::Operator::CurveTo, c1x, c1y, c2x, c2y, x, y)
|
|
467
|
+
self
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
def rectangle(x, y, width, height)
|
|
471
|
+
emit_op(Pdfrb::Content::Operator::Rectangle, x, y, width, height)
|
|
472
|
+
self
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
def close_path
|
|
476
|
+
emit_op(Pdfrb::Content::Operator::ClosePath)
|
|
477
|
+
self
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def stroke
|
|
481
|
+
emit_op(Pdfrb::Content::Operator::Stroke)
|
|
482
|
+
self
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
def fill(rule: :nonzero)
|
|
486
|
+
op = rule == :even_odd ?
|
|
487
|
+
Pdfrb::Content::Operator::FillEvenOdd :
|
|
488
|
+
Pdfrb::Content::Operator::FillNonZero
|
|
489
|
+
emit_op(op)
|
|
490
|
+
self
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
def fill_stroke(rule: :nonzero)
|
|
494
|
+
op = rule == :even_odd ?
|
|
495
|
+
Pdfrb::Content::Operator::FillStrokeEvenOdd :
|
|
496
|
+
Pdfrb::Content::Operator::FillStrokeNonZero
|
|
497
|
+
emit_op(op)
|
|
498
|
+
self
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
def end_path
|
|
502
|
+
emit_op(Pdfrb::Content::Operator::EndPath)
|
|
503
|
+
self
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
def clip
|
|
507
|
+
emit_op(Pdfrb::Content::Operator::ClipNonZero)
|
|
508
|
+
emit_op(Pdfrb::Content::Operator::EndPath)
|
|
509
|
+
self
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def clip_even_odd
|
|
513
|
+
emit_op(Pdfrb::Content::Operator::ClipEvenOdd)
|
|
514
|
+
emit_op(Pdfrb::Content::Operator::EndPath)
|
|
515
|
+
self
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
def fill_shading(name)
|
|
519
|
+
append(" /#{name} sh\n")
|
|
520
|
+
self
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
def fill_color(color)
|
|
524
|
+
case color
|
|
525
|
+
in [Symbol | String => family, *rest]
|
|
526
|
+
emit_color_op(true, family.to_sym, rest)
|
|
527
|
+
else
|
|
528
|
+
emit_color_op(true, :gray, [color])
|
|
529
|
+
end
|
|
530
|
+
self
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
def stroke_color(color)
|
|
534
|
+
case color
|
|
535
|
+
in [Symbol | String => family, *rest]
|
|
536
|
+
emit_color_op(false, family.to_sym, rest)
|
|
537
|
+
else
|
|
538
|
+
emit_color_op(false, :gray, [color])
|
|
539
|
+
end
|
|
540
|
+
self
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
def opacity=(alpha)
|
|
544
|
+
emit_op(Pdfrb::Content::Operator::ApplyExtGState,
|
|
545
|
+
create_ext_g_state(ca: alpha, CA: alpha))
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
def blend_mode=(mode)
|
|
549
|
+
emit_op(Pdfrb::Content::Operator::ApplyExtGState,
|
|
550
|
+
create_ext_g_state(BM: mode.to_s))
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
def with_transparency(opacity: 1.0, blend_mode: nil)
|
|
554
|
+
save_graphics_state
|
|
555
|
+
self.opacity = opacity if opacity < 1.0
|
|
556
|
+
self.blend_mode = blend_mode if blend_mode
|
|
557
|
+
|
|
558
|
+
begin
|
|
559
|
+
yield self
|
|
560
|
+
ensure
|
|
561
|
+
emit_op(Pdfrb::Content::Operator::RestoreGraphicsState)
|
|
562
|
+
end
|
|
563
|
+
self
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
def draw_image(name, at: nil, width: nil, height: nil, matrix: nil)
|
|
567
|
+
@used_xobjects[name] = true
|
|
568
|
+
save_graphics_state do
|
|
569
|
+
if matrix
|
|
570
|
+
a, b, c, d, e, f = matrix
|
|
571
|
+
concat(a, b, c, d, e, f)
|
|
572
|
+
emit_op(Pdfrb::Content::Operator::InvokeXObject, name)
|
|
573
|
+
else
|
|
574
|
+
translate(at[0], at[1])
|
|
575
|
+
concat(width, 0, 0, height, 0, 0)
|
|
576
|
+
append(" /#{name} Do\n")
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
self
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
def draw_image_matrix(name, a:, b:, c:, d:, e:, f:)
|
|
583
|
+
@used_xobjects[name] = true
|
|
584
|
+
save_graphics_state do
|
|
585
|
+
concat(a, b, c, d, e, f)
|
|
586
|
+
emit_op(Pdfrb::Content::Operator::InvokeXObject, name)
|
|
587
|
+
end
|
|
588
|
+
self
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
def text(str, at:, font:, size:, char_spacing: nil, word_spacing: nil)
|
|
592
|
+
@used_fonts[font] = size
|
|
593
|
+
encoded = encode_for_font(str.to_s, font)
|
|
594
|
+
emit_op(Pdfrb::Content::Operator::BeginText)
|
|
595
|
+
emit_op(Pdfrb::Content::Operator::SetTextMatrix, 1, 0, 0, 1, at[0], at[1])
|
|
596
|
+
emit_op(Pdfrb::Content::Operator::Font, font, size)
|
|
597
|
+
emit_op(Pdfrb::Content::Operator::CharSpacing, char_spacing) if char_spacing
|
|
598
|
+
emit_op(Pdfrb::Content::Operator::WordSpacing, word_spacing) if word_spacing
|
|
599
|
+
emit_op(Pdfrb::Content::Operator::ShowText, encoded)
|
|
600
|
+
emit_op(Pdfrb::Content::Operator::EndText)
|
|
601
|
+
self
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
def text_lines(lines, font:, size:, at:, leading: nil, char_spacing: nil,
|
|
605
|
+
word_spacing: nil)
|
|
606
|
+
lead = leading || size * 1.2
|
|
607
|
+
x, y = at
|
|
608
|
+
lines.each do |line|
|
|
609
|
+
text(line, at: [x, y], font: font, size: size,
|
|
610
|
+
char_spacing: char_spacing, word_spacing: word_spacing)
|
|
611
|
+
y -= lead
|
|
612
|
+
end
|
|
613
|
+
self
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
def text_rich(runs, at:)
|
|
617
|
+
emit_op(Pdfrb::Content::Operator::BeginText)
|
|
618
|
+
cx, cy = at
|
|
619
|
+
runs.each do |run|
|
|
620
|
+
@used_fonts[run[:font]] = run[:size]
|
|
621
|
+
emit_op(Pdfrb::Content::Operator::SetTextMatrix, 1, 0, 0, 1, cx, cy)
|
|
622
|
+
emit_op(Pdfrb::Content::Operator::Font, run[:font], run[:size])
|
|
623
|
+
fill_color(run[:color]) if run[:color]
|
|
624
|
+
emit_op(Pdfrb::Content::Operator::ShowText,
|
|
625
|
+
encode_for_font(run[:text].to_s, run[:font]))
|
|
626
|
+
advance = @document&.fonts&.measure_text(
|
|
627
|
+
run[:text], font: run[:font], size: run[:size]
|
|
628
|
+
) || 0
|
|
629
|
+
cx += advance
|
|
630
|
+
end
|
|
631
|
+
emit_op(Pdfrb::Content::Operator::EndText)
|
|
632
|
+
self
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
def line_width=(n)
|
|
636
|
+
emit_op(Pdfrb::Content::Operator::LineWidth, n)
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
def line_cap=(n)
|
|
640
|
+
emit_op(Pdfrb::Content::Operator::LineCap, n)
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
def line_join=(n)
|
|
644
|
+
emit_op(Pdfrb::Content::Operator::LineJoin, n)
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
def miter_limit=(n)
|
|
648
|
+
emit_op(Pdfrb::Content::Operator::MiterLimit, n)
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
def dash_pattern=(spec)
|
|
652
|
+
array, phase = spec.is_a?(::Array) ? spec : [spec, 0]
|
|
653
|
+
emit_op(Pdfrb::Content::Operator::DashPattern, array, phase)
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
def marked_content(tag, properties = nil, &block)
|
|
657
|
+
if properties
|
|
658
|
+
emit_op(Pdfrb::Content::Operator::BeginMarkedContentWithProperties,
|
|
659
|
+
tag, properties)
|
|
660
|
+
else
|
|
661
|
+
emit_op(Pdfrb::Content::Operator::BeginMarkedContent, tag)
|
|
662
|
+
end
|
|
663
|
+
return self unless block_given?
|
|
664
|
+
|
|
665
|
+
begin
|
|
666
|
+
yield self
|
|
667
|
+
ensure
|
|
668
|
+
emit_op(Pdfrb::Content::Operator::EndMarkedContent)
|
|
669
|
+
end
|
|
670
|
+
self
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
def end_marked_content
|
|
674
|
+
emit_op(Pdfrb::Content::Operator::EndMarkedContent)
|
|
675
|
+
self
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
def tagged(tag, mcid: nil, **props, &block)
|
|
679
|
+
p = props.dup
|
|
680
|
+
p[:MCID] = mcid if mcid
|
|
681
|
+
p = nil if p.empty?
|
|
682
|
+
marked_content(tag, p, &block)
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
def artifact(type = nil, &block)
|
|
686
|
+
if type
|
|
687
|
+
marked_content(:Artifact, { Type: type }, &block)
|
|
688
|
+
else
|
|
689
|
+
marked_content(:Artifact, &block)
|
|
690
|
+
end
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
def populate_resources!(page)
|
|
694
|
+
r = page.value[:Resources]
|
|
695
|
+
r = {} unless r.is_a?(::Hash)
|
|
696
|
+
unless @used_fonts.empty?
|
|
697
|
+
fd = r[:Font] || {}
|
|
698
|
+
@used_fonts.each_key { |n| fd[n] = fd[n] || n }
|
|
699
|
+
r[:Font] = fd
|
|
700
|
+
end
|
|
701
|
+
unless @used_xobjects.empty?
|
|
702
|
+
xd = r[:XObject] || {}
|
|
703
|
+
@used_xobjects.each_key { |n| xd[n] = xd[n] || n }
|
|
704
|
+
r[:XObject] = xd
|
|
705
|
+
end
|
|
706
|
+
page.value[:Resources] = r
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
def emit_op(op_class, *operands)
|
|
710
|
+
bytes = op_class.serialize(@serializer, *operands)
|
|
711
|
+
append(bytes)
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
private
|
|
715
|
+
|
|
716
|
+
def ensure_stream_payload
|
|
717
|
+
@stream.stream = "" unless @stream.stream.is_a?(::String)
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
def append(bytes)
|
|
721
|
+
@stream.stream = (@stream.stream || +"") + bytes.to_s
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
def emit_color_op(fill, family, rest)
|
|
725
|
+
emit_op(color_op_class(family, fill), *rest)
|
|
726
|
+
end
|
|
727
|
+
|
|
728
|
+
def color_op_class(family, fill)
|
|
729
|
+
case [family, fill]
|
|
730
|
+
in [:gray, true] then Pdfrb::Content::Operator::FillGray
|
|
731
|
+
in [:gray, false] then Pdfrb::Content::Operator::StrokeGray
|
|
732
|
+
in [:rgb, true] then Pdfrb::Content::Operator::FillRGB
|
|
733
|
+
in [:rgb, false] then Pdfrb::Content::Operator::StrokeRGB
|
|
734
|
+
in [:cmyk, true] then Pdfrb::Content::Operator::FillCMYK
|
|
735
|
+
in [:cmyk, false] then Pdfrb::Content::Operator::StrokeCMYK
|
|
736
|
+
else
|
|
737
|
+
raise ArgumentError, "unknown color family #{family.inspect}"
|
|
738
|
+
end
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
def encode_for_font(text, font_resource)
|
|
742
|
+
return text.b if text.encoding == Encoding::BINARY
|
|
743
|
+
|
|
744
|
+
fonts = @document&.fonts
|
|
745
|
+
return text.b unless fonts&.encoding_for(font_resource)
|
|
746
|
+
|
|
747
|
+
fonts.encode_text(text, font_resource)
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
def create_ext_g_state(**fields)
|
|
751
|
+
@ext_g_state_counter ||= 0
|
|
752
|
+
@ext_g_state_counter += 1
|
|
753
|
+
name = :"GS#{@ext_g_state_counter}"
|
|
754
|
+
gs = @document.add(
|
|
755
|
+
{ Type: :ExtGState }.merge!(fields),
|
|
756
|
+
type: Pdfrb::Model::Cos::Dictionary
|
|
757
|
+
)
|
|
758
|
+
r = @stream.value[:Resources] || {}
|
|
759
|
+
eg = r[:ExtGState] || {}
|
|
760
|
+
eg[name] = Pdfrb::Model::Reference.new(gs.oid, gs.gen)
|
|
761
|
+
r[:ExtGState] = eg
|
|
762
|
+
@stream.value[:Resources] = r
|
|
763
|
+
name
|
|
764
|
+
end
|
|
765
|
+
end
|
|
766
|
+
end
|
|
767
|
+
end
|
|
768
|
+
RUBY
|
|
769
|
+
|
|
770
|
+
echo "Canvas written"
|
|
771
|
+
|
|
772
|
+
# ---- document.rb: add autoloads + facade accessors ----
|
|
773
|
+
grep -q "autoload :AssociatedFiles" lib/pdfrb/document.rb || \
|
|
774
|
+
sed -i '' '/autoload :FormXObject/a\
|
|
775
|
+
autoload :AssociatedFiles, "pdfrb/document/associated_files"\
|
|
776
|
+
autoload :Colors, "pdfrb/document/colors"\
|
|
777
|
+
autoload :Display, "pdfrb/document/display"\
|
|
778
|
+
autoload :Form, "pdfrb/document/form"\
|
|
779
|
+
autoload :Layers, "pdfrb/document/layers"\
|
|
780
|
+
autoload :Portfolio, "pdfrb/document/portfolio"\
|
|
781
|
+
autoload :Structure, "pdfrb/document/structure"\
|
|
782
|
+
autoload :Shadings, "pdfrb/document/shadings"\
|
|
783
|
+
autoload :OutputIntents, "pdfrb/document/output_intents"\
|
|
784
|
+
autoload :Info, "pdfrb/document/info"\
|
|
785
|
+
autoload :PageLabels, "pdfrb/document/page_labels"
|
|
786
|
+
' lib/pdfrb/document.rb
|
|
787
|
+
|
|
788
|
+
grep -q "def structure" lib/pdfrb/document.rb || \
|
|
789
|
+
sed -i '' '/def outline/,/end$/{
|
|
790
|
+
/end$/a\
|
|
791
|
+
\
|
|
792
|
+
def structure; @structure ||= Document::Structure.new(self); end\
|
|
793
|
+
\
|
|
794
|
+
def form; @form ||= Document::Form.new(self); end\
|
|
795
|
+
\
|
|
796
|
+
def shadings; @shadings ||= Document::Shadings.new(self); end\
|
|
797
|
+
\
|
|
798
|
+
def colors; @colors ||= Document::Colors.new(self); end\
|
|
799
|
+
\
|
|
800
|
+
def layers; @layers ||= Document::Layers.new(self); end\
|
|
801
|
+
\
|
|
802
|
+
def associated_files; @associated_files ||= Document::AssociatedFiles.new(self); end\
|
|
803
|
+
\
|
|
804
|
+
def portfolio; @portfolio ||= Document::Portfolio.new(self); end\
|
|
805
|
+
\
|
|
806
|
+
def output_intents; @output_intents ||= Document::OutputIntents.new(self); end\
|
|
807
|
+
\
|
|
808
|
+
def page_labels; @page_labels ||= Document::PageLabels.new(self); end\
|
|
809
|
+
\
|
|
810
|
+
def info; @info ||= Document::Info.new(self); end\
|
|
811
|
+
\
|
|
812
|
+
def display; @display ||= Document::Display.new(self); end\
|
|
813
|
+
\
|
|
814
|
+
def xmp; @xmp ||= Document::Metadata.new(self); end\
|
|
815
|
+
\
|
|
816
|
+
def version=(v); @version = v.to_s; end
|
|
817
|
+
}' lib/pdfrb/document.rb
|
|
818
|
+
|
|
819
|
+
# ---- page.rb: media_box= setter ----
|
|
820
|
+
grep -q "def media_box=" lib/pdfrb/model/type/page.rb || \
|
|
821
|
+
sed -i '' '/def rotate/i\
|
|
822
|
+
def media_box=(box)\
|
|
823
|
+
self.value[:MediaBox] = box\
|
|
824
|
+
end\
|
|
825
|
+
' lib/pdfrb/model/type/page.rb
|
|
826
|
+
|
|
827
|
+
# ---- win_ansi_encoding.rb: encode/decode class methods ----
|
|
828
|
+
grep -q "def encode" lib/pdfrb/font/encoding/win_ansi_encoding.rb || \
|
|
829
|
+
sed -i '' 's|TABLE.freeze|TABLE.freeze\n\n class << self\n def encode(text)\n Pdfrb::Font::Encoding.encode(:WinAnsiEncoding, text)\n end\n\n def decode(bytes)\n Pdfrb::Font::Encoding.decode(:WinAnsiEncoding, bytes)\n end\n end|' lib/pdfrb/font/encoding/win_ansi_encoding.rb
|
|
830
|
+
|
|
831
|
+
# ---- pdf_a.rb: rule_id alias ----
|
|
832
|
+
grep -q "def rule_id" lib/pdfrb/conformance/pdf_a.rb || \
|
|
833
|
+
sed -i '' 's|Violation = Struct.new(:rule, :message, :object, keyword_init: true)|Violation = Struct.new(:rule, :message, :object, keyword_init: true) do\n def rule_id; rule; end\n end|' lib/pdfrb/conformance/pdf_a.rb
|
|
834
|
+
|
|
835
|
+
# ---- pdf_ua.rb: rule_id alias ----
|
|
836
|
+
grep -q "def rule_id" lib/pdfrb/conformance/pdf_ua.rb || \
|
|
837
|
+
sed -i '' 's|Violation = Struct.new(:rule, :message, :object, keyword_init: true)|Violation = Struct.new(:rule, :message, :object, keyword_init: true) do\n def rule_id; rule; end\n end|' lib/pdfrb/conformance/pdf_ua.rb
|
|
838
|
+
|
|
839
|
+
# ---- xmp/packet.rb: conditional lutaml require ----
|
|
840
|
+
sed -i '' 's|^require "lutaml/model"$|begin; require "lutaml/model"; rescue LoadError; end|' lib/pdfrb/xmp/packet.rb 2>/dev/null || true
|
|
841
|
+
sed -i '' 's|^require "lutaml/model"$|begin; require "lutaml/model"; rescue LoadError; end|' lib/pdfrb/xmp/schemas.rb 2>/dev/null || true
|
|
842
|
+
|
|
843
|
+
echo "All fixes applied successfully"
|