hexapdf 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTERS +1 -1
- data/LICENSE +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/hexapdf +1 -1
- data/examples/text_layouter_styling.rb +1 -2
- data/lib/hexapdf.rb +2 -2
- data/lib/hexapdf/cli.rb +3 -3
- data/lib/hexapdf/cli/batch.rb +5 -5
- data/lib/hexapdf/cli/command.rb +15 -17
- data/lib/hexapdf/cli/files.rb +3 -3
- data/lib/hexapdf/cli/images.rb +3 -4
- data/lib/hexapdf/cli/info.rb +5 -5
- data/lib/hexapdf/cli/inspect.rb +6 -6
- data/lib/hexapdf/cli/merge.rb +6 -6
- data/lib/hexapdf/cli/modify.rb +4 -4
- data/lib/hexapdf/cli/optimize.rb +3 -3
- data/lib/hexapdf/configuration.rb +4 -5
- data/lib/hexapdf/content.rb +2 -2
- data/lib/hexapdf/content/canvas.rb +35 -36
- data/lib/hexapdf/content/color_space.rb +9 -14
- data/lib/hexapdf/content/graphic_object.rb +2 -2
- data/lib/hexapdf/content/graphic_object/arc.rb +3 -3
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +4 -8
- data/lib/hexapdf/content/graphics_state.rb +4 -13
- data/lib/hexapdf/content/operator.rb +33 -35
- data/lib/hexapdf/content/parser.rb +28 -18
- data/lib/hexapdf/content/processor.rb +4 -5
- data/lib/hexapdf/content/transformation_matrix.rb +2 -2
- data/lib/hexapdf/data_dir.rb +2 -2
- data/lib/hexapdf/dictionary.rb +8 -9
- data/lib/hexapdf/dictionary_fields.rb +7 -10
- data/lib/hexapdf/document.rb +18 -18
- data/lib/hexapdf/document/files.rb +12 -10
- data/lib/hexapdf/document/fonts.rb +2 -2
- data/lib/hexapdf/document/images.rb +3 -3
- data/lib/hexapdf/document/pages.rb +4 -4
- data/lib/hexapdf/encryption.rb +2 -2
- data/lib/hexapdf/encryption/aes.rb +2 -2
- data/lib/hexapdf/encryption/arc4.rb +4 -4
- data/lib/hexapdf/encryption/fast_aes.rb +2 -2
- data/lib/hexapdf/encryption/fast_arc4.rb +4 -4
- data/lib/hexapdf/encryption/identity.rb +5 -4
- data/lib/hexapdf/encryption/ruby_aes.rb +147 -139
- data/lib/hexapdf/encryption/ruby_arc4.rb +4 -4
- data/lib/hexapdf/encryption/security_handler.rb +11 -12
- data/lib/hexapdf/encryption/standard_security_handler.rb +6 -9
- data/lib/hexapdf/error.rb +7 -9
- data/lib/hexapdf/filter.rb +2 -3
- data/lib/hexapdf/filter/ascii85_decode.rb +3 -3
- data/lib/hexapdf/filter/ascii_hex_decode.rb +2 -2
- data/lib/hexapdf/filter/dct_decode.rb +2 -2
- data/lib/hexapdf/filter/encryption.rb +2 -2
- data/lib/hexapdf/filter/flate_decode.rb +16 -33
- data/lib/hexapdf/filter/jpx_decode.rb +2 -2
- data/lib/hexapdf/filter/lzw_decode.rb +4 -4
- data/lib/hexapdf/filter/predictor.rb +2 -6
- data/lib/hexapdf/filter/run_length_decode.rb +2 -2
- data/lib/hexapdf/font/cmap.rb +2 -3
- data/lib/hexapdf/font/cmap/parser.rb +11 -11
- data/lib/hexapdf/font/cmap/writer.rb +25 -25
- data/lib/hexapdf/font/encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/base.rb +2 -2
- data/lib/hexapdf/font/encoding/difference_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/glyph_list.rb +6 -6
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/standard_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +2 -2
- data/lib/hexapdf/font/invalid_glyph.rb +7 -7
- data/lib/hexapdf/font/true_type.rb +2 -2
- data/lib/hexapdf/font/true_type/builder.rb +13 -7
- data/lib/hexapdf/font/true_type/font.rb +2 -3
- data/lib/hexapdf/font/true_type/optimizer.rb +2 -2
- data/lib/hexapdf/font/true_type/subsetter.rb +4 -4
- data/lib/hexapdf/font/true_type/table.rb +3 -5
- data/lib/hexapdf/font/true_type/table/cmap.rb +2 -2
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +9 -16
- data/lib/hexapdf/font/true_type/table/directory.rb +4 -4
- data/lib/hexapdf/font/true_type/table/glyf.rb +2 -2
- data/lib/hexapdf/font/true_type/table/head.rb +3 -2
- data/lib/hexapdf/font/true_type/table/hhea.rb +2 -2
- data/lib/hexapdf/font/true_type/table/hmtx.rb +2 -2
- data/lib/hexapdf/font/true_type/table/kern.rb +3 -3
- data/lib/hexapdf/font/true_type/table/loca.rb +3 -3
- data/lib/hexapdf/font/true_type/table/maxp.rb +2 -2
- data/lib/hexapdf/font/true_type/table/name.rb +3 -5
- data/lib/hexapdf/font/true_type/table/os2.rb +4 -3
- data/lib/hexapdf/font/true_type/table/post.rb +3 -7
- data/lib/hexapdf/font/true_type_wrapper.rb +20 -22
- data/lib/hexapdf/font/type1.rb +2 -2
- data/lib/hexapdf/font/type1/afm_parser.rb +7 -7
- data/lib/hexapdf/font/type1/character_metrics.rb +2 -2
- data/lib/hexapdf/font/type1/font.rb +3 -3
- data/lib/hexapdf/font/type1/font_metrics.rb +2 -4
- data/lib/hexapdf/font/type1/pfb_parser.rb +2 -2
- data/lib/hexapdf/font/type1_wrapper.rb +8 -9
- data/lib/hexapdf/font_loader.rb +2 -2
- data/lib/hexapdf/font_loader/from_configuration.rb +2 -2
- data/lib/hexapdf/font_loader/from_file.rb +2 -2
- data/lib/hexapdf/font_loader/standard14.rb +2 -2
- data/lib/hexapdf/image_loader.rb +2 -2
- data/lib/hexapdf/image_loader/jpeg.rb +6 -4
- data/lib/hexapdf/image_loader/pdf.rb +2 -2
- data/lib/hexapdf/image_loader/png.rb +6 -6
- data/lib/hexapdf/importer.rb +6 -4
- data/lib/hexapdf/layout.rb +2 -2
- data/lib/hexapdf/layout/box.rb +4 -4
- data/lib/hexapdf/layout/inline_box.rb +2 -2
- data/lib/hexapdf/layout/line.rb +6 -6
- data/lib/hexapdf/layout/numeric_refinements.rb +2 -2
- data/lib/hexapdf/layout/style.rb +17 -8
- data/lib/hexapdf/layout/text_fragment.rb +86 -48
- data/lib/hexapdf/layout/text_layouter.rb +40 -21
- data/lib/hexapdf/layout/text_shaper.rb +2 -2
- data/lib/hexapdf/name_tree_node.rb +2 -2
- data/lib/hexapdf/number_tree_node.rb +2 -2
- data/lib/hexapdf/object.rb +6 -8
- data/lib/hexapdf/parser.rb +10 -10
- data/lib/hexapdf/rectangle.rb +4 -4
- data/lib/hexapdf/reference.rb +2 -2
- data/lib/hexapdf/revision.rb +4 -4
- data/lib/hexapdf/revisions.rb +5 -5
- data/lib/hexapdf/serializer.rb +27 -24
- data/lib/hexapdf/stream.rb +4 -4
- data/lib/hexapdf/task.rb +2 -2
- data/lib/hexapdf/task/dereference.rb +4 -4
- data/lib/hexapdf/task/optimize.rb +5 -4
- data/lib/hexapdf/tokenizer.rb +12 -14
- data/lib/hexapdf/type.rb +2 -2
- data/lib/hexapdf/type/action.rb +3 -3
- data/lib/hexapdf/type/actions.rb +2 -2
- data/lib/hexapdf/type/actions/go_to.rb +2 -2
- data/lib/hexapdf/type/actions/go_to_r.rb +2 -2
- data/lib/hexapdf/type/actions/launch.rb +2 -2
- data/lib/hexapdf/type/actions/uri.rb +3 -3
- data/lib/hexapdf/type/annotation.rb +3 -3
- data/lib/hexapdf/type/annotations.rb +2 -2
- data/lib/hexapdf/type/annotations/link.rb +2 -2
- data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -2
- data/lib/hexapdf/type/annotations/text.rb +2 -2
- data/lib/hexapdf/type/catalog.rb +4 -4
- data/lib/hexapdf/type/cid_font.rb +4 -5
- data/lib/hexapdf/type/embedded_file.rb +3 -3
- data/lib/hexapdf/type/file_specification.rb +6 -7
- data/lib/hexapdf/type/font.rb +4 -4
- data/lib/hexapdf/type/font_descriptor.rb +3 -4
- data/lib/hexapdf/type/font_simple.rb +12 -16
- data/lib/hexapdf/type/font_true_type.rb +2 -2
- data/lib/hexapdf/type/font_type0.rb +5 -5
- data/lib/hexapdf/type/font_type1.rb +4 -4
- data/lib/hexapdf/type/form.rb +3 -3
- data/lib/hexapdf/type/graphics_state_parameter.rb +3 -3
- data/lib/hexapdf/type/image.rb +13 -14
- data/lib/hexapdf/type/info.rb +2 -2
- data/lib/hexapdf/type/names.rb +2 -2
- data/lib/hexapdf/type/object_stream.rb +5 -5
- data/lib/hexapdf/type/page.rb +9 -10
- data/lib/hexapdf/type/page_tree_node.rb +5 -6
- data/lib/hexapdf/type/resources.rb +11 -11
- data/lib/hexapdf/type/trailer.rb +3 -3
- data/lib/hexapdf/type/viewer_preferences.rb +2 -2
- data/lib/hexapdf/type/xref_stream.rb +8 -4
- data/lib/hexapdf/utils/bit_field.rb +4 -4
- data/lib/hexapdf/utils/bit_stream.rb +4 -4
- data/lib/hexapdf/utils/graphics_helpers.rb +2 -2
- data/lib/hexapdf/utils/lru_cache.rb +2 -2
- data/lib/hexapdf/utils/math_helpers.rb +2 -2
- data/lib/hexapdf/utils/object_hash.rb +3 -3
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +3 -3
- data/lib/hexapdf/utils/sorted_tree_node.rb +12 -11
- data/lib/hexapdf/version.rb +3 -3
- data/lib/hexapdf/writer.rb +8 -8
- data/lib/hexapdf/xref_section.rb +3 -3
- data/test/hexapdf/common_tokenizer_tests.rb +6 -7
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +0 -1
- data/test/hexapdf/content/test_canvas.rb +28 -36
- data/test/hexapdf/content/test_color_space.rb +4 -0
- data/test/hexapdf/content/test_graphics_state.rb +2 -0
- data/test/hexapdf/content/test_operator.rb +6 -7
- data/test/hexapdf/content/test_parser.rb +2 -2
- data/test/hexapdf/content/test_processor.rb +1 -1
- data/test/hexapdf/document/test_files.rb +1 -0
- data/test/hexapdf/document/test_images.rb +1 -1
- data/test/hexapdf/encryption/common.rb +3 -3
- data/test/hexapdf/encryption/test_aes.rb +10 -4
- data/test/hexapdf/encryption/test_identity.rb +1 -1
- data/test/hexapdf/encryption/test_security_handler.rb +13 -17
- data/test/hexapdf/encryption/test_standard_security_handler.rb +12 -12
- data/test/hexapdf/filter/test_ascii85_decode.rb +2 -3
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +6 -1
- data/test/hexapdf/filter/test_flate_decode.rb +2 -2
- data/test/hexapdf/filter/test_lzw_decode.rb +10 -10
- data/test/hexapdf/filter/test_predictor.rb +10 -2
- data/test/hexapdf/filter/test_run_length_decode.rb +1 -1
- data/test/hexapdf/font/cmap/test_parser.rb +40 -40
- data/test/hexapdf/font/cmap/test_writer.rb +29 -29
- data/test/hexapdf/font/test_true_type_wrapper.rb +3 -2
- data/test/hexapdf/font/true_type/common.rb +2 -0
- data/test/hexapdf/font/true_type/table/test_cmap.rb +1 -1
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +5 -4
- data/test/hexapdf/font/true_type/table/test_glyf.rb +2 -2
- data/test/hexapdf/font/true_type/table/test_head.rb +2 -2
- data/test/hexapdf/font/true_type/table/test_name.rb +9 -6
- data/test/hexapdf/font/true_type/test_builder.rb +8 -3
- data/test/hexapdf/font/true_type/test_optimizer.rb +1 -2
- data/test/hexapdf/font/type1/test_afm_parser.rb +2 -2
- data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
- data/test/hexapdf/image_loader/test_pdf.rb +1 -1
- data/test/hexapdf/image_loader/test_png.rb +3 -3
- data/test/hexapdf/layout/test_inline_box.rb +10 -1
- data/test/hexapdf/layout/test_line.rb +4 -4
- data/test/hexapdf/layout/test_style.rb +19 -7
- data/test/hexapdf/layout/test_text_fragment.rb +73 -27
- data/test/hexapdf/layout/test_text_layouter.rb +84 -68
- data/test/hexapdf/layout/test_text_shaper.rb +4 -6
- data/test/hexapdf/task/test_dereference.rb +2 -2
- data/test/hexapdf/task/test_optimize.rb +16 -7
- data/test/hexapdf/test_configuration.rb +1 -1
- data/test/hexapdf/test_data_dir.rb +2 -2
- data/test/hexapdf/test_dictionary.rb +6 -3
- data/test/hexapdf/test_dictionary_fields.rb +15 -14
- data/test/hexapdf/test_document.rb +47 -48
- data/test/hexapdf/test_filter.rb +30 -26
- data/test/hexapdf/test_importer.rb +14 -0
- data/test/hexapdf/test_object.rb +16 -4
- data/test/hexapdf/test_parser.rb +36 -36
- data/test/hexapdf/test_reference.rb +7 -5
- data/test/hexapdf/test_revision.rb +1 -1
- data/test/hexapdf/test_revisions.rb +90 -90
- data/test/hexapdf/test_serializer.rb +3 -2
- data/test/hexapdf/test_stream.rb +2 -4
- data/test/hexapdf/test_tokenizer.rb +2 -2
- data/test/hexapdf/test_writer.rb +80 -80
- data/test/hexapdf/test_xref_section.rb +1 -1
- data/test/hexapdf/type/annotations/test_link.rb +1 -1
- data/test/hexapdf/type/annotations/test_text.rb +3 -3
- data/test/hexapdf/type/test_font_descriptor.rb +1 -1
- data/test/hexapdf/type/test_font_simple.rb +2 -2
- data/test/hexapdf/type/test_font_type0.rb +0 -1
- data/test/hexapdf/type/test_image.rb +0 -3
- data/test/hexapdf/type/test_object_stream.rb +2 -1
- data/test/hexapdf/type/test_page.rb +5 -1
- data/test/hexapdf/type/test_page_tree_node.rb +4 -4
- data/test/hexapdf/type/test_trailer.rb +1 -1
- data/test/hexapdf/type/test_xref_stream.rb +4 -0
- data/test/hexapdf/utils/test_bit_field.rb +2 -0
- data/test/hexapdf/utils/test_bit_stream.rb +1 -1
- data/test/hexapdf/utils/test_lru_cache.rb +1 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -4
- data/test/test_helper.rb +3 -6
- metadata +3 -3
@@ -5,37 +5,37 @@ require 'hexapdf/font/cmap/writer'
|
|
5
5
|
|
6
6
|
describe HexaPDF::Font::CMap::Writer do
|
7
7
|
before do
|
8
|
-
@cmap_data =
|
9
|
-
/CIDInit /ProcSet findresource begin
|
10
|
-
12 dict begin
|
11
|
-
begincmap
|
12
|
-
/CIDSystemInfo
|
13
|
-
<< /Registry (Adobe)
|
14
|
-
/Ordering (UCS)
|
15
|
-
/Supplement 0
|
16
|
-
>> def
|
17
|
-
/CMapName /Adobe-Identity-UCS def
|
18
|
-
/CMapType 2 def
|
19
|
-
1 begincodespacerange
|
20
|
-
<0000> <FFFF>
|
21
|
-
endcodespacerange
|
22
|
-
2 beginbfchar
|
23
|
-
<0060><0090>
|
24
|
-
<3A51><d840dc3e>
|
25
|
-
endbfchar
|
26
|
-
2 beginbfrange
|
27
|
-
<0000><005E><0020>
|
28
|
-
<1379><137B><90fe>
|
29
|
-
endbfrange
|
30
|
-
endcmap
|
31
|
-
CMapName currentdict /CMap defineresource pop
|
32
|
-
end
|
33
|
-
end
|
34
|
-
EOF
|
8
|
+
@cmap_data = <<~EOF
|
9
|
+
/CIDInit /ProcSet findresource begin
|
10
|
+
12 dict begin
|
11
|
+
begincmap
|
12
|
+
/CIDSystemInfo
|
13
|
+
<< /Registry (Adobe)
|
14
|
+
/Ordering (UCS)
|
15
|
+
/Supplement 0
|
16
|
+
>> def
|
17
|
+
/CMapName /Adobe-Identity-UCS def
|
18
|
+
/CMapType 2 def
|
19
|
+
1 begincodespacerange
|
20
|
+
<0000> <FFFF>
|
21
|
+
endcodespacerange
|
22
|
+
2 beginbfchar
|
23
|
+
<0060><0090>
|
24
|
+
<3A51><d840dc3e>
|
25
|
+
endbfchar
|
26
|
+
2 beginbfrange
|
27
|
+
<0000><005E><0020>
|
28
|
+
<1379><137B><90fe>
|
29
|
+
endbfrange
|
30
|
+
endcmap
|
31
|
+
CMapName currentdict /CMap defineresource pop
|
32
|
+
end
|
33
|
+
end
|
34
|
+
EOF
|
35
35
|
@mapping = []
|
36
|
-
0x00.upto(0x5e) {|i| @mapping << [i, 0x20 + i]}
|
36
|
+
0x00.upto(0x5e) {|i| @mapping << [i, 0x20 + i] }
|
37
37
|
@mapping << [0x60, 0x90]
|
38
|
-
0x1379.upto(0x137B) {|i| @mapping << [i, 0x90FE + i - 0x1379]}
|
38
|
+
0x1379.upto(0x137B) {|i| @mapping << [i, 0x90FE + i - 0x1379] }
|
39
39
|
@mapping << [0x3A51, 0x2003E]
|
40
40
|
end
|
41
41
|
|
@@ -32,7 +32,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
32
32
|
describe "decode_utf8" do
|
33
33
|
it "returns an array of glyph objects" do
|
34
34
|
assert_equal("Test",
|
35
|
-
@font_wrapper.decode_utf8("Test").map {|g| @cmap.gid_to_code(g.id)}.pack('U*'))
|
35
|
+
@font_wrapper.decode_utf8("Test").map {|g| @cmap.gid_to_code(g.id) }.pack('U*'))
|
36
36
|
end
|
37
37
|
|
38
38
|
it "invokes font.on_missing_glyph for UTF-8 characters for which no glyph exists" do
|
@@ -110,7 +110,8 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
110
110
|
cidfont = dict[:DescendantFonts][0]
|
111
111
|
assert_equal(:Font, cidfont[:Type])
|
112
112
|
assert_equal(:CIDFontType2, cidfont[:Subtype])
|
113
|
-
assert_equal({Registry: "Adobe", Ordering: "Identity", Supplement: 0},
|
113
|
+
assert_equal({Registry: "Adobe", Ordering: "Identity", Supplement: 0},
|
114
|
+
cidfont[:CIDSystemInfo])
|
114
115
|
assert_equal(:Identity, cidfont[:CIDToGIDMap])
|
115
116
|
assert_equal(@font_wrapper.glyph(3).width, cidfont[:DW])
|
116
117
|
assert_equal([2, [glyph.width]], cidfont[:W])
|
@@ -38,7 +38,7 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
|
|
38
38
|
|
39
39
|
describe "parse" do
|
40
40
|
def table(data)
|
41
|
-
@klass.new(3, 1).tap {|obj| obj.parse(StringIO.new(data), 0)}
|
41
|
+
@klass.new(3, 1).tap {|obj| obj.parse(StringIO.new(data), 0) }
|
42
42
|
end
|
43
43
|
|
44
44
|
it "works for format 0" do
|
@@ -49,11 +49,13 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
|
|
49
49
|
|
50
50
|
assert_equal(0, t.gid_to_code(255))
|
51
51
|
assert_equal(234, t.gid_to_code(233))
|
52
|
+
|
53
|
+
assert_raises(HexaPDF::Error) { table([0, 20, 0].pack('n3') + "a" * 20) }
|
52
54
|
end
|
53
55
|
|
54
56
|
it "works for format 2" do
|
55
57
|
f2 = ([0, 8] + [0] * 254).pack('n*') + \
|
56
|
-
[[0, 256, 0, 2 + 8], [0x33, 3, 5, 2 + 256 * 2]].map {|a| a.pack('n2s>n')}.join('') + \
|
58
|
+
[[0, 256, 0, 2 + 8], [0x33, 3, 5, 2 + 256 * 2]].map {|a| a.pack('n2s>n') }.join('') + \
|
57
59
|
((0..255).to_a + [35, 65534, 0]).pack('n*')
|
58
60
|
t = table([2, f2.length + 6, 0].pack('n3') << f2)
|
59
61
|
assert_nil(t[0x0132])
|
@@ -70,7 +72,7 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
|
|
70
72
|
end
|
71
73
|
|
72
74
|
it "works for format 4" do
|
73
|
-
f4 = [6, 8, 2, 4, 35, 134, 65535,
|
75
|
+
f4 = [6, 8, 2, 4, 35, 134, 65535, 0, 30, 133, 65535, 100, 110, 120,
|
74
76
|
0, 6, 2, 65500, 0, 1].pack('n*')
|
75
77
|
t = table([4, f4.length + 6, 0].pack('n3') << f4)
|
76
78
|
assert_nil(t[25])
|
@@ -135,6 +137,5 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
|
|
135
137
|
it "returns false if a format is not supported" do
|
136
138
|
refute(@klass.new(3, 1).parse(StringIO.new("\x00\x03".b), 0))
|
137
139
|
end
|
138
|
-
|
139
140
|
end
|
140
141
|
end
|
@@ -8,8 +8,8 @@ describe HexaPDF::Font::TrueType::Table::Glyf do
|
|
8
8
|
before do
|
9
9
|
loca = Object.new
|
10
10
|
loca.define_singleton_method(:offsets) { @offsets ||= [] }
|
11
|
-
loca.define_singleton_method(:offset) {|i| @offsets[i]}
|
12
|
-
loca.define_singleton_method(:length) {|i| @offsets[i + 1] - @offsets[i]}
|
11
|
+
loca.define_singleton_method(:offset) {|i| @offsets[i] }
|
12
|
+
loca.define_singleton_method(:length) {|i| @offsets[i + 1] - @offsets[i] }
|
13
13
|
loca.offsets << 0 << 0
|
14
14
|
data = [1, -10, -20, 100, 150].pack('s>5')
|
15
15
|
loca.offsets << data.size
|
@@ -16,8 +16,8 @@ describe HexaPDF::Font::TrueType::Table::Head do
|
|
16
16
|
describe "initialize" do
|
17
17
|
it "reads the data from the associated file" do
|
18
18
|
table = create_table(:Head)
|
19
|
-
assert_equal('1.0', '%1.1f'
|
20
|
-
assert_equal('2.1', '%1.1f'
|
19
|
+
assert_equal('1.0', sprintf('%1.1f', table.version))
|
20
|
+
assert_equal('2.1', sprintf('%1.1f', table.font_revision))
|
21
21
|
assert_equal(42, table.checksum_adjustment)
|
22
22
|
assert_equal(3, table.flags)
|
23
23
|
assert_equal(64, table.units_per_em)
|
@@ -9,7 +9,7 @@ describe HexaPDF::Font::TrueType::Table::Name do
|
|
9
9
|
data = [0, 3, 42].pack('n3') << \
|
10
10
|
[1, 0, 0, 0, 4, 0].pack('n6') << \
|
11
11
|
[0, 3, 1, 0, 8, 4].pack('n6') << \
|
12
|
-
[
|
12
|
+
[3, 1, 1033, 1, 14, 12].pack('n6') << \
|
13
13
|
'hexa'.encode('MACROMAN').b << \
|
14
14
|
'hexa'.encode('UTF-16BE').b <<
|
15
15
|
'hexapdf'.encode('UTF-16BE').b
|
@@ -30,10 +30,12 @@ describe HexaPDF::Font::TrueType::Table::Name do
|
|
30
30
|
assert_equal(3, table[:copyright][1].encoding_id)
|
31
31
|
assert_equal(1, table[:copyright][1].language_id)
|
32
32
|
assert_equal('hexapdf', table[:font_family][0])
|
33
|
-
assert_equal(
|
34
|
-
assert_equal(
|
35
|
-
assert_equal(
|
36
|
-
|
33
|
+
assert_equal(3, table[:font_family][0].platform_id)
|
34
|
+
assert_equal(1, table[:font_family][0].encoding_id)
|
35
|
+
assert_equal(1033, table[:font_family][0].language_id)
|
36
|
+
|
37
|
+
assert_equal(table[0][0], table[0].preferred_record)
|
38
|
+
assert_equal(table[:font_family][0], table[:font_family].preferred_record)
|
37
39
|
end
|
38
40
|
|
39
41
|
it "reads the data in format 1 from the associated file" do
|
@@ -55,7 +57,7 @@ describe HexaPDF::Font::TrueType::Table::Name do
|
|
55
57
|
it "returns the correct value" do
|
56
58
|
assert(@table[:copyright][0].platform?(:macintosh))
|
57
59
|
assert(@table[:copyright][1].platform?(:unicode))
|
58
|
-
|
60
|
+
assert(@table[:font_family][0].platform?(:microsoft))
|
59
61
|
end
|
60
62
|
|
61
63
|
it "raises an error when called with an unknown identifier" do
|
@@ -67,6 +69,7 @@ describe HexaPDF::Font::TrueType::Table::Name do
|
|
67
69
|
it "returns true for names in US English that had been converted to UTF-8" do
|
68
70
|
assert(@table[:copyright][0].preferred?)
|
69
71
|
refute(@table[:copyright][1].preferred?)
|
72
|
+
assert(@table[:font_family][0].preferred?)
|
70
73
|
end
|
71
74
|
end
|
72
75
|
end
|
@@ -9,7 +9,6 @@ describe HexaPDF::Font::TrueType::Builder do
|
|
9
9
|
before do
|
10
10
|
font_file = File.join(TEST_DATA_DIR, "fonts", "Ubuntu-Title.ttf")
|
11
11
|
@font = HexaPDF::Font::TrueType::Font.new(File.open(font_file))
|
12
|
-
@subsetter = HexaPDF::Font::TrueType::Subsetter.new(@font)
|
13
12
|
end
|
14
13
|
|
15
14
|
after do
|
@@ -18,9 +17,9 @@ describe HexaPDF::Font::TrueType::Builder do
|
|
18
17
|
|
19
18
|
it "builds the font file" do
|
20
19
|
tables = {
|
20
|
+
"loca" => @font[:loca].raw_data << "0",
|
21
21
|
"head" => @font[:head].raw_data,
|
22
22
|
"glyf" => @font[:glyf].raw_data,
|
23
|
-
"loca" => @font[:loca].raw_data,
|
24
23
|
"maxp" => @font[:maxp].raw_data,
|
25
24
|
}
|
26
25
|
font_data = HexaPDF::Font::TrueType::Builder.build(tables)
|
@@ -28,10 +27,16 @@ describe HexaPDF::Font::TrueType::Builder do
|
|
28
27
|
|
29
28
|
assert(built_font[:head].checksum_valid?)
|
30
29
|
assert_equal(@font[:glyf].raw_data, built_font[:glyf].raw_data)
|
30
|
+
assert(built_font.directory.entry('glyf').offset % 4 == 0)
|
31
31
|
assert(built_font[:glyf].checksum_valid?)
|
32
|
-
assert_equal(@font[:loca].raw_data, built_font[:loca].raw_data)
|
32
|
+
assert_equal(@font[:loca].raw_data << "0", built_font[:loca].raw_data)
|
33
33
|
assert(built_font[:loca].checksum_valid?)
|
34
|
+
assert(built_font.directory.entry('loca').offset % 4 == 0)
|
34
35
|
assert_equal(@font[:maxp].raw_data, built_font[:maxp].raw_data)
|
35
36
|
assert(built_font[:maxp].checksum_valid?)
|
37
|
+
assert(built_font.directory.entry('maxp').offset % 4 == 0)
|
38
|
+
|
39
|
+
tables = built_font.directory.instance_variable_get(:@tables)
|
40
|
+
assert_equal(tables.keys.sort, tables.keys)
|
36
41
|
end
|
37
42
|
end
|
@@ -8,7 +8,6 @@ describe HexaPDF::Font::TrueType::Optimizer do
|
|
8
8
|
before do
|
9
9
|
font_file = File.join(TEST_DATA_DIR, "fonts", "Ubuntu-Title.ttf")
|
10
10
|
@font = HexaPDF::Font::TrueType::Font.new(File.open(font_file))
|
11
|
-
@subsetter = HexaPDF::Font::TrueType::Subsetter.new(@font)
|
12
11
|
end
|
13
12
|
|
14
13
|
after do
|
@@ -19,7 +18,7 @@ describe HexaPDF::Font::TrueType::Optimizer do
|
|
19
18
|
it "builds a font file that is optimized for use with PDFs" do
|
20
19
|
font_data = HexaPDF::Font::TrueType::Optimizer.build_for_pdf(@font)
|
21
20
|
built_font = HexaPDF::Font::TrueType::Font.new(StringIO.new(font_data))
|
22
|
-
|
21
|
+
[:FFTM, :GDEF, :GPOS, :GSUB, :name, :post].each do |table|
|
23
22
|
refute(built_font[table])
|
24
23
|
end
|
25
24
|
end
|
@@ -11,7 +11,7 @@ describe HexaPDF::Font::Type1::AFMParser do
|
|
11
11
|
describe "::parse" do
|
12
12
|
before do
|
13
13
|
@file = Tempfile.new('hexapdf-afm')
|
14
|
-
@file.write("StartFontMetrics 4.1\nFontName Test\nEndFontMetrics\n")
|
14
|
+
@file.write("StartFontMetrics 4.1\nFontName Test\nEndFontMetrics\nFontName Other\n")
|
15
15
|
@file.close
|
16
16
|
end
|
17
17
|
|
@@ -35,7 +35,7 @@ describe HexaPDF::Font::Type1::AFMParser do
|
|
35
35
|
basename = File.basename(file, '.*')
|
36
36
|
assert_equal(basename, metrics.font_name, basename)
|
37
37
|
assert_equal(basename.sub(/-.*/, ''), metrics.family_name, basename)
|
38
|
-
|
38
|
+
refute(metrics.character_metrics.empty?, basename)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -15,7 +15,7 @@ describe HexaPDF::ImageLoader::JPEG do
|
|
15
15
|
it "works for jpeg files" do
|
16
16
|
@images.each do |image|
|
17
17
|
assert(@loader.handles?(image))
|
18
|
-
File.open(image, 'rb') {|file| assert(@loader.handles?(file))}
|
18
|
+
File.open(image, 'rb') {|file| assert(@loader.handles?(file)) }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -14,7 +14,7 @@ describe HexaPDF::ImageLoader::PDF do
|
|
14
14
|
describe "handles?" do
|
15
15
|
it "works for PDF files" do
|
16
16
|
assert(@loader.handles?(@pdf))
|
17
|
-
File.open(@pdf, 'rb') {|file| assert(@loader.handles?(file))}
|
17
|
+
File.open(@pdf, 'rb') {|file| assert(@loader.handles?(file)) }
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -15,7 +15,7 @@ describe HexaPDF::ImageLoader::PNG do
|
|
15
15
|
it "works for png files" do
|
16
16
|
@images.each do |image|
|
17
17
|
assert(@loader.handles?(image))
|
18
|
-
File.open(image, 'rb') {|file| assert(@loader.handles?(file))}
|
18
|
+
File.open(image, 'rb') {|file| assert(@loader.handles?(file)) }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -30,7 +30,7 @@ describe HexaPDF::ImageLoader::PNG do
|
|
30
30
|
assert_equal(height, image[:Height])
|
31
31
|
assert_equal(bpc, image[:BitsPerComponent])
|
32
32
|
assert_equal(color_space, image[:ColorSpace]) if color_space
|
33
|
-
data = stream.map {|row| [row.map {|i| i.to_s(2).rjust(bpc, '0')}.join("")].pack('B*')}.join("")
|
33
|
+
data = stream.map {|row| [row.map {|i| i.to_s(2).rjust(bpc, '0') }.join("")].pack('B*') }.join("")
|
34
34
|
assert_equal(data, image.stream)
|
35
35
|
end
|
36
36
|
|
@@ -231,7 +231,7 @@ describe HexaPDF::ImageLoader::PNG do
|
|
231
231
|
zip(image[:ColorSpace][1][:Matrix]).each do |r, e|
|
232
232
|
assert_in_delta(r, e, 0.0001)
|
233
233
|
end
|
234
|
-
if png
|
234
|
+
if png.match?(/srgb/)
|
235
235
|
assert_equal(:AbsoluteColorimetric, image[:Intent])
|
236
236
|
end
|
237
237
|
end
|
@@ -8,9 +8,18 @@ describe HexaPDF::Layout::InlineBox do
|
|
8
8
|
@box = HexaPDF::Layout::InlineBox.create(width: 10, height: 15, style: {margin: [15, 10]})
|
9
9
|
end
|
10
10
|
|
11
|
+
it "needs a box to wrap and an optional alignment on initialization" do
|
12
|
+
ibox = HexaPDF::Layout::InlineBox.new(@box)
|
13
|
+
assert_equal(@box, ibox.box)
|
14
|
+
assert_equal(:baseline, ibox.valign)
|
15
|
+
|
16
|
+
ibox = HexaPDF::Layout::InlineBox.new(@box, valign: :top)
|
17
|
+
assert_equal(:top, ibox.valign)
|
18
|
+
end
|
19
|
+
|
11
20
|
it "draws the wrapped box at the correct position" do
|
12
21
|
canvas = Object.new
|
13
|
-
block =
|
22
|
+
block = lambda do |c, x, y|
|
14
23
|
assert_equal(canvas, c)
|
15
24
|
assert_equal(10, x)
|
16
25
|
assert_equal(15, y)
|
@@ -35,7 +35,7 @@ describe HexaPDF::Layout::Line do
|
|
35
35
|
describe "initialize" do
|
36
36
|
it "allows setting the items of the line fragment" do
|
37
37
|
frag1 = setup_fragment("Hello")
|
38
|
-
frag2 = HexaPDF::Layout::TextFragment.new(
|
38
|
+
frag2 = HexaPDF::Layout::TextFragment.new(frag1.items.slice!(3, 2), frag1.style)
|
39
39
|
line = HexaPDF::Layout::Line.new([frag1, frag2])
|
40
40
|
assert_equal(1, line.items.count)
|
41
41
|
assert_equal(5, line.items[0].items.count)
|
@@ -50,7 +50,7 @@ describe HexaPDF::Layout::Line do
|
|
50
50
|
|
51
51
|
it "combines text fragments if possible" do
|
52
52
|
frag1 = setup_fragment("Home")
|
53
|
-
frag2 = HexaPDF::Layout::TextFragment.new(
|
53
|
+
frag2 = HexaPDF::Layout::TextFragment.new(frag1.items.slice!(2, 2), frag1.style)
|
54
54
|
@line << setup_fragment("o") << :other << frag1 << frag2
|
55
55
|
assert_equal(3, @line.items.length)
|
56
56
|
assert_equal(4, @line.items.last.items.length)
|
@@ -58,7 +58,7 @@ describe HexaPDF::Layout::Line do
|
|
58
58
|
|
59
59
|
it "duplicates the first of two combinable text fragments if its items are frozen" do
|
60
60
|
frag1 = setup_fragment("Home")
|
61
|
-
frag2 = HexaPDF::Layout::TextFragment.new(
|
61
|
+
frag2 = HexaPDF::Layout::TextFragment.new(frag1.items.slice!(2, 2), frag1.style)
|
62
62
|
frag1.items.freeze
|
63
63
|
frag2.items.freeze
|
64
64
|
|
@@ -189,7 +189,7 @@ describe HexaPDF::Layout::Line do
|
|
189
189
|
[@line.items[4], @line.items[0].width + 30, @line.text_y_min],
|
190
190
|
[@line.items[5], @line.items[0].width + 40, @line.y_min],
|
191
191
|
]
|
192
|
-
assert_equal(result, @line.to_enum(:each).map {|*a| a})
|
192
|
+
assert_equal(result, @line.to_enum(:each).map {|*a| a })
|
193
193
|
end
|
194
194
|
|
195
195
|
it "fails if an item uses an invalid valign value" do
|
@@ -10,7 +10,7 @@ require 'hexapdf/layout/box'
|
|
10
10
|
describe HexaPDF::Layout::Style::LineSpacing do
|
11
11
|
before do
|
12
12
|
@line1 = Object.new
|
13
|
-
@line1.define_singleton_method(:y_min) { - 1}
|
13
|
+
@line1.define_singleton_method(:y_min) { - 1 }
|
14
14
|
@line1.define_singleton_method(:y_max) { 2 }
|
15
15
|
@line2 = Object.new
|
16
16
|
@line2.define_singleton_method(:y_min) { -3 }
|
@@ -87,6 +87,12 @@ describe HexaPDF::Layout::Style::Quad do
|
|
87
87
|
assert_equal(5, quad.right)
|
88
88
|
assert_equal(5, quad.bottom)
|
89
89
|
assert_equal(5, quad.left)
|
90
|
+
|
91
|
+
quad = create_quad([5])
|
92
|
+
assert_equal(5, quad.top)
|
93
|
+
assert_equal(5, quad.right)
|
94
|
+
assert_equal(5, quad.bottom)
|
95
|
+
assert_equal(5, quad.left)
|
90
96
|
end
|
91
97
|
|
92
98
|
it "works with two values" do
|
@@ -351,14 +357,14 @@ describe HexaPDF::Layout::Style::Layers do
|
|
351
357
|
end
|
352
358
|
|
353
359
|
it "can be initialized with an array of layers" do
|
354
|
-
data = [
|
360
|
+
data = [lambda {}]
|
355
361
|
layers = HexaPDF::Layout::Style::Layers.new(data)
|
356
362
|
assert_equal(data, layers.enum_for(:each, {}).to_a)
|
357
363
|
end
|
358
364
|
|
359
365
|
describe "add and each" do
|
360
366
|
it "can use a given block" do
|
361
|
-
block = proc { true}
|
367
|
+
block = proc { true }
|
362
368
|
@layers.add(&block)
|
363
369
|
assert_equal([block], @layers.enum_for(:each, {}).to_a)
|
364
370
|
end
|
@@ -366,9 +372,9 @@ describe HexaPDF::Layout::Style::Layers do
|
|
366
372
|
it "can store a reference" do
|
367
373
|
@layers.add(:link, option: :value)
|
368
374
|
value = Object.new
|
369
|
-
value.define_singleton_method(:new) {
|
375
|
+
value.define_singleton_method(:new) {|*| :new }
|
370
376
|
config = Object.new
|
371
|
-
config.define_singleton_method(:constantize) {
|
377
|
+
config.define_singleton_method(:constantize) {|*| value }
|
372
378
|
assert_equal([:new], @layers.enum_for(:each, config).to_a)
|
373
379
|
end
|
374
380
|
|
@@ -395,7 +401,8 @@ describe HexaPDF::Layout::Style::Layers do
|
|
395
401
|
canvas = HexaPDF::Document.new.pages.add.canvas
|
396
402
|
canvas.context.document.config['style.layers_map'][:test] = klass
|
397
403
|
|
398
|
-
@layers.
|
404
|
+
@layers.draw(canvas, 10, 15, box)
|
405
|
+
@layers.add {|canv, ibox| assert_equal(box, ibox); canv.line_width(10) }
|
399
406
|
@layers.add(:test, option: :value)
|
400
407
|
@layers.draw(canvas, 10, 15, box)
|
401
408
|
ops = [[:save_graphics_state],
|
@@ -435,7 +442,12 @@ describe HexaPDF::Layout::Style::LinkLayer do
|
|
435
442
|
def call_link(hash)
|
436
443
|
link = HexaPDF::Layout::Style::LinkLayer.new(hash)
|
437
444
|
link.call(@canvas, @box)
|
438
|
-
@canvas.context[:Annots]
|
445
|
+
@canvas.context[:Annots]&.first
|
446
|
+
end
|
447
|
+
|
448
|
+
it "does nothing if the context is not a page object" do
|
449
|
+
@canvas = HexaPDF::Document.new.add(Type: :XObject, Subtype: :Form).canvas
|
450
|
+
assert_nil(call_link(dest: true))
|
439
451
|
end
|
440
452
|
|
441
453
|
it "sets general values like /Rect and /QuadPoints" do
|