Class: TTFunk::SubsetCollection

Inherits:
Object
  • Object
show all
Defined in:
lib/ttfunk/subset_collection.rb

Overview

Subset collection.

For many use cases a font subset can be efficiently encoded using MacRoman encoding. However, for full font coverage and characters that are not in MacRoman encoding an additional Unicode subset is used. There can be as many as needed Unicode subsets to fully cover glyphs provided by the original font. Ther resulting set of subsets all use 8-bit encoding helping to efficiently encode text in Prawn.

Instance Method Summary collapse

Constructor Details

#initialize(original) ⇒ SubsetCollection

Returns a new instance of SubsetCollection.

Parameters:

Source Code
lib/ttfunk/subset_collection.rb, line 16
16
def initialize(original)
17
  @original = original
18
  @subsets = [Subset.for(@original, :mac_roman)]
19
end

Instance Method Details

#[](subset) ⇒ TTFunk::Subset::Unicode, ...

Get subset by index.

Source Code
lib/ttfunk/subset_collection.rb, line 26
26
def [](subset)
27
  @subsets[subset]
28
end

#encode(characters) ⇒ Array<Array(Integer, String)>

Encode characters into subset-character pairs.

Parameters:

  • characters (Array<Integer>)

    should be an array of UTF-16 code points

Returns:

  • (Array<Array(Integer, String)>)

    subset chunks, where each chunk is another array of two elements. The first element is the subset number, and the second element is the string of characters to render with that font subset. The strings will be encoded for their subset font, and so may not look (in the raw) like what was passed in, but they will render correctly with the corresponding subset font.

Source Code
lib/ttfunk/subset_collection.rb, line 67
67
def encode(characters)
68
  return [] if characters.empty?
69
70
  # TODO: probably would be more optimal to nix the #use method,
71
  # and merge it into this one, so it can be done in a single
72
  # pass instead of two passes.
73
  use(characters)
74
75
  parts = []
76
  current_subset = 0
77
  current_char = 0
78
  char = characters[current_char]
79
80
  loop do
81
    while @subsets[current_subset].includes?(char)
82
      char = @subsets[current_subset].from_unicode(char)
83
84
      if parts.empty? || parts.last[0] != current_subset
85
        encoded_char = char.chr
86
        if encoded_char.respond_to?(:force_encoding)
87
          encoded_char.force_encoding('ASCII-8BIT')
88
        end
89
        parts << [current_subset, encoded_char]
90
      else
91
        parts.last[1] << char
92
      end
93
94
      current_char += 1
95
      return parts if current_char >= characters.length
96
97
      char = characters[current_char]
98
    end
99
100
    current_subset = (current_subset + 1) % @subsets.length
101
  end
102
end

#use(characters) ⇒ void

This method returns an undefined value.

Add chracters to appropiate subsets.

Parameters:

  • characters (Array<Integer>)

    should be an array of UTF-16 code points

Source Code
lib/ttfunk/subset_collection.rb, line 35
35
def use(characters)
36
  characters.each do |char|
37
    covered = false
38
    i = 0
39
    length = @subsets.length
40
    while i < length
41
      subset = @subsets[i]
42
      if subset.covers?(char)
43
        subset.use(char)
44
        covered = true
45
        break
46
      end
47
      i += 1
48
    end
49
50
    unless covered
51
      @subsets << Subset.for(@original, :unicode_8bit)
52
      @subsets.last.use(char)
53
    end
54
  end
55
end