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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +74 -0
  4. data/README.md +17 -15
  5. data/lib/ttfunk/aggregate.rb +5 -0
  6. data/lib/ttfunk/bin_utils.rb +27 -8
  7. data/lib/ttfunk/bit_field.rb +25 -2
  8. data/lib/ttfunk/collection.rb +27 -3
  9. data/lib/ttfunk/directory.rb +7 -1
  10. data/lib/ttfunk/encoded_string.rb +58 -4
  11. data/lib/ttfunk/max.rb +14 -0
  12. data/lib/ttfunk/min.rb +14 -0
  13. data/lib/ttfunk/one_based_array.rb +20 -0
  14. data/lib/ttfunk/otf_encoder.rb +5 -14
  15. data/lib/ttfunk/placeholder.rb +15 -1
  16. data/lib/ttfunk/reader.rb +6 -4
  17. data/lib/ttfunk/resource_file.rb +29 -5
  18. data/lib/ttfunk/sci_form.rb +20 -3
  19. data/lib/ttfunk/sub_table.rb +29 -4
  20. data/lib/ttfunk/subset/base.rb +48 -0
  21. data/lib/ttfunk/subset/code_page.rb +49 -2
  22. data/lib/ttfunk/subset/mac_roman.rb +2 -0
  23. data/lib/ttfunk/subset/unicode.rb +32 -0
  24. data/lib/ttfunk/subset/unicode_8bit.rb +32 -0
  25. data/lib/ttfunk/subset/windows_1252.rb +2 -0
  26. data/lib/ttfunk/subset.rb +8 -0
  27. data/lib/ttfunk/subset_collection.rb +39 -14
  28. data/lib/ttfunk/sum.rb +13 -0
  29. data/lib/ttfunk/table/cff/charset.rb +96 -18
  30. data/lib/ttfunk/table/cff/charsets/expert.rb +3 -2
  31. data/lib/ttfunk/table/cff/charsets/expert_subset.rb +3 -2
  32. data/lib/ttfunk/table/cff/charsets/iso_adobe.rb +3 -2
  33. data/lib/ttfunk/table/cff/charsets/standard_strings.rb +3 -2
  34. data/lib/ttfunk/table/cff/charsets.rb +1 -0
  35. data/lib/ttfunk/table/cff/charstring.rb +33 -12
  36. data/lib/ttfunk/table/cff/charstrings_index.rb +17 -11
  37. data/lib/ttfunk/table/cff/dict.rb +53 -23
  38. data/lib/ttfunk/table/cff/encoding.rb +82 -24
  39. data/lib/ttfunk/table/cff/encodings/expert.rb +3 -2
  40. data/lib/ttfunk/table/cff/encodings/standard.rb +3 -2
  41. data/lib/ttfunk/table/cff/encodings.rb +1 -0
  42. data/lib/ttfunk/table/cff/fd_selector.rb +61 -21
  43. data/lib/ttfunk/table/cff/font_dict.rb +30 -18
  44. data/lib/ttfunk/table/cff/font_index.rb +22 -10
  45. data/lib/ttfunk/table/cff/header.rb +16 -3
  46. data/lib/ttfunk/table/cff/index.rb +97 -65
  47. data/lib/ttfunk/table/cff/one_based_index.rb +11 -1
  48. data/lib/ttfunk/table/cff/path.rb +43 -4
  49. data/lib/ttfunk/table/cff/private_dict.rb +31 -11
  50. data/lib/ttfunk/table/cff/subr_index.rb +7 -2
  51. data/lib/ttfunk/table/cff/top_dict.rb +82 -59
  52. data/lib/ttfunk/table/cff/top_index.rb +10 -6
  53. data/lib/ttfunk/table/cff.rb +41 -21
  54. data/lib/ttfunk/table/cmap/format00.rb +27 -6
  55. data/lib/ttfunk/table/cmap/format04.rb +34 -14
  56. data/lib/ttfunk/table/cmap/format06.rb +28 -1
  57. data/lib/ttfunk/table/cmap/format10.rb +29 -2
  58. data/lib/ttfunk/table/cmap/format12.rb +29 -2
  59. data/lib/ttfunk/table/cmap/subtable.rb +50 -6
  60. data/lib/ttfunk/table/cmap.rb +21 -0
  61. data/lib/ttfunk/table/dsig.rb +47 -6
  62. data/lib/ttfunk/table/glyf/compound.rb +73 -6
  63. data/lib/ttfunk/table/glyf/path_based.rb +40 -3
  64. data/lib/ttfunk/table/glyf/simple.rb +50 -5
  65. data/lib/ttfunk/table/glyf.rb +15 -7
  66. data/lib/ttfunk/table/head.rb +84 -6
  67. data/lib/ttfunk/table/hhea.rb +71 -10
  68. data/lib/ttfunk/table/hmtx.rb +32 -5
  69. data/lib/ttfunk/table/kern/format0.rb +25 -7
  70. data/lib/ttfunk/table/kern.rb +16 -4
  71. data/lib/ttfunk/table/loca.rb +21 -8
  72. data/lib/ttfunk/table/maxp.rb +195 -10
  73. data/lib/ttfunk/table/name.rb +126 -9
  74. data/lib/ttfunk/table/os2.rb +150 -26
  75. data/lib/ttfunk/table/post/format10.rb +7 -0
  76. data/lib/ttfunk/table/post/format20.rb +9 -0
  77. data/lib/ttfunk/table/post/format30.rb +6 -0
  78. data/lib/ttfunk/table/post/format40.rb +5 -0
  79. data/lib/ttfunk/table/post.rb +63 -7
  80. data/lib/ttfunk/table/sbix.rb +50 -14
  81. data/lib/ttfunk/table/simple.rb +5 -0
  82. data/lib/ttfunk/table/vorg.rb +31 -3
  83. data/lib/ttfunk/table.rb +20 -1
  84. data/lib/ttfunk/ttf_encoder.rb +39 -41
  85. data/lib/ttfunk.rb +154 -1
  86. data.tar.gz.sig +0 -0
  87. metadata +50 -28
  88. metadata.gz.sig +0 -0
