从TTF字体流创建GlyphTypeface对象

本文关键字:GlyphTypeface 对象 创建 TTF 字体 | 更新日期: 2023-09-27 18:13:13

我知道如何通过给出绝对路径来使用位于磁盘上的字体文件创建GlyphTypeface对象。

  GlyphTypeface glyphTypeface = new GlyphTypeface(new Uri(@"C:'SomeTrueTypeFont.ttf", UriKind.Absolute));

我无法弄清楚如何使用存储在内存流中的字体文件创建相同的GlyphTypeface对象。由于权限等问题,我的应用程序无法将字体流保存到磁盘。如果有人能告诉我该怎么做,我将不胜感激。

从TTF字体流创建GlyphTypeface对象

可以从(流的副本)创建GlyphTypeface

它的实现方式与使用WPF应用程序打包字体类似。

你必须复制font流到一个内存包的PackagePart,它被添加到PackageStore中。关键部分是获取传递给GlyphTypeface构造函数的正确Uri。

下面是一个内存包的可能实现:

sealed class MemoryPackage : IDisposable
{
    private static int packageCounter;
    private readonly Uri packageUri = new Uri("payload://memorypackage" + Interlocked.Increment(ref packageCounter), UriKind.Absolute);
    private readonly Package package = Package.Open(new MemoryStream(), FileMode.Create);
    private int partCounter;
    public MemoryPackage()
    {
        PackageStore.AddPackage(this.packageUri, this.package);
    }
    public Uri CreatePart(Stream stream)
    {
        return this.CreatePart(stream, "application/octet-stream");
    }
    public Uri CreatePart(Stream stream, string contentType)
    {
        var partUri = new Uri("/stream" + (++this.partCounter), UriKind.Relative);
        var part = this.package.CreatePart(partUri, contentType);
        using (var partStream = part.GetStream())
            CopyStream(stream, partStream);
        // Each packUri must be globally unique because WPF might perform some caching based on it.
        return PackUriHelper.Create(this.packageUri, partUri);
    }
    public void DeletePart(Uri packUri)
    {
        this.package.DeletePart(PackUriHelper.GetPartUri(packUri));
    }
    public void Dispose()
    {
        PackageStore.RemovePackage(this.packageUri);
        this.package.Close();
    }
    private static void CopyStream(Stream source, Stream destination)
    {
        const int bufferSize = 4096;
        byte[] buffer = new byte[bufferSize];
        int read;
        while ((read = source.Read(buffer, 0, buffer.Length)) != 0)
            destination.Write(buffer, 0, read);
    }
}

下面是一个示例代码,如何使用它来创建GlyphTypeface从一个(副本)MemoryStream:

GlyphTypeface glyphTypeface;
using (var memoryPackage = new MemoryPackage())
{
    using (var fontStream = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "font"))))
    {
        var typefaceSource = memoryPackage.CreatePart(fontStream);
        glyphTypeface = new GlyphTypeface(typefaceSource);
        memoryPackage.DeletePart(typefaceSource);
    }
}
var familyName = glyphTypeface.FamilyNames[CultureInfo.GetCultureInfo("en-US")];
Console.WriteLine(familyName);

我认为这不可能。WPF卧底使用本地IDWriteFontFile接口,该接口依赖于物理文件。