Class: TTFunk::Table::Cff::TopDict

Inherits:
Dict show all
Defined in:
lib/ttfunk/table/cff/top_dict.rb

Overview

CFF top dict.

Constant Summary collapse

DEFAULT_CHARSTRING_TYPE =

Default charstring type.

2
POINTER_PLACEHOLDER_LENGTH =

Length of placeholders for pointer operators.

5
PLACEHOLDER_LENGTH =

Length of placeholders for other operators.

5
POINTER_OPERATORS =

Operators whose values are offsets that point to other parts of the file.

{
  charset: 15,
  encoding: 16,
  charstrings_index: 17,
  private: 18,
  font_index: 1236,
  font_dict_selector: 1237,
}.freeze
OPERATORS =

All the operators we currently care about.

{
  **POINTER_OPERATORS,
  ros: 1230,
  charstring_type: 1206,
}.freeze
OPERATOR_CODES =

Inverse operator mapping.

OPERATORS.invert

Constants inherited from Dict

Dict::MAX_OPERANDS, Dict::OPERAND_BZERO, Dict::OPERATOR_BZERO, Dict::VALID_SCI_EXPONENT_RE, Dict::VALID_SCI_SIGNIFICAND_RE, Dict::WIDE_OPERATOR_ADJUSTMENT, Dict::WIDE_OPERATOR_BZERO

Instance Attribute Summary

Attributes inherited from SubTable

#file, #length, #table_offset

Instance Method Summary collapse

Methods inherited from Dict

#[], #[]=, #each

Methods inherited from SubTable

#eot?, #initialize, #read

Constructor Details

This class inherits a constructor from TTFunk::SubTable

Instance Method Details

#cffTTFunk::Table::Cff

CFF table in this file.

Returns:



207
208
209
# File 'lib/ttfunk/table/cff/top_dict.rb', line 207

def cff
  file.cff
end

#cff_offsetInteger

Ofsset of CFF table in the file.

Returns:

  • (Integer)


214
215
216
# File 'lib/ttfunk/table/cff/top_dict.rb', line 214

def cff_offset
  cff.offset
end

#charsetTTFunk::Table::Cff::Charset?

Charset specified in this dict.

Returns:



123
124
125
126
127
128
129
130
131
132
# File 'lib/ttfunk/table/cff/top_dict.rb', line 123

def charset
  @charset ||=
    if (charset_offset_or_id = self[OPERATORS[:charset]])
      if charset_offset_or_id.empty?
        Charset.new(self, file)
      else
        Charset.new(self, file, charset_offset_or_id.first)
      end
    end
end

#charstring_typeInteger

Charstring type specified in this dict.

Returns:

  • (Integer)


167
168
169
170
# File 'lib/ttfunk/table/cff/top_dict.rb', line 167

def charstring_type
  @charstring_type =
    self[OPERATORS[:charstring_type]] || DEFAULT_CHARSTRING_TYPE
end

#charstrings_indexTTFunk::Table::Cff::CharstringsIndex?

Charstrings index specified in this dict.

> OpenType fonts with TrueType outlines use a glyph index to specify

and access glyphs within a font; e.g., to index within the `loca`
table and thereby access glyph data in the `glyf` table. This
concept is retained in OpenType CFF fonts, except that glyph data is
accessed through the CharStrings INDEX of the CFF table.

> — [CFF — Compact Font Format Table](www.microsoft.com/typography/otspec/cff.htm)



157
158
159
160
161
162
# File 'lib/ttfunk/table/cff/top_dict.rb', line 157

def charstrings_index
  @charstrings_index ||=
    if (charstrings_offset = self[OPERATORS[:charstrings_index]])
      CharstringsIndex.new(self, file, cff_offset + charstrings_offset.first)
    end
end

#encodeTTFunk::EncodedString

Encode dict.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ttfunk/table/cff/top_dict.rb', line 41

