Пример #1
0
        }                                               // temporarily replace the abstract modifier with virtual

        protected virtual void CalculateCheckSum()
        {
            // This will need to be overridden for the 'head' table
            _calculatedChecksum = OTFile.CalcTableCheckSum(_parentFont.MemoryStream, _tableRecord.Offset, _tableRecord.Length);
        }
Пример #2
0
        protected override void CalculateCheckSum()
        {
            /* The 'head' table requires special handling for calculating a checksum. The
             * process also involves the head.checksumAdjustment field. Both will be
             * calculated.
             *
             * From OT spec (v1.8.3) font file regarding TableRecord.checkSum for 'head':
             *     To calculate the checkSum for the 'head' table which itself includes the
             *     checkSumAdjustment entry for the entire font, do the following:
             *       1. Set the checkSumAdjustment to 0.
             *       2. Calculate the checksum for all the tables including the 'head' table
             *          and enter that value into the table directory.
             *
             * NOTE: This wording is unclear and can be misleading. The TableRecord.checkSum
             * for 'head' is calculated using the modified 'head' data only, not the rest of
             * the file.
             *
             * From OT spec 'head' table regarding checkSumAdjustment:
             *     To compute it: set it to 0, sum the entire font as uint32,
             *     then store 0xB1B0AFBA - sum.
             *
             *     If the font is used as a component in a font collection file, the value
             *     of this field will be invalidated by changes to the file structure and
             *     font table directory, and must be ignored.
             *
             * If in a TTC, ignore all that and just set both to 0.
             */

            if (_parentFont.File.IsCollection)
            {
                _calculatedChecksum           = 0;
                _calculatedCheckSumAdjustment = 0;
                return;
            }

            // get a copy of the byte array segment for the 'head' table
            byte[] fileData = _parentFont.MemoryStream.GetBuffer(); // ref, not copy!

            // make sure to get a four-byte-integral slice
            uint length = (_tableRecord.Length + 3U) & ~3U;

            byte[] headDataSegment = new byte[length];
            Array.ConstrainedCopy(fileData, (int)_tableRecord.Offset, headDataSegment, 0, (int)length);

            // In the copy, clear the checkSumAdjustment field, bytes at relative offset 8 to 11
            byte[] bytes = new byte[4] {
                0, 0, 0, 0
            };
            bytes.CopyTo(headDataSegment, 8);

            // calculate the checksum for this modified 'head' copy -- that should match what's in TableRecord
            MemoryStream ms = new MemoryStream(headDataSegment, 0, headDataSegment.Length, true, true);

            _calculatedChecksum = OTFile.CalcTableCheckSum(ms, 0, length);


            // Now to calculate checkSumAdjustment: need to checksum the entire file with
            // head.checkSumAdjustment set to 0. Instead of copying the entire file, we
            // can compute checksum in steps: start with the file segment before the
            // 'head' table; then add onto that the modified 'head' copy; then add to
            // that the remainder of the file.
            //
            // NOTE: C# addition is left associative. We can't calculate three separate
            // checksums and then combine them. We need to start the calculation for the
            // second and third portions using the prior sum as the initial left operand.



            // get checksum for first file segment before the 'head' table
            // (note: head offset must be > 0)
            UInt32 sum = OTFile.CalcTableCheckSum(_parentFont.MemoryStream, 0, _tableRecord.Offset);

            // continue with the modified 'head' segment, passing sum as leftPriorSum
            sum = OTFile.CalcTableCheckSum(ms, 0, length, sum);

            // continue with the remainder of the file
            uint offsetAfterHead = _tableRecord.Offset + length;

            if (offsetAfterHead < _parentFont.File.Length)
            {
                sum = OTFile.CalcTableCheckSum(_parentFont.MemoryStream, offsetAfterHead, (uint)(_parentFont.File.Length - offsetAfterHead), sum);
            }

            // Now get 0xB1B0AFBA - sum
            unchecked
            {
                _calculatedCheckSumAdjustment = 0xB1B0AFBA - sum;
            }
        } // CalculateChecksum