Class: Fontisan::Type1::PFMGenerator

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

Overview

PFM (Printer Font Metrics) file generator

PFMGenerator generates Printer Font Metrics files from TTF/OTF fonts.

PFM files are binary files used by Windows for printer font metrics. They include:

  • Character widths
  • Kerning pairs
  • Font metadata (name, version, copyright, etc.)
  • Extended text metrics

Examples:

Generate PFM from TTF

font = Fontisan::FontLoader.load("font.ttf")
pfm_data = Fontisan::Type1::PFMGenerator.generate(font)
File.binwrite("font.pfm", pfm_data)

Generate PFM with 1000 UPM scaling

pfm_data = Fontisan::Type1::PFMGenerator.generate(font, upm_scale: 1000)

See Also:

Constant Summary collapse

PFM_VERSION =

PFM constants

0x0100
PFM_HEADER_SIZE =
256
DRIVER_INFO_SIZE =

Driver info structure

118
EXT_METRICS_SIZE =

Extended metrics size

48
ANSI_CHARSET =

Windows charset constants

0
DEFAULT_CHARSET =
1
SYMBOL_CHARSET =
2
FIXED_PITCH =

Font pitch and family bits

1
VARIABLE_PITCH =
0
FAMILY_DONTCARE =

Family bits (shift left 4)

0 << 4
FAMILY_ROMAN =
1 << 4
FAMILY_SWISS =
2 << 4
FAMILY_MODERN =
3 << 4
FAMILY_SCRIPT =
4 << 4
FAMILY_DECORATIVE =
5 << 4
FAMILY_MODERN_LOWERCASE =
6 << 4

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(font, options = {}) ⇒ PFMGenerator

Initialize a new PFMGenerator

Parameters:



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/fontisan/type1/pfm_generator.rb', line 82

def initialize(font, options = {})
  @font = font
  @metrics = MetricsCalculator.new(font)

  # Set up scaler
  upm_scale = options[:upm_scale] || 1000
  @scaler = if upm_scale == :native
              UPMScaler.native(font)
            else
              UPMScaler.new(font, target_upm: upm_scale)
            end
end

Class Method Details

.generate(font, options = {}) ⇒ String

Generate PFM binary data from a font

Parameters:

Options Hash (options):

  • :upm_scale (Integer, :native)

    Target UPM (1000 for Type 1, :native for no scaling)

Returns:

  • (String)

    PFM file binary data



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

def generate(font, options = {})
  new(font, options).generate_pfm
end

.generate_to_file(font, path, options = {}) ⇒ void

This method returns an undefined value.

Generate PFM file from a font and write to file

Parameters:



72
73
74
75
# File 'lib/fontisan/type1/pfm_generator.rb', line 72

def generate_to_file(font, path, options = {})
  pfm_data = generate(font, options)
  File.binwrite(path, pfm_data)
end

Instance Method Details

#generate_pfmString

Generate PFM binary data

Returns:

  • (String)

    PFM file binary data



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/fontisan/type1/pfm_generator.rb', line 98

def generate_pfm
  # Collect font data
  char_widths = collect_character_widths
  return "" if char_widths.empty?

  # Build sections
  header_data = build_header(char_widths)
  face_name_data = build_face_name
  driver_info_data = build_driver_info
  ext_metrics_data = build_extended_metrics
  width_table_data = build_width_table(char_widths)
  kerning_data = build_kerning_table

  # Calculate offsets
  dfFace_offset = PFM_HEADER_SIZE
  dfExtMetrics_offset = dfFace_offset + face_name_data.length + driver_info_data.length
  dfExtentTable_offset = dfExtMetrics_offset + ext_metrics_data.length
  dfPairKernTable_offset = if kerning_data.empty?
                             0
                           else
                             dfExtentTable_offset + width_table_data.length
                           end
  dfDriverInfo_offset = if dfPairKernTable_offset.positive?
                          dfPairKernTable_offset + kerning_data.length
                        else
                          dfExtentTable_offset + width_table_data.length
                        end

  # Update offsets in header
  update_header_offsets(header_data, dfFace_offset, dfExtMetrics_offset,
                        dfExtentTable_offset, dfPairKernTable_offset,
                        dfDriverInfo_offset)

  # Combine all sections: Header + Face Name + Driver Info + Ext Metrics + Width Table + Kerning
  header_data + face_name_data + driver_info_data + ext_metrics_data +
    width_table_data + kerning_data
end