Class: Fontisan::Export::Transformers::FontToTtx

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/export/transformers/font_to_ttx.rb

Overview

FontToTtx orchestrates font to TTX transformation

Main transformer that coordinates conversion of a complete font to TTX format using individual table transformers. Follows model-to-model transformation principles with clean separation of concerns.

Constant Summary collapse

TABLE_TRANSFORMERS =

Per-tag TTX model transformer dispatch.

{
  "head" => [HeadTransformer, :head_table=],
  "hhea" => [HheaTransformer, :hhea_table=],
  "maxp" => [MaxpTransformer, :maxp_table=],
  "name" => [NameTransformer, :name_table=],
  "OS/2" => [Os2Transformer, :os2_table=],
  "post" => [PostTransformer, :post_table=],
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(font) ⇒ FontToTtx

Initialize transformer

Parameters:



16
17
18
# File 'lib/fontisan/export/transformers/font_to_ttx.rb', line 16

def initialize(font)
  @font = font
end

Instance Method Details

#format_sfnt_version(version) ⇒ String

Format SFNT version

Parameters:

  • version (Integer)

    SFNT version

Returns:

  • (String)

    Formatted version as escaped bytes



156
157
158
159
# File 'lib/fontisan/export/transformers/font_to_ttx.rb', line 156

def format_sfnt_version(version)
  bytes = [version].pack("N").bytes
  "\\x#{bytes.map { |b| b.to_s(16).rjust(2, '0') }.join('\\x')}"
end

#get_glyph_name(glyph_id) ⇒ String

Get glyph name by ID

Parameters:

  • glyph_id (Integer)

    Glyph ID

Returns:

  • (String)

    Glyph name



141
142
143
144
145
146
147
148
149
150
# File 'lib/fontisan/export/transformers/font_to_ttx.rb', line 141

def get_glyph_name(glyph_id)
  post = @font.table("post")
  if post.is_a?(Tables::Post) && post.glyph_names
    post.glyph_names[glyph_id] || ".notdef"
  elsif glyph_id.zero?
    ".notdef"
  else
    "glyph#{glyph_id.to_s.rjust(5, '0')}"
  end
end

#glyph_countInteger

Get number of glyphs

Returns:

  • (Integer)

    Number of glyphs



132
133
134
135
# File 'lib/fontisan/export/transformers/font_to_ttx.rb', line 132

def glyph_count
  maxp = @font.table("maxp")
  maxp ? maxp.num_glyphs.to_i : 0
end

#select_tables(table_list) ⇒ Array<String>

Select tables to transform

Parameters:

  • table_list (Symbol, Array<String>)

    :all or list of tags

Returns:

  • (Array<String>)

    Table tags to transform



119
120
121
122
123
124
125
126
127
# File 'lib/fontisan/export/transformers/font_to_ttx.rb', line 119

def select_tables(table_list)
  if table_list == :all
    @font.table_names
  else
    available = @font.table_names
    requested = Array(table_list).map(&:to_s)
    requested.select { |tag| available.include?(tag) }
  end
end

#transform(options = {}) ⇒ Models::Ttx::TtFont

Transform font to TTX model

Parameters:

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

    Transformation options

Options Hash (options):

  • :tables (Array<String>)

    Specific tables to include

Returns:



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/fontisan/export/transformers/font_to_ttx.rb', line 25

def transform(options = {})
  table_list = options[:tables] || :all

  Models::Ttx::TtFont.new.tap do |ttx|
    ttx.sfnt_version = format_sfnt_version(@font.header.sfnt_version.to_i)
    ttx.ttlib_version = "4.0"
    ttx.glyph_order = build_glyph_order

    # Transform specific tables
    tables_to_transform = select_tables(table_list)
    tables_to_transform.each do |tag|
      transform_table(ttx, tag)
    end
  end
end

#transform_binary_table(tag, table) ⇒ Models::Ttx::Tables::BinaryTable?

Transform table to binary representation

Parameters:

  • tag (String)

    Table tag

  • table (Object)

    Table object

Returns:



105
106
107
108
109
110
111
112
113
# File 'lib/fontisan/export/transformers/font_to_ttx.rb', line 105

def transform_binary_table(tag, table)
  binary_data = table ? table.to_binary_s : ""
  return nil if binary_data.empty?

  Models::Ttx::Tables::BinaryTable.new.tap do |bin_table|
    bin_table.tag = tag
    bin_table.hexdata = binary_data
  end
end

#transform_table(ttx, tag) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/fontisan/export/transformers/font_to_ttx.rb', line 78

def transform_table(ttx, tag)
  table = @font.table(tag)
  return unless table

  entry = TABLE_TRANSFORMERS[tag]
  if entry
    transformer, setter = entry
    ttx.public_send(setter, transformer.transform(table))
  else
    # Fallback to binary table
    binary_table = transform_binary_table(tag, table)
    ttx.binary_tables ||= []
    ttx.binary_tables << binary_table if binary_table
  end
rescue StandardError => e
  # On error, fall back to binary representation
  warn "Error transforming #{tag}: #{e.message}"
  binary_table = transform_binary_table(tag, table)
  ttx.binary_tables ||= []
  ttx.binary_tables << binary_table if binary_table
end