gdi+ and line break

D

deerchao

Hi, I'd like to render colorful text with word wrap on screen (kind of
inline <font> tag to change text color in html), but run into the line
break problem.

Graphics provides several DrawString methods with line break features,
but I can't make them draw different colors within one string, And if
I split the string into several part, so I can specify their colors,
line breaking won't work.

So, I have to break my string to lines before I pass it/them to
DrawString. This is something I don't know (yet) how to do efficiently
in c#.

I can create many sub strings (with length 1, 2, 3, ...) to
MeasureString them, but this leads to lots of gabage objects, which I
think I should avoid in a OnPaint event handler;

And I can use MeasureCharacterRanges to every chars in the string, so
I will have every char's width. but I found I can only process 32
chars a time because if I passed more CharacterRanges to
StringFormat.SetMeasurableCharacterRanges, there would be an
OverflowException. Since there is a limit number, I think this may be
more unefficient than making lots of strings.

I think there should be a way to do this, though I havn't found it
right now. I looked around for a HTML renderer example, but none of
them is done in C# or .net without a Browser control.

Any help is appreciated, Thanks!
 
N

Nicholas Paldino [.NET/C# MVP]

You mentioned that you should avoid creating a lot of objects in the
OnPaint handler. I don't think that this is an issue here. Granted, you
might trigger memory pressure in the OnPaint handler, but simply creating
the objects isn't going to trigger a GC. A GC is going to happen when it
happens. Also, creating all of those strings and not holding references to
them is going to make the cleanup of those strings rather quick (it's not
going to survive past one generation).

Are you using .NET 3.0 by chance? If so, have you considered using WPF?
It will make what you are trying to do much, MUCH easier and it might be
worth the upgrade if you are already using .NET 2.0 (as it is just extra
libraries, no CLR changes).
 
D

deerchao

Thanks!

What you said made me feel much better. I'll use the substring way to
break text into lines.

One of my friends showed me how to do this in WPF with TextBlock, it's
dead easy, made me want to kill myself. Anyway, I can't just switch to
WPF from WinForms right now, I'm not ready (know little about WPF),
and I don't think my users are ready, either. May be after one or more
years, I'll turn to WPF.

Thanks again!

You mentioned that you should avoid creating a lot of objects in the
OnPaint handler. I don't think that this is an issue here. Granted, you
might trigger memory pressure in the OnPaint handler, but simply creating
the objects isn't going to trigger a GC. A GC is going to happen when it
happens. Also, creating all of those strings and not holding references to
them is going to make the cleanup of those strings rather quick (it's not
going to survive past one generation).

Are you using .NET 3.0 by chance? If so, have you considered using WPF?
It will make what you are trying to do much, MUCH easier and it might be
worth the upgrade if you are already using .NET 2.0 (as it is just extra
libraries, no CLR changes).

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hi, I'd like to render colorful text with word wrap on screen (kind of
inline <font> tag to change text color in html), but run into the line
break problem.
Graphics provides several DrawString methods with line break features,
but I can't make them draw different colors within one string, And if
I split the string into several part, so I can specify their colors,
line breaking won't work.
So, I have to break my string to lines before I pass it/them to
DrawString. This is something I don't know (yet) how to do efficiently
in c#.
I can create many sub strings (with length 1, 2, 3, ...) to
MeasureString them, but this leads to lots of gabage objects, which I
think I should avoid in a OnPaint event handler;
And I can use MeasureCharacterRanges to every chars in the string, so
I will have every char's width. but I found I can only process 32
chars a time because if I passed more CharacterRanges to
StringFormat.SetMeasurableCharacterRanges, there would be an
OverflowException. Since there is a limit number, I think this may be
more unefficient than making lots of strings.
I think there should be a way to do this, though I havn't found it
right now. I looked around for a HTML renderer example, but none of
them is done in C# or .net without a Browser control.
Any help is appreciated, Thanks!
 
N

Nicholas Paldino [.NET/C# MVP]

Just a piece of advice, you might want to take a look at it sooner than
later. It's easier to learn the basics now and keep up with them as you
move along.

Granted, there is a cost, but if doing what you are doing now was done
so easy in WPF, imagine what other things could be done more easily for you.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

deerchao said:
Thanks!

What you said made me feel much better. I'll use the substring way to
break text into lines.

One of my friends showed me how to do this in WPF with TextBlock, it's
dead easy, made me want to kill myself. Anyway, I can't just switch to
WPF from WinForms right now, I'm not ready (know little about WPF),
and I don't think my users are ready, either. May be after one or more
years, I'll turn to WPF.

Thanks again!

You mentioned that you should avoid creating a lot of objects in the
OnPaint handler. I don't think that this is an issue here. Granted, you
might trigger memory pressure in the OnPaint handler, but simply creating
the objects isn't going to trigger a GC. A GC is going to happen when it
happens. Also, creating all of those strings and not holding references
to
them is going to make the cleanup of those strings rather quick (it's not
going to survive past one generation).

Are you using .NET 3.0 by chance? If so, have you considered using
WPF?
It will make what you are trying to do much, MUCH easier and it might be
worth the upgrade if you are already using .NET 2.0 (as it is just extra
libraries, no CLR changes).

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hi, I'd like to render colorful text with word wrap on screen (kind of
inline <font> tag to change text color in html), but run into the line
break problem.
Graphics provides several DrawString methods with line break features,
but I can't make them draw different colors within one string, And if
I split the string into several part, so I can specify their colors,
line breaking won't work.
So, I have to break my string to lines before I pass it/them to
DrawString. This is something I don't know (yet) how to do efficiently
in c#.
I can create many sub strings (with length 1, 2, 3, ...) to
MeasureString them, but this leads to lots of gabage objects, which I
think I should avoid in a OnPaint event handler;
And I can use MeasureCharacterRanges to every chars in the string, so
I will have every char's width. but I found I can only process 32
chars a time because if I passed more CharacterRanges to
StringFormat.SetMeasurableCharacterRanges, there would be an
OverflowException. Since there is a limit number, I think this may be
more unefficient than making lots of strings.
I think there should be a way to do this, though I havn't found it
right now. I looked around for a HTML renderer example, but none of
them is done in C# or .net without a Browser control.
Any help is appreciated, Thanks!
 
M

Martin Bonner

Hi, I'd like to render colorful text with word wrap on screen (kind of
inline <font> tag to change text color in html), but run into the line
break problem.
[snip]
I think there should be a way to do this, though I havn't found it
right now. I looked around for a HTML renderer example, but none of
them is done in C# or .net without a Browser control.

Can you use a browser control?

(The problem with .Net 3.0 is that it won't run on Win2K - and
certainly our customers won't accept that for several years ... it's
not long since we weaned them off NT4 + Win98)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top