@@ -1,10 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTFunk
4
+ # Encoded String placeholder.
5
+ #
6
+ # @api private
4
7
  class Placeholder
8
+ # Placeholder position in the cintaining Encoded String
9
+ # @return [Integer]
5
10
  attr_accessor :position
6
- attr_reader :name, :length
7
11
 
12
+ # Planceholder name
13
+ # @return [Symbol]
14
+ attr_reader :name
15
+
16
+ # Length of the placeholder
17
+ # @return [Integer]
18
+ attr_reader :length
19
+
20
+ # @param name [Symbol]
21
+ # @param length [Integer]
8
22
  def initialize(name, length: 1)
9
23
  @name = name
10
24
  @length = length
data/lib/ttfunk/reader.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTFunk
4
+ # Helper methods to read form file content.
5
+ # @api rpivate
4
6
  module Reader
5
7
  private
6
8
 
@@ -23,7 +25,7 @@ module TTFunk
23
25
  def parse_from(position)
24
26
  saved = io.pos
25
27
  io.pos = position
26
- result = yield position
28
+ result = yield(position)
27
29
  io.pos = saved
28
30
  result
29
31
  end
@@ -36,12 +38,12 @@ module TTFunk
36
38
  if ((i + 1) % 16).zero?
37
39
  puts
38
40
  elsif ((i + 1) % 8).zero?
39
- print ' '
41
+ print(' ')
40
42
  else
41
- print ' '
43
+ print(' ')
42
44
  end
43
45
  end
44
- puts unless (bytes.length % 16).zero?
46
+ puts if (bytes.length % 16) != 0
45
47
  end
46
48
  end
47
49
  end
@@ -1,16 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTFunk
4
+ # Data-fork suitcases resource file
4
5
  class ResourceFile
6
+ # Resource map
7
+ #
8
+ # @return [Hash]
5
9
  attr_reader :map
6
10
 
