Class: Fontisan::Tables::Cff::TopDict

Inherits:
Dict
  • Object
show all
Defined in:
lib/fontisan/tables/cff/top_dict.rb

Overview

CFF Top DICT structure

The Top DICT contains font-level metadata and pointers to other CFF structures like CharStrings, Charset, Encoding, and Private DICT.

Top DICT Operators (in addition to common DICT operators):

  • charset: Offset to Charset data
  • encoding: Offset to Encoding data
  • charstrings: Offset to CharStrings INDEX
  • private: Size and offset to Private DICT
  • font_bbox: Font bounding box [xMin, yMin, xMax, yMax]
  • unique_id: Unique ID for this font
  • xuid: Extended unique ID array
  • ros: CIDFont registry, ordering, supplement
  • cidcount: Number of CIDs in CIDFont
  • fdarray: Offset to Font DICT INDEX (CIDFont)
  • fdselect: Offset to FDSelect data (CIDFont)

Reference: CFF specification section 9 "Top DICT" https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf

Examples:

Parsing a Top DICT

top_dict_data = cff.top_dict_index[0]
top_dict = Fontisan::Tables::Cff::TopDict.new(top_dict_data)
puts top_dict[:charstrings]  # => offset to CharStrings
puts top_dict[:charset]      # => offset to Charset

Constant Summary collapse

TOP_DICT_OPERATORS =

Top DICT specific operators

These extend the common operators defined in the base Dict class

{
  5 => :font_bbox,
  13 => :unique_id,
  14 => :xuid,
  15 => :charset,
  16 => :encoding,
  17 => :charstrings,
  18 => :private,
  [12, 30] => :ros,
  [12, 31] => :cid_font_version,
  [12, 32] => :cid_font_revision,
  [12, 33] => :cid_font_type,
  [12, 34] => :cid_count,
  [12, 35] => :uid_base,
  [12, 36] => :fd_array,
  [12, 37] => :fd_select,
  [12, 38] => :font_name,
}.freeze
DEFAULTS =

Default values for Top DICT operators

These are used when an operator is not present in the DICT

{
  is_fixed_pitch: false,
  italic_angle: 0,
  underline_position: -100,
  underline_thickness: 50,
  paint_type: 0,
  charstring_type: 2,
  font_matrix: [0.001, 0, 0, 0.001, 0, 0],
  unique_id: nil,
  font_bbox: [0, 0, 0, 0],
  stroke_width: 0,
  charset: 0,       # Offset 0 = ISOAdobe charset
  encoding: 0,      # Offset 0 = Standard encoding
  cid_count: 8720,
}.freeze

Constants inherited from Dict

Dict::OPERATORS

Instance Attribute Summary

Attributes inherited from Dict

#data, #dict

Instance Method Summary collapse

Methods inherited from Dict

#[], #[]=, #empty?, #has_key?, #initialize, #keys, #size, #to_h, #values

Constructor Details

This class inherits a constructor from Fontisan::Tables::Cff::Dict

Instance Method Details

#charsetInteger

Get the charset offset

Charset determines which glyphs are present and their SIDs

Special values:

  • 0: ISOAdobe charset
  • 1: Expert charset
  • 2: Expert Subset charset
  • Otherwise: Offset to custom charset

Returns:

  • (Integer)

    Charset offset or predefined charset ID



93
94
95
# File 'lib/fontisan/tables/cff/top_dict.rb', line 93

def charset
  fetch(:charset)
end

#charstring_typeInteger

Get the CharString type

Returns:

  • (Integer)

    CharString type (typically 2 for Type 2 CharStrings)



203
204
205
# File 'lib/fontisan/tables/cff/top_dict.rb', line 203

def charstring_type
  fetch(:charstring_type)
end

#charstringsInteger?

Get the CharStrings offset

CharStrings INDEX contains the glyph programs (outline data)

Returns:

  • (Integer, nil)

    Offset to CharStrings INDEX



116
117
118
# File 'lib/fontisan/tables/cff/top_dict.rb', line 116

def charstrings
  @dict[:charstrings]
end

#cid_countInteger

Get the CID count for CIDFonts

Returns:

  • (Integer)

    Number of CIDs



178
179
180
# File 'lib/fontisan/tables/cff/top_dict.rb', line 178

