--File: IntTransDefs.mesa
--Written by Martin Newell, July 1979
--Last edited June 10, 1981 11:12 AM
IntTransDefs: DEFINITIONS =

--*************************************************************************************

--This package of transformation procedures is designed to support the processing of
-- CalTech Intermediate Form files on an Alto computer. The impact of these requirements
-- are threefold: 1) nesting of transformations involves post-multiplication of the
-- incremental transformation and premultiplication of the current transformation;
-- 2) input parameters specified in (long) integers (no reals); and 3) slow floating point
-- support.

--The package supports the tree structure of transformations found in nested calls to CIF
-- symbols by implementing a stack of transformations. In addition to the stack there is
-- a "Current Transformation" and a "Local Transformation". The Current transformation
-- represents the accumulated effect of all the transformations invoked. The Local
-- transformation describes the relationship of the current transformation, or coordinate
-- system, to the previous one.

--A new coordinate system is started by calling Push. This pushes the Current
-- transformation onto the stack, and sets the Local transformation to the identity; the
-- Current transformation is not changed yet. Subsequent calls to transformation
-- procedures such as Rotate, Translate, etc. cause the Local transformation to be
-- post-multiplied by appropriate matrices. As soon as a call is made to a procedure
-- that needs to use the Current transformation (e.g. TransformPoint) the Current
-- transformation is pre-multiplied by the Local transformation to yield a new Current
-- transformation describing the current coordinate system. The current coordinate system
-- is terminated by a call to Pop which simply pops the top of the stack into the Current
-- transformation.

--Calls to procedures in the package must be arranged (sequentially) into nested "Blocks",
-- where a Block has the form:

--
Push;
--
<Calls that affect the local transformation(e.g. Rotate, Translate...)>;
--
<Calls that use the current transformation(e.g. TransformPoint, ... other Blocks)>;
--
Pop;

--Failure to conform to this sequence will result in the ERROR TransformationBadContext,
-- e.g. by calling Rotate after TransformPoint without an intervening Push.

--The only other ERROR generated by the package is TransformationStackUnderflow.

--For use with CIF it is expected that direct execution of a call to a CIF symbol would
-- result in a Push, calls to the relevant transformations in the same order as they are
-- given in the CIF line, invocation of the CIF symbol, Pop. e.g. the CIF statement:

--
CS100 MX R-1,1 T10,20

--would be executed by:

--
Push; Mirror[x]; Rotate[-1,1]; Translate[10,20]; "InvokeSymbol[100]"; Pop;


--For generating the compiled form of a symbol, the above statement would generate:

--
Push; Mirror[x]; Rotate[-1,1]; Translate[10,20]; T←GetLocal[];
--
"SaveCompiledFormOfInvokeSymbol[100]WithTransformation[T]";
--
Pop;

--The compiled form would then be executed by the sequence:

--
Push; ApplyLocal[@T]; "InvokeSymbol[100]"; Pop;

--New addition - March 1980 - Contexts
--The package supports multiple transformation contexts, for use in processing CIF
-- files in an order different from a walk of the symbol structure. This is for use
-- with an Interpreter that does sorting based on geametry. The current
-- transformation can be "frozen" to produce a new context, on which the usual Push,
-- Pop, Rotate etc. operations can be performed. See FreezeContext, IncrementRefCount,
-- DecrementRefCount and SwapContext.

--*************************************************************************************

BEGIN

Transform: TYPE = LONG POINTER TO TransformRecord;
TransformRecord: TYPE = RECORD[
type: [ident..translate+rotscale],
a11,a21,a31,a12,a22,a32,a33: REAL,
prev: Transform];
ident: INTEGER = 0;
translate: INTEGER = 1;
rotscale: INTEGER = 2;
CoordName: TYPE = {x,y};

InitTransformation: PUBLIC PROCEDURE RETURNS [BOOLEAN];
-- Initialize (or re-initialize) Transformations package

FinishTransformation: PUBLIC PROCEDURE RETURNS [BOOLEAN];

FreezeContext: PUBLIC PROCEDURE RETURNS[id: CARDINAL];
-- Create new context based on existing context state

IncrementRefCount: PUBLIC PROCEDURE[id: CARDINAL];
-- Increment reference count of context id

DecrementRefCount: PUBLIC PROCEDURE[id: CARDINAL];
-- Decrement reference count of context id

SwapContext: PUBLIC PROCEDURE[id: CARDINAL];
-- Change context to id

Push: PUBLIC PROCEDURE;
-- Push current transformation - start a new relative coordinate system

Pop: PUBLIC PROCEDURE;
-- Pop current transformation - return to previous coordinate system

Rotate: PUBLIC PROCEDURE[xRot,yRot: LONG INTEGER];
-- Rotate x axis to direction of (xRot,yRot)

Translate
: PUBLIC PROCEDURE[xTrans,yTrans: LONG INTEGER];
-- Translate by (xTrans,yTrans)

Mirror
: PUBLIC PROCEDURE[coord: CoordName];
-- Mirror the indicated coordinates

Scale
: PUBLIC PROCEDURE[numerator,denominator: LONG INTEGER];
-- Scale by numerator/denominator

GetLocal
: PUBLIC PROCEDURE RETURNS[localTransform: TransformRecord];
-- Return incremental transformation built since last Push

ApplyLocal
: PUBLIC PROCEDURE[transform: Transform];
-- Apply transformation to current local transformation

GetCurrent
: PUBLIC PROCEDURE RETURNS[currentTransform: TransformRecord];
-- Return current cummulative transformation

TransformPoint: PUBLIC PROCEDURE[x,y: LONG INTEGER] RETURNS[xT,yT: LONG INTEGER];
-- Transform the point (x,y) by current cumulative transformation

TransformVector
: PUBLIC PROCEDURE[x,y: LONG INTEGER] RETURNS[xT,yT: LONG INTEGER];
-- Transform the direction (x,y) by current cumulative transformation

RTransformPoint: PUBLIC PROCEDURE[x,y: REAL] RETURNS[xT,yT: REAL];
-- Transform the point (x,y) by current cumulative transformation - in REALs

RTransformVector
: PUBLIC PROCEDURE[x,y: REAL] RETURNS[xT,yT: REAL];
-- Transform the direction (x,y) by current cumulative transformation - in REALs

TransformationStackUnderflow: PUBLIC ERROR;
TransformationBadContext: PUBLIC ERROR;
TransformationInvalidContext: PUBLIC ERROR[id: CARDINAL];

END.