TEXT RENDERING ON WINDOWS FORMS
In the early days of developing text edit control for Windows Forms, the very first task to solve was to implement ultra-fast and flicker-free text rendering for the multi-line text content.
First, we started experiencing with the Graphics device context, which provides an abstraction layer for the rendering text and graphical primitives on top of GDI plus.
As our text editor is primarily used with the parser, allowing us to write code in some programming language, the text is typically broken into fragments. Different syntax structures (i.e., reserved words, numbers, comments, etc.) are highlighted with different colors, resulting in many text fragments being drawn on the graphical surface.
We tried GDI plus first, and among other things, we have found that DrawString/MeasureString methods need to be faster to render large enough text divided into lots of text fragments.
On top of that, Graphics do not provide a mode when the text is rendered in an opaque mode (i.e., together with the background), and background first and then text in transparent mode results in noticeable flickering.
We have quickly realized that for WinForms, using GDI would be the best way to go.
As a primary usage of our editor is code writing, it primarily uses the mono-spaced font to display the text. That allows for some optimizations with the text measurement. However, as we support international character drawing and different font styles in the editor, we can not assume that all the characters in the text would be the same width, even with mono-spaced fonts.
The editor can display text with non-monospaced font, but features like square blocks are disabled in this mode.
We use ExtTextOut internally to render text fragments, allowing text and background underneath it to be drawn simultaneously (unless the text editor is used in Transparent mode, which also supports displaying background images or watermarks). It also allows caching a character width for every character used in the text for fast text measurements.
Drawing text and background simultaneously could have minor issues with text clipping. Say, italic text in some fonts can have an overhang, requiring an extra width to render that character, which we don’t consider when rendering the following text fragment.
For non-monospaced fonts, the editor can be configured to use DrawText instead, which supports some other text rendering features like kerning.
TEXT RENDERING ON WINDOWS WPF
WPF version of the text editor uses an entirely different approach - it constructs WPF layers with background, text, and other graphical primitives. Internally, WPF uses graphic acceleration based on DirectX to draw graphic primitives on the drawing surface, which can handle much more complex scenes. We use the WPF text rendering engine in the editor, which provides text rendering with antialiasing, text measurement, and formatting. We use System.Windows.Media.TextFormatting’s TextLine and TextSource classes for the text rendering to get the maximum performance available on WFP.
As we go forward, we envisage developing a cross-platform version of the Code Editor with the help of the AlterNET UI framework and potentially using fast-rendering cross-platform engines like SKIA.