DIRECTORY ImagerBox, ImagerTransformation, IO, Pipal, PipalInt, PipalReal, PipalRealInline, RefTab; PipalRealImpl: CEDAR PROGRAM IMPORTS ImagerTransformation, IO, Pipal, PipalInt, PipalRealInline, RefTab EXPORTS PipalReal, PipalRealInline = BEGIN OPEN PipalReal; VectorToRope: PUBLIC PROC [v: Vector] RETURNS [rope: Pipal.ROPE] = { rope _ IO.PutFR["[%g, %g]", IO.real[v.x], IO.real[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]]]; }; TransformationToRope: PUBLIC PROC [t: Transformation] RETURNS [rope: Pipal.ROPE] = { rope _ IO.PutFR["[...Transformation...]"]; }; Add: PUBLIC PROC [v1, v2: Vector] RETURNS [Vector] = { RETURN [PipalRealInline.Add[v1, v2]] }; Sub: PUBLIC PROC [v1, v2: Vector] RETURNS [Vector] = { RETURN [PipalRealInline.Sub[v1, v2]] }; Min: PUBLIC PROC [v1, v2: Vector] RETURNS [Vector] = { RETURN [PipalRealInline.Min[v1, v2]] }; Max: PUBLIC PROC [v1, v2: Vector] RETURNS [Vector] = { RETURN [PipalRealInline.Max[v1, v2]] }; Neg: PUBLIC PROC [v: Vector] RETURNS [Vector] = { RETURN [PipalRealInline.Neg[v]] }; IsDegeneratedSize: PUBLIC PROC [s: Size] RETURNS [BOOL] = { RETURN [PipalRealInline.IsDegeneratedSize[s]] }; IsEmptySize: PUBLIC PROC [s: Size] RETURNS [BOOL] = { RETURN [PipalRealInline.IsEmptySize[s]] }; IntersectionIntervals: PUBLIC PROC [i1, i2: Interval] RETURNS [Interval] = { RETURN [PipalRealInline.IntersectionIntervals[i1, i2]] }; UnionIntervals: PUBLIC PROC [i1, i2: Interval] RETURNS [Interval] = { RETURN [PipalRealInline.UnionIntervals[i1, i2]] }; DoIntervalsIntersect: PUBLIC PROC [i1, i2: Interval] RETURNS [BOOL] = { RETURN [PipalRealInline.DoIntervalsIntersect[i1, i2]] }; IsInsideInterval: PUBLIC PROC [container, candidate: Interval] RETURNS [BOOL] = { RETURN [PipalRealInline.IsInsideInterval[container, candidate]] }; IsInsideIntervalNumber: PUBLIC PROC [container: Interval, candidate: Number] RETURNS [BOOL] = { RETURN [PipalRealInline.IsInsideIntervalNumber[container, candidate]] }; Translate: PUBLIC PROC [r: Rectangle, v: Vector] RETURNS [Rectangle] = { RETURN [PipalRealInline.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 _ PipalRealInline.Max[r1.base, r2.base]; r.size _ PipalRealInline.Sub[PipalRealInline.Min[PipalRealInline.Extremity[r1], PipalRealInline.Extremity[r2]], r.base]; }; BoundingBox: PUBLIC PROC [r1, r2: Rectangle] RETURNS [r: Rectangle] = { r.base _ PipalRealInline.Min[r1.base, r2.base]; r.size _ PipalRealInline.Sub[PipalRealInline.Max[PipalRealInline.Extremity[r1], PipalRealInline.Extremity[r2]], r.base]; }; BoundingRectangle: PUBLIC PROC [p1, p2: Position] RETURNS [r: Rectangle] = { r.base _ PipalRealInline.Min[p1, p2]; r.size _ PipalRealInline.Sub[PipalRealInline.Max[p1, p2], r.base]; }; IsDegeneratedRectangle: PUBLIC PROC [r: Rectangle] RETURNS [BOOL] = { RETURN [PipalRealInline.IsDegeneratedRectangle[r]] }; IsEmptyRectangle: PUBLIC PROC [r: Rectangle] RETURNS [BOOL] = { RETURN [PipalRealInline.IsEmptyRectangle[r]] }; DoRectanglesIntersect: PUBLIC PROC [r1, r2: Rectangle] RETURNS [BOOL] = { RETURN [PipalRealInline.DoRectanglesIntersect[r1, r2]] }; IsInsideRectangle: PUBLIC PROC [container, candidate: Rectangle] RETURNS [BOOL] = { RETURN [PipalRealInline.IsInsideRectangle[container, candidate]] }; IsInsidePoint: PUBLIC PROC [container: Rectangle, candidate: Position] RETURNS [BOOL] = { RETURN [PipalRealInline.IsInsidePoint[container, candidate]] }; AlwaysQuit: PUBLIC RectangleProc = {quit _ TRUE}; Extremity: PUBLIC PROC [r: Rectangle] RETURNS [Position] = { RETURN [PipalRealInline.Extremity[r]] }; DecomposeRect: PUBLIC PROC [r, clip: Rectangle, inside, outside: RectangleProc _ NIL] RETURNS [quit: BOOL _ FALSE] = { clipext: Position = PipalRealInline.Extremity[clip]; rext: Position = PipalRealInline.Extremity[r]; delta: Vector = PipalRealInline.Sub[r.base, clip.base]; IF clip.base.x (NARROW [ref, REF BBoxProc]^), HasEnumerate[object] => BBoxFromEnumerate, ENDCASE => BBoxFromSize)[object, transformation]; }; UseIntSize: PUBLIC SizeProc = { size _ PipalRealInline.IntToRealVector[PipalInt.ObjectSize[object]]; }; SizeFromEnumerate: SizeProc = { transformation: Transformation _ CreateTransformation[]; size _ BBoxFromEnumerate[object, transformation].size; DestroyTransformation[transformation]; }; 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 { transformation: Transformation _ CreateTransformation[]; bbox _ BBoxFromEnumerate[object, transformation]; DestroyTransformation[transformation]; refBBox _ NEW [Rectangle _ bbox]; [] _ RefTab.Store[cachedBBoxes, object, refBBox]; }; bbox _ TransformRectangle[transformation, bbox]; }; transformClass: PUBLIC Pipal.Class _ Pipal.RegisterClass["RealTransform", CODE [TransformRec]]; EnumerateTransform: EnumerateProc = { transform: Transform _ NARROW [object]; rt: Transformation _ Compose[transformation, transform.transformation]; quit _ each[rt, transform.child]; DestroyTransformation[rt]; }; DescribeTransform: Pipal.DescribeProc = { transform: Transform _ NARROW [object]; Pipal.PutIndent[out, indent, cr]; IO.PutF[out, "RealTransform %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]]; }; identityTransformation: PRIVATE Transformation = CreateTransformation[]; TransformObject: PUBLIC PROC [transformation: Transformation, child: Pipal.Object] RETURNS [Pipal.Object] = { RETURN [SELECT TRUE FROM transformation=identityTransformation => child, ENDCASE => CreateTransform[transformation, child] ]; }; IntToRealVector: PUBLIC PROC [v: PipalInt.Vector] RETURNS [Vector] = {RETURN [PipalRealInline.IntToRealVector[v]]}; IntToRealRectangle: PUBLIC PROC [r: PipalInt.Rectangle] RETURNS [Rectangle] = {RETURN [PipalRealInline.IntToRealRectangle[r]]}; IntToRealTransformation: PUBLIC PROC [t: PipalInt.Transformation] RETURNS [Transformation] = {RETURN [PipalRealInline.IntToRealTransformation[t]]}; ApplyRealInt: PUBLIC PROC [t1: Transformation, t2: PipalInt.Transformation] = { rt: Transformation _ PipalRealInline.IntToRealTransformation[t2]; Apply[t1, rt]; DestroyTransformation[rt]; }; EnumerateOverlay: EnumerateProc ~ { overlay: Pipal.Overlay _ NARROW [object]; FOR i: NAT IN [0..overlay.size) DO IF each[transformation, overlay[i]] THEN RETURN[TRUE]; ENDLOOP; }; BBoxAnnotation: BBoxProc = { annotation: Pipal.Annotation _ NARROW [object]; bbox _ BBox[annotation.child, transformation]; IF annotation.key=PipalInt.abutBoxProp THEN bbox _ BoundingBox[ bbox, TransformRectangle[transformation, PipalRealInline.IntToRealRectangle[(NARROW [annotation.value, REF PipalInt.Rectangle]^)]] ]; }; Pipal.PutClassMethod[Pipal.overlayClass, enumerateMethod, NEW [EnumerateProc _ EnumerateOverlay]]; -- speed up only Pipal.PutClassMethod[Pipal.overlayClass, sizeMethod, NEW [SizeProc _ CachedSizeFromEnumerate]]; -- speed up only Pipal.PutClassMethod[Pipal.overlayClass, bboxMethod, NEW [BBoxProc _ CachedBBoxFromEnumerate]]; -- speed up only Pipal.PutClassMethod[Pipal.annotationClass, bboxMethod, NEW [BBoxProc _ BBoxAnnotation]]; Pipal.PutClassMethod[transformClass, enumerateMethod, NEW [EnumerateProc _ EnumerateTransform]]; Pipal.PutClassMethod[transformClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeTransform]]; END. ΨPipalRealImpl.mesa Copyright Σ 1985, 1987 by Xerox Corporation. All rights reserved. Bertrand Serlet May 17, 1988 2:19:43 pm PDT Louis Monier January 15, 1988 11:30:47 pm PST Barth, January 27, 1988 11:30:23 am 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 optimized and 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. Geometrical Classes General Transform Compacted creation of objects Coercion with PipalInt Types Can be optimized! Initialization Pipal classes functions Pipal classes Classes defined in this interface Κ §– "cedar" style˜codešœ™KšœB™BKšœ+™+Kšœ*Οk™-K™'K™—Kš œ"œ6˜cK˜•StartOfExpansion[]šΟn œœ˜Kšœœ*˜JKšœ˜%Kšœœ ˜—head™š ž œœœ œœ˜DJšœœœ œ ˜8K˜—š žœœœœœ˜JJšœœœœ˜fK˜—š žœœœœœ˜TJšœœ!˜*K˜——™š žœœœœœ!˜^K˜—š žœœœœœ!˜^K˜—š žœœœœœ!˜^K˜—š žœœœœœ!˜^K˜—š žœœœ œœ˜TK˜—š žœœœ œœœ*˜lK˜—š ž œœœ œœœ$˜`K˜——™šžœœœœ ˜HKšœœ3˜=K˜—šžœœœœ ˜AKšœœ,˜6K˜—š žœœœœœ˜CKšœœ2˜˜HK˜—šž œœœœ˜HKšΟb™Kšœ/˜/Kšœx˜xK˜K˜—šž œœœœ˜GKšŸ™Kšœ/˜/Kšœx˜xK˜K˜—šžœœœœ˜LKšŸ™Kšœ%˜%KšœB˜BK˜—K˜—™ š žœœœœœ˜AKšœœ/˜9K˜—š žœœœœœ˜;Kšœœ)˜3K˜—š žœœœœœ˜EJšœœ3˜=J˜—š žœœœ#œœ˜OJšœœ=˜GJ˜—š ž œœœ-œœ˜UJšœœ9˜CJ˜——™šž œœœ˜1K˜—šž œœœœ ˜8Jšœœ"˜,J˜—šž œœœ7œœœœ˜vKšœ4˜4Kšœ.˜.Kšœ7˜7šœœ˜Kšœ œœœ'˜ZKšœœœœ˜*Kšœ˜—šœœ˜Kš œ œœœ5œ˜zKšœœœœ˜*Kšœ˜—šœœ˜Kš œ œœœœ$˜hKšœœœœ˜*Kšœ˜—šœœ˜Kš œ œœœœ(œ˜‡Kšœœœœ˜*Kšœ˜—Kšœœœ&˜8šœ˜K˜——šžœœœœ ˜5Jšœœ0˜:J˜———™šžœœœ œ ˜PKšŸ™Kšœ(˜.K˜K˜—šž œœœœ˜OKšŸ™Jšœ*˜0K˜K˜—šžœœœ#œ˜]KšŸ ™ Kšœo˜oKšœ"˜"K˜K˜—šžœœœœ˜JKšŸ™Kšœ'˜-K˜K˜—šžœœœ˜/KšŸ™Kšœ,˜,K˜K˜—šžœœœœ˜>Kšœ2˜8J˜—šžœœœœ˜PKšœ!˜'J˜—šžœœœ9˜[K˜—Kš žœœœœœœ-˜—™šœœ6˜MK˜—š ž œœœœœ˜CKšœ.œ5œ˜uK˜K˜—šž œœ˜#Kšœœ/˜8Kš œœœœœœœ0˜oK˜K˜—šžœ˜"šž œ˜%Kšœ<˜œœ5œ˜ šž œ˜šœ˜ JšœJœ˜TJšœ˜—Jšœ˜—Jšœ2˜2K˜K˜—š ž œœœœ œ ˜NKšœ<˜