Beispiel #1
0
        /// <summary>
        ///     Reads the contents of the "maxp" 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;

            // These two fields are common to versions 0.5 and 1.0
            versionNo = stream.ReadFixed();
            numGlyphs = stream.ReadUShort();

            // Version 1.0 of this table contains more data
            if (versionNo == 0x00010000)
            {
                maxPoints             = stream.ReadUShort();
                maxContours           = stream.ReadUShort();
                maxCompositePoints    = stream.ReadUShort();
                maxCompositeContours  = stream.ReadUShort();
                maxZones              = stream.ReadUShort();
                maxTwilightPoints     = stream.ReadUShort();
                maxStorage            = stream.ReadUShort();
                maxFunctionDefs       = stream.ReadUShort();
                maxInstructionDefs    = stream.ReadUShort();
                maxStackElements      = stream.ReadUShort();
                maxSizeOfInstructions = stream.ReadUShort();
                maxComponentElements  = stream.ReadUShort();
                maxComponentDepth     = stream.ReadUShort();
            }
        }
Beispiel #2
0
        protected internal override void Write(FontFileWriter writer)
        {
            FontFileStream stream = writer.Stream;

            // These two fields are common to versions 0.5 and 1.0
            stream.WriteFixed(versionNo);
            stream.WriteUShort(numGlyphs);

            // Version 1.0 of this table contains more data
            if (versionNo == 0x00010000)
            {
                stream.WriteUShort(maxPoints);
                stream.WriteUShort(maxContours);
                stream.WriteUShort(maxCompositePoints);
                stream.WriteUShort(maxCompositeContours);
                stream.WriteUShort(maxZones);
                stream.WriteUShort(maxTwilightPoints);
                stream.WriteUShort(maxStorage);
                stream.WriteUShort(maxFunctionDefs);
                stream.WriteUShort(maxInstructionDefs);
                stream.WriteUShort(maxStackElements);
                stream.WriteUShort(maxSizeOfInstructions);
                stream.WriteUShort(maxComponentElements);
                stream.WriteUShort(maxComponentDepth);
            }
        }
Beispiel #3
0
 /// <summary>
 ///     Writes a glyph description to the supplied stream.
 /// </summary>
 /// <param name="stream"></param>
 public void Write(FontFileStream stream)
 {
     if (glyphData != null && glyphData.Length > 0)
     {
         stream.Write(glyphData, 0, glyphData.Length);
     }
 }
Beispiel #4
0
        /// <summary>
        ///     Reads the contents of the "hmtx" 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;

            // Obtain number of horizonal metrics from 'hhea' table
            int numberOfHMetrics = reader.GetHorizontalHeaderTable().HMetricCount;

            // Obtain glyph count from 'maxp' table
            int numGlyphs = reader.GetMaximumProfileTable().GlyphCount;

            // Metrics might not be supplied for each glyph.  For example, if
            // the font is monospaced the hMetrics array will only contain a
            // single entry
            int metricsSize = (numGlyphs > numberOfHMetrics) ? numGlyphs : numberOfHMetrics;

            metrics = new List <HorizontalMetric>();//(metricsSize);

            for (int i = 0; i < numberOfHMetrics; i++)
            {
                metrics.Add(new HorizontalMetric(stream.ReadUShort(), stream.ReadShort()));
            }

            // Fill in missing widths
            if (numberOfHMetrics < metricsSize)
            {
                HorizontalMetric lastHMetric = metrics[metrics.Count - 1];
                for (int i = numberOfHMetrics; i < numGlyphs; i++)
                {
                    metrics.Add(
                        new HorizontalMetric(lastHMetric.AdvanceWidth, stream.ReadShort()));
                }
            }
        }
Beispiel #5
0
        /// <summary>
        ///     Writes the contents of the glyf table to the supplied stream.
        /// </summary>
        /// <param name="writer"></param>
        protected internal override void Write(FontFileWriter writer)
        {
            FontFileStream stream = writer.Stream;

            foreach (int subsetIndex in glyphDescriptions.Keys)
            {
                this[subsetIndex].Write(stream);
            }
        }
Beispiel #6
0
        /// <summary>
        ///     Class constructor.
        /// </summary>
        /// <param name="stream">Font data stream.</param>
        /// <param name="fontName">Name of a font in a TrueType collection.</param>
        public FontFileReader(MemoryStream stream, string fontName) {
            this.stream = new FontFileStream(stream);
            this.fontName = fontName;

            // Parse offset and directory tables
            ReadTableHeaders();

            // Caches commonly requested tables
            ReadRequiredTables();
        }
Beispiel #7
0
 /// <summary>
 ///     Creates a new instance of the <see cref="FontFileWriter"/> class
 ///     using <i>stream</i> as the underlying stream object.
 /// </summary>
 /// <param name="stream"></param>
 /// <exception cref="ArgumentException">
 ///     If <i>stream</i> is not writable.
 /// </exception>
 /// <exception cref="ArgumentNullException">
 ///     If <i>streamm</i> is a null reference.
 /// </exception>
 public FontFileWriter(Stream stream) {
     if (stream == null) {
         throw new ArgumentNullException("stream", "Supplied stream cannot be a null reference");
     }
     if (!stream.CanWrite) {
         throw new ArgumentException("The supplied stream is not writable", "stream");
     }
     this.stream = new FontFileStream(stream);
     this.tables = new Hashtable();
 }
