Class: Fontisan::Tables::Cff::PrivateDict

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

Overview

CFF Private DICT structure

The Private DICT contains glyph-specific hinting and width data. Each font has its own Private DICT (or multiple for CIDFonts).

Private DICT Operators:

  • blue_values: Alignment zones for overshoot suppression

  • other_blues: Additional alignment zones

  • family_blues: Family-wide alignment zones

  • family_other_blues: Family-wide additional alignment zones

  • blue_scale: Point size for overshoot suppression

  • blue_shift: Pixels to shift alignment zones

  • blue_fuzz: Tolerance for alignment zones

  • std_hw: Standard horizontal stem width

  • std_vw: Standard vertical stem width

  • stem_snap_h: Horizontal stem snap widths

  • stem_snap_v: Vertical stem snap widths

  • force_bold: Force bold flag

  • language_group: Language group (0=Latin, 1=CJK)

  • expansion_factor: Expansion factor for counters

  • initial_random_seed: Random seed for Type 1 hinting

  • subrs: Offset to Local Subr INDEX (relative to Private DICT)

  • default_width_x: Default glyph width

  • nominal_width_x: Nominal glyph width

Reference: CFF specification section 10 “Private DICT” adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf

Examples:

Parsing a Private DICT

private_size, private_offset = top_dict.private
private_data = cff.raw_data[private_offset, private_size]
private_dict = Fontisan::Tables::Cff::PrivateDict.new(private_data)
puts private_dict[:blue_values]  # => [array of blue values]
puts private_dict.default_width_x  # => default glyph width

Constant Summary collapse

PRIVATE_DICT_OPERATORS =

Private DICT specific operators

These extend the common operators defined in the base Dict class

{
  6 => :blue_values,
  7 => :other_blues,
  8 => :family_blues,
  9 => :family_other_blues,
  [12, 9] => :blue_scale,
  [12, 10] => :blue_shift,
  [12, 11] => :blue_fuzz,
  10 => :std_hw,
  11 => :std_vw,
  [12, 12] => :stem_snap_h,
  [12, 13] => :stem_snap_v,
  [12, 14] => :force_bold,
  [12, 17] => :language_group,
  [12, 18] => :expansion_factor,
  [12, 19] => :initial_random_seed,
  19 => :subrs,
  20 => :default_width_x,
  21 => :nominal_width_x,
}.freeze
DEFAULTS =

Default values for Private DICT operators

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

{
  blue_scale: 0.039625,
  blue_shift: 7,
  blue_fuzz: 1,
  force_bold: false,
  language_group: 0,
  expansion_factor: 0.06,
  initial_random_seed: 0,
  default_width_x: 0,
  nominal_width_x: 0,
}.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

#blue_fuzzInteger

Get the blue fuzz

Tolerance for alignment zone matching

Returns:

  • (Integer)

    Blue fuzz in font units



147
148
149
# File 'lib/fontisan/tables/cff/private_dict.rb', line 147

def blue_fuzz
  fetch(:blue_fuzz)
end

#blue_scaleFloat

Get the blue scale

Point size at which overshoot suppression is maximum

Returns:

  • (Float)

    Blue scale value



129
130
131
# File 'lib/fontisan/tables/cff/private_dict.rb', line 129

def blue_scale
  fetch(:blue_scale)
end

#blue_shiftInteger

Get the blue shift

Number of device pixels to shift alignment zones

Returns:

  • (Integer)

    Blue shift in pixels



138
139
140
# File 'lib/fontisan/tables/cff/private_dict.rb', line 138

def blue_shift
  fetch(:blue_shift)
end

#blue_valuesArray<Integer>?

Get the blue values (alignment zones)

Blue values define vertical zones for overshoot suppression

Returns:

  • (Array<Integer>, nil)

    Array of blue values (pairs of bottom/top)



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

def blue_values
  @dict[:blue_values]
end

#cjk?Boolean

Check if this is for CJK language group

Returns:

  • (Boolean)

    True if language group is 1 (CJK)



269
270
271
# File 'lib/fontisan/tables/cff/private_dict.rb', line 269

def cjk?
  language_group == 1
end

#default_width_xInteger

Get the default glyph width

Used when width is not explicitly specified in CharString

Returns:

  • (Integer)

    Default width in font units



239
240
241
# File 'lib/fontisan/tables/cff/private_dict.rb', line 239

def default_width_x
  fetch(:default_width_x)
end

#expansion_factorFloat

Get the expansion factor

Controls horizontal counter expansion

Returns:

  • (Float)

    Expansion factor



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

