Class: Fontisan::Tables::Name
- Inherits:
-
Binary::BaseRecord
- Object
- BinData::Record
- Binary::BaseRecord
- Fontisan::Tables::Name
- 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
Constant Summary collapse
- COPYRIGHT =
Name ID constants for common name records
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
-
#decoded_names_cache ⇒ Object
Cache for decoded names.
Instance Method Summary collapse
-
#after_read_hook ⇒ Object
Hook that gets called after all fields are read.
-
#count ⇒ Integer
Get the count of name records (for backward compatibility).
-
#decode_all_strings ⇒ void
Decode all strings from the string storage area.
-
#do_read(io) ⇒ Object
Make sure we call our hook after BinData finishes reading.
-
#english_name(name_id) ⇒ String?
Find an English name for the given name ID.
-
#family_name_present? ⇒ Boolean
Validation helper: Check if family name is present and non-empty.
-
#has_valid_platform_combos?(*combos) ⇒ Boolean
Validation helper: Check if required platform combinations exist.
-
#postscript_name_present? ⇒ Boolean
Validation helper: Check if PostScript name is present and non-empty.
-
#postscript_name_valid? ⇒ Boolean
Validation helper: Check if PostScript name is valid.
-
#valid? ⇒ Boolean
Validate the table.
-
#valid_encoding_heuristics? ⇒ Boolean
Validation helper: Check if encoding combinations are valid.
-
#valid_version? ⇒ Boolean
Validation helper: Check if version is valid (0 or 1).
Methods inherited from Binary::BaseRecord
Instance Attribute Details
#decoded_names_cache ⇒ Object
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_hook ⇒ Object
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 |
#count ⇒ Integer
Get the count of name records (for backward compatibility)
128 129 130 |
# File 'lib/fontisan/tables/name.rb', line 128 def count record_count end |
#decode_all_strings ⇒ void
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
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 |
#family_name_present? ⇒ Boolean
Validation helper: Check if family name is present and non-empty
253 254 255 256 |
# File 'lib/fontisan/tables/name.rb', line 253 def family_name_present? name = english_name(FAMILY) !name.nil? && !name.empty? end |
#has_valid_platform_combos?(*combos) ⇒ Boolean
Validation helper: Check if required platform combinations exist
240 241 242 243 244 245 246 247 248 |
# File 'lib/fontisan/tables/name.rb', line 240 def has_valid_platform_combos?(*combos) combos.all? do |platform_id, encoding_id, language_id| name_records.any? do |rec| rec.platform_id == platform_id && rec.encoding_id == encoding_id && rec.language_id == language_id end end end |
#postscript_name_present? ⇒ Boolean
Validation helper: Check if PostScript name is present and non-empty
261 262 263 264 |
# File 'lib/fontisan/tables/name.rb', line 261 def postscript_name_present? name = english_name(POSTSCRIPT_NAME) !name.nil? && !name.empty? end |
#postscript_name_valid? ⇒ Boolean
Validation helper: Check if PostScript name is valid
PostScript names must contain only ASCII alphanumerics and hyphens
271 272 273 274 275 276 |
# File 'lib/fontisan/tables/name.rb', line 271 def postscript_name_valid? name = english_name(POSTSCRIPT_NAME) return false if name.nil? || name.empty? name.match?(/^[A-Za-z0-9-]+$/) end |
#valid? ⇒ Boolean
Validate the table
196 197 198 199 200 |
# File 'lib/fontisan/tables/name.rb', line 196 def valid? !format.nil? rescue StandardError false end |
#valid_encoding_heuristics? ⇒ Boolean
Validation helper: Check if encoding combinations are valid
According to OpenType spec, certain platform/encoding combinations are valid:
-
Platform 0 (Unicode): encoding 0-6
-
Platform 1 (Mac): encoding 0-32
-
Platform 3 (Windows): encoding 0-10
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/fontisan/tables/name.rb', line 217 def valid_encoding_heuristics? name_records.all? do |rec| case rec.platform_id when PLATFORM_UNICODE rec.encoding_id.between?(0, 6) when PLATFORM_MACINTOSH rec.encoding_id.between?(0, 32) when PLATFORM_WINDOWS rec.encoding_id.between?(0, 10) else # Unknown platform - consider invalid false end end end |
#valid_version? ⇒ Boolean
Validation helper: Check if version is valid (0 or 1)
205 206 207 |
# File 'lib/fontisan/tables/name.rb', line 205 def valid_version? [0, 1].include?(format) end |