11
+ # Open a resource file
12
+ #
13
+ # @param path [String, Pathname]
14
+ # @yieldparam resource_file [TTFunk::ResourceFile]
15
+ # @return [any] result of the block
7
16
  def self.open(path)
8
- ::File.open(path, 'rb') do |io|
17
+ ::File.open(path, 'rb') { |io|
9
18
  file = new(io)
10
- yield file
11
- end
19
+ yield(file)
20
+ }
12
21
  end
13
22
 
23
+ # @param io [IO]
14
24
  def initialize(io)
15
25
  @io = io
16
26
 
@@ -41,7 +51,7 @@ module TTFunk
41
51
  id: id,
42
52
  attributes: attr,
43
53
  offset: data_ofs,
44
- handle: handle
54
+ handle: handle,
45
55
  }
46
56
 
47
57
  if name_list_offset + name_ofs < map_offset + map_length
@@ -58,6 +68,16 @@ module TTFunk
58
68
  end
59
69
  end
60
70
 
71
+ # Get resource
72
+ #
73
+ # @overload [](type, index = 0)
74
+ # @param type [String]
75
+ # @param inxed [Integer]
76
+ # @return [String]
77
+ # @overload [](type, name)
78
+ # @param type [String]
79
+ # @param name [String]
80
+ # @return [String]
61
81
  def [](type, index = 0)
62
82
  if @map[type]
63
83
  collection = index.is_a?(Integer) ? :list : :named
@@ -70,8 +90,12 @@ module TTFunk
70
90
  end
71
91
  end
72
92
 
93
+ # Get resource names
94
+ #
95
+ # @param type [String]
96
+ # @return [Array<String>]
73
97
  def resources_for(type)
74
- (@map[type] && @map[type][:named] || {}).keys
98
+ ((@map[type] && @map[type][:named]) || {}).keys
75
99
  end
76
100
 
77
101
  private
@@ -1,19 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTFunk
4
+ # Scientific number representation
4
5
  class SciForm
5
- attr_reader :significand, :exponent
6
- alias eql? ==
6
+ # Significand
7
+ # @return [Float, Integer]
8
+ attr_reader :significand
9
+
10
+ # Exponent
11
+ # @return [Float, Integer]
12
+ attr_reader :exponent
7
13
 
14
+ # @param significand [Float, Integer]
15
+ # @param exponent [Float, Integer]
8
16
  def initialize(significand, exponent = 0)
9
17
  @significand = significand
10
18
  @exponent = exponent
11
19
  end
12
20
 
21
+ # Convert to Float.
22
+ #
23
+ # @return [Float]
13
24
  def to_f
14
- significand * 10**exponent
25
+ significand * (10**exponent)
15
26
  end
16
27
 
28
+ # Check equality to another number.
29
+ #
30
+ # @param other [Float, SciForm]
31
+ # @return [Boolean]
17
32
  def ==(other)
18
33
  case other
19
34
  when Float
@@ -25,5 +40,7 @@ module TTFunk
25
40
  false
26
41
  end
27
42
  end
43
+
44
+ alias eql? ==
28
45
  end
29
46
  end
@@ -1,16 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './reader'
3
+ require_relative 'reader'
4
4
 
5
5
  module TTFunk
6
+ # SFNT sub-table
6
7
  class SubTable
8
+ # A read past sub-table end was attempted.
7
9
  class EOTError < StandardError
8
10
  end
9
11
 
10
12
  include Reader
11
13
 
12
- attr_reader :file, :table_offset, :length
14
+ # File or IO this sub-table is in.
15
+ # @return [IO]
16
+ attr_reader :file
13
17
 
18
+ # This sub-table's offset from the file beginning.
19
+ # @return [Integer]
20
+ attr_reader :table_offset
21
+
22
+ # This sub-table's length in byes.
23
+ # @return [Integer, nil]
24
+ attr_reader :length
25
+
26
+ # @param file [IO]
27
+ # @param offset [Integer]
28
+ # @param length [Integer]
14
29
  def initialize(file, offset, length = nil)
15
30
  @file = file
16
31
  @table_offset = offset
@@ -18,15 +33,25 @@ module TTFunk
18
33
  parse_from(@table_offset) { parse! }
