PWStretch.mesa
Copyright © 1984 by Xerox Corporation. All rights reversed.
Created by: Monier, November 19, 1984 10:01:05 am PST
Last Edited by: Serlet, February 26, 1985 2:56:40 pm PST
This interface defines in what frame works stretching, as used by PW.
The idea is to do automatic stretching of uninteresting and non-critical cells as routing cells. To achieve this aim one must be able to parse any object, that is tell where it is possible to stretch, and to create a new object from given stretch constraints.
We use a data structure called SortedSegments for different purposes.
DIRECTORY
CD USING [Design, Number, ObPtr, Rect], Rope USING [ROPE];
PWStretch: CEDAR DEFINITIONS =
BEGIN
-- Data structures
-- Easi!
ROPE: TYPE = Rope.ROPE;
-- PosRange describe the projection of some rectangles on an edge. Attention, contrary to what Christian does to rectangles, min is included and max excluded. It is an unchecked error to create a PosRange with min>=max.
PosRange: TYPE = RECORD [min, max: CD.Number];
-- Segment is PosRange plus additionnal information
Segment: TYPE = REF SegmentRec;
SegmentRec: TYPE = RECORD [
pos: PosRange, 
info: REF ANYNIL  -- All other information
];
-- Sorted (in increasing pos order) list of Segments. Two Segments in a SortedSegments cannot intersect.
SortedSegments: TYPE = LIST OF Segment ← NIL;
The biggest segment possible, used as neutral element in some operations
worldSegment: READONLY Segment;
The biggest SortedSegments possible, used as neutral element in some operations
worldSortedSegments: READONLY SortedSegments;
Some Segments record stretch information, that is the wanted amount of stretch.
This amount is stored in the info field of Segments.
StretchInfo: TYPE = REF StretchInfoRec;
StretchInfoRec: TYPE = RECORD [
value: CD.Number ← 0       -- Wanted value of stretch
];
For documenting purposes, we define new types for segments which have a StretchInfo in their info field.
StretchSegment: TYPE = Segment;
SortedStretchSegments: TYPE = SortedSegments;
-- Operations on those data structures
-- Operations on PosRange
PosRangeXFromRect: PROC [rect: CD.Rect] RETURNS [posrange: PosRange];
PosRangeYFromRect: PROC [rect: CD.Rect] RETURNS [posrange: PosRange];
RectFromPosRangeX: PROC [pos: PosRange, y: CD.Number] RETURNS [rect: CD.Rect];
RectFromPosRangeY: PROC [pos: PosRange, x: CD.Number] RETURNS [rect: CD.Rect];
-- Predicate telling if 2 PosRanges Intersects
IntersectPos: PROC [pos1, pos2: PosRange] RETURNS [intersect: BOOL];
-- Offsets a PosRange by an INT amount
OffsetPosRange: PROC [pos: PosRange, offset: INT] RETURNS [posrange: PosRange];
-- Intersects 2 PosRange
IntersectPosRange: PROC [pos1, pos2: PosRange] RETURNS [posrange: PosRange];
-- Union of 2 PosRange
UnionPosRange: PROC [pos1, pos2: PosRange] RETURNS [posrange: PosRange];
-- Operations on Segment
-- Creates a new Segment
MakeNewSegment: PROC [pos: PosRange, info: REFNIL] RETURNS [seg: Segment];
-- Tells whether 2 segments do intersect
IntersectSeg: PROC [s1, s2: Segment] RETURNS [intersect: BOOL];
-- Creates a new Segment at the intersection of 2
IntersectSegment: PROC [s1, s2: Segment, info: REFNIL] RETURNS [seg: Segment];
-- Creates a new Segment at the reunion of 2
UnionSegment: PROC [s1, s2: Segment, info: REFNIL] RETURNS [seg: Segment];
-- Copies a segment with displacing it
CopySegment: PROC [s: Segment, offset: INT ← 0] RETURNS [seg: Segment];
-- Operations on SortedSegments
-- Returns the sorted list of all segments which intersect some given PosRange
IntersectPosSegs: PROC [pos: PosRange, segments: SortedSegments] RETURNS [inter: SortedSegments];
-- Appends a SortedSegments to an existing one, with copying and displacing the Segments. With only first argument, returns a top-level copy of it.
Append: PROC [s1: SortedSegments, s2: SortedSegments ← NIL, offset: INT ← 0] RETURNS [SortedSegments];
-- Reverse a SortedSegments, as Lisp's reverse! In fact list is not really a SortedSegments before the call to reverse.
Reverse: PROC [list: SortedSegments] RETURNS [new: SortedSegments];
-- Makes a new SortedSegments with all segments that appear in both lists
Intersect: PROC [list1, list2: SortedSegments] RETURNS [list: SortedSegments];
-- Makes a new SortedSegments with all segments that appear in either lists
Union: PUBLIC PROC [list1, list2: SortedSegments] RETURNS [list: SortedSegments];
-- Inserts a new Segment
Insert: PROC [pos: PosRange, info: REF, list: SortedSegments ← NIL] RETURNS [SortedSegments];
-- Makes a list with all segments in range that are excluded by list
Complement: PROC [list: SortedSegments, range: PosRange] RETURNS [SortedSegments];
-- Operations on StretchSegment
GetStretchValue: PROC [s: StretchSegment] RETURNS [CD.Number];
Inserts a new StretchSegment at pos with value value, unless there is already one, in case it only add the stretch value to the present one.
InsertStretchSegment: PROC [pos: PosRange, value: CD.Number, s: SortedStretchSegments] RETURNS [SortedStretchSegments];
-- Computes the new location of a Rect once composed with the given SortedStretchSegments
ComposeRectStretches: PROC [rect: CD.Rect, hor, ver: SortedStretchSegments] RETURNS [CD.Rect];
-- Stretch related operations
Every class of object must register a $ParseStretchProc with CDObjectProcs. Default is NOT stretchable. It is also possible to put a ParseStretchProc on a particular object, under the property name $ParseStretchProc.
ParseStretchProc: TYPE = PROC [design: CD.Design, obj: CD.ObPtr] RETURNS [hor, ver: SortedSegments];
Every stretchable object must register a $DoStretchProc with CDObjectProcs. It is also possible to put a DoStretchProc on a particular instance of object, under the attribute $DoStretchProc.
-- design is the design into the new object should be entered. It is the same design in which the object comes from.
-- obj is the object to be stretched
-- hor and ver are a list of segments telling where we want to do the stretch. The info field of segments contains an integer which is the amount of stretch desired.
-- newObj is a new obj or NIL if something went wrong (in that case errMsg is a rope telling what went wrong).
DoStretchProc: TYPE = PROC [design: CD.Design, obj: CD.ObPtr, hor, ver: SortedSegments] RETURNS [newObj: CD.ObPtr, errMsg: ROPENIL];
-- Given any cell, tells where the stretch areas are
ParseStretch: ParseStretchProc;
-- Given cell and wanted stretches, return a new cell
DoStretch: DoStretchProc;
-- Used for telling that an object is not stretchable
HardObjParseStretch: ParseStretchProc;
END.