<> <> 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.