Class: Fontisan::TrueTypeFont

Inherits:
SfntFont
  • Object
show all
Defined in:
lib/fontisan/true_type_font.rb,
lib/fontisan/true_type_font_extensions.rb

Overview

Extensions to TrueTypeFont for table-based construction

Constant Summary

Constants inherited from SfntFont

SfntFont::PADDING_BYTES, SfntFont::SFNT_TABLE_CLASS_MAP, SfntFont::TABLE_CLASS_MAP

Instance Attribute Summary

Attributes inherited from SfntFont

#io_source, #lazy_load_enabled, #loading_mode, #parsed_tables, #sfnt_tables, #table_data, #table_entry_cache

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from SfntFont

#all_sfnt_tables, #close, #family_name, finalize, #find_table_entry, from_collection, #full_name, #has_table?, #head_table, #initialize_storage, #post_script_name, #preferred_family_name, #preferred_subfamily_name, #read_metadata_tables_batched, #read_table_data, #setup_finalizer, #sfnt_table, #subfamily_name, #table, #table_available?, #table_names, #to_file, #units_per_em, #update_checksum_adjustment_in_file, #update_checksum_adjustment_in_io, #valid?

Class Method Details

.from_file(path, mode: LoadingModes::FULL, lazy: false) ⇒ TrueTypeFont

Read TrueType Font from a file

Parameters:

  • path (String)

    Path to the TTF file

  • mode (Symbol) (defaults to: LoadingModes::FULL)

    Loading mode (:metadata or :full, default: :full)

  • lazy (Boolean) (defaults to: false)

    If true, load tables on demand (default: false)

Returns:

Raises:

  • (ArgumentError)

    if path is nil or empty, or if mode is invalid

  • (Errno::ENOENT)

    if file does not exist

  • (RuntimeError)

    if file format is invalid



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/fontisan/true_type_font.rb', line 37

def self.from_file(path, mode: LoadingModes::FULL, lazy: false)
  if path.nil? || path.to_s.empty?
    raise ArgumentError,
          "path cannot be nil or empty"
  end
  raise Errno::ENOENT, "File not found: #{path}" unless File.exist?(path)

  # Validate mode
  LoadingModes.validate_mode!(mode)

  File.open(path, "rb") do |io|
    font = read(io)
    font.initialize_storage
    font.loading_mode = mode
    font.lazy_load_enabled = lazy

    if lazy
      # Reuse existing IO handle by duplicating it to prevent double file open
      # The dup ensures the handle stays open after this block closes
      font.io_source = io.dup
      font.setup_finalizer
    else
      # Read tables upfront
      font.read_table_data(io)
    end

    font
  end
rescue BinData::ValidityError, EOFError => e
  raise "Invalid TTF file: #{e.message}"
end

.from_tables(tables) ⇒ TrueTypeFont

Create font from hash of tables

This is used during font conversion when we have tables but not a file.

Parameters:

  • tables (Hash<String, String>)

    Map of table tag to binary data

Returns:



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/fontisan/true_type_font_extensions.rb', line 12

def self.from_tables(tables)
  # Create minimal header structure
  font = new
  font.initialize_storage
  font.loading_mode = LoadingModes::FULL

  # Store table data
  font.table_data = tables

  # Build header from tables
  num_tables = tables.size
  max_power = 0
  n = num_tables
  while n > 1
    n >>= 1
    max_power += 1
  end

  search_range = (1 << max_power) * 16
  entry_selector = max_power
  range_shift = (num_tables * 16) - search_range

  font.header.sfnt_version = 0x00010000 # TrueType
  font.header.num_tables = num_tables
  font.header.search_range = search_range
  font.header.entry_selector = entry_selector
  font.header.range_shift = range_shift

  # Build table directory
  font.tables.clear
  tables.each_key do |tag|
    entry = TableDirectory.new
    entry.tag = tag
    entry.checksum = 0 # Will be calculated on write
    entry.offset = 0 # Will be calculated on write
    entry.table_length = tables[tag].bytesize
    font.tables << entry
  end

  font
end

.from_ttc(io, offset, mode: LoadingModes::FULL) ⇒ TrueTypeFont

Read TrueType Font from TTC at specific offset

Parameters:

  • io (IO)

    Open file handle

  • offset (Integer)

    Byte offset to the font

  • mode (Symbol) (defaults to: LoadingModes::FULL)

    Loading mode (:metadata or :full, default: :full)

Returns:



75
76
77
78
79
80
81
82
83
84
# File 'lib/fontisan/true_type_font.rb', line 75

def self.from_ttc(io, offset, mode: LoadingModes::FULL)
  LoadingModes.validate_mode!(mode)

  io.seek(offset)
  font = read(io)
  font.initialize_storage
  font.loading_mode = mode
  font.read_table_data(io)
  font
end

Instance Method Details

#cff?Boolean

Check if font is CFF flavored

Returns:

  • (Boolean)

    false for TrueType fonts



96
97
98
# File 'lib/fontisan/true_type_font.rb', line 96

def cff?
  false
end

#truetype?Boolean

Check if font is TrueType flavored

Returns:

  • (Boolean)

    true for TrueType fonts



89
90
91
# File 'lib/fontisan/true_type_font.rb', line 89

def truetype?
  true
end