Reputation: 492
I know how to create a GlyphTypeface object using the font file located on the disk by giving absolute path.
GlyphTypeface glyphTypeface = new GlyphTypeface(new Uri(@"C:\SomeTrueTypeFont.ttf", UriKind.Absolute));
I am not able to figure out how to create the same GlyphTypeface object using font file which is stored in memory stream. My application can't save the font stream to disk due to issues like permission etc. I appreciate if someone could suggest me about how to go about it.
Upvotes: 3
Views: 3228
Reputation: 4606
It is possible to create GlyphTypeface from a (copy of a) Stream.
It is accomplished in a similar way as is Packaging Fonts with WPF Applications.
You must copy font stream to a PackagePart of an in-memory Package which is added to the PackageStore. The crucial part is obtaining the correct Uri which is passed to GlyphTypeface constructor.
Here is one possible implementation of an in-memory package:
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);
}
}
And here is a sample code how to use it to create GlyphTypeface from a (copy of a) 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);
Upvotes: 8
Reputation: 138960
I don't think it's possible. WPF undercover uses the native IDWriteFontFile interface which relies on physical files.
Upvotes: 0