Class: Fontisan::Variation::InstanceWriter
- Inherits:
-
Object
- Object
- Fontisan::Variation::InstanceWriter
- Defined in:
- lib/fontisan/variation/instance_writer.rb
Overview
Writes generated static font instances to files in various formats
InstanceWriter takes
instance tables generated by
InstanceGenerator and
writes them to files in the desired output format. It handles:
- Format detection from file extension
- Format conversion when needed (e.g., glyf → CFF for OTF)
- SFNT version selection based on output format
- Integration with FontWriter for binary output
- Integration with OutlineConverter for format conversion
- Integration with WoffWriter for WOFF packaging
Supported Output Formats:
- TTF (TrueType with glyf outlines)
- OTF (OpenType with CFF outlines)
- WOFF (Web Open Font Format)
- WOFF2 (Web Open Font Format 2.0, future)
Constant Summary collapse
- SUPPORTED_FORMATS =
Supported output formats
%i[ttf otf woff woff2].freeze
- SFNT_VERSION_TRUETYPE =
SFNT version constants
0x00010000- SFNT_VERSION_CFF =
TrueType with glyf
0x4F54544F- TABLE_PARSERS =
Per-tag table parser dispatch. Each entry maps tag → [class, init_mode]. :parse means call obj.parse(data); :data= means call obj.data = data.
{ "head" => [Tables::Head, :parse], "maxp" => [Tables::Maxp, :parse], "loca" => [Tables::Loca, :data_assign], "glyf" => [Tables::Glyf, :data_assign], "CFF " => [Tables::Cff, :parse], "CFF2" => [Tables::Cff2, :parse], }.freeze
Instance Attribute Summary collapse
-
#options ⇒ Hash
readonly
Writer options.
-
#tables ⇒ Hash<String, String>
readonly
Instance tables.
Class Method Summary collapse
-
.write(tables, output_path, options = {}) ⇒ Integer
Write instance tables to file.
Instance Method Summary collapse
-
#initialize(tables, options = {}) ⇒ InstanceWriter
constructor
Initialize writer with instance tables.
- #parse_table(tag, data) ⇒ Object
-
#sfnt_version_for_format(format) ⇒ Integer
Get SFNT version for output format.
-
#write(output_path) ⇒ Integer
Write instance to file.
-
#write_sfnt(tables, output_path, format) ⇒ Integer
Write SFNT format (TTF or OTF).
-
#write_woff(tables, output_path, source_format) ⇒ Integer
Write WOFF format.
-
#write_woff2(tables, output_path, source_format) ⇒ Integer
Write WOFF2 format.
Constructor Details
#initialize(tables, options = {}) ⇒ InstanceWriter
Initialize writer with instance tables
76 77 78 79 80 |
# File 'lib/fontisan/variation/instance_writer.rb', line 76 def initialize(tables, = {}) @tables = tables @options = validate_tables! end |
Instance Attribute Details
#options ⇒ Hash (readonly)
Returns Writer options.
67 68 69 |
# File 'lib/fontisan/variation/instance_writer.rb', line 67 def @options end |
#tables ⇒ Hash<String, String> (readonly)
Returns Instance tables.
64 65 66 |
# File 'lib/fontisan/variation/instance_writer.rb', line 64 def tables @tables end |
Class Method Details
.write(tables, output_path, options = {}) ⇒ Integer
Write instance tables to file
59 60 61 |
# File 'lib/fontisan/variation/instance_writer.rb', line 59 def self.write(tables, output_path, = {}) new(tables, ).write(output_path) end |
Instance Method Details
#parse_table(tag, data) ⇒ Object
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/fontisan/variation/instance_writer.rb', line 267 def parse_table(tag, data) entry = TABLE_PARSERS[tag] if entry klass, init_mode = entry obj = klass.new init_mode == :parse ? obj.parse(data) : obj.data = data obj else # For other tables, return a simple object that just holds data Object.new.tap do |obj| obj.define_singleton_method(:data) { data } end end rescue StandardError => e warn "Warning: Failed to parse #{tag} table: #{e.}" nil end |
#sfnt_version_for_format(format) ⇒ Integer
Get SFNT version for output format
355 356 357 |
# File 'lib/fontisan/variation/instance_writer.rb', line 355 def sfnt_version_for_format(format) format == :otf ? SFNT_VERSION_CFF : SFNT_VERSION_TRUETYPE end |
#write(output_path) ⇒ Integer
Write instance to file
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/fontisan/variation/instance_writer.rb', line 86 def write(output_path) # Detect output format format = detect_output_format(output_path) validate_format!(format) # Detect source format from tables source_format = detect_source_format(@tables) # Convert format if needed output_tables = if format_conversion_needed?(source_format, format) convert_format(source_format, format) else @tables end # Write to file based on format case format when :ttf, :otf write_sfnt(output_tables, output_path, format) when :woff write_woff(output_tables, output_path, source_format) when :woff2 write_woff2(output_tables, output_path, source_format) end end |
#write_sfnt(tables, output_path, format) ⇒ Integer
Write SFNT format (TTF or OTF)
291 292 293 294 295 296 297 298 299 300 |
# File 'lib/fontisan/variation/instance_writer.rb', line 291 def write_sfnt(tables, output_path, format) # Determine SFNT version sfnt_version = @options[:sfnt_version] || sfnt_version_for_format( format, ) # Write using FontWriter FontWriter.write_to_file(tables, output_path, sfnt_version: sfnt_version) end |
#write_woff(tables, output_path, source_format) ⇒ Integer
Write WOFF format
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/fontisan/variation/instance_writer.rb', line 308 def write_woff(tables, output_path, source_format) # Create temporary font for WOFF writer temp_font = create_temp_font(tables, source_format) # Add cff? method for WoffWriter flavor detection temp_font.define_singleton_method(:cff?) do tables.key?("CFF ") || tables.key?("CFF2") end # Use WoffWriter to create WOFF writer = Converters::WoffWriter.new woff_data = writer.convert(temp_font) # Write to file File.binwrite(output_path, woff_data) rescue StandardError => e raise Fontisan::Error, "Failed to write WOFF output: #{e.}" end |
#write_woff2(tables, output_path, source_format) ⇒ Integer
Write WOFF2 format
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/fontisan/variation/instance_writer.rb', line 334 def write_woff2(tables, output_path, source_format) require "tmpdir" sfnt_version = sfnt_version_for_format(source_format) Dir.mktmpdir("fontisan-woff2-") do |dir| temp_ttf = File.join(dir, "instance.ttf") FontWriter.write_to_file(tables, temp_ttf, sfnt_version: sfnt_version) font = FontLoader.load(temp_ttf) woff2_data = Converters::Woff2Encoder.new.convert(font) File.binwrite(output_path, woff2_data) end rescue StandardError => e raise Fontisan::Error, "Failed to write WOFF2 output: #{e.}" end |