<> <> <> <> <> DIRECTORY CD, CDVScale; CDVScaleImpl: CEDAR PROGRAM IMPORTS CDVScale EXPORTS CDVScale = BEGIN ScaleRange: TYPE = CDVScale.ScaleRange; ScaleRec: TYPE = CDVScale.ScaleRec; MakeScale: PUBLIC PROC [off: CD.Position_[0, 0], nscale: ScaleRange_4, 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]; 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]; 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]; 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> <<--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; END.