DIRECTORY Basics USING [DoubleShiftRight], CD USING [Number, Position, Rect]; CDVScale: CEDAR DEFINITIONS IMPORTS Basics = BEGIN scaleNum: CARDINAL = 22; ScaleRange: TYPE = [0..scaleNum); ScaleRec: TYPE = RECORD [ off: CD.Position, xx: PRIVATE INT, useMultiply: PRIVATE BOOL, sS: PRIVATE NAT, sA, sB, sC, sD: PRIVATE CARDINAL, designToViewerFactor: PRIVATE REAL, grid: INTEGER, --in DesignCoordinates nscale: INTEGER ]; ArithmeticShiftRight: PROC [x: INT, by: NAT] RETURNS [INT] = INLINE BEGIN IF x>=0 THEN RETURN [LOOPHOLE[Basics.DoubleShiftRight[LOOPHOLE[x], by]]] ELSE RETURN [LOOPHOLE[ LAST[LONG CARDINAL] - LOOPHOLE[ Basics.DoubleShiftRight[ LOOPHOLE[ LAST[LONG CARDINAL] - LOOPHOLE[x, LONG CARDINAL] ], by ], LONG CARDINAL ] ]] END; DesignToViewerFactor: PROC [scale: ScaleRec] RETURNS [REAL] ~ INLINE { RETURN [scale.designToViewerFactor] }; DesignToViewerScalar: PROC [scale: ScaleRec, n: CD.Number] RETURNS [CD.Number] ~ INLINE { RETURN [IF scale.useMultiply THEN n*scale.xx ELSE ArithmeticShiftRight[n, scale.sS]]; }; DesignToViewerPosition: PROC[scale: ScaleRec, designPos: CD.Position] RETURNS [viewerPos: CD.Position] ~ INLINE { RETURN[ IF scale.useMultiply THEN CD.Position[ (designPos.x-scale.off.x)*scale.xx, (designPos.y-scale.off.y)*scale.xx ] ELSE CD.Position[ ArithmeticShiftRight[designPos.x-scale.off.x, scale.sS], ArithmeticShiftRight[designPos.y-scale.off.y, scale.sS] ] ] }; DesignToViewerRect: PROC[scale: ScaleRec, designRect: CD.Rect] RETURNS [CD.Rect] ~ INLINE { RETURN[ IF scale.useMultiply THEN CD.Rect[ x1: (designRect.x1-scale.off.x)*scale.xx, y1: (designRect.y1-scale.off.y)*scale.xx, x2: (designRect.x2-scale.off.x)*scale.xx, y2: (designRect.y2-scale.off.y)*scale.xx ] ELSE CD.Rect[ x1: ArithmeticShiftRight[designRect.x1-scale.off.x, scale.sS], y1: ArithmeticShiftRight[designRect.y1-scale.off.y, scale.sS], x2: ArithmeticShiftRight[designRect.x2-scale.off.x, scale.sS], y2: ArithmeticShiftRight[designRect.y2-scale.off.y, scale.sS] ] ] }; UngriddedViewerToDesignScalar: PROC [scale: ScaleRec, v: LONG CARDINAL] RETURNS [CD.Number] = INLINE { IF scale.useMultiply THEN RETURN [LOOPHOLE[(v*scale.sA+scale.xx-1)/scale.xx, CD.Number]] ELSE RETURN [LOOPHOLE[(v*scale.sA), CD.Number]] }; ViewerToDesignScalar: PROC [scale: ScaleRec, v: LONG CARDINAL] RETURNS [CD.Number] = INLINE { RETURN [LOOPHOLE[(v*scale.sA+scale.sB)/scale.sC*scale.sD, CD.Number]] }; ViewerToDesignPosition: PROC[scale: ScaleRec, viewerPos: CD.Position] RETURNS [designPos: CD.Position] = INLINE { RETURN[CD.Position[ ViewerToDesignScalar[scale, viewerPos.x]+scale.off.x, ViewerToDesignScalar[scale, viewerPos.y]+scale.off.y] ] }; MakeScale: PROC [off: CD.Position_[0, 0], nscale: ScaleRange_4, grid: INTEGER_-1] RETURNS [ScaleRec]; GetClipRecord: PROC [scale: ScaleRec, highX, highY: CARDINAL] RETURNS [CD.Rect]; END. ŠCDVScale.mesa (a ChipNDale module) Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, July 15, 1983 11:16 am Last edited by: Christian Jacobi, September 19, 1986 11:21:46 am PDT Non public ChipNDale interface to scaling of viewers. -- Scaling must be real fast, therefore the crazyness. -- Design -> Viewer is the most speed critical operation done, used for drawing -- every rectangle... -- Viewer -> Design is speed critical for cursor tracking -- This interface is thought as an implementation module and freely recompiled to improve the -- inline procedures. Do never copy code from this module, because this module changes to -- often, but if new need for scaling appears, include it here. -- Analyzing compiler generated code showed that it is feasible to have a full record as -- parameter, since the optimization will get rid of copying the record. --A type describing scales; increasing a scale number means viewing a bigger part of the --chip in a viewer; (more overview, less detail). --data in this record must be gridded correctly, such that the origin of --the viewer lies on a grid point; otherwise the gridding would --require more complex and slower arithmetic. --without translation --without translation --Including translation to viewer origin --Caller must make sure that the designRect is only little outside the viewer clip rect --Including translation to viewer origin. --Caller must make sure that the designRect is only little outside the viewer clip rect. --without translation, without grid --without translation, but gridded to the current grid --with offset and grid --given the grid, offset and nscale; makes a correctly gridded and initialized ScaleRec --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). ΚV˜codešœ)™)Kšœ Οmœ7™BKšœ4™4K™DK˜—šΟk ˜ Kšœžœ˜ Kšžœžœ˜"—K˜šΟnœžœž ˜Kšžœ ˜—Kšž˜K˜šœ7™7K™Kšœ6™6K™PK™K™9K™]K™ZK™?K™YK™H—K˜Kšœ žœ˜šœ žœ˜#KšœX™XKšœ1™1K˜—šœ žœžœ˜KšœI™IKšœ?™?Kšœ-™-Kšœžœ ˜Kšœžœžœ˜Kšœ žœžœ˜Kšœžœžœ˜Kšœžœžœ˜!Kšœž ˜#KšœžœΟc˜%Kšœž˜Kšœ˜—K˜š Ÿœžœžœžœžœžœ˜˜>Kšœ>˜>Kšœ>˜>Kšœ=˜=Kšœ˜—Kšœ˜—Kšžœ˜—K˜šŸœžœžœžœžœžœ žœ˜fKšœ#™#šžœž˜Kšžœžœ#žœ ˜>—šž˜Kšžœžœžœ ˜*—Kšœ˜K˜—šŸœžœžœžœžœžœ žœ˜]Kšœ6™6Kšžœžœ*žœ ˜EKšœ˜K˜—š Ÿœžœžœ žœ žœ žœ˜qKšœ™šžœžœ ˜Kšœ5˜5Kšœ5˜5Kšœ˜—KšœŸ˜—K˜š Ÿ œžœžœ.žœžœ ˜eKšœW™WK˜—š Ÿ œžœ žœžœžœ˜PK™VK™Z—K˜Kšžœ˜K˜K˜K˜—…— $