CDVScaleImpl.mesa
Copyright © 1983, 1984 by Xerox Corporation. All rights reserved.
by Christian Jacobi, August 5, 1983 11:07 am
redesigned by Christian Jacobi August 28, 1984 9:19:36 am PDT
last edited by Christian Jacobi January 27, 1986 5:06:53 pm PST
MakeScale:
PUBLIC PROC [off:
CD.Position←[0, 0], nscale: ScaleRange𡤄, grid:
INTEGER←-1]
RETURNS [s: ScaleRec] =
--given the grid, offset and nscale; makes a correctly gridded and initialized ScaleRec
BEGIN
--explanation of crazy scaling procedure for ScaleViewerToDesign
--v * scale + offset :: ideal
--v* s1/s2 + offset :: integer arithmetic
--(v*s1 + s2/2) / s2 + offset :: correct round of screen point
--( (v*s1 + s2/2) / s2) + grid/2) / grid * grid + offset :: introduce grid
--(v*s1 + s2/2 + grid/2*s2 ) / s2 / grid * grid + offset
--(v*s1 + s2/2 + grid/2*s2 ) / (s2*grid) * grid + offset
sE: INTEGER;
noDivisionScale: ScaleRange = 8;
scaleE:
ARRAY ScaleRange
OF
INTEGER =
--scale for factors
[24, 16, 12, 8, 6, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
scaleF:
ARRAY ScaleRange
OF
INTEGER =
--scale for divisors
[1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192];
scaleS:
ARRAY ScaleRange
OF
NAT =
--scale for shifts
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
s.nscale ← nscale; --MIN[MAX[nscale, 0], CDVScale.scaleNum-1];
s.grid ← MAX[1, grid];
sE ← scaleE[s.nscale];
s.sA ← scaleF[s.nscale];
s.sB ← (s.grid/2)*sE+sE/2;
s.sC ← sE*s.grid;
s.sD ← s.grid;
s.sS ← scaleS[s.nscale];
s.off.x ← off.x/s.grid*s.grid;
s.off.y ← off.y/s.grid*s.grid;
IF s.useMultiply ← s.nscale<noDivisionScale
THEN {
s.xx ← sE;
s.designToViewerFactor ← sE;
}
ELSE {
s.xx ← s.sA;
s.designToViewerFactor ← 1.0/s.sA;
};
END;
GetClipRecord:
PUBLIC
PROC[scale: ScaleRec, highX, highY:
CARDINAL]
RETURNS [CD.Rect] =
--given the index of the (high-most) pixel in the viewer, compute an outside clipping
--rectangle in design coordinates; (such that all outside the clipping area is invisible).
BEGIN
UnGridedScaleViewerToDesignUp:
PROC [scale: ScaleRec, v:
LONG
CARDINAL]
RETURNS [
CD.Number] =
INLINE {
sE: INTEGER = IF scale.useMultiply THEN scale.xx ELSE 1;
RETURN [LOOPHOLE[(v*scale.sA+sE+sE)/sE, CD.Number]]
};
RETURN [
CD.Rect[
x1: CDVScale.ViewerToDesignScalar[scale, 0]+scale.off.x,
y1: CDVScale.ViewerToDesignScalar[scale, 0]+scale.off.y,
x2: UnGridedScaleViewerToDesignUp[scale, highX+1]+scale.off.x,
y2: UnGridedScaleViewerToDesignUp[scale, highY+1]+scale.off.y]
]
END;