/// <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(); } }
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); } }
/// <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); } }
/// <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())); } } }
/// <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); } }
/// <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(); }
/// <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(); }
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); } }
/// <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); } } }
/// <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 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()); } }
/// <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; } } } }
/// <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(); }
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); } }
/// <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); }
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); }
/// <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(); }
/// <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(); }
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); } }
public GdiFontCreator(GdiDeviceContent dc) { this.dc = dc; this.header = new TrueTypeHeader(); this.ms = new MemoryStream(); this.fs = new FontFileStream(ms); }
/// <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); }