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. ŠImagerDisplayMasksImpl.mesa Last Edited by: Crow, September 1, 1983 2:08 pm Client Procedures (exported to Imager) 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. Draw line using current color Draw whole path using the current color Fill rectangular area with the current color Internal Procedures Trivial acceptance test Trivial rejection test Actual clipping necessary Κ+˜head™J™0šΟk ˜ Jšœœ˜!Jšœ œœœ ˜+Jšœ œ˜Jšœœ<˜OJšœ%˜%Jšœœ2˜GJšœœ˜$Jšœœ˜Jšœ œ ˜——šœ ˜%Jšœ˜%Jšœ˜J˜Jšœœ˜J˜Jšœœœœ˜(—™&JšΟn œ œ:œ˜Všœ4œœ˜HšœE™EJšœŽ™Ž—Jšœ,œ˜AJšœ˜J™—unitšžœ œ5˜KJ™˜>Mšœ˜Jšœ˜—šžœœœ8˜SJ™'—šž œœœ=˜WJ™,—šžœœœ=˜[Mšœœ˜"Mšœ,œ˜AMšœM˜MMšœœ&˜0Mšœ œ&˜2Mšœœ˜MšœB˜BMšœœ˜Mšœ@˜@šœ)˜)Mšœ˜Mšœ'˜'Mšœ ˜ —Mšœ˜——™šž œœGœ˜`Mšœ˜šœœ˜JšœO˜O—šœœ!œΟc˜Bšœœ˜.Jšœ8˜8Jšœ-˜-Jšœœ:˜DJšœ+˜+J˜—Jšœœ )˜L—Jšœ#˜#Jšœ˜—Lšžœœ8˜Qšœœœ.œ˜LJšœœœœ˜6Jš œœœœœ˜,š žœœœœ œ˜3Jšœ ˜ Jšœ˜Jš œ œ œœœ œ˜OJš œ œœœœ œ˜LJšœ ˜J˜—š žœœ#œœœœ˜SJšœ˜Jš œ œ  œ œ œ˜Nšœ œ˜Jš œœœœ œ˜T—J˜—š žœœ#œœœœ˜SJšœ˜Jš œ œ  œ œ œ˜Nšœ œ˜Jš œœœœ œ˜T—J˜—Jšœ˜Jšœ˜šœœ˜ šœ0˜0J™—Jš œ œœ œœ œ˜LJšœœ œ˜šœœœ˜J™—Jš œœœ œœ œ˜LJšœ œ œ˜šœœœ˜J™—Jšœœœœ˜0Jšœœ˜Jšœ#˜#Jšœ ˜ Jšœ4˜4Jšœ ˜ Jšœ%˜%Jšœ ˜ Jšœ2˜2Jšœ˜Jšœ˜Jšœ œœ˜%—Jšœ˜Jšœ ˜(Jšœ˜J˜—Jšœ˜——…—¦[