PipalPaint.mesa 
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Louis Monier February 2, 1988 1:29:41 am PST
Bertrand Serlet May 20, 1988 2:13:11 pm PDT
Barth, January 27, 1988 12:20:33 pm PST
DIRECTORY
Imager,
Pipal, PipalInt, PipalReal;
PipalPaint: CEDAR DEFINITIONS IMPORTS Imager = BEGIN
Theory
How to display Pipal structures into a context.
Painting Procedures
paintMethod: Pipal.Method;
PaintProc: TYPE = PROC [object: Pipal.Object, context: Imager.Context];
Paint: PaintProc;
Applies the function found in the class, if any.
Otherwise uses the class enumeration for painting recursively.
Paint Method Annotation
Annotation for specifying painting information for an object.
paintMethodProp: ATOM;
CreatePaintMethodAnnotation: PROC [child: Pipal.Object, paint: PaintProc] RETURNS [annotation: Pipal.Annotation];
Defining new Colors
Temporary, of course.
Color: TYPE = Imager.Color;
Areas
Areas are objects for which the "Area" method applies. Areas denotes LIST OF Rectangles. They can be used for clipping. Union of areas is just an overlay of them. Rectangles composing an area should be finite (finite base, finite size), with the exception of fullArea, that corresponds to PipalReal.fullRectangle.
Area: TYPE = Pipal.Object;
enumerateAreaMethod: Pipal.Method;
EnumerateAreaProc: TYPE = PROC [area: Area, each: PipalReal.RectangleProc, transformation: PipalReal.Transformation] RETURNS [quit: BOOLFALSE];
Might enumerate empty rectangles (of size=0) but not degenerated rectangles (of size<0).
EnumerateArea: EnumerateAreaProc;
Applies the function found in the class, if any.
Otherwise uses the class enumeration for computing the area recursively.
emptyArea: READONLY Area; -- corresponds to PipalReal.emptyRectangle
fullArea: READONLY Area; -- corresponds to PipalReal.fullRectangle
IsEmptyArea: PROC [area: Area] RETURNS [BOOL];
Only returns whether the area enumerates some rectangle, but does not check that the enumerated rectangles are non-empty.
Might be slow.
AreaToRope: PROC [area: Area] RETURNS [Pipal.ROPE];
For debugging purposes.
CreateExplicitArea: PROC [rectangle: PipalReal.Rectangle] RETURNS [area: Area];
Creates an explicit area.
IntersectArea: PROC [area1, area2: Area] RETURNS [area: Area];
Creates an area that is the intersection of area1 and area2.
Fast (only creates a new object, slow at enumeration of the area).
SubArea: PROC [area1, area2: Area] RETURNS [area: Area];
Creates an area that is the intersection of area1 and the complement of area2.
Fast (only creates a new object, slow at enumeration of the area).
AreaOption: TYPE = {bboxChild, edgesChild, edgesChildren};
ChildArea: PROC [child: Pipal.Object, option: AreaOption] RETURNS [area: Area];
Area of such an annotation is
bboxChild => the BBox of child.
edgesChild => the 4 rectangles corresponding to the 4 edges of the BBox of child.
edgesChildren => 4 rectangles for each rectangle of the area of child.
CreatePaintAreaOutline: PROC [area: Area] RETURNS [annotation: Pipal.Annotation];
Creates a new PaintMethod annotation which, when painted, paints the outline of the area.
Paint Queue
RequestType: TYPE = {none, clearArea, paintArea, clearAndPaint, scale, other};
RequestFunction: TYPE = PROC [REF];
Request: TYPE = RECORD [
type: RequestType,
area: Area ← NIL,
data: REFNIL
];
SELECT type FROM
none   => used internally.
clearArea  => area is the area to be cleared.
paintArea  => area is the area to be painted. The object to be painted is in data. Sequentiality of paintArea requests is guaranteed.
clearAndPaint => short cut for clearArea followed by paintArea.
scale  => change of context. New context transformation is data. All previous paintArea requests are discarded. Usually foolowed by a clear and repaint of the whole viewer. When dequeued, the effect is usually to change the viewer context.
other  => other request, undisturbed by any optimization, and sequential. Fileds data and area might be used.
Queue: TYPE = PRIVATE REF QueueRec;
QueueRec: PRIVATE TYPE = MONITORED RECORD [
start: NAT, -- first request to be unqueued
size: NAT, -- number of requests to be unqueued
requests: REF Requests -- grows as queue fills
];
Requests: PRIVATE TYPE = RECORD [SEQUENCE max: NAT OF Request];
Contents must be de-referencable.
RequestToRope: PROC [request: Request] RETURNS [Pipal.ROPE];
For debugging purposes.
CreateQueue: PROC RETURNS [queue: Queue];
IsQueueEmpty: PROC [queue: Queue] RETURNS [BOOL];
Not monitored (=> just a hint).
Enqueue: PROC [queue: Queue, request: Request, reverse: BOOLFALSE];
reverse argument allows stopping by enqueuing to do requests.
Monitored.
Optimizes queue:
clearArea are composed with previous paintArea and clearArea;
paintArea are composed with previous paintArea with the same data;
scale get rid of previous paintArea and clearArea;
other is left undisturbed.
Dequeue: PROC [queue: Queue] RETURNS [empty: BOOL, request: Request];
Cannot return a request of type none.
Monitored.
Lower-level Utilities
For writing Pipal PaintProcs, or viewer PaintProcs.
ClearArea: PROC [context: Imager.Context, area: Area];
Fills area with white.
ClipAndPaint: PROC [context: Imager.Context, object: Pipal.Object, clipArea: Area];
Clips according to clipArea and then does a standard Paint.
ClearClipAndPaint: PROC [context: Imager.Context, object: Pipal.Object, clipArea: Area];
Clears and clips according to clipArea and then does a standard Paint.
PaintOutline: PROC [context: Imager.Context, r: PipalReal.Rectangle, color: Color ← Imager.black];
Paints 4 vectors corresponding to the given outline.
PaintAreaOutline: PROC [context: Imager.Context, area: Area, color: Color ← Imager.black];
Paints the outline of the area in the given color
PaintArea: PROC [context: Imager.Context, area: Area, color: Color ← Imager.black];
Paints the area in the given color
PaintText: PROC [context: Imager.Context, contents: Pipal.ROPE, font: Imager.Font, color: Color ← Imager.black];
Paints a text.
PaintFlippedText: PROC [context: Imager.Context, contents: Pipal.ROPE, font: Imager.Font, bbox: PipalInt.Rectangle, color: Color ← Imager.black];
Paints a text, while flipping it if necessary.
invertingBlack: Imager.Color;
invertingLightGray: Imager.Color;
invertingDarkGray: Imager.Color;
GetBounds: PROC [context: Imager.Context] RETURNS [bounds: PipalReal.Rectangle];
Returns the current bounds of the context (i.e. the area that will end up really on the display). Might return PipalReal.fullRectangle if the context does not know how to get this information.
SetColor: PROC [context: Imager.Context, color: Color];
Same as Imager.SetColor, but only sets the color when it is different than current (and when the context knows how to handle that!)!
END.