-- CIFOutDeviceImpl.mesa
-- Define CedarGraphics device for non-screen objects
-- There will be only one instance of this device ever.
-- Its only function is to direct CedarGraphics output (polygons) to
-- the relevant CIF device
-- Written by Martin Newell, October 1980
-- Last changed: November 13, 1980 2:56 PM

DIRECTORY
Area USING [Rec, Handle, Rectangular, Rectangle, Free, Vertices],
CIFDevicesDefs USING [DeviceDescriptor],
CIFOutDevice,
Device USING [Handle, Procs, Object],
Font USING [Id],
Mapper USING [Handle],
OpaqueDevice USING [TextHandle, DeviceContext],
Pipe USING [Handle, Object, Procs],
Poly USING [NewRec],
Style USING [Data],
Vector USING [Vec, Matrix];

CIFOutDeviceImpl: PROGRAM
IMPORTS Area,Poly
EXPORTS CIFOutDevice SHARES Device,Pipe = {
OPEN Device;

CurrentDevice: CIFDevicesDefs.DeviceDescriptor;


DeviceProcsRecord: Device.Procs ← [
NewPipe: NewPipe,
NewText: NewText,
ApplyBaseTransform: ApplyBaseTransform,
Boundary: Boundary,
Free: DFree];

TheCIFOutDevice: Device.Object ← [
procs: @DeviceProcsRecord,
data: NIL,
refs: 1];

PipeProcsRecord: Pipe.Procs ← [
Put: PPut,
Free: PFree];

TheCIFOutPipe: Pipe.Object ← [
procs: @PipeProcsRecord,
data: NIL];

MakeCIFOutDevice: PUBLIC PROCEDURE RETURNS[OpaqueDevice.DeviceContext] =
{ RETURN[LOOPHOLE[LONG[@TheCIFOutDevice]]]; };

NewPipe: PROCEDURE[self: Handle, style: POINTER TO Style.Data] RETURNS[Pipe.Handle] =
{ RETURN[@TheCIFOutPipe]; };

PPut: PROCEDURE[self: Pipe.Handle, area: Area.Handle] = {
IF Area.Rectangular[area] THEN {
r: Area.Rec=Area.Rectangle[area];
CurrentDevice.deviceRectangle[[r.ll.x,r.ll.y, r.ur.x,r.ur.y]];
}
ELSE {
first: BOOLEAN←TRUE;
Put: PROC[v: Vector.Vec] =
{IF first THEN { CurrentDevice.deviceStartPoly[v.x,v.y]; first←FALSE }
ELSE CurrentDevice.devicePolyVertex[v.x,v.y];
};
Area.Vertices[area,Put];
CurrentDevice.deviceEndPoly[];
};
Area.Free[@area];
};

PFree: PROCEDURE[self: Pipe.Handle] = {};

NewText: 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]; };

ApplyBaseTransform: PROCEDURE[self: Handle, mapper: Mapper.Handle] = {};

Boundary: PROCEDURE[self: Handle] RETURNS[Area.Handle] =
{ RETURN[Poly.NewRec[[[-1.0e30,-1.0e30],[1.0e30,1.0e30]]]]; };

DFree: PROCEDURE[self: Handle] = {};

SetCurrentDevice: PUBLIC PROCEDURE[device: CIFDevicesDefs.DeviceDescriptor] =
{ CurrentDevice ← device; };

}.