Class: Fontisan::Type1::PrivateDict

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/type1/private_dict.rb

Overview

Type 1 Private Dictionary model

PrivateDict parses and stores the private dictionary from a Type 1 font, which contains hinting and spacing information used by the CharString interpreter.

The private dictionary includes:

  • BlueValues and OtherBlues (alignment zones for optical consistency)
  • StdHW and StdVW (standard stem widths)
  • StemSnapH and StemSnapV (stem snap arrays)
  • Subrs (local subroutines)
  • lenIV (CharString encryption IV length)

Examples:

Parse private dictionary from decrypted font data

priv = Fontisan::Type1::PrivateDict.parse(decrypted_data)
puts priv.blue_values
puts priv.std_hw

See Also:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePrivateDict

Initialize a new PrivateDict



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/fontisan/type1/private_dict.rb', line 92

def initialize
  @blue_values = []
  @other_blues = []
  @family_blues = []
  @family_other_blues = []
  @blue_scale = 0.039625
  @blue_shift = 7
  @blue_fuzz = 1
  @std_hw = []
  @std_vw = []
  @stem_snap_h = []
  @stem_snap_v = []
  @force_bold = false
  @len_iv = 4
  @subrs = []
  @language_group = 0
  @expansion_factor = 0.06
  @initial_random_seed = 0
  @raw_data = {}
  @parsed = false
end

Instance Attribute Details

#blue_fuzzInteger

Returns BlueFuzz.

Returns:

  • (Integer)

    BlueFuzz



44
45
46
# File 'lib/fontisan/type1/private_dict.rb', line 44

def blue_fuzz
  @blue_fuzz
end

#blue_scaleFloat

Returns BlueScale.

Returns:

  • (Float)

    BlueScale



38
39
40
# File 'lib/fontisan/type1/private_dict.rb', line 38

def blue_scale
  @blue_scale
end

#blue_shiftInteger

Returns BlueShift.

Returns:

  • (Integer)

    BlueShift



41
42
43
# File 'lib/fontisan/type1/private_dict.rb', line 41

def blue_shift
  @blue_shift
end

#blue_valuesArray<Integer>

Returns BlueValues alignment zones.

Returns:

  • (Array<Integer>)

    BlueValues alignment zones



26
27
28
# File 'lib/fontisan/type1/private_dict.rb', line 26

def blue_values
  @blue_values
end

#expansion_factorFloat

Returns ExpansionFactor for counter widening.

Returns:

  • (Float)

    ExpansionFactor for counter widening



71
72
73
# File 'lib/fontisan/type1/private_dict.rb', line 71

def expansion_factor
  @expansion_factor
end

#family_bluesArray<Integer>

Returns FamilyBlues alignment zones.

Returns:

  • (Array<Integer>)

    FamilyBlues alignment zones



32
33
34
# File 'lib/fontisan/type1/private_dict.rb', line 32

def family_blues
  @family_blues
end

#family_other_bluesArray<Integer>

Returns FamilyOtherBlues alignment zones.

Returns:

  • (Array<Integer>)

    FamilyOtherBlues alignment zones



35
36
37
# File 'lib/fontisan/type1/private_dict.rb', line 35

def family_other_blues
  @family_other_blues
end

#force_boldBoolean

Returns ForceBold flag.

Returns:

  • (Boolean)

    ForceBold flag



59
60
61
# File 'lib/fontisan/type1/private_dict.rb', line 59

def force_bold
  @force_bold
end

#initial_random_seedInteger

Returns InitialRandomSeed for randomization.

Returns:

  • (Integer)

    InitialRandomSeed for randomization



74
75
76
# File 'lib/fontisan/type1/private_dict.rb', line 74

def initial_random_seed
  @initial_random_seed
end

#language_groupInteger

Returns LanguageGroup (0 for Latin, 1 for Japanese, etc.).

Returns:

  • (Integer)

    LanguageGroup (0 for Latin, 1 for Japanese, etc.)



