PDFsharp 1.50 implements a new mechanism for private fonts (fonts that are not installed on the system). You simply implement IFontResolver and assign this to a global property:
Code:
// That's all it takes to register your own fontresolver
GlobalFontSettings.FontResolver = new DemoFontResolver();
The interesting part is IFontResolver and how you implement it.
The IFontResolver interface requires two methods: ResolveTypeface and GetFont.
I derived my class DemoFontResolver from PDFsharp’s class FontResolverBase. For this demo I downloaded two free font: Janitor (regular only) and Ubuntu (using regular, italic, bold, bold italic).
Here is the ResolveTypeface code:
Code:
public override FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
{
// Ignore case of font names.
var name = familyName.ToLower();
// Deal with the fonts we know.
switch (name)
{
case "ubuntu":
if (isBold)
{
if (isItalic)
return new FontResolverInfo("Ubuntu#bi");
return new FontResolverInfo("Ubuntu#b");
}
if (isItalic)
return new FontResolverInfo("Ubuntu#i");
return new FontResolverInfo("Ubuntu#");
case "janitor":
return new FontResolverInfo("Janitor#");
}
// We pass all other font requests to the default handler.
// When running on a web server without sufficient permission, you can return a default font at this stage.
return base.ResolveTypeface(familyName, isBold, isItalic);
}
The other method, GetFont, must return the TTF file in a byte array.
My implementation of GetFont looks like this:
Code:
/// <summary>
/// Return the font data for the fonts.
/// </summary>
public override byte[] GetFont(string faceName)
{
switch (faceName)
{
case "Janitor#":
return FontHelper.Janitor;
case "Ubuntu#":
return FontHelper.Ubuntu;
case "Ubuntu#b":
return FontHelper.UbuntuBold;
case "Ubuntu#i":
return FontHelper.UbuntuItalic;
case "Ubuntu#bi":
return FontHelper.UbuntuBoldItalic;
}
return base.GetFont(faceName);
}
The code that does the work of retrieving the fonts is hidden in a helper class. I added the fonts to the project using the "Embedded Resource" compile type. I then used the free dotPeek tool from JetBrains to find the names of the embedded resources.
Code:
/// <summary>
/// Helper class that reads font data from embedded resources.
/// </summary>
public static class FontHelper
{
public static byte[] Janitor
{
get { return LoadFontData("MyFontResolver.fonts.janitor.Janitor.ttf"); }
}
// Tip: I used JetBrains dotPeek to find the names of the resources (just look how dots in folder names are encoded).
// Make sure the fonts have compile type "Embedded Resource". Names are case-sensitive.
public static byte[] Ubuntu
{
get { return LoadFontData("MyFontResolver.fonts.ubuntufontfamily0._80.Ubuntu-R.ttf"); }
}
public static byte[] UbuntuBold
{
get { return LoadFontData("MyFontResolver.fonts.ubuntufontfamily0._80.Ubuntu-B.ttf"); }
}
public static byte[] UbuntuItalic
{
get { return LoadFontData("MyFontResolver.fonts.ubuntufontfamily0._80.Ubuntu-RI.ttf"); }
}
public static byte[] UbuntuBoldItalic
{
get { return LoadFontData("MyFontResolver.fonts.ubuntufontfamily0._80.Ubuntu-BI.ttf"); }
}
/// <summary>
/// Returns the specified font from an embedded resource.
/// </summary>
static byte[] LoadFontData(string name)
{
var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(name))
{
if (stream == null)
throw new ArgumentException("No resource with name " + name);
int count = (int)stream.Length;
byte[] data = new byte[count];
stream.Read(data, 0, count);
return data;
}
}
}
You can download the complete demo application as a ZIP file (about 2 MiB in size due to the embedded fonts).
http://pdfsharp.th-soft.com/pdfsharp/do ... erDemo.zipThe font resolver applies to PDFsharp and it will also be used when you create PDF files from MigraDoc.
The ZIP file contains two console applications, one demo for PDFsharp and one demo for MigraDoc.
The solution uses PDFsharp 1.50 beta from NuGet. In Visual Studio (I used the free Community Edition Visual Studio 2013) in the <strong>Solution Explorer</strong>, select <strong>Manage NuGet Packages for Solution</strong> from the context menu of the solution.
Sample also discussed in my blog:
http://developer.th-soft.com/developer/?p=11A generic font resolver that implements IFontResolver and simplifies usage for inexperienced users can be found here:
viewtopic.php?p=9576#p9576