Пример #1
0
            public void ReadLayerRecord(MemoryStream ms)
            {
                _validationStatus = OTFile.OTRecordValidation_PartialValidation;

                try
                {
                    _gID = OTFile.ReadUInt16(ms);
                    _paletteIndex = OTFile.ReadUInt16(ms);
                }
                catch (OTDataTypeReadException e)
                {
                    _validationStatus |= OTFile.OTRecordValidation_ReadTrunctated;
                    throw new OTDataIncompleteReadException("OT parse error: unable to read layer record", e);
                }
                // record-internal validations are complete
                _validationStatus &= (0xff - OTFile.OTRecordValidation_PartialValidation);
                _validationStatus |= OTFile.OTRecordValidation_InternalValidationOnly;
            }
Пример #2
0
        protected override void ReadTable_Internal()
        {
            // Base class constructor ran partial validations on the table record,
            // including checking that the offset and length are within bounds

            if ((_validationStatus & OTFile.OTFileValidation_StructureOffsetOutOfRange) != 0)
            {
                // out of range so can't read anything
                return;
            }

            MemoryStream ms = _parentFont.MemoryStream;

            // Read header fields
            // Table has 16-bit (minor) version field, so any version has known fields

            if (_tableRecord.Length < _colr_0_headerLength)
                _validationStatus |= OTFile.OTFileValidation_TableLengthTooShort;

            try
            {
                ms.Seek(_tableRecord.Offset, SeekOrigin.Begin);
                _version = OTFile.ReadUInt16(ms);
                _numBaseGlyphRecords = OTFile.ReadUInt16(ms);
                _baseGlyphRecordsOffset = OTFile.ReadUInt32(ms);
                _layerRecordsOffset = OTFile.ReadUInt32(ms);
                _numLayerRecords = OTFile.ReadUInt16(ms);

            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTDataIncompleteReadException("OT parse error: unable to read " + _tableTag + " table", e);
            }

            if (_version > _latestKnownMinorVersion)
                _validationStatus |= OTFile.OTFileValidation_StructureMinorVersionUnknown;

            // check length then read base glyph records
            uint requiredLength = _baseGlyphRecordsOffset + _numBaseGlyphRecords * _baseGlyphRecordLength;
            if (_tableRecord.Length < requiredLength)
                _validationStatus |= OTFile.OTFileValidation_TableLengthTooShort;

            try
            {
                ms.Seek(_tableRecord.Offset + _baseGlyphRecordsOffset, SeekOrigin.Begin);
                _baseGlyphRecords = new BaseGlyphRecord[_numBaseGlyphRecords];
                for (uint i = 0; i < _numBaseGlyphRecords; i++)
                {
                    _baseGlyphRecords[i].ReadBaseGlyphRecord(ms);
                }
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTDataIncompleteReadException("OT parse error: unable to read " + _tableTag + " table", e);
            }

            // check length then read layer records
            requiredLength = _layerRecordsOffset + _numLayerRecords * _layerRecordLength;
            if (_tableRecord.Length < requiredLength)
                _validationStatus |= OTFile.OTFileValidation_TableLengthTooShort;

            try
            {
                ms.Seek(_tableRecord.Offset + _layerRecordsOffset, SeekOrigin.Begin);
                _layerRecords = new LayerRecord[_numLayerRecords];
                for (uint i = 0; i < _numLayerRecords; i++)
                {
                    _layerRecords[i].ReadLayerRecord(ms);
                }
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTDataIncompleteReadException("OT parse error: unable to read " + _tableTag + " table", e);
            }
        }
