hexapdf 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/font/true_type/table/head'
|
6
|
+
require 'hexapdf/font/true_type/table/loca'
|
7
|
+
|
8
|
+
describe HexaPDF::Font::TrueType::Table::Loca do
|
9
|
+
before do
|
10
|
+
@file = Object.new
|
11
|
+
@file.define_singleton_method(:io) { @io ||= StringIO.new('') }
|
12
|
+
head = HexaPDF::Font::TrueType::Table::Head.new(@file)
|
13
|
+
head.index_to_loc_format = 0
|
14
|
+
@file.define_singleton_method(:[]) {|_arg| head }
|
15
|
+
@entry = HexaPDF::Font::TrueType::Table::Directory::Entry.new('loca', 0, 0, @file.io.length)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "initialize" do
|
19
|
+
it "reads the data in short format from the associated file" do
|
20
|
+
@file.io.string = [0, 10, 30, 50, 90].pack('n*')
|
21
|
+
@entry.length = @file.io.length
|
22
|
+
table = HexaPDF::Font::TrueType::Table::Loca.new(@file, @entry)
|
23
|
+
assert_equal([0, 20, 60, 100, 180], table.offsets)
|
24
|
+
assert_equal(0, table.offset(0))
|
25
|
+
assert_equal(100, table.offset(3))
|
26
|
+
assert_equal(20, table.length(0))
|
27
|
+
assert_equal(80, table.length(3))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "reads the data in long format from the associated file" do
|
31
|
+
@file.io.string = [0, 10, 30, 50, 90].pack('N*')
|
32
|
+
@file[:head].index_to_loc_format = 1
|
33
|
+
@entry.length = @file.io.length
|
34
|
+
table = HexaPDF::Font::TrueType::Table::Loca.new(@file, @entry)
|
35
|
+
assert_equal([0, 10, 30, 50, 90], table.offsets)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "loads some default values if no entry is given" do
|
39
|
+
table = HexaPDF::Font::TrueType::Table::Loca.new(@file)
|
40
|
+
assert_equal([], table.offsets)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/font/true_type/table/maxp'
|
6
|
+
|
7
|
+
describe HexaPDF::Font::TrueType::Table::Maxp do
|
8
|
+
before do
|
9
|
+
data = [1, 0, 10, 11, 12, 13, 14, 2, 15, 16, 17, 18, 19, 20, 21, 22].pack('n*')
|
10
|
+
io = StringIO.new(data)
|
11
|
+
@file = Object.new
|
12
|
+
@file.define_singleton_method(:io) { io }
|
13
|
+
@entry = HexaPDF::Font::TrueType::Table::Directory::Entry.new('hhea', 0, 0, io.length)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "initialize" do
|
17
|
+
it "reads the version 1.0 data from the associated file" do
|
18
|
+
table = HexaPDF::Font::TrueType::Table::Maxp.new(@file, @entry)
|
19
|
+
assert_equal(1, table.version)
|
20
|
+
assert_equal(10, table.num_glyphs)
|
21
|
+
assert_equal(11, table.max_points)
|
22
|
+
assert_equal(12, table.max_contours)
|
23
|
+
assert_equal(13, table.max_component_points)
|
24
|
+
assert_equal(14, table.max_component_contours)
|
25
|
+
assert_equal(15, table.max_twilight_points)
|
26
|
+
assert_equal(16, table.max_storage)
|
27
|
+
assert_equal(17, table.max_function_defs)
|
28
|
+
assert_equal(18, table.max_instruction_defs)
|
29
|
+
assert_equal(19, table.max_stack_elements)
|
30
|
+
assert_equal(20, table.max_size_of_instructions)
|
31
|
+
assert_equal(21, table.max_component_elements)
|
32
|
+
assert_equal(22, table.max_component_depth)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "reads the version 0.5 data from the associated file" do
|
36
|
+
@file.io.string = [0, 0x5000, 10].pack('n*')
|
37
|
+
@entry.length = @file.io.length
|
38
|
+
table = HexaPDF::Font::TrueType::Table::Maxp.new(@file, @entry)
|
39
|
+
assert_equal(0.3125, table.version)
|
40
|
+
assert_equal(10, table.num_glyphs)
|
41
|
+
assert_nil(table.max_points)
|
42
|
+
assert_nil(table.max_contours)
|
43
|
+
assert_nil(table.max_component_points)
|
44
|
+
assert_nil(table.max_component_contours)
|
45
|
+
assert_nil(table.max_twilight_points)
|
46
|
+
assert_nil(table.max_storage)
|
47
|
+
assert_nil(table.max_function_defs)
|
48
|
+
assert_nil(table.max_instruction_defs)
|
49
|
+
assert_nil(table.max_stack_elements)
|
50
|
+
assert_nil(table.max_size_of_instructions)
|
51
|
+
assert_nil(table.max_component_elements)
|
52
|
+
assert_nil(table.max_component_depth)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "loads some default values if no entry is given" do
|
56
|
+
table = HexaPDF::Font::TrueType::Table::Maxp.new(@file)
|
57
|
+
assert_equal(1, table.version)
|
58
|
+
assert_equal(0, table.num_glyphs)
|
59
|
+
assert_equal(0, table.max_points)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/font/true_type/table/name'
|
6
|
+
|
7
|
+
describe HexaPDF::Font::TrueType::Table::Name do
|
8
|
+
before do
|
9
|
+
@file = Object.new
|
10
|
+
@file.define_singleton_method(:io) { @io ||= StringIO.new(''.b) }
|
11
|
+
|
12
|
+
@file.io.string = [0, 3, 42].pack('n3')
|
13
|
+
@file.io.string << [1, 0, 0, 0, 4, 0].pack('n6')
|
14
|
+
@file.io.string << [0, 3, 1, 0, 8, 4].pack('n6')
|
15
|
+
@file.io.string << [0, 3, 2, 1, 14, 12].pack('n6')
|
16
|
+
@file.io.string << 'hexa'.encode('MACROMAN').b << 'hexa'.encode('UTF-16BE').b <<
|
17
|
+
'hexapdf'.encode('UTF-16BE').b
|
18
|
+
|
19
|
+
@entry = HexaPDF::Font::TrueType::Table::Directory::Entry.new('name', 0, 0, @file.io.length)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "initialize" do
|
23
|
+
it "reads the data in format 0 from the associated file" do
|
24
|
+
table = HexaPDF::Font::TrueType::Table::Name.new(@file, @entry)
|
25
|
+
assert_equal(0, table.format)
|
26
|
+
assert_equal({}, table.language_tags)
|
27
|
+
assert_equal('hexa', table[:copyright][0])
|
28
|
+
assert_equal(1, table[:copyright][0].platform_id)
|
29
|
+
assert_equal(0, table[:copyright][0].encoding_id)
|
30
|
+
assert_equal(0, table[:copyright][0].language_id)
|
31
|
+
assert_equal('hexa', table[:copyright][1])
|
32
|
+
assert_equal(0, table[:copyright][1].platform_id)
|
33
|
+
assert_equal(3, table[:copyright][1].encoding_id)
|
34
|
+
assert_equal(1, table[:copyright][1].language_id)
|
35
|
+
assert_equal('hexapdf', table[:font_family][0])
|
36
|
+
assert_equal(0, table[:font_family][0].platform_id)
|
37
|
+
assert_equal(3, table[:font_family][0].encoding_id)
|
38
|
+
assert_equal(2, table[:font_family][0].language_id)
|
39
|
+
assert_equal(table[:copyright][0], table[:copyright].preferred_record)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "reads the data in format 1 from the associated file" do
|
43
|
+
@file.io.string[0, 6] = [1, 3, 52].pack('n3')
|
44
|
+
@file.io.string[42, 0] = [2, 4, 26, 4, 30].pack('n*')
|
45
|
+
@file.io.string << 'ende'.encode('UTF-16BE').b
|
46
|
+
table = HexaPDF::Font::TrueType::Table::Name.new(@file, @entry)
|
47
|
+
assert_equal(1, table.format)
|
48
|
+
assert_equal({0x8000 => 'en', 0x8001 => 'de'}, table.language_tags)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "loads some default values if no entry is given" do
|
52
|
+
table = HexaPDF::Font::TrueType::Table::Name.new(@file)
|
53
|
+
assert_equal(0, table.format)
|
54
|
+
assert_equal({}, table.records)
|
55
|
+
assert_equal({}, table.language_tags)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "add" do
|
60
|
+
it "adds a new record for a name" do
|
61
|
+
table = HexaPDF::Font::TrueType::Table::Name.new(@file)
|
62
|
+
table.add(:postscript_name, "test")
|
63
|
+
record = table[:postscript_name][0]
|
64
|
+
assert_equal("test", record)
|
65
|
+
assert_equal(HexaPDF::Font::TrueType::Table::Name::Record::PLATFORM_MACINTOSH, record.platform_id)
|
66
|
+
assert_equal(0, record.encoding_id)
|
67
|
+
assert_equal(0, record.language_id)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "NameRecord" do
|
72
|
+
before do
|
73
|
+
@table = HexaPDF::Font::TrueType::Table::Name.new(@file, @entry)
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "platform?" do
|
77
|
+
it "returns the correct value" do
|
78
|
+
assert(@table[:copyright][0].platform?(:macintosh))
|
79
|
+
assert(@table[:copyright][1].platform?(:unicode))
|
80
|
+
refute(@table[:copyright][0].platform?(:microsoft))
|
81
|
+
end
|
82
|
+
|
83
|
+
it "raises an error when called with an unknown identifier" do
|
84
|
+
assert_raises(ArgumentError) { @table[:copyright][0].platform?(:testing) }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "preferred?" do
|
89
|
+
it "returns true for names in US English that had been converted to UTF-8" do
|
90
|
+
assert(@table[:copyright][0].preferred?)
|
91
|
+
refute(@table[:copyright][1].preferred?)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/font/true_type/table/os2'
|
6
|
+
|
7
|
+
describe HexaPDF::Font::TrueType::Table::OS2 do
|
8
|
+
before do
|
9
|
+
data = [5, -1, 2, 3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15,
|
10
|
+
'PANOSPANOS', 16, 17, 'VEND', 16, 17, 18, -19, -20, -21, 22, 23, 24, -25, -26,
|
11
|
+
27, 28, 29, 30, 31].pack('ns>n2s>12a10Q>2a4n3s>3n2Q>s>2n5')
|
12
|
+
@file = Object.new
|
13
|
+
@file.define_singleton_method(:io) { @io ||= StringIO.new(data) }
|
14
|
+
@entry = HexaPDF::Font::TrueType::Table::Directory::Entry.new('OS/2', 0, 0, @file.io.length)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "initialize" do
|
18
|
+
it "reads the data from the associated file" do
|
19
|
+
table = HexaPDF::Font::TrueType::Table::OS2.new(@file, @entry)
|
20
|
+
assert_equal(5, table.version)
|
21
|
+
assert_equal(-1, table.x_avg_char_width)
|
22
|
+
assert_equal(200, table.weight_class)
|
23
|
+
assert_equal(3, table.width_class)
|
24
|
+
assert_equal(-4, table.type)
|
25
|
+
assert_equal(-5, table.subscript_x_size)
|
26
|
+
assert_equal(-6, table.subscript_y_size)
|
27
|
+
assert_equal(-7, table.subscript_x_offset)
|
28
|
+
assert_equal(-8, table.subscript_y_offset)
|
29
|
+
assert_equal(-9, table.superscript_x_size)
|
30
|
+
assert_equal(-10, table.superscript_y_size)
|
31
|
+
assert_equal(-11, table.superscript_x_offset)
|
32
|
+
assert_equal(-12, table.superscript_y_offset)
|
33
|
+
assert_equal(-13, table.strikeout_size)
|
34
|
+
assert_equal(-14, table.strikeout_position)
|
35
|
+
assert_equal(-15, table.family_class)
|
36
|
+
assert_equal('PANOSPANOS'.b, table.panose)
|
37
|
+
assert_equal(16 << 64 & 17, table.unicode_range)
|
38
|
+
assert_equal('VEND'.b, table.vendor_id)
|
39
|
+
assert_equal(16, table.selection)
|
40
|
+
assert_equal(17, table.first_char_index)
|
41
|
+
assert_equal(18, table.last_char_index)
|
42
|
+
assert_equal(-19, table.typo_ascender)
|
43
|
+
assert_equal(-20, table.typo_descender)
|
44
|
+
assert_equal(-21, table.typo_line_gap)
|
45
|
+
assert_equal(22, table.win_ascent)
|
46
|
+
assert_equal(23, table.win_descent)
|
47
|
+
assert_equal(24, table.code_page_range)
|
48
|
+
assert_equal(-25, table.x_height)
|
49
|
+
assert_equal(-26, table.cap_height)
|
50
|
+
assert_equal(27, table.default_char)
|
51
|
+
assert_equal(28, table.break_char)
|
52
|
+
assert_equal(29, table.max_context)
|
53
|
+
assert_equal(30, table.lower_point_size)
|
54
|
+
assert_equal(31, table.upper_point_size)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "loads some default values if no entry is given" do
|
58
|
+
table = HexaPDF::Font::TrueType::Table::OS2.new(@file)
|
59
|
+
assert_equal(5, table.version)
|
60
|
+
assert_equal(''.b, table.panose)
|
61
|
+
assert_equal(' '.b, table.vendor_id)
|
62
|
+
assert_equal(0, table.default_char)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/font/true_type/table/post'
|
6
|
+
|
7
|
+
describe HexaPDF::Font::TrueType::Table::Post do
|
8
|
+
before do
|
9
|
+
data = [1, 0, 1, 0, -142, 15, 0, 0, 0, 0, 0].pack('n4s>2N5')
|
10
|
+
@file = Object.new
|
11
|
+
@file.define_singleton_method(:io) { @io ||= StringIO.new(data) }
|
12
|
+
@entry = HexaPDF::Font::TrueType::Table::Directory::Entry.new('post', 0, 0, @file.io.length)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "initialize" do
|
16
|
+
it "reads the format 1 data from the associated file" do
|
17
|
+
table = HexaPDF::Font::TrueType::Table::Post.new(@file, @entry)
|
18
|
+
assert_equal(1, table.format)
|
19
|
+
assert_equal(1, table.italic_angle)
|
20
|
+
assert_equal(-142, table.underline_position)
|
21
|
+
assert_equal(15, table.underline_thickness)
|
22
|
+
assert_equal(0, table.is_fixed_pitch)
|
23
|
+
refute(table.is_fixed_pitch?)
|
24
|
+
assert_equal(0, table.min_mem_type42)
|
25
|
+
assert_equal(0, table.max_mem_type42)
|
26
|
+
assert_equal(0, table.min_mem_type1)
|
27
|
+
assert_equal(0, table.max_mem_type1)
|
28
|
+
assert_equal('.notdef', table[0])
|
29
|
+
assert_equal('A', table[36])
|
30
|
+
assert_equal('Delta', table[168])
|
31
|
+
assert_equal('.notdef', table[1000])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "reads the format 2 data from the associated file" do
|
35
|
+
@file.io.string[0, 2] = [2].pack('n')
|
36
|
+
@file.io.string << ([260, 0] + (1..257).to_a.reverse + [258, 259]).pack('n*')
|
37
|
+
@file.io.string << [4, "hexa", 3, "pdf"].pack('CA4CA3')
|
38
|
+
@entry.length = @file.io.length
|
39
|
+
table = HexaPDF::Font::TrueType::Table::Post.new(@file, @entry)
|
40
|
+
assert_equal(2, table.format)
|
41
|
+
assert_equal('.notdef', table[0])
|
42
|
+
assert_equal('A', table[258 - 36])
|
43
|
+
assert_equal('Delta', table[258 - 168])
|
44
|
+
assert_equal('hexa', table[258])
|
45
|
+
assert_equal('pdf', table[259])
|
46
|
+
assert_equal('.notdef', table[1000])
|
47
|
+
end
|
48
|
+
|
49
|
+
it "reads the format 3 data from the associated file" do
|
50
|
+
@file.io.string[0, 2] = [3].pack('n')
|
51
|
+
table = HexaPDF::Font::TrueType::Table::Post.new(@file, @entry)
|
52
|
+
assert_equal(3, table.format)
|
53
|
+
assert_equal('.notdef', table[0])
|
54
|
+
assert_equal('.notdef', table[36])
|
55
|
+
assert_equal('.notdef', table[1000])
|
56
|
+
end
|
57
|
+
|
58
|
+
it "reads the format 4 data from the associated file" do
|
59
|
+
@file.io.string[0, 2] = [4].pack('n')
|
60
|
+
@file.io.string << [0x1234, 0x5678].pack('n*')
|
61
|
+
@entry.length = @file.io.length
|
62
|
+
table = HexaPDF::Font::TrueType::Table::Post.new(@file, @entry)
|
63
|
+
assert_equal(4, table.format)
|
64
|
+
assert_equal(0x1234, table[0])
|
65
|
+
assert_equal(0x5678, table[1])
|
66
|
+
assert_equal(0xFFFF, table[2])
|
67
|
+
assert_equal(0xFFFF, table[36])
|
68
|
+
assert_equal(0xFFFF, table[1_000_000])
|
69
|
+
end
|
70
|
+
|
71
|
+
it "loads some default values if no entry is given" do
|
72
|
+
table = HexaPDF::Font::TrueType::Table::Post.new(@file)
|
73
|
+
assert_equal(1, table.format)
|
74
|
+
assert_equal(0, table.italic_angle)
|
75
|
+
assert_equal(0, table.underline_position)
|
76
|
+
assert_equal(0, table.underline_thickness)
|
77
|
+
assert_equal(0, table.is_fixed_pitch)
|
78
|
+
assert_equal(0, table.min_mem_type42)
|
79
|
+
assert_equal(0, table.max_mem_type42)
|
80
|
+
assert_equal(0, table.min_mem_type1)
|
81
|
+
assert_equal(0, table.max_mem_type1)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "raises an error if an unsupported format is given" do
|
85
|
+
@file.io.string[0, 2] = [5].pack('n')
|
86
|
+
assert_raises(HexaPDF::Error) { HexaPDF::Font::TrueType::Table::Post.new(@file, @entry) }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/font/true_type/font'
|
6
|
+
require_relative 'common'
|
7
|
+
|
8
|
+
describe HexaPDF::Font::TrueType::Font do
|
9
|
+
before do
|
10
|
+
@io = StringIO.new("TEST\x00\x01\x00\x00\x00\x00\x00\x00" \
|
11
|
+
"TEST----\x00\x00\x00\x1C\x00\x00\x00\x05ENTRY".b)
|
12
|
+
@font = HexaPDF::Font::TrueType::Font.new(io: @io)
|
13
|
+
@font.config['font.true_type.table_mapping'][:TEST] = TestHelper::TrueTypeTestTable.name
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "[]" do
|
17
|
+
it "returns a named table" do
|
18
|
+
table = @font[:TEST]
|
19
|
+
assert_equal('ENTRY', table.data)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "always returns the same table instance" do
|
23
|
+
assert_same(@font[:TEST], @font[:TEST])
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns a generic table if no mapping exists" do
|
27
|
+
@font.config['font.true_type.table_mapping'].delete(:TEST)
|
28
|
+
assert_kind_of(HexaPDF::Font::TrueType::Table, @font[:TEST])
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns nil if the named table doesn't exist in the file" do
|
32
|
+
assert_nil(@font[:OTHE])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "add_table" do
|
37
|
+
it "returns the existing table if one exists" do
|
38
|
+
assert_same(@font[:TEST], @font.add_table(:TEST))
|
39
|
+
end
|
40
|
+
|
41
|
+
it "creates a new table instance if needed" do
|
42
|
+
assert_kind_of(HexaPDF::Font::TrueType::Table::Head, @font.add_table(:head))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "getter methods" do
|
47
|
+
before do
|
48
|
+
@font.add_table(:name)
|
49
|
+
@font.add_table(:post)
|
50
|
+
@font.add_table(:head)
|
51
|
+
@font.add_table(:hhea)
|
52
|
+
@font.add_table(:"OS/2")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns the postscript name" do
|
56
|
+
@font[:name].add(:postscript_name, "name")
|
57
|
+
assert_equal("name", @font.font_name)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns the full name" do
|
61
|
+
@font[:name].add(:font_name, "name")
|
62
|
+
assert_equal("name", @font.full_name)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns the family name" do
|
66
|
+
@font[:name].add(:font_family, "name")
|
67
|
+
assert_equal("name", @font.family_name)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns the font's weight" do
|
71
|
+
@font[:"OS/2"].weight_class = 400
|
72
|
+
assert_equal(400, @font.weight)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "returns the font's bounding box" do
|
76
|
+
@font[:head].bbox = [0, 1, 2, 3]
|
77
|
+
assert_equal([0, 1, 2, 3], @font.bounding_box)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns the font's cap height" do
|
81
|
+
@font[:"OS/2"].cap_height = 832
|
82
|
+
assert_equal(832, @font.cap_height)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns the font's x height" do
|
86
|
+
@font[:"OS/2"].x_height = 642
|
87
|
+
assert_equal(642, @font.x_height)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns the font's ascender" do
|
91
|
+
@font[:"OS/2"].typo_ascender = 800
|
92
|
+
@font[:hhea].ascent = 790
|
93
|
+
assert_equal(800, @font.ascender)
|
94
|
+
@font.instance_eval { @tables.delete(:"OS/2") }
|
95
|
+
assert_equal(790, @font.ascender)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns the font's descender" do
|
99
|
+
@font[:"OS/2"].typo_descender = -200
|
100
|
+
@font[:hhea].descent = -180
|
101
|
+
assert_equal(-200, @font.descender)
|
102
|
+
@font.instance_eval { @tables.delete(:"OS/2") }
|
103
|
+
assert_equal(-180, @font.descender)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "returns the font's italic angle" do
|
107
|
+
@font[:post].italic_angle = Rational(325, 10)
|
108
|
+
assert_equal(32.5, @font.italic_angle)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "returns the font's dominant vertical stem width" do
|
112
|
+
@font[:"OS/2"].weight_class = 400
|
113
|
+
assert_equal(80, @font.dominant_vertical_stem_width)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it "is able to return the ID of the missing glyph" do
|
118
|
+
assert_equal(0, @font.missing_glyph_id)
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/font/true_type/table'
|
6
|
+
require_relative 'common'
|
7
|
+
|
8
|
+
describe HexaPDF::Font::TrueType::Table do
|
9
|
+
before do
|
10
|
+
io = StringIO.new('some string')
|
11
|
+
@file = Object.new
|
12
|
+
@file.define_singleton_method(:io) { io }
|
13
|
+
@entry = HexaPDF::Font::TrueType::Table::Directory::Entry.new('tagg', 0, 0, @file.io.string.length)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "initialize" do
|
17
|
+
it "reads the data from the associated file" do
|
18
|
+
table = TestHelper::TrueTypeTestTable.new(@file, @entry)
|
19
|
+
assert_equal(@file.io.string, table.data)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "loads some default values if no entry is given" do
|
23
|
+
table = TestHelper::TrueTypeTestTable.new(@file)
|
24
|
+
assert_equal('default', table.data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "checksum_valid?" do
|
29
|
+
it "checks whether an entry's checksum is valid" do
|
30
|
+
@file.io.string = 254.chr * 17 + 0.chr * 3
|
31
|
+
@entry.checksum = (0xfefefefe * 4 + 0xfe000000) % 2**32
|
32
|
+
@entry.length = @file.io.string.length
|
33
|
+
table = TestHelper::TrueTypeTestTable.new(@file, @entry)
|
34
|
+
assert(table.checksum_valid?)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises an error if the checksum can't be verified because none is available" do
|
38
|
+
assert_raises(HexaPDF::Error) { TestHelper::TrueTypeTestTable.new(@file).checksum_valid? }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/font/type1'
|
5
|
+
require 'hexapdf/data_dir'
|
6
|
+
require 'tempfile'
|
7
|
+
require 'stringio'
|
8
|
+
|
9
|
+
describe HexaPDF::Font::Type1::AFMParser do
|
10
|
+
describe "::parse" do
|
11
|
+
before do
|
12
|
+
@file = Tempfile.new('hexapdf-afm')
|
13
|
+
@file.write("StartFontMetrics 4.1\nFontName Test\nEndFontMetrics\n")
|
14
|
+
@file.close
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
@file.unlink
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can work with file names" do
|
22
|
+
assert_equal('Test', HexaPDF::Font::Type1::AFMParser.parse(@file.path).font_name)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can work with IO streams" do
|
26
|
+
@file.open
|
27
|
+
assert_equal('Test', HexaPDF::Font::Type1::AFMParser.parse(@file).font_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "can parse the 14 core PDF font files" do
|
32
|
+
Dir[File.join(HexaPDF.data_dir, 'afm', '*.afm')].each do |file|
|
33
|
+
metrics = HexaPDF::Font::Type1::AFMParser.parse(file)
|
34
|
+
basename = File.basename(file, '.*')
|
35
|
+
assert_equal(basename, metrics.font_name, basename)
|
36
|
+
assert_equal(basename.sub(/-.*/, ''), metrics.family_name, basename)
|
37
|
+
assert(metrics.character_metrics.size > 0, basename)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "calculates an ascender and descender value from the font bounding box if necessary" do
|
42
|
+
metrics = HexaPDF::Font::Type1::AFMParser.parse(File.join(HexaPDF.data_dir, 'afm/Symbol.afm'))
|
43
|
+
assert_equal(metrics.bounding_box[1], metrics.descender)
|
44
|
+
assert_equal(metrics.bounding_box[3], metrics.ascender)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "fails if the file doesn't start with the correct line" do
|
48
|
+
file = StringIO.new("some\nthing")
|
49
|
+
assert_raises(HexaPDF::Error) { HexaPDF::Font::Type1::AFMParser.parse(file) }
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/font/type1'
|
5
|
+
|
6
|
+
describe HexaPDF::Font::Type1::Font do
|
7
|
+
before do
|
8
|
+
metrics = HexaPDF::Font::Type1::FontMetrics.new
|
9
|
+
@font = HexaPDF::Font::Type1::Font.new(metrics)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "::from_afm" do
|
13
|
+
it "can load the Font object from an AFM file" do
|
14
|
+
font = HexaPDF::Font::Type1::Font.from_afm(File.join(HexaPDF.data_dir, 'afm/Symbol.afm'))
|
15
|
+
assert_equal('Symbol', font.family_name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "encoding" do
|
20
|
+
it "uses the StandardEncoding if possible" do
|
21
|
+
@font.metrics.encoding_scheme = 'AdobeStandardEncoding'
|
22
|
+
assert_equal(HexaPDF::Font::Encoding.for_name(:StandardEncoding), @font.encoding)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "handles the special case of the ZapfDingbats font" do
|
26
|
+
@font.metrics.font_name = "ZapfDingbats"
|
27
|
+
assert_equal(HexaPDF::Font::Encoding.for_name(:ZapfDingbatsEncoding), @font.encoding)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "handles the special case of the Symbol font" do
|
31
|
+
@font.metrics.font_name = "Symbol"
|
32
|
+
assert_equal(HexaPDF::Font::Encoding.for_name(:SymbolEncoding), @font.encoding)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "generates an encoding object if necessary" do
|
36
|
+
char_metrics = HexaPDF::Font::Type1::CharacterMetrics.new
|
37
|
+
char_metrics.code = 5
|
38
|
+
char_metrics.name = :A
|
39
|
+
@font.metrics.character_metrics[5] = char_metrics.dup
|
40
|
+
char_metrics.code = 6
|
41
|
+
char_metrics.name = :Z
|
42
|
+
@font.metrics.character_metrics[6] = char_metrics.dup
|
43
|
+
|
44
|
+
assert_equal({5 => :A, 6 => :Z}, @font.encoding.code_to_name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "width" do
|
49
|
+
before do
|
50
|
+
@char_metrics = HexaPDF::Font::Type1::CharacterMetrics.new
|
51
|
+
@char_metrics.width = 100
|
52
|
+
end
|
53
|
+
|
54
|
+
it "returns the width for a code point in the built-in encoding" do
|
55
|
+
@font.metrics.character_metrics[5] = @char_metrics
|
56
|
+
assert_equal(100, @font.width(5))
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns the width for a named glyph" do
|
60
|
+
@font.metrics.character_metrics[:A] = @char_metrics
|
61
|
+
assert_equal(100, @font.width(:A))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "is able to return the ID of the missing glyph" do
|
66
|
+
assert_equal(:'.notdef', @font.missing_glyph_id)
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/font/type1'
|
5
|
+
|
6
|
+
describe HexaPDF::Font::Type1::PFBParser do
|
7
|
+
describe "::encoding" do
|
8
|
+
it "can extract the encoding specified as StandardEncoding" do
|
9
|
+
data = "bla bla bla /Encoding StandardEncoding def bla bla"
|
10
|
+
assert_same(HexaPDF::Font::Encoding.for_name(:StandardEncoding),
|
11
|
+
HexaPDF::Font::Type1::PFBParser.encoding(data))
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can extract the encoding specified as array" do
|
15
|
+
data = <<-EOF
|
16
|
+
bla bla bla
|
17
|
+
/Encoding 256 array
|
18
|
+
0 1 255 {1 index exch /.notdef put} for
|
19
|
+
dup 32 /space put
|
20
|
+
dup 33 /exclam put
|
21
|
+
dup 34 /universal put
|
22
|
+
dup 35 /numbersign put
|
23
|
+
dup 36 /existential put
|
24
|
+
readonly def
|
25
|
+
bla bla bla
|
26
|
+
EOF
|
27
|
+
enc = HexaPDF::Font::Type1::PFBParser.encoding(data)
|
28
|
+
assert_equal(:space, enc.name(32))
|
29
|
+
assert_equal(:existential, enc.name(36))
|
30
|
+
end
|
31
|
+
|
32
|
+
it "fails if the encoding can't be extracted" do
|
33
|
+
data = "something without an encoding"
|
34
|
+
assert_raises(HexaPDF::Error) { HexaPDF::Font::Type1::PFBParser.encoding(data) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|