<> <> DIRECTORY Imager, ImagerBasic USING [Rectangle], ImagerPrivate USING [Name, Class], ImagerTransform USING [InverseTransform, Invert, TransformRectangle], Font, Real USING [RoundI, LargestNumber], Graphics USING [Context, Box, UserToWorld, GetBounds], CGVector USING [Vec, Sub, Cross], Rope USING [ActionType, Fetch, Cat, Map, Length, ROPE], ConvertUnsafe USING [ToRope], ViewerOps USING[PaintViewer], ViewerClasses USING [Viewer], JaMBasic USING [Object], JaMInternal USING [Frame], JaMOps USING [defaultFrame, PopInteger, PushReal, PopReal, PopString, RegisterExplicit, StringText], JaMImager, JaMImagerContexts, JaMIPrivate; JaMImagerImpl: MONITOR IMPORTS Graphics, JaMOps, JaMImager, JaMIPrivate, ConvertUnsafe, Real, Imager, ImagerTransform, Font, CGVector, Rope, ViewerOps, JaMImagerContexts EXPORTS JaMImager, JaMIPrivate = { OPEN JaMIPrivate; Vec: TYPE = CGVector.Vec; GProc: TYPE = JaMImagerContexts.GProc; FONT: TYPE = Imager.FONT; ROPE: TYPE = Rope.ROPE; GetVec: PROCEDURE [frame: Frame] RETURNS[Vec] = { y: REAL _ JaMOps.PopReal[frame.opstk]; x: REAL _ JaMOps.PopReal[frame.opstk]; RETURN[[x,y]]; }; GetPoint: PROCEDURE [frame: Frame] RETURNS[x,y: REAL] = { y _ JaMOps.PopReal[frame.opstk]; x _ JaMOps.PopReal[frame.opstk]; RETURN[x,y] }; PutPoint: PROCEDURE[frame: Frame, x,y: REAL] = { JaMOps.PushReal[frame.opstk,x]; JaMOps.PushReal[frame.opstk,y] }; PopRope: PROC [info: Info] = { ls: LONG STRING _ [100]; JaMOps.StringText[JaMOps.PopString[info.frame.opstk],ls]; info.text _ ConvertUnsafe.ToRope[ls]; }; Box: TYPE = RECORD[xmin,ymin,xmax,ymax,w,h: REAL]; GetBox: PROC [frame: Frame] RETURNS[Box] = { b: Box; [b.xmax,b.ymax] _ GetPoint[frame]; [b.xmin,b.ymin] _ GetPoint[frame]; IF b.ymax< b.ymin THEN {t: REAL _ b.ymin; b.ymin _ b.ymax; b.ymax _ t}; IF b.xmax< b.xmin THEN {t: REAL _ b.xmin; b.xmin _ b.xmax; b.xmax _ t}; b.w _ b.xmax-b.xmin; b.h _ b.ymax-b.ymin; RETURN[b]; }; PutFontBox: PROCEDURE[frame: Frame, b: Font.Box] = { PutPoint[frame,b.xmin,b.ymin]; PutPoint[frame,b.xmax,b.ymax]; }; ViewToUser: PUBLIC PROC[context: Imager.Context, vx,vy: REAL] RETURNS [x,y: REAL] = { transformation: REF Imager.Transformation _ NARROW[IGet[context,T]]; [[x,y]] _ ImagerTransform.InverseTransform[p: [vx,vy],transform: transformation^]; }; ViewToUserRectangle: PROC[context: Imager.Context, vBox: ImagerBasic.Rectangle] RETURNS [uBox: ImagerBasic.Rectangle] = { transformation: REF Imager.Transformation _ NARROW[IGet[context,T]]; uBox _ ImagerTransform.TransformRectangle[rect: vBox, transform: ImagerTransform.Invert[transformation^]]; }; Paint: PUBLIC ENTRY SAFE PROCEDURE [self: ViewerClasses.Viewer, context: Graphics.Context, whatChanged: REF ANY, clear: BOOL] = TRUSTED { ENABLE UNWIND => NULL; info: Info _ NARROW[self.data]; IF whatChanged=NIL THEN { -- reset context box: Graphics.Box _ Graphics.GetBounds[context]; rect: Imager.IntRectangle; x,y: REAL; --a priori knowledge of World and Viewer coordinates makes this work [x,y] _ Graphics.UserToWorld[context,box.xmin,box.ymin]; rect _ [x: Real.RoundI[x], y: Real.RoundI[y], w: self.cw, h: self.ch]; Imager.Reset[info.vdc]; Imager.ConcatT[info.vdc, Imager.pointsToMeters]; --we like to think in points Imager.SetView[info.vdc,rect]; info.vw _ self.cw; info.vh _ self.ch; } ELSE info.proc[info]; }; Painter: PUBLIC PROCEDURE[proc: PROC [Imager.Context], frame: Frame _ NIL] = { info: Info; CallBack: PROC [info: Info] = { proc[info.vdc] }; IF frame=NIL THEN frame _ JaMOps.defaultFrame; info _ GetInfo[frame]; JaMImagerContexts.ForAllDCs[info.dcList,proc]; IF info.venabled THEN { info.proc _ CallBack; ViewerOps.PaintViewer[viewer: info.viewer, hint: client, whatChanged: info, clearClient: FALSE]; }; }; State: TYPE = REF StateRec; StateRec: TYPE = RECORD [ DCScpx, DCScpy, T, priorityImportant, color, noImage, strokeWidth, strokeEnd, clipOutline: REF]; stateStack: LIST OF State; IGet: PROC[context: Imager.Context, n: ImagerPrivate.Name] RETURNS [REF] = { class: ImagerPrivate.Class _ NARROW[context.class]; RETURN[class.IGet[context,n]]; }; ISet: PROC[context: Imager.Context, n: ImagerPrivate.Name, x: REF] = { class: ImagerPrivate.Class _ NARROW[context.class]; class.ISet[context,n,x]; }; GetCP: PROC[self: Imager.Context] RETURNS[x,y: REAL] = { class: ImagerPrivate.Class _ NARROW[self.class]; x _ class.IGetReal[self,DCScpx]; y _ class.IGetReal[self,DCScpy]; RETURN[x,y]; }; PushDC: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; new: State _ NEW[StateRec _ [ DCScpx: IGet[info.vdc,DCScpx], DCScpy: IGet[info.vdc,DCScpy], T: IGet[info.vdc,T], priorityImportant: IGet[info.vdc,priorityImportant], color: IGet[info.vdc,color], noImage: IGet[info.vdc,noImage], strokeWidth: IGet[info.vdc,strokeWidth], strokeEnd: IGet[info.vdc,strokeEnd], clipOutline: IGet[info.vdc,clipOutline] ]]; stateStack _ CONS[new,stateStack]; }; PopDC: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; old: State _ stateStack.first; stateStack _ stateStack.rest; ISet[info.vdc,DCScpx,old.DCScpx]; ISet[info.vdc,DCScpy,old.DCScpy]; ISet[info.vdc,T,old.T]; ISet[info.vdc,priorityImportant,old.priorityImportant]; ISet[info.vdc,color,old.color]; ISet[info.vdc,strokeWidth,old.strokeWidth]; ISet[info.vdc,strokeEnd,old.strokeEnd]; ISet[info.vdc,clipOutline,old.clipOutline]; }; JClipArea: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; paint: GProc ={Imager.ClipOutline[context: dc, outline: Imager.MakeOutline[info.trajectory]]}; Painter[paint,frame]; }; JClipBox: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.ClipRectangle[dc, box.xmin, box.ymin, box.w, box.h]}; box: Box _ GetBox[frame]; Painter[paint,frame]; }; JClipXArea: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; paint: GProc ={Imager.ExcludeOutline[dc, Imager.MakeOutline[info.trajectory]]}; Painter[paint,frame]; }; JClipXBox: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.ExcludeRectangle[dc, box.xmin, box.ymin, box.w, box.h]}; box: Box _ GetBox[frame]; Painter[paint,frame]; }; JTranslate: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.TranslateT[dc,tx,ty]}; tx,ty: REAL; [tx,ty]_GetPoint[frame]; Painter[paint,frame]; }; JScale: PROCEDURE [frame: Frame] = { paint: GProc ={ Imager.Scale2T[dc,sx,sy]}; sx,sy: REAL; [sx,sy]_GetPoint[frame]; Painter[paint,frame]; }; JRotate: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.RotateT[dc,a]}; a: REAL _ JaMOps.PopReal[frame.opstk]; Painter[paint,frame]; }; JSixPoint: PROCEDURE [frame: Frame] = { paint: GProc ={ Imager.TranslateT[dc,t1.x,t1.y]; Imager.ConcatT[dc,t]; Imager.TranslateT[dc,-f1.x,-f1.y]; }; f1,f2,f3,t1,t2,t3,df1,df2,dt1,dt2: Vec; adet: REAL; t: Imager.Transformation _ [0,0,0,0,0,0,none]; t3_GetVec[frame]; t2_GetVec[frame]; t1_GetVec[frame]; f3_GetVec[frame]; f2_GetVec[frame]; f1_GetVec[frame]; dt1_CGVector.Sub[t2,t1]; df1_CGVector.Sub[f2,f1]; dt2_CGVector.Sub[t3,t1]; df2_CGVector.Sub[f3,f1]; adet_1.0/CGVector.Cross[df1,df2]; t.a_(dt1.x*df2.y-dt2.x*df1.y)*adet; --m11 t.d_(dt1.y*df2.y-dt2.y*df1.y)*adet; --m12 t.b_(df1.x*dt2.x-df2.x*dt1.x)*adet; --m21 t.e_(df1.x*dt2.y-df2.x*dt1.y)*adet; --m22 Painter[paint,frame]; }; JConcat: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.ConcatT[dc,t]}; t: Imager.Transformation _ [0,0,0,0,0,0, none]; t.e _ JaMOps.PopReal[frame.opstk]; --m22 t.b _ JaMOps.PopReal[frame.opstk]; --m21 t.d _ JaMOps.PopReal[frame.opstk]; --m12 t.a _ JaMOps.PopReal[frame.opstk]; --m11 Painter[paint,frame]; }; <> JGetPos: PROCEDURE [frame: Frame] = { paint: GProc ={[x,y] _ GetCP[dc]}; x,y: REAL; Painter[paint,frame]; PutPoint[frame,x,y]; }; JSetPos: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.SetXY[dc,[x,y]]}; x,y: REAL; [x,y] _ GetPoint[frame]; Painter[paint,frame]; }; JRelSetPos: PROCEDURE [frame: Frame] = { paint: GProc ={ Imager.SetXYRel[dc,[x,y]]}; x,y: REAL; [x,y]_GetPoint[frame]; Painter[paint,frame]; }; JDrawTo: PROCEDURE [frame: Frame] = { paint: GProc ={ x0,y0: REAL; [x0,y0] _ GetCP[dc]; Imager.MaskVector[dc,[x0,y0],[x,y]]; }; x,y: REAL; [x,y]_GetPoint[frame]; Painter[paint,frame]; }; JRelDrawTo: PROCEDURE [frame: Frame] = { paint: GProc ={ x0,y0: REAL; [x0,y0] _ GetCP[dc]; Imager.MaskVector[dc,[x0,y0],[x0+x,y0+y]]; }; x,y: REAL; [x,y]_GetPoint[frame]; Painter[paint,frame]; }; JDrawBox: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.MaskRectangle[dc,box.xmin,box.ymin,box.w,box.h]}; box: Box _ GetBox[frame]; Painter[paint,frame]; }; JCover: PROCEDURE [frame: Frame] = { info: Info _ JaMIPrivate.GetInfo[frame]; paint: GProc ={ box: ImagerBasic.Rectangle _ ViewToUserRectangle[dc,[x:0, y:0, w: info.vw, h: info.vh]]; --only works for viewers Imager.MaskRectangle[dc, box.x, box.y, box.w, box.h]; }; Painter[paint,frame]; }; Erase: PROCEDURE [frame: Frame] = { info: Info _ JaMIPrivate.GetInfo[frame]; paint: GProc ={ erase: SAFE PROC = TRUSTED { box: ImagerBasic.Rectangle _ ViewToUserRectangle[dc,[x:0, y:0, w: info.vw, h: info.vh]]; --only works for viewers Imager.SetColor[dc, Imager.white]; Imager.MaskRectangle[dc, box.x, box.y, box.w, box.h]; }; Imager.DoSaveAll[dc,erase]; }; FOR l: JaMImagerContexts.DCList _ info.dcList, l.next UNTIL l=NIL DO IF l.initOnErase AND l.enabled THEN l.dc _ l.init[]; ENDLOOP; JaMImager.Painter[paint,frame]; }; JSetInvert: PROCEDURE [frame: Frame] = { paint: GProc ={[] _ Imager.SetColor[dc, Imager.XOR]}; Painter[paint,frame]; }; JGetTouch: PROCEDURE [frame: Frame] = { mx,my: REAL; [mx,my] _ JaMImager.ViewerMouse[frame,TRUE]; PutPoint[frame,mx,my]; }; JGetMouse: PROCEDURE [frame: Frame] = { mx,my: REAL; [mx,my] _ JaMImager.ViewerMouse[frame,FALSE]; PutPoint[frame,mx,my]; }; defaultPath: ROPE _ "Xerox/PressFonts/"; defaultFace: ROPE _ "/MRR"; JSetFont: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; size: REAL _ JaMOps.PopReal[frame.opstk]; PopRope[info]; info.font _ Imager.MakeFont[Rope.Cat[defaultPath,info.text,defaultFace],size]; }; JDrawChar: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.ShowChar[context: dc, char: Rope.Fetch[info.text], font: info.font]}; info: Info _ GetInfo[frame]; PopRope[info]; Painter[paint,frame]; }; JDrawText: PROCEDURE [frame: Frame] = { paint: GProc ={Imager.ShowCharacters[context: dc, characters: info.text, font: info.font]}; info: Info _ GetInfo[frame]; PopRope[info]; Painter[paint,frame]; }; JCharBox: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; PopRope[info]; PutFontBox[frame, Font.BoundingBox[font: info.font, char: Rope.Fetch[info.text]]]; }; JFontBox: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; PutFontBox[frame, Font.FontBoundingBox[info.font]]; }; JTextBox: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; PopRope[info]; PutFontBox[frame, RopeBox[info.font, info.text]]; }; JCharWidth: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; x,y: REAL; PopRope[info]; [[x,y]] _ Font.WidthVector[font: info.font, char: Rope.Fetch[info.text]]; PutPoint[frame,x,y]; }; JTextWidth: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; x,y: REAL; PopRope[info]; [x,y] _ RopeWidth[info.font, info.text]; PutPoint[frame,x,y]; }; RopeBox: PROC[font: FONT, rope: ROPE] RETURNS[ropeBox: Font.Box]= { collect: Rope.ActionType = TRUSTED { box: Font.Box _ Font.BoundingBox[font: font, char: c]; ropeBox.xmin _ MIN[ropeBox.xmin,box.xmin]; ropeBox.ymin _ MIN[ropeBox.ymin,box.ymin]; ropeBox.xmax _ MAX[ropeBox.xmax,box.xmax]; ropeBox.ymax _ MAX[ropeBox.ymax,box.ymax]; }; ropeBox _ [xmin: Real.LargestNumber, ymin: Real.LargestNumber, xmax: 0, ymax: 0]; [] _ Rope.Map[base: rope, action: collect, len: Rope.Length[rope]]; }; RopeWidth: PROC[font: FONT, rope: ROPE] RETURNS[wx,wy: REAL]= { collect: Rope.ActionType = TRUSTED { vec: Font.Pair _ Font.WidthVector[font: font, char: c]; wx _ wx+vec.x; wy _ wy+vec.y; }; wx _ wy _ 0; [] _ Rope.Map[base: rope, action: collect, len: Rope.Length[rope]]; }; JFlushPath: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; info.trajectory _ NIL; }; JMoveTo: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; x,y: REAL; [x,y]_GetPoint[frame]; info.trajectory _ LIST[Imager.MoveTo[[x,y]]]; }; JMoveToNext: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; x,y: REAL; [x,y]_GetPoint[frame]; info.trajectory _ CONS[Imager.MoveTo[[x,y]],info.trajectory]; }; JLineTo: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; x,y: REAL; [x,y]_GetPoint[frame]; IF info.trajectory=NIL THEN info.trajectory _ LIST[Imager.MoveTo[[0,0]]]; info.trajectory.first _ Imager.LineTo[info.trajectory.first,[x,y]]; }; JCurveTo: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; x1,y1,x2,y2,x3,y3: REAL; [x3,y3]_GetPoint[frame]; [x2,y2]_GetPoint[frame]; [x1,y1]_GetPoint[frame]; IF info.trajectory=NIL THEN info.trajectory _ LIST[Imager.MoveTo[[0,0]]]; info.trajectory.first _ Imager.CurveTo[info.trajectory.first,[x1,y1],[x2,y2],[x3,y3]]; }; JRectangle: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; box: Box _ GetBox[frame]; paint: GProc = {Imager.MaskRectangle[dc, box.xmin,box.ymin,box.w,box.h]}; Painter[paint,frame]; }; JDrawArea: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; paint: GProc = {Imager.MaskFill[dc, Imager.MakeOutline[info.trajectory]]}; Painter[paint,frame]; }; JDrawStroke: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; paint: GProc = {Imager.MaskStroke[dc,info.trajectory.first,width,ends]}; i: INTEGER _ JaMOps.PopInteger[frame.opstk]; width: REAL _ JaMOps.PopReal[frame.opstk]; ends: Imager.StrokeEnd _ (IF i=1 THEN square ELSE IF i=2 THEN round ELSE butt); IF info.trajectory#NIL THEN Painter[paint,frame]; }; JDrawStrokeClosed: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; paint: GProc = {Imager.MaskStrokeClosed[dc,info.trajectory.first,width]}; width: REAL _ JaMOps.PopReal[frame.opstk]; IF info.trajectory#NIL THEN Painter[paint,frame]; }; <> Init: PROC = { frame: Frame _ JaMOps.defaultFrame; JaMOps.RegisterExplicit[frame,".pushdc"L,PushDC]; JaMOps.RegisterExplicit[frame,".popdc"L,PopDC]; JaMOps.RegisterExplicit[frame,".translate"L,JTranslate]; JaMOps.RegisterExplicit[frame,".scale"L,JScale]; JaMOps.RegisterExplicit[frame,".rotate"L,JRotate]; JaMOps.RegisterExplicit[frame,".sixpoint"L,JSixPoint]; JaMOps.RegisterExplicit[frame,".concat"L,JConcat]; JaMOps.RegisterExplicit[frame,".getpos"L,JGetPos]; JaMOps.RegisterExplicit[frame,".setpos"L,JSetPos]; JaMOps.RegisterExplicit[frame,".rsetpos"L,JRelSetPos]; JaMOps.RegisterExplicit[frame,".drawto"L,JDrawTo]; JaMOps.RegisterExplicit[frame,".rdrawto"L,JRelDrawTo]; JaMOps.RegisterExplicit[frame,".drawbox"L,JDrawBox]; JaMOps.RegisterExplicit[frame,".cover"L,JCover]; JaMOps.RegisterExplicit[frame,".erase"L,Erase]; JaMOps.RegisterExplicit[frame,".setinvert"L,JSetInvert]; JaMOps.RegisterExplicit[frame,".touch"L,JGetTouch]; JaMOps.RegisterExplicit[frame,".mouse"L,JGetMouse]; JaMOps.RegisterExplicit[frame,".setfont"L,JSetFont]; JaMOps.RegisterExplicit[frame,".drawchar"L,JDrawChar]; JaMOps.RegisterExplicit[frame,".drawtext"L,JDrawText]; JaMOps.RegisterExplicit[frame,".charbox"L,JCharBox]; JaMOps.RegisterExplicit[frame,".textbox"L,JTextBox]; JaMOps.RegisterExplicit[frame,".charwidth"L,JCharWidth]; JaMOps.RegisterExplicit[frame,".textwidth"L,JTextWidth]; JaMOps.RegisterExplicit[frame,".fontbox"L,JFontBox]; JaMOps.RegisterExplicit[frame,".cliparea"L,JClipArea]; JaMOps.RegisterExplicit[frame,".clipbox"L,JClipBox]; JaMOps.RegisterExplicit[frame,".clipxarea"L,JClipXArea]; JaMOps.RegisterExplicit[frame,".clipxbox"L,JClipXBox]; JaMOps.RegisterExplicit[frame,".flushpath"L,JFlushPath]; JaMOps.RegisterExplicit[frame,".moveto"L,JMoveTo]; JaMOps.RegisterExplicit[frame,".movetonext"L,JMoveToNext]; JaMOps.RegisterExplicit[frame,".lineto"L,JLineTo]; JaMOps.RegisterExplicit[frame,".curveto"L,JCurveTo]; JaMOps.RegisterExplicit[frame,".rect"L,JRectangle]; JaMOps.RegisterExplicit[frame,".drawarea"L,JDrawArea]; JaMOps.RegisterExplicit[frame,".drawstroke"L,JDrawStroke]; JaMOps.RegisterExplicit[frame,".drawstrokeclosed"L,JDrawStrokeClosed]; }; Init; }. JGetYMode: PROCEDURE [frame: Frame] = { paint: GProc ={mode _ ImagerOps.GetYMode[dc]}; mode: ImagerOps.YMode; Painter[paint,frame]; JaMOps.PushInteger[frame.opstk, IF mode=topDown THEN 1 ELSE 0]; }; JSetYMode: PROCEDURE [frame: Frame] = { mode: LONG INTEGER _ JaMOps.PopInteger[frame.opstk]; paint: GProc ={ImagerOps.SetYMode[dc,IF mode>0 THEN topDown ELSE bottomUp]}; Painter[paint,frame]; }; JStartBoxing: PROCEDURE [frame: Frame] = { <> <> }; JStopBoxing: PROCEDURE [frame: Frame] = { <> <> <> }; JPushBox: PROCEDURE [frame: Frame] = { <> <> <<**** temporarily removed ****>> }; JPopBox: PROCEDURE [frame: Frame] = { <> <<**** temporarily removed ****>> }; PutBox: PROC[frame: Frame, b: Box] = { PutPoint[frame,b.xmin,b.ymin]; PutPoint[frame,b.xmax,b.ymax]; }; JDrawEOArea: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; paint: GProc = {Imager.DrawArea[dc,info.trajectory,TRUE]}; Painter[paint,frame]; }; GetRect: PROCEDURE [frame: Frame] RETURNS[r: Rect] = { [r.xmax,r.ymax] _ GetPoint[frame]; [r.xmin,r.ymin] _ GetPoint[frame]; RETURN[r]; }; PutRect: PROCEDURE[frame: Frame, r: Rect] = { PutPoint[frame,r.xmin,r.ymin]; PutPoint[frame,r.xmax,r.ymax]; }; JSetFat: PROCEDURE [frame: Frame] = { paint: GProc ={[] _ Imager.SetFat[dc,b]}; b: BOOLEAN _ JaMOps.PopBoolean[frame.opstk]; Painter[paint,frame]; }; JSetOpaque: PROCEDURE [frame: Frame] = { paint: GProc ={[] _ Imager.SetPaintMode[dc,IF b THEN opaque ELSE transparent]}; b: BOOLEAN _ JaMOps.PopBoolean[frame.opstk]; Painter[paint,frame]; }; JVisible: PROCEDURE [frame: Frame] = { b: BOOLEAN; paint: GProc = {b _ Imager.Visible[dc]}; Painter[paint,frame]; JaMOps.PushBoolean[frame.opstk,b]; }; JScreenCoords: PROCEDURE [frame: Frame] = { y: REAL _ JaMOps.PopReal[frame.opstk]; x: REAL _ JaMOps.PopReal[frame.opstk]; paint: GProc = {[x, y] _ Imager.UserToWorld[dc, x, y]}; -- get screen coordinates Painter[paint,frame]; JaMOps.PushReal[frame.opstk,x]; JaMOps.PushReal[frame.opstk,y]; }; JUserCoords: PROCEDURE [frame: Frame] = { y: REAL _ JaMOps.PopReal[frame.opstk]; x: REAL _ JaMOps.PopReal[frame.opstk]; paint: GProc = {[x, y] _ Imager.WorldToUser[dc, x, y]}; -- get user coordinates Painter[paint,frame]; JaMOps.PushReal[frame.opstk,x]; JaMOps.PushReal[frame.opstk,y]; }; JKnot: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; y: REAL _ JaMOps.PopReal[frame.opstk]; x: REAL _ JaMOps.PopReal[frame.opstk]; Spline.Knot[info.spline,x,y]; }; JSpline: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; Spline.Enter[info.spline,info.trajectory,FALSE]; }; JCSpline: PROCEDURE [frame: Frame] = { info: Info _ GetInfo[frame]; Spline.Enter[info.spline,info.trajectory,TRUE]; }; <> JaMOps.RegisterExplicit[frame,".setfat"L,JSetFat]; JaMOps.RegisterExplicit[frame,".setopaque"L,JSetOpaque]; <> <> <> <> JaMOps.RegisterExplicit[frame,".visible"L,JVisible]; JaMOps.RegisterExplicit[frame,".setymode"L,JSetYMode]; JaMOps.RegisterExplicit[frame,".getymode"L,JGetYMode]; JaMOps.RegisterExplicit[frame,".screencoords"L,JScreenCoords]; JaMOps.RegisterExplicit[frame,".usercoords"L,JUserCoords]; JaMOps.RegisterExplicit[frame,".settarget"L,JSetTarget]; JaMOps.RegisterExplicit[frame,".draweoarea"L,JDrawEOArea]; JaMOps.RegisterExplicit[frame,".clipeoarea"L,JClipEOArea]; JaMOps.RegisterExplicit[frame,".bitmap"L,JBitmap]; JaMOps.RegisterExplicit[frame,".knot"L,JKnot]; JaMOps.RegisterExplicit[frame,".spline"L,JSpline]; JaMOps.RegisterExplicit[frame,".cspline"L,JCSpline];