473,320 Members | 1,861 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Word Wrap while Printing

Has anyone come across a decent algorithm for implementing word wrap
features in .net printing? I have a small component that uses basic
printing techniques (i.e. e.Graphics.DrawString in a PrintPage event of a
PrintDocument object) to send some formatted text to the printer. However,
if the lines are too long they run off the page rather than wrapping around.
I'm sure I can spend the time and come up with a word wrapping algorithm but
figured why go through the trouble if someone already knows of one :-)

--- Thanks, Jeff

--

Jeff Bramwell
Digerati Technologies, LLC
www.digeratitech.com

Manage Multiple Network Configurations with Select-a-Net
www.select-a-net.com
Nov 16 '05 #1
10 23203
Hi Jeff,

First of all, I would like to confirm my understanding of your issue. From
your description, I understand that you need to print text with word wrap.
If there is any misunderstanding, please feel free to let me know.

As far as I know, if you're trying to print RTF text, you can either use
the old VB6 control and wrap it for .net, or you can write your own code.
You can also use MS Word Automation and copy the RichText to a Word object
and call its print method if you have Word. The latter is the lamest
approach, but it works.

Also, there are some 3rd party .NET components. Please try to check the
following link:

http://www.codeguru.com/Csharp/Cshar...icle.php/c4781

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 16 '05 #2
Hi Jeff,

If you use a drawstring that takes a rectanglef it will word wrap for you.

g.DrawString(textbox1.text, textbox1.font, Brushes.Black,
RectangleF.op_Implicit(e.PageBounds))

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 16 '05 #3
Jeff,

When working with the Graphics.DrawString method, one of the parameters is a
StringFormat object. this object defines wrapping behaviour among other
things.
pass the StringFormat object definitions and a Rectangle object to draw on
(rather than a Point) as parameters to the Graphics.DrawString method and
it should do the trick.

I do that all the time - unless I misunderstood you.

Picho
"Jeff B." <js*@community.nospam> wrote in message
news:OW*************@TK2MSFTNGP15.phx.gbl...
Has anyone come across a decent algorithm for implementing word wrap
features in .net printing? I have a small component that uses basic
printing techniques (i.e. e.Graphics.DrawString in a PrintPage event of a
PrintDocument object) to send some formatted text to the printer.
However, if the lines are too long they run off the page rather than
wrapping around. I'm sure I can spend the time and come up with a word
wrapping algorithm but figured why go through the trouble if someone
already knows of one :-)

--- Thanks, Jeff

--

Jeff Bramwell
Digerati Technologies, LLC
www.digeratitech.com

Manage Multiple Network Configurations with Select-a-Net
www.select-a-net.com

Nov 16 '05 #4
Thanks Kevin and Picho for the info. You both understood exactly what I was
after and the "rectangle" method you mention almost does exactly what I
need. The only part I'm missing is being able to increment the line count
by how many lines the text was wrapped so the subsequent lines display
correctly and the pages break correctly.

I think I'm going to take a slightly different approach and break the lines
out programmatically as I print them. I'll post back any successes - or
failures :-)

--- Jeff

--

Jeff Bramwell
Digerati Technologies, LLC
www.digeratitech.com

Manage Multiple Network Configurations with Select-a-Net
www.select-a-net.com

"Jeff B." <js*@community.nospam> wrote in message
news:OW*************@TK2MSFTNGP15.phx.gbl...
Has anyone come across a decent algorithm for implementing word wrap
features in .net printing? I have a small component that uses basic
printing techniques (i.e. e.Graphics.DrawString in a PrintPage event of a
PrintDocument object) to send some formatted text to the printer.
However, if the lines are too long they run off the page rather than
wrapping around. I'm sure I can spend the time and come up with a word
wrapping algorithm but figured why go through the trouble if someone
already knows of one :-)

--- Thanks, Jeff

--

Jeff Bramwell
Digerati Technologies, LLC
www.digeratitech.com

Manage Multiple Network Configurations with Select-a-Net
www.select-a-net.com

Nov 16 '05 #5
Hi Jeff,

Thanks for sharing your experience with all the people here. If you have
any questions, please feel free to post them in the community.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 16 '05 #6
> I think I'm going to take a slightly different approach and break the
lines out programmatically as I print them. I'll post back any
successes - or failures :-)


