public void ChecksumAdjustment(byte[] headersBuffer, uint headerOffset, uint headerLength, uint tablesChecksum = 0) { Debug.Assert(_headIndex != -1); if (_headIndex == -1) { return; } var headTable = _woffTables[_headIndex] as WoffTableHead; Debug.Assert(headTable != null); if (headTable == null) { return; } // Compute the checksum of the font's header Debug.Assert(headerLength != 0); Debug.Assert(headersBuffer != null && headersBuffer.Length != 0); var headerPadding = (uint)WoffBuffer.CalcPadBytes((int)headerLength, 4); var buffer = headersBuffer; if (headerPadding > 0) { var paddedLength = headerLength + headerPadding; buffer = new byte[paddedLength]; Buffer.BlockCopy(headersBuffer, 0, buffer, 0, headersBuffer.Length); } uint nLongs = (headerLength + 3) / 4; uint headerChecksum = 0; for (uint i = 0; i < nLongs; i += 4) { headerChecksum += WoffBuffer.GetUIntBE(buffer, i); } // Compute the checksum of the font by summing the checksum of the header and tables var fontChecksum = headerChecksum; if (tablesChecksum == 0) { tablesChecksum = headerChecksum; for (ushort i = 0; i < _woffDirs.Count; i++) { tablesChecksum += _woffDirs[i].OrigChecksum; } } fontChecksum += headerChecksum; // Finally, update the 'head' table's checkSumAdjustment. headTable.CheckSumAdjustment = 0xB1B0AFBA - fontChecksum; }
public uint CalculateChecksum() { Debug.Assert(_origLength != 0); Debug.Assert(_origTable != null && _origTable.Length != 0); var padBytesLength = (uint)WoffBuffer.CalcPadBytes((int)_origLength, 4); if (padBytesLength != 0) { _padding = padBytesLength; } var origLength = _origLength; var buffer = _origTable; if (_padding > 0) { origLength = _origLength + _padding; buffer = new byte[origLength]; Buffer.BlockCopy(_origTable, 0, buffer, 0, _origTable.Length); } uint nLongs = (_origLength + 3) / 4; uint sum = 0; //for (uint i = 0; i < nLongs; i++) //{ // sum += WoffBuffer.GetUIntBE(buffer, i * 4); //} for (uint i = 0; i < nLongs; i += 4) { sum += WoffBuffer.GetUIntBE(buffer, i); } return(sum); }
public bool Serialize(WoffWriter writer, WoffIndexer pointsWriter, out uint glyphSize) { glyphSize = 0; if (writer == null) { return(false); } uint startOffset = writer.Offset; // 1. Write the Glyph Header writer.WriteInt16(_numContours); // int16 numberOfContours for number of contours: >= 0 is simple glyph, < 0 composite glyph. writer.WriteInt16(_xMin); // int16 xMin Minimum x for coordinate data. writer.WriteInt16(_yMin); // int16 yMin Minimum y for coordinate data. writer.WriteInt16(_xMax); // int16 xMax Maximum x for coordinate data. writer.WriteInt16(_yMax); // int16 yMax Maximum y for coordinate data. // 2. Write the Simple Glyph Description, if applicable if (_glyphType == WoffGlyphType.Simple) { // uint16 endPtsOfContours[numberOfContours] // Array of point indices for the last point of each contour, in increasing numeric order. Debug.Assert(_endPtsOfContours != null && _endPtsOfContours.Length == _numContours); if (_endPtsOfContours == null || _endPtsOfContours.Length != _numContours) { Debug.Assert(false, "Invalid condition."); return(false); } for (short i = 0; i < _numContours; i++) { writer.WriteUInt16(_endPtsOfContours[i]); } // uint16 instructionLength Total number of bytes for instructions. // If instructionLength is zero, no instructions are present for this glyph, // and this field is followed directly by the flags field.instructionLength writer.WriteUInt16(_instructionLength); // uint8 instructions[instructionLength] Array of instruction byte code for the glyph. if (_instructionLength != 0) { Debug.Assert(_instructions != null && _instructions.Length == _instructionLength); if (_instructions == null || _instructions.Length != _instructionLength) { Debug.Assert(false, "Invalid condition."); return(false); } writer.Write(_instructions); } // Pack the points Debug.Assert(_numPoints == _contours.Count); int pointsCapacity = 5 * _numPoints; // Size without the application of packing. if (pointsWriter == null) { pointsWriter = new WoffIndexer(pointsCapacity); } else { pointsWriter.Offset = 0; } uint pointsLength = 0; if (PackPoints(pointsWriter, (uint)pointsCapacity, ref pointsLength) == false) { Debug.Assert(false, "Invalid condition."); return(false); } // Serialize the points... writer.Write(pointsWriter.GetBuffer(), 0, (int)pointsLength); } // Write the Simple Glyph Description, if applicable else if (_glyphType == WoffGlyphType.Composite) { Debug.Assert(_componentLength != 0); Debug.Assert(_components != null && _componentLength == _components.Length); if (_componentLength == 0 || _components == null || _componentLength != _components.Length) { Debug.Assert(false, "Invalid condition."); return(false); } // Serialize the Composite Glyph data... writer.Write(_components, 0, _componentLength); } // NOTE: Without the padding the serialization of the glyph fails! var padBytesLength = WoffBuffer.CalcPadBytes((int)writer.Offset, 4); if (padBytesLength > 0) { var paddingBuffer = new byte[4]; writer.Write(paddingBuffer, 0, padBytesLength); } uint endOffset = writer.Offset; if (endOffset <= startOffset) { Debug.Assert(false, "Invalid condition."); return(false); } glyphSize = endOffset - startOffset; return(true); }