I believe that almost every .NET developer, assigned a task to display text, has experienced hard times with precise text measuring and drawing. The
DrawString methods have several limitations, worst of all being not so accurate measuring and positioning of the desired text. Since .NET 2.0, Microsoft has introduced the
TextRenderer class that provides more precise text manipulation, but also has its cons – may render only with solid colors, no transparency, etc. Neither of the above described approaches gives you the opportunity to have mixed font texts, extended paragraph layouts like justify, or additional text effects like stroke or shadow. All that said, I thought it would be a nice exercise to create a custom text rendering solution that both solves the standard problems and also adds some nice features. Having solid experience with GDI+ and Windows Forms (I was a GUI developer for over 4 years), I started this project about a month ago, and had contributed to it for an hour or two almost every day. There are many areas that one may or may not find useful, and many parts I consider tricky, so I do hope this article will be useful for many folks.
Who May be Interested in this Project
This project mainly targets the Windows Forms platform. Although, in theory, it may be used to create off-screen graphics for the ASP.NET engine, I doubt that web developers will rely on this solution, having the Web Browser (and all its HTML formatting capabilities) as their main visual surface. The included control provides basic text formatting features, and may be used as a light-weight substitution for the heavy IE ActiveX control.
Using the Code
There are two main aspects of this solution:
- An abstract implementation –
GTextView- that is completely detached from a certain platform (Windows Forms vs. ASP.NET). You may use this abstraction to display text on any
Graphicssurface. For example, you may extend a
ListBoxwhose items will be rich-text enabled.
- A Windows Forms control –
GMarkupLabel- that composes the above class. What that control does is simply delegates paint and mouse events to the internal text view.
This is how we create and utilize a