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

QuestPDF.Drawing.Exceptions.DocumentDrawingException: 'Could not find an appropriate font fallback for the following glyphs: $U-000D ' #838

Open
rverberne-carapax opened this issue Apr 12, 2024 · 16 comments

Comments

@rverberne-carapax
Copy link

Hi,

I am trying version 2024.3.0.

But what does this error mean?

QuestPDF.Drawing.Exceptions.DocumentDrawingException: 'Could not find an appropriate font fallback for the following glyphs: $U-000D '

Is this documented? If so, i have not been able to find it.

@danirzv
Copy link

danirzv commented Apr 15, 2024

FontFallback is the font which get used when QuestPdf could not find specified character in your default font, it's my sample code i use and works fine

        if (!string.IsNullOrEmpty(_options.FontPath))
        {
            FontManager.RegisterFont(File.OpenRead(_options.FontPath));
        }

        if (!string.IsNullOrEmpty(_options.FallBackFontPath))
        {
            FontManager.RegisterFont(File.OpenRead(_options.FallBackFontPath));
        }
Document.Create(pdf =>
        {
            pdf.Page(pageHandler =>
            {
                pageHandler.If(
                    !string.IsNullOrEmpty(_options.FontName),
                    x => x.DefaultTextStyle(text => 
                        text.FontFamily(_options.FontName)
                        .Fallback(text => text.FontFamily(_options.FallBackFontName)).DirectionAuto()));

@rverberne-carapax
Copy link
Author

@danirzv Thanks.

The exception message also includes the following text which i did not see (The VS exception popup was sized so that it did not show all the text):

Possible solutions: 
1) Install fonts that contain missing glyphs in your runtime environment. 
2) Configure the fallback TextStyle using the 'TextStyle.FontFamilyFallback' method. 
3) Register additional application specific fonts using the 'FontManager.RegisterFont' method. 

You can disable this check by setting the 'Settings.CheckIfAllTextGlyphsAreAvailable' option to 'false'. 
However, this may result with text glyphs being incorrectly rendered without any warning.'

@BC89
Copy link

BC89 commented Apr 16, 2024

Seeing the same and I find it perplexing since I'm not specifying a particular font family anywhere and would expect the quest to use it's default. I'm running .net8 in a Linux container. I've tried to specify a few common fonts that I believe exists on both Win and Linux but still no luck.

@rverberne-carapax
Copy link
Author

rverberne-carapax commented Apr 17, 2024

I added below line. But i dont know if this is 'the way to go'. I dont like hacky workarounds, but what i dont like more are exceptions that kill my app... And there is no visual difference in my case anyway.

QuestPDF.Settings.CheckIfAllTextGlyphsAreAvailable = false;

@eros404
Copy link

eros404 commented Apr 17, 2024

I also encountered this problem and I'm not specifying any particular font family.

For me this is due to a call to the Line() function on a TextDescriptor:

 private void ComposeHeader(TableCellDescriptor header)
{
    header
        .Cell()
        .AlignRight()
        .Text(text =>
        {
            text.Line("actuelle").Bold(); // <= Here
            text.Span("Date").Bold();
        });
}

When I remove this line, it works fine.
So I'm guessing that the Line() function add \r\n to the string and that these are not handled by the default font.

Edit :
The Line() function works as expected when I set QuestPDF.Settings.CheckIfAllTextGlyphsAreAvailable = false.

@MarcinZiabek
Copy link
Member

Thank you all for reporting this issue and sharing your feedback 😄

The Line() function works as expected when I set QuestPDF.Settings.CheckIfAllTextGlyphsAreAvailable = false.

@eros404 Thank you for this observation. It looks like the \r symbol (added only on the Windows environment) is not supported by many fonts and/or Skia. I will change the implementation so that only a new line character (\n) is added.

The fix will be released soon.

@Krm1t
Copy link

Krm1t commented Apr 23, 2024

@MarcinZiabek I hope it's okay that i'm adding to this issue as i believe it is related.

This is reproduceable in version 2024.3.1

Just to give you an idea of our setup. Users are writing multiline text in a windows application. The text is then stored in a database. A docker container then generates a pdf. So it's a mix of windows and linux platforms.

Because input happens in windows, new line is added as /r/n.
As per this issue, /r isn't supported, or more precisely /r/n isn't supported because what i found is that if you do /r /n then it does actually seem to work.

I'm no expert on the subject but if i were to guess i would think that /r/n somehow gets interpreted as some special char rather than 2 individual chars.

I've added a small project that can show this. Initially it will fail but if you go to MyDocument and add a space between /r/n then it will run just fine.
While writing this i decided to try and run the project on windows (IIS Express) and i get the same results.

QuestPdfNewLine.zip

@merinofg
Copy link

merinofg commented Apr 24, 2024

Can also confirm issue with version 2024.3.1

Running / debugging in my M1 without any issue. All renders properly by default.
As soon as I put it in a docker container, I get the glyphs error message mentioned in this thread.

Forcing to load a font via FontManager.RegisterFont(File.OpenRead("wwwroot/fonts/Roboto-Regular.ttf")); only works locally, not in the container, and gives the same error message.

My Dockerfile in case it helps to reproduce the issue:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["WebApp/WebApp.csproj", "WebApp/"]
RUN dotnet restore "WebApp/WebApp.csproj"
COPY . .
WORKDIR "/src/WebApp"
RUN dotnet build "WebApp.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "WebApp.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApp.dll"]

@MarcinZiabek
Copy link
Member

Thank you for the collaboration on fixing this issue 😄

I have applied one more enhancement. Since many font files do not contain the carriage return glyph, the mentioned exception could be thrown even for valid environments. I implemented one more step that removes the \r character from text content, hopefully completely fixing this problem.

@Krm1t Your findings have been critical. Thank you for investigating it so profoundly!

Would you please test the newest 2024.3.2 version? https://github.com/QuestPDF/QuestPDF/releases/tag/2024.3.2

@BC89
Copy link

BC89 commented Apr 29, 2024

I just updated to the latest stable - 2024.3.2 and can confirm this is still an open issue. Same error as before running on a windows box with docker enabled and docker file identical to merinofg.

For brevity I've left out the individual components but this will fail. I'm not explicitly adding a carriage return but assume internally that's happening.

    public static byte[] Generate34(Dictionary<string, string> inputParamDict, List<(int, Dictionary<string, string>)> resultsDictionaryList, byte[] logo, byte[] curvature, byte[] deviation)
    {
        var document = Document.Create(container => container.Page(page =>
        {
            page.Size(PageSizes.A4);
            page.Margin(25, Unit.Point);
            page.PageColor(Colors.White);
            page.DefaultTextStyle(x => x.FontSize(13));

            page.Header()
                .Container()
                .AlignLeft()
                .PaddingTop(30)
                .PaddingBottom(15)
                .Table(table =>
                {
                    table.ColumnsDefinition(columns => columns.RelativeColumn());

                    _ = table.Cell().Row(1)
                        .ShowOnce()
                        .Text("Free Movement, TR34 Standard Survey Report").FontSize(22).Bold();

                    _ = table.Cell().Row(2).SkipOnce().Text("Free Movement, TR34 Standard Survey Report")
                        .SemiBold().FontColor(Colors.BlueGrey.Darken3);
                });


            page.Content()
                .Container()
                .AlignLeft()
                .Table(table =>
                {
                    table.ColumnsDefinition(columns => columns.RelativeColumn());

                    table.Cell().Column(1).Row(3).Component(new ProjectDetailsComponent(inputParamDict));
                    table.Cell().PageBreak();

                    table.Cell().Column(1).Row(5).Component(new TR34TestingSpecificationsComponent(resultsDictionaryList.First().Item2, inputParamDict));
                    table.Cell().PageBreak();

                    table.Cell().Column(1).Row(7).Component(new TR34ResultsComponent(resultsDictionaryList.First().Item2));
                    table.Cell().PageBreak();

                    _ = table.Cell().Column(1).Row(9).Element(Block).AlignMiddle().PaddingLeft(10)
                            .Text("Curvature Image").SemiBold().FontColor(Colors.White);
                    _ = table.Cell().Column(1).Row(10).AlignLeft().Image(curvature).FitArea();
                    table.Cell().PageBreak();

                    _ = table.Cell().Column(1).Row(12).Element(Block).AlignMiddle().PaddingLeft(10)
                            .Text("Deviation Image").SemiBold().FontColor(Colors.White);
                    _ = table.Cell().Column(1).Row(13).AlignLeft().Image(deviation).FitArea();
                });


            page.Footer()
                .Table(table =>
                {
                    table.ColumnsDefinition(columns =>
                    {
                        columns.ConstantColumn(105);
                        columns.RelativeColumn();
                    });

                    table.Cell().ColumnSpan(2).Row(1).Height(10).AlignTop().LineHorizontal(1).LineColor(Colors.Grey.Lighten1);
                    _ = table.Cell().Column(1).Row(2).Image(logo);
                    _ = table.Cell().Column(2).Row(2).AlignRight().AlignMiddle().Text($"Generated on {DateTime.Now.ToShortDateString()}")
                        .SemiBold().FontColor(Colors.BlueGrey.Darken3);

                    table.Cell().ColumnSpan(2).Row(3).AlignCenter().Text(x =>
                    {
                        _ = x.CurrentPageNumber();
                        _ = x.Span("/");
                        _ = x.TotalPages();
                    });
                });

        }));

        return document.GeneratePdf();
    }

@MarcinZiabek
Copy link
Member

MarcinZiabek commented Apr 29, 2024

I just updated to the latest stable - 2024.3.2 and can confirm this is still an open issue. Same error as before running on a windows box with docker enabled and docker file identical to merinofg.

Would you provide an example where you think the \r character is placed and throws an exception? Is it used within the block similar to this one?

text.CurrentPageNumber().Format(x => /* formatting code that injects the new line with \r */);

Also, are you sure that the exception is the same? Regarding the $U-000D character?

@Krm1t
Copy link

Krm1t commented Apr 30, 2024

Thank you for the collaboration on fixing this issue 😄

I have applied one more enhancement. Since many font files do not contain the carriage return glyph, the mentioned exception could be thrown even for valid environments. I implemented one more step that removes the \r character from text content, hopefully completely fixing this problem.

@Krm1t Your findings have been critical. Thank you for investigating it so profoundly!

Would you please test the newest 2024.3.2 version? https://github.com/QuestPDF/QuestPDF/releases/tag/2024.3.2

@MarcinZiabek I'm happy it helped.
I'm sorry it took me so long to get back to you but i ran into some unrelated issues which i'll be creating a new issue about unless someone already did.

That being said i can confirm that the solution seems to have helped, both in our actual application and in the test application that i attached in my earlier comment.

Thanks for the quick fix.

@merinofg
Copy link

merinofg commented Apr 30, 2024

Hopefully this will add some more information.

With the last version, 2024.3.2, I still get errors. I think my first comment was not related to the glyph $U-000D as the name of the issue says, so @MarcinZiabek if you consider it is better to open a new issue and close this let me know.

I can see in the logs of the docker image the next when the exception happens:

      QuestPDF.Drawing.Exceptions.DocumentDrawingException: Could not find an appropriate font fallback for the following glyphs: 
      $U-0032 '2'
      U-0023 '#'
      U-004F 'O'
      U-0020 ' '
      U-0054 'T'
      U-0055 'U'
      U-0053 'S'
      U-0045 'E'
      U-0052 'R'
      U-0050 'P' 

The characters are not in order, but they should say PRESUPUESTO #2
Same for when generating invoices (characters not logged in order for FACTURA 2024-000002) it fails and print the next trace:

Unhandled exception rendering component: Could not find an appropriate font fallback for the following glyphs: 
      $U-0030 '0'
      U-0032 '2'
      U-0052 'R'
      U-0055 'U'
      U-002D '-'
      U-0020 ' '
      U-0054 'T'
      U-0043 'C'
      U-0034 '4'
      U-0041 'A'
      U-0046 'F' 

This is always the header of the document, with custom style as title, and as in the next image is visible, when running the .NET app locally, it renders without issues, but in a docker image it does not.

image

The code for the component in my case looks like the next (simplified for the title, as it's where seems to fail):

public void Compose(IContainer container)
    {
        var titleStyle = TextStyle.Default.FontSize(20).SemiBold().FontColor(Colors.Blue.Medium);

        container.Row(row =>
        {
            row.RelativeItem().Column(column =>
            {
                column.Item().Text($"{title.ToUpper()}").Style(titleStyle);
            });
        });
    }

If I comment the header section, for me, the next part failing seems to be the footer where the page counter is, with the trace:

$U-002F '/'
U-0020 ' '
U-0031 '1'

Hope this brings some more insights.
Regards

@MarcinZiabek
Copy link
Member

@merinofg Indeed, it is an entirely separate problem. There is a great chance that the 2024.3.3 release fixes it. Would you please give it a try?

@merinofg
Copy link

merinofg commented May 2, 2024

Can confirm that version 2024.3.3 works as intended for me.
Thanks a lot @MarcinZiabek for such fast responses and help! 🙌🏼

@BC89
Copy link

BC89 commented May 3, 2024

Latest 2024.3.3 solved my issue referenced above. Thanks!

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

7 participants