19
34
  end
20
35
 
21
- # end of table
36
+ # End of sub-table?
37
+ #
38
+ # @return [Boolean]
22
39
  def eot?
23
40
  # if length isn't set yet there's no way to know if we're at the end of
24
- # the table or not
41
+ # the sub-table or not
25
42
  return false unless length
26
43
 
27
44
  io.pos > table_offset + length
28
45
  end
29
46
 
47
+ # Read a series of values.
48
+ #
49
+ # @overload read(bytes, format)
50
+ # @param bytes [Integer] number of bytes to read.
51
+ # @param format [String] format to parse the bytes.
52
+ # @return [Array]
53
+ # @raise [EOTError]
54
+ # @see # Ruby Packed data
30
55
  def read(*args)
31
56
  if eot?
32
57
  raise EOTError, 'attempted to read past the end of the table'
@@ -14,45 +14,87 @@ require_relative '../table/simple'
14
14
 
15
15
  module TTFunk
16
16
  module Subset
17
+ # Base subset.
18
+ #
19
+ # @api private
17
20
  class Base
21
+ # Microsoft Platform ID
18
22
  MICROSOFT_PLATFORM_ID = 3
23
+
24
+ # Symbol Encoding ID for Microsoft Platform
19
25
  MS_SYMBOL_ENCODING_ID = 0
20
26
 
27
+ # Original font
28
+ #
29
+ # @return [TTFunk::File]
21
30
  attr_reader :original
22
31
 
32
+ # @param original [TTFunk::File]
23
33
  def initialize(original)
24
34
  @original = original
25
35
  end
26
36
 
37
+ # Is this Unicode-based subset?
38
+ #
39
+ # @return [Boolean]
27
40
  def unicode?
28
41
  false
29
42
  end
30
43
 
44
+ # Does this subset use Microsoft Symbolic encoding?
45
+ #
46
+ # @return [Boolean]
31
47
  def microsoft_symbol?
32
48
  new_cmap_table[:platform_id] == MICROSOFT_PLATFORM_ID &&
33
49
  new_cmap_table[:encoding_id] == MS_SYMBOL_ENCODING_ID
34
50
  end
35
51
 
52
+ # Get a mapping from this subset to Unicode.
53
+ #
54
+ # @return [Hash{Integer => Integer}]
36
55
  def to_unicode_map
37
56
  {}
38
57
  end
39
58
 
59
+ # Encode this subset into a binary font representation.
60
+ #
61
+ # @param options [Hash]
62
+ # @return [String]
40
63
  def encode(options = {})
41
64
  encoder_klass.new(original, self, options).encode
42
65
  end
43
66
 
67
+ # Encoder class for this subset.
68
+ #
69
+ # @return [TTFunk::TTFEncoder, TTFunk::OTFEncoder]
44
70
  def encoder_klass
45
71
  original.cff.exists? ? OTFEncoder : TTFEncoder
46
72
  end
47
73
 
74
+ # Get the first Unicode cmap from the original font.
75
+ #
76
+ # @return [TTFunk::Table::Cmap::Subtable]
48
77
  def unicode_cmap
49
78
  @unicode_cmap ||= @original.cmap.unicode.first
50
79
  end
51
80
 
81
+ # Get glyphs in this subset.
82
+ #
83
+ # @return [Hash{Integer => TTFunk::Table::Glyf::Simple,
84
+ # TTFunk::Table::Glyf::Compound}] if original is a TrueType font
85
+ # @return [Hash{Integer => TTFunk::Table::Cff::Charstring] if original is
86
+ # a CFF-based OpenType font
52
87
  def glyphs
53
88
  @glyphs ||= collect_glyphs(original_glyph_ids)
54
89
  end
55
90
 
91
+ # Get glyphs by their IDs in the original font.
92
+ #
93
+ # @param glyph_ids [Array<Integer>]
94
+ # @return [Hash{Integer => TTFunk::Table::Glyf::Simple,
95
+ # TTFunk::Table::Glyf::Compound>] if original is a TrueType font
96
+ # @return [Hash{Integer => TTFunk::Table::Cff::Charstring}] if original is
97
+ # a CFF-based OpenType font
56
98
  def collect_glyphs(glyph_ids)
