Пример #1
0
        /// <summary>
        ///     Reads the Offset and Directory tables.  If the FontFileStream represents
        ///     a TrueType collection, this method will look for the aforementioned
        ///     tables belonging to <i>fontName</i>.
        /// </summary>
        /// <remarks>
        ///     This method can handle a TrueType collection.
        /// </remarks>
        protected void ReadTableHeaders()
        {
            // Check for possible TrueType collection
            string tag = Encoding.ASCII.GetString(stream.ReadTag());

            if (tag == TableNames.Ttcf)
            {
                // Skip Version field - will be either 1.0 or 2.0
                stream.Skip(PrimitiveSizes.ULong);

                // Number of fonts in TrueType collection
                int numFonts = (int)stream.ReadULong();

                bool foundFont = false;
                for (int i = 0; i < numFonts && !foundFont; i++)
                {
                    // Offset from beginning of file to a font's subtable
                    uint directoryOffset = stream.ReadULong();

                    // Set a restore point since the code below will alter the stream position
                    stream.SetRestorePoint();
                    stream.Position = directoryOffset;

                    header = new TrueTypeHeader();
                    header.Read(stream);

                    // To ascertain whether this font is the one we're looking for,
                    // we must read the 'name' table.
                    if (!header.Contains(TableNames.Name))
                    {
                        throw new Exception("Unable to parse TrueType collection - missing 'head' table.");
                    }

                    // If font name is not supplied, select the first font in the colleciton;
                    // otherwise must have an exact match
                    NameTable nameTable = (NameTable)GetTable(TableNames.Name);
                    if (fontName == String.Empty || nameTable.FullName == fontName)
                    {
                        foundFont = true;
                    }

                    // Stream will now point to the next directory offset
                    stream.Restore();
                }

                // We were unable to locate font in collection
                if (!foundFont)
                {
                    throw new Exception("Unable to locate font '" + fontName + "' in TrueType collection");
                }
            }
            else
            {
                stream.Position = 0;

                // Read Offset and Directory tables
                header = new TrueTypeHeader();
                header.Read(stream);
            }
        }
Пример #2
0
        /// <summary>
        ///     Reads the contents of the "post" table from the supplied stream
        ///     at the current position.
        /// </summary>
        /// <param name="reader"></param>
        protected internal override void Read(FontFileReader reader)
        {
            FontFileStream stream = reader.Stream;

            version = stream.ReadFixed();

            // The italic angle is stored in the stupid fixed field format.
            italicAngle = (float)stream.ReadFixed() / 65536.0f;

            underlinePosition  = stream.ReadFWord();
            underlineThickness = stream.ReadFWord();
            fixedPitch         = stream.ReadULong();
            minMemType42       = stream.ReadULong();
            maxMemType42       = stream.ReadULong();
            minMemType1        = stream.ReadULong();
            maxMemType1        = stream.ReadULong();
        }
Пример #3
0
        protected internal void Read(FontFileStream stream) {
            // Skip sfnt version (0x00010000 for version 1.0).
            stream.Skip(PrimitiveSizes.Fixed);

            // Number of tables
            int numTables = stream.ReadUShort();

            // Skip searchRange, entrySelector and rangeShift entries (3 x ushort)
            stream.Skip(PrimitiveSizes.UShort*3);

            directoryEntries = new Hashtable(numTables);
            for (int i = 0; i < numTables; i++) {
                DirectoryEntry entry = new DirectoryEntry(
                    stream.ReadTag(), // 4-byte identifier.
                    stream.ReadULong(), // CheckSum for this table. 
                    stream.ReadULong(), // Offset from beginning of TrueType font file. 
                    stream.ReadULong() // Length of this table. 
                    );
                directoryEntries.Add(entry.TableName, entry);
            }
        }
Пример #4
0
        /// <summary>
        ///     Reads the contents of the "head" table from the current position
        ///     in the supplied stream.
        /// </summary>
        /// <param name="reader"></param>
        protected internal override void Read(FontFileReader reader)
        {
            FontFileStream stream = reader.Stream;

            versionNo          = stream.ReadFixed();
            fontRevision       = stream.ReadFixed();
            checkSumAdjustment = stream.ReadULong();
            magicNumber        = stream.ReadULong();
            flags       = stream.ReadUShort();
            unitsPermEm = stream.ReadUShort();
            // Some fonts have dodgy date offsets that cause AddSeconds to throw an exception
            createDate        = GetDate(stream.ReadLongDateTime());
            updateDate        = GetDate(stream.ReadLongDateTime());
            xMin              = stream.ReadShort();
            yMin              = stream.ReadShort();
            xMax              = stream.ReadShort();
            yMax              = stream.ReadShort();
            macStyle          = stream.ReadUShort();
            lowestRecPPEM     = stream.ReadUShort();
            fontDirectionHint = stream.ReadShort();
            indexToLocFormat  = stream.ReadShort();
            glyphDataFormat   = stream.ReadShort();
        }
