Class: Fontisan::Tables::Maxp

Inherits:
Binary::BaseRecord show all
Defined in:
lib/fontisan/tables/maxp.rb

Overview

BinData structure for the ‘maxp’ (Maximum Profile) table

The maxp table contains memory and complexity limits for the font. It provides the number of glyphs and various maximum values needed for font rendering and processing.

The table has two versions:

  • Version 0.5 (0x00005000): CFF fonts - only version and numGlyphs

  • Version 1.0 (0x00010000): TrueType fonts - includes additional fields

Version 1.0 fields provide information about:

  • Glyph outline complexity (points, contours)

  • Composite glyph structure

  • TrueType instruction limitations

Reference: OpenType specification, maxp table docs.microsoft.com/en-us/typography/opentype/spec/maxp

Examples:

Reading a maxp table

data = File.binread("font.ttf", size, maxp_offset)
maxp = Fontisan::Tables::Maxp.read(data)
puts maxp.num_glyphs       # => 512
puts maxp.version          # => 1.0 or 0.5
puts maxp.truetype?        # => true or false

Constant Summary collapse

VERSION_0_5 =

Version 0.5 constant (CFF fonts)

0x00005000
VERSION_1_0 =

Version 1.0 constant (TrueType fonts)

0x00010000
TABLE_SIZE_V0_5 =

Minimum table size for version 0.5 (4 + 2 = 6 bytes)

6
TABLE_SIZE_V1_0 =

Full table size for version 1.0 (4 + 2 + 13×2 = 32 bytes)

32

Instance Method Summary collapse

Methods inherited from Binary::BaseRecord

#raw_data, read

Instance Method Details

#cff?Boolean

Check if this is a CFF font (alias for version_0_5?)

Returns:

  • (Boolean)

    True if CFF font, false otherwise



138
139
140
# File 'lib/fontisan/tables/maxp.rb', line 138

def cff?
  version_0_5?
end

#expected_sizeInteger

Get the expected table size based on version

Returns:

  • (Integer)

    Expected size in bytes



247
248
249
# File 'lib/fontisan/tables/maxp.rb', line 247

def expected_size
  version_1_0? ? TABLE_SIZE_V1_0 : TABLE_SIZE_V0_5
end

#has_truetype_metrics?Boolean

Validation helper: Check if all TrueType metrics are present

For version 1.0, all max* fields should be present

Returns:

  • (Boolean)

    True if all required fields are present



192
193
194
195
196
197
198
# File 'lib/fontisan/tables/maxp.rb', line 192

def has_truetype_metrics?
  version_1_0? &&
    !max_points.nil? &&
    !max_contours.nil? &&
    !max_composite_points.nil? &&
    !max_composite_contours.nil?
end

#reasonable_metrics?Boolean

Validation helper: Check if metrics are reasonable

Checks that values don’t exceed reasonable limits

Returns:

  • (Boolean)

    True if metrics are within reasonable bounds



205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/fontisan/tables/maxp.rb', line 205

def reasonable_metrics?
  # num_glyphs should not exceed 65535
  return false if num_glyphs > 65535

  if version_1_0?
    # Check reasonable limits for TrueType metrics
    # These are generous limits to allow for complex fonts
    return false if max_points && max_points > 50000
    return false if max_contours && max_contours > 10000
    return false if max_stack_elements && max_stack_elements > 1000
  end

  true
end

#truetype?Boolean

Check if this is a TrueType font (alias for version_1_0?)

Returns:

  • (Boolean)

    True if TrueType font, false otherwise



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

def truetype?
  version_1_0?
end

#valid?Boolean

Check if the table is valid

Returns:

  • (Boolean)

    True if valid, false otherwise



145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/fontisan/tables/maxp.rb', line 145

def valid?
  # Version must be either 0.5 or 1.0
  return false unless version_0_5? || version_1_0?

  # Number of glyphs must be at least 1
  return false unless num_glyphs >= 1

  # For version 1.0, maxZones must be 1 or 2
  if version_1_0? && max_zones && !(max_zones >= 1 && max_zones <= 2)
    return false
  end

  true
end

#valid_max_zones?Boolean

Validation helper: Check if maxZones is valid (version 1.0 only)

For TrueType fonts, maxZones must be 1 or 2

Returns:

  • (Boolean)

    True if maxZones is valid or not applicable



181
182
183
184
185
# File 'lib/fontisan/tables/maxp.rb', line 181

def valid_max_zones?
  return true if version_0_5? # Not applicable for CFF

  max_zones&.between?(1, 2)
end

#valid_num_glyphs?Boolean

Validation helper: Check if number of glyphs is valid

Must be at least 1 (.notdef glyph must exist)

Returns:

  • (Boolean)

    True if num_glyphs >= 1



172
173
174
# File 'lib/fontisan/tables/maxp.rb', line 172

def valid_num_glyphs?
  num_glyphs && num_glyphs >= 1
end

#valid_version?Boolean

Validation helper: Check if version is valid (0.5 or 1.0)

Returns:

  • (Boolean)

    True if version is 0.5 or 1.0



163
164
165
# File 'lib/fontisan/tables/maxp.rb', line 163

def valid_version?
  version_0_5? || version_1_0?
end

#validate_structure!Object Also known as: validate!

Validate the table and raise error if invalid

Raises:



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/fontisan/tables/maxp.rb', line 223

def validate_structure!
  unless version_0_5? || version_1_0?
    raise Fontisan::CorruptedTableError,
          "Invalid maxp version: expected 0x00005000 (0.5) or " \
          "0x00010000 (1.0), got 0x#{version_raw.to_s(16).upcase}"
  end

  unless num_glyphs >= 1
    raise Fontisan::CorruptedTableError,
          "Invalid number of glyphs: must be >= 1, got #{num_glyphs}"
  end

  if version_1_0? && max_zones && (max_zones < 1 || max_zones > 2)
    raise Fontisan::CorruptedTableError,
          "Invalid maxZones: must be 1 or 2, got #{max_zones}"
  end
end

#versionFloat

Convert version from fixed-point to float

Version 0.5 (0x00005000) is a special case, not standard 16.16 fixed-point

Returns:

  • (Float)

    Version number (1.0 or 0.5)



103
104
105
106
107
108
109
110
111
112
# File 'lib/fontisan/tables/maxp.rb', line 103

def version
  case version_raw
  when VERSION_0_5
    0.5
  when VERSION_1_0
    1.0
  else
    fixed_to_float(version_raw)
  end
end

#version_0_5?Boolean

Check if this is version 0.5 (CFF)

Returns:

  • (Boolean)

    True if version 0.5, false otherwise



124
125
126
# File 'lib/fontisan/tables/maxp.rb', line 124

def version_0_5?
  version_raw == VERSION_0_5
end

#version_1_0?Boolean

Check if this is version 1.0 (TrueType)

Returns:

  • (Boolean)

    True if version 1.0, false otherwise



117
118
119
# File 'lib/fontisan/tables/maxp.rb', line 117

def version_1_0?
  version_raw == VERSION_1_0
end