Just a follow up...

I ended up creating a method that takes a line of text and returns an
ArrayList of lines after performing a "word wrap" on them. This method lets
me easily, and programatically, print lines while keeping track of how many
lines have been printed - even if they've been "wrapped". Below is the code
to the method I've created. I'm sure it can still be optimized somewhat and
some things can probably be done more efficiently, so if anyone has any
suggestions, please let me know. Please don't pay too much attention to the
formatting, I've altered it somewhat so it takes up less space.

<<< BEGIN CODE SNIPPET >>>
private System.Collections.ArrayList wordWrap(string text,
System.Drawing.Font printFont, System.Drawing.Graphics graphics,
System.Drawing.Rectangle marginBounds)
{
System.Collections.ArrayList lines;
string buffer = text;
System.Drawing.SizeF size;
int index1;
int index2;
char[] whitespace = new char[] {' ', '\t', '\r', '\n'};

try {
lines = new ArrayList();

while (buffer.Length > 0) {
size = graphics.MeasureString(buffer, printFont);

if (size.Width > marginBounds.Width) {
// Find the wrapping point of the line based on the width
for (index1 = buffer.Length - 1; index1 >= 0; index1--) {
size = graphics.MeasureString(buffer.Substring(0, index1),
printFont);

if (size.Width <= marginBounds.Width) {
// We found the wrapping point now let's look for the first
// whitespace character - if there is one
index2 = buffer.LastIndexOfAny(whitespace, index1);

if (index2 >= 0) {
// Whitespace character found
lines.Add(buffer.Substring(0, index2));
buffer = buffer.Substring(index2);
break;
}
else {
// Whitespace was not found
lines.Add(buffer.Substring(0, index1));
buffer = buffer.Substring(index1);
}
break;
}
}
}
else {
// This line completely fits so add it to the buffer unaltered
lines.Add(buffer);
buffer = "";
}
}
return lines;
}
catch {
return null;
}
finally {
lines = null;
}
}
<<< END CODE SNIPPIET >>>

--

Jeff Bramwell
Digerati Technologies, LLC
www.digeratitech.com

Manage Multiple Network Configurations with Select-a-Net
www.select-a-net.com
Nov 16 '05 #7
Jeff,
To get the # of lines used for the wrapped printing you can use the
MeasureString method that takes a SizeF argument (#7 of 7 in my Intellisense
list). The SizeF should be the width and height of the rectangle you are
printing in and, of course, use the same StringFormat as the DrawString
call. This overload has two out parameters nline, and nchars that return
the # of lines and characters that fit. If nchars is less than the length
of the string the string would be truncated on output. You can use this to
see if remaining text fits on the rest of the page and then advance the
baseline by the # of lines returned after you draw the string.

Ron Allen
"Jeff B." <js*@community.nospam> wrote in message
news:eE**************@TK2MSFTNGP09.phx.gbl...
Thanks Kevin and Picho for the info. You both understood exactly what I
was after and the "rectangle" method you mention almost does exactly what
I need. The only part I'm missing is being able to increment the line
count by how many lines the text was wrapped so the subsequent lines
display correctly and the pages break correctly.

I think I'm going to take a slightly different approach and break the
lines out programmatically as I print them. I'll post back any
successes - or failures :-)

--- Jeff

--

Jeff Bramwell
Digerati Technologies, LLC
www.digeratitech.com

Manage Multiple Network Configurations with Select-a-Net
www.select-a-net.com

"Jeff B." <js*@community.nospam> wrote in message
news:OW*************@TK2MSFTNGP15.phx.gbl...
Has anyone come across a decent algorithm for implementing word wrap
features in .net printing? I have a small component that uses basic
printing techniques (i.e. e.Graphics.DrawString in a PrintPage event of a
PrintDocument object) to send some formatted text to the printer.
However, if the lines are too long they run off the page rather than
wrapping around. I'm sure I can spend the time and come up with a word
wrapping algorithm but figured why go through the trouble if someone
already knows of one :-)

--- Thanks, Jeff

--

Jeff Bramwell
Digerati Technologies, LLC
www.digeratitech.com

Manage Multiple Network Configurations with Select-a-Net
www.select-a-net.com


