Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The layout of component 'text1' failed. The initialization of the fonts failed. Could not load the system fonts #77

Open
pedrommuller opened this issue May 20, 2022 · 3 comments

Comments

@pedrommuller
Copy link

I'm getting this issue on a mac OS every time I want to generate a pdf I understand that might be an issue with some dependencies I already have installed mono-libgdiplus

any guidance for this?

@Brandejs
Copy link

Brandejs commented Mar 9, 2023

Hi im run into the same issue on Mac with the M2 chip

https://scrybercore.readthedocs.io/en/latest/libgdiplus.html?highlight=mac

I did following

brew install mono-libgdiplus
sudo ln -s /opt/homebrew/Cellar/mono-libgdiplus/6.1_1/lib/libgdiplus.dylib /usr/local/share/dotnet/shared/Microsoft.NETCore.App/7.0.3  

and stuck on this.
doc.SaveAsPDF(targetFilename, FileMode.OpenOrCreate);

Scryber.PDFLayoutException: The layout of component 'text1' failed. The initialization of the fonts failed. Could not load the system fonts

Scryber.PDFLayoutException
The layout of component 'text1' failed. The initialization of the fonts failed. Could not load the system fonts
   at Scryber.Layout.LayoutEngineBase.DoLayoutTextComponent(IPDFTextComponent text, Style style)
   at Scryber.Layout.LayoutEngineBase.DoLayoutAChild(IPDFComponent comp, Style full)
   at Scryber.Layout.LayoutEngineBase.DoLayoutAChild(Component comp)
   at Scryber.Layout.LayoutEngineBase.DoLayoutChildren(ComponentList children)
   at Scryber.Layout.LayoutEngineBase.DoLayoutChildren()
   at Scryber.Layout.LayoutEnginePanel.DoLayoutBlockComponent(PDFPositionOptions position, PDFColumnOptions columnOptions)
   at Scryber.Layout.LayoutEnginePanel.DoLayoutComponent()
   at Scryber.Layout.LayoutEngineHeading.DoLayoutComponent()
   at Scryber.Layout.LayoutEngineBase.Layout(PDFLayoutContext context, Style fullstyle)
   at Scryber.Layout.LayoutEngineBase.DoLayoutViewPortComponent(IPDFViewPortComponent viewPort, Style style)
   at Scryber.Layout.LayoutEngineBase.DoLayoutAChild(IPDFComponent comp, Style full)
   at Scryber.Layout.LayoutEngineBase.DoLayoutAChild(Component comp)
   at Scryber.Layout.LayoutEngineBase.DoLayoutChildren(ComponentList children)
   at Scryber.Layout.LayoutEngineBase.DoLayoutChildren()
   at Scryber.Layout.LayoutEnginePage.LayoutPageContent()
   at Scryber.Layout.LayoutEnginePage.DoLayoutComponent()
   at Scryber.Layout.LayoutEngineSection.DoLayoutComponent()
   at Scryber.Layout.LayoutEngineBase.Layout(PDFLayoutContext context, Style fullstyle)
   at Scryber.Layout.LayoutEngineDocument.LayoutPageWithStyle(PageBase pg, Style full)
   at Scryber.Layout.LayoutEngineDocument.LayoutPage(PageBase pg)
   at Scryber.Layout.LayoutEngineDocument.LayoutAllPages()
   at Scryber.Layout.LayoutEngineDocument.DoLayoutComponent()
   at Scryber.Layout.LayoutEngineBase.Layout(PDFLayoutContext context, Style fullstyle)
   at Scryber.Components.Document.RenderToPDF(PDFRenderContext context, PDFWriter writer)
   at Scryber.Components.Document.RenderToPDF(Stream tostream)
   at Scryber.Components.Document.RenderTo(Stream tostream, OutputFormat format)
   at Scryber.Components.Document.SaveAs(Stream stream, Boolean bind, OutputFormat format)
   at Scryber.Components.Document.SaveAsPDF(String path, FileMode mode, Boolean bind)
   at Scryber.Components.Document.SaveAsPDF(String path, FileMode mode)
  ...
   at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass48_1.<<InvokeTestMethodAsync>b__1>d.MoveNext() in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\Runners\TestInvoker.cs:line 264
--- End of stack trace from previous location ---
   at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\ExecutionTimer.cs:line 48
   at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in C:\Dev\xunit\xunit\src\xunit.core\Sdk\ExceptionAggregator.cs:line 90

System.Configuration.ConfigurationErrorsException
The initialization of the fonts failed. Could not load the system fonts
   at Scryber.Drawing.PDFFontFactory.AssertInitialized()
   at Scryber.Drawing.PDFFontFactory.GetFontDefinition(String family, FontStyle style, Boolean throwNotFound)
   at Scryber.Components.Document.GetFontResource(PDFFont font, Boolean create, Boolean throwOnNotFound)
   at Scryber.Layout.LayoutEngineText.Layout(PDFLayoutContext context, Style fullstyle)
   at Scryber.Layout.LayoutEngineBase.DoLayoutTextComponent(IPDFTextComponent text, Style style)

System.Exception
Could not load the system fonts
   at Scryber.Drawing.PDFFontFactory.LoadSystemFonts()
   at Scryber.Drawing.PDFFontFactory.AssertInitialized()

System.Collections.Generic.KeyNotFoundException
The given key 'OS/2' was not present in the dictionary.
   at System.Collections.ObjectModel.KeyedCollection`2.get_Item(TKey key)
   at Scryber.OpenType.TTFTableFactory.ReadDirectory(String tname, TTFDirectoryList list, BigEndianReader reader)
   at Scryber.OpenType.TTFRef.DoLoadRef(BigEndianReader reader, String fullpath)
   at Scryber.OpenType.TTFRef.LoadCollectionRefs(BigEndianReader reader, String fullPath)
   at Scryber.OpenType.TTFRef.LoadCollectionRefs(Stream stream, String fullPath)
   at Scryber.OpenType.TTFRef.LoadCollectionRefs(FileInfo fi)
   at Scryber.OpenType.TTFRef.LoadRefs(DirectoryInfo dir)
   at Scryber.Drawing.PDFFontFactory.LoadSystemFonts()

Did you find any solution?

@tristaniels
Copy link

I believe this happens when two threads attempt to call the SafeAsPDF() method at the same time. To fix I wrap the call in a lock statement.

public class MyService
{
    private static readonly object LockObject = new();

    public byte[] CreatePdf()
    {
        var doc = // Code to setup the document.
        var output = // Code to setup the output.

        lock (LockObject)
        {
           doc.SaveAsPDF(output);
        }

        // Code to return.
    }
}

@richard-scryber
Copy link
Owner

Thanks Tristan, Jan - The initialisation of the fonts is wrapped in a thread lock, so should be ok. However it will re-throw any error caused during initialisation.

It is possible to remove the use of system fonts using the configuration options if they are not accessible to the running process.
Depending on your set-up something along these lines should exclude the look up of system fonts.

From the application configuration file...

{
    "Scryber": {
         "Fonts" : {
             "UseSystemFonts": "False",
             "Register" : [
                {
                     "Family": "Segoe UI",
                     "File": "Mocks/Fonts/segoeui.ttf"
                } ]

Or via code (before anything is invoked)

var service = Scryber.ServiceProvider.GetService<IScryberConfigurationService>();
service.FontOptions.UseSystemFonts = false;

Let me know if this works for you. It would be good to know.

Richard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants