예제 #1
0
        } // ReadTableRecord

        public UInt64 Validate(long fileLength)
        {
            // Check that tag is defined and known, and that table
            // offset & length are in bounds.

            if (!OTFont.IsKnownTableType(_tableTag))
            {
                _validationStatus |= OTFile.OTFileValidation_UnknownTableTag;
            }
            if (!OTFont.IsSupportedTableType(_tableTag))
            {
                _validationStatus |= OTFile.OTFileValidation_UnsupportedTableTag;
            }
            if (_tableOffset > fileLength)
            {
                _validationStatus |= OTFile.OTFileValidation_ReferencedStructureOffsetOutOfRange;
            }
            if (_tableOffset + _tableLength > fileLength)
            {
                _validationStatus |= OTFile.OTFileValidation_ReferencedStructureLengthOutOfRange;
            }

            // completed validateions; clear the partial validation flag and check for errors
            _validationStatus &= ~OTFile.OTFileValidation_PartialValidation;
            if ((_validationStatus & OTFile.OTFileValidation_ValidationIssueMask) == 0)
            {
                _validationStatus = OTFile.OTFileValidation_Valid;
            }

            return(_validationStatus);
        } // Validate
예제 #2
0
 public OTTable(OTFont parentFont, TableRecord tableRecord)
 {
     // This is only used temporarily to create a placeholder table if the table type is not supported.
     _parentFont  = parentFont;
     _tableRecord = tableRecord;
     CalculateCheckSum();
     _validationStatus = OTFile.OTFileValidation_PartialValidation | ValidateTableRecord();
 }
예제 #3
0
        public OTTable(OTFont parentFont, TableRecord tableRecord, string expectedTag, bool parseWhenConstructed)
        {
            // Used for derived classes for specific table types
            if (tableRecord.Tag.ToString() != expectedTag)
            {
                throw new ArgumentException("TableRecord has the wrong tag for the '" + expectedTag + " table");
            }

            _parentFont  = parentFont;
            _tableRecord = tableRecord;
            CalculateCheckSum();
            _validationStatus = OTFile.OTFileValidation_PartialValidation | ValidateTableRecord();

            if (parseWhenConstructed)
            {
                ReadTable_Internal();
            }
        }
예제 #4
0
 public TableColr(OTFont parentFont, TableRecord tableRecord)
     : base(parentFont, tableRecord, _tableTag, /* parseWhenConstructed */ true)
 {
     // Base class constructor validates table record values, and marks
     // validation completion status as partial validation
 }
예제 #5
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
예제 #6
0
        private void ReadFont_Internal(MemoryStream ms)
        {
            // results in Offset table for font being read, but no other tables

            // assumed: _offsetInFile has already been set and validated as in bounds
            try
            {
                _offsetTable.ReadOffsetTable(ms, _offsetInFile);
            }
            catch (OTTableParseException e)
            {
                throw new OTFontParseException("Unable to parse font data", e);
            }


            // Offset table for font has been read; we know how many and what kind
            // of tables.

            _tables = new OTTable[_offsetTable.NumTables];                  // initialized with entries == null
            _validationStatusOfTables = new UInt64[_offsetTable.NumTables]; // initialized with entries == NotValidated

            // The following is something temporary: populate an array of OTTable objects
            // passing each its offset table record. The record is all that's needed to
            // parse each table; but once an object is created (OTTable), it can't change
            // itself into a different type; it can only be substituted with a different
            // type of object, and that substitution would have to be done by something
            // else.

            for (int i = 0; i < _offsetTable.NumTables; i++)
            {
                if (OTFont.IsSupportedTableType(_offsetTable.TableRecords[i].Tag))
                {
                    switch (_offsetTable.TableRecords[i].Tag.ToString())
                    {
                    case "COLR":
                        _tables[i] = new TableColr(this, _offsetTable.TableRecords[i]);
                        break;

                    case "fmtx":
                        _tables[i] = new TableFmtx(this, _offsetTable.TableRecords[i]);
                        break;

                    case "head":
                        _tables[i] = new TableHead(this, _offsetTable.TableRecords[i]);
                        break;

                    case "hhea":
                        _tables[i] = new TableHhea(this, _offsetTable.TableRecords[i]);
                        break;

                    case "maxp":
                        _tables[i] = new TableMaxp(this, _offsetTable.TableRecords[i]);
                        break;
                    }
                }
                else
                {
                    _tables[i] = new OTTable(this, _offsetTable.TableRecords[i]);
                }
            }
        } // ReadFont_Internal
