DIRECTORY FunctionCache, GGBasicTypes, GGCircles, GGCircleCache, GGShapes, Imager, ImagerBackdoor, ImagerFastShow, ImagerPixelMap, Real, RealFns; GGCircleCacheImpl: CEDAR PROGRAM IMPORTS FunctionCache, GGCircles, GGShapes, Imager, ImagerBackdoor, ImagerFastShow, ImagerPixelMap, Real, RealFns EXPORTS GGCircleCache = BEGIN Point: TYPE = GGBasicTypes.Point; Cache: TYPE = FunctionCache.Cache; Context: TYPE = Imager.Context; Range: TYPE = FunctionCache.Range; CachedCircle: TYPE = REF CachedCircleRep; CachedCircleRep: TYPE = PixelMap; PixelMapRef: TYPE = REF PixelMap; PixelMap: TYPE = ImagerPixelMap.PixelMap; PixelMapRepRef: TYPE = REF PixelMapRep; PixelMapRep: TYPE = ImagerPixelMap.PixelMapRep; Bitmap: TYPE = ImagerBackdoor.Bitmap; alignmentColor: Imager.Color _ ImagerBackdoor.MakeStipple[145065B]; -- stolen from GGGravityImpl Create: PUBLIC PROC [] RETURNS [Cache] = { RETURN [FunctionCache.GlobalCache[] ]; }; Insert: PUBLIC PROC [x: Cache, radius: REAL] = { IF Lookup[x, radius]#NIL OR radius NOT IN [1.0..512.0] THEN RETURN ELSE { context: Imager.Context; argument: REF REAL _ NEW[REAL _ radius]; circle: GGBasicTypes.Circle; side: INT _ 2*(Real.Fix[radius+1.0]+1); -- round up and add 1 bitmap: Bitmap _ ImagerBackdoor.NewBitmap[side, side]; pixelmapRepRef: PixelMapRepRef _ NEW[PixelMapRep _ [ ref: bitmap.ref, pointer: bitmap.base, words: LONG[bitmap.wordsPerLine]*bitmap.height, lgBitsPerPixel: 0, rast: bitmap.wordsPerLine, lines: bitmap.height ]]; pixelmapRef: PixelMapRef _ NEW[PixelMap _ [ sOrigin: 0, fOrigin: 0, sMin: 0, fMin: 0, sSize: bitmap.height, fSize: bitmap.width, refRep: pixelmapRepRef ] ]; ImagerPixelMap.Clear[pixelmapRef^]; context _ ImagerFastShow.Create[pixelmapRef^, 72, TRUE]; context.SetColor[alignmentColor]; context.SetStrokeWidth[1.0]; circle _ GGCircles.CircleFromPointAndRadius[ [side/2, side/2], radius]; GGShapes.DrawCircle[dc: context, circle: circle ]; FunctionCache.Insert[x: x, argument: argument, value: pixelmapRef, size: pixelmapRepRef.words, clientID: $GGCircle]; }; }; Lookup: PUBLIC PROC [x: Cache, radius: REAL] RETURNS [CachedCircle] = { FindRadius: FunctionCache.CompareProc = { arg: REAL _ NARROW[argument, REF REAL]^; RETURN [RealFns.AlmostEqual[y: arg, x: radius, distance: -10] ]; }; value: Range; ok: BOOL; [value, ok] _ FunctionCache.Lookup[x: x, compare: FindRadius, clientID: $GGCircle]; RETURN [IF ok THEN NARROW[value] ELSE NIL]; }; Remove: PUBLIC PROC [x: Cache, radius: REAL] = { FindRadius: FunctionCache.CompareProc = { arg: REAL _ NARROW[argument, REF REAL]^; RETURN [RealFns.AlmostEqual[y: arg, x: radius, distance: -10] ]; }; [] _ FunctionCache.Obtain[x: x, compare: FindRadius, limit: 1, clientID: $GGCircle]; }; RemoveAll: PUBLIC PROC [x: Cache] = { list: LIST OF FunctionCache.CacheEntry _ FunctionCache.Obtain[x: x, compare: FunctionCache.Any, limit: LAST[INT], clientID: $GGCircle]; UNTIL list=NIL DO list _ FunctionCache.Obtain[x: x, compare: FunctionCache.Any, limit: LAST[INT], clientID: $GGCircle]; ENDLOOP; }; DrawCachedCircle: PUBLIC PROC [context: Context, point: Point, circle: CachedCircle] = { DoDrawCachedCircle: PROC = { context.SetColor[Imager.black]; Imager.MaskBits[context: context, base: circle.refRep.pointer, wordsPerLine: circle.refRep.rast, sMin: 0, fMin: 0, sSize: circle.sSize, fSize: circle.fSize, tx: Real.RoundI[point.x]-(circle.fSize/2), ty: Real.RoundI[point.y]+(circle.sSize/2)] }; Imager.DoSaveAll[context, DoDrawCachedCircle]; }; END. ΦGGCircleCacheImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Created by: Ken Pier, August 14, 1986 Last Edited By: Ken Pier, August 19, 1986 3:53:47 pm PDT Returns NIL if lookup fails Κ_˜™Icodešœ Οmœ1™