Nov 16 '05 #8
Jeff B... Here is an attempt to break up text into an array of lines
that fit on a page.

===== // UNTESTED // ======

public void ResetArray(IPrintEngine pe,
Graphics g,
RectangleF clipRect)
{
arrayLines.Clear();
float pageWidth= clipRect.Width- (this.horizontalMargin*2);
char newLineChar= '\r';
char space= ' ';
// use tabAsString later to convert tabs to spaces
StringBuilder tabBuilder= new StringBuilder();
for(int i=0; i<this.tabSize; i++)
{
tabBuilder.Append(space);
}
string tabAsString= tabBuilder.ToString();

// get properties and parse text
Brush brush;
Font font;
StringFormat stringFormat;
if (this.isUseDocumentProperties)
{
brush= pe.Brush;
font= pe.Font;
stringFormat= pe.StringFormat;
}
else
{
brush= new SolidBrush(Color.Black);
font= this.Font;
stringFormat= this.stringFormat;
}
string text= this.Text;
if (this.isReplaceTokens)
{
text= pe.ReplaceTokens(text);
}

// break out lines with embedded line break
string temp= this.Text.Replace(System.Environment.NewLine,"\r") ;
string[] arrayUnfittedLines= temp.Split(newLineChar);

// break out lines that overflow
foreach (string line in arrayUnfittedLines)
{
// replace tabs with spaces
string parsed;
parsed= line.Replace("\t",tabAsString);
// add to array if line of word tokens fits in page margin
if (g.MeasureString(parsed,font,
Int32.MaxValue,
stringFormat).Width <= pageWidth)
{
arrayLines.Add(parsed);
}
else
// line does not fit on page
// need to break up line into word tokens
// and then place tokens into lines that fit in page margin
{
string[] arrayTokens= parsed.Split(space); // tokenize line
StringBuilder buffer;
int index=0;
while (index < arrayTokens.Length)
{
buffer= new StringBuilder();
// at least one token on line, ? may be clipped
buffer.Append(arrayTokens[index]+space);
index++;
while(index< arrayTokens.Length &&
g.MeasureString(buffer.ToString()+arrayTokens[index],
font,
Int32.MaxValue,
stringFormat).Width <= pageWidth)
{
buffer.Append(arrayTokens[index]+space);
index++;
}
// end of tokens or end of line
arrayLines.Add(buffer.ToString());
}
}
}
this.currentIndex= 0;
}
Regards,
Jeff
I think I'm going to take a slightly different approach and break the

lines out programmatically as I print them. I'll post back any successes
- or failures :-)<

Regards,
Jeff
Has anyone come across a decent algorithm for implementing word wrap
features in .net printing?

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 16 '05 #9
I have had a chance to work on a word wrap alogrithm and it can be
improved by extracting the lines directly from the textbox:

string[] arrayUnfittedLines= new string[this.Lines.Length];
this.Lines.CopyTo(arrayUnfittedLines,0);

Secondly, there is no need to replace tabs, simply set the tab stops as
in:

stringFormat.SetTabStops(0.0f,pe.TabStops);

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 16 '05 #10
I see you've already found a fix to your issue but I thought others might
like a an answer to your original question. Here's what I do for wordwrap
using the tools supplied with .NET.

// This routine will print a document with 2 columns,
// wordraped text in each column, the left and right
// columns match row sizes, similare to equal cell sizes
private void document_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
float left = e.MarginBounds.Left;
float top = e.MarginBounds.Top;
float width = e.MarginBounds.Width / 2 - 5; // this spaces the columns
evenly
float height = e.MarginBounds.Height;
int fitted = 0; // use only to correctly format the MeasureString method
int qFilled = 0, aFilled;

// The variables are named to identify a question column and an answer
column
RectangleF qDrawRect = new RectangleF(left, top, width, height); // Left
column rectangle
RectangleF aDrawRect = new RectangleF(left + width + 10, top, width,
height); // right

// Setup to measure the line lines
SizeF qSizeF = new SizeF(width, height);
SizeF aSizeF = new SizeF(width, height);

// Although you can initialize string attributes here
// this line is only to fill in the parameter list
// We'll use whatever is given to us
StringFormat newStringFormat = new StringFormat();