68
69
70
# File 'lib/fontisan/type1/private_dict.rb', line 68

def language_group
  @language_group
end

#len_ivInteger

Returns lenIV (CharString encryption IV length).

Returns:

  • (Integer)

    lenIV (CharString encryption IV length)



62
63
64
# File 'lib/fontisan/type1/private_dict.rb', line 62

def len_iv
  @len_iv
end

#other_bluesArray<Integer>

Returns OtherBlues alignment zones.

Returns:

  • (Array<Integer>)

    OtherBlues alignment zones



29
30
31
# File 'lib/fontisan/type1/private_dict.rb', line 29

def other_blues
  @other_blues
end

#raw_dataHash (readonly)

Returns Raw dictionary data.

Returns:

  • (Hash)

    Raw dictionary data



77
78
79
# File 'lib/fontisan/type1/private_dict.rb', line 77

def raw_data
  @raw_data
end

#std_hwArray<Float>

Returns StdHW (standard horizontal width).

Returns:

  • (Array<Float>)

    StdHW (standard horizontal width)



47
48
49
# File 'lib/fontisan/type1/private_dict.rb', line 47

def std_hw
  @std_hw
end

#std_vwArray<Float>

Returns StdVW (standard vertical width).

Returns:

  • (Array<Float>)

    StdVW (standard vertical width)



50
51
52
# File 'lib/fontisan/type1/private_dict.rb', line 50

def std_vw
  @std_vw
end

#stem_snap_hArray<Float>

Returns StemSnapH (horizontal stem snap array).

Returns:

  • (Array<Float>)

    StemSnapH (horizontal stem snap array)



53
54
55
# File 'lib/fontisan/type1/private_dict.rb', line 53

def stem_snap_h
  @stem_snap_h
end

#stem_snap_vArray<Float>

Returns StemSnapV (vertical stem snap array).

Returns:

  • (Array<Float>)

    StemSnapV (vertical stem snap array)



56
57
58
# File 'lib/fontisan/type1/private_dict.rb', line 56

def stem_snap_v
  @stem_snap_v
end

#subrsArray<String>

Returns Subrs (local subroutines).

Returns:

  • (Array<String>)

    Subrs (local subroutines)



65
66
67
# File 'lib/fontisan/type1/private_dict.rb', line 65

def subrs
  @subrs
end

Class Method Details

.parse(data) ⇒ PrivateDict

Parse private dictionary from decrypted Type 1 font data

Examples:

Parse from decrypted font data

priv = Fontisan::Type1::PrivateDict.parse(decrypted_data)

Parameters:

  • data (String)

    Decrypted Type 1 font data

Returns:

Raises:



87
88
89
# File 'lib/fontisan/type1/private_dict.rb', line 87

def self.parse(data)
  new.parse(data)
end

Instance Method Details

#[](key) ⇒ Object?

Get raw value from dictionary

Parameters:

  • key (String)

    Dictionary key

Returns:

  • (Object, nil)

    Value or nil if not found



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

def [](key)
  @raw_data[key]
end

#array_to_type1(name, value) ⇒ String

Format an array value for Type 1 output

Parameters:

  • name (Symbol)

    Array name

  • value (Array)

    Array value

Returns:

  • (String)

    Formatted Type 1 array definition



222
223
224
# File 'lib/fontisan/type1/private_dict.rb', line 222

def array_to_type1(name, value)
  "/#{name} [#{value.join(' ')}] def"
end

#boolean_to_type1(name, value) ⇒ String

Format a boolean value for Type 1 output

Parameters:

  • name (Symbol)

    Value name

  • value (Boolean)

    Boolean value

Returns:

  • (String)

    Formatted Type 1 boolean definition



240
241
242
# File 'lib/fontisan/type1/private_dict.rb', line 240

def boolean_to_type1(name, value)
  "/#{name} #{value} def"
end

