PDFsharp & MigraDoc Foundation
http://forum.pdfsharp.com/

Text overlaping with end of numbers in table cell
http://forum.pdfsharp.com/viewtopic.php?f=2&t=4645
Page 1 of 1

Author:  baraccuda7596 [ Wed Aug 14, 2024 5:58 pm ]
Post subject:  Text overlaping with end of numbers in table cell

Hi there !

When creating a table using Migradoc I am facing the following rendering issue:

Image

The issue only occurs within table cells as I am able to have text right after numbers in other parts of the document without issue. I am clueless regarding what could cause this issue so any pointer would be greatly appreciated :( . I have tinkered with fonts, assumed that the problem is with trailing zeros (it isn't), and spent almost an hour troubleshooting.
This is also not a problem with padding since there is plenty of space left as can be seen.

I am using the 6.2.0 preview 1 as I needed a bug fix regarding a windows path separator character hardcoded that prevented images from being found on Linux. However just to be sure I've downgraded to 6.1.1 and the issue is also present there.
My code isn't doing anything fancy, for the subtotals:

Code:
let row = table.AddRow()
        row.Cells[0].Format.Font.Bold <- true
        row.Cells[0].AddParagraph(label) |> ignore
        row.Cells[1].MergeRight <- 2
        row.Cells[1].AddParagraph(value) |> ignore
        row.Cells[1].Format.Alignment <- ParagraphAlignment.Center


And for the product name it's a basic:

Code:
paragraph.AddSpace(3) |> ignore
paragraph.AddCharacter(SymbolName.Bullet) |> ignore
let featureFormattedText = paragraph.AddFormattedText("test" + string feature)
featureFormattedText.Italic <- true

Author:  baraccuda7596 [ Wed Aug 14, 2024 6:44 pm ]
Post subject:  Re: Text overlaping with end of numbers in table cell

It looks like the issue could be somehow relative to the culture used to render the numbers, as I was able to fix the overlap of the 1,000,000 number by rendering it using:

Code:
NumberOfFrancsIncluded.ToString("N0", culture)


instead of

Code:
NumberOfFrancsIncluded.ToString("N0")


However this fix does not seem to work with the other numbers overlaping.

Author:  baraccuda7596 [ Wed Aug 14, 2024 6:55 pm ]
Post subject:  Re: Text overlaping with end of numbers in table cell

Okay i got it, this looks like a bug with MigraDoc, the issue occurs when the number is rendered by a culture using spaces as thousands group separators instead of a comma (as is the case for the French culture). It looks like in this case migradoc/pdfsharp does not correctly calculate the space used by the number when positioning the next element. Setting the document's culture before rendering using the below does NOT seem to help:

Code:
document.Culture <- culture

Author:  TH-Soft [ Wed Aug 14, 2024 7:00 pm ]
Post subject:  Re: Text overlaping with end of numbers in table cell

I only see code fragments, so not much I can say now.

Is there more than one space used as a thousands separator for numbers?

An MDDDL file might help investigate what you get there.
https://www.pdfsharp.net/wiki/MigraDocDDL.ashx

Author:  baraccuda7596 [ Wed Aug 14, 2024 7:24 pm ]
Post subject:  Re: Text overlaping with end of numbers in table cell

Thanks for your swift reply, apparently the space separator only contains a single character.

I have just uploaded the mdddl file here: https://file.io/IvC3lTZjH2J8

Author:  baraccuda7596 [ Wed Aug 14, 2024 7:33 pm ]
Post subject:  Re: Text overlaping with end of numbers in table cell

From what I understand, this situation is supposed to be handled here

Code:
var culture = text.Document!.EffectiveCulture;

                    var decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
                    var decimalSeparatorLength = decimalSeparator.Length;
                    var groupSeparator = culture.NumberFormat.NumberGroupSeparator;
                    var groupSeparatorLength = groupSeparator.Length;

                    // Get the index of the decimal position the word should be aligned at.
                    var decimalPosIndex = -1;
                    var hasNumber = false;
                    for (var i = 0; i < word.Length;)
                    {
                        var c = word[i];

                        // Number is always accepted before decimal position.
                        if (char.IsNumber(c))
                        {
                            hasNumber = true;
                            i++;
                            continue;
                        }

                        var restLength = word.Length - i;

                        // Decimal Separator always determines decimal position.
                        if (decimalSeparatorLength <= restLength && word.Substring(i, decimalSeparatorLength) == decimalSeparator)
                        {
                            decimalPosIndex = i;
                            break;
                        }

                        // Group Separator is always accepted before decimal position.
                        if (groupSeparatorLength <= restLength && word.Substring(i, groupSeparatorLength) == groupSeparator)
                        {
                            i += groupSeparator.Length;
                            continue;
                        }

                        // Other characters determine decimal position, if word contains numbers by now.
                        if (hasNumber)
                        {
                            decimalPosIndex = i;
                            break;
                        }

                        // Otherwise other characters are accepted before decimal position.
                        i++;
                    }

                    if (decimalPosIndex >= 0)
                        word = word[..decimalPosIndex];

                    XUnitPt wordLength = MeasureString(word);
                    notFitting = _currentXPosition + wordLength >= _formattingArea.X + _formattingArea.Width + Tolerance;
                    if (!notFitting)
                        return _formattingArea.X + tabStopPosition - wordLength;

                    return _currentXPosition;
                }


The document culture is indeed used to determine the space used by both decimal separators and thousands separators in the current effective culture of the document (i've ensured that it is correctly set in my case). But for some reason, something does not work.

Author:  baraccuda7596 [ Wed Aug 14, 2024 9:18 pm ]
Post subject:  Re: Text overlaping with end of numbers in table cell

Okay, apparently this issue is solely about the non-breakable narrow space character

https://unicode-explorer.com/c/202F

For some reason, PdfSharp is struggling to render it properly no matter which font I use.

As a workaround I have replaced the number group separator character for the French culture since I luckily have a culture factory allowing me to make this change in a single place, but this is something the core team may want to look into.

Author:  Thomas Hoevel [ Thu Aug 15, 2024 7:07 am ]
Post subject:  Re: Text overlaping with end of numbers in table cell

I still have to look into it.

First impression:
Problem seems to be that NNBSP has a narrow width when being measured, but is really wide when rendered in PDF - and thus text after NNBSP may overlap with other text.

Author:  Thomas Hoevel [ Thu Aug 15, 2024 7:23 am ]
Post subject:  Re: Text overlaping with end of numbers in table cell

baraccuda7596 wrote:
For some reason, PdfSharp is struggling to render it properly no matter which font I use.
Which version of PDFsharp are you using? Which fonts have you tried?
Where did you get OpenSans from?
Have you tried Arial from the Windows folder?

I tried PDFsharp 6.2.0 Preview 1 under Windows 10.
Segoe WP in Core works fine.
Arial in GDI and WPF builds works fine.

Author:  Thomas Hoevel [ Thu Aug 15, 2024 7:35 am ]
Post subject:  Re: Text overlaping with end of numbers in table cell

I downloaded a version of "Open Sans" and it has no NNBSP, so in the PDF I see a rectangle as a placeholder. But yes, I get the overlap.

You can use the new "OnPrepareTextEvent" to replace all NNBSP by a supported character (a character included in your font).
I dunno how to use this with F#.

Author:  baraccuda7596 [ Thu Aug 15, 2024 9:33 am ]
Post subject:  Re: Text overlaping with end of numbers in table cell

Thank you a lot for your continued help with this

To answer your questions: I am using the version 6.2.0 preview 1 and I got the OpenSans font from the Google Font website. I am also using Linux to develop (as my production server is Unix-based).

Fantastic, the F# syntax is the following one:

Code:
pdfDocument.RenderEvents.PrepareTextEvent.Add(fun args -> args.Text <- args.Text.Replace(" ", " "))


And this approach is indeed much better than modifying the CultureInfo object across the whole application.

Apparently the rendering issue when the character is not supported by the font is not be specific to PdfSharp as I have found the following issue for another project:

https://github.com/bpampuch/pdfmake/issues/2614

However the overlap seems to be specific to PdfSharp.

This time since i do not have any hard requirement to use the OpenSans font I have simply switched to the Arimo font (from Google fonts) which supports this character and the issue is gone. The issue above links to a page breaking down all the fonts supporting NNBSP. However, the PrepareTextEvent will be quite a useful tool to keep in my toolbelt, thanks again!

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/