JaMImagerImpl.mesa
Last changed by Maureen Stone December 22, 1983 3:04 pm
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𡤌GVector.Sub[t2,t1];
df1𡤌GVector.Sub[f2,f1];
dt2𡤌GVector.Sub[t3,t1];
df2𡤌GVector.Sub[f3,f1];
adet𡤁.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];
};
note multiple display context behavior
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];
};
Initialization starts here
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] = {
info: Info ← GetInfo[frame];
ImagerOps.BeginBox[dc];
};
JStopBoxing: PROCEDURE [frame: Frame] = {
info: Info ← GetInfo[frame];
b: Imager.Box ← ImagerOps.EndBox[dc];
PutBox[frame,b];
};
JPushBox: PROCEDURE [frame: Frame] = {
b: Imager.Box ← GetBox[frame];
Imager.PushClipBox[dc,b];
**** temporarily removed ****
};
JPopBox: PROCEDURE [frame: Frame] = {
Imager.PopClipBox[dc];
**** 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,".setview"L,JSetVw];
JaMOps.RegisterExplicit[frame,".setfat"L,JSetFat];
JaMOps.RegisterExplicit[frame,".setopaque"L,JSetOpaque];
JaMOps.RegisterExplicit[frame,".initboxer"L,JStartBoxing];
JaMOps.RegisterExplicit[frame,".stopboxer"L,JStopBoxing];
JaMOps.RegisterExplicit[frame,".pushbox"L,JPushBox];
JaMOps.RegisterExplicit[frame,".popbox"L,JPopBox];
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];