[.net] [C#] Drawing a string in different colors?

Started by
14 comments, last by Zipster 14 years, 8 months ago
Quote:Original post by Fiddler
Solution: split your text into text runs (one run per [font, style, size, color] combination) and draw the runs sequentially.

The problem is that if the run word-wraps, it won't wrap with respect to the full bounding rectangle of the whole string, just the bounding rectangle for that individual run.

Quote:Better solution: use a RichTextControl which offers this functionality out of the box.

I looked into this, but there were two problems: firstly it doesn't support drawing to a bitmap and I would have to use some pInvoke magic to get that to work, and secondly it doesn't support a transparent background so I'd have to subclass my own custom control and add that support.

Quote:Another solution: use a WebBrowser Control and format your text using HTML.

I didn't think about this control, but it appears to have the same two limitations as RichTextControl.

At this point I'm just thinking of giving up and not supporting this feature. It's simply too much effort for something I thought would be simple.
Advertisement
I usually punt and use a fixed width font if I want this kind of behavior.
I ended up going with a RichTextBox that renders to a bitmap using a transparent background. Once I had the low-level code set up (which I was mostly able to grab from various forum posts on the web, such as this and this), it was dead simple to format the text. It may not be the cleanest solution, but it has the best functionality-to-effort ratio.
Hey again,

I have one last issue related to the RichTextBox. Right now when I create the text box, the graphics object returned through CreateGraphics is at 96 DPI, presumably because the control assumes it will be rendered to the display. However I need the text to render at 400 DPI. I can manually scale up the font size by a factor of (400/96), but the font is still only anti-aliased at 96 DPI and looks jaggier than other text drawn using Graphics.DrawString at 400 DPI.

Is there a way I can "trick" the RichTextBox into thinking that it should draw at 400 DPI? I apologize for sounding like an idiot, but this is the first time in a while I've had to dive into the specifics of text rendering.
RichTextBox is using GDI, while Graphics.DrawString is using GDI+ - their antialiasing algorithms are different and incompatible. To be more precise, plain GDI does not perform y-direction antialiasing, which results in the jagged text you are observing (it has nothing to do with DPI in this case).

It *might* be possible to force your RichTextBox to use GDI+ rendering by calling Application.UseCompatibleTextRendering(true) before you initialize your application, but I doubt this will affect the RichTextBox (as it is a wrapper of the unmanaged API with the same name).

Welcome to the wonderful world of Windows.Forms. :)

Edit: one solution is to avoid the render-to-bitmap step and send the RichTextBox directly to the printer. This *should* ensure correct text rendering.

[OpenTK: C# OpenGL 4.4, OpenGL ES 3.0 and OpenAL 1.1. Now with Linux/KMS support!]

I tried changing the computability mode and it didn't have any effect, so you're likely correct in that it's just wrapping the unmanaged GDI version.

Unfortunately, I can't send the images directly to the printer because we're not the ones printing the images :) The tool I made generates the images at 400 DPI, but they're sent off to a printing company.

I'll have our artist look at the text, because it probably won't be more than 8pt at 96 DPI (scalled to 33.3pt for 400 DPI) and I personally don't think it looks horrible. Plus the major win of having rich text functionality is hard to pass up.

This topic is closed to new replies.

Advertisement