ttfunk 1.6.2.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -1
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +15 -1
  5. data/lib/ttfunk.rb +3 -2
  6. data/lib/ttfunk/bit_field.rb +1 -1
  7. data/lib/ttfunk/collection.rb +8 -2
  8. data/lib/ttfunk/encoded_string.rb +3 -3
  9. data/lib/ttfunk/max.rb +1 -0
  10. data/lib/ttfunk/min.rb +1 -0
  11. data/lib/ttfunk/one_based_array.rb +1 -1
  12. data/lib/ttfunk/otf_encoder.rb +1 -1
  13. data/lib/ttfunk/reader.rb +3 -3
  14. data/lib/ttfunk/sci_form.rb +1 -1
  15. data/lib/ttfunk/subset.rb +3 -3
  16. data/lib/ttfunk/subset/base.rb +24 -21
  17. data/lib/ttfunk/subset/code_page.rb +16 -19
  18. data/lib/ttfunk/subset/unicode.rb +8 -6
  19. data/lib/ttfunk/subset/unicode_8bit.rb +14 -12
  20. data/lib/ttfunk/sum.rb +1 -0
  21. data/lib/ttfunk/table/cff.rb +17 -17
  22. data/lib/ttfunk/table/cff/charset.rb +31 -30
  23. data/lib/ttfunk/table/cff/charsets.rb +3 -3
  24. data/lib/ttfunk/table/cff/charstring.rb +54 -55
  25. data/lib/ttfunk/table/cff/dict.rb +6 -4
  26. data/lib/ttfunk/table/cff/encoding.rb +20 -21
  27. data/lib/ttfunk/table/cff/encodings.rb +1 -1
  28. data/lib/ttfunk/table/cff/fd_selector.rb +14 -11
  29. data/lib/ttfunk/table/cff/font_index.rb +7 -6
  30. data/lib/ttfunk/table/cff/index.rb +6 -5
  31. data/lib/ttfunk/table/cff/one_based_index.rb +7 -3
  32. data/lib/ttfunk/table/cff/path.rb +5 -3
  33. data/lib/ttfunk/table/cff/top_dict.rb +7 -6
  34. data/lib/ttfunk/table/cff/top_index.rb +5 -4
  35. data/lib/ttfunk/table/cmap.rb +8 -6
  36. data/lib/ttfunk/table/cmap/format00.rb +7 -6
  37. data/lib/ttfunk/table/cmap/format04.rb +16 -15
  38. data/lib/ttfunk/table/cmap/format06.rb +6 -5
  39. data/lib/ttfunk/table/cmap/format10.rb +6 -5
  40. data/lib/ttfunk/table/cmap/format12.rb +13 -12
  41. data/lib/ttfunk/table/cmap/subtable.rb +4 -4
  42. data/lib/ttfunk/table/dsig.rb +11 -9
  43. data/lib/ttfunk/table/glyf.rb +3 -3
  44. data/lib/ttfunk/table/glyf/compound.rb +8 -8
  45. data/lib/ttfunk/table/hmtx.rb +6 -5
  46. data/lib/ttfunk/table/kern.rb +4 -4
  47. data/lib/ttfunk/table/kern/format0.rb +1 -1
  48. data/lib/ttfunk/table/loca.rb +7 -6
  49. data/lib/ttfunk/table/name.rb +6 -5
  50. data/lib/ttfunk/table/os2.rb +261 -151
  51. data/lib/ttfunk/table/post.rb +1 -1
  52. data/lib/ttfunk/table/sbix.rb +15 -13
  53. data/lib/ttfunk/table/vorg.rb +1 -1
  54. data/lib/ttfunk/ttf_encoder.rb +4 -4
  55. metadata +29 -99
  56. metadata.gz.sig +0 -0
@@ -21,7 +21,7 @@ module TTFunk
21
21
  @commands << [:line, x, y]
22
22
  end
23
23
 