def encode(*)
  EncodedString.new do |result|
    each_with_index do |(operator, operands), _idx|
      if operator == OPERATORS[:private]
        result << encode_private
      elsif pointer_operator?(operator)
        result << Placeholder.new(
          OPERATOR_CODES[operator],
          length: POINTER_PLACEHOLDER_LENGTH,
        )
      else
        operands.each { |operand| result << encode_operand(operand) }
      end

      result << encode_operator(operator)
    end
  end
end

#encodingTTFunk::Table::Cff::Encoding?

Encoding specified in this dict.



137
138
139
140
141
142
143
144
# File 'lib/ttfunk/table/cff/top_dict.rb', line 137

def encoding
  # PostScript type 1 fonts, i.e. CID fonts, i.e. some fonts that use
  # the CFF table, don't specify an encoding, so this can be nil
  @encoding ||=
    if (encoding_offset_or_id = self[OPERATORS[:encoding]])
      Encoding.new(self, file, encoding_offset_or_id.first)
    end
end

#finalize(new_cff_data, charmap) ⇒ void

This method returns an undefined value.

Finalize the table.

Parameters:

  • new_cff_data (TTFunk::EncodedString)
  • 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.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ttfunk/table/cff/top_dict.rb', line 68

def finalize(new_cff_data, charmap)
  if charset
    finalize_subtable(new_cff_data, :charset, charset.encode(charmap))
  end

  if encoding
    finalize_subtable(new_cff_data, :encoding, encoding.encode(charmap))
  end

  if charstrings_index
    finalize_subtable(new_cff_data, :charstrings_index, charstrings_index.encode(charmap))
  end

  if font_index
    finalize_subtable(new_cff_data, :font_index, font_index.encode)

    font_index.finalize(new_cff_data)
  end

  if font_dict_selector
    finalize_subtable(new_cff_data, :font_dict_selector, font_dict_selector.encode(charmap))
  end

  if private_dict
    encoded_private_dict = private_dict.encode
    encoded_offset = encode_integer32(new_cff_data.length)
    encoded_length = encode_integer32(encoded_private_dict.length)

    new_cff_data.resolve_placeholder(:"private_length_#{@table_offset}", encoded_length)
    new_cff_data.resolve_placeholder(:"private_offset_#{@table_offset}", encoded_offset)

    private_dict.finalize(encoded_private_dict)
    new_cff_data << encoded_private_dict
  end
end

#font_dict_selectorTTFunk::Table::Cff::FdSelector?

Font dict selector specified in this dict.



185
186
187
188
189
190
# File 'lib/ttfunk/table/cff/top_dict.rb', line 185

def font_dict_selector
  @font_dict_selector ||=
    if (fd_select_offset = self[OPERATORS[:font_dict_selector]])
      FdSelector.new(self, file, cff_offset + fd_select_offset.first)
    end
end

#font_indexTTFunk::Table::Cff::FontIndex?

Font index specified in this dict.



175
176
177
178
179
180
# File 'lib/ttfunk/table/cff/top_dict.rb', line 175

def font_index
  @font_index ||=
    if (font_index_offset = self[OPERATORS[:font_index]])
      FontIndex.new(self, file, cff_offset + font_index_offset.first)
    end
end

#private_dictTTFunk::Table::Cff::PrivateDict?

Private dict specified in this dict.



195
196
197
198
199
200
201
202
# File 'lib/ttfunk/table/cff/top_dict.rb', line 195

def private_dict
  @private_dict ||=
    if (info = self[OPERATORS[:private]])
      private_dict_length, private_dict_offset = info

      PrivateDict.new(file, cff_offset + private_dict_offset, private_dict_length)
    end
end

#rosArray(Integer, Integer, Integer)?

Registry Ordering Supplement.

Returns:

  • (Array(Integer, Integer, Integer), nil)


107
108
109
# File 'lib/ttfunk/table/cff/top_dict.rb', line 107

def ros
  self[OPERATORS[:ros]]
end

#ros?Boolean Also known as: is_cid_font?

Is Registry Ordering Supplement present in this dict?

Returns:

  • (Boolean)


114
115
116
# File 'lib/ttfunk/table/cff/top_dict.rb', line 114

def ros?
  !ros.nil?
end