Пример #5
0
        protected internal void Read(FontFileStream stream)
        {
            // Skip sfnt version (0x00010000 for version 1.0).
            stream.Skip(PrimitiveSizes.Fixed);

            // Number of tables
            int numTables = stream.ReadUShort();

            // Skip searchRange, entrySelector and rangeShift entries (3 x ushort)
            stream.Skip(PrimitiveSizes.UShort * 3);

            directoryEntries = new Hashtable(numTables);
            for (int i = 0; i < numTables; i++)
            {
                DirectoryEntry entry = new DirectoryEntry(
                    stream.ReadTag(),   // 4-byte identifier.
                    stream.ReadULong(), // CheckSum for this table.
                    stream.ReadULong(), // Offset from beginning of TrueType font file.
                    stream.ReadULong()  // Length of this table.
                    );
                directoryEntries.Add(entry.TableName, entry);
            }
        }
Пример #6
0
        /// <summary>
        ///     Calculates the checksum of a <see cref="FontTable"/>.
        /// </summary>
        /// <remarks>
        ///     The supplied <i>stream</i> must be positioned at the beginning of
        ///     the table.
        /// </remarks>
        /// <param name="length"></param>
        /// <returns></returns>
        private uint CalculateCheckSum(long length)
        {
            long numBytes = length + (length % 4);
            uint checkSum = 0;

            for (long i = 0; i < numBytes; i += PrimitiveSizes.ULong)
            {
                checkSum += stream.ReadULong();
                if (checkSum > 0xFFFFFFFF)
                {
                    checkSum = checkSum - 0xFFFFFFFF;
                }
            }

            return(checkSum);
        }
Пример #7
0
        /// <summary>
        ///     Reads the contents of the "os/2" table from the supplied stream
        ///     at the current position.
        /// </summary>
        /// <param name="reader"></param>
        protected internal override void Read(FontFileReader reader)
        {
            FontFileStream stream = reader.Stream;

            version       = stream.ReadUShort();
            avgCharWidth  = stream.ReadShort();
            usWeightClass = stream.ReadUShort();
            usWidthClass  = stream.ReadUShort();
            // According to the OpenType spec, bit 0 must be zero.
            fsType             = (ushort)(stream.ReadUShort() & ~1);
            subscriptXSize     = stream.ReadShort();
            subscriptYSize     = stream.ReadShort();
            subscriptXOffset   = stream.ReadShort();
            subscriptYOffset   = stream.ReadShort();
            superscriptXSize   = stream.ReadShort();
            superscriptYSize   = stream.ReadShort();
            superscriptXOffset = stream.ReadShort();
            superscriptYOffset = stream.ReadShort();
            strikeoutSize      = stream.ReadShort();
            strikeoutPosition  = stream.ReadShort();
            short familyClass = stream.ReadShort();

            classID    = (byte)(familyClass >> 8);
            subclassID = (byte)(familyClass & 255);
            stream.Read(panose, 0, panose.Length);
            unicodeRange1    = stream.ReadULong();
            unicodeRange2    = stream.ReadULong();
            unicodeRange3    = stream.ReadULong();
            unicodeRange4    = stream.ReadULong();
            vendorID[0]      = stream.ReadChar();
            vendorID[1]      = stream.ReadChar();
            vendorID[2]      = stream.ReadChar();
            vendorID[3]      = stream.ReadChar();
            fsSelection      = stream.ReadUShort();
            usFirstCharIndex = stream.ReadUShort();
            usLastCharIndex  = stream.ReadUShort();
            typoAscender     = stream.ReadShort();
            typoDescender    = stream.ReadShort();
            typoLineGap      = stream.ReadShort();
            usWinAscent      = stream.ReadUShort();
            usWinDescent     = stream.ReadUShort();
            codePageRange1   = stream.ReadULong();
            codePageRange2   = stream.ReadULong();
            sxHeight         = stream.ReadShort();
            sCapHeight       = stream.ReadShort();
            usDefaultChar    = stream.ReadUShort();
            usBreakChar      = stream.ReadUShort();
            usMaxContext     = stream.ReadUShort();
        }
        /// <summary>
        ///     Reads the contents of the "loca" table from the supplied stream
        ///     at the current position.
        /// </summary>
        /// <param name="reader"></param>
        protected internal override void Read(FontFileReader reader)
        {
            FontFileStream stream = reader.Stream;

            // Glyph offsets can be stored in either short of long format
            bool isShortFormat = reader.GetHeaderTable().IsShortFormat;

            // Number of glyphs including extra entry
            int glyphCount = reader.GetMaximumProfileTable().GlyphCount + 1;

            offsets = new ArrayList(glyphCount);
            for (int i = 0; i < glyphCount; i++)
            {
                offsets.Insert(i, (isShortFormat) ? (uint)(stream.ReadUShort() << 1) : stream.ReadULong());
            }
        }