Пример #3
0
        public void ReadOffsetTable(MemoryStream ms, uint fileOffset)
        {
            // offset was validated as in bounds by upstream caller; set read position
            _offsetInFile = fileOffset;
            ms.Seek((long)fileOffset, SeekOrigin.Begin);

            _validationStatus = OTFile.OTFileValidation_PartialValidation;

            // check length to read sfnt version tag and read
            if (_offsetInFile + 4 > ms.Length)
            {
                _validationStatus |= OTFile.OTFileValidation_OffsetTableLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange;
            }
            try
            {
                _sfntTag = OTTag.ReadTag(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTTableParseException("OT parse error: unable to read Offset Table", e);
            }


            // check that the sfnt version is supported before continuing
            if (!OTFont.IsSupportedSfntVersion(_sfntTag))
            {
                _validationStatus |= OTFile.OTFileValidation_SfntVersionNotSupported;
                throw new OTTableParseException("OT parse error: font resource has an unsupported sfnt version");
            }


            // check length to read remaining header fields, then read
            if (_offsetInFile + 12 > ms.Length)
            {
                _validationStatus |= OTFile.OTFileValidation_OffsetTableLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange;
            }
            try
            {
                _numTables     = OTFile.ReadUInt16(ms);
                _searchRange   = OTFile.ReadUInt16(ms);
                _entrySelector = OTFile.ReadUInt16(ms);
                _rangeShift    = OTFile.ReadUInt16(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTTableParseException("OT parse error: unable to read Offset Table", e);
            }


            // check length to read encoding records array, then read the records
            if (_offsetInFile + 12 + _numTables * TableRecord.TableRecordSize > ms.Length)
            {
                _validationStatus |= OTFile.OTFileValidation_OffsetTableLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange;
            }
            _tableRecords = new TableRecord[_numTables]; // constructs struct records with default values
            _tableMap     = new Dictionary <string, uint>();
            try
            {
                for (uint i = 0; i < _numTables; i++)
                {
                    _tableRecords[i].ReadTableRecord(ms);
                    try
                    {
                        _tableMap.Add(_tableRecords[i].Tag.ToString(), i);
                    }
                    catch (ArgumentException)
                    {
                        // duplicate tag; first one wins
                        _validationStatus |= OTFile.OTFileValidation_StructureHasDuplicateEntries;
                    }
                }
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTTableParseException("OT parse error: unable to read Offset Table", e);
            }
        } // ReadOffsetTable
Пример #4
0
        } // Validate

        #endregion


        #region Private instance methods

        protected override void ReadTable_Internal()
        {
            // Base class constructor ran partial validations on the table record,
            // including checking that the offset and length are within bounds

            if ((_validationStatus & OTFile.OTFileValidation_StructureOffsetOutOfRange) != 0)
            {
                // out of range so can't read anything
                return;
            }

            MemoryStream ms = _parentFont.MemoryStream;


            // Get the version and check that before continuing
            try
            {
                ms.Seek(_tableRecord.Offset, SeekOrigin.Begin);
                _majorVersion = OTFile.ReadUInt16(ms);
                _minorVersion = OTFile.ReadUInt16(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTFileParseException("OT parse error: unable to read " + _tableTag + " table", e);
            }

            if (_majorVersion != 1)
            {
                _validationStatus |= OTFile.OTFileValidation_StructureVersionNotSupported;
                throw new OTUnknownVersionException("OT parse error: unrecognized " + _tableTag + " version");
            }

            if (_minorVersion > _hhea_1_latestKnownVersion)
            {
                _validationStatus |= OTFile.OTFileValidation_StructureMinorVersionUnknown;
            }
            if (_tableRecord.Length < _hhea_1_0_headerLength)
            {
                _validationStatus |= OTFile.OTFileValidation_TableLengthTooShort;
            }


            // Known version, OK to continue
            try
            {
                _ascender            = OTFile.ReadOTFword(ms);
                _descender           = OTFile.ReadOTFword(ms);
                _lineGap             = OTFile.ReadOTFword(ms);
                _advanceWidthMax     = OTFile.ReadOTUfword(ms);
                _minLeftSideBearing  = OTFile.ReadOTFword(ms);
                _minRightSideBearing = OTFile.ReadOTFword(ms);
                _xMaxExtent          = OTFile.ReadOTFword(ms);
                _caretSlopeRise      = OTFile.ReadInt16(ms);
                _caretSlopeRun       = OTFile.ReadInt16(ms);
                _caretOffset         = OTFile.ReadInt16(ms);
                _reserved1           = OTFile.ReadInt16(ms);
                _reserved2           = OTFile.ReadInt16(ms);
                _reserved3           = OTFile.ReadInt16(ms);
                _reserved4           = OTFile.ReadInt16(ms);
                _metricDataFormat    = OTFile.ReadInt16(ms);
                _numberOfHMetrics    = OTFile.ReadUInt16(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTFileParseException("OT parse error: unable to read " + _tableTag + " table", e);
            }
        } // ReadTable_Internal
Пример #5
0
        } // Validate

        #endregion


        #region Private instance methods

        protected override void ReadTable_Internal()
        {
            // Base class constructor ran partial validations on the table record,
            // including checking that the offset and length are within bounds

            if ((_validationStatus & OTFile.OTFileValidation_StructureOffsetOutOfRange) != 0)
            {
                // out of range so can't read anything
                return;
            }

            MemoryStream ms = _parentFont.MemoryStream;


            // Get the version and check that before continuing
            try
            {
                ms.Seek(_tableRecord.Offset, SeekOrigin.Begin);
                _version = OTFixed.ReadFixed(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTFileParseException("OT parse error: unable to read " + _tableTag + " table", e);
            }

            if (_version.Mantissa != 0 && _version.Mantissa != 1)
            {
                _validationStatus |= OTFile.OTFileValidation_StructureVersionNotSupported;
                throw new OTUnknownVersionException("OT parse error: unrecognized " + _tableTag + " version");
            }

            switch (_version.Mantissa)
            {
            case 0:
                if (_version.FixedTableMinorVersionToInteger() > _maxp_0_latestKnownMinorVersion)
                {
                    _validationStatus |= OTFile.OTFileValidation_StructureMinorVersionUnknown;
                }
                if (_tableRecord.Length < _maxp_0_5_headerLength)
                {
                    _validationStatus |= OTFile.OTFileValidation_TableLengthTooShort;
                }
                break;

            case 1:
                if (_version.FixedTableMinorVersionToInteger() > _maxp_1_latestKnownMinorVersion)
                {
                    _validationStatus |= OTFile.OTFileValidation_StructureMinorVersionUnknown;
                }
                if (_tableRecord.Length < _maxp_1_0_headerLength)
                {
                    _validationStatus |= OTFile.OTFileValidation_TableLengthTooShort;
                }
                break;
            }


            // Known version, OK to continue
            try
            {
                _numGlyphs = OTFile.ReadUInt16(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTFileParseException("OT parse error: unable to read " + _tableTag + " table", e);
            }

            if (_version.Mantissa == 1)
            {
                try
                {
                    _maxPoints             = OTFile.ReadUInt16(ms);
                    _maxContours           = OTFile.ReadUInt16(ms);
                    _maxCompositePoints    = OTFile.ReadUInt16(ms);
                    _maxCompositeContours  = OTFile.ReadUInt16(ms);
                    _maxZones              = OTFile.ReadUInt16(ms);
                    _maxTwilightPoints     = OTFile.ReadUInt16(ms);
                    _maxStorage            = OTFile.ReadUInt16(ms);
                    _maxFunctionDefs       = OTFile.ReadUInt16(ms);
                    _maxInstructionDefs    = OTFile.ReadUInt16(ms);
                    _maxStackElements      = OTFile.ReadUInt16(ms);
                    _maxSizeOfInstructions = OTFile.ReadUInt16(ms);
                    _maxComponentElements  = OTFile.ReadUInt16(ms);
                    _maxComponentDepth     = OTFile.ReadUInt16(ms);
                }
                catch (OTDataIncompleteReadException e)
                {
                    _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                    throw new OTFileParseException("OT parse error: unable to read " + _tableTag + " table", e);
                }
            }
        } // ReadTable_Internal
Пример #6
0
        public void ReadTtcHeader(MemoryStream ms)
        {
            // Makes sure we're at the start of the file.
            ms.Seek(0, SeekOrigin.Begin);
            _fileOffset = 0;

            _validationStatus = OTFile.OTFileValidation_PartialValidation;

            if (ms.Length < (4 + 2 * sizeof(UInt16)))
            {
                _validationStatus |= OTFile.OTFileValidation_TtcHeaderLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange;
            }

            try
            {
                _tag = new byte[4];
                if (ms.Read(_tag) < 4)
                {
                    _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                    throw new OTDataIncompleteReadException("OT parse error: unable to read sufficient bytes to TTC header tag");
                }

                _majorVersion = OTFile.ReadUInt16(ms);
                _minorVersion = OTFile.ReadUInt16(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTFileParseException("OT parse error: unable to read TTC header", e);
            }

            if (_majorVersion != 1 && _majorVersion != 2)
            {
                _validationStatus |= OTFile.OTFileValidation_StructureVersionNotSupported;
                throw new OTUnknownVersionException("OT parse error: unrecognized TTC header version");
            }

            if (ms.Length < (4 + 2 * sizeof(UInt16) + sizeof(UInt32)))
            {
                _validationStatus |= OTFile.OTFileValidation_TtcHeaderLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange;
            }

            try
            {
                _numFonts = OTFile.ReadUInt32(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTFileParseException("OT parse error: unable to read TTC header", e);
            }

            if (ms.Length < (4 + 2 * sizeof(UInt16) + (_numFonts + 1) * sizeof(UInt32)))
            {
                _validationStatus |= OTFile.OTFileValidation_TtcHeaderLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange;
            }

            _offsetTableOffsets = new uint[_numFonts];
            for (UInt32 i = 0; i < _numFonts; i++)
            {
                try
                {
                    _offsetTableOffsets[i] = OTFile.ReadUInt32(ms);
                }
                catch (OTDataIncompleteReadException e)
                {
                    _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                    throw new OTFileParseException("OT parse error: unable to read TTC header", e);
                }
            } // loop over offsets array

            if (_majorVersion == 2)
            {
                // may have DSIG table

                if (ms.Length < (4 + 2 * sizeof(UInt16) + (_numFonts + 4) * sizeof(UInt32)))
                {
                    _validationStatus |= OTFile.OTFileValidation_TtcHeaderLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange;
                }

                try
                {
                    _dsigTag = new byte[4];
                    if (ms.Read(_dsigTag) < 4)
                    {
                        throw new OTDataIncompleteReadException("OT parse error: unable to read sufficient bytes to DSIG tag");
                    }

                    _dsigLength = OTFile.ReadUInt32(ms);
                    _dsigOffset = OTFile.ReadUInt32(ms);
                }
                catch (OTDataIncompleteReadException e)
                {
                    _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                    throw new OTFileParseException("OT parse error: unable to read TTC header", e);
                }
            } // version 2.x
        }     // ReadTtcHeader
Пример #7
0
        } // Validate

        #endregion


        #region Private instance methods

        protected override void ReadTable_Internal()
        {
            // Base class constructor ran partial validations on the table record,
            // including checking that the offset and length are within bounds

            if ((_validationStatus & OTFile.OTFileValidation_StructureOffsetOutOfRange) != 0)
            {
                // out of range so can't read anything
                return;
            }

            MemoryStream ms = _parentFont.MemoryStream;


            // Get the version and check that before continuing
            try
            {
                ms.Seek(_tableRecord.Offset, SeekOrigin.Begin);
                _majorVersion = OTFile.ReadUInt16(ms);
                _minorVersion = OTFile.ReadUInt16(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTFileParseException("OT parse error: unable to read " + _tableTag + " table", e);
            }

            if (_majorVersion != 1)
            {
                _validationStatus |= OTFile.OTFileValidation_StructureVersionNotSupported;
                throw new OTUnknownVersionException("OT parse error: unrecognized " + _tableTag + " version");
            }

            if (_minorVersion > _head_1_latestKnownMinorVersion)
            {
                _validationStatus |= OTFile.OTFileValidation_StructureMinorVersionUnknown;
            }
            if (_tableRecord.Length < _head_1_0_headerLength)
            {
                _validationStatus |= OTFile.OTFileValidation_TableLengthTooShort;
            }


            // Known version, OK to continue
            try
            {
                _fontRevision       = OTFixed.ReadFixed(ms);
                _checkSumAdjustment = OTFile.ReadUInt32(ms);
                _magicNumber        = OTFile.ReadUInt32(ms);
                _flagsRaw           = OTFile.ReadUInt16(ms);
                _unitsPerEm         = OTFile.ReadUInt16(ms);
                _createdRaw         = OTFile.ReadOTLongDateTimeAsInt64(ms);
                _modifiedRaw        = OTFile.ReadOTLongDateTimeAsInt64(ms);
                _xMin              = OTFile.ReadInt16(ms);
                _yMin              = OTFile.ReadInt16(ms);
                _xMax              = OTFile.ReadInt16(ms);
                _yMax              = OTFile.ReadInt16(ms);
                _macStyleRaw       = OTFile.ReadUInt16(ms);
                _lowestRecPPEm     = OTFile.ReadUInt16(ms);
                _fontDirectionHint = OTFile.ReadInt16(ms);
                _indexToLocFormat  = OTFile.ReadInt16(ms);
                _glyphDataFormat   = OTFile.ReadInt16(ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                _validationStatus |= OTFile.OTFileValidation_ReadTrunctated;
                throw new OTFileParseException("OT parse error: unable to read " + _tableTag + " table", e);
            }

            SetHeadFlagValues();     // set HeadFlags struct values
            SetHeadMacStyleValues(); // set HeadMacStyle struct values
        } // ReadTable_Internal