DIRECTORY ImagerBasic, Rope USING [ROPE], UnifiedFonts USING [FONT]; Imager: CEDAR DEFINITIONS ~ BEGIN Rectangle: TYPE ~ ImagerBasic.Rectangle; -- RECORD [x, y, w, h: REAL] IntRectangle: TYPE ~ ImagerBasic.IntRectangle; -- RECORD [x, y, w, h: INTEGER] Pair: TYPE ~ ImagerBasic.Pair; -- RECORD [x, y: REAL] IntPair: TYPE ~ ImagerBasic.IntPair; -- RECORD [x, y: INTEGER] Context: TYPE ~ REF ContextRep; -- Holds the imager state ContextRep: TYPE ~ RECORD[class: REF ClassRep, data: REF]; Class: PRIVATE PROC [context: Context] RETURNS [REF ClassRep] ~ INLINE {RETURN [context.class]}; Create: PROC [deviceType: ATOM, name: Rope.ROPE _ NIL] RETURNS [Context]; UnImplementedDevice: ERROR; DeviceType: PROC [context: Context] RETURNS [ATOM] ~ INLINE {RETURN [Class[context].deviceType]}; Flush: PROC [context: Context] ~ INLINE {Class[context].Flush[context]}; Close: PROC [context: Context] ~ INLINE {Class[context].Close[context]}; DoSaveAll: PROC [context: Context, action: PROC] ~ INLINE {Class[context].DoSaveAll[context, action]}; DoSave: PROC [context: Context, action: PROC] ~ INLINE {Class[context].DoSave[context, action]}; Transformation: TYPE ~ ImagerBasic.Transformation; TranslateT: PROC [context: Context, dx, dy: REAL] ~ INLINE {Class[context].TranslateT[context, dx, dy]}; RotateT: PROC [context: Context, degrees: REAL] ~ INLINE {Class[context].RotateT[context, degrees]}; ScaleT: PROC [context: Context, sx, sy: REAL] ~ INLINE {Class[context].ScaleT[context, sx, sy]}; ConcatT: PROC [context: Context, transformation: Transformation] ~ INLINE {Class[context].ConcatT[context, transformation]}; GetT: PROC [context: Context] RETURNS [Transformation] ~ INLINE {RETURN [Class[context].GetT[context]]}; SetT: PROC [context: Context, transformation: Transformation] ~ INLINE {Class[context].SetT[context, transformation]}; IntTranslateT: PROC [context: Context, dx, dy: INTEGER] ~ INLINE {Class[context].IntTranslateT[context, dx, dy]}; IntScaleT: PROC [context: Context, sx, sy: INTEGER] ~ INLINE {Class[context].IntScaleT[context, sx, sy]}; Visibility: TYPE ~ ImagerBasic.Visibility; -- {visible, partlyVisible, invisible} Clipper: TYPE ~ REF; -- for use in GetClipper and SetClipper only. GetClipper: PROC [context: Context] RETURNS [Clipper] ~ INLINE {RETURN [Class[context].GetClipper[context]]}; SetClipper: PROC [context: Context, clipper: Clipper] ~ INLINE {Class[context].SetClipper[context, clipper]}; ClipPath: PROC [context: Context, outline: Path, exclude: BOOLEAN _ FALSE] ~ INLINE {Class[context].ClipPath[context, outline, exclude]}; ClipRectangle: PROC [context: Context, outline: Rectangle, exclude: BOOLEAN _ FALSE] ~ INLINE {Class[context].ClipRectangle[context, outline, exclude]}; TestRectangle: PROC [context: Context, area: Rectangle] RETURNS [Visibility] ~ INLINE {RETURN [Class[context].TestRectangle[context, area]]}; ClipIntRectangle: PROC [context: Context, outline: IntRectangle, exclude: BOOLEAN _ FALSE] ~ INLINE {Class[context].ClipIntRectangle[context, outline, exclude]}; TestIntRectangle: PROC [context: Context, area: IntRectangle] RETURNS [Visibility] ~ INLINE {RETURN [Class[context].TestIntRectangle[context, area]]}; DoWithoutClipping: PROC [context: Context, bounds: IntRectangle, callBack: PROC[Context]] ~ INLINE {Class[context].DoWithoutClipping[context, bounds, callBack]}; Color: TYPE ~ ImagerBasic.Color; black: Color; white: Color; SetColor: PROC [context: Context, color: Color] ~ INLINE {Class[context].SetColor[context, color]}; GetColor: PROC [context: Context] RETURNS [Color] ~ INLINE {RETURN [Class[context].GetColor[context]]}; Path: TYPE ~ ImagerBasic.Path; StrokeEnds: TYPE ~ ImagerBasic.StrokeEnds; -- {butt, square, round} MaskStroke: PROC [context: Context, path: Path, width: REAL, strokeEnds: StrokeEnds, closed: BOOLEAN _ FALSE] ~ INLINE {Class[context].MaskStroke[context, path, width, strokeEnds, closed]}; MaskFill: PROC [context: Context, path: Path] ~ INLINE {Class[context].MaskFill[context, path]}; MaskPixel: PROC [context: Context, pixelArray: ImagerBasic.PixelArray] ~ INLINE {Class[context].MaskPixel[context, pixelArray]}; MaskBits: PROC [context: Context, base: LONG POINTER, raster: CARDINAL, tile: IntRectangle, area: IntRectangle] ~ INLINE {Class[context].MaskBits[context, base, raster, tile, area]}; MaskSegment: PROC [context: Context, p: Pair] ~ INLINE {Class[context].MaskSegment[context, p]}; MaskIntSegment: PROC [context: Context, p: IntPair] ~ INLINE {Class[context].MaskIntSegment[context, p]}; MaskThinStroke: PROC [context: Context, path: Path] ~ INLINE {Class[context].MaskThinStroke[context, path]}; MaskRectangle: PROC [context: Context, area: Rectangle] ~ INLINE {Class[context].MaskRectangle[context, area]}; MaskIntRectangle: PROC [context: Context, area: IntRectangle] ~ INLINE {Class[context].MaskIntRectangle[context, area]}; SetCP: PROC [context: Context, cp: Pair] ~ INLINE {Class[context].SetCP[context, cp]}; GetCP: PROC [context: Context] RETURNS [cp: Pair] ~ INLINE {RETURN [Class[context].GetCP[context]]}; SetIntCP: PROC [context: Context, cp: IntPair] ~ INLINE {Class[context].SetIntCP[context, cp]}; GetIntCP: PROC [context: Context] RETURNS [cp: IntPair] ~ INLINE {RETURN [Class[context].GetIntCP[context]]}; MaskChar: PROC [context: Context, font: UnifiedFonts.FONT, char: CHAR] ~ INLINE {Class[context].MaskChar[context, font, char]}; MaskCharacters: PROC [ context: Context, font: UnifiedFonts.FONT, characters: REF, -- may be a Rope.ROPE or a REF TEXT start: INT _ 0, length: INT _ LAST[INT] ] ~ INLINE {Class[context].MaskCharacters[context, font, characters, start, length]}; CreateBuffer: PROC [deviceType: ATOM, box: IntRectangle] RETURNS [Context]; TransferBuffer: PROC [context, source: Context] ~ INLINE {Class[context].TransferBuffer[context, source]}; IncompatibleContexts: ERROR; Reset: PROC [context: Context] ~ INLINE {Class[context].Reset[context]}; SetView: PROC [context: Context, box: IntRectangle, halftoneOrigin: IntPair _ [0, 0]] ~ INLINE {Class[context].SetView[context, box, halftoneOrigin]}; ClipView: PROC [context: Context, box: IntRectangle, exclude: BOOLEAN] ~ INLINE {Class[context].ClipView[context, box, exclude]}; GetSurfaceBounds: PROC [context: Context] RETURNS [IntRectangle] ~ INLINE {RETURN [Class[context].GetSurfaceBounds[context]]}; GetViewBounds: PROC [context: Context] RETURNS [IntRectangle] ~ INLINE {RETURN [Class[context].GetViewBounds[context]]}; MoveSurfaceRectangle: PROC [context: Context, source: IntRectangle, dest: IntPair] RETURNS [BOOLEAN] ~ INLINE {RETURN [Class[context].MoveSurfaceRectangle[context, source, dest]]}; SetColorInvert: PROC [context: Context] ~ INLINE {Class[context].SetColorInvert[context]}; DrawBitmap: PROC [context: Context, base: LONG POINTER, raster: CARDINAL, area: IntRectangle] ~ INLINE {Class[context].DrawBitmap[context, base, raster, area]}; SpecialOp: PROC [context: Context, op: ATOM, data: REF] RETURNS [BOOLEAN] ~ INLINE {RETURN [Class[context].SpecialOp[context, op, data]]}; ClassRep: TYPE ~ RECORD [ deviceType: ATOM, Init: PROC [context: Context, name: Rope.ROPE, bounds: IntRectangle], DoSaveAll: PROC [context: Context, action: PROC], DoSave: PROC [context: Context, action: PROC], Flush: PROC [context: Context], Close: PROC [context: Context], TranslateT: PROC [context: Context, dx, dy: REAL], RotateT: PROC [context: Context, degrees: REAL], ScaleT: PROC [context: Context, sx, sy: REAL], ConcatT: PROC [context: Context, transformation: Transformation], GetT: PROC [context: Context] RETURNS [Transformation], SetT: PROC [context: Context, transformation: Transformation], IntTranslateT: PROC [context: Context, dx, dy: INTEGER], IntScaleT: PROC [context: Context, sx, sy: INTEGER], GetClipper: PROC [context: Context] RETURNS [Clipper], SetClipper: PROC [context: Context, clipper: Clipper], ClipPath: PROC [context: Context, outline: Path, exclude: BOOLEAN], ClipRectangle: PROC [context: Context, outline: Rectangle, exclude: BOOLEAN], TestRectangle: PROC [context: Context, area: Rectangle] RETURNS [Visibility], ClipIntRectangle: PROC [context: Context, outline: IntRectangle, exclude: BOOLEAN], TestIntRectangle: PROC [context: Context, area: IntRectangle] RETURNS [Visibility], DoWithoutClipping: PROC [context: Context, bounds: IntRectangle, callBack: PROC[Context]], SetColor: PROC [context: Context, color: Color], GetColor: PROC [context: Context] RETURNS [Color], MaskStroke: PROC [context: Context, path: Path, width: REAL, strokeEnds: StrokeEnds, closed: BOOLEAN _ FALSE], MaskFill: PROC [context: Context, path: Path], MaskPixel: PROC [context: Context, pixelArray: ImagerBasic.PixelArray], MaskBits: PROC [context: Context, base: LONG POINTER, raster: CARDINAL, tile: IntRectangle, area: IntRectangle], MaskSegment: PROC [context: Context, p: Pair], MaskIntSegment: PROC [context: Context, p: IntPair], MaskThinStroke: PROC [context: Context, path: Path], MaskRectangle: PROC [context: Context, area: Rectangle], MaskIntRectangle: PROC [context: Context, area: IntRectangle], SetCP: PROC [context: Context, cp: Pair], GetCP: PROC [context: Context] RETURNS [Pair], SetIntCP: PROC [context: Context, cp: IntPair], GetIntCP: PROC [context: Context] RETURNS [IntPair], MaskChar: PROC [context: Context, font: UnifiedFonts.FONT, char: CHAR], MaskCharacters: PROC [context: Context, font: UnifiedFonts.FONT, characters: REF, start: INT _ 0, length: INT], TransferBuffer: PROC [context, source: Context] _ NIL, Reset: PROC [context: Context] _ NIL, SetView: PROC [context: Context, box: IntRectangle, halftoneOrigin: IntPair] _ NIL, ClipView: PROC [context: Context, box: IntRectangle, exclude: BOOLEAN] _ NIL, GetSurfaceBounds: PROC [context: Context] RETURNS [IntRectangle] _ NIL, GetViewBounds: PROC [context: Context] RETURNS [IntRectangle] _ NIL, MoveSurfaceRectangle: PROC [context: Context, source: IntRectangle, dest: IntPair] RETURNS [BOOLEAN] _ NIL, SetColorInvert: PROC [context: Context] _ NIL, DrawBitmap: PROC [context: Context, base: LONG POINTER, raster: CARDINAL, area: IntRectangle] _ NIL, SpecialOp: PROC [context: Context, op: ATOM, data: REF] RETURNS [BOOLEAN] _ NIL ]; nullBounds: IntRectangle ~ [FIRST[INTEGER], FIRST[INTEGER], FIRST[INTEGER], FIRST[INTEGER]]; END. 2Imager.mesa This interface is the public expression of the client view of the procedures, structures, etc. for making images on all devices. At this level (client), only operations which affect only the client world are allowed. Therefore, updates to the viewers or device parameters go through lower level interfaces. There are two "tracks" for many operations: a "Fast Track" for efficient operations, using integers, and a "General Track" for more general operations, using floating point. For time-critical applications, the interface ImagerInline may be used. It implements the same operations as this interface, but saves one procedure call per operation. Last Edited by: Crow, August 1, 1983 4:02 pm Wyatt, June 21, 1983 11:46 am Plass, August 3, 1983 10:01 am Basic Numbers and Shapes Context For making a new context. The name is used for output file names, etc. May raise: If printer or InterPress, start new page; otherwise clear inside context. If printer or InterPress, close output file; otherwise nop. Saving and restoring imager variables. See also GetT/SetT, GetColor/SetColor, GetClipper/SetClipper, GetCP/SetCP Save the imager variables, execute the action, and restore the variables to their old values. Like DoSaveAll, but CP is not restored Transformations These calls, for clients, automatically concatenate to the current client transform. General Track Direct control of the client-to-view transformation. Fast Track Clipping These routines allow the definition and testing of client clipping paths. Clipping paths are assumed to be glued to the viewer once defined. Subsequent changes in the client transform do not effect previously defined clipping paths. Direct control of the client-to-view clipper. Should be the same context the clipper was obtained from, since clipper representation is device specific. General Track Modifies old clipping region by supplied outline. Exclude sets clipping outside path rather than inside. Modifies old clipping region by supplied outline. Exclude sets clipping outside path rather than inside. Fast Track Modifies old clipping region by supplied outline. Exclude sets clipping outside path rather than inside. Uses TestIntRectangle with "bounds" to verify that no clipping is needed. In cases of inaccurate bounding rectangles, the client assumes liability for garbaged displays, but not for garbaged worlds. Color A Color is a specification for coloring the Euclidean plane. There are three kinds of color: (1) a constant color (ImagerBasic.CIEColor), (2) color from an array of samples, which tile the plane (ImagerBasic.SampledColor), and (3) special colors (see ImagerDoc.tioga for details). Various procedures in ImagerColor provide transformations from common color spaces to Colors. Paths Masks These procedures take the current color and apply it to those pixels which lie inside an area defined by the mask parameter (stroke, area, or pixelmask). The defined area is treated as a stencil which is conceptually superposed over the page while the color or image is applied. (1) "Butt" ends are squared off at the endpoint coordinate. (2) "Square" ends are extended by half the stroke width before squaring. (3) "Round" ends have semicircular caps at the ends. Form a stencil of "width" thickness around a spine defined by "path". Connected path segments will be mitered together. The client's path expansion scheme determines whether the path is open or closed. Use the path to outline an area to be filled with the current color Use the supplied pixel array as the stencil. The origin of the pixel array will be placed at the origin of the client space. The samples will be assumed to be placed at one unit intervals in the client space. Use a set of bits beginning at "base" to form a single-bit per pixel tile with dimensions given by "tile". The tile will be used (repetitively if necessary) to color the "area". The tile is filled with bits from "base" as follows: FOR y DECREASING IN [0..tile.h) DO FOR x IN [0..tile.w) DO tile[x, y] _ GetBit[base, x]; ENDLOOP; base _ base + raster; ENDLOOP; where GetBit[base, i] gets the ith bit after base. Fast Track. The width of lines, etc. is device dependent, approximately .1% page height. Draw a thin line from the current position to p, and set the current position to p. Draw whole path using the current color Fill rectangular area with the current color Characters Use the font interface to obtain FONTs and their metrics. Affects current position. Fast Track Uses the DeviceWidth of each character for positioning. Operations not supported on all devices. Not all devices support these operations. To determine whether or not a given operation is supported, clients should inspect the appropriate field of the class record, e. g., IF context.class.MoveSurfaceRectangle = NIL THEN RedrawRectangle[] ELSE context.MoveSurfaceRectangle[. . .]; Procedures for moving and storing images, double-buffering, etc. Makes an undisplayed buffer compatible with the specified device type. Moves the image from source to context, subject to the context clipper and view transformation. The client transformations and current positions of the contexts are ignored, as well as the source clipper. May raise: which probably indicates an error in the client program. Procedures for manipulating View-to-Surface transformation and clipper (window packages only, please) Sets the View-to-Surface transformation to map the origin in View coordinates to (box.x and box.y) in Surface coordinates, and the View-to-Surface clipper to show the specified box. The halftoneOrigin parameter is for controlling the phase of halftones, and is also expressed in terms of Surface coordinates. For setting up fancier clippers; the box is in Surface coordinates. For finding out where the usable parts of the Surface are. The results are in Surface coordinates. Yields the bounding box of the View clipper, in Surface coordinates. Moves the source rectangle so that its new origin is at dest. Both source and dest are in Surface coordinates. Returns FALSE if the device does not support the operation. Overlapping source and dest are allowed. Clippers are ignored. Beware of moving images containing halftones, because this may cause misaligned halftone screens. The halftone screens are aligned by SetView, so the window package may move viewers around without problems. Special operations Class record definition. Κ `– "cedar" style˜headšœ ™ J™δJ™©unitšœ™Jšœ™Jšœ™J™—šΟk ˜ Jšœ ˜ Jšœœœ˜Jšœ œœ˜——head2šœœ ˜Jšœ˜—head3šΟb™Lšœ œΟc˜ELšœœŸ˜NLšœœŸ˜6Lšœ œŸ˜?—šž™Jšœ œœŸ˜<š œ œœœœ˜:š Οnœœœœœ ˜=Jšœœœ˜"——J˜š  œœœ œœœ ˜IJšœG™Gšœ ™ Jšœœ˜——š  œœœœ˜2Jšœœœ˜.—š œœ˜Jšœœ!˜)JšœI™I—š œœ˜Jšœœ!˜)Jšœ;™;J™—ašΟi&™&Jš‘I™I—š  œœœ˜0Jšœœ-˜5J™]—š œœœ˜-Jšœœ*˜2Jšœ&™&——šž™Jšœœ˜2™TLš‘ ™ —š  œœœ˜1Jšœœ.˜6—š œœœ˜/Jšœœ,˜4—š œœœ˜-Jšœœ*˜2—š œœ3˜@Jšœœ3˜;—˜Lš‘4™4—š œœœ˜6Jšœœœ!˜1—š œœ3˜=Jšœœ0˜8Lš‘ ™ —š  œœœ˜7Jšœœ1˜9—š  œœœ˜3Jšœœ-˜5——šž™™J™κLšœ œŸ&˜QJšœ œœŸ-˜CLš‘-™-—š  œœœ ˜5Jšœœœ'˜7—š  œœ%˜5Jšœœ/˜7J™jLš‘ ™ —š œœ+œœ˜JJšœœ6˜>Jšœi™i—š  œœ1œœ˜TJšœœ;˜CJšœi™i—š  œœ%œ ˜LJšœœœ0˜@Lš‘ ™ —š œœ4œœ˜ZJšœœ>˜FJšœi™i—š œœ(œ ˜RJšœœœ3˜C—š œœ4œ ˜YJšœœ?˜GJšœ œ³™Θ——šž™šœ]™]Jšœ,™,JšœX™XJšœ5™5—Jšœ]™]Jšœœ˜ Jšœ ˜ Jšœ ˜ š œœ!˜/Jšœœ+˜3—š œœœ˜1Jšœœœ%˜5——šž™Jšœœ˜—šž™Jšœ–™–šœ œŸ˜EJšœ;™;JšœH™HJšœ4™4—š   œœ'œ"œœ˜mJšœœG˜OšœE™EJšœ„™„——š œœ˜-Jšœœ*˜2JšœC™C—š  œœ6˜FJšœœ1˜9JšœΠ™Π—š  œœœœ œ)˜oJšœœ>˜F™θšœ œœ ™"šœœ ™J™Jš™—J™Jš™—Jšœ Οuœ™2——J™JšœY™Yš  œœ˜-Jšœœ*˜2J™S—š œœ˜3Jšœœ-˜5—š œœ˜3Jšœœ0˜8J™'—š  œœ$˜7Jšœœ/˜7J™,—š œœ&˜=Jšœœ2˜:——šž ™ šœ9™9Lš‘™—š œœ˜(Jšœœ%˜-—š œœœ ˜1Jšœœœ"˜2J™ —š œœ ˜.Jšœœ(˜0—š œœœ˜7Jšœœœ%˜5—š œœ'œœ˜FJšœœ0˜8—š œœ˜Jšœ˜Jšœœ˜Jšœ œŸ#˜4Jšœœ˜Jšœœœœ˜Jšœ˜JšœœK˜SJ™7——™(default™―šœ&™+Pšœ™Pšœ%™)——J˜™@š  œœœœ ˜KJ™F—š œœ˜/Jšœœ2˜:™ΩJšœœ˜—J™8J˜——™eš œœ˜Jšœœ!˜)—š œœH˜UJšœœ8˜@Jšœ΅™΅—š œœ0œ˜FJšœœ2˜:J™C—š œœœ˜@Jšœœœ-˜=J™c—š  œœœ˜=Jšœœœ*˜:J™D—š œœ9œœ˜dJšœœœ?˜OJ™Ύ——™š œœ˜'Jšœœ*˜2—š   œœœœ œ˜]Jšœœ:˜B—š   œœœœœœ˜IJšœœœ0˜@———™šœ œœ˜Jšœ œ˜Jš œœœ˜EJš  œœœ˜1Jš œœœ˜.Jš œœ˜Jš œœ˜Jš  œœœ˜2Jš œœœ˜0Jš œœœ˜.Jš œœ4˜AJš œœœ˜7Jš œœ4˜>Jš  œœœ˜8Jš  œœœ˜4Jš  œœœ ˜6Jš  œœ&˜6Jš œœ,œ˜CJš  œœ1œ˜MJš  œœ%œ˜MJš œœ4œ˜SJš œœ(œ˜SJš œœ4œ ˜ZJš œœ"˜0Jš œœœ ˜2Jš   œœ'œ"œœ˜nJš œœ ˜.Jš  œœ8˜GJš  œœœœ œ*˜pJš  œœ˜.Jš œœ ˜4Jš œœ ˜4Jš  œœ%˜8Jš œœ(˜>Jš œœ˜)Jš œœœ˜.Jš œœ!˜/Jš œœœ ˜4Jš œœ'œœ˜GJš  œœ'œœ œœ˜oJš œœœ˜6Jš œœœ˜%Jš œœBœ˜SJš œœ0œœ˜MJš œœœœ˜GJš  œœœœ˜DJš  œœ9œœœ˜kJš œœœ˜.Jš   œœœœ œœ˜dJš   œœœœœœ˜OJšœ˜—J˜Jšœœœœœœœœœ˜\J˜—J˜Jšœ˜—…—(N’