<> <> <> <> DIRECTORY Basics USING [bitsPerWord, LongMult], CD, CDBasics, CDDraw, CDProperties, CDSequencer USING [Command], CDVPrivate, CDVScale, CDVTicks, PrincOps USING [BBptr, BitAddress, SrcDesc, GrayParm], PrincOpsUtils USING [BITBLT], RuntimeError USING [UNCAUGHT], Terminal, TerminalExtras; CDVTicksImpl: CEDAR MONITOR IMPORTS Basics, CDDraw, CDBasics, CDProperties, CDVPrivate, CDVScale, PrincOpsUtils, RuntimeError, Terminal, TerminalExtras EXPORTS CDVTicks = BEGIN <<>> <<-- implement ticks for chipndale viewers >> <<>> black: REF CARDINAL = NEW[CARDINAL_LAST[CARDINAL]]; virtual: Terminal.Virtual = Terminal.Current[]; PaintTicks: CDVPrivate.PainterProc = <<-- PROC [me: MyGraphicRef, paintRef: REF PainterRec, interrestRect: CD.DesignRect];>> BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => { IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT }; }; 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 dTicks: CD.DesignNumber = NARROW[paintRef.data, REF CD.DesignNumber]^; IF dTicks>0 THEN { vTicks: CD.Number = CDVScale.DesignToViewerScalar[me.scale, dTicks]; IF vTicks>6 AND vTicks<1000 THEN TRUSTED { x, xStop, xMod: INT; yStart, yStop, yTem, yInc: LONG CARDINAL; ticks: CARDINAL = vTicks; dr: CD.DesignRect = CDBasics.Intersection[me.deviceDrawRef.interestClip, paintRef.rect]; -- design coords vr: CD.Rect _ CDVScale.DesignToViewerRect[me.scale, CD.Rect[ -- viewer coords x1: ModDown[dr.x1, dTicks], y1: ModDown[dr.y1, dTicks], x2: ModUp[dr.x2, dTicks], y2: ModUp[dr.y2, dTicks] ]]; vx1: INTEGER _ vr.x1; vy1: INTEGER _ vr.y1; vx2: INTEGER _ vr.x2; vy2: INTEGER _ vr.y2; IF vx1<0 THEN vx1 _ vr.x1 + ModUp[-vr.x1, vTicks]; IF vy1<0 THEN vy1 _ vr.y1 + ModUp[-vr.y1, vTicks]; IF vx2>LOOPHOLE[me.viewer.cw] THEN vx2 _ vr.x2-ModUp[vr.x2-me.viewer.cw, vTicks]; IF vy2>LOOPHOLE[me.viewer.ch] THEN vy2 _ vr.y2-ModUp[vr.y2-me.viewer.ch, vTicks]; <<-- Now v.. denotes area for ticks; vTicks denote increment; in viewer coordinates>> me.xBBptr.width _ me.bpp; me.xBBptr.height _ 1; me.xBBptr.src _ [LOOPHOLE[black],,0]; me.xBBptr.srcDesc _ PrincOps.SrcDesc[gray[PrincOps.GrayParm[ yOffset: 0, widthMinusOne: 0, --words heightMinusOne: 0 --lines ]]]; yStart _ LOOPHOLE[me.screen+Basics.LongMult[(me.vy-vy2), me.scWidthWords]]; yStop _ LOOPHOLE[me.screen+Basics.LongMult[(me.vy-vy1), me.scWidthWords]]; yInc _ Basics.LongMult[ticks, me.scWidthWords]; x _ Basics.LongMult[vx1+me.vx, me.bpp]; xStop _ Basics.LongMult[vx2+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.xBBptr.dst _ [LOOPHOLE[yTem],,xMod]; PrincOpsUtils.BITBLT[me.xBBptr]; yTem _ yTem+yInc ENDLOOP; x _ x+Basics.LongMult[ticks, me.bpp] ENDLOOP; IF me.bpp#1 THEN TerminalExtras.UnlockColorFrame[virtual]; }; } EXITS SomeError => NULL END; ShowTicks: PUBLIC PROC [onto: REF, value: INT_0] = <<--called from client>> BEGIN me: CDVPrivate.MyGraphicRef; WITH onto SELECT FROM x: CDVPrivate.MyGraphicRef => me _ x; c: CDSequencer.Command => {ShowTicks[onto: c.ref, value: value]; RETURN}; ENDCASE => RETURN; IF me#NIL THEN { pr: REF CDVPrivate.PainterRec ~ GetAPainterRec[me]; value _ MAX[0, value]; value _ MIN[4096, value]; pr.data _ NEW[CD.DesignNumber_value]; IF value=0 THEN CDVPrivate.RemoveAPainterRec[me, pr] ELSE CDVPrivate.IncludeAPainterRec[me, pr]; CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: rect, erase: TRUE, rect: CDBasics.universe, ref: NIL]] } END; GetAPainterRec: ENTRY PROC [me: CDVPrivate.MyGraphicRef] RETURNS [pr: REF CDVPrivate.PainterRec] = BEGIN ENABLE UNWIND => NULL; x: REF = CDProperties.GetPropFromList[me.properties, $CDxTickProc]; IF x#NIL THEN pr _ NARROW[x] ELSE { pr _ NEW[CDVPrivate.PainterRec_[proc: PaintTicks, rect: CDBasics.universe]]; me.properties _ Atom.PutPropOnList[me.properties, $CDxTickProc, pr] } END; END.