从TTF字体流创建GlyphTypeface对象
本文关键字:GlyphTypeface 对象 创建 TTF 字体 | 更新日期: 2023-09-27 18:13:13
我知道如何通过给出绝对路径来使用位于磁盘上的字体文件创建GlyphTypeface对象。
GlyphTypeface glyphTypeface = new GlyphTypeface(new Uri(@"C:'SomeTrueTypeFont.ttf", UriKind.Absolute));
我无法弄清楚如何使用存储在内存流中的字体文件创建相同的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接口,该接口依赖于物理文件。