Class: Fontisan::Tables::Name
- Inherits:
-
Binary::BaseRecord
- Object
- BinData::Record
- Binary::BaseRecord
- Fontisan::Tables::Name
- Extended by:
- Registered
- 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.
Attributes inherited from Binary::BaseRecord
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 included from Registered
Methods inherited from Binary::BaseRecord
Instance Attribute Details
#decoded_names_cache ⇒ Object
Cache for decoded names
112 113 114 |
# File 'lib/fontisan/tables/name.rb', line 112 def decoded_names_cache @decoded_names_cache end |
Instance Method Details
#after_read_hook ⇒ Object
Hook that gets called after all fields are read
115 116 117 118 |
# File 'lib/fontisan/tables/name.rb', line 115 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)
129 130 131 |
# File 'lib/fontisan/tables/name.rb', line 129 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.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/fontisan/tables/name.rb', line 140 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
121 122 123 124 |
# File 'lib/fontisan/tables/name.rb', line 121 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
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/fontisan/tables/name.rb', line 169 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
254 255 256 257 |
# File 'lib/fontisan/tables/name.rb', line 254 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
241 242 243 244 245 246 247 248 249 |
# File 'lib/fontisan/tables/name.rb', line 241 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
262 263 264 265 |
# File 'lib/fontisan/tables/name.rb', line 262 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
272 273 274 275 276 277 |
# File 'lib/fontisan/tables/name.rb', line 272 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
197 198 199 200 201 |
# File 'lib/fontisan/tables/name.rb', line 197 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
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/fontisan/tables/name.rb', line 218 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)
206 207 208 |
# File 'lib/fontisan/tables/name.rb', line 206 def valid_version? [0, 1].include?(format) end |