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" https://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



145
146
147
# File 'lib/fontisan/tables/cff/private_dict.rb', line 145

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



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

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



136
137
138
# File 'lib/fontisan/tables/cff/private_dict.rb', line 136

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)



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

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)



267
268
269
# File 'lib/fontisan/tables/cff/private_dict.rb', line 267

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



237
238
239
# File 'lib/fontisan/tables/cff/private_dict.rb', line 237

def default_width_x
  fetch(:default_width_x)
end

#expansion_factorFloat

Get the expansion factor

Controls horizontal counter expansion

Returns:

  • (Float)

    Expansion factor



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

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



111
112
113
# File 'lib/fontisan/tables/cff/private_dict.rb', line 111

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



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

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



84
85
86
# File 'lib/fontisan/tables/cff/private_dict.rb', line 84

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



192
193
194
# File 'lib/fontisan/tables/cff/private_dict.rb', line 192

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



260
261
262
# File 'lib/fontisan/tables/cff/private_dict.rb', line 260

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



253
254
255
# File 'lib/fontisan/tables/cff/private_dict.rb', line 253

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



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

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)



201
202
203
# File 'lib/fontisan/tables/cff/private_dict.rb', line 201

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



246
247
248
# File 'lib/fontisan/tables/cff/private_dict.rb', line 246

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



102
103
104
# File 'lib/fontisan/tables/cff/private_dict.rb', line 102

def other_blues
  @dict[:other_blues]
end

#std_hwInteger?

Get the standard horizontal width

Dominant horizontal stem width

Returns:

  • (Integer, nil)

    Standard horizontal width



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

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



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

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



176
177
178
# File 'lib/fontisan/tables/cff/private_dict.rb', line 176

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



185
186
187
# File 'lib/fontisan/tables/cff/private_dict.rb', line 185

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



228
229
230
# File 'lib/fontisan/tables/cff/private_dict.rb', line 228

def subrs
  @dict[:subrs]
end