从TTF字体流创建GlyphTypeface对象

时间:2014-07-16 07:39:07

标签: c# .net wpf

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

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

我无法弄清楚如何使用存储在内存流中的字体文件创建相同的 GlyphTypeface 对象。由于许可等问题,我的应用程序无法将字体流保存到磁盘。如果有人可以建议我如何处理它,我会很感激。

2 个答案:

答案 0 :(得分:8)

可以从GlyphTypeface的副本创建Stream

它以与Packaging Fonts with WPF Applications类似的方式完成。

您必须将字体流复制到添加到PackagePart的内存PackagePackageStore。关键部分是获得传递给Uri的正确GlyphTypeface constructor

以下是内存包的一种可能实现:

PU:BL:IC:IP:80

以下是一个示例代码,如何使用它来创建GlyphTypeface({3}}的副本:

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);
    }
}

答案 1 :(得分:0)

我认为不可能。 WPF undercover使用依赖于物理文件的本地IDWriteFontFile接口。