Class: Fontisan::SfntTable Abstract
- Inherits:
-
Object
- Object
- Fontisan::SfntTable
- Defined in:
- lib/fontisan/sfnt_table.rb
Overview
Subclasses should override parser_class and validate_parsed_table?
Base class for SFNT font tables
Represents a single table in an SFNT font file, encapsulating:
- Table metadata (tag, checksum, offset, length)
- Lazy loading of table data
- Parsing of table data into structured objects
- Table-specific validation
This class provides an OOP representation of font tables, replacing the previous separation of TableDirectory (metadata), @table_data (raw bytes), and @parsed_tables (parsed objects) with a single cohesive domain object.
Direct Known Subclasses
Tables::CmapTable, Tables::GlyfTable, Tables::HeadTable, Tables::HheaTable, Tables::HmtxTable, Tables::LocaTable, Tables::MaxpTable, Tables::NameTable, Tables::Os2Table, Tables::PostTable
Instance Attribute Summary collapse
-
#data ⇒ String?
readonly
Raw table data (loaded lazily).
-
#entry ⇒ TableDirectory
readonly
Table metadata entry (from TableDirectory).
-
#font ⇒ SfntFont
readonly
Parent font containing this table.
-
#parsed ⇒ Object?
readonly
Parsed table object (cached).
Instance Method Summary collapse
-
#available? ⇒ Boolean
Check if table is available in current loading mode.
-
#calculate_checksum ⇒ Integer
Calculate table checksum.
-
#checksum ⇒ Integer
Table checksum.
-
#data_loaded? ⇒ Boolean
Check if table data is loaded.
-
#human_name ⇒ String
Get human-readable table name.
-
#initialize(font, entry) ⇒ SfntTable
constructor
Initialize a new SfntTable.
-
#inspect ⇒ String
String representation.
-
#length ⇒ Integer
Table length in bytes.
-
#load_data! ⇒ self
Load raw table data from font file.
-
#offset ⇒ Integer
Table offset in font file.
-
#parse ⇒ Object?
Parse table data into structured object.
-
#parsed? ⇒ Boolean
Check if table has been parsed.
-
#required? ⇒ Boolean
Check if table is required for the font.
-
#tag ⇒ String
Table tag (4-character string).
-
#to_s ⇒ String
String representation for display.
-
#validate! ⇒ Boolean
Validate the table.
Constructor Details
#initialize(font, entry) ⇒ SfntTable
Initialize a new SfntTable
88 89 90 91 92 93 |
# File 'lib/fontisan/sfnt_table.rb', line 88 def initialize(font, entry) @font = font @entry = entry @data = nil @parsed = nil end |
Instance Attribute Details
#data ⇒ String? (readonly)
Raw table data (loaded lazily)
49 50 51 |
# File 'lib/fontisan/sfnt_table.rb', line 49 def data @data end |
#entry ⇒ TableDirectory (readonly)
Table metadata entry (from TableDirectory)
39 40 41 |
# File 'lib/fontisan/sfnt_table.rb', line 39 def entry @entry end |
#font ⇒ SfntFont (readonly)
Parent font containing this table
44 45 46 |
# File 'lib/fontisan/sfnt_table.rb', line 44 def font @font end |
#parsed ⇒ Object? (readonly)
Parsed table object (cached)
54 55 56 |
# File 'lib/fontisan/sfnt_table.rb', line 54 def parsed @parsed end |
Instance Method Details
#available? ⇒ Boolean
Check if table is available in current loading mode
204 205 206 |
# File 'lib/fontisan/sfnt_table.rb', line 204 def available? @font.table_available?(tag) end |
#calculate_checksum ⇒ Integer
Calculate table checksum
195 196 197 198 199 |
# File 'lib/fontisan/sfnt_table.rb', line 195 def calculate_checksum load_data! unless data_loaded? Utilities::ChecksumCalculator.calculate_table_checksum(@data) end |
#checksum ⇒ Integer
Table checksum
66 67 68 |
# File 'lib/fontisan/sfnt_table.rb', line 66 def checksum @entry.checksum end |
#data_loaded? ⇒ Boolean
Check if table data is loaded
125 126 127 |
# File 'lib/fontisan/sfnt_table.rb', line 125 def data_loaded? !@data.nil? end |
#human_name ⇒ String
Get human-readable table name
218 219 220 |
# File 'lib/fontisan/sfnt_table.rb', line 218 def human_name Constants::TABLE_NAMES[tag] || tag end |
#inspect ⇒ String
String representation
225 226 227 |
# File 'lib/fontisan/sfnt_table.rb', line 225 def inspect "#<#{self.class.name} tag=#{tag.inspect} offset=0x#{offset.to_s(16).upcase} length=#{length}>" end |
#length ⇒ Integer
Table length in bytes
80 81 82 |
# File 'lib/fontisan/sfnt_table.rb', line 80 def length @entry.table_length end |
#load_data! ⇒ self
Load raw table data from font file
Reads the table data from the font's IO source or from cached table data. This method supports lazy loading.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/fontisan/sfnt_table.rb', line 102 def load_data! # Check if already loaded return self if @data # Try to get from font's table_data cache if @font.table_data && @font.table_data[tag] @data = @font.table_data[tag] return self end # Load from IO source if available if @font.io_source @font.io_source.seek(offset) @data = @font.io_source.read(length) return self end raise "Cannot load table '#{tag}': no IO source or cached data" end |
#offset ⇒ Integer
Table offset in font file
73 74 75 |
# File 'lib/fontisan/sfnt_table.rb', line 73 def offset @entry.offset end |
#parse ⇒ Object?
Parse table data into structured object
Loads data if needed, then parses using the table-specific parser class. Results are cached for subsequent calls.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/fontisan/sfnt_table.rb', line 143 def parse return @parsed if parsed? # Load data if not already loaded load_data! unless data_loaded? # Get parser class for this table type parser = parser_class return nil unless parser # Parse and cache @parsed = parser.read(@data) @parsed end |
#parsed? ⇒ Boolean
Check if table has been parsed
132 133 134 |
# File 'lib/fontisan/sfnt_table.rb', line 132 def parsed? !@parsed.nil? end |
#required? ⇒ Boolean
Check if table is required for the font
211 212 213 |
# File 'lib/fontisan/sfnt_table.rb', line 211 def required? Constants::REQUIRED_TABLES.include?(tag) end |
#tag ⇒ String
Table tag (4-character string)
59 60 61 |
# File 'lib/fontisan/sfnt_table.rb', line 59 def tag @entry.tag end |
#to_s ⇒ String
String representation for display
232 233 234 |
# File 'lib/fontisan/sfnt_table.rb', line 232 def to_s "#{tag}: #{human_name} (#{length} bytes @ 0x#{offset.to_s(16).upcase})" end |
#validate! ⇒ Boolean
Validate the table
Performs table-specific validation. Subclasses should override
validate_parsed_table? to provide custom validation logic.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/fontisan/sfnt_table.rb', line 165 def validate! # Ensure data is loaded load_data! unless data_loaded? # Basic validation: data size matches expected size if @data.bytesize != length raise InvalidFontError, "Table '#{tag}' data size mismatch: expected #{length} bytes, got #{@data.bytesize}" end # Validate checksum if not head table (head table checksum is special) if tag != Constants::HEAD_TAG expected_checksum = calculate_checksum if checksum != expected_checksum # Checksum mismatch might be OK for some tables, log a warning # But don't fail validation for it end end # Table-specific validation (if parsed) if parsed? validate_parsed_table? end true end |