ttfunk 1.7.0 → 1.8.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/CHANGELOG.md +74 -0
- data/README.md +17 -15
- data/lib/ttfunk/aggregate.rb +5 -0
- data/lib/ttfunk/bin_utils.rb +27 -8
- data/lib/ttfunk/bit_field.rb +25 -2
- data/lib/ttfunk/collection.rb +27 -3
- data/lib/ttfunk/directory.rb +7 -1
- data/lib/ttfunk/encoded_string.rb +58 -4
- data/lib/ttfunk/max.rb +14 -0
- data/lib/ttfunk/min.rb +14 -0
- data/lib/ttfunk/one_based_array.rb +20 -0
- data/lib/ttfunk/otf_encoder.rb +5 -14
- data/lib/ttfunk/placeholder.rb +15 -1
- data/lib/ttfunk/reader.rb +6 -4
- data/lib/ttfunk/resource_file.rb +29 -5
- data/lib/ttfunk/sci_form.rb +20 -3
- data/lib/ttfunk/sub_table.rb +29 -4
- data/lib/ttfunk/subset/base.rb +48 -0
- data/lib/ttfunk/subset/code_page.rb +49 -2
- data/lib/ttfunk/subset/mac_roman.rb +2 -0
- data/lib/ttfunk/subset/unicode.rb +32 -0
- data/lib/ttfunk/subset/unicode_8bit.rb +32 -0
- data/lib/ttfunk/subset/windows_1252.rb +2 -0
- data/lib/ttfunk/subset.rb +8 -0
- data/lib/ttfunk/subset_collection.rb +39 -14
- data/lib/ttfunk/sum.rb +13 -0
- data/lib/ttfunk/table/cff/charset.rb +96 -18
- data/lib/ttfunk/table/cff/charsets/expert.rb +3 -2
- data/lib/ttfunk/table/cff/charsets/expert_subset.rb +3 -2
- data/lib/ttfunk/table/cff/charsets/iso_adobe.rb +3 -2
- data/lib/ttfunk/table/cff/charsets/standard_strings.rb +3 -2
- data/lib/ttfunk/table/cff/charsets.rb +1 -0
- data/lib/ttfunk/table/cff/charstring.rb +33 -12
- data/lib/ttfunk/table/cff/charstrings_index.rb +17 -11
- data/lib/ttfunk/table/cff/dict.rb +53 -23
- data/lib/ttfunk/table/cff/encoding.rb +82 -24
- data/lib/ttfunk/table/cff/encodings/expert.rb +3 -2
- data/lib/ttfunk/table/cff/encodings/standard.rb +3 -2
- data/lib/ttfunk/table/cff/encodings.rb +1 -0
- data/lib/ttfunk/table/cff/fd_selector.rb +61 -21
- data/lib/ttfunk/table/cff/font_dict.rb +30 -18
- data/lib/ttfunk/table/cff/font_index.rb +22 -10
- data/lib/ttfunk/table/cff/header.rb +16 -3
- data/lib/ttfunk/table/cff/index.rb +97 -65
- data/lib/ttfunk/table/cff/one_based_index.rb +11 -1
- data/lib/ttfunk/table/cff/path.rb +43 -4
- data/lib/ttfunk/table/cff/private_dict.rb +31 -11
- data/lib/ttfunk/table/cff/subr_index.rb +7 -2
- data/lib/ttfunk/table/cff/top_dict.rb +82 -59
- data/lib/ttfunk/table/cff/top_index.rb +10 -6
- data/lib/ttfunk/table/cff.rb +41 -21
- data/lib/ttfunk/table/cmap/format00.rb +27 -6
- data/lib/ttfunk/table/cmap/format04.rb +34 -14
- data/lib/ttfunk/table/cmap/format06.rb +28 -1
- data/lib/ttfunk/table/cmap/format10.rb +29 -2
- data/lib/ttfunk/table/cmap/format12.rb +29 -2
- data/lib/ttfunk/table/cmap/subtable.rb +50 -6
- data/lib/ttfunk/table/cmap.rb +21 -0
- data/lib/ttfunk/table/dsig.rb +47 -6
- data/lib/ttfunk/table/glyf/compound.rb +73 -6
- data/lib/ttfunk/table/glyf/path_based.rb +40 -3
- data/lib/ttfunk/table/glyf/simple.rb +50 -5
- data/lib/ttfunk/table/glyf.rb +15 -7
- data/lib/ttfunk/table/head.rb +84 -6
- data/lib/ttfunk/table/hhea.rb +71 -10
- data/lib/ttfunk/table/hmtx.rb +32 -5
- data/lib/ttfunk/table/kern/format0.rb +25 -7
- data/lib/ttfunk/table/kern.rb +16 -4
- data/lib/ttfunk/table/loca.rb +21 -8
- data/lib/ttfunk/table/maxp.rb +195 -10
- data/lib/ttfunk/table/name.rb +126 -9
- data/lib/ttfunk/table/os2.rb +150 -26
- data/lib/ttfunk/table/post/format10.rb +7 -0
- data/lib/ttfunk/table/post/format20.rb +9 -0
- data/lib/ttfunk/table/post/format30.rb +6 -0
- data/lib/ttfunk/table/post/format40.rb +5 -0
- data/lib/ttfunk/table/post.rb +63 -7
- data/lib/ttfunk/table/sbix.rb +50 -14
- data/lib/ttfunk/table/simple.rb +5 -0
- data/lib/ttfunk/table/vorg.rb +31 -3
- data/lib/ttfunk/table.rb +20 -1
- data/lib/ttfunk/ttf_encoder.rb +39 -41
- data/lib/ttfunk.rb +154 -1
- data.tar.gz.sig +0 -0
- metadata +50 -28
- metadata.gz.sig +0 -0
data/lib/ttfunk/table/os2.rb
CHANGED
@@ -5,44 +5,147 @@ require 'set'
|
|
5
5
|
|
6
6
|
module TTFunk
|
7
7
|
class Table
|
8
|
+
# OS/2 and Windows Metrics (`OS/2`) table
|
8
9
|
class OS2 < Table
|
10
|
+
# Table version.
|
11
|
+
# @return [Integer]
|
9
12
|
attr_reader :version
|
10
13
|
|
14
|
+
# Average weighted escapement.
|
15
|
+
# @return [Integer]
|
11
16
|
attr_reader :ave_char_width
|
17
|
+
|
18
|
+
# Weight class.
|
19
|
+
# @return [Integer]
|
12
20
|
attr_reader :weight_class
|
21
|
+
|
22
|
+
# Width class.
|
23
|
+
# @return [Integer]
|
13
24
|
attr_reader :width_class
|
25
|
+
|
26
|
+
# Type flags.
|
27
|
+
# @return [Integer]
|
14
28
|
attr_reader :type
|
29
|
+
|
30
|
+
# Subscript horizontal font size.
|
31
|
+
# @return [Integer]
|
15
32
|
attr_reader :y_subscript_x_size
|
33
|
+
|
34
|
+
# Subscript vertical font size.
|
35
|
+
# @return [Integer]
|
16
36
|
attr_reader :y_subscript_y_size
|
37
|
+
|
38
|
+
# Subscript x offset.
|
39
|
+
# @return [Integer]
|
17
40
|
attr_reader :y_subscript_x_offset
|
41
|
+
|
42
|
+
# Subscript y offset.
|
43
|
+
# @return [Integer]
|
18
44
|
attr_reader :y_subscript_y_offset
|
45
|
+
|
46
|
+
# Superscript horizontal font size.
|
47
|
+
# @return [Integer]
|
19
48
|
attr_reader :y_superscript_x_size
|
49
|
+
|
50
|
+
# Superscript vertical font size.
|
51
|
+
# @return [Integer]
|
20
52
|
attr_reader :y_superscript_y_size
|
53
|
+
|
54
|
+
# Superscript x offset.
|
55
|
+
# @return [Integer]
|
21
56
|
attr_reader :y_superscript_x_offset
|
57
|
+
|
58
|
+
# Superscript y offset.
|
59
|
+
# @return [Integer]
|
22
60
|
attr_reader :y_superscript_y_offset
|
61
|
+
|
62
|
+
# Strikeout size.
|
63
|
+
# @return [Integer]
|
23
64
|
attr_reader :y_strikeout_size
|
65
|
+
|
66
|
+
# Strikeout position.
|
67
|
+
# @return [Integer]
|
24
68
|
attr_reader :y_strikeout_position
|
69
|
+
|
70
|
+
# Font-family class and subclass.
|
71
|
+
# @return [Integer]
|
25
72
|
attr_reader :family_class
|
73
|
+
|
74
|
+
# PANOSE classification number.
|
75
|
+
# @return [Integer]
|
26
76
|
attr_reader :panose
|
77
|
+
|
78
|
+
# Unicode Character Range.
|
79
|
+
# @return [Integer]
|
27
80
|
attr_reader :char_range
|
81
|
+
|
82
|
+
# Font Vendor Identification.
|
83
|
+
# @return [String]
|
28
84
|
attr_reader :vendor_id
|
85
|
+
|
86
|
+
# Font selection flags.
|
87
|
+
# @return [Integer]
|
29
88
|
attr_reader :selection
|
89
|
+
|
90
|
+
# The minimum Unicode index (character code) in this font.
|
91
|
+
# @return [Integer]
|
30
92
|
attr_reader :first_char_index
|
93
|
+
|
94
|
+
# The maximum Unicode index (character code) in this font.
|
95
|
+
# @return [Integer]
|
31
96
|
attr_reader :last_char_index
|
32
97
|
|
98
|
+
# The typographic ascender for this font.
|
99
|
+
# @return [Integer]
|
33
100
|
attr_reader :ascent
|
101
|
+
|
102
|
+
# The typographic descender for this font.
|
103
|
+
# @return [Integer]
|
34
104
|
attr_reader :descent
|
105
|
+
|
106
|
+
# The typographic line gap for this font.
|
107
|
+
# @return [Integer]
|
35
108
|
attr_reader :line_gap
|
109
|
+
|
110
|
+
# The "Windows ascender" metric.
|
111
|
+
# @return [Integer]
|
36
112
|
attr_reader :win_ascent
|
113
|
+
|
114
|
+
# The "Windows descender" metric.
|
115
|
+
# @return [Integer]
|
37
116
|
attr_reader :win_descent
|
117
|
+
|
118
|
+
# Code Page Character Range.
|
119
|
+
# @return [Integer]
|
38
120
|
attr_reader :code_page_range
|
39
121
|
|
122
|
+
# The distance between the baseline and the approximate height of
|
123
|
+
# non-ascending lowercase letters.
|
124
|
+
# @return [Integer]
|
40
125
|
attr_reader :x_height
|
126
|
+
|
127
|
+
# The distance between the baseline and the approximate height of
|
128
|
+
# uppercase letters.
|
129
|
+
# @return [Integer]
|
41
130
|
attr_reader :cap_height
|
131
|
+
|
132
|
+
# The Unicode code point, in UTF-16 encoding, of a character that can be
|
133
|
+
# used for a default glyph if a requested character is not supported in
|
134
|
+
# the font.
|
135
|
+
# @return [Integer]
|
42
136
|
attr_reader :default_char
|
137
|
+
|
138
|
+
# The Unicode code point, in UTF-16 encoding, of a character that can be
|
139
|
+
# used as a default break character.
|
140
|
+
# @return [Integer]
|
43
141
|
attr_reader :break_char
|
142
|
+
|
143
|
+
# The maximum length of a target glyph context for any feature in this
|
144
|
+
# font.
|
145
|
+
# @return [Integer]
|
44
146
|
attr_reader :max_context
|
45
147
|
|
148
|
+
# Code page bits.
|
46
149
|
CODE_PAGE_BITS = {
|
47
150
|
1252 => 0,
|
48
151
|
1250 => 1,
|
@@ -75,9 +178,10 @@ module TTFunk
|
|
75
178
|
737 => 60,
|
76
179
|
708 => 61,
|
77
180
|
850 => 62,
|
78
|
-
437 => 63
|
181
|
+
437 => 63,
|
79
182
|
}.freeze
|
80
183
|
|
184
|
+
# Unicode blocks.
|
81
185
|
UNICODE_BLOCKS = {
|
82
186
|
(0x0000..0x007F) => 0,
|
83
187
|
(0x0080..0x00FF) => 1,
|
@@ -247,17 +351,29 @@ module TTFunk
|
|
247
351
|
(0x10280..0x1029F) => 121,
|
248
352
|
(0x10920..0x1093F) => 121,
|
249
353
|
(0x1F030..0x1F09F) => 122,
|
250
|
-
(0x1F000..0x1F02F) => 122
|
354
|
+
(0x1F000..0x1F02F) => 122,
|
251
355
|
}.freeze
|
252
356
|
|
357
|
+
# Indicates that font supports supplementary characters.
|
253
358
|
UNICODE_MAX = 0xFFFF
|
254
|
-
|
359
|
+
|
360
|
+
# Unicode block ranges.
|
361
|
+
UNICODE_RANGES = UNICODE_BLOCKS.keys.sort_by(&:max).freeze
|
362
|
+
|
363
|
+
# Start chracter for average character width calculation.
|
255
364
|
LOWERCASE_START = 'a'.ord
|
365
|
+
|
366
|
+
# End chracter for average character width calculation.
|
256
367
|
LOWERCASE_END = 'z'.ord
|
368
|
+
|
369
|
+
# Number of chracters for average character width calculation.
|
257
370
|
LOWERCASE_COUNT = (LOWERCASE_END - LOWERCASE_START) + 1
|
371
|
+
|
372
|
+
# Space character code point.
|
258
373
|
CODEPOINT_SPACE = 32
|
259
|
-
|
260
|
-
|
374
|
+
|
375
|
+
# Error message for missing space character.
|
376
|
+
SPACE_GLYPH_MISSING_ERROR = "Space glyph (0x#{CODEPOINT_SPACE.to_s(16)}) must be included in the font"
|
261
377
|
|
262
378
|
# Used to calculate the xAvgCharWidth field.
|
263
379
|
# From https://docs.microsoft.com/en-us/typography/opentype/spec/os2:
|
@@ -272,16 +388,26 @@ module TTFunk
|
|
272
388
|
# 26 letters in the Latin alphabet. Each weight is the relative
|
273
389
|
# frequency of that letter in the English language.
|
274
390
|
WEIGHT_SPACE = 166
|
391
|
+
|
392
|
+
# chracter weights for average character width calculation.
|
275
393
|
WEIGHT_LOWERCASE = [
|
276
394
|
64, 14, 27, 35, 100, 20, 14, 42, 63, 3, 6, 35, 20,
|
277
|
-
56, 56, 17, 4, 49, 56, 71, 31, 10, 18, 3, 18, 2
|
395
|
+
56, 56, 17, 4, 49, 56, 71, 31, 10, 18, 3, 18, 2,
|
278
396
|
].freeze
|
279
397
|
|
398
|
+
# Table tag.
|
399
|
+
# @return [String]
|
280
400
|
def tag
|
281
401
|
'OS/2'
|
282
402
|
end
|
283
403
|
|
284
404
|
class << self
|
405
|
+
# Encode table.
|
406
|
+
#
|
407
|
+
# @param os2 [TTFunk::Table::OS2]
|
408
|
+
# @param subset [TTFunk::Subset::MacRoman, TTFunk::Subset::Windows1252,
|
409
|
+
# TTFunk::Subset::Unicode, TTFunk::Subset::Unicode8Bit]
|
410
|
+
# @return [String]
|
285
411
|
def encode(os2, subset)
|
286
412
|
result = ''.b
|
287
413
|
result << [
|
@@ -291,7 +417,7 @@ module TTFunk
|
|
291
417
|
os2.y_subscript_y_offset, os2.y_superscript_x_size,
|
292
418
|
os2.y_superscript_y_size, os2.y_superscript_x_offset,
|
293
419
|
os2.y_superscript_y_offset, os2.y_strikeout_size,
|
294
|
-
os2.y_strikeout_position, os2.family_class
|
420
|
+
os2.y_strikeout_position, os2.family_class,
|
295
421
|
].pack('n*')
|
296
422
|
|
297
423
|
result << os2.panose
|
@@ -301,7 +427,7 @@ module TTFunk
|
|
301
427
|
.slice_int(
|
302
428
|
new_char_range.value,
|
303
429
|
bit_width: 32,
|
304
|
-
slice_count: 4
|
430
|
+
slice_count: 4,
|
305
431
|
)
|
306
432
|
.pack('N*')
|
307
433
|
|
@@ -322,27 +448,27 @@ module TTFunk
|
|
322
448
|
last_char_index = [code_points.last || 0, UNICODE_MAX].min
|
323
449
|
|
324
450
|
result << [
|
325
|
-
os2.selection, first_char_index, last_char_index
|
451
|
+
os2.selection, first_char_index, last_char_index,
|
326
452
|
].pack('n*')
|
327
453
|
|
328
454
|
if os2.version.positive?
|
329
455
|
result << [
|
330
456
|
os2.ascent, os2.descent, os2.line_gap,
|
331
|
-
os2.win_ascent, os2.win_descent
|
457
|
+
os2.win_ascent, os2.win_descent,
|
332
458
|
].pack('n*')
|
333
459
|
|
334
460
|
result << BinUtils
|
335
461
|
.slice_int(
|
336
462
|
code_pages_for(subset).value,
|
337
463
|
bit_width: 32,
|
338
|
-
slice_count: 2
|
464
|
+
slice_count: 2,
|
339
465
|
)
|
340
466
|
.pack('N*')
|
341
467
|
|
342
468
|
if os2.version > 1
|
343
469
|
result << [
|
344
470
|
os2.x_height, os2.cap_height, os2.default_char,
|
345
|
-
os2.break_char, os2.max_context
|
471
|
+
os2.break_char, os2.max_context,
|
346
472
|
].pack('n*')
|
347
473
|
end
|
348
474
|
end
|
@@ -380,13 +506,15 @@ module TTFunk
|
|
380
506
|
|
381
507
|
def group_original_code_points_by_bit(os2)
|
382
508
|
Hash.new { |h, k| h[k] = [] }.tap do |result|
|
383
|
-
os2.file.cmap.unicode.first.code_map.
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
509
|
+
code_points = os2.file.cmap.unicode.first.code_map.keys.sort
|
510
|
+
UNICODE_RANGES.each do |r|
|
511
|
+
code_points = code_points.drop_while { |p| p < r.min }
|
512
|
+
code_points.take_while { |p| p <= r.max }.each do |code_point|
|
513
|
+
if (bit = UNICODE_BLOCKS[r])
|
514
|
+
result[bit] << code_point
|
515
|
+
end
|
389
516
|
end
|
517
|
+
code_points = code_points.drop_while { |p| p <= r.max }
|
390
518
|
end
|
391
519
|
end
|
392
520
|
end
|
@@ -405,7 +533,7 @@ module TTFunk
|
|
405
533
|
|
406
534
|
# use new -> old glyph mapping in order to include compound glyphs
|
407
535
|
# in the calculation
|
408
|
-
subset.new_to_old_glyph.
|
536
|
+
subset.new_to_old_glyph.each_value do |old_gid|
|
409
537
|
if (metric = os2.file.horizontal_metrics.for(old_gid))
|
410
538
|
total_width += metric.advance_width
|
411
539
|
num_glyphs += 1 if metric.advance_width.positive?
|
@@ -456,7 +584,7 @@ module TTFunk
|
|
456
584
|
|
457
585
|
# use new -> old glyph mapping in order to include compound glyphs
|
458
586
|
# in the calculation
|
459
|
-
subset.new_to_old_glyph.
|
587
|
+
subset.new_to_old_glyph.each_value do |old_gid|
|
460
588
|
if (metric = os2.file.horizontal_metrics.for(old_gid))
|
461
589
|
total_width += metric.advance_width
|
462
590
|
end
|
@@ -481,9 +609,7 @@ module TTFunk
|
|
481
609
|
@y_strikeout_position, @family_class = read_signed(12)
|
482
610
|
@panose = io.read(10)
|
483
611
|
|
484
|
-
@char_range = BitField.new(
|
485
|
-
BinUtils.stitch_int(read(16, 'N*'), bit_width: 32)
|
486
|
-
)
|
612
|
+
@char_range = BitField.new(BinUtils.stitch_int(read(16, 'N*'), bit_width: 32))
|
487
613
|
|
488
614
|
@vendor_id = io.read(4)
|
489
615
|
@selection, @first_char_index, @last_char_index = read(6, 'n*')
|
@@ -491,9 +617,7 @@ module TTFunk
|
|
491
617
|
if @version.positive?
|
492
618
|
@ascent, @descent, @line_gap = read_signed(3)
|
493
619
|
@win_ascent, @win_descent = read(4, 'nn')
|
494
|
-
@code_page_range = BitField.new(
|
495
|
-
BinUtils.stitch_int(read(8, 'N*'), bit_width: 32)
|
496
|
-
)
|
620
|
+
@code_page_range = BitField.new(BinUtils.stitch_int(read(8, 'N*'), bit_width: 32))
|
497
621
|
|
498
622
|
if @version > 1
|
499
623
|
@x_height, @cap_height = read_signed(2)
|
@@ -3,7 +3,10 @@
|
|
3
3
|
module TTFunk
|
4
4
|
class Table
|
5
5
|
class Post
|
6
|
+
# Version 1.0 provides glyph names for standard 258 glyphs in the standard
|
7
|
+
# Macintosh TrueType font file.
|
6
8
|
module Format10
|
9
|
+
# Glyph names.
|
7
10
|
POSTSCRIPT_GLYPHS = %w[
|
8
11
|
.notdef .null nonmarkingreturn space exclam quotedbl numbersign dollar
|
9
12
|
percent ampersand quotesingle parenleft parenright asterisk plus comma
|
@@ -36,6 +39,10 @@ module TTFunk
|
|
36
39
|
scedilla Cacute cacute Ccaron ccaron dcroat
|
37
40
|
].freeze
|
38
41
|
|
42
|
+
# Get glyph name for character code.
|
43
|
+
#
|
44
|
+
# @param code [Integer]
|
45
|
+
# @return [String]
|
39
46
|
def glyph_for(code)
|
40
47
|
POSTSCRIPT_GLYPHS[code] || '.notdef'
|
41
48
|
end
|
@@ -6,9 +6,18 @@ require 'stringio'
|
|
6
6
|
module TTFunk
|
7
7
|
class Table
|
8
8
|
class Post
|
9
|
+
# Version 2.0 is used for fonts that use glyph names that are not in the
|
10
|
+
# set of Macintosh glyph names. A given font may map some of its glyphs to
|
11
|
+
# the standard Macintosh glyph names, and some to its own custom names.
|
12
|
+
# A version 2.0 `post` table can be used in fonts with TrueType or CFF
|
13
|
+
# version 2 outlines.
|
9
14
|
module Format20
|
10
15
|
include Format10
|
11
16
|
|
17
|
+
# Get glyph name for character code.
|
18
|
+
#
|
19
|
+
# @param code [Integer]
|
20
|
+
# @return [String]
|
12
21
|
def glyph_for(code)
|
13
22
|
index = @glyph_name_index[code]
|
14
23
|
return '.notdef' unless index
|
@@ -3,7 +3,13 @@
|
|
3
3
|
module TTFunk
|
4
4
|
class Table
|
5
5
|
class Post
|
6
|
+
# Version 3.0 specifies that no PostScript name information is provided
|
7
|
+
# for the glyphs in this font file.
|
6
8
|
module Format30
|
9
|
+
# Get glyph name for character code.
|
10
|
+
#
|
11
|
+
# @param _code [Integer]
|
12
|
+
# @return [String]
|
7
13
|
def glyph_for(_code)
|
8
14
|
'.notdef'
|
9
15
|
end
|
@@ -3,7 +3,12 @@
|
|
3
3
|
module TTFunk
|
4
4
|
class Table
|
5
5
|
class Post
|
6
|
+
# Version 4.0 names glyphs by their character code.
|
6
7
|
module Format40
|
8
|
+
# Get glyph name for character code.
|
9
|
+
#
|
10
|
+
# @param code [Integer]
|
11
|
+
# @return [String]
|
7
12
|
def glyph_for(code)
|
8
13
|
@map[code] || 0xFFFF
|
9
14
|
end
|
data/lib/ttfunk/table/post.rb
CHANGED
@@ -4,33 +4,93 @@ require_relative '../table'
|
|
4
4
|
|
5
5
|
module TTFunk
|
6
6
|
class Table
|
7
|
+
# PostScript (`post`) table.
|
8
|
+
#
|
9
|
+
# This class can be extended with version-specific modules.
|
10
|
+
#
|
11
|
+
# @see TTFunk::Table::Post::Format10
|
12
|
+
# @see TTFunk::Table::Post::Format20
|
13
|
+
# @see TTFunk::Table::Post::Format30
|
14
|
+
# @see TTFunk::Table::Post::Format40
|
7
15
|
class Post < Table
|
16
|
+
# Table version.
|
17
|
+
# @return [Integer]
|
8
18
|
attr_reader :format
|
19
|
+
|
20
|
+
# Italic angle in counter-clockwise degrees from the vertical.
|
21
|
+
# @return [Integer]
|
9
22
|
attr_reader :italic_angle
|
23
|
+
|
24
|
+
# Suggested distance of the top of the underline from the baseline
|
25
|
+
# @return [Integer]
|
10
26
|
attr_reader :underline_position
|
27
|
+
|
28
|
+
# Suggested values for the underline thickness.
|
29
|
+
# @return [Integer]
|
11
30
|
attr_reader :underline_thickness
|
31
|
+
|
32
|
+
# 0 if the font is proportionally spaced, non-zero if the font is not
|
33
|
+
# proportionally spaced.
|
34
|
+
# @return [Integer]
|
12
35
|
attr_reader :fixed_pitch
|
36
|
+
|
37
|
+
# Minimum memory usage when an OpenType font is downloaded.
|
38
|
+
# @return [Integer]
|
13
39
|
attr_reader :min_mem_type42
|
40
|
+
|
41
|
+
# Maximum memory usage when an OpenType font is downloaded.
|
42
|
+
# @return [Integer]
|
14
43
|
attr_reader :max_mem_type42
|
44
|
+
|
45
|
+
# Minimum memory usage when an OpenType font is downloaded as
|
46
|
+
# a Type 1 font.
|
47
|
+
# @return [Integer]
|
15
48
|
attr_reader :min_mem_type1
|
49
|
+
|
50
|
+
# Maximum memory usage when an OpenType font is downloaded as
|
51
|
+
# a Type 1 font.
|
52
|
+
# @return [Integer]
|
16
53
|
attr_reader :max_mem_type1
|
17
54
|
|
55
|
+
# Version-specific fields.
|
56
|
+
# @return [TTFunk::Table::Post::Format10, TTFunk::Table::Post::Format20,
|
57
|
+
# TTFunk::Table::Post::Format30, TTFunk::Table::Post::Format40]
|
18
58
|
attr_reader :subtable
|
19
59
|
|
60
|
+
# Encode table.
|
61
|
+
#
|
62
|
+
# @param post [TTFunk::Table::Post]
|
63
|
+
# @param mapping [Hash{Integer => Integer}] keys are new glyph IDs, values
|
64
|
+
# are old glyph IDs
|
65
|
+
# @return [String, nil]
|
20
66
|
def self.encode(post, mapping)
|
21
|
-
return
|
67
|
+
return if post.nil?
|
22
68
|
|
23
69
|
post.recode(mapping)
|
24
70
|
end
|
25
71
|
|
72
|
+
# Is this font monospaced?
|
73
|
+
#
|
74
|
+
# @return [Boolean]
|
26
75
|
def fixed_pitch?
|
27
76
|
@fixed_pitch != 0
|
28
77
|
end
|
29
78
|
|
79
|
+
# Get glyph name for character code.
|
80
|
+
#
|
81
|
+
# This is a placeholder.
|
82
|
+
#
|
83
|
+
# @param _code [Integer]
|
84
|
+
# @return [String]
|
30
85
|
def glyph_for(_code)
|
31
86
|
'.notdef'
|
32
87
|
end
|
33
88
|
|
89
|
+
# Re-encode this table.
|
90
|
+
#
|
91
|
+
# @param mapping [Hash{Integer => Integer}] keys are new glyph IDs, values
|
92
|
+
# are old glyph IDs
|
93
|
+
# @return [String]
|
34
94
|
def recode(mapping)
|
35
95
|
return raw if format == 0x00030000
|
36
96
|
|
@@ -46,7 +106,7 @@ module TTFunk
|
|
46
106
|
if position
|
47
107
|
index << position
|
48
108
|
else
|
49
|
-
index << 257 + strings.length
|
109
|
+
index << (257 + strings.length)
|
50
110
|
strings << post_glyph
|
51
111
|
end
|
52
112
|
end
|
@@ -85,11 +145,7 @@ module TTFunk
|
|
85
145
|
end
|
86
146
|
|
87
147
|
def parse_format!
|
88
|
-
warn(
|
89
|
-
Kernel.format(
|
90
|
-
'postscript table format 0x%08X is not supported', @format
|
91
|
-
)
|
92
|
-
)
|
148
|
+
warn(Kernel.format('postscript table format 0x%08X is not supported', @format))
|
93
149
|
end
|
94
150
|
end
|
95
151
|
end
|
data/lib/ttfunk/table/sbix.rb
CHANGED
@@ -4,14 +4,48 @@ require_relative '../table'
|
|
4
4
|
|
5
5
|
module TTFunk
|
6
6
|
class Table
|
7
|
+
# Standard Bitmap Graphics (`sbix`) table.
|
7
8
|
class Sbix < Table
|
9
|
+
# Table version.
|
10
|
+
# @return [Integer]
|
8
11
|
attr_reader :version
|
12
|
+
|
13
|
+
# Flags.
|
14
|
+
# @return [Integer]
|
9
15
|
attr_reader :flags
|
16
|
+
|
17
|
+
# Number of bitmap strikes.
|
18
|
+
# @return [Integer]
|
10
19
|
attr_reader :num_strikes
|
20
|
+
|
21
|
+
# Strikes.
|
22
|
+
# @return [Array<Hash>]
|
11
23
|
attr_reader :strikes
|
12
24
|
|
25
|
+
# Bitmap Data.
|
26
|
+
#
|
27
|
+
# @!attribute [rw] x
|
28
|
+
# The horizontal (x-axis) position of the left edge of the bitmap
|
29
|
+
# graphic in relation to the glyph design space origin.
|
30
|
+
# @!attribute [rw] y
|
31
|
+
# The vertical (y-axis) position of the bottom edge of the bitmap
|
32
|
+
# graphic in relation to the glyph design space origin.
|
33
|
+
# @!attribute [rw] type
|
34
|
+
# Indicates the format of the embedded graphic data: one of `jpg `,
|
35
|
+
# `png `, `tiff`, or the special format `dupe`.
|
36
|
+
# @!attribute [rw] data
|
37
|
+
# The actual embedded graphic data.
|
38
|
+
# @!attribute [rw] ppem
|
39
|
+
# The PPEM size for which this strike was designed.
|
40
|
+
# @!attribute [rw] resolution
|
41
|
+
# The device pixel density (in PPI) for which this strike was designed.
|
13
42
|
BitmapData = Struct.new(:x, :y, :type, :data, :ppem, :resolution)
|
14
43
|
|
44
|
+
# Get bitmap for glyph strike.
|
45
|
+
#
|
46
|
+
# @param glyph_id [Integer]
|
47
|
+
# @param strike_index [Integer]
|
48
|
+
# @return [BitmapData]
|
15
49
|
def bitmap_data_for(glyph_id, strike_index)
|
16
50
|
strike = strikes[strike_index]
|
17
51
|
return if strike.nil?
|
@@ -22,21 +56,23 @@ module TTFunk
|
|
22
56
|
if glyph_offset && next_glyph_offset
|
23
57
|
bytes = next_glyph_offset - glyph_offset
|
24
58
|
if bytes.positive?
|
25
|
-
parse_from(offset + strike[:offset] + glyph_offset)
|
59
|
+
parse_from(offset + strike[:offset] + glyph_offset) {
|
26
60
|
x, y, type = read(8, 's2A4')
|
27
61
|
data = StringIO.new(io.read(bytes - 8))
|
28
|
-
BitmapData.new(
|
29
|
-
|
30
|
-
)
|
31
|
-
end
|
62
|
+
BitmapData.new(x, y, type, data, strike[:ppem], strike[:resolution])
|
63
|
+
}
|
32
64
|
end
|
33
65
|
end
|
34
66
|
end
|
35
67
|
|
68
|
+
# Get all bitmaps for glyph.
|
69
|
+
#
|
70
|
+
# @param glyph_id [Integer]
|
71
|
+
# @return [Array<BitmapData>]
|
36
72
|
def all_bitmap_data_for(glyph_id)
|
37
|
-
strikes.each_index.
|
73
|
+
strikes.each_index.filter_map { |strike_index|
|
38
74
|
bitmap_data_for(glyph_id, strike_index)
|
39
|
-
|
75
|
+
}
|
40
76
|
end
|
41
77
|
|
42
78
|
private
|
@@ -46,21 +82,21 @@ module TTFunk
|
|
46
82
|
strike_offsets = Array.new(num_strikes) { read(4, 'N').first }
|
47
83
|
|
48
84
|
@strikes =
|
49
|
-
strike_offsets.map
|
50
|
-
parse_from(offset + strike_offset)
|
85
|
+
strike_offsets.map { |strike_offset|
|
86
|
+
parse_from(offset + strike_offset) {
|
51
87
|
ppem, resolution = read(4, 'n2')
|
52
88
|
data_offsets =
|
53
|
-
Array.new(file.maximum_profile.num_glyphs + 1)
|
89
|
+
Array.new(file.maximum_profile.num_glyphs + 1) {
|
54
90
|
read(4, 'N').first
|
55
|
-
|
91
|
+
}
|
56
92
|
{
|
57
93
|
ppem: ppem,
|
58
94
|
resolution: resolution,
|
59
95
|
offset: strike_offset,
|
60
|
-
glyph_data_offset: data_offsets
|
96
|
+
glyph_data_offset: data_offsets,
|
61
97
|
}
|
62
|
-
|
63
|
-
|
98
|
+
}
|
99
|
+
}
|
64
100
|
end
|
65
101
|
end
|
66
102
|
end
|
data/lib/ttfunk/table/simple.rb
CHANGED
@@ -4,9 +4,14 @@ require_relative '../table'
|
|
4
4
|
|
5
5
|
module TTFunk
|
6
6
|
class Table
|
7
|
+
# A table that TTFunk doesn't decode but preserve.
|
7
8
|
class Simple < Table
|
9
|
+
# Table tag
|
10
|
+
# @return [String]
|
8
11
|
attr_reader :tag
|
9
12
|
|
13
|
+
# @param file [TTFunk::File]
|
14
|
+
# @param tag [String]
|
10
15
|
def initialize(file, tag)
|
11
16
|
@tag = tag
|
12
17
|
super(file)
|