--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.