-- File CIFUtilities.Mesa -- August 1980 by MN -- Last changed: June 10, 1981 11:26 PM DIRECTORY AltoDevice: FROM "AltoDevice" USING [Bitmap, ScreenBitmap, NewAltoDevice, ScreenOrigin], BitBltDefs: FROM "BitBltDefs" USING [BBTable, BITBLT], CIFUtilitiesDefs: FROM "CIFUtilitiesDefs" USING [Rectangle], Graphics: FROM "Graphics" USING [DisplayContext, BoundingBox, StartAreaPath, EnterPoint, DestroyPath, SetClipArea, NewContext, Translate, Scale, Map, MoveTo, DrawTo, PushClipBox, PopClipBox, ScreenToUser, UserToScreen, CopyContext, PushContext, PopContext, SetPaint, SetTexture, black, DrawScreenArea, SetFont, MakeFont], InlineDefs: FROM "InlineDefs" USING [HighHalf, LowHalf], IODefs: FROM "IODefs" USING [WriteLine], JaMFnsDefs: FROM "JaMFnsDefs" USING [SetMouseProc, JaMStream, PushReal], KeyDefs: FROM "KeyDefs" USING [MouseButton, Mouse], Memory: FROM "Memory" USING [long], Real: FROM "Real" USING [FixI], Vector: FROM "Vector" USING [Vec]; CIFUtilities: PROGRAM IMPORTS AltoDevice, BitBltDefs, Graphics, InlineDefs, IODefs, JaMFnsDefs, Memory, Real EXPORTS CIFUtilitiesDefs = BEGIN OPEN AltoDevice, BitBltDefs, CIFUtilitiesDefs, Graphics, InlineDefs, IODefs, JaMFnsDefs, KeyDefs, Real, Vector; InitCedarGraphics: PUBLIC PROCEDURE = BEGIN screenbitmap _ ScreenBitmap[]; ScreenBaseContext _ NewContext[AltoDevice.NewAltoDevice[screenbitmap]]; ScreenBaseClipRectangle _ [llx:1, lly:1, urx:screenbitmap.raster*16-1, ury:screenbitmap.height-1]; SetFont[ScreenBaseContext, MakeFont["Helvetica"], 10]; ScreenContext _ CurrentDisplayContext _ CopyContext[ScreenBaseContext]; CurrentClipRectangle _ ScreenBaseClipRectangle; --This is always held in Base Coordinates ClippingOn _ TRUE; SetClipRect[ScreenBaseContext, ScreenBaseClipRectangle]; SetMouseProc[JaMStream[], MouseToUser]; END; SetDisplayContext: PUBLIC PROCEDURE[dc: DisplayContext] = BEGIN IF ~ClippingOn THEN EnableClipping[]; CurrentDisplayContext _ dc; END; GetDisplayContext: PUBLIC PROCEDURE RETURNS[dc: DisplayContext] = BEGIN RETURN[CurrentDisplayContext]; END; GetBaseContext: PUBLIC PROCEDURE RETURNS[dc: DisplayContext] = BEGIN RETURN[ScreenBaseContext]; END; SetClipRectangle: PUBLIC PROCEDURE[cr: Rectangle] = --set clip rectangle in current context BEGIN SetClipRect[CurrentDisplayContext, cr]; CurrentClipRectangle _ MapRectangle[cr, CurrentDisplayContext,ScreenBaseContext]; END; SetClipRect: PROCEDURE[dc: DisplayContext, cr: Rectangle] = --set clip rectangle in dc context BEGIN StartAreaPath[dc,FALSE]; EnterPoint[dc,[cr.llx,cr.lly]]; EnterPoint[dc,[cr.urx,cr.lly]]; EnterPoint[dc,[cr.urx,cr.ury]]; EnterPoint[dc,[cr.llx,cr.ury]]; SetClipArea[dc]; DestroyPath[dc]; END; GetClipRectangle: PUBLIC PROCEDURE RETURNS[cr: Rectangle] = BEGIN RETURN[MapRectangle[CurrentClipRectangle, ScreenBaseContext,CurrentDisplayContext]]; END; GetBaseClipRectangle: PUBLIC PROCEDURE RETURNS[cr: Rectangle] = BEGIN RETURN[MapRectangle[ScreenBaseClipRectangle, ScreenBaseContext,CurrentDisplayContext]]; END; DrawClipRectangle: PUBLIC PROCEDURE = BEGIN DrawRectOutline[ScreenBaseContext, CurrentClipRectangle]; END; ClearClipRectangle: PUBLIC PROCEDURE = BEGIN PushContext[CurrentDisplayContext]; SetPaint[CurrentDisplayContext, erase]; SetTexture[CurrentDisplayContext, black]; DrawScreenArea[CurrentDisplayContext]; PopContext[CurrentDisplayContext]; END; DrawRectangleOutline: PUBLIC PROCEDURE[cr: Rectangle] = BEGIN --draw it in BaseContext to get uniform thin lines SetClipRect[ScreenBaseContext, CurrentClipRectangle]; DrawRectOutline[ScreenBaseContext, MapRectangle[cr, CurrentDisplayContext,ScreenBaseContext]]; SetClipRect[ScreenBaseContext, ScreenBaseClipRectangle]; END; DrawRectOutline: PROCEDURE[dc: DisplayContext, cr: Rectangle] = BEGIN --draw cr in dc Graphics.MoveTo[dc, [cr.llx,cr.lly]]; Graphics.DrawTo[dc, [cr.urx,cr.lly]]; Graphics.DrawTo[dc, [cr.urx,cr.ury]]; Graphics.DrawTo[dc, [cr.llx,cr.ury]]; Graphics.DrawTo[dc, [cr.llx,cr.lly]]; END; MoveTo: PUBLIC PROCEDURE[x,y: REAL] = BEGIN SetClipRect[ScreenBaseContext, CurrentClipRectangle]; Graphics.MoveTo[ScreenBaseContext, Map[CurrentDisplayContext, ScreenBaseContext, [x,y]]]; SetClipRect[ScreenBaseContext, ScreenBaseClipRectangle]; -- Graphics.MoveTo[CurrentDisplayContext, [x,y]]; END; DrawTo: PUBLIC PROCEDURE[x,y: REAL] = BEGIN --draw it in BaseContext to get uniform thin lines SetClipRect[ScreenBaseContext, CurrentClipRectangle]; Graphics.DrawTo[ScreenBaseContext, Map[CurrentDisplayContext, ScreenBaseContext, [x,y]]]; SetClipRect[ScreenBaseContext, ScreenBaseClipRectangle]; END; Debugging: BOOLEAN _ TRUE; EnableClipping: PUBLIC PROCEDURE = BEGIN IF Debugging THEN RETURN; --***Temporary IF ClippingOn THEN RETURN ELSE { PopClipBox[CurrentDisplayContext]; ClippingOn _ TRUE; }; END; DisableClipping: PUBLIC PROCEDURE = --big kludge to turn off clipping - -- PushClipBox with zero size box at center of clipping region BEGIN IF Debugging THEN RETURN; --***Temporary IF ~ClippingOn THEN RETURN ELSE { cr: Rectangle _ GetClipRectangle[]; c: Vec _ [(cr.llx + cr.urx)/2, (cr.lly + cr.ury)/2]; box: BoundingBox _ [c,c,c,c]; PushClipBox[CurrentDisplayContext, @box]; ClippingOn _ FALSE; }; END; MapRectangle: PUBLIC PROCEDURE[rect1: Rectangle, cntxt1,cntxt2: DisplayContext] RETURNS[rect2: Rectangle] = BEGIN --return rectangle which in cntxt2 generates same as rect1 does in cntxt1 v0,v1: Vec; v0 _ Map[cntxt1,cntxt2, [rect1.llx,rect1.lly]]; v1 _ Map[cntxt1,cntxt2, [rect1.urx,rect1.ury]]; RETURN[[llx:MIN[v0.x,v1.x],lly:MIN[v0.y,v1.y], urx:MAX[v0.x,v1.x],ury:MAX[v0.y,v1.y]]]; END; --GetBaseContextRecord: PUBLIC PROCEDURE RETURNS[baseContext: DisplayContext] = -- BEGIN --get the base context RECORD -- PushBaseContext[]; -- baseContext _ GetDisplayContext[]^; -- PopDisplayContext[]; -- END; SetUniformView: PUBLIC PROCEDURE[rfrom, rto: Rectangle] = --Set up transform to map rectangles, but without introducing differential scaling --Minimum scale factor is used, and centers will correspond BEGIN sx,sy,scale: REAL; dxfrom: REAL _ rfrom.urx-rfrom.llx; dyfrom: REAL _ rfrom.ury-rfrom.lly; dxto: REAL _ rto.urx-rto.llx; dyto: REAL _ rto.ury-rto.lly; IF dxfrom=0 OR dyfrom=0 OR dxto=0 OR dyto=0 THEN BEGIN WriteLine["Invalid scale factor"]; RETURN; END; sx _ dxto/dxfrom; sy _ dyto/dyfrom; scale _ IF ABS[sx]