DIRECTORY Basics, IO, Pipal, PipalInt, PipalIntInline, RefTab; PipalIntImpl: CEDAR PROGRAM IMPORTS Basics, IO, Pipal, PipalIntInline, RefTab EXPORTS PipalInt, PipalIntInline = BEGIN OPEN PipalInt; VectorToRope: PUBLIC PROC [v: Vector] RETURNS [rope: Pipal.ROPE] = { rope _ IO.PutFR["[%g, %g]", IO.int[v.x], IO.int[v.y]]; }; RectangleToRope: PUBLIC PROC [r: Rectangle] RETURNS [rope: Pipal.ROPE] = { rope _ IO.PutFR["[base: %g, size: %g]", IO.rope[VectorToRope[r.base]], IO.rope[VectorToRope[r.size]]]; }; OrientationToRope: PUBLIC PROC [o: Orientation] RETURNS [rope: Pipal.ROPE] = { rope _ SELECT o FROM identity => "identity", mirrorX => "mirrorX", rotate90 => "rotate90", rotate90X => "rotate90X", rotate180 => "rotate180", rotate180X => "rotate180X", rotate270 => "rotate270", rotate270X => "rotate270X", ENDCASE => ERROR; }; TransformationToRope: PUBLIC PROC [t: Transformation] RETURNS [rope: Pipal.ROPE] = { rope _ IO.PutFR["[%g, %g]", IO.rope[VectorToRope[t.translation]], IO.rope[OrientationToRope[t.orientation]]]; }; Add: PUBLIC PROC [v1, v2: Vector] RETURNS [Vector] = { RETURN [PipalIntInline.Add[v1, v2]] }; Sub: PUBLIC PROC [v1, v2: Vector] RETURNS [Vector] = { RETURN [PipalIntInline.Sub[v1, v2]] }; Min: PUBLIC PROC [v1, v2: Vector] RETURNS [Vector] = { RETURN [PipalIntInline.Min[v1, v2]] }; Max: PUBLIC PROC [v1, v2: Vector] RETURNS [Vector] = { RETURN [PipalIntInline.Max[v1, v2]] }; Neg: PUBLIC PROC [v: Vector] RETURNS [Vector] = { RETURN [PipalIntInline.Neg[v]] }; IsDegeneratedSize: PUBLIC PROC [s: Size] RETURNS [BOOL] = { RETURN [PipalIntInline.IsDegeneratedSize[s]] }; IsEmptySize: PUBLIC PROC [s: Size] RETURNS [BOOL] = { RETURN [PipalIntInline.IsEmptySize[s]] }; IntersectionIntervals: PUBLIC PROC [i1, i2: Interval] RETURNS [Interval] = {RETURN [PipalIntInline.IntersectionIntervals[i1, i2]] }; UnionIntervals: PUBLIC PROC [i1, i2: Interval] RETURNS [Interval] = {RETURN [PipalIntInline.UnionIntervals[i1, i2]] }; DoIntervalsIntersect: PUBLIC PROC [i1, i2: Interval] RETURNS [BOOL] = { RETURN [PipalIntInline.DoIntervalsIntersect[i1, i2]] }; IsInsideInterval: PUBLIC PROC [container, candidate: Interval] RETURNS [BOOL] = { RETURN [PipalIntInline.IsInsideInterval[container, candidate]] }; IsInsideIntervalNumber: PUBLIC PROC [container: Interval, candidate: Number] RETURNS [BOOL] = { RETURN [PipalIntInline.IsInsideIntervalNumber[container, candidate]] }; Translate: PUBLIC PROC [r: Rectangle, v: Vector] RETURNS [Rectangle] = { RETURN [PipalIntInline.Translate[r, v]] }; Extend: PUBLIC PROC [r: Rectangle, n: Number] RETURNS [Rectangle] = { RETURN [[[r.base.x-n, r.base.y-n], [r.size.x+n+n, r.size.y+n+n]]] }; IntersectBox: PUBLIC PROC [r1, r2: Rectangle] RETURNS [r: Rectangle] = { r.base _ PipalIntInline.Max[r1.base, r2.base]; r.size _ PipalIntInline.Sub[PipalIntInline.Min[PipalIntInline.Extremity[r1], PipalIntInline.Extremity[r2]], r.base]; }; BoundingBox: PUBLIC PROC [r1, r2: Rectangle] RETURNS [r: Rectangle] = { r.base _ PipalIntInline.Min[r1.base, r2.base]; r.size _ PipalIntInline.Sub[PipalIntInline.Max[PipalIntInline.Extremity[r1], PipalIntInline.Extremity[r2]], r.base]; }; BoundingRectangle: PUBLIC PROC [p1, p2: Position] RETURNS [r: Rectangle] = { r.base _ PipalIntInline.Min[p1, p2]; r.size _ PipalIntInline.Sub[PipalIntInline.Max[p1, p2], r.base]; }; IsDegeneratedRectangle: PUBLIC PROC [r: Rectangle] RETURNS [BOOL] = { RETURN [PipalIntInline.IsDegeneratedRectangle[r]] }; IsEmptyRectangle: PUBLIC PROC [r: Rectangle] RETURNS [BOOL] = { RETURN [PipalIntInline.IsEmptyRectangle[r]] }; DoRectanglesIntersect: PUBLIC PROC [r1, r2: Rectangle] RETURNS [BOOL] = { RETURN [PipalIntInline.DoRectanglesIntersect[r1, r2]] }; IsInsideRectangle: PUBLIC PROC [container, candidate: Rectangle] RETURNS [BOOL] = { RETURN [PipalIntInline.IsInsideRectangle[container, candidate]] }; IsInsidePoint: PUBLIC PROC [container: Rectangle, candidate: Position] RETURNS [BOOL] = { RETURN [PipalIntInline.IsInsidePoint[container, candidate]] }; AlwaysQuit: PUBLIC RectangleProc = {quit _ TRUE}; Extremity: PUBLIC PROC [r: Rectangle] RETURNS [Position] = { RETURN [PipalIntInline.Extremity[r]] }; DecomposeRect: PUBLIC PROC [r, clip: Rectangle, inside, outside: RectangleProc _ NIL] RETURNS [quit: BOOL _ FALSE] = { clipext: Position = PipalIntInline.Extremity[clip]; rext: Position = PipalIntInline.Extremity[r]; delta: Vector = PipalIntInline.Sub[r.base, clip.base]; IF clip.base.x RETURN [[+v.x, +v.y]]; mirrorX => RETURN [[-v.x, +v.y]]; rotate90 => RETURN [[-v.y, +v.x]]; rotate90X => RETURN [[+v.y, +v.x]]; rotate180 => RETURN [[-v.x, -v.y]]; rotate180X => RETURN [[+v.x, -v.y]]; rotate270 => RETURN [[+v.y, -v.x]]; rotate270X => RETURN [[-v.y, -v.x]]; ENDCASE => ERROR; }; TransformVector: PUBLIC PROC [t: Transformation, v: Vector] RETURNS [Vector] = { RETURN [PipalIntInline.Add[t.translation, OrientVector[t.orientation, v]]]; }; TransformBBox: PUBLIC PROC [t: Transformation, s: Size] RETURNS [Rectangle] = { RETURN [TransformRectangle[t, [zeroVector, s]]]; }; TransformRectangle: PUBLIC PROC [t: Transformation, r: Rectangle] RETURNS [Rectangle] = { RETURN [PipalIntInline.Translate[ [SELECT t.orientation FROM identity => [+r.base.x, +r.base.y], mirrorX => [-r.base.x-r.size.x, +r.base.y], rotate90 => [-r.base.y-r.size.y, +r.base.x], rotate90X => [+r.base.y, +r.base.x], rotate180 => [-r.base.x-r.size.x, -r.base.y-r.size.y], rotate180X => [+r.base.x, -r.base.y-r.size.y], rotate270 => [+r.base.y, -r.base.x-r.size.x], rotate270X => [-r.base.y-r.size.y, -r.base.x-r.size.x], ENDCASE => ERROR, PipalIntInline.OrientSize[t.orientation, r.size]], t.translation ]]; }; Compose: PUBLIC PROC [t1, t2: Transformation] RETURNS [Transformation] = { RETURN [[TransformVector[t1, t2.translation], PipalIntInline.ComposeOrientation[t1.orientation, t2.orientation]]]; }; enumerateMethod: PUBLIC Pipal.Method _ Pipal.RegisterMethod["IntEnumerate"]; HasEnumerate: PUBLIC PROC [object: Pipal.Object] RETURNS [BOOL] = { RETURN [Pipal.ObjectMethod[object, enumerateMethod]#NIL]; }; Enumerate: PUBLIC EnumerateProc = { quit _ (NARROW [Pipal.ObjectMethod[object, enumerateMethod], REF EnumerateProc]^)[object, each, transformation]; }; NthChild: PUBLIC PROC [object: Pipal.Object, transformation: Transformation _ [], rank: NAT _ 0] RETURNS [nthTrans: Transformation, nthChild: Pipal.Object _ NIL] = { EachChild: EachChildProc = { IF rank=0 THEN {nthChild _ child; nthTrans _ transformation; quit _ TRUE} ELSE rank _ rank - 1; }; [] _ Enumerate[object, EachChild, transformation]; }; CountChildren: PUBLIC PROC [object: Pipal.Object] RETURNS [count: NAT _ 0] = { EachChild: EachChildProc = {count _ count + 1}; [] _ Enumerate[object, EachChild]; }; sizeMethod: PUBLIC Pipal.Method _ Pipal.RegisterMethod["IntSize"]; bboxMethod: PUBLIC Pipal.Method _ Pipal.RegisterMethod["IntBBox"]; ObjectSize: PUBLIC SizeProc = { ref: REF = Pipal.ObjectMethod[object, sizeMethod]; size _ (IF ref=NIL THEN SizeFromEnumerate ELSE NARROW [ref, REF SizeProc]^)[object]; }; BBox: PUBLIC BBoxProc = { ref: REF = Pipal.ObjectMethod[object, bboxMethod]; bbox _ (SELECT TRUE FROM ref#NIL => (NARROW [ref, REF BBoxProc]^), HasEnumerate[object] => BBoxFromEnumerate, ENDCASE => BBoxFromSize)[object, transformation]; }; SizeFromEnumerate: SizeProc = { RETURN [BBoxFromEnumerate[object, []].size]; }; BBoxFromEnumerate: BBoxProc = { ComputeBBoxRec: EachChildProc = { bbox _ BoundingBox[bbox, BBox[child, transformation]]; }; bbox _ emptyRectangle; [] _ Enumerate[object, ComputeBBoxRec, transformation]; }; BBoxFromSize: BBoxProc = { bbox _ TransformRectangle[transformation, [zeroVector, ObjectSize[object]]]; }; cachedSizes: Pipal.ObjectCache _ Pipal.CreateObjectCache[]; CachedSizeFromEnumerate: PUBLIC SizeProc = { refSize: REF Size _ NARROW [RefTab.Fetch[cachedSizes, object].val]; IF refSize#NIL THEN RETURN [refSize^]; size _ SizeFromEnumerate[object]; refSize _ NEW [Size _ size]; [] _ RefTab.Store[cachedSizes, object, refSize]; }; cachedBBoxes: Pipal.ObjectCache _ Pipal.CreateObjectCache[]; CachedBBoxFromEnumerate: PUBLIC BBoxProc = { refBBox: REF Rectangle _ NARROW [RefTab.Fetch[cachedBBoxes, object].val]; IF refBBox#NIL THEN bbox _ refBBox^ ELSE { bbox _ BBoxFromEnumerate[object, []]; refBBox _ NEW [Rectangle _ bbox]; [] _ RefTab.Store[cachedBBoxes, object, refBBox]; }; bbox _ TransformRectangle[transformation, bbox]; }; abutBoxMethod: PUBLIC Pipal.Method _ Pipal.RegisterMethod["IntAbutBox"]; AbutBox: PUBLIC AbutBoxProc = { ref: REF = Pipal.ObjectMethod[object, abutBoxMethod]; abutBox _ (IF ref=NIL THEN AbutBoxFromEnumerate ELSE NARROW [ref, REF AbutBoxProc]^)[object]; }; AbutBoxFromEnumerate: AbutBoxProc = { ComputeBBox: EachChildProc = { abutBox _ BoundingBox[abutBox, TransformRectangle[transformation, AbutBox[child]]]; }; abutBox _ emptyRectangle; [] _ Enumerate[object, ComputeBBox]; }; AbutBoxFromSize: PUBLIC AbutBoxProc = { abutBox _ [zeroVector, ObjectSize[object]]; }; cachedAbutBoxes: Pipal.ObjectCache _ Pipal.CreateObjectCache[]; CachedAbutBoxFromEnumerate: PUBLIC AbutBoxProc = { refAbutBox: REF Rectangle _ NARROW [RefTab.Fetch[cachedAbutBoxes, object].val]; IF refAbutBox#NIL THEN RETURN [refAbutBox^]; abutBox _ AbutBoxFromEnumerate[object]; refAbutBox _ NEW [Rectangle _ abutBox]; [] _ RefTab.Store[cachedAbutBoxes, object, refAbutBox]; }; transformClass: PUBLIC Pipal.Class _ Pipal.RegisterClass["IntTransform", CODE [TransformRec]]; EnumerateTransform: EnumerateProc = { transform: Transform _ NARROW [object]; quit _ each[Compose[transformation, transform.transformation], transform.child]; }; DescribeTransform: Pipal.DescribeProc = { transform: Transform _ NARROW [object]; Pipal.PutIndent[out, indent, cr]; IO.PutF[out, "IntTransform %g of : ", IO.rope[TransformationToRope[transform.transformation]]]; Pipal.Describe[out, transform.child, indent+1, level-1, cr]; }; CreateTransform: PUBLIC PROC [transformation: Transformation, child: Pipal.Object] RETURNS [transform: Transform] = { transform _ NEW [TransformRec _ [transformation, child]]; }; translationClass: PUBLIC Pipal.Class _ Pipal.RegisterClass["IntTranslation", CODE [TranslationRec]]; EnumerateTranslation: EnumerateProc = { translation: Translation _ NARROW [object]; quit _ each[Compose[transformation, [translation.vector]], translation.child]; }; DescribeTranslation: Pipal.DescribeProc = { translation: Translation _ NARROW [object]; Pipal.PutIndent[out, indent, cr]; IO.PutF[out, "IntTranslation %g of : ", IO.rope[VectorToRope[translation.vector]]]; Pipal.Describe[out, translation.child, indent+1, level-1, cr]; }; CreateTranslation: PUBLIC PROC [vector: Vector, child: Pipal.Object] RETURNS [translation: Translation] = { translation _ NEW [TranslationRec _ [vector, child]]; }; orientClass: PUBLIC Pipal.Class _ Pipal.RegisterClass["IntOrient", CODE [OrientRec]]; EnumerateOrient: EnumerateProc = { orient: Orient _ NARROW [object]; quit _ each[Compose[transformation, [zeroVector, orient.orientation]], orient.child]; }; DescribeOrient: Pipal.DescribeProc = { orient: Orient _ NARROW [object]; Pipal.PutIndent[out, indent, cr]; IO.PutF[out, "IntOrient %g of : ", IO.rope[OrientationToRope[orient.orientation]]]; Pipal.Describe[out, orient.child, indent+1, level-1, cr]; }; CreateOrient: PUBLIC PROC [orientation: Orientation, child: Pipal.Object] RETURNS [orient: Orient] = { orient _ NEW [OrientRec _ [orientation, child]]; }; TransformObject: PUBLIC PROC [transformation: Transformation, child: Pipal.Object] RETURNS [Pipal.Object] = { RETURN [WITH child SELECT FROM transform: Transform => TransformObject[Compose[transformation, transform.transformation], transform.child], translation: Translation => TransformObject[Compose[transformation, [translation.vector]], translation.child], orient: Orient => TransformObject[Compose[transformation, [orientation: orient.orientation]], orient.child], ENDCASE => SELECT TRUE FROM transformation=[] => child, transformation.orientation=identity => CreateTranslation[transformation.translation, child], transformation.translation=zeroVector => CreateOrient[transformation.orientation, child], ENDCASE => CreateTransform[transformation, child] ]; }; abutBoxProp: PUBLIC ATOM _ $AbutBoxAnnotation; CreateAbutBoxAnnotation: PUBLIC PROC [child: Pipal.Object, rectangle: Rectangle] RETURNS [annotation: Pipal.Annotation] = { annotation _ Pipal.CreateAnnotation[child, abutBoxProp, NEW [Rectangle _ rectangle]]; }; abutClass: PUBLIC Pipal.Class _ Pipal.RegisterClass["IntAbut", CODE [AbutRec]]; EnumerateAbut: EnumerateProc = { abut: Abut _ NARROW [object]; pos: Position _ zeroVector; FOR i: NAT IN [0 .. abut.size) DO ab: Rectangle = AbutBox[abut[i]]; quit _ each[Compose[transformation, [Sub[pos, ab.base]]], abut[i]]; IF quit THEN RETURN; IF abut.inX THEN pos.x _ pos.x + ab.size.x ELSE pos.y _ pos.y + ab.size.y; ENDLOOP; }; DescribeAbut: Pipal.DescribeProc = { abut: Abut _ NARROW [object]; Pipal.PutIndent[out, indent, cr]; IO.PutF[out, "Abut in %g of: ", IO.rope[IF abut.inX THEN "X" ELSE "Y"]]; IF level=1 THEN {IO.PutRope[out, "..."]; RETURN}; FOR i: NAT IN [0 .. abut.size) DO Pipal.Describe[out, abut[i], indent+1, level-1, cr]; ENDLOOP; }; CreateAbut: PUBLIC PROC [inX: BOOL, children: Pipal.Objects] RETURNS [abut: Abut] = { size: NAT _ Pipal.Length[children]; abut _ NEW [AbutRec[size]]; abut.inX _ inX; FOR i: NAT IN [0 .. size) DO abut[i] _ children.first; children _ children.rest ENDLOOP; IF size#0 THEN { irs0: Size = AbutBox[abut[0]].size; FOR i: NAT IN [1 .. size) DO irs: Size = AbutBox[abut[i]].size; IF (IF inX THEN irs0.y#irs.y ELSE irs0.x#irs.x) THEN ERROR; -- incompatible x dimension for an abutY or incompatible y dimension for an abutX ENDLOOP; }; }; HashByEnumeration: PUBLIC Pipal.HashProc = { Each: EachChildProc = { hash _ hash + transformation.translation.x + transformation.translation.y + ORD [transformation.orientation] + Pipal.Hash[child] + 1; }; hash _ Pipal.HashObjectClass[object]; [] _ Enumerate[object, Each]; }; hashCache: Pipal.ObjectCache _ Pipal.CreateObjectCache[]; CachedHashByEnumeration: PUBLIC Pipal.HashProc = { refHash: REF CARD _ NARROW [RefTab.Fetch[hashCache, object].val]; IF refHash#NIL THEN RETURN [refHash^]; hash _ HashByEnumeration[object]; [] _ RefTab.Store[hashCache, object, NEW [CARD _ hash]]; }; HashObjectSize: PUBLIC Pipal.HashProc = { size: Size = ObjectSize[object]; hash _ size.x+size.y; }; EqualByEnumeration: PUBLIC Pipal.EqualProc = { size: NAT _ CountChildren[object1]; IF CountChildren[object2]#size THEN RETURN [FALSE]; FOR i: NAT IN [0 .. size) DO nthTrans1: Transformation; nthChild1: Pipal.Object; nthTrans2: Transformation; nthChild2: Pipal.Object; [nthTrans1, nthChild1] _ NthChild[object1]; [nthTrans2, nthChild2] _ NthChild[object2]; IF nthTrans1#nthTrans2 OR NOT Pipal.Equal[nthChild1, nthChild2] THEN RETURN [FALSE]; ENDLOOP; RETURN [TRUE]; }; AtEdge: PUBLIC PROC [abutBox: Rectangle, trans: Transformation, object: Pipal.Object] RETURNS [BOOL] = { RETURN [NOT IsInsideRectangle[Extend[abutBox, -1], BBox[object, trans]]]; }; composeTable: PUBLIC ARRAY Orientation OF ARRAY Orientation OF Orientation; ReallyComposeOrientation: PROC [o1, o2: Orientation] RETURNS [Orientation] = { refl1: [0..1] ~ Basics.BITAND[ORD[o1], 1]; rot2: [0..6] _ Basics.BITAND[ORD[o2], 6]; IF refl1#0 AND rot2#0 THEN rot2 _ 8-rot2; RETURN [VAL[Basics.BITAND[ Basics.BITAND[ORD[o1], 6] + rot2 + Basics.BITXOR[refl1, Basics.BITAND[ORD[o2], 1]], 7]]]; }; EnumerateOverlay: EnumerateProc ~ { overlay: Pipal.Overlay _ NARROW [object]; FOR i: NAT IN [0..overlay.size) DO IF each[transformation, overlay[i]] THEN RETURN[TRUE]; ENDLOOP; }; EnumerateIcon: EnumerateProc ~ { icon: Pipal.Icon _ NARROW [object]; quit _ each[transformation, icon.reference]; }; EnumerateAnnotation: EnumerateProc ~ { annotation: Pipal.Annotation _ NARROW [object]; quit _ each[transformation, annotation.child]; }; SizeAnnotation: SizeProc = { size _ BBoxAnnotation[object, []].size; }; BBoxAnnotation: BBoxProc = { annotation: Pipal.Annotation _ NARROW [object]; bbox _ BBox[annotation.child, transformation]; IF annotation.key=abutBoxProp THEN bbox _ BoundingBox[ bbox, TransformRectangle[transformation, (NARROW [annotation.value, REF Rectangle]^)] ]; }; AbutBoxAnnotation: AbutBoxProc = { annotation: Pipal.Annotation _ NARROW [object]; abutBox _ IF annotation.key=abutBoxProp THEN (NARROW [annotation.value, REF Rectangle]^) ELSE AbutBox[annotation.child]; }; FOR o1: Orientation IN Orientation DO FOR o2: Orientation IN Orientation DO composeTable[o1][o2] _ ReallyComposeOrientation[o2, o1]; ENDLOOP; ENDLOOP; Pipal.PutClassMethod[Pipal.overlayClass, enumerateMethod, NEW [EnumerateProc _ EnumerateOverlay]]; Pipal.PutClassMethod[Pipal.overlayClass, sizeMethod, NEW [SizeProc _ CachedSizeFromEnumerate]]; Pipal.PutClassMethod[Pipal.overlayClass, bboxMethod, NEW [BBoxProc _ CachedBBoxFromEnumerate]]; Pipal.PutClassMethod[Pipal.overlayClass, abutBoxMethod, NEW [AbutBoxProc _ CachedAbutBoxFromEnumerate]]; Pipal.PutClassMethod[Pipal.overlayClass, Pipal.hashMethod, NEW [Pipal.HashProc _ CachedHashByEnumeration]]; Pipal.PutClassMethod[Pipal.overlayClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualByEnumeration]]; Pipal.PutClassMethod[Pipal.iconClass, enumerateMethod, NEW [EnumerateProc _ EnumerateIcon]]; Pipal.PutClassMethod[Pipal.iconClass, Pipal.hashMethod, NEW [Pipal.HashProc _ HashByEnumeration]]; Pipal.PutClassMethod[Pipal.iconClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualByEnumeration]]; Pipal.PutClassMethod[Pipal.annotationClass, enumerateMethod, NEW [EnumerateProc _ EnumerateAnnotation]]; Pipal.PutClassMethod[Pipal.annotationClass, sizeMethod, NEW [SizeProc _ SizeAnnotation]]; Pipal.PutClassMethod[Pipal.annotationClass, bboxMethod, NEW [BBoxProc _ BBoxAnnotation]]; Pipal.PutClassMethod[Pipal.annotationClass, abutBoxMethod, NEW [AbutBoxProc _ AbutBoxAnnotation]]; Pipal.PutClassMethod[transformClass, enumerateMethod, NEW [EnumerateProc _ EnumerateTransform]]; Pipal.PutClassMethod[transformClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeTransform]]; Pipal.PutClassMethod[transformClass, Pipal.hashMethod, NEW [Pipal.HashProc _ HashByEnumeration]]; Pipal.PutClassMethod[transformClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualByEnumeration]]; Pipal.PutClassMethod[translationClass, enumerateMethod, NEW [EnumerateProc _ EnumerateTranslation]]; Pipal.PutClassMethod[translationClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeTranslation]]; Pipal.PutClassMethod[translationClass, Pipal.hashMethod, NEW [Pipal.HashProc _ HashByEnumeration]]; Pipal.PutClassMethod[translationClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualByEnumeration]]; Pipal.PutClassMethod[orientClass, enumerateMethod, NEW [EnumerateProc _ EnumerateOrient]]; Pipal.PutClassMethod[orientClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeOrient]]; Pipal.PutClassMethod[orientClass, Pipal.hashMethod, NEW [Pipal.HashProc _ HashByEnumeration]]; Pipal.PutClassMethod[orientClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualByEnumeration]]; Pipal.PutClassMethod[abutClass, enumerateMethod, NEW [EnumerateProc _ EnumerateAbut]]; Pipal.PutClassMethod[abutClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeAbut]]; Pipal.PutClassMethod[abutClass, Pipal.hashMethod, NEW [Pipal.HashProc _ CachedHashByEnumeration]]; Pipal.PutClassMethod[abutClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualByEnumeration]]; Pipal.PutClassMethod[abutClass, sizeMethod, NEW [SizeProc _ CachedSizeFromEnumerate]]; Pipal.PutClassMethod[abutClass, bboxMethod, NEW [BBoxProc _ CachedBBoxFromEnumerate]]; Pipal.PutClassMethod[abutClass, abutBoxMethod, NEW [AbutBoxProc _ CachedAbutBoxFromEnumerate]]; END. PipalIntImpl.mesa Copyright Σ 1985, 1987 by Xerox Corporation. All rights reserved. Bertrand Serlet May 18, 1988 12:10:59 pm PDT Louis Monier January 15, 1988 11:30:47 pm PST Printing Utilities Operations on Vectors Operations on Intervals Operations on Rectangles Transformations Could be optimized Could be optimized Could be inlined Predicates Others Operations on Transformations Can be inlined!!!! Can be inlined!!!! Can be inlined!!!! Can be inlined!!!! Can be inlined!!!! Enumeration Method Size Method It's kind of tricky: objects inherently have a size, but no bbox. However, within an overlay, objects have a bbox. The implementation reflects that situation, and the bbox and size methods play ping-pong. AbutBox Method Geometrical Classes General Transform Translation Could be optimized Orient Could be optimized Compacted creation of objects Abut-related Annotations and Classes Abut Box Annotation Abut Miscellaneous Initialization Rotation composition table This procedure produces the composite orientation obtained by first doing o1 and then doing o2. It uses the observation that a reflection in x followed by a z-degree clockwise rotation is the same as a (360-z)-degree clockwise rotation followed by a reflection in x. Thus if o1 contains a final reflection, then o2's rotation operates in reverse. Pipal Classes Rotation composition table Pipal Classes Classes defined in this interface Κ– "cedar" style˜codešœ™KšœB™BKšœ,™,Kšœ*Οk™-K™—Kš œ œ*˜>K˜•StartOfExpansion[]šΟn œœ˜Kšœ œ˜1Kšœ˜#Kšœœ ˜—head™š ž œœœ œœ˜DJšœœœ œ ˜6K˜—š žœœœœœ˜JJšœœœœ˜fK˜—š žœœœœœ˜Nšœœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœœ˜—K˜—š žœœœœœ˜TJšœœœ$œ)˜mK˜——™š žœœœœœ ˜]K˜—š žœœœœœ ˜]K˜—š žœœœœœ ˜]K˜—š žœœœœœ ˜]K˜—š žœœœ œœ˜SK˜—š žœœœ œœœ)˜kK˜—š ž œœœ œœœ#˜_K˜——™šžœœœœ ˜HKšœœ2˜;K˜—šžœœœœ ˜AKšœœ+˜4K˜—š žœœœœœ˜CKšœœ1˜;K˜—š žœœœ"œœ˜MKšœœ;˜EK˜—š žœœœ*œœœA˜§K˜——™™šž œœœœ ˜DKšœœ$˜.K˜—šžœœœœ ˜AKšœœ>˜HK˜—šž œœœœ˜HKšΟb™Kšœ.˜.Kšœt˜tK˜K˜—šž œœœœ˜GKšŸ™Kšœ.˜.Kšœt˜tK˜K˜—šžœœœœ˜LKšŸ™Kšœ$˜$Kšœ@˜@K˜——™ š žœœœœœ˜AKšœœ.˜8K˜—š žœœœœœ˜;Kšœœ(˜2K˜—š žœœœœœ˜EJšœœ2˜˜>K˜—šžœœœ'œ˜kKšœœ$˜5K˜——šœ™Kšœ œ0œ˜Ušžœ˜"KšŸ™Kšœœ ˜!KšœU˜UK˜—šžœ˜&Kšœœ ˜!Kšœ!˜!Kšœ!œ/˜TKšœ9˜9K˜—šž œœœ1œ˜fKšœ œ$˜0K˜——™šžœœœ7œ˜mšœœœ˜šœ˜KšœT˜T—šœ˜KšœR˜R—šœ˜KšœZ˜Z—šœœœ˜Kšœ˜Kšœ\˜\KšœY˜YKšœ*˜1—Kšœ˜—K˜K™———™$™šœ œœ˜.J˜—šžœœœ-œ#˜{Jšœ8œ˜UJ˜——™Kšœ œ.œ ˜Ošž œ˜ Kšœ œ ˜Kšœ˜šœœœ˜!Kšœ!˜!KšœC˜CJšœœœ˜Jšœ œœ˜JJšœ˜—K˜—šž œ˜$Kšœ œ ˜Jšœ!˜!Jš œœœ œœ˜HKšœ œœœ˜1šœœœ˜!Kšœ4˜4Kšœ˜ —K˜—š ž œœœœœ˜UJšœœ˜#Jšœœ˜Jšœ˜Jš œœœ œ4œ˜Xšœœ˜Jšœ#˜#šœœœ ˜Jšœ"˜"Jš œœœœœœΟcQ˜Jšœ˜—J˜—K˜———™ šžœœ˜,šžœ˜KšœLœ6˜…K˜—Jšœ%˜%Jšœ˜K˜K˜—Kšœ9˜9šžœœ˜2Kšœ œœœ'˜AKšœ œœœ ˜&Kšœ!˜!Kšœ%œœ ˜8K˜K˜—šžœœ˜)K˜ Kšœ˜K˜K˜—šžœœ˜.Kšœœ˜#Kšœœœœ˜3šœœœ ˜Kšœ3˜3Kšœ3˜3Kšœ+˜+Kšœ+˜+šœœœ"˜?Kšœœœ˜—Kšœ˜—Kšœœ˜K˜K˜—š žœœœCœœ˜hKšœœ>˜IK˜——™™š œœœ œœ œ ˜KK˜—šžœœœ˜NKšœά™άKšœœœ ˜*Kšœœœ ˜)Kšœ œœ˜)šœœœ˜Kš œœœœœœ ˜SKšœ˜—Kšœ˜——™ šžœ˜#Kšœœ ˜)šœœœ˜"Kšœ"œœœ˜6Kšœ˜—Kšœ˜K˜—šž œ˜ Kšœœ ˜#Kšœ,˜,Kšœ˜K˜—šžœ˜&Kšœœ ˜/Kšœ.˜.Kšœ˜K˜—šžœ˜Kšœ'˜'Kšœ˜K˜—šžœ˜Kšœœ ˜/Kšœ.˜.šœœ˜6Kšœ˜Kšœ$œœ˜OKšœ˜—Kšœ˜K˜—šžœ˜"Kšœœ ˜/šœ œ˜(Kšœœœ˜1Kšœ˜—Kšœ˜——™šœœ ˜%šœœ ˜%Kšœ8˜8Kšœ˜—Kšœ˜——™ Kšœ:œ%˜bKšœ5œ'˜_Kšœ5œ'˜_Kšœ8œ-˜hKšœ;œ-˜kšœ<œ)˜hK˜—Kšœ7œ"˜\Kšœ8œ'˜bšœ9œ)˜eK˜—Kšœ=œ(˜hKšœ8œ˜YKšœ8œ˜YKšœ;œ$˜b—™!Kšœ6œ'˜`Kšœ;œ+˜iKšœ7œ'˜aKšœ8œ)˜dK˜Kšœ8œ)˜dKšœ=œ-˜mKšœ9œ'˜cKšœ:œ)˜fK˜Kšœ3œ$˜ZKšœ8œ(˜cKšœ4œ'˜^Kšœ5œ)˜aK˜Kšœ1œ"˜VKšœ6œ&˜_Kšœ2œ-˜bKšœ3œ)˜_Kšœ,œ'˜VKšœ,œ'˜VKšœ/œ-˜_K˜—K˜—Kšœ˜K™—…—Ql)