예제 #7
0
        public void ReadFromFile(FileInfo fileInfo)
        {
            // save fileinfo for later reference
            _fi = fileInfo;

            // Check that file exists. (Handle FileStream exception in advance.)
            if (!_fi.Exists)
            {
                throw new FileNotFoundException("File " + _fi.FullName + " was not found.", _fi.FullName);
            }

            // read file as a byte array, then construct memory stream from byte array
            {
                byte[] bytes;
                try
                {
                    // File.ReadAllBytes opens a filestream and then ensures it is closed
                    bytes = File.ReadAllBytes(_fi.FullName);
                    _ms   = new MemoryStream(bytes, 0, bytes.Length, false, true);
                }
                catch (IOException e)
                {
                    throw e;
                }
            }

            // Read sfntVersion tag
            try
            {
                _sfntVersionTag = OTTag.ReadTag(_ms);
            }
            catch (OTDataIncompleteReadException e)
            {
                throw new OTFileParseException("OT parse error: unable to read sfnt tag", e);
            }

            // supported format?
            if (!IsSupportedSfntVersion(_sfntVersionTag))
            {
                _validationStatus = OTFileValidation_SfntVersionNotSupported;
                throw new OTFileParseException("OT parse error: not a known and supported sfnt type (sfnt tag = " + _sfntVersionTag.ToString());
            }

            _validationStatus = OTFile.OTFileValidation_PartialValidation;

            // TTC? get TTC header
            if (_sfntVersionTag == (OTTag)"ttcf")
            {
                try
                {
                    _ttcHeader.ReadTtcHeader(_ms); // will set read position to start of file
                }
                catch (OTException e)
                {
                    _validationStatus = _ttcHeader.ValidationStatus;
                    throw new OTFileParseException("OT parse error: unable to read TTC header", e);
                }

                _numFonts = _ttcHeader.NumFonts;
            }
            else
            {
                _numFonts = 1;
            }

            // initialize new font object(s); this will get the font headers for each font resource
            _fonts = new OTFont[_numFonts];
            if (_sfntVersionTag == (OTTag)"ttcf")
            {
                for (uint i = 0; i < _numFonts; i++)
                {
                    _fonts[i] = new OTFont(this, _ttcHeader.OffsetTableOffsets[i], i);
                }
            }
            else // single font
            {
                _fonts[0] = new OTFont(this);
            }

            // got TTC header; created font objects and got all the header info for each
            // caller can now poke individual fonts to get additional info as needed

            // finally, get validation status on ttc header, offset tables
            _validationStatusOfFonts = new UInt64[_numFonts];
            for (int i = 0; i < _numFonts; i++)
            {
                // simple validations -- full validation on a table-by-table basis
                _fonts[i].Validate(_ms.Length, true);
            }

            if (_sfntVersionTag == (OTTag)"ttcf")
            {
                // treat ttc header validation as part of the file validation
                _validationStatus |= _ttcHeader.Validate(_ms.Length);

                // check for validation issues in any of the font resources
                for (int i = 0; i < _numFonts; i++)
                {
                    if ((_fonts[i].ValidationStatus & OTFile.OTFileValidation_ValidationIssueMask) != 0)
                    {
                        _validationStatus |= OTFile.OTFileValidation_ValidationIssueInChildStructure;
                        break;
                    }
                }
            }
            else
            {
                // treat font resource validation as part of the file validation
                _validationStatus |= (_fonts[0].ValidationStatus & OTFile.OTFileValidation_ValidationIssueMask);
            }
        } // ReadFromFile