The path to simple text effects

By: David Pankhurst

Abstract: Discusses the path API calls in Windows, and the various effects possible, especially for text, such as clipping and outlining. By David Pankhurst.

(Source code is available via this link)

Paths are a little-used method of creating some very interesting effects in Windows. And it's no wonder -- typically, paths require some tedious and complex source code. However, Borland C++Builder and its TCanvas object make using these functions very straightforward, combining the convenience of RAD with the power of direct API calls.

A path is composed of drawing commands, and can be figures, shapes, or even text. By keeping a record of these shapes when drawn, a path can be created. Later, this path can be used for a variety of effects. For instance, a drawing of a rectangle would result in a path to outline the rectangle -- draw a circle beside it, and the path becomes more complicated, but still usable. Lines, text, and so forth can also be included; however lines are less useful, since some of the effects rely on closed paths to work.

The BeginPath() call is used to begin, and EndPath() (surprise!) ends it. Both take as their sole parameter the device context. At the API level, this would normally require acquiring a Device Context, saving the old handles (font, brush, and pen), making new handles and making them current, performing the drawing, and then restoring the old handles and releasing the device context. This bookkeeping code ends up being much longer than the actual path manipulation. In addition, it is error-prone, since a resource that isnt handled properly could cause a memory leak.

With C++Builder, the details are wrapped up in the TCanvas object, which manages all of these resources transparently. It provides the device context handle (Canvas->Handle), and manages the handles to all the other objects (brush, pen, font). As well, you can set the values early and forget about them. For example, the demo program has the font set at build time through the IDE.

Back to the path code: Once EndPath() ends, you have a path ready to use. The sample program shows four ways of using the resulting path. There are others, but these are the most interesting. For the other uses, consult the help file Win32 Programmer's Reference for a good explanation of the subject.

The first effect is simple outlining. By using the StrokePath() command, the path is stroked but not filled. This results in outlined text, showing how easy it is to create outlining.

Its counterpart is StrokeAndFillPath(), which both fills and outlines. Note that the stroking is done using the current pen, and the filling is with the current Canvas color (those rather garish colors were set in the forms constructor).

Another command is FillPath(), which simply fills. It can be used for exotic effects (for instance, if the brush was set to a crosshatch fill), but since StrokeAndFillPath() also demonstrates filling, it was left out.

The third effect shows the clipping possible with paths. Once the path is created, SelectClipPath() is used to make the path a clip region. Various flags are possible, but the RGN_COPY flag used here causes the text itself to be the clip path, resulting in it being the only place the grid lines are visible. After SelectClipPath(), a series of lines is drawn across the whole form. Yet the lines appear only within the text.

The fourth effect shows a rather exotic use for paths. The PathToRegion() command converts the path to a region, which is then used by SetWindowRgn() to make the text into a window. This isn't completely practical (there's no title bar, for instance, and no Close button), it highlights the flexibility of paths.

Although the examples here focus on text, they could easily have been a series of shapes or the results of any drawing command. The key is to record the drawing with BeginPath and EndPath and then process the resulting path immediately.

Using C++Builder, the code is minimal. For those who have worked in the Windows API, the code necessary to save and restore device context settings and doing the drawing makes it easy to appreciate the TCanvas object.

Server Response from: ETNASC01