-- JaMGraphicsImpl.mesa -- Mesa 6 version -- Last changed by Doug Wyatt, March 30, 1981 1:43 PM DIRECTORY JaMGraphicsDefs, Graphics USING [DeviceContext, DisplayContext, NewContext, FreeContext, InitContext, PushContext, PopContext, PaintingFunction, white, Color, SetPaint, SetTexture, SetColor, Translate, Scale, Rotate, Concatenate, ScreenToUser, SetLineWidth, GetPosition, MoveTo, DrawTo, RelMoveTo, RelDrawTo, DrawCubic, DrawRectangle, DrawScreenArea, StartAreaPath, EnterPoint, EnterCubic, NewBoundary, DrawArea, MakeFont, SetFont, DisplayChar, DisplayString, CharData, GetCharBox, GetStringBox, GetFontBox, BoundingBox, InitBoxer, StopBoxer, PushClipBox, PopClipBox, Visible, SetClipArea, IntersectClipArea], AltoDevice USING [NewAltoDevice, ScreenBitmap, ScreenOrigin], PressDevice USING [NewPressDevice], Device USING [Object, Free], OpaqueDevice USING [], Vector USING [Vec, Matrix, Sub, Cross, Min, Max], Cubic USING [Coeffs, Bezier, CoeffsToBezier, BezierToCoeffs], JaMFnsDefs USING [PopInteger, PushReal, GetReal, PopString, PushBoolean, Register, SetMouseProc, JaMStream, GetJaMBreak], KeyDefs USING [Mouse]; JaMGraphicsImpl: PROGRAM IMPORTS JaMFnsDefs,Graphics,AltoDevice,PressDevice,Device,Vector,Cubic EXPORTS JaMGraphicsDefs, OpaqueDevice = { OPEN J:JaMFnsDefs,G:Graphics; Vec: TYPE = Vector.Vec; Coeffs: TYPE = Cubic.Coeffs; DeviceObject: PUBLIC TYPE = Device.Object; dev: G.DeviceContext_NIL; pressdev: G.DeviceContext_NIL; olddc: G.DisplayContext_NIL; mousedc: G.DisplayContext_NIL; dc: G.DisplayContext_NIL; GetDC: PUBLIC PROCEDURE RETURNS[G.DisplayContext] = { RETURN[dc]; }; InitDC: PROCEDURE = { G.InitContext[dc]; }; PushDC: PROCEDURE = { G.PushContext[dc]; }; PopDC: PROCEDURE = { G.PopContext[dc]; }; Point: TYPE = Vec; GetPoint: PROCEDURE[p: POINTER TO Point] = { p.y _ J.GetReal[]; p.x _ J.GetReal[]; }; PutPoint: PROCEDURE[p: POINTER TO Point] = { J.PushReal[p.x]; J.PushReal[p.y]; }; Rect: TYPE = RECORD[ll,ur: Point]; GetRect: PROCEDURE[r: POINTER TO Rect] = { GetPoint[@r.ur]; GetPoint[@r.ll]; }; PutRect: PROCEDURE[r: POINTER TO Rect] = { PutPoint[@r.ll]; PutPoint[@r.ur]; }; JSetVw: PROCEDURE = { rf: Rect; rt: Rect; GetRect[@rt]; GetRect[@rf]; -- *** fix this -- SetView[dc,@rf,@rt]; }; JEnterRect: PROCEDURE = { r: Rect; ll,ur: Vec; GetRect[@r]; ll_Vector.Min[r.ll,r.ur]; ur_Vector.Max[r.ll,r.ur]; G.EnterPoint[dc,ll]; G.EnterPoint[dc,[ll.x,ur.y]]; G.EnterPoint[dc,ur]; G.EnterPoint[dc,[ur.x,ll.y]]; G.NewBoundary[dc]; }; JSetClip: PROCEDURE = { G.StartAreaPath[dc]; JEnterRect; G.SetClipArea[dc]; }; JClipArea: PROCEDURE = { G.SetClipArea[dc]; }; JClippedClipArea: PROCEDURE = { G.IntersectClipArea[dc]; }; JTranslate: PROCEDURE = { p: Point; GetPoint[@p]; G.Translate[dc,p]; }; JScale: PROCEDURE = { p: Point; GetPoint[@p]; G.Scale[dc,p]; }; JRotate: PROCEDURE = { a: REAL; a _ J.GetReal[]; G.Rotate[dc,a]; }; JSixPoint: PROCEDURE = { f1,f2,f3,t1,t2,t3,o1,df1,df2,dt1,dt2:Point; adet:REAL; m:Vector.Matrix; GetPoint[@t3]; GetPoint[@t2]; GetPoint[@t1]; GetPoint[@f3]; GetPoint[@f2]; GetPoint[@f1]; o1_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]; m.a11_(dt1.x*df2.y-dt2.x*df1.y)*adet; m.a12_(df1.x*dt2.x-df2.x*dt1.x)*adet; m.a21_(dt1.y*df2.y-dt2.y*df1.y)*adet; m.a22_(df1.x*dt2.y-df2.x*dt1.y)*adet; G.Translate[dc,o1]; G.Concatenate[dc,m] }; JConcat: PROCEDURE = { m: Vector.Matrix; m.a22 _ J.GetReal[]; m.a21 _ J.GetReal[]; m.a12 _ J.GetReal[]; m.a11 _ J.GetReal[]; G.Concatenate[dc,m]; }; JLineWidth: PROCEDURE = { w: REAL _ J.GetReal[]; G.SetLineWidth[dc,w]; }; JGetPos: PROCEDURE = { p: Point_G.GetPosition[dc]; PutPoint[@p]; }; JMoveTo: PROCEDURE = { p: Point; GetPoint[@p]; G.MoveTo[dc,p]; }; JDrawTo: PROCEDURE = { p: Point; GetPoint[@p]; G.DrawTo[dc,p]; }; JDot: PROCEDURE = { p: Point; GetPoint[@p]; G.MoveTo[dc,p]; G.DrawTo[dc,p]; }; JRelMoveTo: PROCEDURE = { p: Point; GetPoint[@p]; G.RelMoveTo[dc,p]; }; JRelDrawTo: PROCEDURE = { p: Point; GetPoint[@p]; G.RelDrawTo[dc,p]; }; JDrawBoxArea: PROCEDURE = { r: Rect; GetRect[@r]; G.DrawRectangle[dc,r.ll,r.ur]; }; JDrawScreenArea: PUBLIC PROCEDURE = { G.DrawScreenArea[dc]; }; JSetPaint: PROCEDURE = { f: INTEGER; p: G.PaintingFunction; f_J.PopInteger[]; SELECT f FROM 0 => p_paint; 1 => p_replace; 2 => p_invert; 3 => p_erase; ENDCASE => p_paint; G.SetPaint[dc,p]; }; JSetTexture: PROCEDURE = { t: CARDINAL; t_LOOPHOLE[J.PopInteger[],CARDINAL]; G.SetTexture[dc,t]; }; JSetColor: PROCEDURE = { h,s,b: CARDINAL; b_LOOPHOLE[J.PopInteger[],CARDINAL]; s_LOOPHOLE[J.PopInteger[],CARDINAL]; h_LOOPHOLE[J.PopInteger[],CARDINAL]; G.SetColor[dc,G.Color[h,s,b]]; }; JErase: PROCEDURE = { G.PushContext[dc]; G.SetTexture[dc,G.white]; G.SetPaint[dc,replace]; G.DrawScreenArea[dc]; G.PopContext[dc]; }; Coords: TYPE = MACHINE DEPENDENT RECORD[x,y: INTEGER]; mouse: POINTER TO Coords = LOOPHOLE[424B]; cursor: POINTER TO Coords = LOOPHOLE[426B]; JGetTouch: PROCEDURE = { UNTIL KeyDefs.Mouse.buttons = Red DO IF J.GetJaMBreak[] THEN RETURN ENDLOOP; UNTIL KeyDefs.Mouse.buttons = None DO IF J.GetJaMBreak[] THEN RETURN ENDLOOP; JGetMouse; }; JGetMouse: PROCEDURE = { p: Point_ScreenCoordsToUser[mouse^]; PutPoint[@p]; }; MouseToUser: PROCEDURE[x,y:INTEGER] = { p: Point_ScreenCoordsToUser[[x,y]]; PutPoint[@p]; }; half: REAL=0.5; ScreenCoordsToUser: PROCEDURE[c: Coords] RETURNS[Point] = { x0,y0: INTEGER; pt: Point; [x0,y0]_AltoDevice.ScreenOrigin[]; pt_[(c.x-x0)+half,(c.y-y0)+half]; -- the center of the pixel RETURN[G.ScreenToUser[mousedc,pt]]; }; JSetFont: PROCEDURE = { fam: STRING _ [30]; size: REAL; size_J.GetReal[]; J.PopString[fam]; G.SetFont[dc,G.MakeFont[fam],size]; }; JDrawChar: PROCEDURE = { s: STRING _ [5]; J.PopString[s]; G.DisplayChar[dc,s[0]]; }; JDrawChars: PROCEDURE = { s: STRING _ [256]; J.PopString[s]; FOR i:CARDINAL IN[0..s.length) DO G.DisplayChar[dc,s[i]]; ENDLOOP; }; JEraseChar: PROCEDURE = { s: STRING _ [5]; J.PopString[s]; -- *** fix this -- EraseChar[dc,s[0]]; }; JDrawString: PROCEDURE = { s: STRING _ [256]; J.PopString[s]; G.DisplayString[dc,s] }; JGetCharBox: PROCEDURE = { s: STRING _ [5]; box: G.CharData; J.PopString[s]; G.GetCharBox[dc,s[0],@box]; J.PushReal[box.size.x]; J.PushReal[box.size.y]; J.PushReal[box.origin.x]; J.PushReal[box.origin.y]; J.PushReal[box.width.x]; J.PushReal[box.width.y]; }; JGetStringBox: PROCEDURE = { s: STRING _ [256]; box: G.CharData; J.PopString[s]; G.GetStringBox[dc,s,@box]; J.PushReal[box.size.x]; J.PushReal[box.size.y]; J.PushReal[box.origin.x]; J.PushReal[box.origin.y]; J.PushReal[box.width.x]; J.PushReal[box.width.y]; }; JGetFontBox: PROCEDURE = { box: G.CharData; G.GetFontBox[dc,@box]; J.PushReal[box.size.x]; J.PushReal[box.size.y]; J.PushReal[box.origin.x]; J.PushReal[box.origin.y]; J.PushReal[box.width.x]; J.PushReal[box.width.y]; }; JEnterCubic: PROCEDURE = { c: Coeffs; GetPoint[@c.c3]; GetPoint[@c.c2]; GetPoint[@c.c1]; GetPoint[@c.c0]; G.EnterCubic[dc,@c]; }; JDrawCubic: PROCEDURE = { c: Coeffs; GetPoint[@c.c3]; GetPoint[@c.c2]; GetPoint[@c.c1]; GetPoint[@c.c0]; G.DrawCubic[dc,@c]; }; JBezierToCubic: PROCEDURE = { b: Cubic.Bezier; c: Coeffs; GetPoint[@b.b3]; GetPoint[@b.b2]; GetPoint[@b.b1]; GetPoint[@b.b0]; c_Cubic.BezierToCoeffs[b]; PutPoint[@c.c0]; PutPoint[@c.c1]; PutPoint[@c.c2]; PutPoint[@c.c3]; }; JCubicToBezier: PROCEDURE = { c: Coeffs; b: Cubic.Bezier; GetPoint[@c.c3]; GetPoint[@c.c2]; GetPoint[@c.c1]; GetPoint[@c.c0]; b_Cubic.CoeffsToBezier[c]; PutPoint[@b.b0]; PutPoint[@b.b1]; PutPoint[@b.b2]; PutPoint[@b.b3]; }; GetBoundingBox: PROCEDURE[b: POINTER TO G.BoundingBox] = { FOR i: CARDINAL IN[0..4) DO GetPoint[@b[i]] ENDLOOP; }; PutBoundingBox: PROCEDURE[b: POINTER TO G.BoundingBox] = { FOR i: CARDINAL IN[0..4) DO PutPoint[@b[i]] ENDLOOP; }; JStartBoxing: PROCEDURE = { G.InitBoxer[dc]; }; JStopBoxing: PROCEDURE = { b: G.BoundingBox; G.StopBoxer[dc,@b]; PutBoundingBox[@b]; }; JPushBox: PROCEDURE = { b: G.BoundingBox; GetBoundingBox[@b]; G.PushClipBox[dc,@b]; }; JPopBox: PROCEDURE = { G.PopClipBox[dc]; }; JVisible: PROCEDURE = { J.PushBoolean[G.Visible[dc]]; }; JStartPath: PROCEDURE = { G.StartAreaPath[dc]; }; JStartEOPath: PROCEDURE = { G.StartAreaPath[dc,TRUE]; }; JEnterPoint: PROCEDURE = { p: Point; GetPoint[@p]; G.EnterPoint[dc,p]; }; JNewBoundary: PROCEDURE = { G.NewBoundary[dc]; }; JDrawArea: PROCEDURE = { G.DrawArea[dc]; }; JOpenPress: PROCEDURE = { pressfilename: STRING_[64]; J.PopString[pressfilename]; pressdev_PressDevice.NewPressDevice[pressfilename]; olddc_dc; dc_G.NewContext[pressdev] }; JClosePress: PROCEDURE = { G.FreeContext[@dc]; dc_olddc; Device.Free[@pressdev]; }; -- Initialization starts here dev_AltoDevice.NewAltoDevice[AltoDevice.ScreenBitmap[]]; dc_G.NewContext[dev]; mousedc_dc; J.SetMouseProc[J.JaMStream[],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[".linewidth"L,JLineWidth]; 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[".dot"L,JDot]; J.Register[".drawboxarea"L,JDrawBoxArea]; J.Register[".drawscreenarea"L,JDrawScreenArea]; J.Register[".paint"L,JSetPaint]; J.Register[".texture"L,JSetTexture]; J.Register[".color"L,JSetColor]; J.Register[".entercubic"L,JEnterCubic]; J.Register[".drawcubic"L,JDrawCubic]; J.Register[".beziertocubic"L,JBezierToCubic]; J.Register[".cubictobezier"L,JCubicToBezier]; 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[".drawchars"L,JDrawChars]; J.Register[".erasechar"L,JEraseChar]; J.Register[".drawstring"L,JDrawString]; J.Register[".getcharbox"L,JGetCharBox]; J.Register[".getstringbox"L,JGetStringBox]; J.Register[".getfontbox"L,JGetFontBox]; 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[".setclip"L,JSetClip]; J.Register[".cliparea"L,JClipArea]; J.Register[".clippedcliparea"L,JClippedClipArea]; J.Register[".startpath"L,JStartPath]; J.Register[".starteopath"L,JStartEOPath]; J.Register[".enterpoint"L,JEnterPoint]; J.Register[".newboundary"L,JNewBoundary]; J.Register[".enterrect"L,JEnterRect]; J.Register[".drawarea"L,JDrawArea]; J.Register[".openpress",JOpenPress]; J.Register[".closepress",JClosePress]; }.(670)