<> <> <> <> <> DIRECTORY CD, CDVScale; CDVScaleImpl: CEDAR PROGRAM IMPORTS CDVScale EXPORTS CDVScale = BEGIN ScaleRange: TYPE = CDVScale.ScaleRange; ScaleRec: TYPE = CDVScale.ScaleRec; MakeScale: PUBLIC PROC [off: CD.DesignPosition_[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 = [24, 16, 12, 8, 6, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; scaleF: ARRAY ScaleRange OF INTEGER = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]; <> <<[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.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 ELSE s.xx _ s.sA; END; GetClipRecord: PUBLIC PROC[scale: ScaleRec, highX, highY: CARDINAL] RETURNS [CD.DesignRect] = <<--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.DesignNumber] = INLINE { sE: INTEGER = IF scale.useMultiply THEN scale.xx ELSE 1; RETURN [LOOPHOLE[(v*scale.sA+sE+sE)/sE, CD.DesignNumber]] }; RETURN [CD.DesignRect[ 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.