public HRESULT GetCurrentFontFile(out IDWriteFontFile fontFile) { DWriteFontFile file; try { file = _enumerator.Current; } catch (Exception e) { ComError.SetError(e.GetAllMessages()); fontFile = null; return(HRESULTS.DISP_E_EXCEPTION); } if (file is DWriteFontStreamFile sf && sf.FilePath != null) { using (var mem = new ComMemory(Marshal.SizeOf <long>())) { if (sf.LastWriteTime.HasValue) { Marshal.WriteInt64(mem.Pointer, sf.LastWriteTime.Value.ToFileTime()); } var ptr = sf.LastWriteTime.HasValue ? mem.Pointer : IntPtr.Zero; return(_factory.CreateFontFileReference(sf.FilePath, ptr, out fontFile)); } } var stream = new FontFileStream(file); _loader.AddStream(stream); return(_factory.CreateCustomFontFileReference(stream.Key, (uint)stream.KeySize, _loader, out fontFile)); }
public GdiFontCreator(GdiDeviceContent dc) { this.dc = dc; this.header = new TrueTypeHeader(); this.ms = new MemoryStream(); this.fs = new FontFileStream(ms); }
/// <summary> /// Reads a glyph description from the specified offset. /// </summary> public Glyph ReadGlyph(int glyphIndex) { FontFileStream stream = reader.Stream; // Offset from beginning of font file uint fileOffset = glyfEntry.Offset + loca[glyphIndex]; long length = GetGlyphLength(glyphIndex); Glyph glyph = new Glyph(reader.IndexMappings.Map(glyphIndex)); if (length != 0) { byte[] glyphData = new byte[length]; // Read glyph description into byte array stream.Position = fileOffset; stream.Read(glyphData, 0, glyphData.Length); glyph.SetGlyphData(glyphData); FontFileStream glyphStream = new FontFileStream(glyphData); // This fields dictates whether the glyph is a simple or composite glyph bool compositeGlyph = (glyphStream.ReadShort() < 0); // Skip font bounding box glyphStream.Skip(PrimitiveSizes.Short*4); if (compositeGlyph) { ReadCompositeGlyph(glyphStream, glyph); } } return glyph; }
/// <summary> /// Populate the <i>composites</i>IList containing all child glyphs /// that this glyph uses. /// </summary> /// <remarks> /// The <i>stream</i> parameter must be positioned 10 bytes from /// the beginning of the glyph description, i.e. the flags field. /// </remarks> /// <param name="stream"></param> private void ReadCompositeGlyph(FontFileStream stream, Glyph glyph) { bool moreComposites = true; while (moreComposites) { short flags = stream.ReadShort(); long offset = stream.Position; int subsetIndex = reader.IndexMappings.Map(stream.ReadShort()); glyph.AddChild(subsetIndex); // While we're here, remap the child glyph index stream.Position = stream.Position - PrimitiveSizes.Short; stream.WriteShort(subsetIndex); // The following code is based on the C pseudo code supplied // in the glyf table specification. int skipBytes = 0; if ((flags & BitMasks.Arg1And2AreWords) > 0) { skipBytes = PrimitiveSizes.Short*2; } else { skipBytes = PrimitiveSizes.UShort; } if ((flags & BitMasks.WeHaveAScale) > 0) { // Skip scale skipBytes = PrimitiveSizes.F2DOT14; } else if ((flags & BitMasks.WeHaveAnXAndYScale) > 0) { // Skip xscale and yscale skipBytes = PrimitiveSizes.F2DOT14*2; } else if ((flags & BitMasks.WeHaveATwoByTwo) > 0) { // Skip xscale, scale01, scale10 and yscale skipBytes = PrimitiveSizes.F2DOT14*4; } // Glyph instructions if ((flags & BitMasks.WeHaveInstructions) > 0) { skipBytes = PrimitiveSizes.Byte*stream.ReadUShort(); } if ((flags & BitMasks.MoreComponents) > 0) { moreComposites = true; } else { moreComposites = false; } stream.Skip(skipBytes); } }
/// <summary> /// Reads a glyph description from the specified offset. /// </summary> public Glyph ReadGlyph(int glyphIndex) { FontFileStream stream = reader.Stream; // Offset from beginning of font file uint fileOffset = glyfEntry.Offset + loca[glyphIndex]; long length = GetGlyphLength(glyphIndex); Glyph glyph = new Glyph(reader.IndexMappings.Map(glyphIndex)); if (length != 0) { byte[] glyphData = new byte[length]; // Read glyph description into byte array stream.Position = fileOffset; stream.Read(glyphData, 0, glyphData.Length); glyph.SetGlyphData(glyphData); FontFileStream glyphStream = new FontFileStream(glyphData); // This fields dictates whether the glyph is a simple or composite glyph bool compositeGlyph = (glyphStream.ReadShort() < 0); // Skip font bounding box glyphStream.Skip(PrimitiveSizes.Short * 4); if (compositeGlyph) { ReadCompositeGlyph(glyphStream, glyph); } } return(glyph); }
/// <summary> /// Return a pointer to the unmanaged version of this callback. /// </summary> /// <param name="callback">The callback.</param> /// <returns>A pointer to a shadow c++ callback</returns> public static IntPtr ToIntPtr(FontFileStream callback) { return(ToCallbackPtr <FontFileStream>(callback)); }
/// <summary> /// Return a pointer to the unmanaged version of this callback. /// </summary> /// <param name="callback">The callback.</param> /// <returns>A pointer to a shadow c++ callback</returns> public static IntPtr ToIntPtr(FontFileStream callback) { return ToCallbackPtr<FontFileStream>(callback); }
public void AddStream(FontFileStream stream) { _streams[_index] = stream; Marshal.WriteInt32(stream.Key, _index); _index++; }
/// <summary> /// Populate the <i>composites</i>IList containing all child glyphs /// that this glyph uses. /// </summary> /// <remarks> /// The <i>stream</i> parameter must be positioned 10 bytes from /// the beginning of the glyph description, i.e. the flags field. /// </remarks> /// <param name="stream"></param> private void ReadCompositeGlyph(FontFileStream stream, Glyph glyph) { bool moreComposites = true; while (moreComposites) { short flags = stream.ReadShort(); long offset = stream.Position; int subsetIndex = reader.IndexMappings.Map(stream.ReadShort()); glyph.AddChild(subsetIndex); // While we're here, remap the child glyph index stream.Position = stream.Position - PrimitiveSizes.Short; stream.WriteShort(subsetIndex); // The following code is based on the C pseudo code supplied // in the glyf table specification. int skipBytes = 0; if ((flags & BitMasks.Arg1And2AreWords) > 0) { skipBytes = PrimitiveSizes.Short * 2; } else { skipBytes = PrimitiveSizes.UShort; } if ((flags & BitMasks.WeHaveAScale) > 0) { // Skip scale skipBytes = PrimitiveSizes.F2DOT14; } else if ((flags & BitMasks.WeHaveAnXAndYScale) > 0) { // Skip xscale and yscale skipBytes = PrimitiveSizes.F2DOT14 * 2; } else if ((flags & BitMasks.WeHaveATwoByTwo) > 0) { // Skip xscale, scale01, scale10 and yscale skipBytes = PrimitiveSizes.F2DOT14 * 4; } // Glyph instructions if ((flags & BitMasks.WeHaveInstructions) > 0) { skipBytes = PrimitiveSizes.Byte * stream.ReadUShort(); } if ((flags & BitMasks.MoreComponents) > 0) { moreComposites = true; } else { moreComposites = false; } stream.Skip(skipBytes); } }