DIRECTORY Basics USING [BITSHIFT, bitsPerWord, LongMult], CD, CDApplications, CDBasics, CDColors, CDOps, CDOrient, CDPrivate, CDTexts, CDValue, CDVPrivate, CDVScale, Graphics, GraphicsBasic, GraphicsColor, GraphicsOps, PrincOps USING [BBptr, BitAddress, BBTable, SrcDesc, BitBltFlags, GrayParm], PrincOpsUtils USING [BITBLT], Real, Rope, RuntimeError, Terminal, TerminalExtras, ViewerClasses, ViewerSpecs; CDVDraw: CEDAR MONITOR IMPORTS Basics, CD, CDApplications, CDBasics, CDOps, CDOrient, CDValue, CDVPrivate, CDVScale, Graphics, GraphicsOps, PrincOpsUtils, Real, RuntimeError, Terminal, TerminalExtras EXPORTS CDVPrivate, CD --DrawRef's private fields-- = BEGIN ViewerPrivateRep: PUBLIC TYPE = CDVPrivate.MyGraphicRec; ViewerSaveRep: PUBLIC TYPE = INTEGER; -- XXX 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 CDColors.Brick ]; bitBltFlagsForPaint: PrincOps.BitBltFlags = PrincOps.BitBltFlags[ direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: TRUE, srcFunc: null, dstFunc: or ]; bitBltFlagsForOutline: PrincOps.BitBltFlags = PrincOps.BitBltFlags[ direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: TRUE, srcFunc: null, dstFunc: or ]; bitBltFlagsForClearPattern: PrincOps.BitBltFlags = PrincOps.BitBltFlags[ direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: TRUE, srcFunc: complement, dstFunc: and ]; blackBrick: REF CDColors.Brick = NEW[CDColors.Brick_ALL[LAST[CARDINAL]]]; whiteBrick: REF CDColors.Brick = NEW[CDColors.Brick_ALL[0]]; BitBlitDraw: PROC[me: MyGraphicRef, r: CD.Rect, color: REF CDColors.Brick] = TRUSTED INLINE BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => { errrorReport.text _ "BitBlitDraw"; errrorReport.me _ me; errrorReport.r_r; errrorReport.color_color; IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT; }; }; xBit, x1, x2, y1, y2: CARDINAL; vr: CD.Rect; IF ~CDBasics.NonEmpty[r] THEN RETURN; vr _ CDVScale.DesignToViewerRect[me.scale, 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.viewer.cw]; y2 _ MIN[vr.y2, me.viewer.ch]; IF x1>=x2 OR y1>=y2 THEN RETURN; 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[(xBit/Basics.bitsPerWord)],, xBit MOD Basics.bitsPerWord ]; me.pBBptr.src _ [ LOOPHOLE[ LOOPHOLE[color, LONG CARDINAL] + y1 MOD 4, LONG POINTER],, xBit MOD Basics.bitsPerWord]; me.pBBptr.srcDesc.gray.yOffset _ y1 MOD 4; IF me.bpp=1 THEN PrincOpsUtils.BITBLT[me.pBBptr] ELSE { TerminalExtras.LockColorFrame[vt: virtual, xmin: x1+me.vx, ymin: y1, xmax: x2+me.vx, ymax: y1+me.pBBptr.height ]; PrincOpsUtils.BITBLT[me.pBBptr]; TerminalExtras.UnlockColorFrame[virtual] }; EXITS SomeError => NULL; END; BitBlitSave: ENTRY PROC[me: MyGraphicRef, r: CD.Rect, color: REF CDColors.Brick, clearPattern: REF CDColors.Brick_NIL] = TRUSTED BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => { errrorReport.text _ "BitBlitSave"; errrorReport.me _ me; errrorReport.r_r; errrorReport.color_color; IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT; }; }; xBit, x1, x2, y1, y2: CARDINAL; vr: CD.Rect; r _ CDBasics.Intersection[r, me.deviceDrawRef.interestClip]; IF ~CDBasics.NonEmpty[r] THEN RETURN; vr _ CDVScale.DesignToViewerRect[me.scale, 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.viewer.cw]; y2 _ MIN[vr.y2, me.viewer.ch]; IF x1>=x2 OR y1>=y2 THEN RETURN; xBit _ Basics.BITSHIFT[x1+me.vx, me.logbpp]; me.xBBptr.width _ Basics.BITSHIFT[x2-x1, me.logbpp]; me.xBBptr.height _ y2-y1; y1 _ me.vy-y2; -- now y1 is device top pixel me.xBBptr.srcDesc _ PrincOps.SrcDesc[gray[PrincOps.GrayParm[ yOffset: y1 MOD 4, widthMinusOne: 0, --words heightMinusOne: 3 --lines ]]]; me.xBBptr.dst _ [ me.screen + Basics.LongMult[y1, me.scWidthWords] + LONG[(xBit/Basics.bitsPerWord)],, xBit MOD Basics.bitsPerWord ]; IF me.bpp#1 THEN TerminalExtras.LockColorFrame[vt: virtual, xmin: x1+me.vx, ymin: y1, xmax: x2+me.vx, ymax: y1+me.xBBptr.height ]; IF clearPattern#NIL THEN { me.xBBptr.flags _ bitBltFlagsForClearPattern; me.xBBptr.src _ [ LOOPHOLE[ LOOPHOLE[clearPattern, LONG CARDINAL] + y1 MOD 4, LONG POINTER],, xBit MOD Basics.bitsPerWord]; PrincOpsUtils.BITBLT[me.xBBptr]; }; me.xBBptr.src _ [ LOOPHOLE[ LOOPHOLE[color, LONG CARDINAL] + y1 MOD 4, LONG POINTER],, xBit MOD Basics.bitsPerWord]; me.xBBptr.flags _ bitBltFlagsForOutline; PrincOpsUtils.BITBLT[me.xBBptr]; IF me.bpp#1 THEN TerminalExtras.UnlockColorFrame[virtual]; EXITS SomeError => NULL; 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, clipr: CD.Rect; DrawBlack: --INTERNAL-- PROC[me: MyGraphicRef, x1, y1, x2, y2: INTEGER] = TRUSTED INLINE BEGIN xBits: CARDINAL ~ Basics.BITSHIFT[x1+INTEGER[me.vx], me.logbpp]; me.xBBptr.width _ Basics.BITSHIFT[x2-x1, me.logbpp]; me.xBBptr.height _ y2-y1; me.xBBptr.dst _ [ me.screen + Basics.LongMult[INTEGER[me.vy]-y2, me.scWidthWords] + LONG[(xBits/Basics.bitsPerWord)],, xBits MOD Basics.bitsPerWord ]; PrincOpsUtils.BITBLT[me.xBBptr]; END; IF r.x2>me.dClip.x2 THEN r.x2_me.dClip.x2+1; IF r.y2>me.dClip.y2 THEN r.y2_me.dClip.y2+1; IF r.x1=clipr.x2 OR clipr.y1>=clipr.y2 THEN RETURN; --harder empty test than CDBasics --necessary because we add/subtract one TRUSTED { me.xBBptr.src _ [LOOPHOLE[blackBrick, LONG POINTER],,0]; me.xBBptr.flags _ bitBltFlagsForOutline; me.xBBptr.srcDesc _ PrincOps.SrcDesc[gray[PrincOps.GrayParm[ yOffset: 0, widthMinusOne: 0, --words heightMinusOne: 0 --lines ]]]; }; IF me.bpp#1 THEN { TerminalExtras.LockColorFrame[vt: virtual, xmin: clipr.x1+me.vx, ymin: me.vy+1-clipr.y2, xmax: clipr.x2+me.vx-1, ymax: me.vy-clipr.y1 ]; }; IF vr.x1>=clipr.x1 THEN DrawBlack[me, clipr.x1, clipr.y1, clipr.x1+1, clipr.y2]; --left IF vr.y2<=clipr.y2 THEN DrawBlack[me, clipr.x1, clipr.y2-1, clipr.x2, clipr.y2]; --top IF vr.x2<=clipr.x2 THEN DrawBlack[me, clipr.x2-1, clipr.y1, clipr.x2, clipr.y2]; --right IF vr.y1>=clipr.y1 THEN DrawBlack[me, clipr.x1, clipr.y1, clipr.x2, clipr.y1+1]; --bottom IF me.bpp#1 THEN TerminalExtras.UnlockColorFrame[virtual]; EXITS SomeError => NULL; END; BitBlitDrawRectForViewers: ENTRY PROC[r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN ENABLE UNWIND => NULL; me: MyGraphicRef = pr.viewerPrivate; BitBlitDraw[me, CDBasics.Intersection[r, pr.interestClip], me.colorTable[l]]; END; SaveRectForViewers: ENTRY PROCEDURE[r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN ENABLE UNWIND => NULL; me: MyGraphicRef = pr.viewerPrivate; IF me.saveList=NIL OR me.saveList.first.next>=CDVPrivate.saveListSize THEN me.saveList _ CONS[CDVPrivate.SavedRectArraySeq[next: 0], me.saveList]; me.saveList.first.x[me.saveList.first.next] _ [r: CDBasics.Intersection[r, pr.interestClip], l: l]; me.saveList.first.next _ me.saveList.first.next+1 END; SetGround: --CD.SetGroundProc-- PROC [pr: CD.DrawRef, pushedOut: BOOL] = BEGIN WITH pr.devicePrivate SELECT FROM me: MyGraphicRef => me.colorTable _ me.personalColors[me.display][IF pushedOut THEN back ELSE normal] ENDCASE => NULL; 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 _ CDVScale.DesignToViewerRect[me.scale, 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 { me.viewContext.SetColor[Graphics.black]; me.viewContext.SetCP[vr.x1+leftMargin, vr.y2-topToFontLine]; me.viewContext.DrawRope[comment]; } }; END; RepaintRectAreaInViewer: PUBLIC PROC[me: MyGraphicRef, rect: CD.DesignRect, eraseFirst: BOOL] = BEGIN ENABLE { RuntimeError.UNCAUGHT => IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT }; interestRect: CD.DesignRect; UpdateDrawInformation[me]; me.deviceDrawRef.interestClip _ interestRect _ CDBasics.Intersection[rect, me.dClip]; IF CDBasics.NonEmpty[interestRect] THEN { [] _ Graphics.SetPaintMode[me.viewContext, transparent]; RepaintBackground[me, interestRect, eraseFirst]; CDOps.QuickDrawDesign[me.actualDesign, me.deviceDrawRef]; [] _ Graphics.SetPaintMode[me.viewContext, opaque]; IF me.saveList#NIL THEN { l: CDVPrivate.SaveList _ me.saveList; me.saveList _ NIL; WHILE l#NIL DO FOR i: INTEGER IN [0..l.first.next) DO BitBlitSave[me, l.first.x[i].r, me.colorTable[l.first.x[i].l], me.greyTable[l.first.x[i].l]]; ENDLOOP; l _ l.rest ENDLOOP; }; 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.catchAny THEN CONTINUE ELSE REJECT ] ENDLOOP } EXITS SomeError=> NULL 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, CDBasics.Intersection[r, me.dClip], me.colorTable[CD.backGround]]; END; 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: CDApplications.ARectO[me.actualDesign.actual.first.mightReplace], outside: DrawOutside ]; EXITS SomeError => NULL; END; InitForBBLT: PROC [me: MyGraphicRef] = BEGIN x, y: REAL; scWidthBits: INTEGER; IF me.viewer.column=color THEN TRUSTED { m: Terminal.ColorMode = Terminal.GetColorMode[virtual]; IF m.full OR m.bitsPerPixelChannelA=0 THEN ERROR CDVPrivate.notSupportedColorMode; me.bpp _ m.bitsPerPixelChannelA; me.screen _ virtual.colorBitmapA; me.scWidth _ virtual.colorWidth; -- pixels scWidthBits _ virtual.colorWidth*me.bpp; me.scHeight _ virtual.colorHeight; IF me.bpp=4 THEN { me.display _ bit4; me.logbpp _ 2; } ELSE IF me.bpp=8 THEN { me.display _ bit8; me.logbpp _ 3; } ELSE ERROR; } ELSE { -- b+w me.display _ bw; me.bpp _ 1; me.logbpp _ 0; me.scWidth _ ViewerSpecs.screenW/Basics.bitsPerWord; scWidthBits _ ViewerSpecs.screenW; me.scHeight _ ViewerSpecs.screenH; me.screen _ Terminal.GetBitBltTable[virtual].bbt.dst.word; }; me.colorTable _ me.personalColors[me.display][normal]; me.greyTable _ me.personalColors[me.display][grey]; [x, y] _ GraphicsOps.UserToDevice[me.viewContext, 0, 0]; -- in device in pixels me.vx _ Real.RoundI[x]; --distance from left of screen to left most pixel me.vy _ Real.RoundI[y]; --distance from top of screen to bottom most pixel me.scWidthWords _ scWidthBits/Basics.bitsPerWord; TRUSTED BEGIN me.pBBptr^ _ PrincOps.BBTable[ dst: TRASH, dstBpl: scWidthBits, src: TRASH, srcDesc: PrincOps.SrcDesc[gray[PrincOps.GrayParm[ yOffset: 0, --is actually trash widthMinusOne: 0, --words heightMinusOne: 3 --lines ]]], width: TRASH, height: TRASH, flags: bitBltFlagsForPaint ]; me.xBBptr^ _ me.pBBptr^; END; END; SetupContext: PROC [pr: CD.DrawRef, me: MyGraphicRef] = BEGIN s: REAL; pr.deviceContext _ Graphics.CopyContext[me.viewContext]; s _ CDVScale.DesignToViewerFactor[me.scale]; pr.scaleHint _ s*me.suppressFactorForCells; pr.b1 _ me.b1; pr.b2 _ me.b2; Graphics.Scale[pr.deviceContext, s, s]; Graphics.Translate[pr.deviceContext, -me.scale.off.x, -me.scale.off.y]; END; InternalCreateDrawInformation: INTERNAL PROC [me: MyGraphicRef] = BEGIN pr: CD.DrawRef = CD.CreateDrawRef[me.actualDesign]; me.deviceDrawRef _ pr; pr.contextFilter _ me.contextFilter _ GetContextFilter[me]; pr.drawRect _ BitBlitDrawRectForViewers; pr.outLineProc _ BitBlitOutLine; pr.drawComment _ DrawCommentForViewers; pr.setGround _ SetGround; pr.devicePrivate _ me; pr.stopFlag _ me.stoprequest; pr.symbolics _ me.symbolics; pr.environment _ me.environment; pr.interestClip _ me.dClip _ CDVScale.GetClipRecord[me.scale, me.viewer.cw, me.viewer.ch]; pr.minimalSize _ --XXX-- MIN[(me.dClip.x2-me.dClip.x1)/8, (me.dClip.y2-me.dClip.y1)/8]; InitForBBLT[me]; pr.saveRect _ (IF me.display=bit8 THEN BitBlitDrawRectForViewers ELSE SaveRectForViewers); pr.viewerPrivate _ me; -- this line last! it tells DummyNotify that the rest is initialized END; UpdateDrawInformation: ENTRY PROC [me: MyGraphicRef] = BEGIN ENABLE UNWIND => NULL; IF me.deviceDrawRef=NIL THEN InternalCreateDrawInformation[me]; SetupContext[me.deviceDrawRef, me]; END; CreateDrawInformation: PUBLIC ENTRY PROC [me: MyGraphicRef] = BEGIN ENABLE UNWIND => NULL; InternalCreateDrawInformation[me]; SetupContext[me.deviceDrawRef, me]; END; GetContextFilter: PROC [me: MyGraphicRef] RETURNS [REF CD.ContextFilter] = BEGIN WITH CDValue.Fetch[boundTo: me.actualDesign.technology, key: $ContextFilter, propagation: global] SELECT FROM rcf: REF CD.ContextFilter => RETURN [rcf]; ENDCASE => RETURN [defaultContextFilter] END; defaultContextFilter: REF CD.ContextFilter = NEW[CD.ContextFilter]; FOR l: CD.Layer IN CD.Layer DO defaultContextFilter[l].paintMode _ transparent; defaultContextFilter[l].doit _ TRUE; ENDLOOP; defaultContextFilter[CD.backGround].doit _ FALSE; CDValue.EnregisterKey[$ContextFilter]; CDValue.Store[NIL, $ContextFilter, defaultContextFilter]; END. :CDVDraw.mesa Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. Christian Jacobi, August 5, 1983 11:07 am last edited by Christian Jacobi, May 1, 1985 10:40:38 am PDT -- r ALLREADY CLIPPED --DONE OUTSIDE r _ CDBasics.Intersection[r, me.deviceDrawRef.interestClip]; --draw exclusive high border pixels --no empty test; is guaranteed by caller --clip to area where --1) small enogh: it does not crash on scaling later --2) big enogh: if drawn, it does not draw artificial lines --RepaintBackground ---------- --fixed pBBptr initializations --done in viewerprocess: me.pBBptr _ PrincOpsUtils.AlignedBBTable[@bBTableSpace]; PROCEDURE NOT USED because Qickdraw gives us no chance NamedDrawChild: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Comment: PROC [comment: Rope.ROPE] = BEGIN me: MyGraphicRef _ NARROW[pr.devicePrivate]; vpos: CD.Position = CDVScale.DesignToViewerPosition[me.scale, pos]; pr.deviceContext.SetColor[Graphics.black]; pr.deviceContext.SetCP[vpos.x+1, vpos.y+1]; pr.deviceContext.DrawRope[comment]; END; aptr.ob.p.drawMe[aptr, pos, orient, pr]; IF pr.b2 THEN { WITH CDProperties.GetPropFromApplication[from: aptr, prop: $SignalName] SELECT FROM r: Rope.ROPE => Comment[r]; a: ATOM => Comment[Atom.GetPName[a]]; ENDCASE => NULL; }; END; ʘšœ ™ Jšœ Ïmœ7™BJšœ)™)Jšœ<™˜LJšœžœžœ˜Jšœ˜J˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜J˜ J˜—šÏbœžœž˜Jšžœžœž˜°Jšžœ žœÏcœ˜5—Jšž˜J˜Jšœžœžœ˜8Jšœžœžœžœ ˜:J˜Jšœžœ˜-Jšœžœ˜-Jšœžœ˜"Jšœ/˜/Jšœ:˜:J˜šœžœ˜Jšœ žœ˜Jšœ˜Jšœžœ˜ Jšœžœ˜Jšœ˜—J˜šœA˜AJ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜ Jšœ˜Jšœ ˜ J˜—J˜šœC˜CJ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜ Jšœ˜Jšœ ˜ J˜—J˜šœH˜HJ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜ Jšœ˜Jšœ ˜ J˜—J˜Jš œ žœžœžœžœžœ˜IJšœ žœžœžœ˜—Jšœ˜Jšœžœžœžœ˜ZJšœ D˜\Jšžœ˜—J˜Jš¡6™6š ¡œžœžœžœžœ ™^Jšœžœ ™Jšž™J™š¡œžœžœ™$Jšž™Jšœžœ™,Jšœžœ;™CJšœ*™*Jšœ+™+Jšœ#™#Jšžœ™—J™Jšœ(™(šžœžœ™šžœDž ™SJšœžœ™Jšœžœ™%Jšžœžœ™—J™—Jšžœ™J™—š¡œžœžœ˜6šžœ˜Jšžœžœžœ˜—šžœžœžœ˜Jšœ"˜"—Jšœ#˜#Jšžœ˜J˜—š¡œžœžœžœ˜=šžœ˜Jšžœžœžœ˜—Jšœ"˜"Jšœ#˜#Jšžœ˜J˜—š ¡œžœžœžœžœ˜JJšžœ˜šžœ^žœž˜mJšœžœžœžœ˜*Jšžœžœ˜(—Jšžœ˜J˜—Jš œžœžœžœžœ˜Cš žœžœžœžœž˜Jšœ0˜0Jšœžœ˜$Jšžœ˜—Jšœžœžœ˜1Jšœ&˜&Jšœžœ(˜9Jšžœ˜J˜—…—8jQª