#effective_blue_valuesArray<Float>

Get effective BlueValues for hinting

Returns BlueValues adjusted by BlueScale.

Returns:

  • (Array<Float>)

    Scaled blue values



145
146
147
148
149
# File 'lib/fontisan/type1/private_dict.rb', line 145

def effective_blue_values
  return [] if @blue_values.empty?

  @blue_values.map { |v| v * @blue_scale }
end

#has_blues?Boolean

Check if font has blues

Returns:

  • (Boolean)

    True if BlueValues or OtherBlues are defined



154
155
156
# File 'lib/fontisan/type1/private_dict.rb', line 154

def has_blues?
  !@blue_values.empty? || !@other_blues.empty?
end

#has_stem_hints?Boolean

Check if font has stem hints

Returns:

  • (Boolean)

    True if StdHW, StdVW, or StemSnap arrays are defined



161
162
163
164
# File 'lib/fontisan/type1/private_dict.rb', line 161

def has_stem_hints?
  !@std_hw.empty? || !@std_vw.empty? ||
    !@stem_snap_h.empty? || !@stem_snap_v.empty?
end

#parse(data) ⇒ PrivateDict

Parse private dictionary from decrypted Type 1 font data

Parameters:

  • data (String)

    Decrypted Type 1 font data

Returns:



118
119
120
121
122
123
# File 'lib/fontisan/type1/private_dict.rb', line 118

def parse(data)
  extract_private_dict(data)
  extract_properties
  @parsed = true
  self
end

#parsed?Boolean

Check if dictionary was successfully parsed

Returns:

  • (Boolean)

    True if dictionary has been parsed



128
129
130
# File 'lib/fontisan/type1/private_dict.rb', line 128

def parsed?
  @parsed
end

#scalar_to_type1(name, value) ⇒ String

Format a scalar value for Type 1 output

Parameters:

  • name (Symbol)

    Value name

  • value (Numeric)

    Numeric value

Returns:

  • (String)

    Formatted Type 1 scalar definition



231
232
233
# File 'lib/fontisan/type1/private_dict.rb', line 231

def scalar_to_type1(name, value)
  "/#{name} #{value} def"
end

#to_type1_formatString

Convert PrivateDict to Type 1 text format

Generates the PostScript code for the Private dictionary section of a Type 1 font.

Examples:

Generate Type 1 format

priv = PrivateDict.new
priv.blue_values = [-10, 0, 470, 480]
puts priv.to_type1_format

Returns:

  • (String)

    Type 1 Private dictionary text



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/fontisan/type1/private_dict.rb', line 177

def to_type1_format
  result = []
  unless @blue_values.empty?
    result << array_to_type1(:BlueValues,
                             @blue_values)
  end
  unless @other_blues.empty?
    result << array_to_type1(:OtherBlues,
                             @other_blues)
  end
  unless @family_blues.empty?
    result << array_to_type1(:FamilyBlues,
                             @family_blues)
  end
  unless @family_other_blues.empty?
    result << array_to_type1(:FamilyOtherBlues,
                             @family_other_blues)
  end
  result << scalar_to_type1(:BlueScale, @blue_scale)
  result << scalar_to_type1(:BlueShift, @blue_shift)
  result << scalar_to_type1(:BlueFuzz, @blue_fuzz)
  result << array_to_type1(:StdHW, @std_hw) unless @std_hw.empty?
  result << array_to_type1(:StdVW, @std_vw) unless @std_vw.empty?
  unless @stem_snap_h.empty?
    result << array_to_type1(:StemSnapH,
                             @stem_snap_h)
  end
  unless @stem_snap_v.empty?
    result << array_to_type1(:StemSnapV,
                             @stem_snap_v)
  end
  unless @force_bold == false
    result << boolean_to_type1(:ForceBold,
                               @force_bold)
  end
  result << scalar_to_type1(:lenIV, @len_iv)

  result.join("\n")
end