ABatch.T is a data structure containing a sequence of VBT painting commands. Batches are untraced: they must be explicitly allocated and freed using the procedures in this interface.
INTERFACE Batch; IMPORT Word;
TYPE T <: ADDRESS;
PROCEDURE New(len: INTEGER := -1): T;
Allocate a batch containing at leastlen Word.Ts.
Iflen = -1, the number ofWord.Ts in the result will beVBTTuning.BatchSize. Initially the clip and scroll source areRect.Empty.
PROCEDURE Free(VAR ba: T);
Returnbato the free list and setba := NIL.
Free(ba)is a checked runtime error ifbaisNIL.
END Batch.
10.2
The BatchUtil interface
This interface provides operations to clip and translate a batch of painting commands. It is useful to those who are implementing window classes with customized painting behavior.
Don’t apply these procedures to a batch whose contents are concurrently being read or written.
INTERFACE BatchUtil;
IMPORT Batch, Rect, Point, PaintPrivate; PROCEDURE GetLength(ba: Batch.T): CARDINAL;
Return the number ofWord.Tsin use inba.
PROCEDURE Copy(ba: Batch.T): Batch.T;
Allocate and return a new batch initialized with a copy ofba.
Every entry in a batch has a clipping rectangle; there is also a clipping rectangle for the batch as a whole. The effective clipping rectangle for a painting operation is the intersection of its clipping rectangle with its batch’s clipping rectangle.
10.2 The BatchUtil interface 133
PROCEDURE GetClip(ba: Batch.T): Rect.T;
Returnba’s clipping rectangle.
TYPE ClipState = {Unclipped, Clipped, Tight}; PROCEDURE GetClipState(ba: Batch.T): ClipState;
Returnba’s clipping state.
If GetClipState(ba)isClipped then the clipping rectangle of every painting operation inbais a subset ofGetClip(ba). IfGetClipState(ba)isTightthen
GetClip(ba)is equal to the join of the clipping rectangles of the painting operations inba. If GetClipState(ba)isUnclipped, there is no particular relationship betweenba’s clipping rectangle and the clipping rectangles of the entries inba.
PROCEDURE Meet(ba: Batch.T; READONLY clip: Rect.T);
Setba’s clipping rectangle toRect.Meet(GetClip(ba), clip).
If the assignment is non-trivial, this will change the clip state ofbato beUnclipped.
PROCEDURE Clip(ba: Batch.T);
Applyba’s clipping rectangle to each operation.
That is, ifGetClipState(ba)isUnclipped, then for each painting operation in
ba,Clipreplaces the clipping rectangle of the operation with the meet of the rectangle andGetClip(ba), and sets the clipstate ofbatoClipped.
PROCEDURE Tighten(ba: Batch.T);
Achieveba.clipped = Tightwithout changing the effect ofba.
That is, Tighten(ba)is equivalent to Clip(ba)followed by assigning toba’s clipping rectangle the join of the resulting clipping rectangles of the entries inba.
PROCEDURE Translate(ba: Batch.T; READONLY delta: Point.T);
Translatebabydelta.
That is, for each painting operation inba, translate the target of the painting operation bydelta. This always involves translating the clipping rectangle of the operation by delta. It also adds delta to the delta components of all textures and to the reference point of TextComs. It adjusts the p1, p2, vlo, and vhi fields of
TrapComs. The relative displacement of a scrolling command is not affected; that is, both the source and target of the scroll are translated bydelta. The clipping rectangle of the batch is also translated.
PROCEDURE ByteSwap(ba: Batch.T);
Convert all text painting operations in ba to have the same byteorder as
PROCEDURE Succ(ba: Batch.T; cptr: PaintPrivate.CommandPtr) : PaintPrivate.CommandPtr;
Return the pointer to the entry inbathat follows the one pointed to bycptr.
Succ(ba, NIL) returns the first entry in ba; Succ(ba, cptr) = NIL when
cptris the last entry inba. To visit each entry in the batchba, use a loop like this:
cptr := BatchUtil.Succ(ba, NIL); WHILE cptr # NIL DO
CASE cptr.command OF ... END; cptr := BatchUtil.Succ(ba, cptr) END
ThePaintPrivateinterface explains the format of the entries.
END BatchUtil.
10.3
The PaintPrivate interface
This interface defines the layout of entries in paint batches.
INTERFACE PaintPrivate;
IMPORT Rect, Point, Trapezoid, Word; TYPE
PaintOp = INTEGER; Pixmap = INTEGER; Font = INTEGER;
In a paint batch,PaintOps,Pixmaps, andFontsare represented by integers in a screentype-dependent way. During rescreening an old batch might find its way to a screen of the wrong type, causing garbage to be painted; but the garbage will be painted over with the correct pixels promptly.
TYPE
PaintCommand = {RepeatCom, TintCom, TextureCom, PixmapCom, ScrollCom, TrapCom, TextCom,
ExtensionCom};
PackedCommand = BITS 32 FOR PaintCommand; FixedSzCommand =
[PaintCommand.RepeatCom..PaintCommand.TrapCom]; ByteOrder = {MSBFirst, LSBFirst};
PackedByteOrder = BITS 32 FOR ByteOrder; VAR (*CONST*)
10.3 The PaintPrivate interface 135
There are eight types of entries; each of which begins with a word containing a
PaintCommandthat indicates which type of entry it is.
Entries of typeTintCom,TextureCom,PixmapCom,ScrollCom,TrapCom, andTextComare used to implement theVBToperationsPaintTint,PaintTex- ture,PaintPixmap,Scroll,PaintTrapezoid, andPaintText/PaintSub.
ARepeatComentry in a batch indicates that the preceding entry is to be re-executed with its clipping rectangle changed to that of theRepeatComentry. For example, these are used for implementingPolyTint,PolyTexture, andPaintRegion. There are some restrictions on whereRepeatComentries can occur.
ExtensionComentries can be used to implement additional painting operations beyond those that are built into Trestle.
Some of the entries are fixed size; that is, the size of the entry is determined by their type. The following array gives the sizes of the fixed-size commands:
CONST
WS = BYTESIZE(Word.T); ComSize =
ARRAY FixedSzCommand OF INTEGER
{(BYTESIZE(CommandRec) + WS-1) DIV WS, (BYTESIZE(TintRec) + WS-1) DIV WS, (BYTESIZE(PixmapRec) + WS-1) DIV WS, (BYTESIZE(PixmapRec) + WS-1) DIV WS, (BYTESIZE(ScrollRec) + WS-1) DIV WS, (BYTESIZE(TrapRec) + WS-1) DIV WS};
ComSize[c]equals the size inWord.Ts of a paint batch entry for the commandc.
TYPE
CommandRec =
RECORD command: PackedCommand; clip: Rect.T END; CommandPtr = UNTRACED REF CommandRec;
RepeatPtr = CommandPtr;
We define aRecand aPtrtype for each kind of batch entry.
Every batch entry is a “pseudo-subtype” of aCommand, in the sense that its record type hasCommandRecas a prefix.
A repeat command has no other fields besides the command identifier itself and the clipping rectangle. Hence aRepeatPtris simply a pointer to aCommandRec.
All of the batch entries that are not repeat commands contain aPaintOp. They are all pseudo-subtypes of the followingRecandPtrtypes:
PaintRec = RECORD
command: PackedCommand; clip: Rect.T;
op: PaintOp END;
PaintPtr = UNTRACED REF PaintRec;
The following four entry types correspond toPaintTint,PaintPixmap,Scroll, andPaintTrapezoidoperations.
TintRec = RECORD
command: PackedCommand; clip: Rect.T;
op: PaintOp END;
TintPtr = UNTRACED REF TintRec; PixmapRec = RECORD command: PackedCommand; clip: Rect.T; op: PaintOp; delta: Point.T; pm: Pixmap END;
PixmapPtr = UNTRACED REF PixmapRec; TexturePtr = PixmapPtr; ScrollRec = RECORD command: PackedCommand; clip: Rect.T; op: PaintOp; delta: Point.T; END;
ScrollPtr = UNTRACED REF ScrollRec;
It is illegal for aScrollRecto be directly followed in a batch by aRepeatcommand.
TrapRec = RECORD command: PackedCommand; clip: Rect.T; op: PaintOp; delta: Point.T; pm: Pixmap; p1, p2: Point.T; m1, m2: Trapezoid.Rational; END;
TrapPtr = UNTRACED REF TrapRec;
Iftris aTrapRec, thentr.p1andtr.p2are points that are on the extensions of the west and east edges of the trapezoid, andtr.m1andtr.m2are the slopes of the west and east edges. The slopes are given as(delta v) / (delta h). A zero denominator represents an infinite slope; i.e., a vertical edge. A zero numerator is illegal.
10.3 The PaintPrivate interface 137
The entries that are not fixed-size are pseudo-subtypes ofVarSzRec, which contains asizefield with the number ofWord.T’s in the entire entry.
VarSzRec = RECORD command: PackedCommand; clip: Rect.T; op: PaintOp; szOfRec: INTEGER; END;
VarSzPtr = UNTRACED REF VarSzRec;
PaintTextandPaintSuboperations result in the following entry type, in which
commandwill equalTextCom:
TextRec = RECORD command: PackedCommand; clip: Rect.T; op: PaintOp; szOfRec: INTEGER; byteOrder: PackedByteOrder;
clipped: BITS BITSIZE(Word.T) FOR BOOLEAN; refpt: Point.T;
fnt: Font;
txtsz, dlsz: INTEGER;
(* dl: ARRAY [0..dlsz-1] OF VBT.Displacement *) (* chars: ARRAY [0..txtsz-1] OF CHAR *)
END;
TextPtr = UNTRACED REF TextRec;
In aTextRec, the booleanclippedmust be set if boundingbox(text)is not a subset of the batch’sclip. ATextReccan be directly followed in a batch by a
Repeatonly ifclippedisTRUE. Thedlandcharsfields are declared in comments since Modula-3 does not allow a record to contain a variable-sized array; they must be accessed using address arithmetic. Thecharsfield will be padded out so that the
TextRecends on a word boundary.
ThebyteOrderfield defines the byteorder of the characters. (Since paint batches can be transported across address spaces and merged, the byte order could be different for different records in a paint batch.)
ExtensionRec = RECORD command: PackedCommand; clip: Rect.T;
op: PaintOp; szOfRec: INTEGER;
delta: Point.T; pm: Pixmap; fnt: Font;
subCommand: INTEGER;
(* extensionData: ARRAY OF CHAR *) END;
ExtensionPtr = UNTRACED REF ExtensionRec;
AnExtensionReccan be used to implement painting operations that exploit rendering primitives that may be available on some particular implementation. Extension commands get aPaintOp, adelta, apm, and afnt“for free”; they can also put whatever data they need into the rest of the extension data part of the record. The field
szOfRecis the number ofWord.Tsin the extension record, including the extension data. When anExtensionRecis translated, it’sclipanddeltafields are translated automatically; its extension data is unaffected.
PROCEDURE CommandLength(p: CommandPtr): INTEGER;
Return the length in words of the command entryp.
139