<> <> DIRECTORY Environment USING [LongNumber], Inline USING [BITOR, BITAND, HighHalf], ImagerBasic USING [Path, IntPair, IntRectangle, PixelArray, Transformation, StrokeEnds], ImagerTransform USING [IntTransform], ImagerDisplay USING [Mask], ImagerDisplayPrivate USING [ContextData], Imager USING [Context]; ImagerDisplayMaskImpl: CEDAR PROGRAM IMPORTS ImagerTransform, Inline EXPORTS Imager = BEGIN OPEN ImagerBasic; NotImplementedYet: PUBLIC SIGNAL = CODE; <> MaskStroke: PUBLIC PROC [context: Imager.Context, path: Path, width: REAL, strokeEnds: StrokeEnds] = { <
> <> displayContext: ImagerDisplayPrivate.ContextData = NARROW[context.data]; }; <<>> MaskFill: PUBLIC PROC [context: Imager.Context, path: Path] = { <> displayContext: ImagerDisplayPrivate.ContextData = NARROW[context.data]; }; MaskPixel: PUBLIC PROC [context: Imager.Context, pixelArray: PixelArray] = { <> displayContext: ImagerDisplayPrivate.ContextData = NARROW[context.data]; }; <<>> <> MoveTo: PUBLIC PROC [context: Imager.Context, p: IntPair] = { displayContext: ImagerDisplayPrivate.ContextData = NARROW[context.data]; displayContext.currentIntPosition _ ImagerTransform.IntTransform[p, displayContext.transform]; <> }; DrawTo: PUBLIC PROC [context: Imager.Context, p: IntPair] = { <> displayContext: ImagerDisplayPrivate.ContextData = NARROW[context.data]; q: IntPair _ p; -- hold onto untransformed point p _ ImagerTransform.IntTransform[p, displayContext.transform]; IF displayContext.noClip THEN { OPEN displayContext; deviceProcs.drawLine[currentIntPosition, p, currentPxlValue]; } ELSE IF displayContext.clipper.refRep = NIL -- rectangular? THEN { in: BOOLEAN; a, b: IntPair; [in, a, b] _ ClipEdgeByRectangle[displayContext.clipper, displayContext.currentIntPosition, p]; IF in THEN displayContext.deviceProcs.drawLine[a, b, displayContext.currentPxlValue]; } ELSE ERROR NotImplementedYet[]; -- until paths are worked out - M. Plass? displayContext.currentIntPosition _ p; }; DrawPath: PUBLIC PROC [context: Imager.Context, path: Path] = { <> }; FillRectangle: PUBLIC PROC [context: Imager.Context, area: IntRectangle] = { <> }; <> ClipEdgeByRectangle: PROC [clipper: ImagerDisplay.Mask, a, b: IntPair] RETURNS [BOOLEAN, IntPair, IntPair] = { 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 < fMin THEN out.left _ TRUE; IF x > fMin + fSize THEN out.right _ TRUE; IF y < sMin THEN out.bottom _ TRUE; IF y > sMin + sSize THEN out.top _ TRUE; RETURN [ out ]; }; ClipY: PROC [a, b: IntPair, xPos: INTEGER] RETURNS [INTEGER] = INLINE { t: Environment.LongNumber; t.high _ LOOPHOLE[xPos - a.x, UNSPECIFIED]; t.low _ LOOPHOLE[0, UNSPECIFIED]; RETURN[ a.y + LOOPHOLE[ Inline.HighHalf[ LOOPHOLE[t, LONG INTEGER] / (b.x - a.x) * (b.y - a.y)], INTEGER] ]; }; ClipX: PROC [a, b: IntPair, yPos: INTEGER] RETURNS [INTEGER] = INLINE { t: Environment.LongNumber; t.high _ LOOPHOLE[yPos - a.y, UNSPECIFIED]; t.low _ LOOPHOLE[0, UNSPECIFIED]; RETURN[ a.x + LOOPHOLE[ Inline.HighHalf[ LOOPHOLE[t, LONG INTEGER] / (b.y - a.y) * (b.x - a.x)], INTEGER] ]; }; aCode, bCode, out: Out; c: IntPair; WHILE TRUE DO aCode _ Code[a.x, a.y]; bCode _ Code[b.x, b.y]; <> IF Inline.BITOR[LOOPHOLE[aCode, UNSPECIFIED], LOOPHOLE[bCode, UNSPECIFIED]] = LOOPHOLE[0, UNSPECIFIED] THEN RETURN[TRUE, a, b]; <> IF Inline.BITAND[LOOPHOLE[aCode, UNSPECIFIED], LOOPHOLE[bCode, UNSPECIFIED]] # LOOPHOLE[0, UNSPECIFIED] THEN RETURN[ FALSE, a, b]; <> out _ IF aCode # noneOut THEN aCode ELSE bCode; SELECT TRUE FROM out.left => { c.x _ clipper.fMin; c.y _ ClipY[a, b, c.x]; }; out.right => { c.x _ clipper.fMin + clipper.fSize; c.y _ ClipY[a, b, c.x]; }; out.bottom => { c.y _ clipper.sMin; c.x _ ClipX[a, b, c.y]; }; out.top => { c.y _ clipper.sMin + clipper.sSize; c.x _ ClipX[a, b, c.y]; } ENDCASE; IF aCode = out THEN a _ c ELSE b _ c; ENDLOOP; ERROR; -- can't get here, supposedly }; END.