CDVDraw.mesa
by Christian Jacobi August 5, 1983 11:07 am
last edited by Christian Jacobi December 8, 1983 3:12 pm
DIRECTORY
Basics USING [bitsPerWord],
CD,
CDApplications,
CDExtras,
CDInline,
CDOps,
CDOrient,
CDTexts,
CDVPrivate,
Graphics,
GraphicsBasic,
GraphicsColor,
GraphicsOps,
PrincOps USING [BBptr, BitAddress],
PrincOpsUtils USING [BITBLT, BITSHIFT],
Real,
Rope,
RuntimeError,
Terminal,
TerminalExtras,
ViewerClasses,
ViewerSpecs;
CDVDraw:
CEDAR
MONITOR
IMPORTS CD, CDApplications, CDExtras, CDInline, CDOps, CDOrient, CDVPrivate, Graphics, GraphicsOps, PrincOpsUtils, Real, RuntimeError, Terminal, TerminalExtras
EXPORTS CDVPrivate, CD --DrawRef's private fields-- =
BEGIN
ViewerPrivateRep: PUBLIC TYPE ~ CDVPrivate.MyGraphicRec;
ViewerSaveRep: PUBLIC TYPE ~ INTEGER; -- XXXX placeholder
MyGraphicRef: TYPE ~ CDVPrivate.MyGraphicRef;
MyGraphicRec: TYPE ~ CDVPrivate.MyGraphicRec;
maxInfluence: CD.DesignNumber ~ 0;
virtual: Terminal.Virtual ~ Terminal.Current[];
defaultFont: Graphics.FontRef ~ GraphicsOps.DefaultFont[];
errrorReport:
RECORD [
text: Rope.ROPE,
me: MyGraphicRef,
r: CD.Rect,
color: REF CDVPrivate.Brick
];
blackBrick: REF CDVPrivate.Brick = NEW[CDVPrivate.Brick←ALL[LAST[CARDINAL]]];
whiteBrick: REF CDVPrivate.Brick = NEW[CDVPrivate.Brick←ALL[0]];
backBWBrick: REF CDVPrivate.Brick = NEW[CDVPrivate.Brick←[257,0,0,0]];
back4Brick: REF CDVPrivate.Brick = NEW[CDVPrivate.Brick←[0,15,0,0]];
back8Brick: REF CDVPrivate.Brick = NEW[CDVPrivate.Brick←[0,1,256,0]];
Sorry, storage overflow in pass 3
InvertArea: PUBLIC PROC[me: MyGraphicRef, x1, y1, x2, y2: INT] =
--x1, y1, x2, y2 in viewers coordinates; inverts all the border points
TRUSTED BEGIN
ENABLE {
UNWIND => NULL;
RuntimeError.UNCAUGHT => {
errrorReport.text ← "InvertArea";
errrorReport.me ← me;
errrorReport.r←[x1: x1, x2: x2, y1: y1, y2: y2];
IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO SomeError ELSE REJECT;
};
};
xBit: CARDINAL;
xc1: CARDINAL ← MIN[MAX[x1, 0], LONG[me.vwminus1]];
yc1: CARDINAL ← MIN[MAX[y1, 0], LONG[me.vhminus1]];
xc2: CARDINAL ← MIN[MAX[x2, 0], LONG[me.vwminus1]];
yc2: CARDINAL ← MIN[MAX[y2, 0], LONG[me.vhminus1]];
IF xc1>xc2 THEN {t: CARDINAL=xc1; xc1←xc2; xc2←t};
IF yc1>yc2 THEN {t: CARDINAL=yc1; yc1←yc2; yc2←t};
me.bBLT.width ← PrincOpsUtils.BITSHIFT[(xc2+1-xc1), me.logbpp];
me.bBLT.height ← (yc2+1-yc1);
xBit ← PrincOpsUtils.BITSHIFT[(xc1+me.vx), me.logbpp];
yc1 ← me.vy-yc2;
me.bBLT.dst ← [
me.screen
+ (LONG[yc1]*LONG[me.scWidthWords])
+ LONG[(xBit/Basics.bitsPerWord)],,
xBit MOD Basics.bitsPerWord
];
me.bBLT.flags.dstFunc ← xor; -- cursoring is monitored; no drawing!
IF me.bpp=1 THEN
PrincOpsUtils.BITBLT[me.bBLT]
ELSE {
TerminalExtras.LockColorFrame[vt: virtual,
xmin: xc1+me.vx,
ymin: yc1,
xmax: xc2+me.vx+1,
ymax: yc1+me.bBLT.height
];
PrincOpsUtils.BITBLT[me.bBLT];
TerminalExtras.UnlockColorFrame[virtual]
};
me.bBLT.flags.dstFunc ← null;
END;
BitBlitDraw:
--INTERNAL--
PROC[me: MyGraphicRef, r:
CD.Rect, color:
REF CDVPrivate.Brick] =
TRUSTED
-- r ALLREADY CLIPPED
INLINE BEGIN
ENABLE {
UNWIND => NULL;
RuntimeError.
UNCAUGHT => {
errrorReport.text ← "BitBlitDraw";
errrorReport.me ← me;
errrorReport.r←r;
errrorReport.color𡤌olor;
IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT;
};
};
xBit, x1, x2, y1, y2: CARDINAL;
vr: CD.Rect;
--DONE OUTSIDE r ← CDInline.Intersection[r, me.deviceDrawRef.worldClip];
IF ~CDInline.NonEmpty[r] THEN RETURN;
vr ← CDVPrivate.DesignToViewerRect[me, r];
x1 ← MAX[vr.x1, 0]; y1 ← MAX[vr.y1, 0];
IF vr.x2<=0 OR vr.y2<=0 THEN RETURN;
x2 ← MIN[vr.x2, me.vwminus1]; y2 ← MIN[vr.y2, me.vhminus1];
IF x1>=x2 OR y1>=y2 THEN RETURN;
xBit ← PrincOpsUtils.BITSHIFT[(x1+me.vx), me.logbpp];
me.xBLT.width ← PrincOpsUtils.BITSHIFT[(x2 --+1-- -x1), me.logbpp];
me.xBLT.height ← (y2 --+1-- -y1);
y1 ← me.vy-y2;
me.xBLT.dst ← [
me.screen
+ (LONG[y1]*LONG[me.scWidthWords])
+ LONG[(xBit/Basics.bitsPerWord)],,
xBit MOD Basics.bitsPerWord
];
me.xBLT.src ← [
LOOPHOLE[
LOOPHOLE[color,
LONG
CARDINAL] +
y1 MOD 4, LONG POINTER],,
xBit MOD Basics.bitsPerWord];
me.xBLT.srcDesc.gray.yOffset ← y1 MOD 4;
IF me.bpp=1 THEN PrincOpsUtils.BITBLT[me.xBLT]
ELSE {
TerminalExtras.LockColorFrame[vt: virtual,
xmin: x1+me.vx,
ymin: y1,
xmax: x2+me.vx --+1-- ,
ymax: y1+me.xBLT.height
];
PrincOpsUtils.BITBLT[me.xBLT];
TerminalExtras.UnlockColorFrame[virtual]
};
END;
BitBlitSave:
ENTRY
PROC[me: MyGraphicRef, r:
CD.Rect, color:
REF CDVPrivate.Brick, clearPattern:
REF CDVPrivate.Brick←
NIL] =
TRUSTED BEGIN
ENABLE {
UNWIND => NULL;
RuntimeError.
UNCAUGHT => {
errrorReport.text ← "BitBlitSave";
errrorReport.me ← me;
errrorReport.r←r;
errrorReport.color𡤌olor;
IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT;
};
};
xBit, x1, x2, y1, y2: CARDINAL;
vr: CD.Rect;
r ← CDInline.Intersection[r, me.deviceDrawRef.worldClip];
IF ~CDInline.NonEmpty[r] THEN RETURN;
vr ← CDVPrivate.DesignToViewerRect[me, r];
x1 ← MAX[vr.x1, 0]; y1 ← MAX[vr.y1, 0];
IF vr.x2<=0 OR vr.y2<=0 THEN RETURN;
x2 ← MIN[vr.x2, me.vwminus1]; y2 ← MIN[vr.y2, me.vhminus1];
IF x1>=x2 OR y1>=y2 THEN RETURN;
xBit ← PrincOpsUtils.BITSHIFT[(x1+me.vx), me.logbpp];
me.xBLT.width ← PrincOpsUtils.BITSHIFT[(x2 --+1-- -x1), me.logbpp];
me.xBLT.height ← (y2 --+1-- -y1);
y1 ← me.vy-y2;
me.xBLT.dst ← [
me.screen
+ (LONG[y1]*LONG[me.scWidthWords])
+ LONG[(xBit/Basics.bitsPerWord)],,
xBit MOD Basics.bitsPerWord
];
me.xBLT.srcDesc.gray.yOffset ← y1 MOD 4;
IF me.bpp#1
THEN TerminalExtras.LockColorFrame[vt: virtual,
xmin: x1+me.vx,
ymin: y1,
xmax: x2+me.vx --+1-- ,
ymax: y1+me.xBLT.height
];
IF clearPattern#
NIL
THEN {
me.xBLT.flags.dstFunc ← and;
me.xBLT.flags.srcFunc ← complement;
me.xBLT.src ← [
LOOPHOLE[
LOOPHOLE[clearPattern,
LONG
CARDINAL] +
y1 MOD 4, LONG POINTER],,
xBit MOD Basics.bitsPerWord];
PrincOpsUtils.BITBLT[me.xBLT];
me.xBLT.flags.srcFunc ← null;
me.xBLT.flags.dstFunc ← or;
};
me.xBLT.src ← [
LOOPHOLE[
LOOPHOLE[color,
LONG
CARDINAL] +
y1 MOD 4, LONG POINTER],,
xBit MOD Basics.bitsPerWord];
PrincOpsUtils.BITBLT[me.xBLT];
IF me.bpp#1 THEN TerminalExtras.UnlockColorFrame[virtual];
END;
BitBlitOutLine:
ENTRY
PROC[r:
CD.Rect, pr:
CD.DrawRef] =
BEGIN
ENABLE {
UNWIND => NULL;
RuntimeError.
UNCAUGHT => {
errrorReport.text ← "BitBlitOutLine";
errrorReport.me ← pr.viewerPrivate;
errrorReport.r←r;
IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT;
};
};
me: MyGraphicRef ~ pr.viewerPrivate;
vr: CD.Rect;
DrawBlack:
--INTERNAL--
PROC[me: MyGraphicRef, xx1, yy1, xx2, yy2:
INT] =
TRUSTED INLINE BEGIN
xBits, x1, x2, y1, y2: CARDINAL;
IF xx2<=0 OR yy2<=0 OR xx1>me.vwminus1 OR yy1>me.vhminus1 THEN RETURN;
--no empty test; is guaranteed by caller
x1 ← MAX[xx1, LONG[0]];
y1 ← MAX[yy1, LONG[0]];
x2 ← MIN[xx2, LONG[me.vwminus1]];
y2 ← MIN[yy2, LONG[me.vhminus1]];
me.bBLT.width ← PrincOpsUtils.BITSHIFT[(x2 --+1-- -x1), me.logbpp];
me.bBLT.height ← (y2 --+1-- -y1);
xBits ← PrincOpsUtils.BITSHIFT[(x1+me.vx), me.logbpp];
y1 ← me.vy-y2;
me.bBLT.dst ← [
me.screen
+ (LONG[y1]*LONG[me.scWidthWords])
+ LONG[(xBits/Basics.bitsPerWord)],,
xBits MOD Basics.bitsPerWord
];
IF me.bpp=1 THEN PrincOpsUtils.BITBLT[me.bBLT]
ELSE {
TerminalExtras.LockColorFrame[vt: virtual,
xmin: x1+me.vx,
ymin: y1,
xmax: x2+me.vx --+1--,
ymax: y1+me.bBLT.height
];
PrincOpsUtils.BITBLT[me.bBLT];
--outside: TerminalExtras.UnlockColorFrame[virtual]
};
END;
--clip generous to avoid wrong border
IF r.x2>me.deviceDrawRef.worldClip.x2 THEN r.x2←me.deviceDrawRef.worldClip.x2+1;
IF r.y2>me.deviceDrawRef.worldClip.y2 THEN r.y2←me.deviceDrawRef.worldClip.y2+1;
IF r.x1<me.deviceDrawRef.worldClip.x1 THEN r.x1←me.deviceDrawRef.worldClip.x1-1;
IF r.y1<me.deviceDrawRef.worldClip.y1 THEN r.y1←me.deviceDrawRef.worldClip.y1-1;
vr ← CDVPrivate.DesignToViewerRect[me, r];
IF ~CDInline.NonEmpty[vr] THEN RETURN; --empty
DrawBlack[me, vr.x1, vr.y1, vr.x1+1, vr.y2]; --left
DrawBlack[me, vr.x1, vr.y2-1, vr.x2, vr.y2]; --top
DrawBlack[me, vr.x2-1, vr.y1, vr.x2, vr.y2]; --right
DrawBlack[me, vr.x1, vr.y1, vr.x2, vr.y1+1]; --bottom
TerminalExtras.UnlockColorFrame[virtual];
END;
BitBlitDrawRectForViewers:
ENTRY
PROC[r:
CD.Rect, l:
CD.Level, pr:
CD.DrawRef] =
BEGIN
ENABLE UNWIND => NULL;
me: MyGraphicRef = pr.viewerPrivate;
BitBlitDraw[me, CDInline.Intersection[r, pr.worldClip], me.colorTable[l]];
END;
SaveRectForViewers:
ENTRY
PROCEDURE[r:
CD.Rect, l:
CD.Level, pr:
CD.DrawRef] =
BEGIN
ENABLE UNWIND => NULL;
me: MyGraphicRef = pr.viewerPrivate;
me.saveList ← CONS[[r: CDInline.Intersection[r, pr.worldClip], l: l], me.saveList]
END;
DrawCommentForViewers:
PUBLIC
PROC[r:
CD.DesignRect, comment: Rope.
ROPE, pr:
CD.DrawRef] =
BEGIN
topToFontLine: NAT ~ 9+2;
fontHeight: NAT ~ 12;
leftMargin: NAT ~ 2;
bothMargin: NAT ~ 2*leftMargin;
me: MyGraphicRef ← NARROW[pr.devicePrivate];
vr: CD.Rect ← CDVPrivate.DesignToViewerRect[me, r];
IF vr.y2-vr.y1>fontHeight
THEN {
xw: REAL ~ Graphics.RopeWidth[font: defaultFont, rope: comment].xw;
IF vr.x2-vr.x1>xw+bothMargin
THEN {
--tc: Graphics.Context;
--tc ← Graphics.CopyContext[me.viewerContext];
--Graphics.SetColor[tc, Graphics.black];
--Graphics.SetCP[tc, vr.x1+leftMargin, vr.y2-topToFontLine];
--Graphics.DrawRope[tc, comment];
Graphics.SetCP[me.viewerContext, vr.x1+leftMargin, vr.y2-topToFontLine];
Graphics.DrawRope[me.viewerContext, comment];
}
};
END;
RepaintRectAreaInViewer:
PUBLIC
PROC[me: MyGraphicRef, rect:
CD.DesignRect, eraseFirst:
BOOL] =
BEGIN
pr: CD.DrawRef ~ CDVPrivate.CreateDrawInformation[me];
pr.worldClip ← CDInline.Intersection[rect, pr.worldClip];
IF CDInline.NonEmpty[pr.worldClip]
THEN
BEGIN
[] ← Graphics.SetPaintMode[me.viewerContext, transparent];
RepaintBackground[me, rect, eraseFirst];
CDOps.DrawDesign[me.actualDesign, pr];
[] ← Graphics.SetPaintMode[me.viewerContext, opaque];
IF me.saveList#
NIL
THEN {
l: LIST OF CDVPrivate.SavedRect ← me.saveList;
me.saveList ← NIL;
WHILE l#
NIL
DO
BitBlitSave[me, l.first.r, me.colorTable[l.first.l], me.greyTable[l.first.l]];
l ← l.rest
ENDLOOP;
};
IF me.ticks>0 THEN PaintTicks[me, rect];
IF me.designRec.arrowOn AND me.arrowIsOn
AND CDInline.Intersect[rect, me.arrowRect] THEN PaintArrow[me, rect];
END
END;
RepaintBackground:
PUBLIC
ENTRY
PROC[me: MyGraphicRef, r:
CD.DesignRect, eraseFirst:
BOOL] =
BEGIN
ENABLE {
UNWIND => NULL;
RuntimeError.
UNCAUGHT => {
errrorReport.text ← "background";
errrorReport.me ← me;
errrorReport.r ← r;
IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT
};
};
DrawOutside:
--INTERNAL--
PROC [r:
CD.DesignRect] =
BEGIN
BitBlitDraw[me, CDInline.Intersection[r, me.deviceDrawRef.worldClip], me.backGround];
END;
--RepaintBackground
IF eraseFirst
THEN {
TRUSTED {me.xBLT.flags.dstFunc ← null};
BitBlitDraw[me, CDInline.Intersection[r, me.deviceDrawRef.worldClip], whiteBrick];
TRUSTED {me.xBLT.flags.dstFunc ← or};
};
IF me.actualDesign.actual.first.mightReplace#
NIL
AND ~me.suppressOutsidePushedCell
AND
me.actualDesign.actual.first.mightReplace.ob#NIL THEN
CDExtras.DecomposeRect[r: r,
test: CDApplications.ApplicationRect[me.actualDesign.actual.first.mightReplace],
outside: DrawOutside];
END;
PaintArrow:
PROC[me: MyGraphicRef, r:
CD.DesignRect] =
BEGIN
temContext: Graphics.Context ← Graphics.CopyContext[me.viewerContext];
vp: CD.Position ← CDVPrivate.DesignToViewerPosition[me,
[me.designRec.arowAt.x, me.designRec.arowAt.y]];
vp ← CDInline.AddPoints[vp, [1, 1]];
Graphics.SetColor[temContext, Graphics.black];
[]← Graphics.SetPaintMode[temContext, opaque];
Graphics.SetCP[temContext, vp.x+10, vp.y];
Graphics.DrawTo[temContext, vp.x, vp.y];
Graphics.DrawTo[temContext, vp.x, vp.y+10];
Graphics.SetCP[temContext, vp.x, vp.y];
Graphics.DrawTo[temContext, vp.x+18, vp.y+18];
END;
PaintTicks:
PUBLIC
ENTRY
PROC[me: MyGraphicRef, r:
CD.DesignRect] =
--paints ticks
BEGIN
ENABLE UNWIND => NULL;
ModUp:
PROC [x, md:
CD.Number]
RETURNS [
CD.Number] =
INLINE {
RETURN [( IF x>0 THEN (x+md-1) ELSE (x) ) / md * md]
}; -- division rounds towards 0
ModDown:
PROC [x, md:
CD.Number]
RETURNS [
CD.Number] =
INLINE {
RETURN [( IF x>0 THEN (x) ELSE (x-md+1) ) / md * md]
}; -- division rounds towards 0
IF me.ticks>0
THEN {
vTicks: CD.Number ~ CDVPrivate.ScaleDesignToViewer[me, me.ticks];
IF vTicks>6
THEN
TRUSTED {
x, xStop, xMod: INT;
yStart, yStop, yTem, yInc: LONG CARDINAL;
dr: CD.DesignRect ~ CDInline.Intersection[me.deviceDrawRef.worldClip, r]; -- design coords
vr:
CD.Rect ← CDVPrivate.DesignToViewerRect[me,
CD.Rect[
-- viewer coords
x1: ModUp[dr.x1, me.ticks],
y1: ModUp[dr.y1, me.ticks],
x2: ModDown[dr.x2, me.ticks],
y2: ModDown[dr.y2, me.ticks]
]];
IF vr.x1<0 THEN vr.x1 ← vr.x1 + ModUp[-vr.x1, vTicks];
IF vr.y1<0 THEN vr.y1 ← vr.y1 + ModUp[-vr.y1, vTicks];
IF vr.x2>me.vwminus1 THEN vr.x2 ← vr.x2 - ModUp[vr.x2-me.vwminus1, vTicks];
IF vr.y2>me.vhminus1 THEN vr.y2 ← vr.y2 - ModUp[vr.y2-me.vhminus1, vTicks];
-- Now vr denotes area for ticks; vTicks denote increment; in viewer coordinates
me.xBLT.width ← me.bpp;
me.xBLT.height ← 1;
me.xBLT.src ← [LOOPHOLE[blackBrick],,0];
me.xBLT.srcDesc.gray.yOffset ← 0;
yStart ← LOOPHOLE[(me.vy-vr.y2-1)*me.scWidthWords, LONG CARDINAL]+LOOPHOLE[me.screen, LONG CARDINAL];
yStop ← LOOPHOLE[(me.vy-vr.y1-1)*me.scWidthWords, LONG CARDINAL]+LOOPHOLE[me.screen, LONG CARDINAL];
yInc ← vTicks*me.scWidthWords;
x ← (vr.x1+me.vx)*me.bpp;
xStop ← (vr.x2+me.vx)*me.bpp;
IF me.bpp#1 THEN {TerminalExtras.LockColorFrame[virtual]};
WHILE x<=xStop
DO
yTem ← yStart+LOOPHOLE[(x/Basics.bitsPerWord), LONG CARDINAL];
xMod ← x MOD Basics.bitsPerWord;
WHILE yTem<=yStop
DO
me.xBLT.dst ← [LOOPHOLE[yTem],,xMod];
PrincOpsUtils.BITBLT[me.xBLT];
yTem ← yTem+yInc
ENDLOOP;
x ← x+vTicks*me.bpp
ENDLOOP;
IF me.bpp#1 THEN {TerminalExtras.UnlockColorFrame[virtual]};
};
}
END;
CreateDrawInformation:
PUBLIC
ENTRY
PROC [me: MyGraphicRef]
RETURNS [
CD.DrawRef] =
BEGIN
GraphicsBoxToRect:
PROC[box: Graphics.Box]
RETURNS [
CD.Rect] =
--INLINE sorry storage overflow in pass 3-- BEGIN
RETURN [
CD.Rect[
x1: Real.RoundI[box.xmin],
y1: Real.RoundI[box.ymin],
x2: Real.RoundI[box.xmax],
y2: Real.RoundI[box.ymax]]];
END;
NextBiggerBack:
PROC[me: CDVPrivate.MyGraphicRef, r:
CD.Rect, off:
CD.DesignPosition, scale: CDVPrivate.ScaleRange]
RETURNS [CD.DesignRect] =
BEGIN
UnGridedScaleViewerToDesignUp:
PROC [me: MyGraphicRef, v:
LONG
CARDINAL]
RETURNS [
CD.DesignNumber] =
--without translation, gridding,
INLINE {RETURN [LOOPHOLE[(v*me.sA+me.sE+me.sE)/me.sE, CD.DesignNumber]]};
UnGridedScaleViewerToDesignDown:
PROC [me: MyGraphicRef, v:
LONG
CARDINAL]
RETURNS [
CD.DesignNumber] =
--without translation, gridding
INLINE {RETURN [LOOPHOLE[(v*me.sA-me.sE)/me.sE, CD.DesignNumber]]};
RETURN [
CD.DesignRect[
UnGridedScaleViewerToDesignDown[me, r.x1]+off.x,
UnGridedScaleViewerToDesignDown[me, r.y1]+off.y,
UnGridedScaleViewerToDesignUp[me, r.x2+1]+off.x,
UnGridedScaleViewerToDesignUp[me, r.y2+1]+off.y]]
END;
ScaleValue:
PROC [me: MyGraphicRef]
RETURNS [s:
REAL] =
--without necessary translation
factor to scale design to viewer
--INLINE sorry storage overflow in pass 3-- {RETURN [Real.Float[me.sE]/Real.Float[me.sF]]};
--CreateMyDeviceDrawRef
s: REAL;
pr: CD.DrawRef ~ CD.NewNullDeviceDrawRef[me.actualDesign];
pr.drawRect ← BitBlitDrawRectForViewers;
pr.saveRect ← SaveRectForViewers;
pr.outLineProc ← BitBlitOutLine;
pr.drawComment ← DrawCommentForViewers;
pr.deviceContext ← Graphics.CopyContext[me.viewerContext];
s ← ScaleValue[me];
pr.scaleHint ← s*me.suppressFactorForCells;
Graphics.Scale[pr.deviceContext, s, s];
Graphics.Translate[pr.deviceContext, -me.noff.x, -me.noff.y];
pr.contextFilter ← defaultContextFilter;
pr.devicePrivate ← me;
pr.stopFlag ← me.stoprequest;
pr.suppressOutsidePushedCell ← me.suppressOutsidePushedCell;
pr.worldClip ← NextBiggerBack[me, GraphicsBoxToRect[Graphics.GetBounds[me.viewerContext]],
me.noff, me.nscale];
pr.minimalSize ←
IF me.cellClipp<0
THEN
MIN[(pr.worldClip.x2-pr.worldClip.x1)/8, (pr.worldClip.y2-pr.worldClip.y1)/8]
ELSE me.cellClipp;
DoBBLTInit: PROC [] =
BEGIN
x, y: REAL;
IF me.viewer.column=color
THEN
TRUSTED {
m: Terminal.ColorMode = Terminal.GetColorMode[virtual];
IF m.full THEN ERROR;
IF m.bitsPerPixelChannelA=0 THEN ERROR;
me.bpp ← m.bitsPerPixelChannelA;
me.screen ← virtual.colorBitmapA;
me.scWidth ← virtual.colorWidth; -- pixels
me.scWidthBits ← virtual.colorWidth*me.bpp;
me.scHeight ← virtual.colorHeight;
IF me.bpp=4
THEN {
me.logbpp ← 2;
me.colorTable ← CDVPrivate.colorTable4;
me.greyTable ← CDVPrivate.greyTable4;
me.backGround ← back4Brick;
}
ELSE
IF me.bpp=8
THEN {
me.logbpp ← 3;
me.colorTable ← CDVPrivate.colorTable8;
me.greyTable ← CDVPrivate.greyTable8;
me.backGround ← back8Brick;
}
ELSE ERROR;
}
ELSE {
-- b+w
me.bpp ← 1;
me.logbpp ← 0;
me.colorTable ← CDVPrivate.colorTableBW;
me.greyTable ← CDVPrivate.greyTableBW;
me.backGround ← backBWBrick;
me.scWidth ← ViewerSpecs.screenW/Basics.bitsPerWord;
me.scWidthBits ← ViewerSpecs.screenW;
me.scHeight ← ViewerSpecs.screenH;
me.screen ← Terminal.GetBitBltTable[virtual].bbt.dst.word;
};
[x, y] ← GraphicsOps.UserToDevice[me.viewerContext, 0, 0];
--experiment showed: returns pixel number, not bit number
me.vx ← Real.RoundI[x];
me.vy ← Real.RoundI[y];
me.vwminus1 ← me.viewer.cw-1;
me.vhminus1 ← me.viewer.ch-1;
me.scWidthWords ← me.scWidthBits/Basics.bitsPerWord;
------------
--fixed xBLT initializations
--done in viewerprocess: me.xBLT ← PrincOpsUtils.AlignedBBTable[@bBTableSpace];
--varying: me.xBLT.dst
TRUSTED {i: INTEGER ← me.scWidthBits; me.xBLT.dstBpl ← i};
--varying: me.xBLT.src
TRUSTED {
me.xBLT.srcDesc.gray ← [yOffset: 0 --XXX set later--,
widthMinusOne: 0, --words--
heightMinusOne: 3 --lines-- ]
};
-varying: me.xBLT.width
--varying: me.xBLT.height
--default: TRUSTED{me.xBLT.flags.direction ← forward};
TRUSTED {me.xBLT.flags.disjoint ← TRUE};
--default: TRUSTED{me.xBLT.flags.disjointItems ← TRUE};
TRUSTED {me.xBLT.flags.gray ← TRUE};
TRUSTED {me.xBLT.flags.srcFunc ← null};
TRUSTED {me.xBLT.flags.dstFunc ← or};
--default: me.xBLT.flags.reserved
--default: me.xBLT.reserved
TRUSTED {me.bBLT^ ← me.xBLT^};
TRUSTED {
me.bBLT.srcDesc.gray ← [yOffset: 0,
widthMinusOne: 0, --words--
heightMinusOne: 0 --lines-- ];
me.bBLT.src ← [
LOOPHOLE[blackBrick,
LONG
POINTER],,0]
};
END;
pr.viewerPrivate ← me; -- this line last! it tells DummyNotify that the rest is initialized
RETURN [pr]
END;
defaultContextFilter: REF CD.ContextFilter = NEW[CD.ContextFilter];
FOR l:
CD.Level
IN
CD.Level
DO
defaultContextFilter[l].doit←TRUE;
ENDLOOP;
END.