PipalReal.mesa 
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Louis Monier January 14, 1988 12:56:05 pm PST
Bertrand Serlet May 12, 1988 10:34:42 pm PDT
Barth, January 26, 1988 11:40:48 am PST
DIRECTORY Imager, Pipal, PipalInt, Real;
PipalReal: CEDAR DEFINITIONS = BEGIN
Theory
Type definitions and basic operations for Pipal real data types. Real types are used for layout and schematics painting, or for capture of device independent data. Refer to Imager documentation for more information on the geometrical data structures.
Types
Number: TYPE = REAL;
infinity: Number = Real.LargestNumber/16;
Vector: TYPE = Imager.VEC;
Position: TYPE = Vector; -- alias when a Vector expresses a position
Size: TYPE = Vector; -- alias when a Vector expresses a size
zeroVector: Vector = Imager.zeroVEC;
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: BOOLFALSE];
Standard types for enumerations of rectangles.
Transformation: TYPE = Imager.Transformation;
Printing Utilities
VectorToRope: PROC [v: Vector] RETURNS [Pipal.ROPE];
RectangleToRope: PROC [r: Rectangle] RETURNS [Pipal.ROPE];
TransformationToRope: PROC [t: Transformation] RETURNS [Pipal.ROPE];
Vector Operations
Transformations
Add: PROC [v1, v2: Vector] RETURNS [Vector];
Sum, v1+v2.
Sub: PROC [v1, v2: Vector] RETURNS [Vector];
Difference, v1-v2.
Min: PROC [v1, v2: Vector] RETURNS [Vector];
Max: PROC [v1, v2: Vector] RETURNS [Vector];
Neg: PROC [v: Vector] RETURNS [Vector];
Negative, -v.
Predicates
IsDegeneratedSize: PROC [s: Size] RETURNS [BOOL];
Returns TRUE iff s.x<0 OR s.y<0.
IsEmptySize: PROC [s: Size] RETURNS [BOOL];
Returns TRUE iff s.x<=0 OR s.y<=0.
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: BOOLFALSE];
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
Transformation Operations
Application
TransformVector: PROC [t: Transformation, v: Vector] RETURNS [Vector];
TransformBBox: PROC [t: Transformation, s: Size] RETURNS [Rectangle];
Same as TransformRectangle[t, [zeroVector, s]];
TransformRectangle: PROC [t: Transformation, r: Rectangle] RETURNS [Rectangle];
Composition
Compose: PROC [t1, t2: Transformation] RETURNS [Transformation];
For each position p, the following equality holds:
TransformVector [Compose [t1, t2], p] = TransformVector [t1, TransformVector [t2, p]]
Expensive: a new Transformation is created.
Apply: PROC [t1, t2: Transformation];
Equivalent to t1^ ← Compose[t1, IntToRealTransformation[t2]]^.
Careful: t1 is modified in place.
Creation, Destruction and Equality
CreateTransformation: PROC RETURNS [Transformation];
Creates an identity transformation.
CopyTransformation: PROC [t: Transformation] RETURNS [Transformation];
Returns a copy of t.
DestroyTransformation: PROC [t: Transformation];
Asserts the Transformation is available for re-use.
EqualTransformation: PROC [t1, t2: Transformation] RETURNS [BOOL];
Returns TRUE if t1 and t2 are close.
Basic Methods
Enumeration
enumerateMethod: Pipal.Method;
EachChildProc: TYPE = PROC [transformation: Transformation, child: Pipal.Object] RETURNS [quit: BOOLFALSE];
transformation should not be modified at exit.
EnumerateProc: TYPE = PROC [object: Pipal.Object, each: EachChildProc, transformation: Transformation] RETURNS [quit: BOOLFALSE];
Enumerates all children of an object.
There is an implicit overlay to compose all children.
In order to be efficient, it is OK to modify transformation in place. However, at exit, transformation should be the same as at entry, even if quit.
HasEnumerate: PROC [object: Pipal.Object] RETURNS [BOOL];
Enumerate: EnumerateProc;
Applies the enumerate method.
No enumerate method => all children are enumerated using PipalInt.Enumerate.
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.
nthTrans is a new transformation.
CountChildren: PROC [object: Pipal.Object] RETURNS [count: NAT];
Returns the number of children obtained by enumeration.
Size
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.
UseIntSize: SizeProc;
Calls PipalInt.ObjectSize.
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];
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.
Coercion from PipalInt Types
IntToRealVector: PROC [v: PipalInt.Vector] RETURNS [Vector];
IntToRealRectangle: PROC [r: PipalInt.Rectangle] RETURNS [Rectangle];
IntToRealTransformation: PROC [t: PipalInt.Transformation] RETURNS [Transformation];
ApplyRealInt: PROC [t1: Transformation, t2: PipalInt.Transformation];
Equivalent to t1^ ← Compose[t1, IntToRealTransformation[t2]]^.
Careful: t1 is modified in place.
END.