13.3 The Text Cursor

In the days when display devices displayed only two-dimensional arrays of fixed-width characters, the text cursor was a simple thing. A discrete position was selected in integer character units, and a character could go there and nowhere else. Even for variable-width fonts, it was enough to address a character by the pixel position of one of its corners. However, variable-height fonts with variable baselines on pixel-addressable displays upset this simple model. The "logical" vertical reference point is the baseline, as it is in typesetting. In typesetting, however, an entire line of text is created with baselines aligned and padded to the maximum ascent and descent, and then the entire line is put below the previous line.

It is clearly desirable to have the characters on a line aligned with their baselines, but when the line on the display is formed piece by piece, it is impossible to pick in advance the proper baseline. The solution CLIM adopts is to choose a provisional baseline.

We assume that text has at least six properties. With a reference point of (0, 0) at the upper left of the text, it has a bounding box consisting of ascent, descent, left kerning, right extension, and a displacement to the next reference point in both x and y . CLIM determines the position of the reference point and draws the text relative to that, and then the cursor position is adjusted by the displacement. In this way, text has width and height, but the x and y displacements need not equal the width and height.

CLIM adopts the following approach to the actual rendering of a glyph. Textual output using the stream functions ( not the graphics functions) maintains text on a "line." Note that a line is not an output record, but is rather a collection of "text so far," a top (positioned at the bottom of the previous line plus the stream's vertical spacing), a baseline, a bottom, and a "cursor position." The cursor position is defined to be at the top of the line, not at the baseline. The reason for this is that the baseline can move, but the top is relative to the previous line, which has been completed and therefore doesn't move. If text is drawn on the current line whose ascent is greater than the current ascent of the line, then the line is moved down to make room. This can be done easily using the output records for the existing text on the line. When there is enough room, the reference point for the text is the x position of the cursor at the baseline, and the cursor position is adjusted by the displacement.

Figure 21 shows this in action before and after each of three characters are drawn. In all three cases, the small circle is the "cursor position." At first, there is nothing on the line.


Figure 21. Determining the Position of the Text Cursor

The first character establishes the initial baseline and is then drawn. The upper left corner of the character is where the cursor was (as in the traditional model), but this will not remain the case. Drawing the second character, which is larger than the first, requires moving the first character down in order to get the baselines to align; during this time, the top of the line remains the same. Again, the upper left of the second character is where the cursor was, but that is no longer the case for the first character (which has moved down). The third character is smaller than the second, so no moving of characters needs to be done. However, the character is drawn to align the baselines, which in this case means the upper left is not where the cursor was. Nor is the cursor at the upper right of the character as it was for the previous two characters. It is, however, at the upper right of the collective line.

13.3.1 The Text Cursor Protocol

13.3.2 The Stream Text Cursor Protocol

Common Lisp Interface Manager 2.0 User's Guide - 27 Feb 2008