ttfunk 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +114 -0
- data/{README.rdoc → README.md} +12 -8
- data/lib/ttfunk.rb +27 -21
- data/lib/ttfunk/collection.rb +41 -0
- data/lib/ttfunk/directory.rb +10 -4
- data/lib/ttfunk/encoding/mac_roman.rb +50 -40
- data/lib/ttfunk/encoding/windows_1252.rb +28 -22
- data/lib/ttfunk/reader.rb +11 -10
- data/lib/ttfunk/resource_file.rb +28 -21
- data/lib/ttfunk/subset.rb +5 -5
- data/lib/ttfunk/subset/base.rb +66 -38
- data/lib/ttfunk/subset/mac_roman.rb +11 -10
- data/lib/ttfunk/subset/unicode.rb +10 -8
- data/lib/ttfunk/subset/unicode_8bit.rb +16 -16
- data/lib/ttfunk/subset/windows_1252.rb +16 -15
- data/lib/ttfunk/subset_collection.rb +7 -8
- data/lib/ttfunk/table.rb +3 -5
- data/lib/ttfunk/table/cmap.rb +13 -13
- data/lib/ttfunk/table/cmap/format00.rb +8 -10
- data/lib/ttfunk/table/cmap/format04.rb +37 -32
- data/lib/ttfunk/table/cmap/format06.rb +16 -16
- data/lib/ttfunk/table/cmap/format10.rb +22 -17
- data/lib/ttfunk/table/cmap/format12.rb +28 -22
- data/lib/ttfunk/table/cmap/subtable.rb +30 -23
- data/lib/ttfunk/table/glyf.rb +13 -11
- data/lib/ttfunk/table/glyf/compound.rb +13 -10
- data/lib/ttfunk/table/glyf/simple.rb +5 -4
- data/lib/ttfunk/table/head.rb +13 -13
- data/lib/ttfunk/table/hhea.rb +13 -13
- data/lib/ttfunk/table/hmtx.rb +23 -18
- data/lib/ttfunk/table/kern.rb +57 -48
- data/lib/ttfunk/table/kern/format0.rb +18 -10
- data/lib/ttfunk/table/loca.rb +9 -9
- data/lib/ttfunk/table/maxp.rb +9 -9
- data/lib/ttfunk/table/name.rb +65 -56
- data/lib/ttfunk/table/os2.rb +21 -21
- data/lib/ttfunk/table/post.rb +32 -32
- data/lib/ttfunk/table/post/format10.rb +33 -27
- data/lib/ttfunk/table/post/format20.rb +10 -10
- data/lib/ttfunk/table/post/format30.rb +5 -5
- data/lib/ttfunk/table/post/format40.rb +3 -3
- data/lib/ttfunk/table/sbix.rb +19 -10
- metadata +55 -32
- metadata.gz.sig +0 -0
- data/CHANGELOG +0 -5
- data/data/fonts/DejaVuSans.ttf +0 -0
- data/examples/metrics.rb +0 -45
@@ -1,24 +1,28 @@
|
|
1
1
|
module TTFunk
|
2
2
|
module Encoding
|
3
3
|
class Windows1252
|
4
|
-
#
|
5
|
-
TO_UNICODE = Hash[*(0..255).zip((0..255).to_a).flatten]
|
6
|
-
TO_UNICODE.update(
|
7
|
-
0x80 => 0x20AC, 0x82 => 0x201A, 0x83 => 0x0192, 0x84 => 0x201E, 0x85 => 0x2026,
|
8
|
-
0x86 => 0x2020, 0x87 => 0x2021, 0x88 => 0x02C6, 0x89 => 0x2030, 0x8A => 0x0160,
|
9
|
-
0x8B => 0x2039, 0x8C => 0x0152, 0x8E => 0x017D, 0x91 => 0x2018, 0x92 => 0x2019,
|
10
|
-
0x93 => 0x201C, 0x94 => 0x201D, 0x95 => 0x2022, 0x96 => 0x2013, 0x97 => 0x2014,
|
11
|
-
0x98 => 0x02DC, 0x99 => 0x2122, 0x9A => 0x0161, 0x9B => 0x203A, 0x9C => 0x0152,
|
12
|
-
0x9E => 0x017E, 0x9F => 0x0178
|
13
|
-
)
|
4
|
+
# rubocop: disable Style/ExtraSpacing
|
14
5
|
|
15
|
-
|
16
|
-
|
6
|
+
TO_UNICODE =
|
7
|
+
Hash[*(0..255).zip((0..255)).flatten]
|
8
|
+
.update(
|
9
|
+
0x80 => 0x20AC, 0x82 => 0x201A, 0x83 => 0x0192, 0x84 => 0x201E,
|
10
|
+
0x85 => 0x2026, 0x86 => 0x2020, 0x87 => 0x2021, 0x88 => 0x02C6,
|
11
|
+
0x89 => 0x2030, 0x8A => 0x0160, 0x8B => 0x2039, 0x8C => 0x0152,
|
12
|
+
0x8E => 0x017D, 0x91 => 0x2018, 0x92 => 0x2019, 0x93 => 0x201C,
|
13
|
+
0x94 => 0x201D, 0x95 => 0x2022, 0x96 => 0x2013, 0x97 => 0x2014,
|
14
|
+
0x98 => 0x02DC, 0x99 => 0x2122, 0x9A => 0x0161, 0x9B => 0x203A,
|
15
|
+
0x9C => 0x0152, 0x9E => 0x017E, 0x9F => 0x0178
|
16
|
+
).freeze
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
#
|
21
|
-
#
|
18
|
+
FROM_UNICODE = TO_UNICODE.invert.freeze
|
19
|
+
|
20
|
+
# Maps Windows-1252 codes to their corresponding index in the Postscript
|
21
|
+
# glyph table (see TTFunk::Table::Post::Format10). If any entry in this
|
22
|
+
# array is a string, it is a postscript glyph that is not in the standard
|
23
|
+
# list, and which should be emitted specially in the TTF postscript table
|
24
|
+
# ('post', see format 2).
|
25
|
+
# rubocop: disable Metrics/LineLength,Style/AlignArray,Style/IndentArray
|
22
26
|
POSTSCRIPT_GLYPH_MAPPING = [
|
23
27
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
24
28
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
@@ -28,7 +32,7 @@ module TTFunk
|
|
28
32
|
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
|
29
33
|
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
|
30
34
|
83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 0,
|
31
|
-
|
35
|
+
'Euro', 0, 196, 166, 197, 171, 130, 194, 216, 198, 228, 190, 176, 0, 230, 0,
|
32
36
|
0, 182, 183, 180, 181, 135, 178, 179, 217, 140, 229, 191, 177, 0, 231, 186,
|
33
37
|
3, 163, 132, 133, 189, 150, 232, 134, 142, 139, 157, 169, 164, 16, 138, 218,
|
34
38
|
131, 147, 242, 243, 141, 151, 136, 195, 222, 241, 158, 170, 245, 244, 246, 162,
|
@@ -36,26 +40,28 @@ module TTFunk
|
|
36
40
|
233, 102, 211, 208, 209, 175, 103, 240, 145, 214, 212, 213, 104, 235, 237, 137,
|
37
41
|
106, 105, 107, 109, 108, 110, 160, 111, 113, 112, 114, 115, 117, 116, 118, 119,
|
38
42
|
234, 120, 122, 121, 123, 125, 124, 184, 161, 127, 126, 128, 129, 236, 238, 186
|
39
|
-
]
|
43
|
+
].freeze
|
44
|
+
|
45
|
+
# rubocop: enable Style/AlignArray,Metrics/LineLength,Style/ExtraSpacing,Style/IndentArray
|
40
46
|
|
41
47
|
def self.covers?(character)
|
42
48
|
!FROM_UNICODE[character].nil?
|
43
49
|
end
|
44
50
|
|
45
51
|
def self.to_utf8(string)
|
46
|
-
to_unicode_codepoints(string.unpack(
|
52
|
+
to_unicode_codepoints(string.unpack('C*')).pack('U*')
|
47
53
|
end
|
48
54
|
|
49
55
|
def self.to_unicode(string)
|
50
|
-
to_unicode_codepoints(string.unpack(
|
56
|
+
to_unicode_codepoints(string.unpack('C*')).pack('n*')
|
51
57
|
end
|
52
58
|
|
53
59
|
def self.from_utf8(string)
|
54
|
-
from_unicode_codepoints(string.unpack(
|
60
|
+
from_unicode_codepoints(string.unpack('U*')).pack('C*')
|
55
61
|
end
|
56
62
|
|
57
63
|
def self.from_unicode(string)
|
58
|
-
from_unicode_codepoints(string.unpack(
|
64
|
+
from_unicode_codepoints(string.unpack('n*')).pack('C*')
|
59
65
|
end
|
60
66
|
|
61
67
|
def self.to_unicode_codepoints(array)
|
data/lib/ttfunk/reader.rb
CHANGED
@@ -11,31 +11,32 @@ module TTFunk
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def read_signed(count)
|
14
|
-
read(count*2,
|
14
|
+
read(count * 2, 'n*').map { |i| to_signed(i) }
|
15
15
|
end
|
16
16
|
|
17
17
|
def to_signed(n)
|
18
|
-
|
18
|
+
n >= 0x8000 ? -((n ^ 0xFFFF) + 1) : n
|
19
19
|
end
|
20
20
|
|
21
21
|
def parse_from(position)
|
22
|
-
saved
|
22
|
+
saved = io.pos
|
23
|
+
io.pos = position
|
23
24
|
result = yield position
|
24
25
|
io.pos = saved
|
25
|
-
|
26
|
+
result
|
26
27
|
end
|
27
28
|
|
28
29
|
# For debugging purposes
|
29
30
|
def hexdump(string)
|
30
|
-
bytes = string.unpack(
|
31
|
+
bytes = string.unpack('C*')
|
31
32
|
bytes.each_with_index do |c, i|
|
32
|
-
|
33
|
-
if (i+1) % 16 == 0
|
33
|
+
printf('%02X', c)
|
34
|
+
if (i + 1) % 16 == 0
|
34
35
|
puts
|
35
|
-
elsif (i+1) % 8 == 0
|
36
|
-
print
|
36
|
+
elsif (i + 1) % 8 == 0
|
37
|
+
print ' '
|
37
38
|
else
|
38
|
-
print
|
39
|
+
print ' '
|
39
40
|
end
|
40
41
|
end
|
41
42
|
puts unless bytes.length % 16 == 0
|
data/lib/ttfunk/resource_file.rb
CHANGED
@@ -3,7 +3,7 @@ module TTFunk
|
|
3
3
|
attr_reader :map
|
4
4
|
|
5
5
|
def self.open(path)
|
6
|
-
::File.open(path,
|
6
|
+
::File.open(path, 'rb') do |io|
|
7
7
|
file = new(io)
|
8
8
|
yield file
|
9
9
|
end
|
@@ -12,33 +12,39 @@ module TTFunk
|
|
12
12
|
def initialize(io)
|
13
13
|
@io = io
|
14
14
|
|
15
|
-
data_offset, map_offset, map_length = @io.read(16).unpack(
|
15
|
+
data_offset, map_offset, map_length = @io.read(16).unpack('NNx4N')
|
16
16
|
|
17
17
|
@map = {}
|
18
|
-
|
19
|
-
|
18
|
+
# skip header copy, next map handle, file reference, and attrs
|
19
|
+
@io.pos = map_offset + 24
|
20
|
+
type_list_offset, name_list_offset = @io.read(4).unpack('n*')
|
20
21
|
|
21
22
|
type_list_offset += map_offset
|
22
23
|
name_list_offset += map_offset
|
23
24
|
|
24
25
|
@io.pos = type_list_offset
|
25
|
-
max_index = @io.read(2).unpack(
|
26
|
+
max_index = @io.read(2).unpack('n').first
|
26
27
|
0.upto(max_index) do
|
27
|
-
type, max_type_index, ref_list_offset = @io.read(8).unpack(
|
28
|
-
@map[type] = { :
|
28
|
+
type, max_type_index, ref_list_offset = @io.read(8).unpack('A4nn')
|
29
|
+
@map[type] = { list: [], named: {} }
|
29
30
|
|
30
31
|
parse_from(type_list_offset + ref_list_offset) do
|
31
32
|
0.upto(max_type_index) do
|
32
|
-
id, name_ofs, attr = @io.read(5).unpack(
|
33
|
+
id, name_ofs, attr = @io.read(5).unpack('nnC')
|
33
34
|
data_ofs = @io.read(3)
|
34
|
-
data_ofs = data_offset + [0, data_ofs].pack(
|
35
|
-
handle = @io.read(4).unpack(
|
35
|
+
data_ofs = data_offset + [0, data_ofs].pack('CA*').unpack('N').first
|
36
|
+
handle = @io.read(4).unpack('N').first
|
36
37
|
|
37
|
-
entry = {
|
38
|
+
entry = {
|
39
|
+
id: id,
|
40
|
+
attributes: attr,
|
41
|
+
offset: data_ofs,
|
42
|
+
handle: handle
|
43
|
+
}
|
38
44
|
|
39
45
|
if name_list_offset + name_ofs < map_offset + map_length
|
40
46
|
parse_from(name_ofs + name_list_offset) do
|
41
|
-
len = @io.read(1).unpack(
|
47
|
+
len = @io.read(1).unpack('C').first
|
42
48
|
entry[:name] = @io.read(len)
|
43
49
|
end
|
44
50
|
end
|
@@ -50,12 +56,12 @@ module TTFunk
|
|
50
56
|
end
|
51
57
|
end
|
52
58
|
|
53
|
-
def [](type, index=0)
|
59
|
+
def [](type, index = 0)
|
54
60
|
if @map[type]
|
55
|
-
collection = index.is_a?(
|
61
|
+
collection = index.is_a?(Integer) ? :list : :named
|
56
62
|
if @map[type][collection][index]
|
57
63
|
parse_from(@map[type][collection][index][:offset]) do
|
58
|
-
length = @io.read(4).unpack(
|
64
|
+
length = @io.read(4).unpack('N').first
|
59
65
|
return @io.read(length)
|
60
66
|
end
|
61
67
|
end
|
@@ -68,11 +74,12 @@ module TTFunk
|
|
68
74
|
|
69
75
|
private
|
70
76
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
+
def parse_from(offset)
|
78
|
+
saved = @io.pos
|
79
|
+
@io.pos = offset
|
80
|
+
yield
|
81
|
+
ensure
|
82
|
+
@io.pos = saved
|
83
|
+
end
|
77
84
|
end
|
78
85
|
end
|
data/lib/ttfunk/subset.rb
CHANGED
@@ -7,11 +7,11 @@ module TTFunk
|
|
7
7
|
module Subset
|
8
8
|
def self.for(original, encoding)
|
9
9
|
case encoding.to_sym
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
when :unicode then Unicode.new(original)
|
11
|
+
when :unicode_8bit then Unicode8Bit.new(original)
|
12
|
+
when :mac_roman then MacRoman.new(original)
|
13
|
+
when :windows_1252 then Windows1252.new(original)
|
14
|
+
else raise NotImplementedError, "encoding #{encoding} is not supported"
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/ttfunk/subset/base.rb
CHANGED
@@ -27,11 +27,14 @@ module TTFunk
|
|
27
27
|
{}
|
28
28
|
end
|
29
29
|
|
30
|
-
def encode(options={})
|
30
|
+
def encode(options = {})
|
31
31
|
cmap_table = new_cmap_table(options)
|
32
32
|
glyphs = collect_glyphs(original_glyph_ids)
|
33
33
|
|
34
|
-
old2new_glyph = cmap_table[:charmap]
|
34
|
+
old2new_glyph = cmap_table[:charmap]
|
35
|
+
.each_with_object(0 => 0) do |(_, ids), map|
|
36
|
+
map[ids[:old]] = ids[:new]
|
37
|
+
end
|
35
38
|
next_glyph_id = cmap_table[:max_glyph_id]
|
36
39
|
|
37
40
|
glyphs.keys.each do |old_id|
|
@@ -45,29 +48,45 @@ module TTFunk
|
|
45
48
|
|
46
49
|
# "mandatory" tables. Every font should ("should") have these, including
|
47
50
|
# the cmap table (encoded above).
|
48
|
-
glyf_table = TTFunk::Table::Glyf.encode(
|
51
|
+
glyf_table = TTFunk::Table::Glyf.encode(
|
52
|
+
glyphs, new2old_glyph, old2new_glyph
|
53
|
+
)
|
49
54
|
loca_table = TTFunk::Table::Loca.encode(glyf_table[:offsets])
|
50
|
-
hmtx_table = TTFunk::Table::Hmtx.encode(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
hmtx_table = TTFunk::Table::Hmtx.encode(
|
56
|
+
original.horizontal_metrics, new2old_glyph
|
57
|
+
)
|
58
|
+
hhea_table = TTFunk::Table::Hhea.encode(
|
59
|
+
original.horizontal_header, hmtx_table
|
60
|
+
)
|
61
|
+
maxp_table = TTFunk::Table::Maxp.encode(
|
62
|
+
original.maximum_profile, old2new_glyph
|
63
|
+
)
|
64
|
+
post_table = TTFunk::Table::Post.encode(
|
65
|
+
original.postscript, new2old_glyph
|
66
|
+
)
|
67
|
+
name_table = TTFunk::Table::Name.encode(
|
68
|
+
original.name, glyf_table[:table]
|
69
|
+
)
|
70
|
+
head_table = TTFunk::Table::Head.encode(
|
71
|
+
original.header, loca_table
|
72
|
+
)
|
73
|
+
|
74
|
+
# "optional" tables. Fonts may omit these if they do not need them.
|
75
|
+
# Because they apply globally, we can simply copy them over, without
|
76
|
+
# modification, if they exist.
|
60
77
|
os2_table = original.os2.raw
|
61
|
-
cvt_table = TTFunk::Table::Simple.new(original,
|
62
|
-
fpgm_table = TTFunk::Table::Simple.new(original,
|
63
|
-
prep_table = TTFunk::Table::Simple.new(original,
|
78
|
+
cvt_table = TTFunk::Table::Simple.new(original, 'cvt ').raw
|
79
|
+
fpgm_table = TTFunk::Table::Simple.new(original, 'fpgm').raw
|
80
|
+
prep_table = TTFunk::Table::Simple.new(original, 'prep').raw
|
64
81
|
|
65
82
|
# for PDF's, the kerning info is all included in the PDF as the text is
|
66
83
|
# drawn. Thus, the PDF readers do not actually use the kerning info in
|
67
|
-
# embedded fonts. If the library is used for something else, the
|
68
|
-
# subfont may need a kerning table... in that case, you need
|
84
|
+
# embedded fonts. If the library is used for something else, the
|
85
|
+
# generated subfont may need a kerning table... in that case, you need
|
86
|
+
# to opt into it.
|
69
87
|
if options[:kerning]
|
70
|
-
kern_table =
|
88
|
+
kern_table =
|
89
|
+
TTFunk::Table::Kern.encode(original.kerning, old2new_glyph)
|
71
90
|
end
|
72
91
|
|
73
92
|
tables = { 'cmap' => cmap_table[:table],
|
@@ -85,21 +104,27 @@ module TTFunk
|
|
85
104
|
'fpgm' => fpgm_table,
|
86
105
|
'cvt ' => cvt_table }
|
87
106
|
|
88
|
-
tables.delete_if { |
|
107
|
+
tables.delete_if { |_tag, table| table.nil? }
|
89
108
|
|
90
109
|
search_range = (Math.log(tables.length) / Math.log(2)).to_i * 16
|
91
110
|
entry_selector = (Math.log(search_range) / Math.log(2)).to_i
|
92
111
|
range_shift = tables.length * 16 - search_range
|
93
112
|
|
94
|
-
newfont = [
|
113
|
+
newfont = [
|
114
|
+
original.directory.scaler_type,
|
115
|
+
tables.length,
|
116
|
+
search_range,
|
117
|
+
entry_selector,
|
118
|
+
range_shift
|
119
|
+
].pack('Nn*')
|
95
120
|
|
96
121
|
directory_size = tables.length * 16
|
97
122
|
offset = newfont.length + directory_size
|
98
123
|
|
99
|
-
table_data =
|
124
|
+
table_data = ''
|
100
125
|
head_offset = nil
|
101
126
|
tables.each do |tag, data|
|
102
|
-
newfont << [tag, checksum(data), offset, data.length].pack(
|
127
|
+
newfont << [tag, checksum(data), offset, data.length].pack('A4N*')
|
103
128
|
table_data << data
|
104
129
|
head_offset = offset if tag == 'head'
|
105
130
|
offset += data.length
|
@@ -112,30 +137,33 @@ module TTFunk
|
|
112
137
|
newfont << table_data
|
113
138
|
sum = checksum(newfont)
|
114
139
|
adjustment = 0xB1B0AFBA - sum
|
115
|
-
newfont[head_offset+8,4] = [adjustment].pack(
|
140
|
+
newfont[head_offset + 8, 4] = [adjustment].pack('N')
|
116
141
|
|
117
|
-
|
142
|
+
newfont
|
118
143
|
end
|
119
144
|
|
120
145
|
private
|
121
146
|
|
122
|
-
|
123
|
-
|
124
|
-
|
147
|
+
def unicode_cmap
|
148
|
+
@unicode_cmap ||= @original.cmap.unicode.first
|
149
|
+
end
|
125
150
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
151
|
+
def checksum(data)
|
152
|
+
data += "\0" * (4 - data.length % 4) unless data.length % 4 == 0
|
153
|
+
data.unpack('N*').reduce(:+) & 0xFFFF_FFFF
|
154
|
+
end
|
130
155
|
|
131
|
-
|
132
|
-
|
133
|
-
|
156
|
+
def collect_glyphs(glyph_ids)
|
157
|
+
glyphs = glyph_ids.each_with_object({}) do |id, h|
|
158
|
+
h[id] = original.glyph_outlines.for(id)
|
159
|
+
end
|
160
|
+
additional_ids = glyphs.values.select { |g| g && g.compound? }
|
161
|
+
.map(&:glyph_ids).flatten
|
134
162
|
|
135
|
-
|
163
|
+
glyphs.update(collect_glyphs(additional_ids)) if additional_ids.any?
|
136
164
|
|
137
|
-
|
138
|
-
|
165
|
+
glyphs
|
166
|
+
end
|
139
167
|
end
|
140
168
|
end
|
141
169
|
end
|
@@ -34,18 +34,19 @@ module TTFunk
|
|
34
34
|
|
35
35
|
protected
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
TTFunk::Table::Cmap.encode(mapping, :mac_roman)
|
37
|
+
def new_cmap_table(_options)
|
38
|
+
mapping = {}
|
39
|
+
@subset.each_with_index do |unicode, roman|
|
40
|
+
mapping[roman] = unicode_cmap[unicode] if roman
|
44
41
|
end
|
45
42
|
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
TTFunk::Table::Cmap.encode(mapping, :mac_roman)
|
44
|
+
end
|
45
|
+
|
46
|
+
def original_glyph_ids
|
47
|
+
([0] + @subset.map { |unicode| unicode && unicode_cmap[unicode] })
|
48
|
+
.compact.uniq.sort
|
49
|
+
end
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
@@ -14,14 +14,14 @@ module TTFunk
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def to_unicode_map
|
17
|
-
@subset.
|
17
|
+
@subset.each_with_object({}) { |code, map| map[code] = code }
|
18
18
|
end
|
19
19
|
|
20
20
|
def use(character)
|
21
21
|
@subset << character
|
22
22
|
end
|
23
23
|
|
24
|
-
def covers?(
|
24
|
+
def covers?(_character)
|
25
25
|
true
|
26
26
|
end
|
27
27
|
|
@@ -35,14 +35,16 @@ module TTFunk
|
|
35
35
|
|
36
36
|
protected
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
def new_cmap_table(_options)
|
39
|
+
mapping = @subset.each_with_object({}) do |code, map|
|
40
|
+
map[code] = unicode_cmap[code]
|
41
41
|
end
|
42
|
+
TTFunk::Table::Cmap.encode(mapping, :unicode)
|
43
|
+
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
def original_glyph_ids
|
46
|
+
([0] + @subset.map { |code| unicode_cmap[code] }).uniq.sort
|
47
|
+
end
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|