CDRemovedDrawContext.mesa
Jacobi, January 15, 1986 6:01:49 pm PST
DrawContext: PUBLIC PROC [pr: DrawRef, proc: DrawContextLayerProc, ob: Object, pos: Position, orient: Orientation, layer: Layer] =
--calls proc which may use context; mode and color are set to layer's need
--call is suppressed if layer does not need drawing; this is default.
--on recursive calls, the context may or may not include previous transformations
BEGIN
ActionWithContext: PROC [] =
BEGIN
IF ob#NIL THEN {
Imager.TranslateT[pr.deviceContext, [pos.x, pos.y]];
CDOrient.OrientateContext[pr.deviceContext, ob.size, orient];
};
Imager.SetColor[pr.deviceContext, pr.contextFilter[layer]];
proc[pr.deviceContext, ob, layer];
END;
IF pr.contextFilter#NIL AND pr.contextFilter[layer]#NIL THEN {
IF pr.deviceContext#NIL THEN Imager.DoSave[pr.deviceContext, ActionWithContext]
ELSE IF ob#NIL THEN {
--if ob is nil we don't know the size for the bitmap nor the clip region
clip: CD.Rect ~ CDOrient.DeMapRect[itemInWorld: pr.interestClip, cellSize: ob.size, cellInstOrient: orient, cellInstPos: pos].itemInCell; --in object coordinates
inter: CD.Rect ~ CDBasics.Intersection[CDBasics.RectAt[[0, 0], ob.size], clip];
IF CDBasics.NonEmpty[inter] THEN {
Operator: PROC [context: Imager.Context] = {
Imager.ClipRectangle[context, [x: inter.x1, y: inter.y1, w: inter.x2-inter.x1, h: inter.y2-inter.y1]];
proc[context, ob, layer ! ImagerMaskCapture.Cant => --RESUME--REJECT];
};
man: ImagerMaskCapture.Manhattan;
man ← ImagerMaskCapture.CaptureManhattan[Operator, ImagerTransformation.Scale[1]];
FOR m: ImagerMaskCapture.Manhattan ← man, m.rest UNTIL m=NIL DO
r: CD.Rect ← CDOrient.MapRect[
itemInCell: [x1: m.first.sMin, y1: m.first.fMin, x2: m.first.sMin+m.first.sSize, y2: m.first.fMin+m.first.fSize],
cellSize: ob.size,
cellInstOrient: orient,
cellInstPos: pos];
r ← CDBasics.Intersection[r, pr.interestClip];
IF CDBasics.NonEmpty[r] THEN pr.drawRect[r, layer, pr];
ENDLOOP;
ImagerManhattan.Destroy[man];
};
};
};
END;
--version with bitmaps
DrawContext: PUBLIC PROC [pr: DrawRef, proc: DrawContextLayerProc, ob: Object, pos: Position, orient: Orientation, layer: Layer] =
--calls proc which may use context; mode and color are set to layer's need
--call is suppressed if layer does not need drawing; this is default.
--on recursive calls, the context may or may not include previous transformations
BEGIN
ActionWithContext: PROC [] =
BEGIN
IF ob#NIL THEN {
Imager.TranslateT[pr.deviceContext, [pos.x, pos.y]];
CDOrient.OrientateContext[pr.deviceContext, ob.size, orient];
};
Imager.SetColor[pr.deviceContext, pr.contextFilter[layer]];
proc[pr.deviceContext, ob, layer];
END;
IF pr.contextFilter#NIL AND pr.contextFilter[layer]#NIL THEN {
IF pr.deviceContext#NIL THEN Imager.DoSave[pr.deviceContext, ActionWithContext]
ELSE IF ob#NIL THEN {
--if ob is nil we don't know the size for the bitmap nor the clip region
clip: CD.Rect ~ CDOrient.DeMapRect[itemInWorld: pr.interestClip, cellSize: ob.size, cellInstOrient: orient, cellInstPos: pos].itemInCell; --in object coordinates
inter: CD.Rect ~ CDBasics.Intersection[CDBasics.RectAt[[0, 0], ob.size], clip];
IF CDBasics.NonEmpty[inter] THEN {
DrawToBitmapContext: PROC [] = {
proc[context, ob, layer];
};
CapturePixel: PROC [x, y: INT] = INLINE {
r: CD.Rect ← CDOrient.MapRect[itemInCell: [x1: x, y1: y, x2: x+1, y2: y+1], cellSize: ob.size, cellInstOrient: orient, cellInstPos: pos];
r ← CDBasics.Intersection[r, pr.interestClip];
IF CDBasics.NonEmpty[r] THEN pr.drawRect[r, layer, pr];
};
CaptureBitmap: PROC [bitmap: ImagerBackdoor.Bitmap, off: CD.Position] =
BEGIN
FOR y: CARDINAL IN [0..bitmap.height) DO
FOR x: CARDINAL IN [0..bitmap.width) DO
TRUSTED {
bitsRef: LONG POINTER TO CARDINAL
LOOPHOLE[bitmap.base, LONG POINTER TO CARDINAL]
+ LONG[y]*bitmap.wordsPerLine
+ LONG[x/Basics.bitsPerWord];
IF Basics.BITAND[8000h, Basics.BITSHIFT[bitsRef^, x MOD Basics.bitsPerWord]]#0 THEN
CapturePixel[off.x+x, off.y+bitmap.height-y-1]
}
ENDLOOP;
ENDLOOP;
END;
bitmap: ImagerBackdoor.Bitmap ← ImagerBackdoor.NewBitmap[width: inter.x2-inter.x1, height: inter.y2-inter.y1];
context: Imager.Context ← ImagerBackdoor.BitmapContext[bitmap];
Imager.SetColor[context, Imager.white];
Imager.MaskRectangleI[context, 0, 0, bitmap.width, bitmap.height];
Imager.TranslateT[context, [-inter.x1, -inter.y1]];
Imager.SetColor[context, Imager.black];
Imager.DoSave[context, DrawToBitmapContext];
CaptureBitmap[bitmap, CDBasics.BaseOfRect[inter]];
bitmap ← NIL;
context ← NIL;
};
};
};
END;