Class: Fontisan::Converters::Type1Converter

Inherits:
Object
  • Object
show all
Includes:
CffTableBuilder, ConversionStrategy
Defined in:
lib/fontisan/converters/type1_converter.rb

Overview

Converter for Adobe Type 1 fonts to/from SFNT formats.

[‘Type1Converter`](lib/fontisan/converters/type1_converter.rb) handles bidirectional conversion between Type 1 fonts (PFB/PFA) and SFNT-based formats (TTF, OTF, WOFF, WOFF2).

Conversion Strategy

Type 1 fonts use PostScript CharStrings that are similar to CFF CharStrings used in OpenType fonts. The conversion uses CharStringConverter for the CharString translation.

  • Type 1 → OTF: Convert Type 1 CharStrings to CFF format, build CFF table

  • OTF → Type 1: Convert CFF CharStrings to Type 1 format, build PFB/PFA

  • Type 1 → TTF: Type 1 → OTF → TTF (via OutlineConverter)

  • TTF → Type 1: TTF → OTF → Type 1

Conversion Options

The converter accepts [‘ConversionOptions`](../conversion_options) with opening and generating options:

  • Opening options: decompose_composites, generate_unicode, read_all_records

  • Generating options: decompose_on_output, hinting_mode, write_pfm, write_afm

Examples:

Convert Type 1 to OTF with options

font = FontLoader.load("font.pfb")
options = ConversionOptions.recommended(from: :type1, to: :otf)
converter = Type1Converter.new
tables = converter.convert(font, options: options)

Convert with preset

options = ConversionOptions.from_preset(:type1_to_modern)
tables = converter.convert(font, options: options)

See Also:

Instance Method Summary collapse

Methods included from CffTableBuilder

#build_cff_table

Methods included from ConversionStrategy

#supports?

Constructor Details

#initialize(options = {}) ⇒ Type1Converter

Initialize a new Type1Converter

Parameters:

  • options (Hash) (defaults to: {})

    Converter options

Options Hash (options):

  • :optimize_cff (Boolean)

    Enable CFF optimization (default: false)

  • :preserve_hints (Boolean)

    Preserve hinting (default: true)

  • :target_format (Symbol)

    Target format for conversion



61
62
63
64
65
# File 'lib/fontisan/converters/type1_converter.rb', line 61

def initialize(options = {})
  @optimize_cff = options.fetch(:optimize_cff, false)
  @preserve_hints = options.fetch(:preserve_hints, true)
  @target_format = options[:target_format]
end

Instance Method Details

#convert(font, options = {}) ⇒ Hash<String, String>

Convert font to target format

Parameters:

Options Hash (options):

  • :target_format (Symbol)

    Target format override

  • :options (ConversionOptions)

    ConversionOptions object

Returns:

  • (Hash<String, String>)

    Map of table tags to binary data



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/fontisan/converters/type1_converter.rb', line 74

def convert(font, options = {})
  # Extract ConversionOptions if provided
  conv_options = extract_conversion_options(options)

  target_format = options[:target_format] || conv_options&.to || @target_format ||
    detect_target_format(font)
  validate(font, target_format)

  # Apply opening options to source font
  apply_opening_options(font, conv_options) if conv_options

  source_format = detect_format(font)

  case [source_format, target_format]
  when %i[type1 otf]
    convert_type1_to_otf(font, conv_options)
  when %i[otf type1]
    convert_otf_to_type1(font, conv_options)
  when %i[type1 ttf]
    convert_type1_to_ttf(font, conv_options)
  when %i[ttf type1]
    convert_ttf_to_type1(font, conv_options)
  else
    raise Fontisan::Error,
          "Unsupported conversion: #{source_format}#{target_format}"
  end
end

#supported_conversionsArray<Array<Symbol>>

Get supported conversions

Returns:

  • (Array<Array<Symbol>>)

    Supported conversion pairs



105
106
107
108
109
110
111
112
# File 'lib/fontisan/converters/type1_converter.rb', line 105

def supported_conversions
  [
    %i[type1 otf],
    %i[otf type1],
    %i[type1 ttf],
    %i[ttf type1],
  ]
end

#validate(font, target_format) ⇒ Boolean

Validate font for conversion

Parameters:

Returns:

  • (Boolean)

    True if valid

Raises:

  • (ArgumentError)

    If font is invalid

  • (Error)

    If conversion is not supported



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/fontisan/converters/type1_converter.rb', line 121

def validate(font, target_format)
  raise ArgumentError, "Font cannot be nil" if font.nil?

  unless font.respond_to?(:font_dictionary) || font.respond_to?(:tables)
    raise ArgumentError,
          "Font must be Type1Font or have :tables method"
  end

  source_format = detect_format(font)
  unless supports?(source_format, target_format)
    raise Fontisan::Error,
          "Conversion #{source_format}#{target_format} not supported"
  end

  true
end