CDBasicsInline.mesa (part of ChipNDale)
Copyright © 1983, 1984, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, May 3, 1983 4:26 pm
Last edited by: Christian Jacobi, October 14, 1986 4:21:24 pm PDT
DIRECTORY
CD USING [Number, Instance, Orientation, Position, Rect, Transformation],
Imager USING [Transformation],
ImagerTransformation USING [Create];
CDBasicsInline: CEDAR DEFINITIONS
IMPORTS ImagerTransformation =
BEGIN
This interface is private to ChipNDale implementors in the sense that
Its basic functionality is also exported elsewhere
It may be changed outside the ChipNDale release cycle, according to the need of getting CDRectsImpl, CDCellsImpl and CDVDraw as fast as possible.
Number: TYPE = CD.Number;
Orientation: TYPE = CD.Orientation;
Position: TYPE = CD.Position;
Rect: TYPE = CD.Rect;
Transformation: TYPE = CD.Transformation;
composeTable: READONLY ARRAY CD.Orientation OF ARRAY CD.Orientation OF CD.Orientation;
inverseTable: READONLY ARRAY CD.Orientation OF CD.Orientation;
MapPoint: PROC [pointInCell: CD.Position, cellInWorld: CD.Transformation] RETURNS [pointInWorld: CD.Position←TRASH] = INLINE {
SELECT cellInWorld.orient FROM
original =>
RETURN[CD.Position[
x: cellInWorld.off.x+pointInCell.x,
y: cellInWorld.off.y+pointInCell.y]];
mirrorX =>
RETURN[CD.Position[
x: cellInWorld.off.x-pointInCell.x,
y: cellInWorld.off.y+pointInCell.y]];
rotate90 =>
RETURN[CD.Position[
x: cellInWorld.off.x-pointInCell.y,
y: cellInWorld.off.y+pointInCell.x]];
rotate90X =>
RETURN[CD.Position[
x: cellInWorld.off.x+pointInCell.y,
y: cellInWorld.off.y+pointInCell.x]];
rotate180 =>
RETURN[CD.Position[
x: cellInWorld.off.x-pointInCell.x,
y: cellInWorld.off.y-pointInCell.y]];
rotate180X =>
RETURN[CD.Position[
x: cellInWorld.off.x+pointInCell.x,
y: cellInWorld.off.y-pointInCell.y]];
rotate270 =>
RETURN[CD.Position[
x: cellInWorld.off.x+pointInCell.y,
y: cellInWorld.off.y-pointInCell.x]];
rotate270X =>
RETURN[CD.Position[
x: cellInWorld.off.x-pointInCell.y,
y: cellInWorld.off.y-pointInCell.x]];
ENDCASE;
};
MapRect: PUBLIC PROC [itemInCell: CD.Rect, cellInWorld: CD.Transformation] RETURNS [itemInWorld: CD.Rect←TRASH] = INLINE {
SELECT cellInWorld.orient FROM
original =>
RETURN[CD.Rect[
x1: cellInWorld.off.x+itemInCell.x1,
x2: cellInWorld.off.x+itemInCell.x2,
y1: cellInWorld.off.y+itemInCell.y1,
y2: cellInWorld.off.y+itemInCell.y2
]];
mirrorX =>
RETURN[CD.Rect[
x1: cellInWorld.off.x-itemInCell.x2,
x2: cellInWorld.off.x-itemInCell.x1,
y1: cellInWorld.off.y+itemInCell.y1,
y2: cellInWorld.off.y+itemInCell.y2
]];
rotate90 => {
RETURN[CD.Rect[
x1: cellInWorld.off.x-itemInCell.y2,
y1: cellInWorld.off.y+itemInCell.x1,
x2: cellInWorld.off.x-itemInCell.y1,
y2: cellInWorld.off.y+itemInCell.x2]];
};
rotate90X => {
RETURN[CD.Rect[
x1: cellInWorld.off.x+itemInCell.y1,
y1: cellInWorld.off.y+itemInCell.x1,
x2: cellInWorld.off.x+itemInCell.y2,
y2: cellInWorld.off.y+itemInCell.x2]];
};
rotate180 => {
RETURN[CD.Rect[
x1: cellInWorld.off.x-itemInCell.x2,
y1: cellInWorld.off.y-itemInCell.y2,
x2: cellInWorld.off.x-itemInCell.x1,
y2: cellInWorld.off.y-itemInCell.y1]];
};
rotate180X => {
RETURN[CD.Rect[
x1: cellInWorld.off.x+itemInCell.x1,
y1: cellInWorld.off.y-itemInCell.y2,
x2: cellInWorld.off.x+itemInCell.x2,
y2: cellInWorld.off.y-itemInCell.y1]];
};
rotate270 => {
RETURN[CD.Rect[
x1: cellInWorld.off.x+itemInCell.y1,
y1: cellInWorld.off.y-itemInCell.x2,
x2: cellInWorld.off.x+itemInCell.y2,
y2: cellInWorld.off.y-itemInCell.x1]];
};
rotate270X => {
RETURN[CD.Rect[
x1: cellInWorld.off.x-itemInCell.y2,
y1: cellInWorld.off.y-itemInCell.x2,
x2: cellInWorld.off.x-itemInCell.y1,
y2: cellInWorld.off.y-itemInCell.x1]];
};
ENDCASE;
};
OrientedRect: PUBLIC PROC [itemInCell: CD.Rect, cellInWorld: CD.Orientation] RETURNS [itemInWorld: CD.Rect←TRASH] = INLINE {
RETURN[
SELECT cellInWorld FROM
original => itemInCell,
mirrorX => [-itemInCell.x2, +itemInCell.y1, -itemInCell.x1, +itemInCell.y2],
rotate90 => [-itemInCell.y2, +itemInCell.x1, -itemInCell.y1, +itemInCell.x2],
rotate90X => [+itemInCell.y1, +itemInCell.x1, +itemInCell.y2, +itemInCell.x2],
rotate180 => [-itemInCell.x2, -itemInCell.y2, -itemInCell.x1, -itemInCell.y1],
rotate180X => [+itemInCell.x1, -itemInCell.y2, +itemInCell.x2, -itemInCell.y1],
rotate270 => [+itemInCell.y1, -itemInCell.x2, +itemInCell.y2, -itemInCell.x1],
rotate270X => [-itemInCell.y2, -itemInCell.x2, -itemInCell.y1, -itemInCell.x1],
ENDCASE => ERROR
]
};
ComposeTransform: PROC [itemInCell, cellInWorld: CD.Transformation] RETURNS [itemInWorld: CD.Transformation←TRASH] = INLINE {
itemInWorld.off ← MapPoint[itemInCell.off, cellInWorld];
itemInWorld.orient ← composeTable[itemInCell.orient][cellInWorld.orient];
};
DeMapRect: PUBLIC PROC [itemInWorld: CD.Rect, cellInWorld: CD.Transformation] RETURNS [itemInCell: CD.Rect] = INLINE {
itemInCell ← OrientedRect[
[
x1: itemInWorld.x1-cellInWorld.off.x,
y1: itemInWorld.y1-cellInWorld.off.y,
x2: itemInWorld.x2-cellInWorld.off.x,
y2: itemInWorld.y2-cellInWorld.off.y
],
inverseTable[cellInWorld.orient]
];
};
ImagerTransform: PROC [trans: CD.Transformation] RETURNS [Imager.Transformation] = INLINE {
RETURN [SELECT trans.orient FROM
original => ImagerTransformation.Create[1, 0, trans.off.x, 0, 1, trans.off.y],
mirrorX => ImagerTransformation.Create[-1, 0, trans.off.x, 0, 1, trans.off.y],
rotate90 => ImagerTransformation.Create[0, -1, trans.off.x, 1, 0, trans.off.y],
rotate90X => ImagerTransformation.Create[0, 1, trans.off.x, 1, 0, trans.off.y],
rotate180 => ImagerTransformation.Create[-1, 0, trans.off.x, 0, -1, trans.off.y],
rotate180X => ImagerTransformation.Create[1, 0, trans.off.x, 0, -1, trans.off.y],
rotate270 => ImagerTransformation.Create[0, 1, trans.off.x, -1, 0, trans.off.y],
rotate270X => ImagerTransformation.Create[0, -1, trans.off.x, -1, 0, trans.off.y],
ENDCASE => ERROR
];
};
IntersectRI: PROC[r: CD.Rect, inst: CD.Instance] RETURNS [BOOL] = TRUSTED INLINE {
--returns rect intersects or touches inst
SELECT inst.trans.orient FROM
original =>
RETURN [
r.x2 >= inst.trans.off.x+inst.ob.bbox.x1 AND
r.x1 <= inst.trans.off.x+inst.ob.bbox.x2 AND
r.y2 >= inst.trans.off.y+inst.ob.bbox.y1 AND
r.y1 <= inst.trans.off.y+inst.ob.bbox.y2
];
mirrorX =>
RETURN [
r.x2 >= inst.trans.off.x-inst.ob.bbox.x2 AND
r.x1 <= inst.trans.off.x-inst.ob.bbox.x1 AND
r.y2 >= inst.trans.off.y+inst.ob.bbox.y1 AND
r.y1 <= inst.trans.off.y+inst.ob.bbox.y2
];
rotate90 =>
RETURN [
r.x2 >= inst.trans.off.x-inst.ob.bbox.y2 AND
r.y2 >= inst.trans.off.y+inst.ob.bbox.x1 AND
r.x1 <= inst.trans.off.x-inst.ob.bbox.y1 AND
r.y1 <= inst.trans.off.y+inst.ob.bbox.x2
];
rotate90X =>
RETURN [
r.x2 >= inst.trans.off.x+inst.ob.bbox.y1 AND
r.y2 >= inst.trans.off.y+inst.ob.bbox.x1 AND
r.x1 <= inst.trans.off.x+inst.ob.bbox.y2 AND
r.y1 <= inst.trans.off.y+inst.ob.bbox.x2
];
rotate180 =>
RETURN [
r.x2 >= inst.trans.off.x-inst.ob.bbox.x2 AND
r.y2 >= inst.trans.off.y-inst.ob.bbox.y2 AND
r.x1 <= inst.trans.off.x-inst.ob.bbox.x1 AND
r.y1 <= inst.trans.off.y-inst.ob.bbox.y1
];
rotate180X =>
RETURN [
r.x2 >= inst.trans.off.x+inst.ob.bbox.x1 AND
r.y2 >= inst.trans.off.y-inst.ob.bbox.y2 AND
r.x1 <= inst.trans.off.x+inst.ob.bbox.x2 AND
r.y1 <= inst.trans.off.y-inst.ob.bbox.y1
];
rotate270 =>
RETURN [
r.x2 >= inst.trans.off.x+inst.ob.bbox.y1 AND
r.y2 >= inst.trans.off.y-inst.ob.bbox.x2 AND
r.x1 <= inst.trans.off.x+inst.ob.bbox.y2 AND
r.y1 <= inst.trans.off.y-inst.ob.bbox.x1
];
rotate270X =>
RETURN [
r.x2 >= inst.trans.off.x-inst.ob.bbox.y2 AND
r.y2 >= inst.trans.off.y-inst.ob.bbox.x2 AND
r.x1 <= inst.trans.off.x-inst.ob.bbox.y1 AND
r.y1 <= inst.trans.off.y-inst.ob.bbox.x1
];
ENDCASE => ERROR;
};
END.