24
- def curve_to(x1, y1, x2, y2, x, y)
24
+ def curve_to(x1, y1, x2, y2, x, y) # rubocop: disable Metrics/ParameterLists,Style/CommentedKeyword
25
25
  @commands << [:curve, x1, y1, x2, y2, x, y]
26
26
  end
27
27
 
@@ -44,8 +44,10 @@ module TTFunk
44
44
  new_path.curve_to(
45
45
  x + (cmd[1] * scale),
46
46
  y + (-cmd[2] * scale),
47
- x + (cmd[3] * scale), y + (-cmd[4] * scale),
48
- x + (cmd[5] * scale), y + (-cmd[6] * scale)
47
+ x + (cmd[3] * scale),
48
+ y + (-cmd[4] * scale),
49
+ x + (cmd[5] * scale),
50
+ y + (-cmd[6] * scale)
49
51
  )
50
52
  when :close
51
53
  new_path.close_path
@@ -128,13 +128,14 @@ module TTFunk
128
128
  end
129
129
 
130
130
  def encoding
131
- @encoding ||= begin
132
- # PostScript type 1 fonts, i.e. CID fonts, i.e. some fonts that use
133
- # the CFF table, don't specify an encoding, so this can be nil
134
- if (encoding_offset_or_id = self[OPERATORS[:encoding]])
135
- Encoding.new(self, file, encoding_offset_or_id.first)
131
+ @encoding ||=
132
+ begin
133
+ # PostScript type 1 fonts, i.e. CID fonts, i.e. some fonts that use
134
+ # the CFF table, don't specify an encoding, so this can be nil
135
+ if (encoding_offset_or_id = self[OPERATORS[:encoding]])
136
+ Encoding.new(self, file, encoding_offset_or_id.first)
137
+ end
136
138
  end
137
- end
138
139
  end
139
140
 
140
141
  # https://www.microsoft.com/typography/otspec/cff.htm
@@ -5,10 +5,11 @@ module TTFunk
5
5
  class Cff < TTFunk::Table
6
6
  class TopIndex < TTFunk::Table::Cff::Index
7
7
  def [](index)
8
- entry_cache[index] ||= begin
9
- start, finish = absolute_offsets_for(index)
10
- TTFunk::Table::Cff::TopDict.new(file, start, (finish - start) + 1)
11
- end
8
+ entry_cache[index] ||=
9
+ begin
10
+ start, finish = absolute_offsets_for(index)
11
+ TTFunk::Table::Cff::TopDict.new(file, start, (finish - start) + 1)
12
+ end
12
13
  end
13
14
  end
14
15
  end
@@ -17,18 +17,20 @@ module TTFunk
17
17
  def unicode
18
18
  # Because most callers just call .first on the result, put tables with
19
19
  # highest-number format first. Unsupported formats will be ignored.
20
- @unicode ||= @tables
21
- .select { |table| table.unicode? && table.supported? }
22
- .sort { |a, b| b.format <=> a.format }
20
+ @unicode ||=
21
+ @tables
22
+ .select { |table| table.unicode? && table.supported? }
23
+ .sort { |a, b| b.format <=> a.format }
23
24
  end
24
25
 
25
26
  private
26
27
 
27
28
  def parse!
28
29
  @version, table_count = read(4, 'nn')
29
- @tables = Array.new(table_count) do
30
- Cmap::Subtable.new(file, offset)
31
- end
30
+ @tables =
31
+ Array.new(table_count) do
32
+ Cmap::Subtable.new(file, offset)
33
+ end
32
34
  end
33
35
  end
34
36
  end
@@ -18,12 +18,13 @@ module TTFunk
18
18
  glyph_indexes = Array.new(256, 0)
19
19
  glyph_map = { 0 => 0 }
20
20
 
