/// <summary> /// Calculate the checksum for the whole font by setting checksum adjustment in the head table to 0. /// </summary> public static uint CalculateWholeFontChecksum(IInputBytes bytes, TrueTypeHeaderTable headerTable) { if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } if (!IsHeadTable(headerTable)) { throw new ArgumentException($"Can only calculate checksum for the whole font when the head table is provided. Got: {headerTable}."); } bytes.Seek(0); return(Calculate(ToChecksumSkippedEnumerable(bytes, headerTable))); }
/// <summary> /// Calculate the checksum for the specific table. /// </summary> public static uint Calculate(IInputBytes bytes, TrueTypeHeaderTable table) { bytes.Seek(table.Offset); if (IsHeadTable(table)) { // To calculate the checkSum for the 'head' table which itself includes the // checkSumAdjustment entry for the entire font, do the following: // Set the checkSumAdjustment to 0. // Calculate the checksum as normal. var fullTableBytes = new byte[table.Length]; var read = bytes.Read(fullTableBytes); if (read != table.Length) { throw new InvalidOperationException(); } // Zero out the checksum adjustment fullTableBytes[ChecksumAdjustmentPosition] = 0; fullTableBytes[ChecksumAdjustmentPosition + 1] = 0; fullTableBytes[ChecksumAdjustmentPosition + 2] = 0; fullTableBytes[ChecksumAdjustmentPosition + 3] = 0; return(Calculate(fullTableBytes)); } var result = 0u; unchecked { while (TryReadUInt(bytes, table.Offset + table.Length, out var next)) { result += next; } } return(result); }
private static bool IsHeadTable(TrueTypeHeaderTable table) => string.Equals(HeaderTableTag, table.Tag, StringComparison.OrdinalIgnoreCase);
private static IEnumerable <byte> ToChecksumSkippedEnumerable(IInputBytes bytes, TrueTypeHeaderTable table) { while (bytes.MoveNext()) { // Skip checksum adjustment if (bytes.CurrentOffset > table.Offset + ChecksumAdjustmentPosition && bytes.CurrentOffset <= table.Offset + ChecksumAdjustmentPosition + 4) { continue; } yield return(bytes.CurrentByte); } }