Class: TTFunk::Table::Cff::Charset

Inherits:
SubTable
  • Object
show all
Includes:
Enumerable
Defined in:
lib/ttfunk/table/cff/charset.rb

Overview

CFF Charset

Constant Summary collapse

FIRST_GLYPH_STRING =

First glyph string. This is an implicit glyph present in all charsets.

'.notdef'
ARRAY_FORMAT =

Format 0.

0
RANGE_FORMAT_8 =

Format 1.

1
RANGE_FORMAT_16 =

Format 2.

2
ISO_ADOBE_CHARSET_ID =

Predefined ISOAdobe charset ID.

0
EXPERT_CHARSET_ID =

Predefined Expert charset ID.

1
EXPERT_SUBSET_CHARSET_ID =

Predefined Expert Subset charset ID.

2
DEFAULT_CHARSET_ID =

Default charset ID.

ISO_ADOBE_CHARSET_ID

Instance Attribute Summary collapse

Attributes inherited from SubTable

#file, #table_offset

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from SubTable

#eot?, #read

Constructor Details

#initialize(top_dict, file, offset = nil, length = nil) ⇒ Charset #initialize(top_dict, file, charset_id) ⇒ Charset

Returns a new instance of Charset.

Overloads:

  • #initialize(top_dict, file, offset = nil, length = nil) ⇒ Charset

    Parameters:

    • top_dict (TTFunk::Table:Cff::TopDict)
    • file (TTFunk::File)
    • offset (Integer) (defaults to: nil)
    • length (Integer) (defaults to: nil)
  • #initialize(top_dict, file, charset_id) ⇒ Charset

    Parameters:

    • top_dict (TTFunk::Table:Cff::TopDict)
    • file (TTFunk::File)
    • charset_id (Integer)

      0, 1, or 2

Source Code
lib/ttfunk/table/cff/charset.rb, line 92
92
def initialize(top_dict, file, offset_or_id = nil, length = nil)
93
  @top_dict = top_dict
94
  @offset_or_id = offset_or_id || DEFAULT_CHARSET_ID
95
96
  if offset
97
    super(file, offset, length)
98
  else
99
    @items_count = self.class.strings_for_charset_id(offset_or_id).size
100
  end
101
end

Instance Attribute Details

#entriesTTFunk::OneBasedArray<Integer>, Array<Range<Integer>> (readonly)

Encoded entries.

Returns:

Source Code
lib/ttfunk/table/cff/charset.rb, line 61
61
def entries
62
  @entries
63
end

#formatInteger (readonly)

Encodign format.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/cff/charset.rb, line 73
73
def format
74
  @format
75
end

#items_countInteger (readonly)

Number of encoded items.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/cff/charset.rb, line 77
77
def items_count
78
  @items_count
79
end

#lengthInteger (readonly)

Length of encoded charset subtable.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/cff/charset.rb, line 65
65
def length
66
  @length
67
end

#offset_or_idInteger (readonly)

Offset or charset ID.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/cff/charset.rb, line 81
81
def offset_or_id
82
  @offset_or_id
83
end

#top_dictTTFunk::Table::Cff::TopDict (readonly)

Top dict.

Source Code
lib/ttfunk/table/cff/charset.rb, line 69
69
def top_dict
70
  @top_dict
71
end

Class Method Details

.standard_stringsTTFunk::OneBasedArray<String>

Standard strings defined in the spec that do not need to be defined in the CFF.

Returns:

Source Code
lib/ttfunk/table/cff/charset.rb, line 39
39
def standard_strings
40
  Charsets::STANDARD_STRINGS
41
end

.strings_for_charset_id(charset_id) ⇒ TTFunk::OneBasedArray<String>

Strings for charset ID.

Parameters:

  • charset_id (Integer)

Returns:

Source Code
lib/ttfunk/table/cff/charset.rb, line 47
47
def strings_for_charset_id(charset_id)
48
  case charset_id
49
  when ISO_ADOBE_CHARSET_ID
50
    Charsets::ISO_ADOBE
51
  when EXPERT_CHARSET_ID
52
    Charsets::EXPERT
53
  when EXPERT_SUBSET_CHARSET_ID
54
    Charsets::EXPERT_SUBSET
55
  end
56
end

Instance Method Details

#[](glyph_id) ⇒ String?

Get character name for glyph index.

Parameters:

  • glyph_id (Integer)

Returns:

  • (String, nil)
Source Code
lib/ttfunk/table/cff/charset.rb, line 121
121
def [](glyph_id)
122
  return FIRST_GLYPH_STRING if glyph_id.zero?
123
124
  find_string(sid_for(glyph_id))
125
end

#each {|name| ... } ⇒ void #eachEnumerator

Iterate over character names.

Overloads:

  • #each {|name| ... } ⇒ void

    This method returns an undefined value.

    Yield Parameters:

    • name (String)
  • #eachEnumerator

    Returns:

    • (Enumerator)
Source Code
lib/ttfunk/table/cff/charset.rb, line 110
110
def each
111
  return to_enum(__method__) unless block_given?
112
113
  # +1 adjusts for the implicit .notdef glyph
114
  (items_count + 1).times { |i| yield(self[i]) }
115
end

#encode(charmap) ⇒ String

Encode charset.

Parameters:

  • charmap (Hash{Integer => Hash})

    keys are the charac codes, values are hashes:

    • :old (Integer) - glyph ID in the original font.
    • :new (Integer) - glyph ID in the subset font.

Returns:

  • (String)
Source Code
lib/ttfunk/table/cff/charset.rb, line 149
149
def encode(charmap)
150
  # no offset means no charset was specified (i.e. we're supposed to
151
  # use a predefined charset) so there's nothing to encode
152
  return '' unless offset
153
154
  sids =
155
    charmap
156
      .values
157
      .reject { |mapping| mapping[:new].zero? }
158
      .sort_by { |mapping| mapping[:new] }
159
      .map { |mapping| sid_for(mapping[:old]) }
160
161
  ranges = TTFunk::BinUtils.rangify(sids)
162
  range_max = ranges.map(&:last).max
163
164
  range_bytes =
165
    if range_max.positive?
166
      (Math.log2(range_max) / 8).floor + 1
167
    else
168
      # for cases when there are no sequences at all
169
      Float::INFINITY
170
    end
171
172
  # calculate whether storing the charset as a series of ranges is
173
  # more efficient (i.e. takes up less space) vs storing it as an
174
  # array of SID values
175
  total_range_size = (2 * ranges.size) + (range_bytes * ranges.size)
176
  total_array_size = sids.size * element_width(:array_format)
177
178
  if total_array_size <= total_range_size
179
    ([format_int(:array_format)] + sids).pack('Cn*')
180
  else
181
    fmt = range_bytes == 1 ? :range_format8 : :range_format16
182
    element_fmt = element_format(fmt)
183
    result = [format_int(fmt)].pack('C')
184
    ranges.each { |range| result << range.pack(element_fmt) }
185
    result
186
  end
187
end

#offsetInteger?

Charset offset in the file.

Returns:

  • (Integer, nil)
Source Code
lib/ttfunk/table/cff/charset.rb, line 130
130
def offset
131
  # Numbers from 0..2 mean charset IDs instead of offsets. IDs are
132
  # basically pre-defined sets of characters.
133
  #
134
  # In the case of an offset, add the CFF table's offset since the
135
  # charset offset is relative to the start of the CFF table. Otherwise
136
  # return nil (no offset).
137
  if offset_or_id > 2
138
    offset_or_id + top_dict.cff_offset
139
  end
140
end