21
- new_map = charmap.keys.sort.each_with_object({}) do |code, map|
22
- glyph_map[charmap[code]] ||= next_id += 1
23
- map[code] = { old: charmap[code], new: glyph_map[charmap[code]] }
24
- glyph_indexes[code] = glyph_map[charmap[code]]
25
- map
26
- end
21
+ new_map =
22
+ charmap.keys.sort.each_with_object({}) do |code, map|
23
+ glyph_map[charmap[code]] ||= next_id += 1
24
+ map[code] = { old: charmap[code], new: glyph_map[charmap[code]] }
25
+ glyph_indexes[code] = glyph_map[charmap[code]]
26
+ map
27
+ end
27
28
 
28
29
  # format, length, language, indices
29
30
  subtable = [0, 262, 0, *glyph_indexes].pack('nnnC*')
@@ -20,21 +20,22 @@ module TTFunk
20
20
  last = difference = nil
21
21
 
22
22
  glyph_map = { 0 => 0 }
23
- new_map = charmap.keys.sort.each_with_object({}) do |code, map|
24
- old = charmap[code]
25
- glyph_map[old] ||= next_id += 1
26
- map[code] = { old: old, new: glyph_map[old] }
27
-
28
- delta = glyph_map[old] - code
29
- if last.nil? || delta != difference
30
- end_codes << last if last
31
- start_codes << code
32
- difference = delta
33
- end
34
- last = code
23
+ new_map =
24
+ charmap.keys.sort.each_with_object({}) do |code, map|
25
+ old = charmap[code]
26
+ glyph_map[old] ||= next_id += 1
27
+ map[code] = { old: old, new: glyph_map[old] }
28
+
29
+ delta = glyph_map[old] - code
30
+ if last.nil? || delta != difference
31
+ end_codes << last if last
32
+ start_codes << code
33
+ difference = delta
34
+ end
35
+ last = code
35
36
 
36
- map
37
- end
37
+ map
38
+ end
38
39
 
39
40
  end_codes << last if last
40
41
  end_codes << 0xFFFF
@@ -119,7 +120,7 @@ module TTFunk
119
120
 
120
121
  end_code.each_with_index do |tail, i|
121
122
  start_code[i].upto(tail) do |code|
122
- if id_range_offset[i] == 0
123
+ if (id_range_offset[i]).zero?
123
124
  glyph_id = code + id_delta[i]
124
125
  else
125
126
  index = id_range_offset[i] / 2 +
@@ -17,11 +17,12 @@ module TTFunk
17
17
  entry_count = 1 + high_char - low_char
18
18
  glyph_indexes = Array.new(entry_count, 0)
19
19
 
20
- new_map = charmap.keys.sort.each_with_object({}) do |code, map|
21
- glyph_map[charmap[code]] ||= next_id += 1
22
- map[code] = { old: charmap[code], new: glyph_map[charmap[code]] }
23
- glyph_indexes[code - low_char] = glyph_map[charmap[code]]
24
- end
20
+ new_map =
21
+ charmap.keys.sort.each_with_object({}) do |code, map|
22
+ glyph_map[charmap[code]] ||= next_id += 1
23
+ map[code] = { old: charmap[code], new: glyph_map[charmap[code]] }
24
+ glyph_indexes[code - low_char] = glyph_map[charmap[code]]
25
+ end
25
26
 
