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
109 110 111 |
# File 'lib/fontisan/tables/name.rb', line 109 def decoded_names_cache @decoded_names_cache end |
Instance Method Details
#after_read_hook ⇒ Object
Hook that gets called after all fields are read
112 113 114 115 |
# File 'lib/fontisan/tables/name.rb', line 112 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)
126 127 128 |
# File 'lib/fontisan/tables/name.rb', line 126 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.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/fontisan/tables/name.rb', line 137 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
118 119 120 121 |
# File 'lib/fontisan/tables/name.rb', line 118 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
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/fontisan/tables/name.rb', line 166 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
251 252 253 254 |
# File 'lib/fontisan/tables/name.rb', line 251 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
238 239 240 241 242 243 244 245 246 |
# File 'lib/fontisan/tables/name.rb', line 238 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
259 260 261 262 |
# File 'lib/fontisan/tables/name.rb', line 259 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
269 270 271 272 273 274 |
# File 'lib/fontisan/tables/name.rb', line 269 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
194 195 196 197 198 |
# File 'lib/fontisan/tables/name.rb', line 194 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
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/fontisan/tables/name.rb', line 215 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)
203 204 205 |
# File 'lib/fontisan/tables/name.rb', line 203 def valid_version? [0, 1].include?(format) end |