PDFSharp private fonts for azure 1.50
Asked Answered
C

2

5

I have downloaded and installed PDFSharp 1.5 and I am having trouble using private fonts. I have created in testing a pdf creator and it works great. When I load it into Azure it gives me the error can't load font. Did research and found out that they do not have any loaded fonts so I must use private font. I can only find examples of the older 1.3 version and the methods are changed to new ones. Can somebody show me a simple example using the new version of PDFSharp?

Thanks John

Cumulative answered 22/12, 2014 at 16:47 Comment(4)
The updated samples for version 1.50 have not been released yet - they should come in January. Version 1.50 is currently in beta. You can still get PDFsharp version 1.32 (source and NuGet packages).Ramsden
I have downloaded version 1.32 and version 1.3 and I am still confused. My confusion is that I see in all the examples that they use xprivateFontCollection pfc = new xPrivateFontCollection(); pfc.Add(XXXXXX); and I get pfc.AddFont(XXX) What version are they using to get just the pfc.Add so I can use the examples?Cumulative
ok figured out why I did not see the .Add because I was using the GDI instead of the WPF. Still does not work but I am atlease a little closer.Cumulative
PDFsharp includes a working sample that uses private fonts. You don't show any code so we cannot help you.Ramsden
H
8

This is for PdfSharp 1.5 beta3b. Here is a complete and fixed example based on links from other answers, and other questions - but for Arial.

Add the fonts you want to your project - in my example below I put Arial in MyProject\fonts\arial\arial.ttf etc. Set each font file as an embedded resource (properties -> build action).

Apply the font resolver using the static call like this:

MyFontResolver.Apply(); // Ensures it's only applied once

Here's the font resolver class:

class MyFontResolver : IFontResolver
{
    public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
    {
        // Ignore case of font names.
        var name = familyName.ToLower().TrimEnd('#');

        // Deal with the fonts we know.
        switch (name)
        {
            case "arial":
                if (isBold)
                {
                    if (isItalic)
                        return new FontResolverInfo("Arial#bi");
                    return new FontResolverInfo("Arial#b");
                }
                if (isItalic)
                    return new FontResolverInfo("Arial#i");
                return new FontResolverInfo("Arial#");
        }

        // 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 PlatformFontResolver.ResolveTypeface(familyName, isBold, isItalic);
    }

    public byte[] GetFont(string faceName)
    {
        switch (faceName)
        {
            case "Arial#":
                return LoadFontData("MyProject.fonts.arial.arial.ttf");;

            case "Arial#b":
                return LoadFontData("MyProject.fonts.arial.arialbd.ttf");;

            case "Arial#i":
                return LoadFontData("MyProject.fonts.arial.ariali.ttf");

            case "Arial#bi":
                return LoadFontData("MyProject.fonts.arial.arialbi.ttf");
        }

        return null;
    }

    /// <summary>
    /// Returns the specified font from an embedded resource.
    /// </summary>
    private byte[] LoadFontData(string name)
    {
        var assembly = Assembly.GetExecutingAssembly();

        // Test code to find the names of embedded fonts - put a watch on "ourResources"
        //var ourResources = assembly.GetManifestResourceNames();

        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;
        }
    }

    internal static MyFontResolver OurGlobalFontResolver = null;

    /// <summary>
    /// Ensure the font resolver is only applied once (or an exception is thrown)
    /// </summary>
    internal static void Apply()
    {
        if (OurGlobalFontResolver == null || GlobalFontSettings.FontResolver == null)
        {
            if (OurGlobalFontResolver == null)
                OurGlobalFontResolver = new MyFontResolver();

            GlobalFontSettings.FontResolver = OurGlobalFontResolver;
        }
    }
}
Honshu answered 24/5, 2016 at 9:15 Comment(4)
That's essentially the code from the forum post linked in the other answer (without any credits).Ramsden
You saved my day.Moureaux
I having this error: 'No resource with name Psidar.WebAPI.Content.Fonts.arial.arial.ttf'Address
@Address did you embed the resource as described? If so, you want to find out what your resources are named in your project - I've done this before by querying the resource names in the debugger (again - see the answer particularly "assembly.GetManifestResourceNames()".Honshu
R
1

When using the WPF build of PDFsharp 1.50, you can implement IFontResolver in a class of your own and assign an instance of that class to GlobalFontSettings.FontResolver.

PDFsharp 1.50 is still under construction. When it is final it should include FontResolver samples.

Sample code can be found on the PDFsharp forum:
http://forum.pdfsharp.net/viewtopic.php?p=8961#p8961

Note: The XPrivateFontCollection should work with both the GDI and the WPF build. You have to use XPrivateFontCollection if you use the DocumentPreview and want to see your fonts there.
IFontResolver is probably the best choice for processes without user interface (e.g. PDF generation on web servers), but it does not work with the GDI build.

Ramsden answered 9/9, 2015 at 21:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.