57
99
  collected =
58
100
  glyph_ids.each_with_object({}) do |id, h|
@@ -69,6 +111,9 @@ module TTFunk
69
111
  collected
70
112
  end
71
113
 
114
+ # Glyph ID mapping from the original font to this subset.
115
+ #
116
+ # @return [Hash{Integer => Integer}]
72
117
  def old_to_new_glyph
73
118
  @old_to_new_glyph ||=
74
119
  begin
@@ -91,6 +136,9 @@ module TTFunk
91
136
  end
92
137
  end
93
138
 
139
+ # Glyph ID mapping from this subset to the original font.
140
+ #
141
+ # @return [Hash{Integer => Integer}]
94
142
  def new_to_old_glyph
95
143
  @new_to_old_glyph ||= old_to_new_glyph.invert
96
144
  end
@@ -6,8 +6,13 @@ require_relative 'base'
6
6
 
7
7
  module TTFunk
8
8
  module Subset
9
+ # A subset that uses standard code page encoding.
9
10
  class CodePage < Base
10
11
  class << self
12
+ # Get a mapping from an encoding to Unicode
13
+ #
14
+ # @param encoding [Encoding, String, Symbol]
15
+ # @return [Hash{Integer => Integer}]
11
16
  def unicode_mapping_for(encoding)
12
17
  mapping_cache[encoding] ||=
13
18
  (0..255).each_with_object({}) do |c, ret|
@@ -27,39 +32,74 @@ module TTFunk
27
32
  end
28
33
  end
29
34
 
30
- attr_reader :code_page, :encoding
35
+ # Code page used in this subset.
36
+ # This is used for proper `OS/2` table encoding.
37
+ # @return [Integer]
38
+ attr_reader :code_page
31
39
 
40
+ # Encoding used in this subset.
41
+ # @return [Encoding, String, Symbol]
42
+ attr_reader :encoding
43
+
44
+ # @param original [TTFunk::File]
45
+ # @param code_page [Integer]
46
+ # @param encoding [Encoding, String, Symbol]
32
47
  def initialize(original, code_page, encoding)
33
48
  super(original)
34
49
  @code_page = code_page
35
50
  @encoding = encoding
36
51
  @subset = Array.new(256)
52
+ @from_unicode_cache = {}
37
53
  use(space_char_code)
38
54
  end
39
55
 
56
+ # Get a mapping from this subset to Unicode.
57
+ #
58
+ # @return [Hash]
40
59
  def to_unicode_map
41
60
  self.class.unicode_mapping_for(encoding)
61
+ .select { |codepoint, _unicode| @subset[codepoint] }
42
62
  end
43
63
 
64
+ # Add a character to subset.
65
+ #
66
+ # @param character [Integer] Unicode codepoint
67
+ # @return [void]
44
68
  def use(character)
45
69
  @subset[from_unicode(character)] = character
46
70
  end
47
71
 
72
+ # Can this subset include the character? This depends on the encoding used
73
+ # in this subset.
74
+ #
75
+ # @param character [Integer] Unicode codepoint
76
+ # @return [Boolean]
48
77
  def covers?(character)
49
78
  !from_unicode(character).nil?
50
79
  end
51
80
 
81
+ # Does this subset actually has the character?
82
+ #
83
+ # @param character [Integer] Unicode codepoint
84
+ # @return [Boolean]
52
85
  def includes?(character)
53
86
  code = from_unicode(character)
54
87
  code && @subset[code]
55
88
  end
56
89
 
90
+ # Get character code for Unicode codepoint.
91
+ #
92
+ # @param character [Integer] Unicode codepoint
93
+ # @return [Integer, nil]
57
94
  def from_unicode(character)
58
- [character].pack('U*').encode(encoding).ord
95
+ @from_unicode_cache[character] ||= (+'' << character).encode!(encoding).ord
59
96
  rescue Encoding::UndefinedConversionError
