-- PressDeviceImpl.mesa -- Last changed by Doug Wyatt, September 22, 1980 5:36 PM DIRECTORY Device, PressDevice, OpaqueDevice USING [TextHandle], Vector USING [Vec, Matrix], Area USING [Rec, Handle, Vertices, Rectangular, Rectangle, Free], Poly USING [NewRec], Pipe USING [Handle, Object, Procs], Font USING [Id], Mapper USING [Handle, Concat], Style USING [Data, PaintingFunction, Texture, Color], Memory USING [NewZone, mds], PressDefs USING [PressFileDescriptor, InitPressFileDescriptor, StartOutline, PutDrawTo, EndOutline, SetColor, PutRectangle, ClosePressFile], Real USING [FixC]; PressDeviceImpl: PROGRAM IMPORTS Memory,Mapper,Area,Poly,Real,PressDefs EXPORTS OpaqueDevice,PressDevice SHARES Device,Pipe = { OPEN Device; zone: UNCOUNTED ZONE = Memory.NewZone["PressDeviceImpl"]; mds: MDSZone = Memory.mds; PaintFunction: TYPE = Style.PaintingFunction; Texture: TYPE = Style.Texture; Color: TYPE = Style.Color; DeviceObject: PUBLIC TYPE = Device.Object; PressHandle: TYPE = POINTER TO PressDefs.PressFileDescriptor; -- Concrete form of the data Data: TYPE = RECORD [ pressHandle: PressHandle, fileName: STRING, width,height: CARDINAL -- width and height in micas ]; DataRef: TYPE = LONG POINTER TO Data; procs: LONG POINTER TO READONLY Procs = zone.NEW[Procs = [ NewPipe: CNewPipe, NewText: CNewText, ApplyBaseTransform: CApplyBaseTransform, Boundary: CBoundary, Free: CFree ]]; -- Procedures for creating a Device object NewPressDevice: PUBLIC PROCEDURE[filename: STRING] RETURNS[Handle] = { pd: PressHandle = mds.NEW[PressDefs.PressFileDescriptor]; name: STRING = CopyString[filename]; d: DataRef = zone.NEW[Data _ [ pressHandle: pd, fileName: name, width: (2540/2)*17, height: 2540*11 ]]; PressDefs.InitPressFileDescriptor[pd,name]; RETURN[zone.NEW[Object _ [procs: procs, data: LOOPHOLE[d]]]]; }; CopyString: PROCEDURE[s: STRING] RETURNS[STRING] = { n: CARDINAL=s.length; t: STRING=mds.NEW[StringBody[n]]; FOR i: CARDINAL IN[0..n) DO t[i]_s[i] ENDLOOP; t.length_n; RETURN[t]; }; PData: TYPE = RECORD [ pressHandle: PressHandle, color: Color ]; PDataRef: TYPE = LONG POINTER TO PData; pProcs: LONG POINTER TO READONLY Pipe.Procs = zone.NEW[Pipe.Procs = [ Put: PPut, Free: PFree]]; CNewPipe: PROCEDURE[self: Handle, style: POINTER TO Style.Data] RETURNS[Pipe.Handle] = { d: DataRef=LOOPHOLE[self.data]; pd: PressHandle=d.pressHandle; p: PDataRef=zone.NEW[PData _ [ pressHandle: pd, color: style.color ]]; PressDefs.SetColor[pd,p.color.r,p.color.g,p.color.b]; RETURN[zone.NEW[Pipe.Object _ [procs: pProcs, data: LOOPHOLE[p]]]]; }; RoundC: PROC[r: REAL] RETURNS[CARDINAL] = INLINE { RETURN[Real.FixC[r+.5]] }; PPut: PROCEDURE[self: Pipe.Handle, area: Area.Handle] = { p: PDataRef=LOOPHOLE[self.data]; pd: PressHandle=p.pressHandle; IF Area.Rectangular[area] THEN { r: Area.Rec=Area.Rectangle[area]; llx: CARDINAL=RoundC[r.ll.x]; lly: CARDINAL=RoundC[r.ll.y]; urx: CARDINAL=RoundC[r.ur.x]; ury: CARDINAL=RoundC[r.ur.y]; PressDefs.PutRectangle[pd,llx,lly,urx-llx,ury-lly]; } ELSE { first: BOOLEAN_TRUE; Put: PROC[v: Vector.Vec] = { mx: CARDINAL=RoundC[v.x]; -- rounded to micas my: CARDINAL=RoundC[v.y]; -- rounded to micas IF first THEN { PressDefs.StartOutline[pd,mx,my]; first_FALSE } ELSE PressDefs.PutDrawTo[pd,mx,my]; }; Area.Vertices[area,Put]; PressDefs.EndOutline[pd]; }; Area.Free[@area]; }; PFree: PROCEDURE[self: Pipe.Handle] = { p: PDataRef_LOOPHOLE[self.data]; zone.FREE[@p]; zone.FREE[@self]; }; CNewText: PROCEDURE[self: Handle, id: Font.Id, size: REAL, pm: POINTER TO READONLY Vector.Matrix, style: POINTER TO READONLY Style.Data] RETURNS[OpaqueDevice.TextHandle] = { RETURN[NIL]; }; CApplyBaseTransform: PROCEDURE[self: Handle, mapper: Mapper.Handle] = { s: REAL=2540.0/72.0; Mapper.Concat[mapper,[s,0,0,s]]; }; CBoundary: PROCEDURE[self: Handle] RETURNS[Area.Handle] = { d: DataRef=LOOPHOLE[self.data]; r: Area.Rec=[[0,0],[d.width,d.height]]; RETURN[Poly.NewRec[r]]; }; CFree: PROCEDURE[self: Handle] = { d: DataRef_LOOPHOLE[self.data]; pd: PressHandle_d.pressHandle; name: STRING_d.fileName; PressDefs.ClosePressFile[pd]; mds.FREE[@pd]; mds.FREE[@name]; zone.FREE[@d]; zone.FREE[@self]; }; }.(670)