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” 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



95
96
97
# File 'lib/fontisan/tables/cff/top_dict.rb', line 95

def charset
  fetch(:charset)
end

#charstring_typeInteger

Get the CharString type

Returns:

  • (Integer)

    CharString type (typically 2 for Type 2 CharStrings)



205
206
207
# File 'lib/fontisan/tables/cff/top_dict.rb', line 205

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



118
119
120
# File 'lib/fontisan/tables/cff/top_dict.rb', line 118

def charstrings
  @dict[:charstrings]
end

#cid_countInteger

Get the CID count for CIDFonts

Returns:

  • (Integer)

    Number of CIDs



180
181
182
# File 'lib/fontisan/tables/cff/top_dict.rb', line 180

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



166
167
168
# File 'lib/fontisan/tables/cff/top_dict.rb', line 166

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)



212
213
214
215
# File 'lib/fontisan/tables/cff/top_dict.rb', line 212

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)



220
221
222
223
# File 'lib/fontisan/tables/cff/top_dict.rb', line 220

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



109
110
111
# File 'lib/fontisan/tables/cff/top_dict.rb', line 109

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



189
190
191
# File 'lib/fontisan/tables/cff/top_dict.rb', line 189

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



198
199
200
# File 'lib/fontisan/tables/cff/top_dict.rb', line 198

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



80
81
82
# File 'lib/fontisan/tables/cff/top_dict.rb', line 80

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


148
149
150
# File 'lib/fontisan/tables/cff/top_dict.rb', line 148

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



157
158
159
# File 'lib/fontisan/tables/cff/top_dict.rb', line 157

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



127
128
129
# File 'lib/fontisan/tables/cff/top_dict.rb', line 127

def private
  @dict[:private]
end

#private_offsetInteger?

Get the Private DICT offset

Returns:

  • (Integer, nil)

    Offset in bytes, or nil if no Private DICT



141
142
143
# File 'lib/fontisan/tables/cff/top_dict.rb', line 141

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



134
135
136
# File 'lib/fontisan/tables/cff/top_dict.rb', line 134

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


173
174
175
# File 'lib/fontisan/tables/cff/top_dict.rb', line 173

def ros
  @dict[:ros]
end