【问题标题】:Use font from a compressed folder使用压缩文件夹中的字体
【发布时间】:2015-01-16 01:13:03
【问题描述】:

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

我正在使用 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 加载字体系列,但我无法让它工作。

【问题讨论】:

  • 是否可以将字体的路径指定为c:\folder\file.zip\fontname.ttf
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • PrivateFontCollection.AddMemoryFont 可能对你有用,我以前从未尝试过,但它可能会完成这项工作
  • 对不起约翰,我不会再放标签了。
  • Red Serpent,我在其他地方读到 PrivateFontCollection 不能与 WPF 一起使用?

标签: c# wpf


【解决方案1】:

你是对的,你可以使用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);
}

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

【讨论】:

  • 感谢 Il Vic 的尝试,但我刚刚尝试了您的建议,但 Arial 显示在屏幕上,当我检查 FontFamily 中的 FamilyNames 时,我只有一个条目用于 en-us:Arial .
  • 确实,我在 WPF 窗口中使用了我的解决方案,我可以保证它有效。如果您愿意,我可以发布我的整个代码。无论如何要注意你的 .ttf 文件。如果它包含例如粗体字体,您的 TextBlock 必须将其属性 FontWeight 设置为 Bold,否则您只会看到系统默认字体(可能是 Arial?)。
  • 对不起,Il Vic,你完全正确。我需要将 Regular 添加到字体名称的末尾,然后它就起作用了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 2016-10-17
  • 1970-01-01
  • 2010-09-05
  • 2013-03-09
  • 1970-01-01
相关资源
最近更新 更多