hexapdf 0.1.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 +7 -0
- data/CONTRIBUTERS +3 -0
- data/LICENSE +26 -0
- data/README.md +88 -0
- data/Rakefile +121 -0
- data/VERSION +1 -0
- data/agpl-3.0.txt +661 -0
- data/bin/hexapdf +6 -0
- data/data/hexapdf/afm/Courier-Bold.afm +342 -0
- data/data/hexapdf/afm/Courier-BoldOblique.afm +342 -0
- data/data/hexapdf/afm/Courier-Oblique.afm +342 -0
- data/data/hexapdf/afm/Courier.afm +342 -0
- data/data/hexapdf/afm/Helvetica-Bold.afm +2827 -0
- data/data/hexapdf/afm/Helvetica-BoldOblique.afm +2827 -0
- data/data/hexapdf/afm/Helvetica-Oblique.afm +3051 -0
- data/data/hexapdf/afm/Helvetica.afm +3051 -0
- data/data/hexapdf/afm/MustRead.html +1 -0
- data/data/hexapdf/afm/Symbol.afm +213 -0
- data/data/hexapdf/afm/Times-Bold.afm +2588 -0
- data/data/hexapdf/afm/Times-BoldItalic.afm +2384 -0
- data/data/hexapdf/afm/Times-Italic.afm +2667 -0
- data/data/hexapdf/afm/Times-Roman.afm +2419 -0
- data/data/hexapdf/afm/ZapfDingbats.afm +225 -0
- data/data/hexapdf/encoding/glyphlist.txt +4305 -0
- data/data/hexapdf/encoding/zapfdingbats.txt +225 -0
- data/examples/arc.rb +50 -0
- data/examples/graphics.rb +274 -0
- data/examples/hello_world.rb +16 -0
- data/examples/machupicchu.jpg +0 -0
- data/examples/merging.rb +24 -0
- data/examples/optimizing.rb +20 -0
- data/examples/show_char_bboxes.rb +55 -0
- data/examples/standard_pdf_fonts.rb +72 -0
- data/examples/truetype.rb +45 -0
- data/lib/hexapdf/cli/extract.rb +128 -0
- data/lib/hexapdf/cli/info.rb +121 -0
- data/lib/hexapdf/cli/inspect.rb +157 -0
- data/lib/hexapdf/cli/modify.rb +218 -0
- data/lib/hexapdf/cli.rb +121 -0
- data/lib/hexapdf/configuration.rb +392 -0
- data/lib/hexapdf/content/canvas.rb +1974 -0
- data/lib/hexapdf/content/color_space.rb +364 -0
- data/lib/hexapdf/content/graphic_object/arc.rb +267 -0
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +208 -0
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +173 -0
- data/lib/hexapdf/content/graphic_object.rb +81 -0
- data/lib/hexapdf/content/graphics_state.rb +579 -0
- data/lib/hexapdf/content/operator.rb +1072 -0
- data/lib/hexapdf/content/parser.rb +204 -0
- data/lib/hexapdf/content/processor.rb +451 -0
- data/lib/hexapdf/content/transformation_matrix.rb +172 -0
- data/lib/hexapdf/content.rb +47 -0
- data/lib/hexapdf/data_dir.rb +51 -0
- data/lib/hexapdf/dictionary.rb +303 -0
- data/lib/hexapdf/dictionary_fields.rb +382 -0
- data/lib/hexapdf/document.rb +589 -0
- data/lib/hexapdf/document_utils.rb +209 -0
- data/lib/hexapdf/encryption/aes.rb +206 -0
- data/lib/hexapdf/encryption/arc4.rb +93 -0
- data/lib/hexapdf/encryption/fast_aes.rb +79 -0
- data/lib/hexapdf/encryption/fast_arc4.rb +67 -0
- data/lib/hexapdf/encryption/identity.rb +63 -0
- data/lib/hexapdf/encryption/ruby_aes.rb +447 -0
- data/lib/hexapdf/encryption/ruby_arc4.rb +96 -0
- data/lib/hexapdf/encryption/security_handler.rb +494 -0
- data/lib/hexapdf/encryption/standard_security_handler.rb +616 -0
- data/lib/hexapdf/encryption.rb +94 -0
- data/lib/hexapdf/error.rb +73 -0
- data/lib/hexapdf/filter/ascii85_decode.rb +160 -0
- data/lib/hexapdf/filter/ascii_hex_decode.rb +87 -0
- data/lib/hexapdf/filter/dct_decode.rb +57 -0
- data/lib/hexapdf/filter/encryption.rb +59 -0
- data/lib/hexapdf/filter/flate_decode.rb +93 -0
- data/lib/hexapdf/filter/jpx_decode.rb +56 -0
- data/lib/hexapdf/filter/lzw_decode.rb +191 -0
- data/lib/hexapdf/filter/predictor.rb +266 -0
- data/lib/hexapdf/filter/run_length_decode.rb +108 -0
- data/lib/hexapdf/filter.rb +176 -0
- data/lib/hexapdf/font/cmap/parser.rb +146 -0
- data/lib/hexapdf/font/cmap/writer.rb +176 -0
- data/lib/hexapdf/font/cmap.rb +90 -0
- data/lib/hexapdf/font/encoding/base.rb +77 -0
- data/lib/hexapdf/font/encoding/difference_encoding.rb +64 -0
- data/lib/hexapdf/font/encoding/glyph_list.rb +150 -0
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +221 -0
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +265 -0
- data/lib/hexapdf/font/encoding/standard_encoding.rb +205 -0
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +244 -0
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +280 -0
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +250 -0
- data/lib/hexapdf/font/encoding.rb +68 -0
- data/lib/hexapdf/font/true_type/font.rb +179 -0
- data/lib/hexapdf/font/true_type/table/cmap.rb +103 -0
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +384 -0
- data/lib/hexapdf/font/true_type/table/directory.rb +92 -0
- data/lib/hexapdf/font/true_type/table/glyf.rb +166 -0
- data/lib/hexapdf/font/true_type/table/head.rb +143 -0
- data/lib/hexapdf/font/true_type/table/hhea.rb +109 -0
- data/lib/hexapdf/font/true_type/table/hmtx.rb +79 -0
- data/lib/hexapdf/font/true_type/table/loca.rb +79 -0
- data/lib/hexapdf/font/true_type/table/maxp.rb +112 -0
- data/lib/hexapdf/font/true_type/table/name.rb +218 -0
- data/lib/hexapdf/font/true_type/table/os2.rb +200 -0
- data/lib/hexapdf/font/true_type/table/post.rb +230 -0
- data/lib/hexapdf/font/true_type/table.rb +155 -0
- data/lib/hexapdf/font/true_type.rb +48 -0
- data/lib/hexapdf/font/true_type_wrapper.rb +240 -0
- data/lib/hexapdf/font/type1/afm_parser.rb +230 -0
- data/lib/hexapdf/font/type1/character_metrics.rb +67 -0
- data/lib/hexapdf/font/type1/font.rb +123 -0
- data/lib/hexapdf/font/type1/font_metrics.rb +117 -0
- data/lib/hexapdf/font/type1/pfb_parser.rb +71 -0
- data/lib/hexapdf/font/type1.rb +52 -0
- data/lib/hexapdf/font/type1_wrapper.rb +193 -0
- data/lib/hexapdf/font_loader/from_configuration.rb +70 -0
- data/lib/hexapdf/font_loader/standard14.rb +98 -0
- data/lib/hexapdf/font_loader.rb +85 -0
- data/lib/hexapdf/font_utils.rb +89 -0
- data/lib/hexapdf/image_loader/jpeg.rb +166 -0
- data/lib/hexapdf/image_loader/pdf.rb +89 -0
- data/lib/hexapdf/image_loader/png.rb +410 -0
- data/lib/hexapdf/image_loader.rb +68 -0
- data/lib/hexapdf/importer.rb +139 -0
- data/lib/hexapdf/name_tree_node.rb +78 -0
- data/lib/hexapdf/number_tree_node.rb +67 -0
- data/lib/hexapdf/object.rb +363 -0
- data/lib/hexapdf/parser.rb +349 -0
- data/lib/hexapdf/rectangle.rb +99 -0
- data/lib/hexapdf/reference.rb +98 -0
- data/lib/hexapdf/revision.rb +206 -0
- data/lib/hexapdf/revisions.rb +194 -0
- data/lib/hexapdf/serializer.rb +326 -0
- data/lib/hexapdf/stream.rb +279 -0
- data/lib/hexapdf/task/dereference.rb +109 -0
- data/lib/hexapdf/task/optimize.rb +230 -0
- data/lib/hexapdf/task.rb +68 -0
- data/lib/hexapdf/tokenizer.rb +406 -0
- data/lib/hexapdf/type/catalog.rb +107 -0
- data/lib/hexapdf/type/embedded_file.rb +87 -0
- data/lib/hexapdf/type/file_specification.rb +232 -0
- data/lib/hexapdf/type/font.rb +81 -0
- data/lib/hexapdf/type/font_descriptor.rb +109 -0
- data/lib/hexapdf/type/font_simple.rb +190 -0
- data/lib/hexapdf/type/font_true_type.rb +47 -0
- data/lib/hexapdf/type/font_type1.rb +162 -0
- data/lib/hexapdf/type/form.rb +103 -0
- data/lib/hexapdf/type/graphics_state_parameter.rb +79 -0
- data/lib/hexapdf/type/image.rb +73 -0
- data/lib/hexapdf/type/info.rb +70 -0
- data/lib/hexapdf/type/names.rb +69 -0
- data/lib/hexapdf/type/object_stream.rb +224 -0
- data/lib/hexapdf/type/page.rb +355 -0
- data/lib/hexapdf/type/page_tree_node.rb +269 -0
- data/lib/hexapdf/type/resources.rb +212 -0
- data/lib/hexapdf/type/trailer.rb +128 -0
- data/lib/hexapdf/type/viewer_preferences.rb +73 -0
- data/lib/hexapdf/type/xref_stream.rb +204 -0
- data/lib/hexapdf/type.rb +67 -0
- data/lib/hexapdf/utils/bit_field.rb +87 -0
- data/lib/hexapdf/utils/bit_stream.rb +148 -0
- data/lib/hexapdf/utils/lru_cache.rb +65 -0
- data/lib/hexapdf/utils/math_helpers.rb +55 -0
- data/lib/hexapdf/utils/object_hash.rb +130 -0
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +93 -0
- data/lib/hexapdf/utils/sorted_tree_node.rb +339 -0
- data/lib/hexapdf/version.rb +39 -0
- data/lib/hexapdf/writer.rb +199 -0
- data/lib/hexapdf/xref_section.rb +152 -0
- data/lib/hexapdf.rb +34 -0
- data/man/man1/hexapdf.1 +249 -0
- data/test/data/aes-test-vectors/CBCGFSbox-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-256-encrypt.data.gz +0 -0
- data/test/data/fonts/Ubuntu-Title.ttf +0 -0
- data/test/data/images/cmyk.jpg +0 -0
- data/test/data/images/fillbytes.jpg +0 -0
- data/test/data/images/gray.jpg +0 -0
- data/test/data/images/greyscale-1bit.png +0 -0
- data/test/data/images/greyscale-2bit.png +0 -0
- data/test/data/images/greyscale-4bit.png +0 -0
- data/test/data/images/greyscale-8bit.png +0 -0
- data/test/data/images/greyscale-alpha-8bit.png +0 -0
- data/test/data/images/greyscale-trns-8bit.png +0 -0
- data/test/data/images/greyscale-with-gamma1.0.png +0 -0
- data/test/data/images/greyscale-with-gamma1.5.png +0 -0
- data/test/data/images/indexed-1bit.png +0 -0
- data/test/data/images/indexed-2bit.png +0 -0
- data/test/data/images/indexed-4bit.png +0 -0
- data/test/data/images/indexed-8bit.png +0 -0
- data/test/data/images/indexed-alpha-4bit.png +0 -0
- data/test/data/images/indexed-alpha-8bit.png +0 -0
- data/test/data/images/rgb.jpg +0 -0
- data/test/data/images/truecolour-8bit.png +0 -0
- data/test/data/images/truecolour-alpha-8bit.png +0 -0
- data/test/data/images/truecolour-gama-chrm-8bit.png +0 -0
- data/test/data/images/truecolour-srgb-8bit.png +0 -0
- data/test/data/minimal.pdf +44 -0
- data/test/data/standard-security-handler/README +9 -0
- data/test/data/standard-security-handler/bothpwd-aes-128bit-V4.pdf +44 -0
- data/test/data/standard-security-handler/bothpwd-aes-256bit-V5.pdf +0 -0
- data/test/data/standard-security-handler/bothpwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/bothpwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/bothpwd-arc4-40bit-V1.pdf +0 -0
- data/test/data/standard-security-handler/nopwd-aes-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-aes-256bit-V5.pdf +0 -0
- data/test/data/standard-security-handler/nopwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-arc4-40bit-V1.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-aes-128bit-V4.pdf +0 -0
- data/test/data/standard-security-handler/ownerpwd-aes-256bit-V5.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-40bit-V1.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-aes-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-aes-256bit-V5.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-arc4-128bit-V2.pdf +0 -0
- data/test/data/standard-security-handler/userpwd-arc4-128bit-V4.pdf +0 -0
- data/test/data/standard-security-handler/userpwd-arc4-40bit-V1.pdf +43 -0
- data/test/hexapdf/common_tokenizer_tests.rb +204 -0
- data/test/hexapdf/content/common.rb +31 -0
- data/test/hexapdf/content/graphic_object/test_arc.rb +93 -0
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +91 -0
- data/test/hexapdf/content/graphic_object/test_solid_arc.rb +86 -0
- data/test/hexapdf/content/test_canvas.rb +1113 -0
- data/test/hexapdf/content/test_color_space.rb +97 -0
- data/test/hexapdf/content/test_graphics_state.rb +138 -0
- data/test/hexapdf/content/test_operator.rb +619 -0
- data/test/hexapdf/content/test_parser.rb +66 -0
- data/test/hexapdf/content/test_processor.rb +156 -0
- data/test/hexapdf/content/test_transformation_matrix.rb +64 -0
- data/test/hexapdf/encryption/common.rb +87 -0
- data/test/hexapdf/encryption/test_aes.rb +121 -0
- data/test/hexapdf/encryption/test_arc4.rb +39 -0
- data/test/hexapdf/encryption/test_fast_aes.rb +17 -0
- data/test/hexapdf/encryption/test_fast_arc4.rb +12 -0
- data/test/hexapdf/encryption/test_identity.rb +21 -0
- data/test/hexapdf/encryption/test_ruby_aes.rb +23 -0
- data/test/hexapdf/encryption/test_ruby_arc4.rb +20 -0
- data/test/hexapdf/encryption/test_security_handler.rb +356 -0
- data/test/hexapdf/encryption/test_standard_security_handler.rb +274 -0
- data/test/hexapdf/filter/common.rb +53 -0
- data/test/hexapdf/filter/test_ascii85_decode.rb +60 -0
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +33 -0
- data/test/hexapdf/filter/test_encryption.rb +24 -0
- data/test/hexapdf/filter/test_flate_decode.rb +35 -0
- data/test/hexapdf/filter/test_lzw_decode.rb +52 -0
- data/test/hexapdf/filter/test_predictor.rb +183 -0
- data/test/hexapdf/filter/test_run_length_decode.rb +32 -0
- data/test/hexapdf/font/cmap/test_parser.rb +67 -0
- data/test/hexapdf/font/cmap/test_writer.rb +58 -0
- data/test/hexapdf/font/encoding/test_base.rb +35 -0
- data/test/hexapdf/font/encoding/test_difference_encoding.rb +21 -0
- data/test/hexapdf/font/encoding/test_glyph_list.rb +59 -0
- data/test/hexapdf/font/encoding/test_zapf_dingbats_encoding.rb +16 -0
- data/test/hexapdf/font/test_encoding.rb +27 -0
- data/test/hexapdf/font/test_true_type_wrapper.rb +110 -0
- data/test/hexapdf/font/test_type1_wrapper.rb +66 -0
- data/test/hexapdf/font/true_type/common.rb +19 -0
- data/test/hexapdf/font/true_type/table/test_cmap.rb +59 -0
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +133 -0
- data/test/hexapdf/font/true_type/table/test_directory.rb +35 -0
- data/test/hexapdf/font/true_type/table/test_glyf.rb +58 -0
- data/test/hexapdf/font/true_type/table/test_head.rb +76 -0
- data/test/hexapdf/font/true_type/table/test_hhea.rb +40 -0
- data/test/hexapdf/font/true_type/table/test_hmtx.rb +38 -0
- data/test/hexapdf/font/true_type/table/test_loca.rb +43 -0
- data/test/hexapdf/font/true_type/table/test_maxp.rb +62 -0
- data/test/hexapdf/font/true_type/table/test_name.rb +95 -0
- data/test/hexapdf/font/true_type/table/test_os2.rb +65 -0
- data/test/hexapdf/font/true_type/table/test_post.rb +89 -0
- data/test/hexapdf/font/true_type/test_font.rb +120 -0
- data/test/hexapdf/font/true_type/test_table.rb +41 -0
- data/test/hexapdf/font/type1/test_afm_parser.rb +51 -0
- data/test/hexapdf/font/type1/test_font.rb +68 -0
- data/test/hexapdf/font/type1/test_pfb_parser.rb +37 -0
- data/test/hexapdf/font_loader/test_from_configuration.rb +28 -0
- data/test/hexapdf/font_loader/test_standard14.rb +22 -0
- data/test/hexapdf/image_loader/test_jpeg.rb +83 -0
- data/test/hexapdf/image_loader/test_pdf.rb +47 -0
- data/test/hexapdf/image_loader/test_png.rb +258 -0
- data/test/hexapdf/task/test_dereference.rb +46 -0
- data/test/hexapdf/task/test_optimize.rb +137 -0
- data/test/hexapdf/test_configuration.rb +82 -0
- data/test/hexapdf/test_data_dir.rb +32 -0
- data/test/hexapdf/test_dictionary.rb +284 -0
- data/test/hexapdf/test_dictionary_fields.rb +185 -0
- data/test/hexapdf/test_document.rb +574 -0
- data/test/hexapdf/test_document_utils.rb +144 -0
- data/test/hexapdf/test_filter.rb +96 -0
- data/test/hexapdf/test_font_utils.rb +47 -0
- data/test/hexapdf/test_importer.rb +78 -0
- data/test/hexapdf/test_object.rb +177 -0
- data/test/hexapdf/test_parser.rb +394 -0
- data/test/hexapdf/test_rectangle.rb +36 -0
- data/test/hexapdf/test_reference.rb +41 -0
- data/test/hexapdf/test_revision.rb +139 -0
- data/test/hexapdf/test_revisions.rb +93 -0
- data/test/hexapdf/test_serializer.rb +169 -0
- data/test/hexapdf/test_stream.rb +262 -0
- data/test/hexapdf/test_tokenizer.rb +30 -0
- data/test/hexapdf/test_writer.rb +120 -0
- data/test/hexapdf/test_xref_section.rb +35 -0
- data/test/hexapdf/type/test_catalog.rb +30 -0
- data/test/hexapdf/type/test_embedded_file.rb +16 -0
- data/test/hexapdf/type/test_file_specification.rb +148 -0
- data/test/hexapdf/type/test_font.rb +35 -0
- data/test/hexapdf/type/test_font_descriptor.rb +51 -0
- data/test/hexapdf/type/test_font_simple.rb +190 -0
- data/test/hexapdf/type/test_font_type1.rb +128 -0
- data/test/hexapdf/type/test_form.rb +60 -0
- data/test/hexapdf/type/test_info.rb +14 -0
- data/test/hexapdf/type/test_names.rb +9 -0
- data/test/hexapdf/type/test_object_stream.rb +84 -0
- data/test/hexapdf/type/test_page.rb +260 -0
- data/test/hexapdf/type/test_page_tree_node.rb +255 -0
- data/test/hexapdf/type/test_resources.rb +167 -0
- data/test/hexapdf/type/test_trailer.rb +109 -0
- data/test/hexapdf/type/test_xref_stream.rb +131 -0
- data/test/hexapdf/utils/test_bit_field.rb +47 -0
- data/test/hexapdf/utils/test_lru_cache.rb +22 -0
- data/test/hexapdf/utils/test_object_hash.rb +115 -0
- data/test/hexapdf/utils/test_pdf_doc_encoding.rb +18 -0
- data/test/hexapdf/utils/test_sorted_tree_node.rb +232 -0
- data/test/test_helper.rb +56 -0
- metadata +427 -0
@@ -0,0 +1,148 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'stringio'
|
6
|
+
require 'hexapdf/type/file_specification'
|
7
|
+
require 'hexapdf/document'
|
8
|
+
|
9
|
+
describe HexaPDF::Type::FileSpecification::EFDictionary do
|
10
|
+
it "uses a custom type" do
|
11
|
+
obj = HexaPDF::Type::FileSpecification::EFDictionary.new({})
|
12
|
+
assert_equal(:XXFilespecEFDictionary, obj.type)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe HexaPDF::Type::FileSpecification do
|
17
|
+
before do
|
18
|
+
@doc = HexaPDF::Document.new
|
19
|
+
@obj = HexaPDF::Type::FileSpecification.new({}, document: @doc)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can be asked whether it is a URL or a file" do
|
23
|
+
refute(@obj.url?)
|
24
|
+
@obj[:FS] = :URL
|
25
|
+
assert(@obj.url?)
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "path" do
|
29
|
+
it "returns the first useable file spec string" do
|
30
|
+
@obj[:DOS] = 'hälo'.b
|
31
|
+
assert_equal('hälo'.b, @obj.path)
|
32
|
+
|
33
|
+
@obj[:UF] = 'hälo'
|
34
|
+
assert_equal('hälo', @obj.path)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "unescapes the path string according to the PDF spec" do
|
38
|
+
@obj[:F] = "dir/in\\/out\\too"
|
39
|
+
assert_equal('dir/in/out/too', @obj.path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "path=" do
|
44
|
+
it "only sets /UF and /F, deleting /Mac, /Unix, /DOS entries if they exist" do
|
45
|
+
@obj[:Unix] = @obj[:Mac] = @obj[:DOS] = 'a'
|
46
|
+
@obj.path = 'file/test'
|
47
|
+
assert_equal('file/test', @obj[:UF])
|
48
|
+
assert_equal('file/test', @obj[:F])
|
49
|
+
refute(@obj.key?(:Unix))
|
50
|
+
refute(@obj.key?(:Mac))
|
51
|
+
refute(@obj.key?(:DOS))
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'resets the /FS value' do
|
55
|
+
@obj[:FS] = :Something
|
56
|
+
@obj.path = 'file'
|
57
|
+
refute(@obj.key?(:FS))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "url=" do
|
62
|
+
it "sets the path and the file system entry" do
|
63
|
+
url = 'http://example.com/some?test=ing#done'
|
64
|
+
@obj.url = url
|
65
|
+
assert_equal(url, @obj.path)
|
66
|
+
assert(@obj.url?)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "fails if the provided string is not a valid URL" do
|
70
|
+
assert_raises(HexaPDF::Error) { @obj.url = "a false \\ URL" }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "embedded_file?" do
|
75
|
+
it "checks whether the specification has an embedded file" do
|
76
|
+
refute(@obj.embedded_file?)
|
77
|
+
@obj[:EF] = {UF: {}}
|
78
|
+
assert(@obj.embedded_file?)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "embedded_file_stream" do
|
83
|
+
it "returns the associated embedded file stream" do
|
84
|
+
assert_nil(@obj.embedded_file_stream)
|
85
|
+
@obj[:EF] = {F: 'data'}
|
86
|
+
assert_equal('data', @obj.embedded_file_stream)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "embed/unembed" do
|
91
|
+
before do
|
92
|
+
@file = Tempfile.new('file-embed-test')
|
93
|
+
@file.write("embed-test")
|
94
|
+
@file.close
|
95
|
+
end
|
96
|
+
|
97
|
+
after do
|
98
|
+
@file.unlink
|
99
|
+
end
|
100
|
+
|
101
|
+
it "requires the name argument when given an IO object" do
|
102
|
+
assert_raises(ArgumentError) { @obj.embed(StringIO.new) }
|
103
|
+
end
|
104
|
+
|
105
|
+
it "embeds the given file and registers it with the global name registry" do
|
106
|
+
stream = @obj.embed(@file.path)
|
107
|
+
assert_equal(stream, @obj[:EF][:UF])
|
108
|
+
assert_equal(stream, @obj[:EF][:F])
|
109
|
+
assert_equal(File.basename(@file.path), @obj.path)
|
110
|
+
assert_equal(@obj, @doc.catalog[:Names][:EmbeddedFiles].find_entry(@obj.path))
|
111
|
+
assert_equal(:FlateDecode, stream[:Filter])
|
112
|
+
assert_equal('embed-test', stream.stream)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "embeds the given IO object" do
|
116
|
+
@file.open
|
117
|
+
stream = @obj.embed(@file, name: 'test')
|
118
|
+
assert_equal('embed-test', stream.stream)
|
119
|
+
|
120
|
+
stream = @obj.embed(StringIO.new('test'), name: 'test')
|
121
|
+
assert_equal('test', stream.stream)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "allows overriding the name" do
|
125
|
+
@obj.embed(@file.path, name: 'test')
|
126
|
+
assert_equal('test', @obj.path)
|
127
|
+
assert_equal(@obj, @doc.catalog[:Names][:EmbeddedFiles].find_entry('test'))
|
128
|
+
end
|
129
|
+
|
130
|
+
it "doesn't register the embedded file if instructed to do so" do
|
131
|
+
@obj.embed(@file.path, name: 'test', register: false)
|
132
|
+
assert_nil(@doc.catalog[:Names])
|
133
|
+
end
|
134
|
+
|
135
|
+
it "replaces the value of an already registered name" do
|
136
|
+
(@doc.catalog[:Names] ||= {})[:EmbeddedFiles] = {}
|
137
|
+
@doc.catalog[:Names][:EmbeddedFiles].add_entry('test', 'data')
|
138
|
+
@obj.embed(@file.path, name: 'test')
|
139
|
+
assert_equal(@obj, @doc.catalog[:Names][:EmbeddedFiles].find_entry('test'))
|
140
|
+
end
|
141
|
+
|
142
|
+
it "unembeds an already embedded file before embedding the new one" do
|
143
|
+
@obj.embed(@file.path, name: 'test1')
|
144
|
+
@obj.embed(@file.path, name: 'test2')
|
145
|
+
assert_equal([['test2', @obj]], @doc.catalog[:Names][:EmbeddedFiles].each_entry.to_a)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/type/font'
|
6
|
+
|
7
|
+
describe HexaPDF::Type::Font do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
cmap = @doc.add({}, stream: <<-EOF)
|
11
|
+
2 beginbfchar
|
12
|
+
<20> <0041>
|
13
|
+
<22> <0042>
|
14
|
+
endbfchar
|
15
|
+
EOF
|
16
|
+
@font = @doc.add({Type: :Font, BaseFont: :TestFont, ToUnicode: cmap})
|
17
|
+
end
|
18
|
+
|
19
|
+
it "must always be an indirect" do
|
20
|
+
assert(@font.must_be_indirect?)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "to_utf" do
|
24
|
+
it "uses the /ToUnicode CMap if it is available" do
|
25
|
+
assert_equal("A", @font.to_utf8(32))
|
26
|
+
assert_equal("B", @font.to_utf8(34))
|
27
|
+
assert_equal("", @font.to_utf8(0))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns an empty string if no /ToUnicode CMap is available" do
|
31
|
+
@font.delete(:ToUnicode)
|
32
|
+
assert_equal("", @font.to_utf8(32))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/type/font_descriptor'
|
6
|
+
|
7
|
+
describe HexaPDF::Type::FontDescriptor do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
@font_desc = @doc.add(Type: :FontDescriptor, FontName: :Test, Flags: 0b1001001, ItalicAngle: 10)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "flags" do
|
14
|
+
it "returns all flags" do
|
15
|
+
assert_equal([:fixed_pitch, :script, :italic], @font_desc.flags)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "flagged?" do
|
20
|
+
it "returns true if the given flag is set" do
|
21
|
+
assert(@font_desc.flagged?(:fixed_pitch))
|
22
|
+
refute(@font_desc.flagged?(:serif))
|
23
|
+
end
|
24
|
+
|
25
|
+
it "raises an error if an unknown flag name is provided" do
|
26
|
+
assert_raises(ArgumentError) { @font_desc.flagged?(:unknown) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "flag" do
|
31
|
+
it "sets the given flag bits" do
|
32
|
+
@font_desc.flag(:serif)
|
33
|
+
assert_equal([:fixed_pitch, :serif, :script, :italic], @font_desc.flags)
|
34
|
+
@font_desc.flag(:symbolic, clear_existing: true)
|
35
|
+
assert_equal([:symbolic], @font_desc.flags)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "validation" do
|
40
|
+
it "fails if more than one of /FontFile{,2,3} are set" do
|
41
|
+
assert(@font_desc.validate {|*args| p args})
|
42
|
+
@font_desc[:FontFile] = @font_desc[:FontFile2] = @doc.add({}, stream: 'test')
|
43
|
+
refute(@font_desc.validate)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "fails if /Descent is not a negative number" do
|
47
|
+
@font_desc[:Descent] = 5
|
48
|
+
refute(@font_desc.validate)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/type/font_simple'
|
6
|
+
|
7
|
+
describe HexaPDF::Type::FontSimple do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
cmap = @doc.add({}, stream: <<-EOF)
|
11
|
+
2 beginbfchar
|
12
|
+
<20> <0041>
|
13
|
+
<22> <0042>
|
14
|
+
endbfchar
|
15
|
+
EOF
|
16
|
+
font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
|
17
|
+
FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
|
18
|
+
Descent: -100, CapHeight: 800, StemV: 20)
|
19
|
+
@font = @doc.add({Type: :Font, Encoding: :WinAnsiEncoding,
|
20
|
+
BaseFont: :Embedded, FontDescriptor: font_descriptor, ToUnicode: cmap,
|
21
|
+
FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]
|
22
|
+
}, type: HexaPDF::Type::FontSimple)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "encoding" do
|
26
|
+
it "fails if /Encoding is absent because encoding_from_font is not implemented" do
|
27
|
+
@font.delete(:Encoding)
|
28
|
+
assert_raises(NotImplementedError) { @font.encoding }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "/Encoding is a name" do
|
32
|
+
it "returns a predefined encoding if /Encoding specifies one" do
|
33
|
+
assert_equal(HexaPDF::Font::Encoding.for_name(:WinAnsiEncoding), @font.encoding)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "fails if /Encoding is an invalid name because encoding_from_font is not implemented" do
|
37
|
+
@font[:Encoding] = :SomethingUnknown
|
38
|
+
assert_raises(NotImplementedError) { @font.encoding }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "/Encoding is a dictionary" do
|
43
|
+
before do
|
44
|
+
@font[:Encoding] = {}
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "no /BaseEncoding is specified" do
|
48
|
+
it "fails if the font is embedded because encoding_from_font is not implemented" do
|
49
|
+
@font[:FontDescriptor][:FontFile] = 5
|
50
|
+
assert_raises(NotImplementedError) { @font.encoding }
|
51
|
+
end
|
52
|
+
|
53
|
+
it "fails for a symbolic non-embedded font because encoding_from_font is not implemented" do
|
54
|
+
@font[:FontDescriptor].flag(:symbolic, clear_existing: true)
|
55
|
+
assert_raises(NotImplementedError) { @font.encoding }
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns the StandardEncoding for a non-symbolic non-embedded font" do
|
59
|
+
@font[:FontDescriptor].flag(clear_existing: true)
|
60
|
+
assert_equal(HexaPDF::Font::Encoding.for_name(:StandardEncoding), @font.encoding)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "returns the encoding specified by /BaseEncoding" do
|
65
|
+
@font[:Encoding] = {BaseEncoding: :WinAnsiEncoding}
|
66
|
+
assert_equal(HexaPDF::Font::Encoding.for_name(:WinAnsiEncoding), @font.encoding)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "fails if /BaseEncoding is invalid because encoding_from_font is not implemented" do
|
70
|
+
@font[:Encoding] = {BaseEncoding: :SomethingUnknown}
|
71
|
+
assert_raises(NotImplementedError) { @font.encoding }
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns a difference encoding if /Differences is specified" do
|
75
|
+
@font[:FontDescriptor].flag(clear_existing: true)
|
76
|
+
@font[:Encoding][:Differences] = [32, :A, :B, 34, :Z]
|
77
|
+
refute_equal(HexaPDF::Font::Encoding.for_name(:StandardEncoding), @font.encoding)
|
78
|
+
assert_equal(:A, @font.encoding.name(32))
|
79
|
+
assert_equal(:B, @font.encoding.name(33))
|
80
|
+
assert_equal(:Z, @font.encoding.name(34))
|
81
|
+
end
|
82
|
+
|
83
|
+
it "fails if the /Differences array contains invalid data" do
|
84
|
+
@font[:Encoding][:BaseEncoding] = :WinAnsiEncoding
|
85
|
+
@font[:Encoding][:Differences] = [:B, 32, :A, :B, 34, :Z]
|
86
|
+
assert_raises(HexaPDF::Error) { @font.encoding }
|
87
|
+
|
88
|
+
@font[:Encoding][:Differences] = [32, "data", :A, :B, 34, :Z]
|
89
|
+
assert_raises(HexaPDF::Error) { @font.encoding }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it "fails if /Encoding contains an invalid value" do
|
94
|
+
@font[:Encoding] = 5
|
95
|
+
assert_raises(HexaPDF::Error) { @font.encoding }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "decode" do
|
100
|
+
it "just returns the bytes of the string since this is a simple 1-byte-per-code font" do
|
101
|
+
assert_equal([65, 66], @font.decode("AB"))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "to_utf" do
|
106
|
+
it "uses a /ToUnicode CMap if it is available" do
|
107
|
+
assert_equal("A", @font.to_utf8(32))
|
108
|
+
end
|
109
|
+
|
110
|
+
it "uses the font's encoding to map the code to an UTF-8 string if the /ToUnicode is missing" do
|
111
|
+
@font.delete(:ToUnicode)
|
112
|
+
assert_equal(" ", @font.to_utf8(32))
|
113
|
+
end
|
114
|
+
|
115
|
+
it "returns an empty string if no correct mapping could be found" do
|
116
|
+
@font.delete(:ToUnicode)
|
117
|
+
assert_equal("", @font.to_utf8(0))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "writing_mode" do
|
122
|
+
it "is always horizontal" do
|
123
|
+
assert_equal(:horizontal, @font.writing_mode)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "width" do
|
128
|
+
it "returns the glyph width for a valid code point" do
|
129
|
+
assert_equal(600, @font.width(32))
|
130
|
+
end
|
131
|
+
|
132
|
+
it "returns the /MissingWidth of a /FontDescriptor if available and the width was not found" do
|
133
|
+
assert_equal(0, @font.width(0))
|
134
|
+
@font[:FontDescriptor][:MissingWidth] = 99
|
135
|
+
assert_equal(99, @font.width(0))
|
136
|
+
end
|
137
|
+
|
138
|
+
it "returns 0 for a missing code point when FontDescriptor is not available" do
|
139
|
+
@font.delete(:FontDescriptor)
|
140
|
+
assert_equal(0, @font.width(0))
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "bounding_box" do
|
145
|
+
it "returns the bounding box" do
|
146
|
+
assert_equal([0, 1, 2, 3], @font.bounding_box)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "returns nil if no bounding box information can be found" do
|
150
|
+
@font[:FontDescriptor].delete(:FontBBox)
|
151
|
+
assert_nil(@font.bounding_box)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "embedded" do
|
156
|
+
it "returns true if the font is embedded" do
|
157
|
+
refute(@font.embedded?)
|
158
|
+
@font[:FontDescriptor][:FontFile] = 5
|
159
|
+
assert(@font.embedded?)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "symbolic?" do
|
164
|
+
it "return true if the font is symbolic" do
|
165
|
+
@font[:FontDescriptor].flag(clear_existing: true)
|
166
|
+
refute(@font.symbolic?)
|
167
|
+
|
168
|
+
@font[:FontDescriptor].flag(:symbolic)
|
169
|
+
assert(@font.symbolic?)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "returns nil if it cannot be determined whether the font is symbolic" do
|
173
|
+
@font.delete(:FontDescriptor)
|
174
|
+
assert_nil(@font.symbolic?)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "validation" do
|
179
|
+
it "validates the existence of required keys" do
|
180
|
+
assert(@font.validate)
|
181
|
+
@font.delete(:FirstChar)
|
182
|
+
refute(@font.validate)
|
183
|
+
end
|
184
|
+
|
185
|
+
it "validates the lengths of the /Widths field" do
|
186
|
+
@font[:Widths] = [65]
|
187
|
+
refute(@font.validate)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/type/font_type1'
|
6
|
+
|
7
|
+
describe HexaPDF::Type::FontType1::StandardFonts do
|
8
|
+
before do
|
9
|
+
@obj = HexaPDF::Type::FontType1::StandardFonts
|
10
|
+
end
|
11
|
+
|
12
|
+
it "checks whether a given name corresponds to a standard font via #standard_font?" do
|
13
|
+
assert(@obj.standard_font?(:"Times-Roman"))
|
14
|
+
assert(@obj.standard_font?(:TimesNewRoman))
|
15
|
+
refute(@obj.standard_font?(:LibreSans))
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns the standard PDF name for an alias via #standard_name" do
|
19
|
+
assert_equal(:"Times-Roman", @obj.standard_name(:TimesNewRoman))
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "font" do
|
23
|
+
it "returns the Type1 font object for a given standard name" do
|
24
|
+
font = @obj.font(:"Times-Roman")
|
25
|
+
assert_equal("Times Roman", font.full_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "caches the font for reuse" do
|
29
|
+
font = @obj.font(:"Times-Roman")
|
30
|
+
assert_same(font, @obj.font(:"Times-Roman"))
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns nil if the given name doesn't belong to a standard font" do
|
34
|
+
refute_nil(@obj.font(:TimesNewRoman))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe HexaPDF::Type::FontType1 do
|
40
|
+
before do
|
41
|
+
@doc = HexaPDF::Document.new
|
42
|
+
@font = @doc.add(Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
|
43
|
+
BaseFont: :"Times-Roman")
|
44
|
+
|
45
|
+
font_file = @doc.add({}, stream: <<-EOF)
|
46
|
+
/Encoding 256 array
|
47
|
+
0 1 255 {1 index exch /.notdef put} for
|
48
|
+
dup 32 /A put
|
49
|
+
dup 34 /B put
|
50
|
+
readonly def
|
51
|
+
EOF
|
52
|
+
font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
|
53
|
+
FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
|
54
|
+
Descent: -100, CapHeight: 800, StemV: 20, FontFile: font_file)
|
55
|
+
@embedded_font = @doc.add(Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
|
56
|
+
BaseFont: :Embedded, FontDescriptor: font_descriptor,
|
57
|
+
FirstChar: 32, LastChar: 34, Widths: [600, 0, 700])
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "encoding" do
|
61
|
+
it "returns the the standard font's encoding" do
|
62
|
+
@font.delete(:Encoding)
|
63
|
+
assert_equal(HexaPDF::Font::Encoding.for_name(:StandardEncoding), @font.encoding)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "uses the encoding of the embedded font when necessary" do
|
67
|
+
@embedded_font.delete(:Encoding)
|
68
|
+
assert_equal({32 => :A, 34 => :B}, @embedded_font.encoding.code_to_name)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "fails if the encoding needs to be read from the font but is is not embedded" do
|
72
|
+
@embedded_font.delete(:Encoding)
|
73
|
+
@embedded_font[:FontDescriptor].delete(:FontFile)
|
74
|
+
assert_raises(HexaPDF::Error) { @embedded_font.encoding }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "width" do
|
79
|
+
it "returns the glyph width when using a standard font" do
|
80
|
+
assert_equal(250, @font.width(32))
|
81
|
+
end
|
82
|
+
|
83
|
+
it "defers to its superclass for all other cases" do
|
84
|
+
assert_equal(600, @embedded_font.width(32))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "bounding_box" do
|
89
|
+
it "returns the bounding box for a standard font" do
|
90
|
+
font = HexaPDF::Type::FontType1::StandardFonts.font(:"Times-Roman")
|
91
|
+
assert_equal(font.bounding_box, @font.bounding_box)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "defers to its superclass for all other cases" do
|
95
|
+
assert_equal([0, 1, 2, 3], @embedded_font.bounding_box)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns nil for non-standard fonts without bounding box information" do
|
99
|
+
@embedded_font[:FontDescriptor].delete(:FontBBox)
|
100
|
+
assert_nil(@embedded_font.bounding_box)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "symbolic?" do
|
105
|
+
it "return true for the standard fonts Symbol and ZapfDingbats" do
|
106
|
+
@font[:BaseFont] = :Symbol
|
107
|
+
assert(@font.symbolic?)
|
108
|
+
|
109
|
+
@font[:BaseFont] = :ZapfDingbats
|
110
|
+
assert(@font.symbolic?)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "defers to its superclass for all other cases" do
|
114
|
+
assert(@embedded_font.symbolic?)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns nil if it cannot be determined whether the font is symbolic" do
|
118
|
+
@embedded_font.delete(:FontDescriptor)
|
119
|
+
assert_nil(@embedded_font.symbolic?)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "validation" do
|
124
|
+
it "allows empty fields for standard fonts" do
|
125
|
+
assert(@font.validate)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require_relative '../content/common'
|
5
|
+
require 'hexapdf/document'
|
6
|
+
require 'hexapdf/type/form'
|
7
|
+
|
8
|
+
describe HexaPDF::Type::Form do
|
9
|
+
before do
|
10
|
+
@doc = HexaPDF::Document.new
|
11
|
+
@form = @doc.wrap({}, subtype: :Form)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "box" do
|
15
|
+
it "returns the /BBox entry" do
|
16
|
+
@form[:BBox] = :media
|
17
|
+
assert_equal(:media, @form.box)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "contents" do
|
22
|
+
it "returns a duplicate of the stream" do
|
23
|
+
@form.stream = 'test'
|
24
|
+
assert_equal(@form.stream, @form.contents)
|
25
|
+
@form.contents.gsub!(/test/, 'other')
|
26
|
+
assert_equal(@form.stream, @form.contents)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "contents=" do
|
31
|
+
it "set the stream contents" do
|
32
|
+
@form.contents = 'test'
|
33
|
+
assert_equal('test', @form.stream)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "resources" do
|
38
|
+
it "creates the resource dictionary if it is not found" do
|
39
|
+
resources = @form.resources
|
40
|
+
assert_equal(:XXResources, resources.type)
|
41
|
+
assert_equal({}, resources.value)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns the already used resource dictionary" do
|
45
|
+
@form[:Resources] = {Font: nil}
|
46
|
+
resources = @form.resources
|
47
|
+
assert_equal(:XXResources, resources.type)
|
48
|
+
assert_equal(@form[:Resources], resources)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "process_contents" do
|
53
|
+
it "parses the contents and processes it" do
|
54
|
+
@form.stream = '10 w'
|
55
|
+
processor = TestHelper::OperatorRecorder.new
|
56
|
+
@form.process_contents(processor)
|
57
|
+
assert_equal([[:set_line_width, [10]]], processor.recorded_ops)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'hexapdf/type/info'
|
3
|
+
|
4
|
+
describe HexaPDF::Type::Info do
|
5
|
+
it "must always be indirect" do
|
6
|
+
obj = HexaPDF::Type::Info.new({})
|
7
|
+
assert(obj.must_be_indirect?)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "uses a custom type" do
|
11
|
+
obj = HexaPDF::Type::Info.new({})
|
12
|
+
assert_equal(:XXInfo, obj.type)
|
13
|
+
end
|
14
|
+
end
|