DIRECTORY Environment USING [LongNumber], Inline USING [BITOR, BITAND, HighHalf], ImagerBasic USING [Context, Path, IntVec, IntRectangle, PixelArray, ClipperRecord, TransformRecord], ImagerTransform USING [IntTransform], Imager; ImagerMaskImpl: CEDAR PROGRAM IMPORTS ImagerTransform, Inline EXPORTS Imager = BEGIN OPEN ImagerBasic; MaskStroke: PUBLIC PROC [context: Context, path: Path] = {}; MaskFill: PUBLIC PROC [context: Context, path: Path] = {}; MaskPixel: PUBLIC PROC [context: Context, pixelArray: PixelArray] = {}; DrawTo: PUBLIC PROC [context: Context, p: IntVec] = { q: IntVec _ p; -- hold onto untransformed point p _ ImagerTransform.IntTransform[context.transform, p]; IF context.noClip THEN { OPEN context; deviceProcs.drawLine[currentIntPosition, p, currentSource.pxlValue]; } ELSE IF context.clipper.type = rectangle THEN { in: BOOLEAN; a, b: IntVec; [in, a, b] _ ClipEdgeByRectangle[context.clipper, context.currentIntPosition, p]; IF in THEN context.deviceProcs.drawLine[a, b, context.currentSource.pxlValue]; } ELSE ERROR; -- until paths are worked out - M. Plass? context.currentIntPosition _ p; }; DrawPath: PUBLIC PROC [context: Context, path: Path] = { }; FillRectangle: PUBLIC PROC [context: Context, area: IntRectangle] = { }; ClipEdgeByRectangle: PROC [clipper: ClipperRecord, a, b: IntVec] RETURNS [BOOLEAN, IntVec, IntVec] = { Out: TYPE = RECORD[bottom, top, left, right: BOOLEAN]; noneOut: Out = [FALSE, FALSE, FALSE, FALSE]; Code: PROC [x, y: INTEGER] RETURNS [Out] = INLINE { OPEN clipper; out: Out _ noneOut; IF x < xMin THEN out.left _ TRUE; IF x > xMax THEN out.right _ TRUE; IF y > yMax THEN out.top _ TRUE; IF y < yMin THEN out.bottom _ TRUE; RETURN [ out ]; }; ClipY: PROC [a, b: IntVec, xPos: INTEGER] RETURNS [INTEGER] = INLINE { t: Environment.LongNumber; t.high _ LOOPHOLE[xPos - a.x]; t.low _ LOOPHOLE[0]; RETURN[ a.y + LOOPHOLE[ Inline.HighHalf[ LOOPHOLE[t, LONG INTEGER] / (b.x - a.x) * (b.y - a.y)], INTEGER] ]; }; ClipX: PROC [a, b: IntVec, yPos: INTEGER] RETURNS [INTEGER] = INLINE { t: Environment.LongNumber; t.high _ LOOPHOLE[yPos - a.y]; t.low _ LOOPHOLE[0]; RETURN[ a.x + LOOPHOLE[ Inline.HighHalf[ LOOPHOLE[t, LONG INTEGER] / (b.y - a.y) * (b.x - a.x)], INTEGER] ]; }; aCode, bCode, out: Out; c: IntVec; WHILE TRUE DO aCode _ Code[a.x, a.y]; bCode _ Code[b.x, b.y]; IF Inline.BITOR[LOOPHOLE[aCode], LOOPHOLE[bCode]] = LOOPHOLE[0] THEN RETURN[TRUE, a, b]; IF Inline.BITAND[LOOPHOLE[aCode], LOOPHOLE[bCode]] # LOOPHOLE[0] THEN RETURN[ FALSE, a, b]; out _ IF aCode # noneOut THEN aCode ELSE bCode; SELECT TRUE FROM out.left => { c.x _ clipper.xMin; c.y _ ClipY[a, b, clipper.xMin]; }; out.right => { c.x _ clipper.xMax; c.y _ ClipY[a, b, clipper.xMax]; }; out.bottom => { c.y _ clipper.yMin; c.x _ ClipX[a, b, clipper.yMin]; }; out.top => { c.y _ clipper.yMax; c.x _ ClipX[a, b, clipper.yMax]; } ENDCASE; IF aCode = out THEN a _ c ELSE b _ c; ENDLOOP; ERROR; -- can't get here, supposedly }; END.  ImagerMaskImpl.mesa Last Edited by: Crow, May 31, 1983 3:20 pm Client-called Procedures Form a stencil of "width" thickness around a spine defined by "path". Connected path segments will be mitered together. If the first and last points of a trajectory coincide, the path will be closed and mitered. Use the path to outline an area to be filled with the source Use the supplied pixel array as the stencil. The origin of the pixel array will be placed at the origin of the client space. The samples will be assumed to be placed at one unit intervals in the client space. Fast Track. The width of lines, etc. is device dependent, approximately .1% page height. MoveTo: implemented in Imager.mesa Draw line using source for color Draw whole path using source for color Fill rectangular area with source Unpublicized Procedures Internal Procedures Trivial acceptance test Trivial rejection test Actual clipping necessary ΚW˜head™J™+šΟk ˜ Jšœ œ˜!Jšœ œœœ ˜+Jšœ œA˜TJšœ˜Jšœœ˜(Jšœ˜——šœ ˜Jšœ˜Jšœ˜J˜Jšœœœ ˜—™šΟn œ œ%˜<šœE™EJšœŽ™Ž——unitšžœ œ$˜:J™<—šž œ œ0˜GJšœΠ™Π—J™JšœY™YLšžœ™#šžœ œ"˜5J™ JšœΟc ˜6Jšœ7˜7Jšœ˜šœœ ˜JšœI˜I—šœ"˜)šœœ˜!JšœQ˜QJšœœD˜NJ˜—JšœœŸ)˜:—Jšœ˜Jšœ˜—šžœ œ#˜8J™&Jšœ˜—šž œ œ*˜EJ™!Jšœ˜—L˜—K™™Lšžœœ(˜Ašœœœ˜.Jšœœœœ˜6Jš œœœœœ˜,š žœœœœ œ˜3Jšœ ˜ Jšœ˜Jš œ œ œœ œ œ˜GJš œ œ œœ œœ˜EJšœ ˜J˜—š žœœœœœœ˜FJšœ˜Jšœ œœ˜4šœ œ˜Jš œœœœ œ˜T—J˜—š žœœœœœœ˜FJšœ˜Jšœ œœ˜4šœ œ˜Jš œœœœ œ˜T—J˜—Jšœ˜Jšœ ˜ šœœ˜ šœ0˜0J™—Jš œœœ œ œ˜@šœœœ˜J™—Jš œœœ œ œ˜Ašœœœ˜J™—Jšœœœœ˜0Jšœœ˜Jšœ#˜#Jšœ)˜)Jšœ$˜$Jšœ)˜)Jšœ%˜%Jšœ)˜)Jšœ"˜"Jšœ(˜(Jšœ˜Jšœ œœ˜%—Jšœ˜JšœŸ˜(Jšœ˜J˜—Jšœ˜——…— θί