Module: Fontisan::Ufo::Convert::FromBinData

Defined in:
lib/fontisan/ufo/convert/from_bin_data.rb

Overview

Converts a loaded TTF/OTF font (from Fontisan::FontLoader.load) into a typed Fontisan::Ufo::Font. This is the reverse of Compile::TtfCompiler / Compile::OtfCompiler.

Reads each BinData table, extracts per-glyph data, and builds Ufo::Glyph objects in the default layer.

Composite glyphs are preserved as UFO Components (not decomposed). This keeps the round-trip faithful to the source.

Class Method Summary collapse

Class Method Details

.convert(font) ⇒ Fontisan::Ufo::Font

Returns typed UFO model.

Parameters:

Returns:



18
19
20
21
22
23
24
25
# File 'lib/fontisan/ufo/convert/from_bin_data.rb', line 18

def self.convert(font)
  ufo = Ufo::Font.new
  ufo.ufo_version = 3

  extract_info(font, ufo)
  extract_glyphs(font, ufo)
  ufo
end

.convert_cff_path_to_ufo(path, glyph) ⇒ Object

Convert a CFF CharString path (array of command hashes) to UFO contours. Each :move_to starts a new contour; :line_to and :curve_to append points to the current contour. Cubic bezier curves produce 2 offcurve + 1 curve points per segment (GLIF convention).



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/fontisan/ufo/convert/from_bin_data.rb', line 253

def self.convert_cff_path_to_ufo(path, glyph)
  return if path.empty?

  current_contour = nil

  path.each do |cmd|
    case cmd[:type]
    when :move_to
      glyph.add_contour(current_contour) if current_contour
      current_contour = Ufo::Contour.new
      current_contour.points << Ufo::Point.new(
        x: cmd[:x].to_i, y: cmd[:y].to_i, type: "move",
      )
    when :line_to
      next unless current_contour

      current_contour.points << Ufo::Point.new(
        x: cmd[:x].to_i, y: cmd[:y].to_i, type: "line",
      )
    when :curve_to
      next unless current_contour

      current_contour.points << Ufo::Point.new(
        x: cmd[:x1].to_i, y: cmd[:y1].to_i, type: "offcurve",
      )
      current_contour.points << Ufo::Point.new(
        x: cmd[:x2].to_i, y: cmd[:y2].to_i, type: "offcurve",
      )
      current_contour.points << Ufo::Point.new(
        x: cmd[:x].to_i, y: cmd[:y].to_i, type: "curve",
      )
    end
  end

  glyph.add_contour(current_contour) if current_contour
end

.extract_cff_glyphs_stub(font, ufo, cmap, widths, num_glyphs) ⇒ Object

Fallback: widths only, no contours (used when CFF table can't be parsed — e.g., corrupted or unsupported variant).



238
239
240
241
242
243
244
245
246
# File 'lib/fontisan/ufo/convert/from_bin_data.rb', line 238

def self.extract_cff_glyphs_stub(font, ufo, cmap, widths, num_glyphs)
  num_glyphs.times do |gid|
    glyph_name = glyph_name_for(font, gid) || "gid#{gid}"
    ufo_glyph = Ufo::Glyph.new(name: glyph_name)
    ufo_glyph.width = widths.fetch(gid, 0).to_f
    cmap.fetch(gid, []).each { |cp| ufo_glyph.add_unicode(cp) }
    ufo.layers.default_layer.add(ufo_glyph)
  end
end