RETURNS [
BOOLEAN, IntPair, IntPair] = {
Out: TYPE = RECORD[bottom, top, left, right: BOOLEAN];
noneOut: Out = [FALSE, FALSE, FALSE, FALSE];
Code:
PROC [x, y:
INTEGER]
RETURNS [Out] =
INLINE {
OPEN clipper;
out: Out ← noneOut;
IF x < fMin THEN out.left ← TRUE; IF x > fMin + fSize THEN out.right ← TRUE;
IF y < sMin THEN out.bottom ← TRUE; IF y > sMin + sSize THEN out.top ← TRUE;
RETURN [ out ];
};
ClipY:
PROC [a, b: IntPair, xPos:
INTEGER]
RETURNS [
INTEGER] =
INLINE {
t: Environment.LongNumber;
t.high ← LOOPHOLE[xPos - a.x, UNSPECIFIED]; t.low ← LOOPHOLE[0, UNSPECIFIED];
RETURN[ a.y +
LOOPHOLE[
Inline.HighHalf[ LOOPHOLE[t, LONG INTEGER] / (b.x - a.x) * (b.y - a.y)], INTEGER] ];
};
ClipX:
PROC [a, b: IntPair, yPos:
INTEGER]
RETURNS [
INTEGER] =
INLINE {
t: Environment.LongNumber;
t.high ← LOOPHOLE[yPos - a.y, UNSPECIFIED]; t.low ← LOOPHOLE[0, UNSPECIFIED];
RETURN[ a.x +
LOOPHOLE[
Inline.HighHalf[ LOOPHOLE[t, LONG INTEGER] / (b.y - a.y) * (b.x - a.x)], INTEGER] ];
};
aCode, bCode, out: Out;
c: IntPair;
WHILE
TRUE
DO
aCode ← Code[a.x, a.y]; bCode ← Code[b.x, b.y];
Trivial acceptance test
IF Inline.BITOR[LOOPHOLE[aCode, UNSPECIFIED], LOOPHOLE[bCode, UNSPECIFIED]]
= LOOPHOLE[0, UNSPECIFIED]
THEN
RETURN[
TRUE, a, b];
Trivial rejection test
IF Inline.BITAND[LOOPHOLE[aCode, UNSPECIFIED], LOOPHOLE[bCode, UNSPECIFIED]]
# LOOPHOLE[0, UNSPECIFIED]
THEN
RETURN[
FALSE, a, b];
Actual clipping necessary
out ← IF aCode # noneOut THEN aCode ELSE bCode;
SELECT TRUE FROM
out.left => { c.x ← clipper.fMin;
c.y ← ClipY[a, b, c.x]; };
out.right => { c.x ← clipper.fMin + clipper.fSize;
c.y ← ClipY[a, b, c.x]; };
out.bottom => { c.y ← clipper.sMin;
c.x ← ClipX[a, b, c.y]; };
out.top => { c.y ← clipper.sMin + clipper.sSize;
c.x ← ClipX[a, b, c.y]; }
ENDCASE;
IF aCode = out THEN a ← c ELSE b ← c;
ENDLOOP;
ERROR; -- can't get here, supposedly
};