DIRECTORY CD, CDBasics, CDCSUtil, CDErrors, CDOps, CStitching, D2Basic, Rope; CDCSUtilImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDErrors, CDOps, CStitching EXPORTS CDCSUtil = BEGIN OPEN CDCSUtil; didStop: SIGNAL = CODE; New: PUBLIC PROC [filledWith: REF_NIL, data: REF _ NIL, stopFlag: REF BOOL _ NIL] RETURNS [plane: Tesselation] = BEGIN plane _ CStitching.NewTesselation[data, stopFlag]; CStitching.ChangeRect[plane, CDBasics.universe, filledWith]; END; Dispose: PUBLIC PROC [basis: Tesselation] = BEGIN IF basis#NIL THEN CStitching.ChangeRect[basis, CDBasics.universe]; 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: Tesselation _ 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 CStitching.ChangeRect[plane: sl.first.plane, rect: CDBasics.Extend[rect, sl.first.delta], new: $covered] ENDLOOP; }; END; Make: PUBLIC PROC [what: CDWorld, layers: Layers, into: Tesselation_NIL] RETURNS [Tesselation] = BEGIN cf: REF CD.ContextFilter _ NEW[CD.ContextFilter_ALL[FALSE]]; maxGrow: CD.Number _ 0; pr: CD.DrawRef _ CD.CreateDrawRef[[ stopFlag: what.stopFlag, design: what.design, drawChild: what.drawChild, drawContext: what.drawContext, drawRect: MyDrawRect, interestClip: what.clip, contextFilter: cf ]]; state: REF StateRec; 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] _ TRUE; 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: Tesselation, msg: Rope.ROPE, owner: ATOM_NIL, dispose: BOOL_TRUE, remFirst: BOOL_TRUE, except: REF_NIL] RETURNS [num: INT_0] = BEGIN InternalMsg: CStitching.TileProc = 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 CStitching.EnumerateArea[plane: x, rect: GoodScaleCsFromCDRect[what.clip, what.off, what.scaleNum, what.scaleDenom], eachTile: InternalMsg, data: what, skip: except ! didStop => CONTINUE]; CDOps.DoTheDelayedRedraws[what.design]; --helps debugging and backgrounders IF dispose THEN Dispose[x]; END; Fill: PUBLIC PROC [x: Tesselation, into: Tesselation_NIL, except: REF_NIL, dispose: BOOL_FALSE] RETURNS [Tesselation] = BEGIN IF into=NIL THEN into _ New[stopFlag: x.stopFlag]; IF ~x.stopFlag^ AND ~into.stopFlag^ THEN { CStitching.EnumerateArea[plane: x, rect: CDBasics.universe, eachTile: InternalFillTTile, data: into, skip: except]; }; IF dispose THEN Dispose[x]; RETURN [into] END; InternalFillTTile: CStitching.TileProc = BEGIN into: Tesselation _ NARROW[data]; CStitching.ChangeRect[plane: into, rect: CStitching.Area[tile], new: $covered] END; Rem: PUBLIC PROC [x: Tesselation, into: Tesselation_NIL, except: REF_NIL, dispose: BOOL_FALSE] RETURNS [Tesselation] = BEGIN IF into=NIL THEN into _ New[filledWith: $covered, stopFlag: x.stopFlag]; IF ~x.stopFlag^ AND ~into.stopFlag^ THEN { CStitching.EnumerateArea[plane: x, rect: CDBasics.universe, eachTile: InternalRemTTile, data: into, skip: except]; }; IF dispose THEN Dispose[x]; RETURN [into]; END; InternalRemTTile: CStitching.TileProc = BEGIN into: CStitching.Tesselation _ NARROW[data]; CStitching.ChangeRect[plane: into, rect: CStitching.Area[tile], new: NIL] END; FillGrow: PUBLIC PROC [x: Tesselation, grow: INT_0, into: Tesselation_NIL, except: REF_NIL, use: REF_$covered, dispose: BOOL_FALSE] RETURNS [Tesselation] = BEGIN InternalGrowTTile: CStitching.TileProc = BEGIN r: CD.Rect _ CDBasics.Extend[CDBasics.Intersection[CDBasics.universe, CStitching.Area[tile]], grow]; CStitching.ChangeRect[plane: into, rect: r, new: use]; IF into.stopFlag^ THEN SIGNAL didStop; END; IF into=NIL THEN into _ New[stopFlag: x.stopFlag]; IF ~x.stopFlag^ AND ~into.stopFlag^ THEN { CStitching.EnumerateArea[plane: x, rect: CDBasics.universe, eachTile: InternalGrowTTile, data: NIL, skip: except ! didStop => CONTINUE]; }; IF dispose THEN Dispose[x]; RETURN [into]; END; Copy: PUBLIC PROC [x: Tesselation, into: Tesselation_NIL, dispose: BOOL_FALSE] RETURNS [Tesselation] = BEGIN IF into=NIL THEN into _ New[stopFlag: x.stopFlag]; IF ~x.stopFlag^ AND ~into.stopFlag^ THEN { CStitching.EnumerateArea[plane: x, rect: CDBasics.universe, eachTile: InternalCopyTile, data: into]; }; IF dispose THEN Dispose[x]; RETURN [into] END; InternalCopyTile: CStitching.TileProc = BEGIN into: CStitching.Tesselation _ NARROW[data]; CStitching.ChangeRect[plane: into, rect: CStitching.Area[tile], new: tile.value] END; Not: PUBLIC PROC [x: Tesselation, dispose: BOOL_FALSE] RETURNS [Tesselation] = { RETURN [Rem[x: x, into: NIL, except: NIL, dispose: dispose]] }; AndIn: PUBLIC PROC [x: Tesselation, into: Tesselation, dispose: BOOL_FALSE] RETURNS [Tesselation] = { RETURN [Rem[x: x, into: into, except: $covered, dispose: dispose]] }; OrIn: PUBLIC PROC [x: Tesselation, into: Tesselation, dispose: BOOL_FALSE] RETURNS [Tesselation] = { RETURN [Fill[x: x, into: into, except: NIL, dispose: dispose]] }; AndNotIn: PUBLIC PROC [x: Tesselation, into: Tesselation, dispose: BOOL_FALSE] RETURNS [Tesselation] = { RETURN [Rem[x: x, into: into, except: NIL, dispose: dispose]] }; And: PUBLIC PROC [t1, t2, t3, t4: Tesselation_NIL] RETURNS [into: Tesselation] = { 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: Tesselation_NIL] RETURNS [into: Tesselation] = { 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: Tesselation] RETURNS [Tesselation] = { RETURN [AndNotIn[n, Copy[a]]]; }; Grow: PUBLIC PROC [x: Tesselation, amount: INT_0, dispose: BOOL_FALSE] RETURNS [t: Tesselation] = { 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. ΈCDCSUtilImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Jacobi, December 12, 1985 2:19:57 pm PST Jacobi, March 19, 1986 10:22:51 am PST CStitching.FreeTesselation[basis, FALSE]; --fills "into" with $covered except where "x" has "except" --NIL "into" creates new tesselation filled with NIL --fills "into" with NIL except where "x" has "except" --NIL "into" creates new tesselation filled with $covered --fills "into" with "use" except where "x" has "except" --NIL "into" creates new tesselation filled with NIL --simple copy operation --fills "into" with "x" except where "x" is NIL --NIL "into" creates new tesselation filled with NIL --a AND (~n) Κ Ÿ˜codešœ™Kšœ Οmœ7™BK™(K™&K˜—K˜šΟk ˜ Kšžœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ K˜Kšœ ˜ Kšœ˜Kšœ˜—K˜šΠbl œžœž˜Kšžœžœ'˜1Kšžœ ˜—Kšž œ ˜K˜Kšœ žœžœ˜K˜šΟnœž œžœžœžœžœ žœžœžœžœ˜pKšž˜Kšœ2˜2Kšœ<˜Kšœh˜hKšžœ˜—K˜—Kšžœ˜—K˜š œž œ3žœžœ˜`Kšž˜Kš œžœžœžœžœžœžœ˜K˜—K˜š  œž œ.žœžœžœ˜hKšžœ žœ˜=K˜—K˜š  œžœžœžœžœ˜RKšœ˜Kšžœžœžœ˜&Kšžœžœžœ˜&Kšžœžœžœ˜&K˜—K˜š  œžœžœžœžœ˜RKšœ˜Kšžœžœžœ˜%Kšžœžœžœ˜%Kšžœžœžœ˜%K˜—K˜š œž œžœ˜AKšœ ™ Kšžœ˜K˜—K˜š œžœžœžœ žœžœžœ˜cšžœ˜šžœ žœ˜KšœFžœ"˜k—šžœžœ ž˜Kšœlžœ˜‚—šž˜Kšœ4žœ˜J—K˜—K˜—K˜Kšžœ˜K˜—…— μ/C