// The following code sets the font to be
// the same as the displayed font (in this case, in
// a datagrid)
System.Drawing.Font printFont = new System.Drawing.Font
(myGrid.DefaultCellStyle.Font.Name,
myGrid.DefaultCellStyle.Font.Size,
myGrid.DefaultCellStyle.Font.Style);

// Insert code to render the page here.
// This code will be called when the control is drawn.
while (linesPrinted <= lines.GetUpperBound(0))
{
// Here's where we find out how many lines will be printed during a
word wrap
e.Graphics.MeasureString(lines[linesPrinted,0], printFont,
qSizeF, newStringFormat, out fitted, out qFilled);
e.Graphics.MeasureString(lines[linesPrinted,1], printFont,
aSizeF, newStringFormat, out fitted, out aFilled);

// This prints the two columns, properly formatted and,
// if necessary, wordwrapped
e.Graphics.DrawString(lines[linesPrinted, 0], printFont,
System.Drawing.Brushes.Black, qDrawRect);
e.Graphics.DrawString(lines[linesPrinted++, 1], printFont,
System.Drawing.Brushes.Black, aDrawRect);

// Now we use the info we gathered in the MeasureString statement
// If either column wrapped, qFilled and/or aFilled will be larger
than 1
// I'm using the ?: operator to determine which is larger and using
that
// one. I also add a half line to the equation to provide "paragraph"
// spacing, a nice touch to the printout
aDrawRect.Y += (int)myGrid.DefaultCellStyle.Font.Height *
(qFilled > aFilled ? qFilled : aFilled) +
(int)(myGrid.DefaultCellStyle.Font.Height * .5);
qDrawRect.Y = aDrawRect.Y;

if (aDrawRect.Y >= e.MarginBounds.Bottom)
{
e.HasMorePages = true;
return;
}
}
linesPrinted = 0;
e.HasMorePages = false;
}
"Jeff B." wrote:
Has anyone come across a decent algorithm for implementing word wrap
features in .net printing? I have a small component that uses basic
printing techniques (i.e. e.Graphics.DrawString in a PrintPage event of a
PrintDocument object) to send some formatted text to the printer. However,
if the lines are too long they run off the page rather than wrapping around.
I'm sure I can spend the time and come up with a word wrapping algorithm but
figured why go through the trouble if someone already knows of one :-)

--- Thanks, Jeff

--

Jeff Bramwell
Digerati Technologies, LLC
www.digeratitech.com

Manage Multiple Network Configurations with Select-a-Net
www.select-a-net.com

Nov 17 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: leegold2 | last post by:
I have been looking for a php word wrap function. I know there's an official PHP function but I've tried that and many of the functions contributed on that php.net page and none do what I...
10
by: Douglas G | last post by:
I've tried various ideas on this problem, but I don't see word wrapping. Can you point out what is wrong? It's a K&R exercise, and I'm still new to programming. Other pointers would be helpful...
1
by: Bernerd | last post by:
Would anyone out there tell me how to make my C# datagrid wrap the text in the cells. I haven't seen a good how to out there that does this. I know it has something to do with using styles but...
10
by: Jonathan Smith | last post by:
I have a VB app that has a richtextbox with the word wrap set to true. I need to be able to output the text to a text file, but it just puts the text in the file as one long line. How do i...
9
by: Joel Byrd | last post by:
I've got a div whose width is specified as a percentage so that if you shrink the browser window, the div shrinks, and the text inside the div wraps around to accommadate this. The problem is:...
10
by: Lorenzo Thurman | last post by:
I have a table cell that I want to wrap text inside of. I've tried both hard and soft wrap, but Firefox refuses to obey. IE 6&7 handle the wrap just fine. Does anyone know how I can fix this?
5
by: momo | last post by:
say i have the following table: <table width="500"> <tr> <td width="250">this is the text im concerned with</td> <td></td> </tr> </table> i need the width of the columns to STAY at 250 and...
1
by: vedika | last post by:
Hello, I have problem with word-wrapping. When width is given in pixel style="word-wrap:word-break" works well but when it is given in percentage then it is not working. <table border="1"...
1
by: berky | last post by:
hello my wonderful internet users! I have been assigned a simple word wrap program. I think I've gotten so wrapped up in the method I'm trying to implement, but it's just not coming together. ...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.