def cid_count
  fetch(:cid_count)
end

#cid_font?Boolean

Check if this is a CIDFont

CIDFonts have the ROS (Registry-Ordering-Supplement) operator

Returns:

  • (Boolean)

    True if CIDFont



164
165
166
# File 'lib/fontisan/tables/cff/top_dict.rb', line 164

def cid_font?
  has_key?(:ros)
end

#custom_charset?Boolean

Check if the font has a custom charset

Returns:

  • (Boolean)

    True if charset is custom (not 0, 1, or 2)



210
211
212
213
# File 'lib/fontisan/tables/cff/top_dict.rb', line 210

def custom_charset?
  charset_val = charset
  charset_val && charset_val > 2
end

#custom_encoding?Boolean

Check if the font has a custom encoding

Returns:

  • (Boolean)

    True if encoding is custom (not 0 or 1)



218
219
220
221
# File 'lib/fontisan/tables/cff/top_dict.rb', line 218

def custom_encoding?
  encoding_val = encoding
  encoding_val && encoding_val > 1
end

#encodingInteger

Get the encoding offset

Encoding maps character codes to glyph indices

Special values:

  • 0: Standard encoding
  • 1: Expert encoding
  • Otherwise: Offset to custom encoding

Returns:

  • (Integer)

    Encoding offset or predefined encoding ID



107
108
109
# File 'lib/fontisan/tables/cff/top_dict.rb', line 107

def encoding
  fetch(:encoding)
end

#fd_arrayInteger?

Get the FDArray offset for CIDFonts

FDArray is a Font DICT INDEX for CIDFonts

Returns:

  • (Integer, nil)

    Offset to FDArray



187
188
189
# File 'lib/fontisan/tables/cff/top_dict.rb', line 187

def fd_array
  @dict[:fd_array]
end

#fd_selectInteger?

Get the FDSelect offset for CIDFonts

FDSelect maps CIDs to Font DICTs in FDArray

Returns:

  • (Integer, nil)

    Offset to FDSelect



196
197
198
# File 'lib/fontisan/tables/cff/top_dict.rb', line 196

def fd_select
  @dict[:fd_select]
end

#fetch(key, default = nil) ⇒ Object

Get a value with default fallback

Parameters:

  • key (Symbol)

    Operator name

Returns:

  • (Object)

    Value or default value



78
79
80
# File 'lib/fontisan/tables/cff/top_dict.rb', line 78

def fetch(key, default = nil)
  @dict.fetch(key, DEFAULTS.fetch(key, default))
end

#font_bboxArray<Integer>

Get the font bounding box

Returns:

  • (Array<Integer>)

    [xMin, yMin, xMax, yMax]



146
147
148
# File 'lib/fontisan/tables/cff/top_dict.rb', line 146

def font_bbox
  fetch(:font_bbox)
end

#font_matrixArray<Float>

Get the font matrix

Transform from glyph space to user space

Returns:

  • (Array<Float>)

    6-element affine transformation matrix



155
156
157
# File 'lib/fontisan/tables/cff/top_dict.rb', line 155

def font_matrix
  fetch(:font_matrix)
end

#privateArray<Integer>?

Get the Private DICT size and offset

The private operator stores [size, offset] as a two-element array

Returns:

  • (Array<Integer>, nil)

    [size, offset] or nil if not present



125
126
127
# File 'lib/fontisan/tables/cff/top_dict.rb', line 125

def private
  @dict[:private]
end

#private_offsetInteger?

Get the Private DICT offset

Returns:

  • (Integer, nil)

    Offset in bytes, or nil if no Private DICT



139
140
141
# File 'lib/fontisan/tables/cff/top_dict.rb', line 139

def private_offset
  private&.last
end

#private_sizeInteger?

Get the Private DICT size

Returns:

  • (Integer, nil)

    Size in bytes, or nil if no Private DICT



132
133
134
# File 'lib/fontisan/tables/cff/top_dict.rb', line 132

def private_size
  private&.first
end

#rosArray<Integer>?

Get the ROS (Registry, Ordering, Supplement) for CIDFonts

Returns:

  • (Array<Integer>, nil)

    [registry_sid, ordering_sid, supplement]



171
172
173
# File 'lib/fontisan/tables/cff/top_dict.rb', line 171

def ros
  @dict[:ros]
end