<<-- File: MiscImpl.mesa>> <<-- Last EdiImager.Contexted by: CSChow, February 1, 1985 0:42:38 am PST>> <> <<>> <<--Documentation will come later after consolidating the design -->> DIRECTORY Imager USING[Context, PathProc, MaskFill, MaskStroke, SetGray], IPConstants, Misc; MiscImpl: CEDAR PROGRAM IMPORTS Imager EXPORTS Misc = BEGIN OPEN Misc; WindCreate: PUBLIC PROC[min, max: INT] RETURNS [Window]={ RETURN [NEW[WindowRep_[span: IntlCreate[min, max], curtains: NIL]]]};-- WindCreate-- WindAddCurtain: PUBLIC PROC[w: Window, curtain: Interval]={ <<-- curtain is unioned (in Set theory's sense) with previous curtains>> newCurtainHd, newCurtainTl: LIST OF Interval; IF curtain = NIL THEN RETURN; newCurtainHd _ newCurtainTl _ CONS[NIL, NIL]; FOR c: LIST OF Interval _ w.curtains, c.rest UNTIL c = NIL DO IF IntlIntersect[curtain, c.first] # NIL OR (c.first.max + 1 = curtain.min) OR (curtain.max + 1 = c.first.min) THEN {curtain _ IntlMakeBIntl[curtain, c.first]; LOOP}; IF c.first.max < curtain.min THEN { newCurtainTl.rest _ CONS[c.first, NIL]; newCurtainTl _ newCurtainTl.rest; LOOP}; IF c.first.min > curtain.max THEN { newCurtainTl.rest _ CONS[curtain, c]; EXIT}; REPEAT FINISHED => {newCurtainTl.rest _ LIST[curtain]} ENDLOOP; w.curtains _ newCurtainHd.rest; };-- WindAddCurtain-- WindIsCovered: PUBLIC PROC[w: Window] RETURNS [BOOL]={ <<--Window is covered iff union of all Intervals contain it>> IF w.curtains = NIL THEN RETURN [w.span = NIL]; FOR c: LIST OF Interval _ w.curtains, c.rest UNTIL c = NIL DO IF IntlIntersect[c.first, w.span] # NIL THEN RETURN [IntlContainp[c.first, w.span]] ENDLOOP; RETURN [FALSE] };--WindIsCovered -- WindPassesIntl: PUBLIC PROC[w: Window, intl: Interval] RETURNS [BOOL]={ <<--TRUE <=> interval is contained in window and doesnt intersects any curtains>> IF NOT IntlContainp[w.span, intl] THEN RETURN [FALSE]; FOR c: LIST OF Interval _ w.curtains, c.rest UNTIL c = NIL DO IF IntlIntersect[c.first, intl] # NIL THEN RETURN [FALSE] ENDLOOP; RETURN [TRUE]};-- WindPassesIntl-- WindCurtainsCoverIntl: PUBLIC PROC[w: Window, intl: Interval] RETURNS [BOOL] ={ <<-- TRUE <=> In the union of all previous curtains, 1 of them contains the interval>> FOR c: LIST OF Interval _ w.curtains, c.rest UNTIL c = NIL DO IF IntlIntersect[c.first, intl] # NIL THEN RETURN [IntlContainp[c.first, intl]] ENDLOOP; RETURN [FALSE] };--WindCurtainCoversIntl-- <<>> RectSubtractFailure: PUBLIC ERROR [r1, r2: Rect]= CODE; RectCreate: PUBLIC PROC [xMin, yMin, xMax, yMax: INT] RETURNS[Rect]= { IF xMin > xMax OR yMin> yMax THEN {RETURN[NIL]}; RETURN [NEW[RectRep _ [x: IntlCreate[xMin, xMax], y: IntlCreate[yMin, yMax]]]] }; --RectCreate -- RectCopy: PUBLIC PROC[r: Rect] RETURNS [Rect] ={ IF r = NIL THEN RETURN [NIL]; RETURN [NEW[RectRep _[x: IntlCopy[r.x], y: IntlCopy[r.y]] ]] }; --RectCopy-- RectOneOf: PUBLIC PROC[r: Rect] RETURNS[MiscOneOf] ={ IF r = NIL THEN RETURN [empty]; SELECT IntlOneOf[r.x] FROM interval => {SELECT IntlOneOf[r.y] FROM interval => RETURN[rect]; point => RETURN[interval]; ENDCASE => ERROR}; point => {SELECT IntlOneOf[r.y] FROM interval => RETURN[interval]; point => RETURN[point]; ENDCASE => ERROR}; ENDCASE => ERROR}; --RectOneOf-- RectIntersect: PUBLIC PROC [r1, r2: Rect] RETURNS[Rect]= { xI, yI: Interval; IF r1 = NIL OR r2 = NIL THEN RETURN[NIL]; xI _ IntlIntersect[r1.x, r2.x]; yI _ IntlIntersect[r1.y, r2.y]; IF xI = NIL OR yI = NIL THEN RETURN[NIL]; RETURN[NEW[RectRep _ [x: xI, y: yI]]]; }; -- RectIntersect-- RectContainp: PUBLIC PROC [r1, r2: Rect] RETURNS[BOOL]= { IF r2 =NIL THEN RETURN [TRUE]; IF r1 = NIL THEN RETURN [r2 = NIL]; RETURN[IntlContainp[r1.x, r2.x] AND IntlContainp[r1.y, r2.y]]; }; -- RectContainp-- RectContainPt: PUBLIC PROC[r: Rect, xCoord, yCoord: INT] RETURNS [BOOL] ={ IF r = NIL THEN RETURN [FALSE]; RETURN [IntlContainPt[r.x, xCoord] AND IntlContainPt[r.y, yCoord]]};--RectContainPt-- RectArea: PUBLIC PROC[r: Rect] RETURNS[NAT] ={ IF r = NIL THEN RETURN [0]; RETURN [IntlLength[r.x] * IntlLength[r.y]]}; --RectArea-- RectMakeBRect: PUBLIC PROC [r1, r2: Rect] RETURNS[Rect]= { IF r1 = NIL THEN RETURN [RectCopy[r2]]; IF r2 = NIL THEN RETURN [RectCopy[r1]]; RETURN [NEW[RectRep _ [x: IntlMakeBIntl[r1.x, r2.x], y: IntlMakeBIntl[r1.y, r2.y]]]]; }; -- RectMakeBBox-- RectSubtract: PUBLIC PROC [r1, r2: Rect] RETURNS[Rect]= { ri: Rect; IF r1 = NIL OR r2 = NIL THEN RETURN [RectCopy[r1]]; IF RectContainp[r2, r1] THEN RETURN[NIL]; IF r1.x.max < r2.x.min OR r2.x.max < r1.x.min OR r1.y.max < r2.y.min OR r2.y.max < r1.y.min THEN RETURN [RectCopy[r1]]; ri _ RectIntersect[r1, r2]; IF IntlContainp[ri.x, r1.x] THEN {RETURN [NEW[RectRep _[x: r1.x, y: IntlSubtract[r1.y, ri.y! IntlSubtractFailure => GOTO subtractFailed]]]]}; IF IntlContainp[ri.y, r1.y] THEN {RETURN [NEW[RectRep _[x: IntlSubtract[r1.x, ri.x ! IntlSubtractFailure =>GOTO subtractFailed], y: r1.y]]]}; GOTO subtractFailed; EXITS subtractFailed => RETURN WITH ERROR RectSubtractFailure[r1, r2]; }; -- RectSubtract-- <<>> RectPaint: PUBLIC PROC[r: Rect, context: Imager.Context, xOffset, yOffset: REAL, scaleFactor: REAL _ 1.0, stipple: CARDINAL _ IPConstants.Gray, noFill: BOOL _ FALSE] ={ SELECT RectOneOf[r] FROM rect => { originX: REAL _ xOffset + scaleFactor * r.x.min; originY: REAL _ yOffset + scaleFactor * r.y.min; spanX: REAL _ xOffset + scaleFactor * r.x.max; spanY: REAL _ yOffset + scaleFactor * r.y.max; path: Imager.PathProc ~ { moveTo[[originX, originY]]; lineTo[[spanX, originY]]; lineTo[[spanX, spanY]]; lineTo[[originX, spanY]]; lineTo[[originX, originY]]; }; IF noFill THEN {Imager.MaskStroke[context, path]} ELSE {Imager.SetGray[context, stipple]; Imager.MaskFill[context, path]}}; interval, point => {delta: INT _ 1; originX: REAL _ xOffset + scaleFactor * (r.x.min - delta); originY: REAL _ yOffset + scaleFactor * (r.y.min - delta); spanX: REAL _ xOffset + scaleFactor * (r.x.max + delta); spanY: REAL _ yOffset + scaleFactor * (r.y.max + delta); path: Imager.PathProc ~ { moveTo[[originX, originY]]; lineTo[[spanX, originY]]; lineTo[[spanX, spanY]]; lineTo[[originX, spanY]]; lineTo[[originX, originY]]; }; Imager.SetGray[context, IPConstants.Black]; Imager.MaskStroke[context, path]; }; empty => NULL; ENDCASE => ERROR; }; --RectPaint-- x: PUBLIC PROC [r: Rect] RETURNS [Misc.Interval] ={ RETURN [IF r = NIL THEN NIL ELSE r.x]}; --x-- y: PUBLIC PROC[r: Rect] RETURNS [Misc.Interval] = { RETURN [IF r = NIL THEN NIL ELSE r.y]}; --y-- xMin: PUBLIC PROC [r: Rect] RETURNS[INT]= {RETURN[r.x.min]}; --xMin -- yMin: PUBLIC PROC [r: Rect] RETURNS[INT]= {RETURN [r.y.min]}; -- yMin-- xMax: PUBLIC PROC [r: Rect] RETURNS[INT]= {RETURN [r.x.max]}; -- xMax-- yMax: PUBLIC PROC [r: Rect] RETURNS[INT]= {RETURN [r.y.max]}; --yMax -- IntlSubtractFailure: PUBLIC ERROR [i1, i2: Interval]= CODE; IntlCreate: PUBLIC PROC [min, max: INT] RETURNS[Interval]= { IF min> max THEN {RETURN[NIL]}; RETURN[NEW[IntervalRep _ [min, max]]]; }; -- IntlCreate-- IntlCopy: PUBLIC PROC[i: Interval] RETURNS[Interval] ={ IF i = NIL THEN RETURN [NIL]; RETURN [NEW[IntervalRep _ [i.min, i.max]]]}; --IntlCopy-- IntlOneOf: PUBLIC PROC[i: Interval] RETURNS[MiscOneOf] ={ IF i = NIL THEN RETURN [empty]; SELECT i.min FROM < i.max => RETURN[interval]; i.max => RETURN[point]; ENDCASE => ERROR;}; --IntlOneOf-- IntlMakeBIntl: PUBLIC PROC[i1, i2: Interval] RETURNS[Interval] ={ IF i1 = NIL THEN RETURN [IntlCopy[i2]]; IF i2 = NIL THEN RETURN [IntlCopy[i1]]; RETURN [NEW[IntervalRep _ [MIN[i1.min, i2.min], MAX[i1.max, i2.max]]]] }; --IntlMakeBIntl-- IntlContainp: PUBLIC PROC [i1, i2: Interval] RETURNS[BOOL]= { IF i2 = NIL THEN RETURN [TRUE]; IF i1 = NIL THEN RETURN [i2 = NIL]; IF i1.min <= i2.min AND i2.max <= i1.max THEN {RETURN[TRUE]} ELSE {RETURN[FALSE]}}; -- IntlRectContainp-- IntlContainPt: PUBLIC PROC[i: Interval, p: INT] RETURNS[BOOL]= { IF i = NIL THEN RETURN [FALSE]; RETURN [i.min <= p AND p<= i.max ]};--IntlContainPt-- IntlLength: PUBLIC PROC[i: Interval] RETURNS[NAT] ={ IF i = NIL THEN RETURN [0]; RETURN [i.max - i.min]}; --intlLength-- IntlIntersect: PUBLIC PROC [i1, i2: Interval] RETURNS[Interval]= { IF i1 = NIL OR i2 = NIL THEN RETURN [NIL]; RETURN[IntlCreate[MAX[i1.min, i2.min], MIN[i1.max, i2.max]]]}; -- IntlIntersect-- IntlSubtract: PUBLIC PROC [i1, i2: Interval] RETURNS[Interval]= { IF i1 = NIL OR i2= NIL THEN RETURN [IntlCopy[i1]]; IF IntlContainp[i2, i1] THEN RETURN[NIL]; IF i1.max < i2.min OR i2.max < i1.min THEN RETURN [IntlCopy[i1]]; IF i1.min < i2.min AND i2.max < i1.max THEN {RETURN WITH ERROR IntlSubtractFailure[i1, i2]}; IF i1.min <= i2.max AND i2.max < i1.max THEN RETURN [NEW[IntervalRep _ [i2.max + 1, i1.max]]]; IF i1.min < i2.min AND i2.min <= i1.max THEN RETURN[NEW[IntervalRep _ [i1.min, i2.min - 1]]]; ERROR; }; --IntlSubtract -- <<>> --Raise IntlSubtractFailure- min: PUBLIC PROC [i: Interval] RETURNS [INT]= {RETURN[i.min]}; --min -- max: PUBLIC PROC [i: Interval] RETURNS [INT]= {RETURN[i.max]}; --max -- END. <<--ChangeLog:>> <<-- January 2, 1985 10:28:57 pm PST>> <<-- (1) Add "IF r = NIL THEN RETURN [FALSE]; " to RectContainPt>> <<-- (2) Add IF r = NIL THEN NIL ELSE r. to x and y>>