60
97
  nil
61
98
  end
62
99
 
100
+ # Get `cmap` table for this subset.
101
+ #
102
+ # @return [TTFunk::Table::Cmap]
63
103
  def new_cmap_table
64
104
  @new_cmap_table ||=
65
105
  begin
@@ -73,11 +113,18 @@ module TTFunk
73
113
  end
74
114
  end
75
115
 
116
+ # Get the list of Glyph IDs from the original font that are in this
117
+ # subset.
118
+ #
119
+ # @return [Array<Integer>]
76
120
  def original_glyph_ids
77
121
  ([0] + @subset.map { |unicode| unicode && unicode_cmap[unicode] })
78
122
  .compact.uniq.sort
79
123
  end
80
124
 
125
+ # Get a chacter code for Space in this subset
126
+ #
127
+ # @return [Integer, nil]
81
128
  def space_char_code
82
129
  @space_char_code ||= from_unicode(Unicode::SPACE_CHAR)
83
130
  end
@@ -6,7 +6,9 @@ require_relative 'code_page'
6
6
 
7
7
  module TTFunk
8
8
  module Subset
9
+ # Mac Roman subset. It uses code page 10,000 and Mac OS Roman encoding.
9
10
  class MacRoman < CodePage
11
+ # @param original [TTFunk::File]
10
12
  def initialize(original)
11
13
  super(original, 10_000, Encoding::MACROMAN)
12
14
  end
@@ -5,39 +5,67 @@ require_relative 'base'
5
5
 
6
6
  module TTFunk
7
7
  module Subset
8
+ # Unicode-based subset.
8
9
  class Unicode < Base
10
+ # Space character code
9
11
  SPACE_CHAR = 0x20
10
12
 
13
+ # @param original [TTFunk::File]
11
14
  def initialize(original)
12
15
  super
13
16
  @subset = Set.new
14
17
  use(SPACE_CHAR)
15
18
  end
16
19
 
20
+ # Is this a Unicode-based subset?
21
+ #
22
+ # @return [true]
17
23
  def unicode?
18
24
  true
19
25
  end
20
26
 
27
+ # Get a mapping from this subset to Unicode.
28
+ #
29
+ # @return [Hash{Integer => Integer}]
21
30
  def to_unicode_map
22
31
  @subset.each_with_object({}) { |code, map| map[code] = code }
23
32
  end
24
33
 
34
+ # Add a character to subset.
35
+ #
36
+ # @param character [Integer] Unicode codepoint
37
+ # @return [void]
25
38
  def use(character)
26
39
  @subset << character
27
40
  end
28
41
 
42
+ # Can this subset include the character?
43
+ #
44
+ # @param _character [Integer] Unicode codepoint
45
+ # @return [true]
29
46
  def covers?(_character)
30
47
  true
31
48
  end
32
49
 
50
+ # Does this subset actually has the character?
51
+ #
52
+ # @param character [Integer] Unicode codepoint
53
+ # @return [Boolean]
33
54
  def includes?(character)
34
55
  @subset.include?(character)
35
56
  end
36
57
 
58
+ # Get character code for Unicode codepoint.
59
+ #
60
+ # @param character [Integer] Unicode codepoint
61
+ # @return [Integer]
37
62
  def from_unicode(character)
38
63
  character
39
64
  end
40
65
 
66
+ # Get `cmap` table for this subset.
67
+ #
68
+ # @return [TTFunk::Table::Cmap]
41
69
  def new_cmap_table
42
70
  @new_cmap_table ||=
43
71
  begin
@@ -50,6 +78,10 @@ module TTFunk
50
78
  end
51
79
  end
52
80
 
81
+ # Get the list of Glyph IDs from the original font that are in this
82
+ # subset.
83
+ #
84
+ # @return [Array<Integer>]
53
85
  def original_glyph_ids
54
86
  ([0] + @subset.map { |code| unicode_cmap[code] }).uniq.sort
55
87
  end
@@ -5,7 +5,10 @@ require_relative 'base'
5
5
 
6
6
  module TTFunk
7
7
  module Subset
