Class: Fontisan::Utilities::ChecksumCalculator

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/utilities/checksum_calculator.rb

Overview

ChecksumCalculator provides stateless utility methods for calculating font file checksums.

This class implements the TrueType/OpenType checksum algorithm which sums all uint32 values in a file. The checksum is used to verify file integrity and calculate the checksumAdjustment value stored in the ‘head’ table.

Examples:

Calculate file checksum

checksum = ChecksumCalculator.calculate_file_checksum("font.ttf")
# => 2842116234

Calculate checksum adjustment

adjustment = ChecksumCalculator.calculate_adjustment(checksum)
# => 1452851062

Class Method Summary collapse

Class Method Details

.calculate_adjustment(file_checksum) ⇒ Integer

Calculate the checksum adjustment value for the ‘head’ table.

The checksum adjustment is stored at offset 8 in the ‘head’ table and is calculated as: CHECKSUM_ADJUSTMENT_MAGIC - file_checksum. This value ensures that the checksum of the entire font file equals the magic number.

Examples:

adjustment = ChecksumCalculator.calculate_adjustment(2842116234)
# => 1452851062

Parameters:

  • file_checksum (Integer)

    the calculated file checksum

Returns:

  • (Integer)

    the checksum adjustment value to write to the ‘head’ table



56
57
58
# File 'lib/fontisan/utilities/checksum_calculator.rb', line 56

def self.calculate_adjustment(file_checksum)
  (Constants::CHECKSUM_ADJUSTMENT_MAGIC - file_checksum) & 0xFFFFFFFF
end

.calculate_checksum_from_io_with_tempfile(io) ⇒ Array<Integer, Tempfile>

Note:

On Windows, Ruby’s Tempfile automatically deletes the temp file when the Tempfile object is garbage collected. In multi-threaded environments, this can cause PermissionDenied errors if the file is deleted while another thread is still using it. By returning the tempfile reference, the caller can ensure it remains alive until all operations complete.

Calculate checksum from an IO object using a tempfile for Windows compatibility.

This method creates a temporary file from the IO content to ensure proper file handle semantics on Windows, where file handles must remain open for checksum calculation. The tempfile reference is returned alongside the checksum to prevent premature garbage collection on Windows.

Examples:

checksum, tmpfile = ChecksumCalculator.calculate_checksum_from_io_with_tempfile(io)
# Use checksum...
# tmpfile will be GC'd when it goes out of scope, which is safe

Parameters:

  • io (IO)

    the IO object to read from (must be rewindable)

Returns:

  • (Array<Integer, Tempfile>)

    array containing [checksum, tempfile] The checksum value and the tempfile that must be kept alive until the caller is done with the checksum.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/fontisan/utilities/checksum_calculator.rb', line 127

def self.calculate_checksum_from_io_with_tempfile(io)
  io.rewind

  # Create a tempfile to handle Windows file locking issues
  tmpfile = Tempfile.new(["font", ".ttf"])
  tmpfile.binmode

  # Copy IO content to tempfile
  IO.copy_stream(io, tmpfile)
  tmpfile.close

  # Calculate checksum from the tempfile
  checksum = calculate_file_checksum(tmpfile.path)

  # Return both checksum and tempfile to keep it alive
  # The caller must keep the tempfile reference until done with checksum
  [checksum, tmpfile]
end

.calculate_file_checksum(file_path) ⇒ Integer

Calculate the checksum of an entire font file.

The checksum is calculated by summing all uint32 (4-byte) values in the file. Files that are not multiples of 4 bytes are padded with zeros. The sum is masked to 32 bits to prevent overflow.

Examples:

checksum = ChecksumCalculator.calculate_file_checksum("font.ttf")
# => 2842116234

Parameters:

  • file_path (String)

    path to the font file

Returns:

  • (Integer)

    the calculated uint32 checksum

Raises:

  • (Errno::ENOENT)

    if the file does not exist

  • (Errno::EACCES)

    if the file cannot be read



37
38
39
40
41
# File 'lib/fontisan/utilities/checksum_calculator.rb', line 37

def self.calculate_file_checksum(file_path)
  File.open(file_path, "rb") do |file|
    calculate_checksum_from_io(file)
  end
end

.calculate_table_checksum(data) ⇒ Integer

Calculate checksum for raw table data.

This method calculates the checksum for a binary string of table data. Used when creating WOFF files or validating table integrity.

Examples:

checksum = ChecksumCalculator.calculate_table_checksum(table_data)
# => 1234567890

Parameters:

  • data (String)

    binary table data

Returns:

  • (Integer)

    the calculated uint32 checksum



71
72
73
74
75
# File 'lib/fontisan/utilities/checksum_calculator.rb', line 71

def self.calculate_table_checksum(data)
  io = StringIO.new(data)
  io.set_encoding(Encoding::BINARY)
  calculate_checksum_from_io(io)
end