GGCircleCacheImpl.mesa
Copyright © 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
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 REALNEW[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] = {
Returns NIL if lookup fails
FindRadius: FunctionCache.CompareProc = {
arg: REALNARROW[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: REALNARROW[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.