8
+ # An 8-bit Unicode-based subset. It can include any Unicode character but
9
+ # limits number of characters so that the could be encoded by a single byte.
8
10
  class Unicode8Bit < Base
11
+ # @param original [TTFunk::File]
9
12
  def initialize(original)
10
13
  super
11
14
  @subset = { 0x20 => 0x20 }
@@ -13,14 +16,24 @@ module TTFunk
13
16
  @next = 0x21 # apparently, PDF's don't like to use chars between 0-31
14
17
  end
15
18
 
19
+ # Is this a Unicode-based subset?
20
+ #
21
+ # @return [true]
16
22
  def unicode?
17
23
  true
18
24
  end
19
25
 
26
+ # Get a mapping from this subset to Unicode.
27
+ #
28
+ # @return [Hash{Integer => Integer}]
20
29
  def to_unicode_map
21
30
  @subset.dup
22
31
  end
23
32
 
33
+ # Add a character to subset.
34
+ #
35
+ # @param character [Integer] Unicode codepoint
36
+ # @return [void]
24
37
  def use(character)
25
38
  unless @unicodes.key?(character)
26
39
  @subset[@next] = character
@@ -29,18 +42,33 @@ module TTFunk
29
42
  end
30
43
  end
31
44
 
45
+ # Can this subset include the character?
46
+ #
47
+ # @param character [Integer] Unicode codepoint
48
+ # @return [Boolean]
32
49
  def covers?(character)
33
50
  @unicodes.key?(character) || @next < 256
34
51
  end
35
52
 
53
+ # Does this subset actually has the character?
54
+ #
55
+ # @param character [Integer] Unicode codepoint
56
+ # @return [Boolean]
36
57
  def includes?(character)
37
58
  @unicodes.key?(character)
38
59
  end
39
60
 
61
+ # Get character code for Unicode codepoint.
62
+ #
63
+ # @param character [Integer] Unicode codepoint
64
+ # @return [Integer]
40
65
  def from_unicode(character)
41
66
  @unicodes[character]
42
67
  end
43
68
 
69
+ # Get `cmap` table for this subset.
70
+ #
71
+ # @return [TTFunk::Table::Cmap]
44
72
  def new_cmap_table
45
73
  @new_cmap_table ||=
46
74
  begin
@@ -59,6 +87,10 @@ module TTFunk
59
87
  end
60
88
  end
61
89
 
90
+ # Get the list of Glyph IDs from the original font that are in this
91
+ # subset.
92
+ #
93
+ # @return [Array<Integer>]
62
94
  def original_glyph_ids
63
95
  ([0] + @unicodes.keys.map { |unicode| unicode_cmap[unicode] }).uniq.sort
64
96
  end
@@ -6,7 +6,9 @@ require_relative 'code_page'
6
6
 
7
7
  module TTFunk
8
8
  module Subset
9
+ # Windows 1252 sbset. It uses code page 1252 and Windows-1252 encoding.
9
10
  class Windows1252 < CodePage
11
+ # @param original [TTFunk::File]
10
12
  def initialize(original)
11
13
  super(original, 1252, Encoding::CP1252)
12
14
  end
data/lib/ttfunk/subset.rb CHANGED
@@ -6,7 +6,15 @@ require_relative 'subset/mac_roman'
6
6
  require_relative 'subset/windows_1252'
7
7
 
8
8
  module TTFunk
9
+ # Namespace for different types of subsets.
9
10
  module Subset
11
+ # Create a subset for the font using the specified encoding.
12
+ #
13
+ # @param original [TTFunk::File]
14
+ # @param encoding [:unicode, :unicode_8bit, :mac_roman, :windows_1252]
15
+ # @raise [NotImplementedError] for unsupported encodings
16
+ # @return [TTFunk::Subset::Unicode, TTFunk::Subset::Unicode8Bit,
17
+ # TTFunk::Subset::MacRoman, TTFunk::Subset::Windows1252]
10
18
  def self.for(original, encoding)
11
19
  case encoding.to_sym
12
20
  when :unicode then Unicode.new(original)