-- JaMGraphicsImpl.mesa
-- Last changed by Doug Wyatt, 19-Jan-82 15:20:56
DIRECTORY
JaMGraphics USING [Mouse, Update],
Graphics,
GraphicsExtra,
CGBasic USING [Vec],
CGScreen USING [MouseToWorld],
CGVector USING [Sub, Cross],
Spline USING [Ref, New, Knot, Enter],
JaMFnsDefs USING [PopInteger, PushInteger, PushReal, GetReal, PopString,
PushBoolean, PopBoolean, Register],
JaMTajo USING [SetMouseProc];
JaMGraphicsImpl: PROGRAM
IMPORTS JaMFnsDefs, JaMTajo, JaMGraphics,
Graphics, GraphicsExtra, CGVector, CGScreen, Spline
EXPORTS JaMGraphics = {
OPEN J: JaMFnsDefs, G: Graphics, E: GraphicsExtra,
Vector: CGVector, Screen: CGScreen, JaMGraphics;
Vec: TYPE = CGBasic.Vec;
dc: G.Context←NIL;
box: G.Box;
image: G.ImageRef;
GetDC: PUBLIC PROCEDURE RETURNS[G.Context] = { RETURN[dc] };
InitDC: PROCEDURE = {
dc ← G.NewContext[];
G.ClipBox[dc,box];
};
PushDC: PROCEDURE = {
[] ← G.Save[dc];
};
PopDC: PROCEDURE = {
G.Restore[dc];
};
GetVec: PROCEDURE RETURNS[Vec] = {
y: REAL ← J.GetReal[]; x: REAL ← J.GetReal[]; RETURN[[x,y]] };
GetPoint: PROCEDURE RETURNS[x,y: REAL] = {
y ← J.GetReal[]; x ← J.GetReal[]; RETURN[x,y] };
PutPoint: PROCEDURE[x,y: REAL] = { J.PushReal[x]; J.PushReal[y] };
Rect: TYPE = RECORD[xmin,ymin,xmax,ymax: REAL];
GetRect: PROCEDURE RETURNS[r: Rect] = {
[r.xmax,r.ymax] ← GetPoint[];
[r.xmin,r.ymin] ← GetPoint[];
RETURN[r];
};
PutRect: PROCEDURE[r: Rect] = {
PutPoint[r.xmin,r.ymin];
PutPoint[r.xmax,r.ymax];
};
JSetVw: PROCEDURE = {
rt: Rect ← GetRect[];
rf: Rect ← GetRect[];
-- *** fix this
-- SetView[dc,@rf,@rt];
};
JClipArea: PROCEDURE = {
G.ClipArea[dc];
};
JClipEOArea: PROCEDURE = {
G.ClipArea[self: dc, parityFill: TRUE];
};
JClipXArea: PROCEDURE = {
G.ClipArea[self: dc, exclude: TRUE];
};
JClipBox: PROCEDURE = {
box: G.Box ← GetBox[];
G.ClipBox[dc,box];
};
JClipXBox: PROCEDURE = {
box: G.Box ← GetBox[];
G.ClipBox[dc,box,TRUE];
};
JTranslate: PROCEDURE = {
tx,ty: REAL; [tx,ty]←GetPoint[];
G.Translate[dc,tx,ty];
};
JScale: PROCEDURE = {
sx,sy: REAL; [sx,sy]←GetPoint[];
G.Scale[dc,sx,sy];
};
JRotate: PROCEDURE = {
a: REAL ← J.GetReal[];
G.Rotate[dc,a];
};
JSixPoint: PROCEDURE = {
f1,f2,f3,t1,t2,t3,df1,df2,dt1,dt2: Vec;
adet: REAL;
xx,xy,yx,yy,tx,ty: REAL;
t3←GetVec[];
t2←GetVec[];
t1←GetVec[];
f3←GetVec[];
f2←GetVec[];
f1←GetVec[];
[[tx,ty]]←Vector.Sub[t1,f1];
dt1←Vector.Sub[t2,t1];
df1←Vector.Sub[f2,f1];
dt2←Vector.Sub[t3,t1];
df2←Vector.Sub[f3,f1];
adet←1.0/Vector.Cross[df1,df2];
xx←(dt1.x*df2.y-dt2.x*df1.y)*adet;
xy←(df1.x*dt2.x-df2.x*dt1.x)*adet;
yx←(dt1.y*df2.y-dt2.y*df1.y)*adet;
yy←(df1.x*dt2.y-df2.x*dt1.y)*adet;
G.Translate[dc,tx,ty];
G.Concat[dc,xx,xy,yx,yy]
};
JConcat: PROCEDURE = {
xx,xy,yx,yy: REAL;
yy ← J.GetReal[];
yx ← J.GetReal[];
xy ← J.GetReal[];
xx ← J.GetReal[];
G.Concat[dc,xx,xy,yx,yy];
};
JGetPos: PROCEDURE = {
x,y: REAL; [x,y]←G.GetCP[dc];
PutPoint[x,y];
};
JMoveTo: PROCEDURE = {
x,y: REAL; [x,y]←GetPoint[];
G.MoveTo[dc,x,y];
};
JDrawTo: PROCEDURE = {
x,y: REAL; [x,y]←GetPoint[];
G.DrawTo[dc,x,y];
Update[];
};
JRelMoveTo: PROCEDURE = {
x,y: REAL; [x,y]←GetPoint[];
G.MoveTo[dc,x,y,TRUE];
};
JRelDrawTo: PROCEDURE = {
x,y: REAL; [x,y]←GetPoint[];
G.DrawTo[dc,x,y,TRUE];
Update[];
};
JDrawBox: PROCEDURE = {
box: G.Box ← GetBox[];
G.DrawBox[dc,box];
Update[];
};
JCover: PROCEDURE = {
G.DrawBox[dc,G.GetBounds[dc]];
Update[];
};
JSetInvert: PROCEDURE = {
[] ← G.SetPaintMode[dc, invert];
};
JSetColor: PROCEDURE = {
t: CARDINAL←LOOPHOLE[J.PopInteger[],CARDINAL];
G.SetColor[dc,t];
};
JSetFat: PROCEDURE = {
b: BOOLEAN ← J.PopBoolean[];
[] ← G.SetFat[dc,b];
};
JSetOpaque: PROCEDURE = {
b: BOOLEAN ← J.PopBoolean[];
[] ← G.SetPaintMode[dc,IF b THEN opaque ELSE transparent];
};
JErase: PROCEDURE = {
mark: G.Mark ← G.Save[dc];
G.SetColor[dc,0];
JCover[];
G.Restore[dc,mark];
};
JGetTouch: PROCEDURE = {
mx,my: INTEGER;
[mx,my] ← Mouse[TRUE];
PutCoords[mx,my];
};
JGetMouse: PROCEDURE = {
mx,my: INTEGER;
[mx,my] ← Mouse[FALSE];
PutCoords[mx,my];
};
PutCoords: PROC[mx,my: INTEGER] = {
x,y: REAL;
[x,y] ← ScreenCoordsToUser[mx,my];
PutPoint[x,y];
};
MouseToUser: PROCEDURE[x,y:INTEGER] = {
ux,uy: REAL; [ux,uy]←ScreenCoordsToUser[x,y];
PutPoint[ux,uy];
};
half: REAL=0.5;
ScreenCoordsToUser: PROCEDURE[sx,sy: INTEGER] RETURNS[x,y: REAL] = {
x0,y0: INTEGER;
[x0,y0] ← Screen.MouseToWorld[sx,sy];
[x,y] ← G.WorldToUser[dc,x0,y0];
RETURN[x,y];
};
font: E.FontRef ← E.DefaultStrikeFont[];
text: REF TEXT ← NEW[TEXT[256]];
JSetFont: PROCEDURE = {
J.PopString[LOOPHOLE[text]];
font ← E.NewStrikeFont[text];
};
JGetYMode: PROCEDURE = {
mode: E.YMode ← E.GetYMode[dc];
J.PushInteger[IF mode=topDown THEN 1 ELSE 0];
};
JSetYMode: PROCEDURE = {
mode: INTEGER ← J.PopInteger[];
E.SetYMode[dc,IF mode>0 THEN topDown ELSE bottomUp];
};
JDrawChar: PROCEDURE = {
J.PopString[LOOPHOLE[text]];
IF text.length>0 THEN text.length ← 1;
G.DrawText[self: dc, text: text, font: font];
Update[];
};
JDrawText: PROCEDURE = {
J.PopString[LOOPHOLE[text]];
G.DrawText[self: dc, text: text, font: font];
Update[];
};
JCharBox: PROCEDURE = {
J.PopString[LOOPHOLE[text]];
IF text.length>0 THEN text.length ← 1;
PushTextBox[text];
};
JTextBox: PROCEDURE = {
J.PopString[LOOPHOLE[text]];
PushTextBox[text];
};
JCharWidth: PROCEDURE = {
J.PopString[LOOPHOLE[text]];
IF text.length>0 THEN text.length ← 1;
PushTextWidth[text];
};
JTextWidth: PROCEDURE = {
J.PopString[LOOPHOLE[text]];
PushTextWidth[text];
};
PushTextBox: PROCEDURE[text: REF READONLY TEXT] = {
xmin,xmax,ymin,ymax: REAL;
[xmin: xmin, ymin: ymin, xmax: xmax, ymax: ymax] ← G.TextBox[font,text];
J.PushReal[xmin];
J.PushReal[ymin];
J.PushReal[xmax];
J.PushReal[ymax];
};
PushTextWidth: PROCEDURE[text: REF READONLY TEXT] = {
xw,yw: REAL;
[xw: xw, yw: yw] ← G.TextWidth[font,text];
J.PushReal[xw];
J.PushReal[yw];
};
JFontBox: PROCEDURE = {
xmin,xmax,ymin,ymax: REAL;
[xmin: xmin, ymin: ymin, xmax: xmax, ymax: ymax] ← G.FontBox[font];
J.PushReal[xmin];
J.PushReal[ymin];
J.PushReal[xmax];
J.PushReal[ymax];
};
PutBox: PROC[b: G.Box] = {
PutPoint[b.xmin,b.ymin];
PutPoint[b.xmax,b.ymax];
};
GetBox: PROC RETURNS[G.Box] = {
b: G.Box;
[b.xmax,b.ymax] ← GetPoint[];
[b.xmin,b.ymin] ← GetPoint[];
RETURN[b];
};
JStartBoxing: PROCEDURE = {
G.BeginBox[dc];
};
JStopBoxing: PROCEDURE = {
b: G.Box ← G.EndBox[dc];
PutBox[b];
};
JPushBox: PROCEDURE = {
b: G.Box ← GetBox[];
-- G.PushClipBox[dc,b];
-- **** temporarily removed ****
};
JPopBox: PROCEDURE = {
-- G.PopClipBox[dc];
-- **** temporarily removed ****
};
JVisible: PROCEDURE = {
J.PushBoolean[G.Visible[dc]];
};
JLineTo: PROCEDURE = {
x,y: REAL; [x,y]←GetPoint[];
G.LineTo[dc,x,y];
};
JCurveTo: PROCEDURE = {
x1,y1,x2,y2,x3,y3: REAL;
[x3,y3]←GetPoint[];
[x2,y2]←GetPoint[];
[x1,y1]←GetPoint[];
G.CurveTo[dc,x1,y1,x2,y2,x3,y3];
};
JRectangle: PROCEDURE = {
x0,y0,x1,y1: REAL;
[x1,y1]←GetPoint[];
[x0,y0]←GetPoint[];
G.Rectangle[dc,x0,y0,x1,y1];
};
JClose: PROCEDURE = {
G.Close[dc];
};
JDrawArea: PROCEDURE = {
G.DrawArea[dc];
Update[];
};
JDrawEOArea: PROCEDURE = {
G.DrawArea[dc,TRUE];
Update[];
};
JDrawPath: PROCEDURE = {
width: REAL ← J.GetReal[];
G.DrawPath[dc,width];
Update[];
};
spline: Spline.Ref ← Spline.New[];
JKnot: PROCEDURE = {
y: REAL ← J.GetReal[];
x: REAL ← J.GetReal[];
Spline.Knot[spline,x,y];
};
JSpline: PROCEDURE = {
Spline.Enter[spline,dc,FALSE];
};
JCSpline: PROCEDURE = {
Spline.Enter[spline,dc,TRUE];
};
bitmap: E.BitmapRef ← NIL;
bmw: CARDINAL = 250;
bmh: CARDINAL = 200;
JBitmap: PROCEDURE = {
E.DrawBitmap[dc,bitmap,bmw,bmh,0,0,0,bmh];
Update[];
};
JSetTarget: PROC = {
b: BOOLEAN ← J.PopBoolean[];
E.SetTargetBitmap[dc,IF b THEN bitmap ELSE NIL];
};
JNewAISImage: PROC = {
J.PopString[LOOPHOLE[text]];
image ← E.NewAisImage[text];
};
JDrawImage: PROC = {
IF image=NIL THEN RETURN;
G.DrawImage[dc,image];
Update[];
};
-- Initialization starts here
dc ← G.NewContext[];
box ← G.GetBounds[dc];
G.ClipBox[dc,box];
bitmap ← E.NewBitmap[bmw,bmh];
[] ← JaMTajo.SetMouseProc[MouseToUser];
J.Register[".initdc"L,InitDC];
J.Register[".pushdc"L,PushDC];
J.Register[".popdc"L,PopDC];
J.Register[".setview"L,JSetVw];
J.Register[".translate"L,JTranslate];
J.Register[".scale"L,JScale];
J.Register[".rotate"L,JRotate];
J.Register[".sixpoint"L,JSixPoint];
J.Register[".concat"L,JConcat];
J.Register[".getpos"L,JGetPos];
J.Register[".moveto"L,JMoveTo];
J.Register[".rmoveto"L,JRelMoveTo];
J.Register[".drawto"L,JDrawTo];
J.Register[".rdrawto"L,JRelDrawTo];
J.Register[".drawbox"L,JDrawBox];
J.Register[".cover"L,JCover];
J.Register[".setinvert"L,JSetInvert];
J.Register[".setcolor"L,JSetColor];
J.Register[".setfat"L,JSetFat];
J.Register[".setopaque"L,JSetOpaque];
J.Register[".touch"L,JGetTouch];
J.Register[".mouse"L,JGetMouse];
J.Register[".erase"L,JErase];
J.Register[".setfont"L,JSetFont];
J.Register[".drawchar"L,JDrawChar];
J.Register[".drawtext"L,JDrawText];
J.Register[".charbox"L,JCharBox];
J.Register[".textbox"L,JTextBox];
J.Register[".charwidth"L,JCharWidth];
J.Register[".textwidth"L,JTextWidth];
J.Register[".fontbox"L,JFontBox];
J.Register[".initboxer"L,JStartBoxing];
J.Register[".stopboxer"L,JStopBoxing];
J.Register[".pushbox"L,JPushBox];
J.Register[".popbox"L,JPopBox];
J.Register[".visible"L,JVisible];
J.Register[".cliparea"L,JClipArea];
J.Register[".clipbox"L,JClipBox];
J.Register[".lineto"L,JLineTo];
J.Register[".curveto"L,JCurveTo];
J.Register[".rect"L,JRectangle];
J.Register[".close"L,JClose];
J.Register[".drawarea"L,JDrawArea];
J.Register[".draweoarea"L,JDrawEOArea];
J.Register[".drawpath"L,JDrawPath];
J.Register[".knot"L,JKnot];
J.Register[".spline"L,JSpline];
J.Register[".cspline"L,JCSpline];
J.Register[".bitmap"L,JBitmap];
J.Register[".clipeoarea"L,JClipEOArea];
J.Register[".clipxarea"L,JClipXArea];
J.Register[".clipxbox"L,JClipXBox];
J.Register[".getymode"L,JGetYMode];
J.Register[".setymode"L,JSetYMode];
J.Register[".settarget"L,JSetTarget];
J.Register[".newaisimage"L,JNewAISImage];
J.Register[".drawimage"L,JDrawImage];
}.