-- Graphics.mesa
-- Last changed by Doug Wyatt, September 25, 1980 11:03 PM

-- This is the lower-level interface to the Cedar Graphics package

DIRECTORY
Vector USING [Vec, Matrix],
Cubic USING [Coeffs],
Style USING [PaintingFunction, Texture, Color],
OpaqueDevice USING [DeviceContext];

Graphics: DEFINITIONS = {

DisplayContext: TYPE = LONG POINTER TO DisplayData;
DisplayData: PRIVATE TYPE;

DeviceContext: TYPE = OpaqueDevice.DeviceContext;

-- NewContext returns a display context for the given device.
-- The initial clipping boundary is the entire screen.
-- The initial transformation puts the origin in the lower left corner
-- and establishes a coordinate system measured in points.
-- If the DeviceContext is NIL, NewContext returns a DisplayContext
-- for the full Alto display.
NewContext: PROCEDURE[device: DeviceContext ← NIL] RETURNS[DisplayContext];

InitContext: PROCEDURE[dc: DisplayContext];

PushContext: PROCEDURE[dc: DisplayContext];
PopContext: PROCEDURE[dc: DisplayContext];

-- CopyContext copies the information in the given display context.
CopyContext: PROCEDURE[dc: DisplayContext] RETURNS[DisplayContext];

-- FreeContext frees the storage for a display context.
FreeContext: PROCEDURE[dcPtr: LONG POINTER TO DisplayContext];


-- Drawing Style routines

PaintingFunction: TYPE = Style.PaintingFunction;
-- {replace,paint,invert,erase};

Texture: TYPE = Style.Texture; -- for now, a 4x4 bit block
white: Texture=0;
black: Texture=177777B;
grey: Texture=122645B;

Color: TYPE = Style.Color;

-- SetPaint sets the painting function for area filling.
SetPaint: PROCEDURE[dc: DisplayContext, p: PaintingFunction ← paint];
-- GetPaint returns the current painting function.
GetPaint: PROCEDURE[dc: DisplayContext] RETURNS[PaintingFunction];

-- SetTexture sets the texture for area filling.
SetTexture: PROCEDURE[dc: DisplayContext, t: Texture ← black];
-- GetTexture returns the current texture.
GetTexture: PROCEDURE[dc: DisplayContext] RETURNS[Texture];

-- SetColor sets the color for area filling.
SetColor: PROCEDURE[dc: DisplayContext, c: Color ← [255,255,255]];
-- GetColor returns the current color.
GetColor: PROCEDURE[dc: DisplayContext] RETURNS[Color];

-- Display information

Vec: TYPE = Vector.Vec;

-- DisplaySize returns the size of a bounding rectangle for the display.
DisplaySize: PROCEDURE[dc: DisplayContext] RETURNS[Vec];

-- Transformation routines

-- Translate translates the context coordinate system by (v.x,v.y).
-- (x’ , y’) = (x - v.x , y - v.y)
Translate: PROCEDURE[dc: DisplayContext, v: Vec];

-- Scale scales the context coordinate system by (v.x,v.y).
-- (x’ , y’) = (x * v.x , y * v.y)
Scale: PROCEDURE[dc: DisplayContext, v: Vec];

-- Rotate rotates the display coordinate system counterclockwise.
-- The angle is measured in degrees.
-- (x’ , y’) = (y , -x) after a 90 degree rotation.
Rotate: PROCEDURE[dc: DisplayContext, angle: REAL];

-- Concatenate postmultiplies the current transformation by the given matrix.
Concatenate: PROCEDURE[dc: DisplayContext, m: Vector.Matrix];

-- Map maps a point from one context coordinate system to another.
-- The source point (sp) is interpreted in the source context (sdc).
-- The resulting point (dp) is the same point expressed in the
-- coordinate system of the destination context (ddc).
Map: PROCEDURE[sdc,ddc: DisplayContext, sp: Vec] RETURNS[dp: Vec];

-- These are temporary crocks for mapping between screen and user coordinates.
ScreenToUser: PROCEDURE[dc: DisplayContext, v: Vec] RETURNS[Vec];
UserToScreen: PROCEDURE[dc: DisplayContext, v: Vec] RETURNS[Vec];


-- Line and Area drawing routines

SetLineWidth: PROCEDURE[dc: DisplayContext, w: REAL];
GetLineWidth: PROCEDURE[dc: DisplayContext] RETURNS[REAL];

MoveTo,RelMoveTo: PROCEDURE[dc: DisplayContext, v: Vec];
DrawTo,RelDrawTo: PROCEDURE[dc: DisplayContext, v: Vec];

DrawCubic: PROCEDURE[dc: DisplayContext, c: POINTER TO Cubic.Coeffs];

-- GetPosition returns the current position in user coordinates.
GetPosition: PROCEDURE[dc: DisplayContext] RETURNS[Vec];

-- The following routines fill a specified area on the display, using the
-- current display context values for paint, texture, and color.

-- EnterPoint, EnterCubic, and NewBoundary are used to define a region
-- to be filled by DrawArea.
-- A path is a set of one or more polygonal boundaries.

-- StartLinePath initializes a path for a line of the given width.
StartLinePath: PROCEDURE[dc: DisplayContext, width: REAL];

-- StartSplinePath initializes a path for a spline curve.
StartSplinePath: PROCEDURE[dc: DisplayContext, width: REAL];

-- StartAreaPath initializes a path for a filled area.
StartAreaPath: PROCEDURE[dc: DisplayContext, oddeven: BOOLEAN←FALSE];

-- EnterPoint stores a point into the current boundary.
EnterPoint: PROCEDURE[dc: DisplayContext, v: Vec];

-- EnterCubic stores the given cubic section into the current boundary.
EnterCubic: PROCEDURE[dc: DisplayContext, c: POINTER TO Cubic.Coeffs];

-- NewBoundary ends the current boundary and starts a new one.
NewBoundary: PROCEDURE[dc: DisplayContext];

-- DestroyPath discards the current path, if any.
DestroyPath: PUBLIC PROCEDURE[dc: DisplayContext];

-- DrawArea fills the area defined by the current path, using the
-- current style parameters. It then discards the path.
DrawArea: PROCEDURE[dc: DisplayContext];

-- DrawRectangle fills a rectangle with the given corners,
-- using the current style parameters.
DrawRectangle: PROCEDURE[dc: DisplayContext, ll,ur: Vec];

-- DrawScreenArea draws an area covering the entire screen
DrawScreenArea: PROCEDURE[dc: DisplayContext];


-- Text display routines

-- The following procedures are used for the display of text. They use
-- and modify the display context position (set by MoveTo or RelMoveTo).

FontId: TYPE[1]; -- a short identifier for a font family and face

-- MakeFont and MakeTexFont returns a short unique identifier for the
-- given font family and face (e.g., Helvetica bold, CMR10)
MakeFont: PROCEDURE[family: STRING, bold,italic: BOOLEAN ← FALSE]
RETURNS[FontId];
MakeTexFont: PROCEDURE[family: STRING, logicalSize: REAL]
RETURNS[FontId];

-- SetFont sets the font to be used for text display. The size parameter
-- gives the font’s "point size" in user coordinates. Coordinates in
-- a newly-created display context are measured in points, so
--
helvB←MakeFont["Helvetica", bold: TRUE];
--
SetFont[dc,helvB,10]; DisplayString["Hello"];
-- will display "Hello" in 10-point Helvetica bold.
SetFont: PROCEDURE[dc: DisplayContext, font: FontId, size: REAL];

-- DisplayChar displays a character in the current font. The character’s
-- origin is placed at the current position, and the position is updated
-- by the character’s width.
DisplayChar: PROCEDURE[dc: DisplayContext, c: CHARACTER];

-- DisplayString displays a string in the current font. It has the same
-- effect as calling DisplayChar for each character, but is more efficient.
DisplayString: PROCEDURE[dc: DisplayContext, s: LONG STRING];

-- The routines in the following group all return dimensions in the
-- current coordinate system.

CharData: TYPE = RECORD[size,origin,width: Vec];

-- For some cd: CharData,
-- cd.size gives the width and height of the box
-- dx=cd.size.x, dy=cd.size.y
-- cd.offset is a vector from the character origin to the box origin
-- ox=cd.offset.x, oy=cd.offset.y.
-- cd.width is a vector from the character origin to the origin
-- of the following character

-- GetCharBox obtains the bounding box and width vector for a character
-- in the current font.
GetCharBox: PROCEDURE[dc: DisplayContext, c: CHARACTER,
data: POINTER TO CharData];

-- GetStringBox obtains the bounding box and width vector for a string
-- in the current font.
GetStringBox: PROCEDURE[dc: DisplayContext, s: LONG STRING,
data: POINTER TO CharData];

-- GetFontBox obtains the font bounding box and maximum width
-- for the current font.
GetFontBox: PROCEDURE[dc: DisplayContext,
data: POINTER TO CharData];


-- Boxing and clipping

BoundingBox: TYPE = ARRAY [0..4) OF Vec;

-- InitBoxer initializes the display context variables that determine the
-- boxing parameters of a display object. The boxer will maintain a bounding
-- box for all subsequent displayed objects.
InitBoxer: PROCEDURE[dc: DisplayContext];

-- StopBoxer stops the boxing process.
-- It returns the bounding box in the user coordinate system.
StopBoxer: PROCEDURE[dc: DisplayContext, bbox: POINTER TO BoundingBox];

-- PushClipBox sets the bounding box for an object about to be displayed.
-- Subsequently displayed objects must fall within the given box until
-- PopClipBox is called. Use this with caution!
PushClipBox: PROCEDURE[dc: DisplayContext, bbox: POINTER TO BoundingBox];

-- PopClipBox ends the scope of the previously given bounding box.
PopClipBox: PROCEDURE[dc: DisplayContext];

-- Visible returns TRUE if any portion of the clipping area
-- (within the current bounding box, if any) is visible.
Visible: PROCEDURE[dc: DisplayContext] RETURNS[BOOLEAN];

-- SetClipArea sets the clipping area to that defined by the current path.
SetClipArea: PROCEDURE[dc: DisplayContext];

-- IntersectClipArea sets the clipping area to the intersection of the
-- current clipping area and the area defined by the current path.
IntersectClipArea: PROCEDURE[dc: DisplayContext];

GraphicsImpl: PRIVATE PROGRAM;
GraphicsControl: PROGRAM;

}.