Beispiel #8
0
        protected internal override void Write(FontFileWriter writer)
        {
            FontFileStream stream = writer.Stream;

            for (int i = 0; i < metrics.Count; i++)
            {
                HorizontalMetric metric = metrics[i];
                stream.WriteUShort(metric.AdvanceWidth);
                stream.WriteShort(metric.LeftSideBearing);
            }
        }
Beispiel #9
0
        /// <summary>
        ///     Class constructor.
        /// </summary>
        /// <param name="stream">Font data stream.</param>
        /// <param name="fontName">Name of a font in a TrueType collection.</param>
        public FontFileReader(MemoryStream stream, string fontName)
        {
            this.stream   = new FontFileStream(stream);
            this.fontName = fontName;

            // Parse offset and directory tables
            ReadTableHeaders();

            // Caches commonly requested tables
            ReadRequiredTables();
        }
Beispiel #10
0
 /// <summary>
 ///     Creates a new instance of the <see cref="FontFileWriter"/> class
 ///     using <i>stream</i> as the underlying stream object.
 /// </summary>
 /// <param name="stream"></param>
 /// <exception cref="ArgumentException">
 ///     If <i>stream</i> is not writable.
 /// </exception>
 /// <exception cref="ArgumentNullException">
 ///     If <i>streamm</i> is a null reference.
 /// </exception>
 public FontFileWriter(Stream stream)
 {
     if (stream == null)
     {
         throw new ArgumentNullException("stream", "Supplied stream cannot be a null reference");
     }
     if (!stream.CanWrite)
     {
         throw new ArgumentException("The supplied stream is not writable", "stream");
     }
     this.stream = new FontFileStream(stream);
     this.tables = new Hashtable();
 }
Beispiel #11
0
        /// <summary>
        ///     Reads the contents of the "kern" 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;

            // Skip version field
            stream.Skip(PrimitiveSizes.UShort);

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

            for (int i = 0; i < numTables; i++)
            {
                // Another pesky version field
                stream.Skip(PrimitiveSizes.UShort);

                // Length of the subtable, in bytes (including header).
                ushort length = stream.ReadUShort();

                // Type of information is contained in this table.
                ushort coverage = stream.ReadUShort();

                // Only interested in horiztonal kerning values in format 0
                if ((coverage & HoriztonalMask) == 1 &&
                    (coverage & MinimumMask) == 0 &&
                    ((coverage >> 8) == 0))
                {
                    // The number of kerning pairs in the table.
                    int numPairs = stream.ReadUShort();

                    hasKerningInfo = true;
                    pairs          = new KerningPairs(numPairs);

                    // Skip pointless shit
                    stream.Skip(3 * PrimitiveSizes.UShort);

                    for (int j = 0; j < numPairs; j++)
                    {
                        pairs.Add(
                            stream.ReadUShort(), // Left glyph index
                            stream.ReadUShort(), // Right glyph index
                            stream.ReadFWord()); // Kerning amount
                    }
                }
                else
                {
                    stream.Skip(length - 3 * PrimitiveSizes.UShort);
                }
            }
        }
Beispiel #12
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();
        }
Beispiel #13
0
        /// <summary>
        ///     Reads a string from the storage area beginning at <i>offset</i>
        ///     consisting of <i>length</i> bytes.  The returned string will be
        ///     converted using the Unicode encoding.
        /// </summary>
        /// <param name="stream">Big-endian font stream.</param>
        /// <param name="stringOffset">
        ///     The offset in bytes from the beginning of the string storage area.
        ///  </param>
        /// <param name="length">The length of the string in bytes.</param>
        /// <returns></returns>
        private string ReadString(FontFileStream stream, int stringOffset, int length)
        {
            // Set a restore point
            stream.SetRestorePoint();

            // Navigate to beginning of string
            stream.Position = Entry.Offset + storageOffset + stringOffset;

            // Read string data
            byte[] buffer = new byte[length];
            stream.Read(buffer, 0, length);
            stream.Restore();

            // Convert to a little-endian Unicode string
            return(Encoding.BigEndianUnicode.GetString(buffer));
        }
        /// <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());
            }
        }
Beispiel #15
0
        /// <summary>
        ///     Reads the contents of the "name" 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;

            // Ignore format selector field
            stream.ReadUShort();

            // Number of name records
            int numRecords = stream.ReadUShort();

            // Offset to start of string storage (from start of table).
            storageOffset = stream.ReadUShort();

            for (int i = 0; i < numRecords; i++)
            {
                int platformID   = stream.ReadUShort();
                int encodingID   = stream.ReadUShort();
                int languageID   = stream.ReadUShort();
                int nameID       = stream.ReadUShort();
                int length       = stream.ReadUShort();
                int stringOffset = stream.ReadUShort();

                // Only interested in name records for Microsoft platform,
                // Unicode encoding and US English language.
                if (platformID == MicrosoftPlatformID &&
                    (encodingID == SymbolEncoding || encodingID == UnicodeEncoding) &&
                    languageID == EnglishAmericanLanguage)
                {
                    switch (nameID)
                    {
                    case FamilyNameID:
                        familyName = ReadString(stream, stringOffset, length);
                        break;

                    case FullNameID:
                        fullName = ReadString(stream, stringOffset, length);
                        break;
                    }

                    if (familyName != String.Empty && fullName != String.Empty)
                    {
                        break;
                    }
                }
            }
        }
