CDCSUtilImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Jacobi, December 12, 1985 2:19:57 pm PST
Jacobi, January 15, 1986 6:14:53 pm PST
DIRECTORY
CD,
CDBasics,
CDCSUtil,
CDErrors,
CDOps,
CornerStitching,
D2Basic,
Imager,
Rope;
CDCSUtilImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDErrors, CDOps, Imager, CornerStitching
EXPORTS CDCSUtil =
BEGIN OPEN CDCSUtil;
didStop: SIGNAL = CODE;
New:
PUBLIC PROC [filledWith:
REF←
NIL, data:
REF ←
NIL, stopFlag:
REF
BOOL ←
NIL]
RETURNS [plane: Plane] =
BEGIN
plane ← CornerStitching.NewTesselation[data, stopFlag];
CornerStitching.ChangeRect[plane, CDBasics.universe, filledWith];
END;
Dispose:
PUBLIC PROC [basis: Plane] =
BEGIN
IF basis#NIL THEN CornerStitching.ChangeRect[basis, CDBasics.universe];
CornerStitching.FreeTesselation[basis, FALSE];
END;
StateRec:
TYPE =
RECORD [
off: CD.Position ← [0, 0],
scaleNum: INT ← 1,
scaleDenom: INT ← 1,
lLa: ARRAY CD.Layer OF StateLayerList ← ALL[NIL]
];
StateLayerList: TYPE = LIST OF StateLayer ← NIL;
StateLayer: TYPE = RECORD [plane: Plane ← NIL, delta: INT ← 0];
UndividedScaleCsFromCDRect:
PROC [r:
CD.Rect, off:
CD.Position, num:
INT]
RETURNS [rect: D2Basic.Rect] =
INLINE {
rect ← [
x1: (r.x1+off.x)*num,
x2: (r.x2+off.x)*num,
y1: (r.y1+off.y)*num,
y2: (r.y2+off.y)*num
];
};
ScaleCsFromCDRect:
PROC [r:
CD.Rect, off:
CD.Position, num:
INT, denom:
INT]
RETURNS [rect: D2Basic.Rect] =
INLINE {
rect ← [
x1: (r.x1+off.x)*num/denom,
x2: (r.x2+off.x)*num/denom,
y1: (r.y1+off.y)*num/denom,
y2: (r.y2+off.y)*num/denom
];
};
GoodScaleCsFromCDRect:
PROC [r:
CD.Rect, off:
CD.Position, num:
INT, denom:
INT]
RETURNS [rect: D2Basic.Rect] =
INLINE {
max: INT = LAST[INT]/num-1;
range:
PROC[n:
INT]
RETURNS [
INT] =
INLINE {
RETURN [MIN[MAX[n, -max], max]]
};
rect ← [
x1: range[r.x1+off.x]*num/denom,
x2: range[r.x2+off.x]*num/denom,
y1: range[r.y1+off.y]*num/denom,
y2: range[r.y2+off.y]*num/denom
];
};
MyDrawRect:
PROC [r:
CD.Rect, l:
CD.Layer, pr:
CD.DrawRef] =
BEGIN
state: REF StateRec ← NARROW[pr.devicePrivate];
IF state.lLa[l]#
NIL
THEN {
rect:
CD.Rect =
IF state.scaleDenom=1 THEN UndividedScaleCsFromCDRect[r, state.off, state.scaleNum]
ELSE ScaleCsFromCDRect[r, state.off, state.scaleNum, state.scaleDenom];
FOR sl: StateLayerList ← state.lLa[l], sl.rest
WHILE sl#
NIL
DO
CornerStitching.ChangeRect[plane: sl.first.plane, rect: CDBasics.Extend[rect, sl.first.delta], newValue: $covered]
ENDLOOP;
};
END;
Make:
PUBLIC PROC [what: CDWorld, layers: Layers, into: Plane←
NIL]
RETURNS [Plane] =
BEGIN
cf: REF CD.ContextFilter ← NEW[CD.ContextFilter←ALL[NIL]];
maxGrow: CD.Number ← 0;
pr: CD.DrawRef ← CD.CreateDrawRef[what.design];
state: REF StateRec;
IF what.stopFlag=NIL THEN what.stopFlag←NEW[BOOL←FALSE];
IF what.drawChild#NIL THEN pr.drawChild ← what.drawChild;
IF what.drawContext#NIL THEN pr.drawContext ← what.drawContext;
pr.drawRect ← MyDrawRect;
pr.stopFlag ← what.stopFlag;
pr.interestClip ← what.clip;
pr.contextFilter ← cf;
state ←
NEW[StateRec←[
off: what.off,
scaleNum: what.scaleNum,
scaleDenom: what.scaleDenom
]];
pr.devicePrivate ← state;
IF into=NIL THEN into ← New[stopFlag: pr.stopFlag];
FOR l: Layers ← layers, l.rest
WHILE l#
NIL
DO
sl: StateLayer ← [
plane: IF l.first.plane=NIL THEN into ELSE l.first.plane,
delta: l.first.deltaDiameter
];
cf[l.first.source] ← Imager.black;
state.lLa[l.first.source] ← CONS[sl, state.lLa[l.first.source]];
maxGrow ← MAX[maxGrow, l.first.growClip];
ENDLOOP;
pr.interestClip ← CDBasics.Extend[what.clip, MAX[maxGrow, what.minGrowClip]];
IF what.ob#
NIL
THEN {
inst: CD.Instance ← NEW[CD.InstanceRep←[ob: what.ob]];
inst.ob.class.drawMe[inst, [0, 0], CD.original, pr]; --first call is not through what.drawChild
}
ELSE CDOps.DrawDesign[what.design, pr];
RETURN [into];
END;
ExtractErrors:
PUBLIC
PROC [what: CDWorld, x: Plane, msg: Rope.
ROPE, owner:
ATOM←
NIL, dispose:
BOOL←
TRUE, remFirst:
BOOL←
TRUE, except:
REF←
NIL]
RETURNS [num:
INT𡤀] =
BEGIN
InternalMsg: CornerStitching.PerTileProc =
BEGIN
csr: CD.Rect ← tile.Area[];
n: INT ← what.scaleNum;
r:
CD.Rect ← [
x1: (csr.x1*what.scaleDenom)/n - what.off.x,
x2: (csr.x2*what.scaleDenom+n-1)/n - what.off.x,
y1: (csr.y1*what.scaleDenom)/n - what.off.y,
y2: (csr.y2*what.scaleDenom+n-1)/n - what.off.y
];
IF x.stopFlag^ THEN SIGNAL didStop;
[] ← CDErrors.IncludeMessage[what.design, what.ob, r, msg, owner];
num ← num+1;
END;
IF remFirst
THEN {
CDErrors.RemoveMessages[what.design, what.ob, owner];
};
IF x#
NIL
THEN
CornerStitching.EnumerateArea[plane: x, rect: GoodScaleCsFromCDRect[what.clip, what.off, what.scaleNum, what.scaleDenom], perTile: InternalMsg, data: what, skipValue: except ! didStop => CONTINUE];
CDOps.DoTheDelayedRedraws[what.design]; --helps debugging and backgrounders
IF dispose THEN Dispose[x];
END;
Fill:
PUBLIC PROC [x: Plane, into: Plane←
NIL, except:
REF←
NIL, dispose:
BOOL←
FALSE]
RETURNS [Plane] =
--fills "into" with $covered except where "x" has "except"
--NIL "into" creates new tesselation filled with NIL
BEGIN
IF into=NIL THEN into ← New[stopFlag: x.stopFlag];
IF ~x.stopFlag^
AND ~into.stopFlag^
THEN {
CornerStitching.EnumerateArea[plane: x, rect: CDBasics.universe, perTile: InternalFillTTile, data: into, skipValue: except];
};
IF dispose THEN Dispose[x];
RETURN [into]
END;
InternalFillTTile: CornerStitching.PerTileProc =
BEGIN
into: REF CornerStitching.Tesselation ← NARROW[data];
CornerStitching.ChangeRect[plane: into, rect: CornerStitching.Area[tile], newValue: $covered]
END;
Rem:
PUBLIC PROC [x: Plane, into: Plane←
NIL, except:
REF←
NIL, dispose:
BOOL←
FALSE]
RETURNS [Plane] =
--fills "into" with NIL except where "x" has "except"
--NIL "into" creates new tesselation filled with $covered
BEGIN
IF into=NIL THEN into ← New[filledWith: $covered, stopFlag: x.stopFlag];
IF ~x.stopFlag^
AND ~into.stopFlag^
THEN {
CornerStitching.EnumerateArea[plane: x, rect: CDBasics.universe, perTile: InternalRemTTile, data: into, skipValue: except];
};
IF dispose THEN Dispose[x];
RETURN [into];
END;
InternalRemTTile: CornerStitching.PerTileProc =
BEGIN
into: REF CornerStitching.Tesselation ← NARROW[data];
CornerStitching.ChangeRect[plane: into, rect: CornerStitching.Area[tile], newValue: NIL]
END;
FillGrow:
PUBLIC PROC [x: Plane, grow:
INT𡤀, into: Plane←
NIL, except:
REF←
NIL, use:
REF←$covered, dispose:
BOOL←
FALSE]
RETURNS [Plane] =
--fills "into" with "use" except where "x" has "except"
--NIL "into" creates new tesselation filled with NIL
BEGIN
InternalGrowTTile: CornerStitching.PerTileProc =
BEGIN
r: CD.Rect ← CDBasics.Extend[CDBasics.Intersection[CDBasics.universe, CornerStitching.Area[tile]], grow];
CornerStitching.ChangeRect[plane: into, rect: r, newValue: use];
IF into.stopFlag^ THEN SIGNAL didStop;
END;
IF into=NIL THEN into ← New[stopFlag: x.stopFlag];
IF ~x.stopFlag^
AND ~into.stopFlag^
THEN {
CornerStitching.EnumerateArea[plane: x, rect: CDBasics.universe, perTile: InternalGrowTTile, data: NIL, skipValue: except ! didStop => CONTINUE];
};
IF dispose THEN Dispose[x];
RETURN [into];
END;
Copy:
PUBLIC PROC [x: Plane, into: Plane←
NIL, dispose:
BOOL←
FALSE]
RETURNS [Plane] =
--simple copy operation
--fills "into" with "x" except where "x" is NIL
--NIL "into" creates new tesselation filled with NIL
BEGIN
IF into=NIL THEN into ← New[stopFlag: x.stopFlag];
IF ~x.stopFlag^
AND ~into.stopFlag^
THEN {
CornerStitching.EnumerateArea[plane: x, rect: CDBasics.universe, perTile: InternalCopyTile, data: into];
};
IF dispose THEN Dispose[x];
RETURN [into]
END;
InternalCopyTile: CornerStitching.PerTileProc =
BEGIN
into: REF CornerStitching.Tesselation ← NARROW[data];
CornerStitching.ChangeRect[plane: into, rect: CornerStitching.Area[tile], newValue: tile.value]
END;
Not:
PUBLIC PROC [x: Plane, dispose:
BOOL←
FALSE]
RETURNS [Plane] = {
RETURN [Rem[x: x, into: NIL, except: NIL, dispose: dispose]]
};
AndIn:
PUBLIC PROC [x: Plane, into: Plane, dispose:
BOOL←
FALSE]
RETURNS [Plane] = {
RETURN [Rem[x: x, into: into, except: $covered, dispose: dispose]]
};
OrIn:
PUBLIC PROC [x: Plane, into: Plane, dispose:
BOOL←
FALSE]
RETURNS [Plane] = {
RETURN [Fill[x: x, into: into, except: NIL, dispose: dispose]]
};
AndNotIn:
PUBLIC PROC [x: Plane, into: Plane, dispose:
BOOL←
FALSE]
RETURNS [Plane] = {
RETURN [Rem[x: x, into: into, except: NIL, dispose: dispose]]
};
And:
PUBLIC
PROC [t1, t2, t3, t4: Plane←
NIL]
RETURNS [into: Plane] = {
into ← Copy[t1];
IF t2#NIL THEN into ← AndIn[t2, into];
IF t3#NIL THEN into ← AndIn[t3, into];
IF t4#NIL THEN into ← AndIn[t4, into];
};
Or:
PUBLIC
PROC [t1, t2, t3, t4: Plane←
NIL]
RETURNS [into: Plane] = {
into ← Copy[t1];
IF t2#NIL THEN into ← OrIn[t2, into];
IF t3#NIL THEN into ← OrIn[t3, into];
IF t4#NIL THEN into ← OrIn[t4, into];
};
AndNot:
PUBLIC PROC [a, n: Plane]
RETURNS [Plane] = {
--a AND (~n)
RETURN [AndNotIn[n, Copy[a]]];
};
Grow:
PUBLIC
PROC [x: Plane, amount:
INT𡤀, dispose:
BOOL←
FALSE]
RETURNS [t: Plane] = {
RETURN [
IF amount>0
THEN
FillGrow[x: x, grow: amount, into: New[stopFlag: x.stopFlag], except: NIL, use: $covered, dispose: dispose]
ELSE
IF amount<0
THEN
FillGrow[x: x, grow: -amount, into: New[filledWith: $covered, stopFlag: x.stopFlag], except: $covered, use: NIL, dispose: dispose]
ELSE
Fill[x: x, into: New[stopFlag: x.stopFlag], except: NIL, dispose: dispose]
]
};
END.