CDVDraw.mesa
Copyright © 1983, 1986 by Xerox Corporation. All rights reserved.
Christian Jacobi, August 5, 1983 11:07 am
last edited by Christian Jacobi, May 22, 1986 5:26:05 pm PDT
Last Edited by: Jacobi June 6, 1986 12:28:07 pm PDT
DIRECTORY
Basics USING [BITSHIFT, BITAND, LongMult, logBitsPerWord],
CD,
CDBasics,
CDColors,
CDInstances,
CDOps,
CDOrient,
CDPrivate,
CDTexts,
CDVPrivate,
CDVScale,
CedarProcess,
Imager,
ImagerFont,
ImagerTransformation,
List,
PrincOps USING [BBptr, BitAddress, BBTable, SrcDesc, BitBltFlags, GrayParm],
PrincOpsUtils USING [BITBLT],
Rope,
RuntimeError,
Terminal,
VFonts,
ViewerClasses,
ViewerSpecs;
CDVDraw: CEDAR MONITOR
IMPORTS Basics, CD, CDBasics, CDColors, CDInstances, CDOps, CDOrient, CDVPrivate, CDVScale, CedarProcess, Imager, ImagerFont, ImagerTransformation, List, PrincOpsUtils, RuntimeError, Terminal, VFonts
EXPORTS CDVPrivate, CD --DrawRef's private fields-- =
BEGIN
VRef: TYPE = CDVPrivate.VRef;
ViewerPrivateRep: PUBLIC TYPE = CDVPrivate.VRec;
virtual: Terminal.Virtual = Terminal.Current[];
blackBrick: REF CDColors.Brick = NEW[CDColors.Brick←ALL[LAST[CARDINAL]]];
whiteBrick: REF CDColors.Brick = NEW[CDColors.Brick←ALL[0]];
defaultFont: Imager.Font = VFonts.DefaultFont[];
maskModBitsPerWord: CARDINAL = 15;
--I don't trust the damned LOOPHOLE's of List
DRemove: PROC [ref: REF CDVPrivate.PainterRec, list: CDVPrivate.PainterList] RETURNS [CDVPrivate.PainterList] = {
l, l1: CDVPrivate.PainterList ← NIL;
l ← list;
UNTIL l = NIL DO
IF l.first = ref THEN {
IF l1 = NIL THEN RETURN[l.rest]; -- ref was first object on list
l1.rest ← l.rest;
RETURN[list];
};
l1 ← l;
l ← l.rest;
ENDLOOP;
RETURN [list];
};
IncludeAPainterRec: PUBLIC ENTRY PROC [me: CDVPrivate.VRef, pr: REF CDVPrivate.PainterRec] =
BEGIN ENABLE UNWIND => NULL;
DOIT: PROC [] = TRUSTED {
IF ~List.Memb[ref: pr, list: LOOPHOLE[me.painterList]] THEN
me.painterList ← CONS[pr, me.painterList];
};
DOIT[];
END;
RemoveAPainterRec: PUBLIC ENTRY PROC [me: CDVPrivate.VRef, pr: REF CDVPrivate.PainterRec] =
BEGIN ENABLE UNWIND => NULL;
DOIT: PROC [] = TRUSTED {
me.painterList ← DRemove[ref: pr, list: me.painterList];
};
DOIT[];
END;
CheckPriority: PUBLIC CD.CheckPriorityProc =
BEGIN
IF pr.checkPriority THEN {
WITH pr.devicePrivate SELECT FROM
me: CDVPrivate.VRef => {
IF me.slowDown THEN {
CedarProcess.SetPriority[CedarProcess.Priority[background]];
me.slowDown ← FALSE;
};
IF me.hurryUp THEN { --this will be executed only after the other slowed down ...
CedarProcess.SetPriority[CedarProcess.Priority[normal]];
me.hurryUp ← FALSE;
};
me.check ← FALSE;
};
ENDCASE => NULL;
pr.checkPriority ← FALSE;
};
END;
BitBlitDraw: PROC[me: VRef, r: CD.Rect, color: REF CDColors.Brick] = {
InlineBitBlitDraw[me, r, color];
};
InlineBitBlitDraw: PROC[me: VRef, r: CD.Rect, color: REF CDColors.Brick] =
-- DONE OUTSIDE r ← CDBasics.Intersection[r, me.deviceDrawRef.interestClip];
-- this guarantees no arithmetic overflows if non empty; but there are nasty guys
-- calling this procedure with empty rects.
-- This is not a complete clip yet
TRUSTED INLINE BEGIN
ENABLE RuntimeError.UNCAUGHT => {
IF CDVPrivate.ShallContinue[me, TRUE, "CDVDraw.bblt"] THEN GOTO oops;
};
xBit, x1, x2, y1, y2: CARDINAL;
vr: CD.Rect;
IF r.x1>r.x2 OR r.y1>r.y2 THEN RETURN; --silly bad guys could cause overflow
vr ← CDVScale.DesignToViewerRect[me.scale, r];
x1 ← MAX[vr.x1, 0];
y1 ← MAX[vr.y1, 0];
x2 ← MIN[vr.x2, me.vw];  
y2 ← MIN[vr.y2, me.vh];
IF x1>=x2 OR y1>=y2 THEN RETURN;
--Arbitrary: rectangles smaller than 1 pixel are not drawn.
xBit ← Basics.BITSHIFT[x1+me.vx, me.logbpp];
me.pBBptr.width ← Basics.BITSHIFT[x2-x1, me.logbpp];
me.pBBptr.height ← y2-y1;
y1 ← me.vy-y2;
me.pBBptr.dst ← [
me.screen
+ Basics.LongMult[y1, me.scWidthWords]
+ LONG[Basics.BITSHIFT[xBit, -Basics.logBitsPerWord]],,
Basics.BITAND[xBit, maskModBitsPerWord]
];
me.pBBptr.src ← [
LOOPHOLE[
LOOPHOLE[color, LONG CARDINAL] + Basics.BITAND[y1, 3], LONG POINTER],,
Basics.BITAND[xBit, maskModBitsPerWord]
];
me.pBBptr.srcDesc.gray.yOffset ← Basics.BITAND[y1, 3];
IF me.display=bw THEN PrincOpsUtils.BITBLT[me.pBBptr]
ELSE {
Blit: PROC [] = TRUSTED {
PrincOpsUtils.BITBLT[me.pBBptr];
};
Terminal.ModifyColorFrame[vt: virtual,
action: Blit,
xmin: x1+me.vx,
ymin: y1,
xmax: x2+me.vx,
ymax: y1+me.pBBptr.height
];
};
EXITS oops => NULL;
END;
InlineBitBlitOutLine: ENTRY PROC[vRef: VRef, r: CD.Rect, color: REF CDColors.Brick] =
TRUSTED INLINE BEGIN
--r in design coordinates
ENABLE {
UNWIND => NULL;
RuntimeError.UNCAUGHT => {
IF CDVPrivate.ShallContinue[vRef, TRUE, "CDVDraw.bbout"] THEN GOTO oops;
};
};
vr: CD.Rect; --in viewer coordinates
clipVr: CD.Rect; --in viewer coordinates
DrawGrey: PROC[vRef: VRef, x1, y1, x2, y2: INTEGER] =
TRUSTED INLINE BEGIN
--no empty test; is guaranteed by caller
xBits: CARDINAL = Basics.BITSHIFT[x1+INTEGER[vRef.vx], vRef.logbpp];
vRef.pBBptr.width ← Basics.BITSHIFT[x2-x1, vRef.logbpp];
vRef.pBBptr.height ← y2-y1;
y1 ← vRef.vy-y2;
vRef.pBBptr.dst ← [
vRef.screen
+ Basics.LongMult[y1, vRef.scWidthWords]
+ LONG[Basics.BITSHIFT[xBits, -Basics.logBitsPerWord]],,
Basics.BITAND[xBits, maskModBitsPerWord]
];
vRef.pBBptr.src ← [
LOOPHOLE[
LOOPHOLE[color, LONG CARDINAL] + Basics.BITAND[y1, 3], LONG POINTER],,
Basics.BITAND[xBits, maskModBitsPerWord]
];
vRef.pBBptr.srcDesc.gray.yOffset ← Basics.BITAND[y1, 3];
PrincOpsUtils.BITBLT[vRef.pBBptr];
END;
DoIt: PROC [] =
TRUSTED BEGIN
IF vr.x1>=clipVr.x1 THEN DrawGrey[vRef, clipVr.x1, clipVr.y1, clipVr.x1+1, clipVr.y2]; --left
IF vr.y2<=clipVr.y2 THEN DrawGrey[vRef, clipVr.x1, clipVr.y2-1, clipVr.x2, clipVr.y2]; --top
IF vr.x2<=clipVr.x2 THEN DrawGrey[vRef, clipVr.x2-1, clipVr.y1, clipVr.x2, clipVr.y2]; --right
IF vr.y1>=clipVr.y1 THEN DrawGrey[vRef, clipVr.x1, clipVr.y1, clipVr.x2, clipVr.y1+1]; --bot
END;
--clip to area where
--1) small enough: it does not crash on scaling later
--2) big enough: if drawn, it does not draw artificial lines
IF r.x2>vRef.dClip.x2 THEN r.x2 ← vRef.dClip.x2+1;
IF r.y2>vRef.dClip.y2 THEN r.y2 ← vRef.dClip.y2+1;
IF r.x1<vRef.dClip.x1 THEN r.x1 ← vRef.dClip.x1-1;
IF r.y1<vRef.dClip.y1 THEN r.y1 ← vRef.dClip.y1-1;
vr ← CDVScale.DesignToViewerRect[vRef.scale, r];
clipVr ← CDBasics.Intersection[ --remember: interestClip can be smaller than viewer
CDVScale.DesignToViewerRect[vRef.scale, vRef.deviceDrawRef.interestClip],
vr
];
clipVr.x1 ← MAX[clipVr.x1, 0];
clipVr.y1 ← MAX[clipVr.y1, 0];
clipVr.x2 ← MIN[clipVr.x2, LONG[vRef.vw]];
clipVr.y2 ← MIN[clipVr.y2, LONG[vRef.vh]];
IF clipVr.x1>=clipVr.x2 OR clipVr.y1>=clipVr.y2 THEN RETURN;
harder empty test than CDBasics
necessary because we add/subtract one
vRef.pBBptr^ ← PrincOps.BBTable[
dst: TRASH,
dstBpl: vRef.frame.width*vRef.frame.bitsPerPixel,
src: TRASH,
srcDesc: PrincOps.SrcDesc[gray[PrincOps.GrayParm[
yOffset: 0, --is actually trash
widthMinusOne: 0, --words
heightMinusOne: 3 --lines
]]],
width: TRASH,
height: TRASH,
flags: PrincOps.BitBltFlags[
direction: forward,
disjoint: TRUE,
disjointItems: TRUE,
gray: TRUE,
srcFunc: null,
dstFunc: or
]
];
IF vRef.display=bw THEN {
DoIt[]
}
ELSE {
Terminal.ModifyColorFrame[vt: virtual,
action: DoIt,
xmin: clipVr.x1+vRef.vx,
ymin: vRef.vy+1-clipVr.y2,
xmax: clipVr.x2+vRef.vx-1,
ymax: vRef.vy-clipVr.y1
];
}
EXITS oops => NULL;
END;
InvertArea: PUBLIC ENTRY PROC[me: VRef, x1, y1, x2, y2: INT] =
BEGIN
ENABLE {
UNWIND => NULL;
RuntimeError.UNCAUGHT =>
IF CDVPrivate.ShallContinue[me, TRUE, "CDVDraw.IA"] THEN GOTO oops;
};
--proc to make the unwind really catching the errors
SafetyProc: PROC [] =
TRUSTED BEGIN
xBit: CARDINAL;
xc1: CARDINALMIN[MAX[x1, 0], LONG[me.vw-2]];
yc1: CARDINALMIN[MAX[y1, 1], LONG[me.vh-1]];
xc2: CARDINALMIN[MAX[x2, 0], LONG[me.vw-2]];
yc2: CARDINALMIN[MAX[y2, 1], LONG[me.vh-1]];
IF xc1>xc2 THEN {t: CARDINAL=xc1; xc1←xc2; xc2←t};
IF yc1>yc2 THEN {t: CARDINAL=yc1; yc1←yc2; yc2←t};
me.xBBptr.width ← Basics.BITSHIFT[(xc2+1-xc1), me.logbpp];
me.xBBptr.height ← (yc2+1-yc1);
xBit ← Basics.BITSHIFT[(xc1+me.vx), me.logbpp];
yc1 ← me.vy-yc2; --yc2>me.vy impossible ??
me.xBBptr.dst ← [
me.screen
+ Basics.LongMult[yc1, me.scWidthWords]
+ LONG[Basics.BITSHIFT[xBit, -Basics.logBitsPerWord]],,
Basics.BITAND[xBit, maskModBitsPerWord]
];
me.xBBptr.flags.dstFunc ← xor;
me.xBBptr.src ← [LOOPHOLE[blackBrick, LONG POINTER],,0];
me.xBBptr.srcDesc ← PrincOps.SrcDesc[gray[PrincOps.GrayParm[
yOffset: 0,
widthMinusOne: 0, --words
heightMinusOne: 0 --lines
]]];
IF me.display=bw THEN PrincOpsUtils.BITBLT[me.xBBptr]
ELSE {
Blit: PROC [] = TRUSTED {
PrincOpsUtils.BITBLT[me.xBBptr];
};
Terminal.ModifyColorFrame[vt: virtual,
action: Blit,
xmin: xc1+me.vx,
ymin: yc1 ,
xmax: xc2+me.vx+1,
ymax: yc1+me.xBBptr.height
];
};
END;
SafetyProc[];
EXITS oops => NULL;
END;
OutLine: PROC[r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] =
BEGIN
vRef: VRef = pr.viewerPrivate;
InlineBitBlitOutLine[vRef: vRef, r: r, color: vRef.colorTable.bricks[l]]
END;
BitBlitDrawRectForViewers: ENTRY PROC[r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] =
BEGIN
ENABLE UNWIND => NULL;
me: VRef = pr.viewerPrivate;
InlineBitBlitDraw[me, CDBasics.Intersection[r, pr.interestClip], me.colorTable.bricks[l]];
END;
SetGround: --CD.SetGroundProc-- PROC [pr: CD.DrawRef, pushedOut: BOOL] =
BEGIN
WITH pr.devicePrivate SELECT FROM
me: VRef =>
me.colorTable ← me.personalColors[me.display][IF pushedOut THEN pushedOut ELSE normal]
ENDCASE => NULL;
END;
DrawCommentForViewers: PUBLIC PROC[r: CD.Rect, comment: Rope.ROPE, pr: CD.DrawRef] =
BEGIN
topToFontLine: NAT = 9+2;
fontHeight: NAT = 10;
leftMargin: NAT = 2;
bothMargin: NAT = 2*leftMargin;
me: VRef ← NARROW[pr.devicePrivate];
vr: CD.Rect ← CDVScale.DesignToViewerRect[me.scale, r];
IF vr.y2-vr.y1>fontHeight THEN {
xw: REAL = ImagerFont.RopeWidth[font: defaultFont, rope: comment].x;
IF vr.x2-vr.x1>xw+bothMargin THEN {
Imager.SetColor[me.viewContext, Imager.black];
Imager.SetFont[me.viewContext, defaultFont];
Imager.SetXY[me.viewContext, [vr.x1+leftMargin, vr.y2-topToFontLine]];
Imager.ShowRope[me.viewContext, comment];
}
};
END;
RepaintRectAreaInViewer: PUBLIC PROC[me: VRef, rect: CD.Rect, eraseFirst: BOOL] =
BEGIN
ENABLE RuntimeError.UNCAUGHT =>
IF CDVPrivate.ShallContinue[me, TRUE, "CDVDraw.rep1"] THEN GOTO oops;
interestRect: CD.Rect;
ReUseDrawInformation[me];
me.deviceDrawRef.interestClip ← interestRect ← CDBasics.Intersection[rect, me.dClip];
IF CDBasics.NonEmpty[interestRect] THEN {
RepaintBackground[me, interestRect, eraseFirst];
CDOps.QuickDrawDesign[me.actualDesign, me.deviceDrawRef];
FOR pl: CDVPrivate.PainterList ← me.painterList, pl.rest WHILE pl#NIL DO
IF CDBasics.Intersect[interestRect, pl.first.rect] THEN
pl.first.proc[me, pl.first, interestRect ! RuntimeError.UNCAUGHT =>
IF CDVPrivate.ShallContinue[me, TRUE, "CDVDraw.rep2"] THEN CONTINUE
]
ENDLOOP
}
EXITS oops=> NULL
END;
RepaintBackground: PUBLIC ENTRY PROC[me: VRef, r: CD.Rect, eraseFirst: BOOL] =
BEGIN
ENABLE {
UNWIND => NULL;
RuntimeError.UNCAUGHT =>
IF CDVPrivate.ShallContinue[me, TRUE, "CDVDraw.back"] THEN GOTO oops;
};
DrawOutside: PROC [r: CD.Rect] =
BEGIN
BitBlitDraw[me, CDBasics.Intersection[r, me.dClip], me.colorTable.bricks[CD.backgroundLayer]];
END;
--RepaintBackground
IF eraseFirst THEN {
TRUSTED {me.pBBptr.flags.dstFunc ← null};
BitBlitDraw[me, CDBasics.Intersection[r, me.dClip], whiteBrick];
TRUSTED {me.pBBptr.flags.dstFunc ← or};
};
IF me.actualDesign.actual.first.mightReplace#NIL AND me.environment AND
me.actualDesign.actual.first.mightReplace.ob#NIL THEN
CDBasics.DecomposeRect[r: r,
test: CDInstances.InstRectO[me.actualDesign.actual.first.mightReplace],
outside: DrawOutside
];
EXITS oops => NULL;
END;
InitForBBLT: INTERNAL PROC [me: VRef] =
INLINE --called only from one place..-- BEGIN
IF me.viewer.column=color THEN TRUSTED {
colorMode: Terminal.ColorMode = Terminal.GetColorMode[virtual];
IF colorMode.full THEN ERROR CDVPrivate.notSupportedColorMode;
SELECT colorMode.bitsPerPixelChannelA FROM
8 => {me.display ← bit8; me.logbpp ← 3};
1 => {me.display ← bit1; me.logbpp ← 0};
4 => {me.display ← bit4; me.logbpp ← 2};
2 => {me.display ← bit2; me.logbpp ← 1};
ENDCASE => ERROR CDVPrivate.notSupportedColorMode;
me.frame ← Terminal.GetColorFrameBufferA[virtual];
}
ELSE { -- b+w
me.display ← bw;
me.logbpp ← 0;
me.frame ← Terminal.GetBWFrameBuffer[virtual];
};
me.bpp ← me.frame.bitsPerPixel;
me.screen ← me.frame.base;
me.colorTable ← me.personalColors[me.display][normal];
me.scWidthWords ← me.frame.wordsPerLine;
-- me.vx ← distance from left of screen to left most pixel
-- me.vy ← distance from top of screen to bottom most pixel
--  in pixels
-- me.vw, me.vh copied to avoid race conditions
me.vw ← me.viewer.cw;
me.vh ← me.viewer.ch;
me.vx ← me.viewer.cx+me.viewer.wx;
me.vy ← me.frame.height-(me.viewer.cy+me.viewer.wy);
--fixed fooBBptr initializations
--done in "viewer" process: me.fooBBptr ← PrincOpsUtils.AlignedBBTable[@fooBTableSpace];
TRUSTED {
me.xBBptr^ ← me.pBBptr^ ← PrincOps.BBTable[
dst: TRASH,
dstBpl: me.frame.width*me.frame.bitsPerPixel,
src: [LOOPHOLE[blackBrick, LONG POINTER],,0],
srcDesc: PrincOps.SrcDesc[gray[PrincOps.GrayParm[
yOffset: 0, --is actually trash
widthMinusOne: 0, --words
heightMinusOne: 3 --lines
]]],
width: TRASH,
height: TRASH,
flags: PrincOps.BitBltFlags[
direction: forward,
disjoint: TRUE, disjointItems: TRUE,
gray: TRUE,
srcFunc: null,
dstFunc: or
]
];
};
END;
CreateTransform: PROC [
cellSize: CD.Position,
cellInstOrient: CD.Orientation,
cellInstPos: CD.Position ← [0,0]]
RETURNS [Imager.Transformation] =
-- Given the size of a cell,
-- the position and orientation of an instance of that cell in "world"
-- co-ordinates, returns the transformation to be applied to
-- cell points to get world points.
INLINE BEGIN
RETURN [SELECT cellInstOrient FROM
--original--0 =>  ImagerTransformation.Create[1, 0, cellInstPos.x, 0, 1, cellInstPos.y],
1 =>  ImagerTransformation.Create[-1, 0, cellInstPos.x+cellSize.x, 0, 1, cellInstPos.y], -- reflection in x
--rotate90-- 2 => ImagerTransformation.Create[0, -1, cellInstPos.x+cellSize.y, 1, 0, cellInstPos.y], -- 90 degrees clockwise
3 =>   ImagerTransformation.Create[0, 1, cellInstPos.x, 1, 0, cellInstPos.y], -- 90 degrees clockwise followed by reflection in x
--rotate180-- 4 => ImagerTransformation.Create[-1, 0, cellInstPos.x+cellSize.x, 0, -1, cellInstPos.y+cellSize.y], -- 180 degrees clockwise
5 =>   ImagerTransformation.Create[1, 0, cellInstPos.x, 0, -1, cellInstPos.y+cellSize.y], -- 180 degrees clockwise followed by reflection in x
--rotate270-- 6 => ImagerTransformation.Create[0, 1, cellInstPos.x, -1, 0, cellInstPos.y+cellSize.x], -- 270 degrees clockwise
7 =>   ImagerTransformation.Create[0, -1, cellInstPos.x+cellSize.y, -1, 0, cellInstPos.y+cellSize.x], -- 270 degrees clockwise followed by reflection in x
ENDCASE => ERROR
];
END;
ViewerDrawContext: PROC [pr: CD.DrawRef, proc: CD.DrawContextLayerProc, ob: CD.Object, pos: CD.Position, orient: CD.Orientation, layer: CD.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
IF pr.deviceContext#NIL AND pr.contextFilter#NIL AND pr.contextFilter[layer] THEN {
Action: PROC [] =
BEGIN
me: VRef = NARROW[pr.viewerPrivate];
Imager.ScaleT[pr.deviceContext, CDVScale.DesignToViewerFactor[me.scale]];
Imager.TranslateT[pr.deviceContext, [-me.scale.off.x, -me.scale.off.y]];
IF ob#NIL THEN {
IF orient=CD.original THEN Imager.TranslateT[pr.deviceContext, [pos.x, pos.y]]
ELSE Imager.ConcatT[pr.deviceContext, CreateTransform[
cellSize: ob.size,
cellInstOrient: orient,
cellInstPos: pos
]];
};
Imager.SetColor[pr.deviceContext, me.colorTable.cols[layer]];
proc[pr.deviceContext, ob, layer];
END;
Imager.DoSave[pr.deviceContext, Action];
}
END;
ICreateDrawRef: INTERNAL PROC [me: VRef] =
BEGIN
pr: CD.DrawRef = CD.CreateDrawRef[[
drawRect: BitBlitDrawRectForViewers,
drawOutLine: OutLine,
drawComment: DrawCommentForViewers,
drawContext: ViewerDrawContext,
setGround: SetGround,
priorityChecker: CheckPriority,
devicePrivate: me,
stopFlag: me.stoprequest,
symbolics: me.symbolics,
borders: me.borders,
environment: me.environment,
specialFonts: me.specialFonts,
checkPriority: me.checkPriority,
b4: me.b4,
b5: me.b5,
design: me.actualDesign
]];
InitForBBLT[me];
me.deviceDrawRef ← pr;
pr.interestClip ← me.dClip ← CDVScale.GetClipRecord[me.intendedScale, me.vw, me.vh];
pr.scaleHint ← CDVScale.DesignToViewerFactor[me.intendedScale]*me.suppressFactorForCells;
pr.contextFilter ← me.contextFilter ← me.colorTable.filter;
pr.viewerPrivate ← me; -- this line last! it tells DummyNotify that the rest is initialized
END;
ReUseContext: PROC [pr: CD.DrawRef, me: VRef] = INLINE
BEGIN
pr.deviceContext ← me.viewContext;
Imager.SetColor[me.viewContext, Imager.black];
Imager.SetFont[me.viewContext, defaultFont];
END;
ReUseDrawInformation: ENTRY PROC [me: VRef] = INLINE
BEGIN
ENABLE UNWIND => NULL;
IF me.deviceDrawRef=NIL THEN --usually not-- ICreateDrawRef[me];
ReUseContext[me.deviceDrawRef, me];
END;
CreateDrawInformation: PUBLIC ENTRY PROC [me: VRef] =
BEGIN
ICreateDrawRef[me];
ReUseContext[me.deviceDrawRef, me];
END;
DoInsideMonitor: PUBLIC ENTRY PROC [proc: PROC [VRef], vRef: VRef] =
BEGIN
ENABLE UNWIND => NULL;
proc[vRef ! RuntimeError.UNCAUGHT =>
IF CDVPrivate.ShallContinue[vRef, TRUE, "CDVDraw.XXX"] THEN CONTINUE;
]
END;
CDColors.DefineColor[CD.undefLayer, NIL, bw];
CDColors.DefineColor[CD.undefLayer, NIL, bit4];
CDColors.DefineColor[CD.undefLayer, NIL, bit8];
CDColors.DefineColor[CD.backgroundLayer, NEW[CDColors.Brick←[257,0,0,0]], bw];
CDColors.DefineColor[CD.backgroundLayer, NEW[CDColors.Brick←[0,10,0,11*256]], bit4];
CDColors.DefineColor[CD.backgroundLayer, NEW[CDColors.Brick←[8, 0, 800h, 0]], bit8];
CDColors.DefineColor[CD.shadeLayer, NEW[CDColors.Brick←[101H, 0, 0, 0]], bw];
CDColors.DefineColor[CD.shadeLayer, NEW[CDColors.Brick←[0, 0F0FH, 0, 0]], bit4];
CDColors.DefineColor[CD.shadeLayer, NEW[CDColors.Brick←[255, 0, 255, 0]], bit8];
CDColors.DefineColor[CD.errorLayer, NEW[CDColors.Brick←[101H, 0, 101H, 0]], bw];
CDColors.DefineColor[CD.errorLayer, NEW[CDColors.Brick←[0, 0F0FH, 0, 0F0FH]], bit4];
CDColors.DefineColor[CD.errorLayer, NEW[CDColors.Brick←[0, 255, 0, 0]], bit8];
CDColors.DefineColor[CD.outlineLayer, NEW[CDColors.Brick←[8888h, 4444h, 2222h, 1111h]], bw];
CDColors.DefineColor[CD.outlineLayer, NEW[CDColors.Brick←[07C7CH, 07C7CH, 07C7CH, 07C7CH]], bit4];
CDColors.DefineColor[CD.outlineLayer, NEW[CDColors.Brick←[07C7CH, 07C7CH, 07C7CH, 07C7CH]], bit8];
CDColors.DefineColor[CD.selectionLayer, NEW[CDColors.Brick←[0ffffH, 0ffffH, 0ffffH, 0ffffH]], bw];
CDColors.DefineColor[CD.selectionLayer, NEW[CDColors.Brick←[0ffffH, 0ffffH, 0ffffH, 0ffffH]], bit4];
CDColors.DefineColor[CD.selectionLayer, NEW[CDColors.Brick←[0ffffH, 0ffffH, 0ffffH, 0ffffH]], bit8];
CDColors.DefineColor[CD.commentLayer, NEW[CDColors.Brick←[07777h, 0bbbbH, 0ddddH, 0eeeeH]], bw];
CDColors.DefineColor[CD.commentLayer, NEW[CDColors.Brick←[0bbbbH, 0bbbbH, 0bbbbH, 0bbbbH]], bit4];
CDColors.DefineColor[CD.commentLayer, NEW[CDColors.Brick←[07f7fh, 07f7fh, 07f7fh, 07f7fh]], bit8];
CDColors.DefineColor[CD.commentLayer, NEW[CDColors.Brick←[07f00h, 0007fh, 07f00h, 0007fh]], bit8, pushedOut];
END.