Class: TTFunk::Table::Cff::Encoding

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

Overview

CFF Encoding.

Constant Summary collapse

STANDARD_ENCODING_ID =

Predefined Standard Encoding ID.

0
EXPERT_ENCODING_ID =

Predefined Expert Encoding ID.

1
DEFAULT_ENCODING_ID =

Default encoding ID.

STANDARD_ENCODING_ID

Instance Attribute Summary collapse

Attributes inherited from SubTable

#file, #length, #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) ⇒ Encoding #initialize(top_dict, file, charset_id) ⇒ Encoding

Returns a new instance of Encoding.

Overloads:

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

    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) ⇒ Encoding

    Parameters:

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

      0, 1, or 2

Source Code
lib/ttfunk/table/cff/encoding.rb, line 59
59
def initialize(top_dict, file, offset_or_id = nil, length = nil)
60
  @top_dict = top_dict
61
  @offset_or_id = offset_or_id || DEFAULT_ENCODING_ID
62
63
  if offset
64
    super(file, offset, length)
65
    @supplemental = format >> 7 == 1
66
  else
67
    @items_count = self.class.codes_for_encoding_id(offset_or_id).size
68
    @supplemental = false
69
  end
70
end

Instance Attribute Details

#formatInteger (readonly)

Encodign format.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/cff/encoding.rb, line 40
40
def format
41
  @format
42
end

#items_countInteger (readonly)

Number of encoded items.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/cff/encoding.rb, line 44
44
def items_count
45
  @items_count
46
end

#offset_or_idInteger (readonly)

Offset or encoding ID.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/cff/encoding.rb, line 48
48
def offset_or_id
49
  @offset_or_id
50
end

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

Top dict.

Source Code
lib/ttfunk/table/cff/encoding.rb, line 36
36
def top_dict
37
  @top_dict
38
end

Class Method Details

.codes_for_encoding_id(encoding_id) ⇒ TTFunk::OneBasedArray<Integer>

Get predefined encoding by ID.

Parameters:

  • encoding_id (Integer)

Returns:

Source Code
lib/ttfunk/table/cff/encoding.rb, line 24
24
def codes_for_encoding_id(encoding_id)
25
  case encoding_id
26
  when STANDARD_ENCODING_ID
27
    Encodings::STANDARD
28
  when EXPERT_ENCODING_ID
29
    Encodings::EXPERT
30
  end
31
end

Instance Method Details

#[](glyph_id) ⇒ Integer?

Get character code for glyph index.

Parameters:

  • glyph_id (Integer)

Returns:

  • (Integer, nil)
Source Code
lib/ttfunk/table/cff/encoding.rb, line 90
90
def [](glyph_id)
91
  return 0 if glyph_id.zero?
92
  return code_for(glyph_id) if offset
93
94
  self.class.codes_for_encoding_id(offset_or_id)[glyph_id]
95
end

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

Iterate over character codes.

Overloads:

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

    This method returns an undefined value.

    Yield Parameters:

    • code (Integer)
  • #eachEnumerator

    Returns:

    • (Enumerator)
Source Code
lib/ttfunk/table/cff/encoding.rb, line 79
79
def each
80
  return to_enum(__method__) unless block_given?
81
82
  # +1 adjusts for the implicit .notdef glyph
83
  (items_count + 1).times { |i| yield(self[i]) }
84
end

#encode(charmap) ⇒ String

Encode encoding.

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/encoding.rb, line 120
120
def encode(charmap)
121
  # Any subset encoding is all but guaranteed to be different from the
122
  # standard encoding so we don't even attempt to see if it matches. We
123
  # assume it's different and just encode it anew.
124
125
  return encode_supplemental(charmap) if supplemental?
126
127
  codes =
128
    charmap
129
      .reject { |_code, mapping| mapping[:new].zero? }
130
      .sort_by { |_code, mapping| mapping[:new] }
131
      .map { |(code, _m)| code }
132
133
  ranges = TTFunk::BinUtils.rangify(codes)
134
135
  # calculate whether storing the charset as a series of ranges is
136
  # more efficient (i.e. takes up less space) vs storing it as an
137
  # array of SID values
138
  total_range_size = (2 * ranges.size) +
139
    (element_width(:range_format) * ranges.size)
140
141
  total_array_size = codes.size * element_width(:array_format)
142
143
  if total_array_size <= total_range_size
144
    ([format_int(:array_format), codes.size] + codes).pack('C*')
145
  else
146
    element_fmt = element_format(:range_format)
147
    result = [format_int(:range_format), ranges.size].pack('CC')
148
    ranges.each { |range| result << range.pack(element_fmt) }
149
    result
150
  end
151
end

#offsetInteger?

Encoding offset in the file.

Returns:

  • (Integer, nil)
Source Code
lib/ttfunk/table/cff/encoding.rb, line 100
100
def offset
101
  # Numbers from 0..1 mean encoding IDs instead of offsets. IDs are
102
  # pre-defined, generic encodings that define the characters present
103
  # in the font.
104
  #
105
  # In the case of an offset, add the CFF table's offset since the
106
  # charset offset is relative to the start of the CFF table. Otherwise
107
  # return nil (no offset).
108
  if offset_or_id > 1
109
    offset_or_id + top_dict.cff_offset
110
  end
111
end

#supplemental?Boolean

Is this a supplemental encoding?

Returns:

  • (Boolean)
Source Code
lib/ttfunk/table/cff/encoding.rb, line 156
156
def supplemental?
157
  # high-order bit set to 1 indicates supplemental encoding
158
  @supplemental
159
end