<> <> DIRECTORY Environment USING [LongNumber], Inline USING [BITOR, BITAND, HighHalf], Real USING [FixI], ImagerBasic USING [Path, Pair, IntPair, Rectangle, IntRectangle, PixelArray, Transformation, StrokeEnds], ImagerTransform USING [Transform, IntTransform, TransformIntRectangle], ImagerDisplay USING [ContextData], ImagerMasks USING [Mask], Imager USING [Context]; ImagerDisplayMasksImpl: CEDAR PROGRAM IMPORTS ImagerTransform, Inline, Real EXPORTS Imager = BEGIN NotImplementedYet: PUBLIC SIGNAL = CODE; <> MaskStroke: PUBLIC PROC [context: Imager.Context, path: ImagerBasic.Path, width: REAL, strokeEnds: ImagerBasic.StrokeEnds, closed: BOOLEAN _ FALSE] = { <
> <> displayContext: ImagerDisplay.ContextData = NARROW[context.data]; }; <<>> MaskFill: PUBLIC PROC [context: Imager.Context, path: ImagerBasic.Path] = { <> displayContext: ImagerDisplay.ContextData = NARROW[context.data]; }; MaskPixel: PUBLIC PROC [context: Imager.Context, pixelArray: ImagerBasic.PixelArray] = { <> displayContext: ImagerDisplay.ContextData = NARROW[context.data]; }; <<>> <> MaskBits: PUBLIC PROC [context: Imager.Context, base: LONG POINTER, raster: CARDINAL, tile: ImagerBasic.IntRectangle, area: ImagerBasic.IntRectangle] = { }; <> MaskSegment: PUBLIC PROC [context: Imager.Context, p: ImagerBasic.Pair] = { displayContext: ImagerDisplay.ContextData = NARROW[context.data]; p _ ImagerTransform.Transform[p, displayContext.transform]; DrawSegment[ [ Real.FixI[p.x], Real.FixI[p.y] ] , displayContext]; }; MaskIntSegment: PUBLIC PROC [context: Imager.Context, p: ImagerBasic.IntPair] = { displayContext: ImagerDisplay.ContextData = NARROW[context.data]; p _ ImagerTransform.IntTransform[p, displayContext.transform]; DrawSegment[p, displayContext]; }; MaskThinStroke: PUBLIC PROC [context: Imager.Context, path: ImagerBasic.Path] = {}; <> MaskRectangle: PUBLIC PROC [context: Imager.Context, area: ImagerBasic.Rectangle] = {}; <> MaskIntRectangle: PUBLIC PROC [context: Imager.Context, area: ImagerBasic.IntRectangle] = { left, bottom, right, top: INTEGER; displayContext: ImagerDisplay.ContextData = NARROW[context.data]; area _ ImagerTransform.TransformIntRectangle[area, displayContext.transform]; left _ MAX[area.x, displayContext.clipper.fMin]; bottom _ MAX[area.y, displayContext.clipper.sMin]; right _ MIN[left + area.w, displayContext.clipper.fMin + displayContext.clipper.fSize]; top _ MIN[bottom + area.h, displayContext.clipper.sMin + displayContext.clipper.sSize]; displayContext.deviceProcs.LoadTrapezoid[ displayContext, top, bottom, left, left, right, right, displayContext.currentPxlValue]; }; <> DrawSegment: PROC [p: ImagerBasic.IntPair, displayContext: ImagerDisplay.ContextData] = INLINE { IF displayContext.noClip THEN { OPEN displayContext; deviceProcs.DrawLine[displayContext, currentPosition, p, currentPxlValue]; } ELSE IF displayContext.clipper.refRep = NIL -- rectangular? THEN { in: BOOLEAN; a, b: ImagerBasic.IntPair; [in, a, b] _ ClipEdgeByRectangle[displayContext.clipper, displayContext.currentPosition, p]; IF in THEN displayContext.deviceProcs.DrawLine[displayContext, a, b, displayContext.currentPxlValue]; } ELSE ERROR NotImplementedYet[]; -- until paths are worked out - M. Plass? displayContext.currentPosition _ p; }; ClipEdgeByRectangle: PROC [clipper: ImagerMasks.Mask, a, b: ImagerBasic.IntPair] RETURNS [BOOLEAN, ImagerBasic.IntPair, ImagerBasic.IntPair] = INLINE { 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: ImagerBasic.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: ImagerBasic.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: ImagerBasic.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.