Search code examples
.netprintingmonospace

.NET PrintDocument does not print monospace fonts correctly


I am this code to print a few blocks of text:

var doc=new PrintDocument();
 doc.PrintPage += (sender, e) => {
   e.Graphics.DrawString(
    "123456789 123456789 123456789 123456789 123456789 123456789 123456789 ", 
     new Font("Courier New", 12), 
     Brushes.Black, 0, 0);
   };
 doc.Print();

Courier New is supposed to be 10 CharsPerInch, so each block (including the space) should be 2.54 cm long. When printing it - regardless on which printer, I measure 13.1 cm for 5 blocks instead of 12.7 cm. When I draw rectangles with 1 inch width, I can see that the text is actually longer than it should be, so it is not a general scaling problem, just the text is printed wrong.

Can anyone confirm this and more importantly show me a way around? I need the text to be exactly 10 CPI, not 10.3 CPI as experienced :-(


Solution

  • "10 CPI" was meaningful in the previous century when dot-matrix printers were still dominant. It fell victim to typographer's insistence on getting perfect letter shapes, they are very picky about that. The Graphics class does not keep that a secret, when you use Graphics.MeasureString() on the string you'll see it is 7.164388 inches wide, not 7.0 like you hoped.

    The typographer's preferences were powered by scalable outline font support and laser printers with 600 dpi resolution. Do take advantage of that, the font size is a floating point value, not an integer. Graphics.ScaleTransform() works too. Which is what you probably should prefer, printer engines are still subject to mechanical tolerances so you ought to keep a config parameter around that the user can tweak to get it pixel-perfect.

    Quick fix:

        new Font("Courier New", 11.72465f),