Class: Fontisan::Tables::Head

Inherits:
Binary::BaseRecord show all
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

Examples:

Reading a head table

data = File.binread("font.ttf", 54, head_offset)
head = Fontisan::Tables::Head.read(data)
puts head.units_per_em  # => 2048
puts head.version_number  # => 1.0

Constant Summary collapse

MAGIC_NUMBER =

Magic number that must be present in the head table

0x5F0F3CF5
FLAG_LOSSLESS_MODIFYING =

Bit flags for the flags field (uint16), per OpenType spec. Only bits we currently reference are named here; see the OpenType head table 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

Instance Method Summary collapse

Methods inherited from Binary::BaseRecord

#raw_data, read

Instance Method Details

#createdTime

Convert created timestamp to Time object

Returns:

  • (Time)

    Creation time



75
76
77
# File 'lib/fontisan/tables/head.rb', line 75

def created
  longdatetime_to_time(created_raw)
end

#font_revisionFloat

Convert font revision from fixed-point to float

Returns:

  • (Float)

    Font revision number



68
69
70
# File 'lib/fontisan/tables/head.rb', line 68

def font_revision
  fixed_to_float(font_revision_raw)
end

#modifiedTime

Convert modified timestamp to Time object

Returns:

  • (Time)

    Modification time



82
83
84
# File 'lib/fontisan/tables/head.rb', line 82

def modified
  longdatetime_to_time(modified_raw)
end

#valid?Boolean

Validate that the magic number is correct

Returns:

  • (Boolean)

    True if magic number is valid



89
90
91
# File 'lib/fontisan/tables/head.rb', line 89

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

Returns:

  • (Boolean)

    True if bounding box coordinates are valid



131
132
133
# File 'lib/fontisan/tables/head.rb', line 131

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

Returns:

  • (Boolean)

    True if format is 0



149
150
151
# File 'lib/fontisan/tables/head.rb', line 149

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)

Returns:

  • (Boolean)

    True if format is 0 or 1



140
141
142
# File 'lib/fontisan/tables/head.rb', line 140

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

Returns:

  • (Boolean)

    True if magic number equals 0x5F0F3CF5



96
97
98
# File 'lib/fontisan/tables/head.rb', line 96

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

Returns:

  • (Boolean)

    True if units_per_em is valid



114
115
116
117
118
119
120
121
122
123
124
# File 'lib/fontisan/tables/head.rb', line 114

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

Returns:

  • (Boolean)

    True if version is 1.0



105
106
107
# File 'lib/fontisan/tables/head.rb', line 105

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

Raises:



156
157
158
159
160
161
162
163
164
165
# File 'lib/fontisan/tables/head.rb', line 156

def validate_magic_number!
  return if valid?

  message = "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(message)
  error.set_backtrace(caller)
  Kernel.raise(error)
end

#versionFloat

Convert version from fixed-point to float

Returns:

  • (Float)

    Version number (e.g., 1.0)



61
62
63
# File 'lib/fontisan/tables/head.rb', line 61

def version
  fixed_to_float(version_raw)
end