Class: Fontisan::Tables::Head
- Inherits:
-
Binary::BaseRecord
- Object
- BinData::Record
- Binary::BaseRecord
- Fontisan::Tables::Head
- Extended by:
- Registered
- Defined in:
- lib/fontisan/tables/head.rb
Overview
BinData structure for the 'head' (Font Header) table
The head table contains global information about the font, including metadata about the font file, bounding box, and indexing information.
Reference: OpenType specification, head table
Constant Summary collapse
- MAGIC_NUMBER =
Magic number that must be present in the head table
0x5F0F3CF5- FLAG_LOSSLESS_MODIFYING =
Bit flags for the
flagsfield (uint16), per OpenType spec. Only bits we currently reference are named here; see the OpenTypeheadtable specification for the full list.Bit 11 indicates the font data has been losslessly modified (e.g. by subsetting or WOFF2 encoding). Per WOFF2 spec section 5, encoders MUST set this bit. Chrome's OpenType Sanitizer (OTS) rejects WOFF2 files where it is not set.
0x0800- MAC_EPOCH_OFFSET =
Difference between 1904-01-01 00:00:00 UTC (Mac epoch, used by LONGDATETIME fields) and 1970-01-01 00:00:00 UTC (Unix epoch). Single source of truth for converting between the two — head's created/modified fields are LONGDATETIME.
2_082_844_800
Instance Attribute Summary
Attributes inherited from Binary::BaseRecord
Class Method Summary collapse
-
.longdatetime_to_time(seconds) ⇒ Time
Convert LONGDATETIME to Ruby Time.
-
.now_longdatetime ⇒ Integer
Current wall clock time as a LONGDATETIME integer (seconds since Mac epoch).
-
.to_longdatetime(time = Time.now) ⇒ Integer
Convert a Unix-epoch
Time(or Integer seconds) to a LONGDATETIME integer (Mac-epoch seconds).
Instance Method Summary collapse
-
#created ⇒ Time
Convert created timestamp to Time object.
-
#font_revision ⇒ Float
Convert font revision from fixed-point to float.
-
#modified ⇒ Time
Convert modified timestamp to Time object.
-
#valid? ⇒ Boolean
Validate that the magic number is correct.
-
#valid_bounding_box? ⇒ Boolean
Validation helper: Check if bounding box is valid.
-
#valid_glyph_data_format? ⇒ Boolean
Validation helper: Check if glyph_data_format is valid.
-
#valid_index_to_loc_format? ⇒ Boolean
Validation helper: Check if index_to_loc_format is valid.
-
#valid_magic? ⇒ Boolean
Validation helper: Check if magic number is valid.
-
#valid_units_per_em? ⇒ Boolean
Validation helper: Check if units per em is valid.
-
#valid_version? ⇒ Boolean
Validation helper: Check if version is valid.
-
#validate_magic_number! ⇒ Object
(also: #validate!)
Validate magic number and raise error if invalid.
-
#version ⇒ Float
Convert version from fixed-point to float.
Methods included from Registered
Methods inherited from Binary::BaseRecord
Class Method Details
.longdatetime_to_time(seconds) ⇒ Time
Convert LONGDATETIME to Ruby Time
203 204 205 |
# File 'lib/fontisan/tables/head.rb', line 203 def self.longdatetime_to_time(seconds) Time.at(seconds - MAC_EPOCH_OFFSET) end |
.now_longdatetime ⇒ Integer
Current wall clock time as a LONGDATETIME integer (seconds since
Mac epoch). Used wherever a created/modified timestamp needs
to be set to a meaningful "now" value (WOFF2 encoder, Type 1
converter, UFO compile fallback).
168 169 170 |
# File 'lib/fontisan/tables/head.rb', line 168 def self.now_longdatetime to_longdatetime(Time.now) end |
.to_longdatetime(time = Time.now) ⇒ Integer
Convert a Unix-epoch Time (or Integer seconds) to a LONGDATETIME
integer (Mac-epoch seconds). Symmetric with #longdatetime_to_time
— pair them whenever you convert across the epoch boundary.
178 179 180 |
# File 'lib/fontisan/tables/head.rb', line 178 def self.to_longdatetime(time = Time.now) time.to_i + MAC_EPOCH_OFFSET end |
Instance Method Details
#created ⇒ Time
Convert created timestamp to Time object
84 85 86 |
# File 'lib/fontisan/tables/head.rb', line 84 def created self.class.longdatetime_to_time(created_raw) end |
#font_revision ⇒ Float
Convert font revision from fixed-point to float
77 78 79 |
# File 'lib/fontisan/tables/head.rb', line 77 def font_revision fixed_to_float(font_revision_raw) end |
#modified ⇒ Time
Convert modified timestamp to Time object
91 92 93 |
# File 'lib/fontisan/tables/head.rb', line 91 def modified self.class.longdatetime_to_time(modified_raw) end |
#valid? ⇒ Boolean
Validate that the magic number is correct
98 99 100 |
# File 'lib/fontisan/tables/head.rb', line 98 def valid? magic_number == MAGIC_NUMBER end |
#valid_bounding_box? ⇒ Boolean
Validation helper: Check if bounding box is valid
The bounding box should have xMin < xMax and yMin < yMax
140 141 142 |
# File 'lib/fontisan/tables/head.rb', line 140 def valid_bounding_box? x_min < x_max && y_min < y_max end |
#valid_glyph_data_format? ⇒ Boolean
Validation helper: Check if glyph_data_format is valid
Must be 0 for current format
158 159 160 |
# File 'lib/fontisan/tables/head.rb', line 158 def valid_glyph_data_format? glyph_data_format.zero? end |
#valid_index_to_loc_format? ⇒ Boolean
Validation helper: Check if index_to_loc_format is valid
Must be 0 (short) or 1 (long)
149 150 151 |
# File 'lib/fontisan/tables/head.rb', line 149 def valid_index_to_loc_format? [0, 1].include?(index_to_loc_format) end |
#valid_magic? ⇒ Boolean
Validation helper: Check if magic number is valid
105 106 107 |
# File 'lib/fontisan/tables/head.rb', line 105 def valid_magic? magic_number == MAGIC_NUMBER end |
#valid_units_per_em? ⇒ Boolean
Validation helper: Check if units per em is valid
Units per em should be a power of 2 between 16 and 16384
123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/fontisan/tables/head.rb', line 123 def valid_units_per_em? return false if units_per_em.nil? || units_per_em.zero? # Must be between 16 and 16384 return false unless units_per_em.between?(16, 16384) # Should be a power of 2 (recommended but not required) # Common values: 1000, 1024, 2048 # We'll allow any value in range for flexibility true end |
#valid_version? ⇒ Boolean
Validation helper: Check if version is valid
OpenType spec requires version to be 1.0
114 115 116 |
# File 'lib/fontisan/tables/head.rb', line 114 def valid_version? version_raw == 0x00010000 # Version 1.0 end |
#validate_magic_number! ⇒ Object Also known as: validate!
Validate magic number and raise error if invalid
185 186 187 188 189 190 191 192 193 194 |
# File 'lib/fontisan/tables/head.rb', line 185 def validate_magic_number! return if valid? = "Invalid magic number in head table: " \ "expected 0x#{MAGIC_NUMBER.to_s(16).upcase}, " \ "got 0x#{magic_number.to_s(16).upcase}" error = Fontisan::CorruptedTableError.new() error.set_backtrace(caller) Kernel.raise(error) end |
#version ⇒ Float
Convert version from fixed-point to float
70 71 72 |
# File 'lib/fontisan/tables/head.rb', line 70 def version fixed_to_float(version_raw) end |