All Manuals > CLIM 2.0 User Guide > 13 Extended Stream Output Facilities

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 does not 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.

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

Many streams that maintain a text cursor also display some visible indication of it. The object that represents this display is (somewhat confusingly) also called a cursor.

cursor Protocol Class

Summary: The protocol class that corresponds to cursors. If you want to create a new class that behaves like cursor, it should be a subclass of cursor. Subclasses of cursor must obey the cursor protocol. Members of this class are mutable.

cursorp Function

cursorp object

Summary: Returns t if object is a cursor; otherwise, it returns nil.

:sheet Initarg

Summary: The :sheet initarg is used to specify the sheet with which the cursor is associated.

standard-text-cursor Class

Summary: The instantiable class that implements a text cursor. Typically, ports will further specialize this class.

cursor-sheet Generic Function

cursor-sheet cursor

Summary: Returns the sheet with which the cursor cursor is associated.

cursor-position Generic Function

cursor-position cursor

Summary: Returns the x and y position of the cursor cursor as two values.

(setf* cursor-position) Generic Function

(setf* cursor-position) x y cursor

Summary: Sets the x and y position of the cursor cursor to the specified position. For the details of setf*, see C.4 Multiple-Value Setf.

cursor-visibility Generic Function

cursor-visibility cursor

(setf cursor-visibility) Generic Function

(setf cursor-visibility) visibility cursor

Summary: Returns (or sets) the visibility of the cursor cursor. The visibility is one of :on (the cursor will be visible at its current position), :off (the cursor is active, but not visible at its current position), or nil (the cursor is to be deactivated).

display-cursor Generic Function

display-cursor cursor state

Summary: This draws or erases the cursor cursor. If state is :draw, the cursor will be drawn. If the state is :erase, the cursor will be erased.

13.3.2 The Stream Text Cursor Protocol

The following generic functions comprise the stream text cursor protocol. Any extended output stream class must implement methods for these generic functions.

stream-text-cursor Generic Function

stream-text-cursor stream

(setf stream-text-cursor) Generic Function

(setf stream-text-cursor) cursor stream

Summary: Returns (or sets) the text cursor object for the stream stream.

stream-cursor-position Generic Function

stream-cursor-position stream

Summary: Returns the current text cursor position for the extended output stream stream as two integer values, the x and y positions.

(setf* stream-cursor-position) Generic Function

(setf* stream-cursor-position) x y stream

Summary: Sets the text cursor position of the extended output stream stream to x and y. x and y are in device units, and must be integers. For the details of setf*, see C.4 Multiple-Value Setf.

stream-increment-cursor-position Generic Function

stream-increment-cursor-position stream dx dy

Summary: Moves the text cursor position of the extended output stream stream relatively, adding dx to the x coordinate and dy to the y coordinate. Either of dx or dy may be nil, meaning the the x or y cursor position will be unaffected. Otherwise, dx and dy must be integers.


CLIM 2.0 User Guide - 01 Dec 2021 19:38:59