Class: Fontisan::Converters::FormatConverter

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/converters/format_converter.rb

Overview

Main orchestrator for font format conversions

[‘FormatConverter`](lib/fontisan/converters/format_converter.rb) is the primary entry point for all format conversion operations. It:

  • Selects appropriate conversion strategy based on source/target formats

  • Validates conversions against the conversion matrix

  • Delegates actual conversion to strategy implementations

  • Provides clean error messages for unsupported conversions

The converter uses a strategy pattern with pluggable strategies for different conversion types:

  • OutlineConverter: TTF ↔ OTF conversions

  • TableCopier: Same-format operations

  • Woff2Encoder: TTF/OTF → WOFF2 compression

  • SvgGenerator: TTF/OTF → SVG font generation

Supported conversions are defined in the conversion matrix configuration file, making it easy to extend without modifying code.

Examples:

Converting TTF to OTF

converter = Fontisan::Converters::FormatConverter.new
tables = converter.convert(font, :otf)
FontWriter.write_to_file(tables, 'output.otf',
                         sfnt_version: 0x4F54544F)

Same-format copy

converter = Fontisan::Converters::FormatConverter.new
tables = converter.convert(font, :ttf)  # TTF to TTF
FontWriter.write_to_file(tables, 'copy.ttf')

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(conversion_matrix_path: nil) ⇒ FormatConverter

Initialize converter with strategies

Parameters:

  • conversion_matrix_path (String, nil) (defaults to: nil)

    Path to conversion matrix config. If nil, uses default.



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/fontisan/converters/format_converter.rb', line 54

def initialize(conversion_matrix_path: nil)
  @strategies = [
    TableCopier.new,
    OutlineConverter.new,
    Type1Converter.new,
    WoffWriter.new,
    Woff2Encoder.new,
    SvgGenerator.new,
  ]

  load_conversion_matrix(conversion_matrix_path)
end

Instance Attribute Details

#conversion_matrixHash (readonly)

Returns Conversion matrix loaded from config.

Returns:

  • (Hash)

    Conversion matrix loaded from config



45
46
47
# File 'lib/fontisan/converters/format_converter.rb', line 45

def conversion_matrix
  @conversion_matrix
end

#strategiesArray (readonly)

Returns Available conversion strategies.

Returns:

  • (Array)

    Available conversion strategies



48
49
50
# File 'lib/fontisan/converters/format_converter.rb', line 48

def strategies
  @strategies
end

Instance Method Details

#all_conversionsArray<Hash>

Get all supported conversions

Returns:

  • (Array<Hash>)

    Array of conversion hashes with :from and :to



160
161
162
163
164
165
166
167
168
169
# File 'lib/fontisan/converters/format_converter.rb', line 160

def all_conversions
  return [] unless conversion_matrix

  conversions = conversion_matrix["conversions"]
  return [] unless conversions

  conversions.map do |conv|
    { from: conv["from"].to_sym, to: conv["to"].to_sym }
  end
end

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

Convert font to target format

This is the main entry point for format conversion. It:

  1. Detects source format from font

  2. Validates conversion is supported

  3. Selects appropriate strategy

  4. Delegates conversion to strategy

Examples:

tables = converter.convert(font, :otf)

Variable font to SVG at specific weight

result = converter.convert(variable_font, :svg, instance_coordinates: { "wght" => 700.0 })

Convert with hint preservation

tables = converter.convert(font, :otf, preserve_hints: true)

Parameters:

  • font (TrueTypeFont, OpenTypeFont)

    Source font

  • target_format (Symbol)

    Target format (:ttf, :otf, :woff2, :svg)

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

    Additional conversion options

Options Hash (options):

  • :preserve_variation (Boolean)

    Preserve variation data (default: true)

  • :preserve_hints (Boolean)

    Preserve rendering hints (default: false)

  • :instance_coordinates (Hash)

    Coordinates for variable→SVG

  • :instance_index (Integer)

    Named instance index for variable→SVG

Returns:

  • (Hash<String, String>)

    Map of table tags to binary data

Raises:

  • (ArgumentError)

    If parameters are invalid

  • (Error)

    If conversion is not supported



96
97
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
# File 'lib/fontisan/converters/format_converter.rb', line 96

def convert(font, target_format, options = {})
  validate_parameters!(font, target_format)

  source_format = detect_format(font)
  validate_conversion_supported!(source_format, target_format)

  # Special case: Variable font to SVG
  if variable_font?(font) && target_format == :svg
    return convert_variable_to_svg(font, options)
  end

  strategy = select_strategy(source_format, target_format)
  tables = strategy.convert(font,
                            options.merge(target_format: target_format))

  # Preserve variation data if requested and font is variable
  if options.fetch(:preserve_variation, true) && variable_font?(font)
    tables = preserve_variation_data(
      font,
      tables,
      source_format,
      target_format,
      options,
    )
  end

  tables
end

#supported?(source_format, target_format) ⇒ Boolean

Check if a conversion is supported

Parameters:

  • source_format (Symbol)

    Source format

  • target_format (Symbol)

    Target format

Returns:

  • (Boolean)

    True if conversion is supported



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/fontisan/converters/format_converter.rb', line 130

def supported?(source_format, target_format)
  return false unless conversion_matrix

  conversions = conversion_matrix["conversions"]
  return false unless conversions

  conversions.any? do |conv|
    conv["from"] == source_format.to_s &&
      conv["to"] == target_format.to_s
  end
end

#supported_targets(source_format) ⇒ Array<Symbol>

Get list of supported target formats for a source format

Parameters:

  • source_format (Symbol)

    Source format

Returns:

  • (Array<Symbol>)

    Supported target formats



146
147
148
149
150
151
152
153
154
155
# File 'lib/fontisan/converters/format_converter.rb', line 146

def supported_targets(source_format)
  return [] unless conversion_matrix

  conversions = conversion_matrix["conversions"]
  return [] unless conversions

  conversions
    .select { |conv| conv["from"] == source_format.to_s }
    .map { |conv| conv["to"].to_sym }
end