Class: Fontisan::Tables::Name

Inherits:
Binary::BaseRecord show all
Defined in:
lib/fontisan/tables/name.rb

Overview

BinData structure for the ‘name’ (Naming Table) table

The name table allows multilingual strings to be associated with the font. These strings can represent copyright notices, font names, family names, style names, and other information.

Reference: OpenType specification, name table

Examples:

Reading a name table

data = File.binread("font.ttf", length, name_offset)
name = Fontisan::Tables::Name.read(data)
puts name.english_name(Fontisan::Tables::Name::FAMILY)

Constant Summary collapse

0
FAMILY =
1
SUBFAMILY =
2
UNIQUE_ID =
3
FULL_NAME =
4
VERSION =
5
POSTSCRIPT_NAME =
6
TRADEMARK =
7
MANUFACTURER =
8
DESIGNER =
9
DESCRIPTION =
10
VENDOR_URL =
11
DESIGNER_URL =
12
LICENSE_DESCRIPTION =
13
LICENSE_URL =
14
PREFERRED_FAMILY =
16
PREFERRED_SUBFAMILY =
17
COMPATIBLE_FULL =
18
SAMPLE_TEXT =
19
POSTSCRIPT_CID =
20
WWS_FAMILY =
21
WWS_SUBFAMILY =
22
PLATFORM_UNICODE =

Platform IDs

0
PLATFORM_MACINTOSH =
1
PLATFORM_WINDOWS =
3
WINDOWS_LANGUAGE_EN_US =

Windows language ID for US English

0x0409
MAC_LANGUAGE_ENGLISH =

Mac language ID for English

0

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Binary::BaseRecord

#raw_data, read

Instance Attribute Details

#decoded_names_cacheObject

Cache for decoded names



111
112
113
# File 'lib/fontisan/tables/name.rb', line 111

def decoded_names_cache
  @decoded_names_cache
end

Instance Method Details

#after_read_hookObject

Hook that gets called after all fields are read



114
115
116
117
# File 'lib/fontisan/tables/name.rb', line 114

def after_read_hook
  # Don't decode anything yet - wait for request
  @decoded_names_cache = {}
end

#countInteger

Get the count of name records (for backward compatibility)

Returns:

  • (Integer)

    Number of name records



128
129
130
# File 'lib/fontisan/tables/name.rb', line 128

def count
  record_count
end

#decode_all_stringsvoid

This method returns an undefined value.

Decode all strings from the string storage area

This method can be called explicitly to decode all name records upfront. Useful for testing or when you know you’ll need all strings. By default, strings are decoded lazily on demand.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/fontisan/tables/name.rb', line 139

def decode_all_strings
  # Get the raw string storage as a plain Ruby binary string
  storage_bytes = string_storage.to_s.b

  return if storage_bytes.empty?

  name_records.each do |record|
    # Extract string data from storage using offset and length
    offset = record.string_offset
    length = record.string_length

    # Validate bounds
    next if offset.nil? || length.nil?
    next if offset + length > storage_bytes.bytesize
    next if length.zero?

    # Slice the bytes from storage
    string_data = storage_bytes.byteslice(offset, length)
    record.decode_string(string_data) if string_data && !string_data.empty?
  end
end

#do_read(io) ⇒ Object

Make sure we call our hook after BinData finishes reading



120
121
122
123
# File 'lib/fontisan/tables/name.rb', line 120

def do_read(io)
  super
  after_read_hook
end

#english_name(name_id) ⇒ String?

Find an English name for the given name ID

Priority: Platform 3 (Windows) with language 0x0409 (US English) Fallback: Platform 1 (Mac) with language 0

Parameters:

  • name_id (Integer)

    The name ID to search for

Returns:

  • (String, nil)

    The decoded string or nil if not found



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/fontisan/tables/name.rb', line 168

def english_name(name_id)
  # Check cache first
  return @decoded_names_cache[name_id] if @decoded_names_cache.key?(name_id)

  # Find record (don't decode yet)
  record = find_name_record(
    name_id,
    platform: PLATFORM_WINDOWS,
    language: WINDOWS_LANGUAGE_EN_US
  )

  record ||= find_name_record(
    name_id,
    platform: PLATFORM_MACINTOSH,
    language: MAC_LANGUAGE_ENGLISH
  )

  return nil unless record

  # Decode only this one record
  decoded = decode_name_record(record)
  @decoded_names_cache[name_id] = decoded
  decoded
end

#valid?Boolean

Validate the table

Returns:

  • (Boolean)

    True if the table is valid



196
197
198
199
200
# File 'lib/fontisan/tables/name.rb', line 196

def valid?
  !format.nil?
rescue StandardError
  false
end