ttfunk 1.7.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
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)