0

Good morning. I have to print some long strings that falls off the margins of my page. I'm not able to split automatically as a multi-line string.

private void pd_PrintPage(object sender, PrintPageEventArgs ev)
{
  ...
  string line ="Condimentum a a ac aenean parturient risus suscipit et orci scelerisque convallis porttitor enim venenatis viverra.Egestas nibh natoque mus etiam a parturient feugiat hendrerit a sagittis viverra dui ante varius lectus arcu."
  float leftMargin = ev.MarginBounds.Left;
  float topMargin = ev.MarginBounds.Top;    
  ev.Graphics.DrawString(line, printFont, Brushes.Black, new RectangleF(leftMargin, yPos, 400.0f, 200.0f));
  ...
}

I tried using the overload with the bounding box specification, as you can see, but the result is a jam of chars on the page, because the lines from the long string is printed over itself.

Is there a quick way to solve this problem?

Thanks

Simone Conti
  • 349
  • 1
  • 17
  • I would recommend either using Xaml and create some sort of Document to Print, or you can use HTML and Rotativa to convert HTML to Printable PDF. – Akash Kava Feb 18 '20 at 10:41
  • @AkashKava What does this have to do with PDFs though? – DavidG Feb 18 '20 at 10:42
  • @DavidG Printing HTML will require some renderer, instance of browser and additional UI, all thing can be avoided as Rotativa is headless browser. – Akash Kava Feb 18 '20 at 10:45
  • @AkashKava Maybe I did not understand what you're suggesting, but my application must be a stand alone one... no browsers or other stuff. – Simone Conti Feb 18 '20 at 10:51
  • You can still create FlowDocument and print it, but it has to be WPF application. Because sizing, aligning text on printer is too much of work, it is already done in FlowDocument. https://stackoverflow.com/a/40745687/85597 – Akash Kava Feb 18 '20 at 10:53
  • Graphics.DrawString() doesn't produce a "jam". Guessing at a problem with the font is not productive, I'd guess what you really see is the actual code writing multiple strings to ypos. Seeing how ypos gets updated is pretty crucial. You would never write the code this way if you do it correctly, given that the same rectangle needs to be used more than once. – Hans Passant Feb 18 '20 at 11:28
  • 1
    @SimoneConti It would be better to post the solution as an Answer, and then Accept your own answer, instead of putting the solution into the question. That way you may even get upvotes on the Answer :-) – Peter B Feb 18 '20 at 16:07

1 Answers1

1

SOLVED I finally solved my problem. It's not so easy to explain how, so I post here a piece of code that shows what I did:

private void pd_PrintPage(object sender, PrintPageEventArgs ev)
    {
        float linesPerPage = 0;
        int count = 0;
        float leftMargin = ev.MarginBounds.Left;
        float topMargin = ev.MarginBounds.Top;
        float printAreaHeight = ev.MarginBounds.Height;
        float printAreaWidth = ev.MarginBounds.Width;
        string line = null;
        float yPos = topMargin;

        int charactersFitted = 0;
        int linesFilled = 0;
        SizeF theSize = new SizeF();
        Font printFont = new Font("Arial", 12, FontStyle.Regular);

        SizeF layoutSize = new SizeF(printAreaWidth, printAreaHeight);

        // Calculate the number of lines per page.
        linesPerPage = printAreaHeight / printFont.GetHeight(ev.Graphics);

        // Print each line of the array.
        while (count < linesPerPage && lineIdx < linesArray.Count())
        {
            line = linesArray[lineIdx++];
            theSize = ev.Graphics.MeasureString(line, printFont, layoutSize, new StringFormat(), out charactersFitted, out linesFilled);
            ev.Graphics.DrawString(line, printFont, Brushes.Black, new RectangleF(50.0F, yPos, theSize.Width, theSize.Height));
            yPos += (1 + linesFilled) * printFont.GetHeight(ev.Graphics);
            count += linesFilled + 1;
         }

         // If more lines exist, print another page.
         if (count > linesPerPage)
            ev.HasMorePages = true;
         else
            ev.HasMorePages = false;
    }
Simone Conti
  • 349
  • 1
  • 17