-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Printing from WPF is leaving random small spaces in the text when using Arial or Calibri fonts #7499
Comments
@miloush @campeters, I am not sure yet but this issue looks like the effect of this fix #6295 The main issue here comes from the fact that when we print to XPS ( pdf here ) the 'advance width' values are converted from double to int and therefore after a few characters the difference between what is displayed on the screen and when it is printed became significant. Therefore, to mitigate this, we cumulated the error of conversion and update the next 'advance width' value by +/-1 when the cumulated error exceeded +/-1. |
Yes it looks like a rounding error (though I would expect it to repeat on the right side). The solution in #6295 might even lead to catastrophic cancellation. It would be better to keep track of the accumulated advance widths rather than errors. |
@dipeshmsft @miloush - I can confirm that reversing #6295 fixes the rendering problem in our app. |
Is there a repo that contains an example of the rendering issue shown here? #6525 If so, I could try to find a fix for my issue that does not break that one... |
I can find a sample repo for this issue. I will get back to you with the sample application. |
Hey @campeters, here is the sample app GlyphRunIssue.zip |
Here is a repo that shows both of the issues: https://github.com/campeters/GlyphRunIssue In .net 5, the text renders correctly. In .net 6, the glyphs render correctly. |
@miloush / @dipeshmsft - I've reviewed this in more detail and the advanceErrorRounding is not the root of the problem. Somewhere upstream of the GlyphSerializer (maybe the DrawingContextFlattener), the GlyphRuns are separated into groups of no more than 100 characters. Within the 100 character glyph run, the spacing is correct. However, when the drawing caret is advanced to start the next 100 character glyph run, the error correction is not taken into account, leaving an extra space (or possibly two characters squished together). I'm going to look further, but if you have some idea where in the code the glyph runs are separated we could correct the root cause of this issue. |
The ±100 character chopping happens in |
OK while technically true, it is not a simple algorithmical issue, there seems to be an actual bug in what is rounded. I suspect the advance widths from shaping and from font can differ in floating precision but not integer precision. In such case, the error from shaping is taken but the font one should be used. There is also question about what precision does the "font width" use in XPS. I will have a look. |
I've messed around with the code in TextStore and I can improve the rendering by changing FetchTextRun so that it prefers breaking on a space. That way the extra fraction of a space is not noticeable. However, I suspect you are right... there is a a difference in the precision XPS uses for font width and what WPF uses when it does the layout. |
Not all scripts use spaces for word separation, and there can be significant differences after and before shaping due to kerning etc., so changing the breaking limit is not really solving the issue. Btw. Open XPS specification ECMA-388 states in [M5.6]:
Which is what I originally suggested needs to be done in terms of rounding. @dipeshmsft a good practice might be to consult the specification when changing code in areas that have one. Nowhere it is stated that the advance width coming from the font table is rounded. Therefore, when the value is omitted from XML, it sounds like the advance width is potentially not an integer. [M5.13] states:
I don't see the 2% increase in the code for IsSideways (or for algorithmically emboldened glyphs). However, these rules are only for optimizing the XML and I expect the conflicting cases to affect the layout only very rarely. Either way, if that is to be fixed, it should be fixed as a separate issue. |
Yes, it might even lead to catastrophic cancellation, but I think that was good in this case - it just means that the unrounded position and the rounded position are so close together that 0 is a good enough approximation. Am I missing something? |
@dipeshmsft My intent with the catastrophic cancellation note was that if you subtract two close numbers, you can get arbitrarily large relative error, which then keeps accumulating. I thought I could avoid it by keeping the total advance in an integer, but then I noticed the XPS specification is not clear on whether the advance is integral or not. You are correct, if we don't accumulate it it is fine. |
Glad I found this topic. We are experiencing the same issue when printing out XPS documents. When we render on screen, everything looks fine (dpi of screen is much smaller compared to dpi of printer. (printer often 1200, 600 dpi): When we print the XPS we see The two strings:
@jeffhandley @dipeshmsft : How can we get this fix at/for our customers? I've seen this being merged But there has also seen a question by @campeters if this is going into a dotnet 6 maintenance release. So I assume this fix it not available yet for us? We are also on .net 6. (also this issue explains why we see the pipe-chars |
Description
When printing in WPF, the graphics engine is inserting small spaces within words. For instance, the French word 'fonctions' is printed either as 'fonction s' or 'fo nctions' depending on where the word appears within the other text.
Reproduction Steps
Reproduction repository: https://github.com/campeters/Wpf-Print-Font-Issue
Expected behavior
The text should print correctly without extra spaces.
Actual behavior
The following file shows a space between 'fonction' and the 's'. It should be a single french word 'fonctions'
Test Print.pdf
Regression?
This code works correctly in dot net framework and it also seems to work correctly in .net 5.
Known Workarounds
None.
Impact
This bug impacts the quality of PDF and print files generated from WPF programs using the 'Arial' or 'Calibri' fonts. Some fonts work correctly. However, the filing of some government forms require that only 'Arial' be used.
Configuration
This bug occurs in .net 6, confirmed in 6.0.11 and 6.0.13 and .net 7. It does not appear to be specific to the configuration. It happens on Windows 10 and Windows 11.
The exact same code works correctly in .net framework 4.8.1
Other information
No response
The text was updated successfully, but these errors were encountered: