PDFSharp WPF 1.32 private fonts will not work with Azure Blob storage
Asked Answered
R

1

1

I have some code that adds text using a private font to a PDF file using PDFSharp. This works successfully if the font is located on the local file system but does not work when I provide it with a url to a font stored on a Azure blog storage. I also tried using a google font on their CDN, which also didn't work. Is there some problem with loading fonts from a web url?

The sample code is below. Note that I have solved the CORS issue on Azure blob storage so it isn't that.

private readonly XPdfFontOptions _fontOptions = 
    new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
private static readonly XPrivateFontCollection PrivateFontCollection =
    XPrivateFontCollection.Global;

[Test]
public async Task Test01RawPdfSharp()
{
    //SETUP 
    var account = "labelapptest";
    var fs = new FileStore(account);
    var fontUrl =
        "http://labelapptest.blob.core.windows.net/designernospamcom/justyna sokolowska - erazm-regular.otf";
    var pdfUrl =
        "https://labelapptest.blob.core.windows.net/label-highrez-blank/blank-label00001.pdf";
    var fontFamily = "Erazm Regular";
    var localFontPath = Path.Combine(TestFileHelpers.GetTestDataFileDirectory(@"\TestFonts"),
        "Justyna Sokolowska - Erazm-Regular.otf");

    //ATTEMPT
    var sFontFamilyname = "./#" + fontFamily;
    var uri = new Uri(fontUrl);
    PrivateFontCollection.Add(uri, sFontFamilyname);

    var readDirStatus = await fs.GetDirHandleAsync(FileStorageTypes.LabelHighRezBlank);
    using (var readStream = new MemoryStream())
    {
        await readDirStatus.Result.ReadFileAsync(readStream, pdfUrl);
        readStream.Seek(0, SeekOrigin.Begin);
        var document = PdfReader.Open(readStream);
        var gfx = XGraphics.FromPdfPage(document.Pages[0]);

        var font = new XFont(fontFamily, new XUnit(12, XGraphicsUnit.Point), XFontStyle.Regular, _fontOptions);
        var brush = new XSolidBrush(XColor.FromKnownColor(XKnownColor.Red));
        gfx.DrawString("Hello world", font, brush, 10, 10);
    }
    //VERIFY
}    

In the example above if I use the fontUrl in the uri for adding the font then the code fails at the line where the XFont is created (6th from bottom). If on the other hand I use the localFontPath then it works.

The error is: Cannot get a matching glyph typeface for font 'Erazm Regular' at line at PdfSharp.Drawing.XFont.Initialize() in XFont.cs: line 234.

NOTE: I have downloaded and edited the 1.32 PDFSharp code to replace the Debugger.Break statement with an exception at this point. The NuGet version has a Debugger.Break which causes a hang in released code - see my SO question about that issue.

UPDATE

In the end I swapped to PDFsharp WPF 1.50 beta as its font handling is much better and I wasn't getting anywhere with the problem of loading a font via a http link. Seems to be working really well.

Rainproof answered 8/4, 2015 at 8:15 Comment(0)
Q
2

The call to PrivateFontCollection.Add(uri, sFontFamilyname) just passes the URI to new System.Windows.Media.FontFamily(baseUri, familyName). I don't know whether Media.FontFamily can handle URIs for Azure storage.

We use the PrivateFontCollection with fonts from resources - and loading fonts from resources is the only sample given in the help for FontFamily Constructor (Uri, String). That's the type of URI that is known to work with PDFsharp.

The syntax for FontFamily Constructor (Uri, String) is somewhat cryptic and the smallest error will lead to "not found".

Qulllon answered 8/4, 2015 at 8:34 Comment(1)
Hi @PDFsharp Team. Thanks for your comments. I decided in the end to move to PDFSharp WPF 1.50 Beta, especially after seeing the information by ThomasH on the new font resolver. Seems to be working out so far.Rainproof

© 2022 - 2024 — McMap. All rights reserved.