Wrapped text is too tall to fit graphics height

2020R1 Web 2.0 on Windows 10
I am creating a complicated pdf invoice. It is a service repair invoice, so it contains comments that need to be drawn on the document. Sometimes these comments can be very long and can spill over to more than one page. If I wrap the text using graphics.drawtext, I don’t see any way to split that onto another page. So my question is, anyone have a method to split the text into chunks that I can fit into a specific pixel height. Or even split the text into array of lines that don’t exceed a specific pixel width and don’t split in the middle of a word?
I am using font name Times.
Thanks

You should be able to use Graphics.TextHeight to figure out how tall the text is going to be, with that you can calculate how much will fit on your page and how much should go on another page (or whatever your process is when they won’t fit in the provided space.

Ok, I have the Graphics.TextHeight and I know that it won’t fit on the page. But how how do I split the text into a height that will fit onto the page? For example my TextHeight is 1200 and I have available height of 400 on each page to put the text. I need to split the text into 3 chunks, each being 400 height. Not sure how to split the text to get 400.
Thanks

Well, perhaps start with just dividing by the number of characters in the string and see if that works out. If that doesn’t, you could then start adjusting by adding or subtracting characters, calculating the TextHeight each time until you know you have the amount that will fit in the first section. Then just do the same for the next one.

1 Like

My suggestion is to handle the word wrapping yourself and divide what you need to print into an array of lines.

You can do this using a while loop (writing this from memory without the aid of a computer):

// split your text into individual words
Var words() as string = text.split(“ “)
Var lines() as String
Var lineWords() as String

// only continue making lines if there are words remaining
While words.ubound > -1

  // only continue adding words if we
  // haven’t exceeded the desired width
  // and haven’t run out of words. 
  While g.StringWidth(join(lineWords(“ “))) < desiredWidth and words.ubound > -1
    LineWords.AddRow(words(0))
    Words.Remove(0)
  Wend

  // if we didn’t empty the array, we exceeded the width
  // so we need to back off by one word
  If words.ubound > -1 then
    Words.AddRowAt(0, lineWords.pop)
  End If

  // add the words we’ve gathered as the next line
  Lines.AddRow lineWords.join(“ “)

  // clear the array of words on the current line
  Redim lineWords(-1)
Wend

Now that you have the lines you can either draw them one line at a time or use your other calculation to join the groups of lines together that you want to draw.

Thanks @Greg_O_Lone I will give that try. I think your method might eliminate the line endings, but that will be Ok.

To work around this, you can also create a line array first and then split each line into its words and run through them.

Var lines() As String = text.Split(EndOfLine)
Var words() As String

For Each line As String In lines

  If words.Count > 0 Then
    words.ResizeTo(-1)
  End If

  words = line.Split(" ")

  // Go on with Greg's Code (While...Wend)

Next

@Martin_T
Here the code from Greg that I tweaked. It works great as long as I remove the line endings first. After leaving the line endings, I tried adding your code to the tweaked code but it just causes an endless loop. I tried a few changes but could not make it work. I would like to keep the line endings if possible. Can you help?

// split your text into individual words
Var words() as string = pString.split(" ")
Var lines() as String
Var lineWords() as String
// only continue making lines if there are words remaining
While words.ubound > -1
  // only continue adding words if we
  // haven’t exceeded the desired width
  // and haven’t run out of words. 
  While session.Document.Graphics.TextWidth(join(lineWords,(" "))) < desiredWidth and words.ubound > -1
    LineWords.AddRow(words(0))
    Words.Remove(0)
  Wend
  // if we didn’t empty the array, we exceeded the width
  // so we need to back off by one word
  If words.ubound > -1 then
    Words.AddRowAt(0, lineWords.pop)
  End If
  // add the words we’ve gathered as the next line
  Lines.AddRow join(linewords,(" "))
  // clear the array of words on the current line
  Redim lineWords(-1)
Wend

Return Lines

Replace your line endings with a character like chrb(1) and then put them back in when you render the lines.