PipalInt.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Louis Monier January 15, 1988 11:24:39 pm PST
Bertrand Serlet May 18, 1988 12:11:00 pm PDT
Barth, January 26, 1988 11:30:32 am PST
Types
Number: TYPE = INT32;
infinity: Number =
LAST [Number]/2;
Vector:
TYPE =
RECORD [
x: Number, -- horizontal dimension, going right
y: Number]; -- vertical dimension, going down
Position: TYPE = Vector; -- alias when a vector expresses a position
Size: TYPE = Vector; -- alias when a vector expresses a size
zeroVector: Vector = [0, 0];
emptySize: Size = [-infinity, -infinity];
Interval:
TYPE =
RECORD [
base: Number,
size: Number];
size<=0 <=> empty interval. All empty intervals are legal. Intervals are closed at the base and open at the extremity. If anyone can tell us why this should be so please do.
Rectangle:
TYPE =
RECORD [
base: Vector,
size: Size];
size.x<=0 or size.y<=0 <=> empty rectangle. All empty rectangles are legal
emptyRectangle: Rectangle = [[infinity/2, infinity/2], emptySize];
fullRectangle: Rectangle = [[-infinity/2, -infinity/2], [infinity, infinity]];
RectangleProc:
TYPE =
PROC [rect: Rectangle]
RETURNS [quit:
BOOL ←
FALSE];
Standard types for enumerations of rectangles.
Orientation:
TYPE =
MACHINE
DEPENDENT {identity(0), mirrorX(1), rotate90(2), rotate90X(3), rotate180(4), rotate180X(5), rotate270(6), rotate270X(7)};
An orientation represents an anticlockwise rotation maybe followed by a reflection in x.
[Reflection in x means: modify x coordinates, leave y coordinates]
Transformation:
TYPE =
RECORD [translation: Vector ← zeroVector, orientation: Orientation ← identity];
A transformation represents an orientation followed by a translation.
Printing Utilities
VectorToRope: PROC [v: Vector] RETURNS [Pipal.ROPE];
RectangleToRope: PROC [r: Rectangle] RETURNS [Pipal.ROPE];
OrientationToRope: PROC [o: Orientation] RETURNS [Pipal.ROPE];
TransformationToRope: PROC [t: Transformation] RETURNS [Pipal.ROPE];
Interval Operations
IntersectionIntervals: PROC [i1, i2: Interval] RETURNS [Interval];
UnionIntervals:
PROC [i1, i2: Interval]
RETURNS [Interval];
DoIntervalsIntersect: PROC [i1, i2: Interval] RETURNS [BOOL];
IsInsideInterval:
PROC [container, candidate: Interval]
RETURNS [
BOOL];
Returns TRUE iff candidate is inside of container.
IsInsideIntervalNumber:
PROC [container: Interval, candidate: Number]
RETURNS [
BOOL];
Returns TRUE iff candidate is inside of container.
Extremity is included.
Rectangle Operations
Transformations
Translate:
PROC [r: Rectangle, v: Vector]
RETURNS [Rectangle];
Extend:
PROC [r: Rectangle, n: Number]
RETURNS [Rectangle];
IntersectBox:
PROC [r1, r2: Rectangle]
RETURNS [Rectangle];
fullRectangle is a neutral element for this operation.
BoundingBox:
PROC [r1, r2: Rectangle]
RETURNS [Rectangle];
emptyRectangle is a neutral element for this operation.
BoundingRectangle:
PROC [p1, p2: Position]
RETURNS [Rectangle];
no neutral element for this operation.
Predicates
IsDegeneratedRectangle: PROC [r: Rectangle] RETURNS [BOOL];
IsEmptyRectangle: PROC [r: Rectangle] RETURNS [BOOL];
DoRectanglesIntersect:
PROC [r1, r2: Rectangle]
RETURNS [
BOOL];
Returns TRUE iff r1 and r2 have some common points or border; TRUE if rects touch on a single point.
IsInsideRectangle: PROC [container, candidate: Rectangle] RETURNS [BOOL];
IsInsidePoint: PROC [container: Rectangle, candidate: Position] RETURNS [BOOL];
Others
AlwaysQuit: RectangleProc;
Extremity:
PROC [r: Rectangle]
RETURNS [Position];
DecomposeRect:
PROC [r, clip: Rectangle, inside, outside: RectangleProc ←
NIL]
RETURNS [quit:
BOOL ←
FALSE];
Calls inside [part of r inside of clip] and outside [parts of r outside of clip].
Border points might be part of both calls.
NIL call backs means discard.
Center:
PROC [r: Rectangle]
RETURNS [Position];
Returns center of rect r
Enumeration Method
enumerateMethod: Pipal.Method;
EachChildProc: TYPE = PROC [transformation: Transformation, child: Pipal.Object] RETURNS [quit: BOOL ← FALSE];
EnumerateProc:
TYPE =
PROC [object: Pipal.Object, each: EachChildProc, transformation: Transformation ← []]
RETURNS [quit:
BOOL ← FALSE];
Enumerates all children of an object.
There is an implicit overlay to compose all children.
HasEnumerate: PROC [object: Pipal.Object] RETURNS [BOOL];
Enumerate: EnumerateProc;
Short cut for applying the enumerate method.
No enumerate method => crash and burn.
Successive invocations with the same object should apply each in the same order.
NthChild:
PROC [object: Pipal.Object, transformation: Transformation ← [], rank:
NAT ← 0]
RETURNS [nthTrans: Transformation, nthChild: Pipal.Object ←
NIL];
Returns the Nth child, 0 being of course the first child, NIL if no such child.
CountChildren:
PROC [object: Pipal.Object]
RETURNS [count:
NAT];
Returns the number of children obtained by enumeration.
Size Method
sizeMethod: Pipal.Method;
bboxMethod: Pipal.Method;
SizeProc: TYPE = PROC [object: Pipal.Object] RETURNS [size: Size];
BBoxProc:
TYPE =
PROC [object: Pipal.Object, transformation: Transformation]
RETURNS [bbox: Rectangle];
ObjectSize: SizeProc;
Short cut for applying the size method.
Default when no size method is found is:
Compute the size by computing the size of the bounding box of children.
No enumerate method => crash and burn.
No child => emptySize
BBox: BBoxProc;
Computes the bounding box of an object, in the context of an overlay.
CachedSizeFromEnumerate: SizeProc;
Computes the size by enumeration and caches its result.
CachedBBoxFromEnumerate: BBoxProc;
Computes the bbox by enumeration and caches its result.
AbutBox Method
abutBoxMethod: Pipal.Method;
AbutBoxProc: TYPE = PROC [object: Pipal.Object] RETURNS [abutBox: Rectangle];
AbutBox: AbutBoxProc;
Short cut for applying the abutBox method.
Default when no abutBox method is found is:
Computes the abutBox by computing the bounding box of children.
No enumerate method => crash and burn.
No child => emptyRectangle
AbutBoxFromSize: AbutBoxProc;
Returns [[0, 0], ObjectSize[object]].
For use by atomic classes which do not fiddle the abutBox.
CachedAbutBoxFromEnumerate: AbutBoxProc;
Computes the abutbox by enumeration and caches its result.
Geometrical Classes
General Transform
transformClass: Pipal.Class;
Transform: TYPE = REF TransformRec;
TransformRec:
TYPE =
RECORD [
transformation: Transformation,
child: Pipal.Object];
CreateTransform: PROC [transformation: Transformation, child: Pipal.Object] RETURNS [transform: Transform];
Translation
translationClass: Pipal.Class;
Translation: TYPE = REF TranslationRec;
TranslationRec:
TYPE =
RECORD [
vector: Vector,
child: Pipal.Object];
CreateTranslation: PROC [vector: Vector, child: Pipal.Object] RETURNS [translation: Translation];
Orient
orientClass: Pipal.Class;
Orient: TYPE = REF OrientRec;
OrientRec:
TYPE =
RECORD [
orientation: Orientation,
child: Pipal.Object];
CreateOrient: PROC [orientation: Orientation, child: Pipal.Object] RETURNS [orient: Orient];
Compacted creation of objects
TransformObject:
PROC [transformation: Transformation, child: Pipal.Object]
RETURNS [Pipal.Object];
Creates the densest object possible.
Might even return child itself if the transformation is the identity.
Miscellaneous
HashByEnumeration: Pipal.HashProc;
Uses Enumerate on children to compute hash.
CachedHashByEnumeration: Pipal.HashProc;
Same as previous, but caches its result.
HashObjectSize: Pipal.HashProc;
EqualByEnumeration: Pipal.EqualProc;
Uses Enumerate on children to decide whether equal.
AtEdge:
PROC [abutBox: Rectangle, trans: Transformation, object: Pipal.Object]
RETURNS [
BOOL];
Returns TRUE iff transformed object touches or extends beyond abutBox.