使用压缩文件夹中的字体

Use font from a compressed folder

我有一个压缩文件夹,其中包含我需要打开和使用的字体(以及其他内容)。我知道我可以将字体提取到一个临时文件夹并以这种方式使用它,但我宁愿找到一个解决方案以尽可能将其保存在内存中。

我正在使用 System.IO.Compression 将字体作为流获取,但从那时起我有点卡住了!

using (ZipArchive zipArchive = ZipFile.Open(filelocation, ZipArchiveMode.Update))
{
    ZipArchiveEntry fontEntry = zipArchive.Entries.FirstOrDefault(ze => ze.Name.EndsWith("ttf"));
    if (fontEntry != null)
    {
        Stream fontStream = fontEntry.Open();
        // I need a TextBlock to somehow use this stream as the FontFamily
    }
}

我查看了 System.IO.Packaging 来打包流,然后尝试使用包 URI 加载字体系列,但我无法让它工作。

你说得对,可以用System.IO.Packaging。假设"textBlock"是你要使用的控件:

using (ZipArchive zipArchive = ZipFile.Open(filelocation, ZipArchiveMode.Update))
{
    ZipArchiveEntry fontEntry = zipArchive.Entries.FirstOrDefault(ze => ze.Name.EndsWith("ttf"));
    if (fontEntry != null)
    {
        Stream fontStream = fontEntry.Open();
        Uri uri = CreateMemoryUriFromStream(fileStream);
        textBlock.FontFamily = new FontFamily(uri, "myFont");
    }
}

这里是CreateMemoryUriFromStream方法

public static Uri CreateMemoryUriFromStream(Stream stream)
{
    MemoryStream memoryStream = new MemoryStream();
    byte[] streamData = new byte[stream.Length];
    stream.Read(streamData, 0, streamData.Length);

    Package pack = Package.Open(memoryStream, FileMode.Create, FileAccess.ReadWrite);
    Uri packageUri = new Uri("memory:");

    PackageStore.AddPackage(packageUri, pack);

    Uri packagePartUri = new Uri("/packagePart", UriKind.Relative);
    PackagePart packagePart = pack.CreatePart(packagePartUri, "application/font");

    Stream packageStream = packagePart.GetStream();
    packageStream.Write(streamData, 0, streamData.Length);

    return PackUriHelper.Create(packageUri, packagePart.Uri);
}

所以不需要使用临时文件夹!