Beispiel #16
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();
        }
Beispiel #17
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);
            }
        }
Beispiel #18
0
        /// <summary>
        ///     Writes the contents of the head table to the supplied stream.
        /// </summary>
        /// <param name="writer"></param>
        protected internal override void Write(FontFileWriter writer)
        {
            FontFileStream stream = writer.Stream;

            stream.WriteFixed(versionNo);
            stream.WriteFixed(fontRevision);
            stream.WriteULong(0);
            stream.WriteULong(0x5F0F3CF5);
            stream.WriteUShort(flags);
            stream.WriteUShort(unitsPermEm);
            stream.WriteDateTime((long)(createDate - BaseDate).TotalSeconds);
            stream.WriteDateTime((long)(updateDate - BaseDate).TotalSeconds);
            stream.WriteShort(xMin);
            stream.WriteShort(yMin);
            stream.WriteShort(xMax);
            stream.WriteShort(yMax);
            stream.WriteUShort(macStyle);
            stream.WriteUShort(lowestRecPPEM);
            stream.WriteShort(fontDirectionHint);
            stream.WriteShort(1);
            stream.WriteShort(glyphDataFormat);
        }
Beispiel #19
0
        protected internal override void Write(FontFileWriter writer)
        {
            FontFileStream stream = writer.Stream;

            stream.WriteFixed(versionNo);
            stream.WriteFWord(ascender);
            stream.WriteFWord(decender);
            stream.WriteFWord(lineGap);
            stream.WriteUFWord(advanceWidthMax);
            stream.WriteFWord(minLeftSideBearing);
            stream.WriteFWord(minRightSideBearing);
            stream.WriteFWord(xMaxExtent);
            stream.WriteShort(caretSlopeRise);
            stream.WriteShort(caretSlopeRun);
            stream.WriteShort(caretOffset);
            stream.WriteShort(0);
            stream.WriteShort(0);
            stream.WriteShort(0);
            stream.WriteShort(0);
            stream.WriteShort(metricDataFormat);
            stream.WriteUShort(numberOfHMetrics);
        }
Beispiel #20
0
        /// <summary>
        ///     Reads the contents of the "hhea" 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();
            ascender            = stream.ReadFWord();
            decender            = stream.ReadFWord();
            lineGap             = stream.ReadFWord();
            advanceWidthMax     = stream.ReadUFWord();
            minLeftSideBearing  = stream.ReadFWord();
            minRightSideBearing = stream.ReadFWord();
            xMaxExtent          = stream.ReadFWord();
            caretSlopeRise      = stream.ReadShort();
            caretSlopeRun       = stream.ReadShort();
            caretOffset         = stream.ReadShort();
            stream.ReadShort();
            stream.ReadShort();
            stream.ReadShort();
            stream.ReadShort();
            metricDataFormat = stream.ReadShort();
            numberOfHMetrics = stream.ReadUShort();
        }
Beispiel #21
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();
        }
Beispiel #22
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);
            }
        }
Beispiel #23
0
 public GdiFontCreator(GdiDeviceContent dc) {
     this.dc = dc;
     this.header = new TrueTypeHeader();
     this.ms = new MemoryStream();
     this.fs = new FontFileStream(ms);
 }
Beispiel #24
0
 /// <summary>
 ///     Writes a glyph description to the supplied stream.
 /// </summary>
 /// <param name="stream"></param>
 public void Write(FontFileStream stream) {
     if (glyphData != null && glyphData.Length > 0) {
         stream.Write(glyphData, 0, glyphData.Length);
     }
 }
Beispiel #25
0
        /// <summary>
        ///     Reads a string from the storage area beginning at <i>offset</i>
        ///     consisting of <i>length</i> bytes.  The returned string will be 
        ///     converted using the Unicode encoding.
        /// </summary>
        /// <param name="stream">Big-endian font stream.</param>
        /// <param name="stringOffset">
        ///     The offset in bytes from the beginning of the string storage area.
        ///  </param>
        /// <param name="length">The length of the string in bytes.</param>
        /// <returns></returns>
        private string ReadString(FontFileStream stream, int stringOffset, int length) {
            // Set a restore point
            stream.SetRestorePoint();

            // Navigate to beginning of string
            stream.Position = Entry.Offset + storageOffset + stringOffset;

            // Read string data 
            byte[] buffer = new byte[length];
            stream.Read(buffer, 0, length);
            stream.Restore();

            // Convert to a little-endian Unicode string
            return Encoding.BigEndianUnicode.GetString(buffer);
        }