def expansion_factor
  fetch(:expansion_factor)
end

#family_bluesArray<Integer>?

Get the family blue values

Family-wide alignment zones shared across fonts in a family

Returns:

  • (Array<Integer>, nil)

    Array of family blue values



113
114
115
# File 'lib/fontisan/tables/cff/private_dict.rb', line 113

def family_blues
  @dict[:family_blues]
end

#family_other_bluesArray<Integer>?

Get the family other blue values

Returns:

  • (Array<Integer>, nil)

    Array of family other blue values



120
121
122
# File 'lib/fontisan/tables/cff/private_dict.rb', line 120

def family_other_blues
  @dict[:family_other_blues]
end

#fetch(key, default = nil) ⇒ Object

Get a value with default fallback

Parameters:

  • key (Symbol)

    Operator name

Returns:

  • (Object)

    Value or default value



86
87
88
# File 'lib/fontisan/tables/cff/private_dict.rb', line 86

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

#force_bold?Boolean

Check if force bold is enabled

Returns:

  • (Boolean)

    True if force bold is enabled



194
195
196
# File 'lib/fontisan/tables/cff/private_dict.rb', line 194

def force_bold?
  fetch(:force_bold)
end

#has_blue_values?Boolean

Check if this Private DICT has blue values defined

Returns:

  • (Boolean)

    True if blue values are present



262
263
264
# File 'lib/fontisan/tables/cff/private_dict.rb', line 262

def has_blue_values?
  !blue_values.nil? && !blue_values.empty?
end

#has_local_subrs?Boolean

Check if this Private DICT has local subroutines

Returns:

  • (Boolean)

    True if subrs offset is present



255
256
257
# File 'lib/fontisan/tables/cff/private_dict.rb', line 255

def has_local_subrs?
  !subrs.nil?
end

#initial_random_seedInteger

Get the initial random seed

Seed for pseudo-random number generation in Type 1 hinting

Returns:

  • (Integer)

    Initial random seed



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

def initial_random_seed
  fetch(:initial_random_seed)
end

#language_groupInteger

Get the language group

0 = Latin/Greek/Cyrillic, 1 = CJK

Returns:

  • (Integer)

    Language group (0 or 1)



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

def language_group
  fetch(:language_group)
end

#nominal_width_xInteger

Get the nominal glyph width

Base value for width calculations in CharStrings

Returns:

  • (Integer)

    Nominal width in font units



248
249
250
# File 'lib/fontisan/tables/cff/private_dict.rb', line 248

def nominal_width_x
  fetch(:nominal_width_x)
end

#other_bluesArray<Integer>?

Get the other blue values

Additional alignment zones beyond the baseline and cap height

Returns:

  • (Array<Integer>, nil)

    Array of other blue values



104
105
106
# File 'lib/fontisan/tables/cff/private_dict.rb', line 104

def other_blues
  @dict[:other_blues]
end

#std_hwInteger?

Get the standard horizontal width

Dominant horizontal stem width

Returns:

  • (Integer, nil)

    Standard horizontal width



156
157
158
159
160
# File 'lib/fontisan/tables/cff/private_dict.rb', line 156

def std_hw
  value = @dict[:std_hw]
  # std_hw is stored as an array with one element
  value.is_a?(Array) ? value.first : value
end

#std_vwInteger?

Get the standard vertical width

Dominant vertical stem width

Returns:

  • (Integer, nil)

    Standard vertical width



167
168
169
170
171
# File 'lib/fontisan/tables/cff/private_dict.rb', line 167

def std_vw
  value = @dict[:std_vw]
  # std_vw is stored as an array with one element
  value.is_a?(Array) ? value.first : value
end

#stem_snap_hArray<Integer>?

Get the horizontal stem snap widths

Array of horizontal stem widths for stem snapping

Returns:

  • (Array<Integer>, nil)

    Horizontal stem snap widths



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

def stem_snap_h
  @dict[:stem_snap_h]
end

#stem_snap_vArray<Integer>?

Get the vertical stem snap widths

Array of vertical stem widths for stem snapping

Returns:

  • (Array<Integer>, nil)

    Vertical stem snap widths



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

def stem_snap_v
  @dict[:stem_snap_v]
end

#subrsInteger?

Get the Local Subr INDEX offset

Offset is relative to the beginning of the Private DICT

Returns:

  • (Integer, nil)

    Offset to Local Subr INDEX



230
231
232
# File 'lib/fontisan/tables/cff/private_dict.rb', line 230

def subrs
  @dict[:subrs]
end