26
27
  subtable = [
27
28
  6, 10 + entry_count * 2, 0, low_char, entry_count, *glyph_indexes
@@ -17,11 +17,12 @@ module TTFunk
17
17
  entry_count = 1 + high_char - low_char
18
18
  glyph_indexes = Array.new(entry_count, 0)
19
19
 
20
- new_map = charmap.keys.sort.each_with_object({}) do |code, map|
21
- glyph_map[charmap[code]] ||= next_id += 1
22
- map[code] = { old: charmap[code], new: glyph_map[charmap[code]] }
23
- glyph_indexes[code - low_char] = glyph_map[charmap[code]]
24
- end
20
+ new_map =
21
+ charmap.keys.sort.each_with_object({}) do |code, map|
22
+ glyph_map[charmap[code]] ||= next_id += 1
23
+ map[code] = { old: charmap[code], new: glyph_map[charmap[code]] }
24
+ glyph_indexes[code - low_char] = glyph_map[charmap[code]]
25
+ end
25
26
 
26
27
  subtable = [
27
28
  10, 0, 20 + entry_count * 4, 0, low_char, entry_count,
@@ -15,20 +15,21 @@ module TTFunk
15
15
  range_lengths = []
16
16
  last_glyph = last_code = -999
17
17
 
18
- new_map = charmap.keys.sort.each_with_object({}) do |code, map|
19
- glyph_map[charmap[code]] ||= next_id += 1
20
- map[code] = { old: charmap[code], new: glyph_map[charmap[code]] }
18
+ new_map =
19
+ charmap.keys.sort.each_with_object({}) do |code, map|
20
+ glyph_map[charmap[code]] ||= next_id += 1
21
+ map[code] = { old: charmap[code], new: glyph_map[charmap[code]] }
21
22
 
22
- if code > last_code + 1 || glyph_map[charmap[code]] > last_glyph + 1
23
- range_firstcodes << code
24
- range_firstglyphs << glyph_map[charmap[code]]
25
- range_lengths << 1
26
- else
27
- range_lengths.push(range_lengths.pop) + 1
23
+ if code > last_code + 1 || glyph_map[charmap[code]] > last_glyph + 1
24
+ range_firstcodes << code
25
+ range_firstglyphs << glyph_map[charmap[code]]
26
+ range_lengths << 1
27
+ else
28
+ range_lengths.push(range_lengths.pop) + 1
29
+ end
30
+ last_code = code
31
+ last_glyph = glyph_map[charmap[code]]
28
32
  end
29
- last_code = code
30
- last_glyph = glyph_map[charmap[code]]
31
- end
32
33
 
33
34
  subtable = [
34
35
  12, 0, 16 + 12 * range_lengths.size, 0, range_lengths.size
@@ -57,9 +57,9 @@ module TTFunk
57
57
  @format = read(2, 'n').first
58
58
 
59
59
  case @format
60
- when 0 then extend(TTFunk::Table::Cmap::Format00)
61
- when 4 then extend(TTFunk::Table::Cmap::Format04)
62
- when 6 then extend(TTFunk::Table::Cmap::Format06)
60
+ when 0 then extend(TTFunk::Table::Cmap::Format00)
61
+ when 4 then extend(TTFunk::Table::Cmap::Format04)
62
+ when 6 then extend(TTFunk::Table::Cmap::Format06)
63
63
  when 10 then extend(TTFunk::Table::Cmap::Format10)
64
64
  when 12 then extend(TTFunk::Table::Cmap::Format12)
65
65
  end
@@ -71,7 +71,7 @@ module TTFunk
71
71
  def unicode?
72
72
  platform_id == 3 && (encoding_id == 1 || encoding_id == 10) &&
73
73
  format != 0 ||
74
- platform_id == 0 && format != 0
74
+ platform_id.zero? && format != 0
75
75
  end
76
76
 
77
77
  def supported?
@@ -19,7 +19,7 @@ module TTFunk
19
19
  TAG = 'DSIG'
20
20
 
21
21
  def self.encode(dsig)
22
- return nil unless dsig
22
+ return unless dsig
23
23
 
24
24
  # Don't attempt to re-sign or anything - just use dummy values.
25
25
  # Since we're subsetting that should be permissible.
@@ -35,15 +35,17 @@ module TTFunk
35
35
  def parse!
36
36
  @version, num_signatures, @flags = read(8, 'Nnn')
37
37
 
38
- @signatures = Array.new(num_signatures) do
39
- format, length, sig_offset = read(12, 'N3')
40
- signature = parse_from(offset + sig_offset) do
41
- _, _, sig_length = read(8, 'nnN')
42
- read(sig_length, 'C*')
43
- end
38
+ @signatures =
39
+ Array.new(num_signatures) do
40
+ format, length, sig_offset = read(12, 'N3')
41
+ signature =
42
+ parse_from(offset + sig_offset) do
43
+ _, _, sig_length = read(8, 'nnN')
44
+ read(sig_length, 'C*')
45
+ end
44
46
 
45
- SignatureRecord.new(format, length, sig_offset, signature)
46
- end
47
+ SignatureRecord.new(format, length, sig_offset, signature)
48
+ end
47
49
  end
48
50
  end
49
51
  end
@@ -32,11 +32,11 @@ module TTFunk
32
32
  return @cache[glyph_id] if @cache.key?(glyph_id)
33
33
 
34
34
  index = file.glyph_locations.index_of(glyph_id)
35
- size = file.glyph_locations.size_of(glyph_id)
35
+ size = file.glyph_locations.size_of(glyph_id)
36
36
 
37
- if size == 0 # blank glyph, e.g. space character
37
+ if size.zero? # blank glyph, e.g. space character
38
38
  @cache[glyph_id] = nil
39
- return nil
39
+ return
40
40
  end
41
41
 
42
42
  parse_from(offset + index) do
@@ -8,12 +8,12 @@ module TTFunk
8
8
  class Compound
9
9
  include Reader
10
10
 
11
- ARG_1_AND_2_ARE_WORDS = 0x0001
12
- WE_HAVE_A_SCALE = 0x0008
13
- MORE_COMPONENTS = 0x0020
11
+ ARG_1_AND_2_ARE_WORDS = 0x0001
12
+ WE_HAVE_A_SCALE = 0x0008
13
+ MORE_COMPONENTS = 0x0020
14
14
  WE_HAVE_AN_X_AND_Y_SCALE = 0x0040
15
- WE_HAVE_A_TWO_BY_TWO = 0x0080
16
- WE_HAVE_INSTRUCTIONS = 0x0100
15
+ WE_HAVE_A_TWO_BY_TWO = 0x0080
16
+ WE_HAVE_INSTRUCTIONS = 0x0100
17
17
 
18
18
  attr_reader :id, :raw
19
19
  attr_reader :number_of_contours
@@ -55,10 +55,10 @@ module TTFunk
55
55
  offset += 4
56
56
 
57
57
  offset +=
58
- if flags & ARG_1_AND_2_ARE_WORDS != 0
59
- 4
60
- else
58
+ if (flags & ARG_1_AND_2_ARE_WORDS).zero?
61
59
  2
60
+ else
61
+ 4
62
62
  end
63
63
 
64
64
  if flags & WE_HAVE_A_TWO_BY_TWO != 0
@@ -10,10 +10,11 @@ module TTFunk
10
10
  attr_reader :widths
11
11
 
12
12
  def self.encode(hmtx, mapping)
13
- metrics = mapping.keys.sort.map do |new_id|
14
- metric = hmtx.for(mapping[new_id])
15
- [metric.advance_width, metric.left_side_bearing]
16
- end
13
+ metrics =
14
+ mapping.keys.sort.map do |new_id|
15
+ metric = hmtx.for(mapping[new_id])
16
+ [metric.advance_width, metric.left_side_bearing]
17
+ end
17
18
 
18
19
  {
19
20
  number_of_metrics: metrics.length,
@@ -43,7 +44,7 @@ module TTFunk
43
44
 
44
45
  file.horizontal_header.number_of_metrics.times do
45
46
  advance = read(2, 'n').first
46
- lsb = read_signed(1).first
47
+ lsb = read_signed(1).first
47
48
  @metrics.push HorizontalMetric.new(advance, lsb)
48
49
  end
49
50
 
@@ -9,10 +9,10 @@ module TTFunk
9
9
  attr_reader :tables
10
10
 
11
11
  def self.encode(kerning, mapping)
12
- return nil unless kerning.exists? && kerning.tables.any?
12
+ return unless kerning.exists? && kerning.tables.any?
13
13
 
14
14
  tables = kerning.tables.map { |table| table.recode(mapping) }.compact
15
- return nil if tables.empty?
15
+ return if tables.empty?
16
16
 
17
17
  [0, tables.length, tables.join].pack('nnA*')
18
18
  end
@@ -53,7 +53,7 @@ module TTFunk
53
53
  length: length,
54
54
  coverage: coverage,
55
55
  data: raw[10..-1],
56
- vertical: (coverage & 0x1 == 0),
56
+ vertical: (coverage & 0x1).zero?,
57
57
  minimum: (coverage & 0x2 != 0),
58
58
  cross: (coverage & 0x4 != 0),
59
59
  override: (coverage & 0x8 != 0)
@@ -79,7 +79,7 @@ module TTFunk
79
79
  end
80
80
 
81
81
  def add_table(format, attributes = {})
82
- if format == 0
82
+ if format.zero?
83
83
  @tables << Kern::Format0.new(attributes)
84
84
  end
85
85
  # Unsupported kerning tables are silently ignored
@@ -48,7 +48,7 @@ module TTFunk
48
48
  end
49
49
  end
50
50
 
51
- return nil if subset.empty?
51
+ return if subset.empty?
52
52
 
53
53
  num_pairs = subset.length
54
54
  search_range = 2 * 2**(Math.log(num_pairs) / Math.log(2)).to_i
@@ -15,10 +15,11 @@ module TTFunk
15
15
  # * :table - the string representing the table's contents
16
16
  # * :type - the type of offset (to be encoded in the 'head' table)
17
17
  def self.encode(offsets)
18
- long_offsets = offsets.any? do |offset|
19
- short_offset = offset / 2
20
- short_offset * 2 != offset || short_offset > 0xffff
21
- end
18
+ long_offsets =
19
+ offsets.any? do |offset|
20
+ short_offset = offset / 2
21
+ short_offset * 2 != offset || short_offset > 0xffff
22
+ end
22
23
 
23
24
  if long_offsets
24
25
  { type: 1, table: offsets.pack('N*') }
@@ -38,10 +39,10 @@ module TTFunk
38
39
  private
39
40
 
40
41
  def parse!
41
- type = file.header.index_to_loc_format == 0 ? 'n' : 'N'
42
+ type = file.header.index_to_loc_format.zero? ? 'n' : 'N'
42
43
  @offsets = read(length, "#{type}*")
43
44
 
44
- if file.header.index_to_loc_format == 0
45
+ if file.header.index_to_loc_format.zero?
45
46
  @offsets.map! { |v| v * 2 }
46
47
  end
47
48
  end
@@ -76,7 +76,7 @@ module TTFunk
76
76
 
77
77
  strings = names.strings.dup
78
78
  strings[6] = [postscript_name]
79
- str_count = strings.inject(0) { |sum, (_, list)| sum + list.length }
79
+ str_count = strings.reduce(0) { |sum, (_, list)| sum + list.length }
80
80
 
81
81
  table = [0, str_count, 6 + 12 * str_count].pack('n*')
82
82
  strtable = +''
@@ -87,9 +87,10 @@ module TTFunk
87
87
  items << [id, string]
88
88
  end
89
89
  end
90
- items = items.sort_by do |id, string|
91
- [string.platform_id, string.encoding_id, string.language_id, id]
92
- end
90
+ items =
91
+ items.sort_by do |id, string|
92
+ [string.platform_id, string.encoding_id, string.language_id, id]
93
+ end
93
94
  items.each do |id, string|
94
95
  table << [
95
96
  string.platform_id, string.encoding_id, string.language_id, id,
@@ -151,7 +152,7 @@ module TTFunk
151
152
 
152
153
  unless @strings[POSTSCRIPT_NAME_NAME_ID].empty?
153
154
  @postscript_name = @strings[POSTSCRIPT_NAME_NAME_ID]
154
- .first.strip_extended
155
+ .first.strip_extended
155
156
  end
156
157
 
157
158
  @trademark = @strings[TRADEMARK_NAME_ID]