DIRECTORY Imager USING [ConcatT, Context, DoSave, DoSaveAll, PathProc, PixelArray, SetColor, SetFont, SetXY], ImagerBackdoor USING [Clipper, IntKey, RealKey, SetInt, SetReal, ViewTranslateI], ImagerBox USING [Rectangle], ImagerColor USING [Color, ColorOperator, ColorRep, SpecialColor], ImagerDevice USING [AllowedMasks, DeviceClass, DeviceClassRep, Device, DeviceParm, MakeDeviceParm], ImagerFont USING [Font, XStringProc], ImagerManhattan USING [BoundingBox, CreateFromBoxes, Destroy, DestructiveUnion, Polygon, Shift], ImagerMaskCache USING [Parameters, ParametersRep], ImagerMaskCapture USING [], ImagerPrivate USING [Class], ImagerRaster USING [Create, CreateClass, GetDevice, SetDeviceClipBox], ImagerSample USING [Clear, Fill, NewSampleMap, SampleMap], ImagerState USING [StateGetFont, StateGetInt, StateGetReal, StateSpace], ImagerTransformation USING [Transformation], Real USING [LargestNumber], SF USING [Box, BoxAction, BoxGenerator, Displace, Max, maxVec, Min, minVec, Nonempty], Vector2 USING [VEC]; ImagerMaskCaptureImpl: CEDAR MONITOR IMPORTS Imager, ImagerBackdoor, ImagerDevice, ImagerManhattan, ImagerRaster, ImagerSample, ImagerState, SF EXPORTS ImagerMaskCapture ~ BEGIN allowMultipleCoverage: BOOL ¬ FALSE; Clipper: TYPE ~ ImagerBackdoor.Clipper; Color: TYPE ~ ImagerColor.Color; Context: TYPE ~ Imager.Context; Device: TYPE ~ ImagerDevice.Device; Font: TYPE ~ ImagerFont.Font; IntKey: TYPE ~ ImagerBackdoor.IntKey; Parameters: TYPE ~ ImagerMaskCache.Parameters; PathProc: TYPE ~ Imager.PathProc; PixelArray: TYPE ~ Imager.PixelArray; RealKey: TYPE ~ ImagerBackdoor.RealKey; Rectangle: TYPE ~ ImagerBox.Rectangle; SampleMap: TYPE ~ ImagerSample.SampleMap; Transformation: TYPE ~ ImagerTransformation.Transformation; VEC: TYPE ~ Vector2.VEC; viewOrigin: NAT ~ 10000; unsetColor: ImagerColor.SpecialColor ~ NEW[ImagerColor.ColorRep.constant.special ¬ [constant[special[type: $Unset, data: NIL, substitute: NIL]]]]; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD [ boundsOnly: BOOL ¬ FALSE, checkColor: BOOL ¬ FALSE, bounds: SF.Box ¬ [], boxes: ImagerManhattan.Polygon ¬ NIL ]; nullReal: REAL ~ Real.LargestNumber; Cant: PUBLIC SIGNAL [why: ATOM] ~ CODE; CreateContext: PROC RETURNS [Context] ~ { data: Data ~ NEW [DataRep ¬ []]; deviceParm: ImagerDevice.DeviceParm ~ ImagerDevice.MakeDeviceParm[ class: deviceClass, sSize: INTEGER.LAST, fSize: INTEGER.LAST, scanMode: [slow: right, fast: up], surfaceUnitsPerInch: [1, 1] ]; context: Context ~ ImagerRaster.Create[class: contextClass, deviceParm: deviceParm, deviceClass: deviceClass, data: data, pixelUnits: TRUE]; ImagerRaster.SetDeviceClipBox[context, [max: [INTEGER.LAST, INTEGER.LAST]]]; ImagerBackdoor.ViewTranslateI[context, viewOrigin, viewOrigin]; FOR key: IntKey IN IntKey[strokeEnd..strokeJoint] DO ImagerBackdoor.SetInt[context, key, INT.LAST]; ENDLOOP; FOR key: RealKey IN RealKey[mediumXSize..correctTY] DO ImagerBackdoor.SetReal[context, key, nullReal]; ENDLOOP; Imager.SetColor[context, unsetColor]; Imager.SetFont[context, NIL]; Imager.SetXY[context, [0, 0]]; RETURN [context] }; defaultParameters: Parameters ¬ NEW[ImagerMaskCache.ParametersRep ¬ []]; GetContext: PROC [parameters: Parameters] RETURNS [context: Context] ~ { context ¬ TryGetContext[]; IF context = NIL THEN context ¬ CreateContext[]; IF parameters = NIL THEN parameters ¬ defaultParameters; ImagerRaster.GetDevice[context].parm.parameters ¬ parameters; }; c1: Context ¬ NIL; c2: Context ¬ NIL; TryGetContext: ENTRY PROC RETURNS [context: Context] ~ INLINE { IF c1#NIL THEN {context ¬ c1; c1 ¬ NIL} ELSE IF c2#NIL THEN {context ¬ c2; c2 ¬ NIL} ELSE context ¬ NIL; }; FreeContext: ENTRY PROC [context: Context] ~ INLINE { IF c1=NIL THEN {c1 ¬ context} ELSE c2 ¬ context; }; CaptureBounds: PUBLIC PROC [operator: PROC [Context], m: Transformation, parameters: Parameters] RETURNS [box: SF.Box] ~ { context: Context ~ GetContext[parameters]; device: Device ~ ImagerRaster.GetDevice[context: context]; data: Data ~ NARROW[device.data]; proc: PROC ~ { Imager.ConcatT[context, m]; operator[context] }; data.boundsOnly ¬ TRUE; data.checkColor ¬ FALSE; data.bounds ¬ [min: SF.maxVec, max: SF.minVec]; Imager.DoSaveAll[context, proc]; box ¬ data.bounds; IF SF.Nonempty[box] THEN box ¬ SF.Displace[box, [-viewOrigin, -viewOrigin]]; FreeContext[context]; RETURN [box]; }; CaptureBoxes: PUBLIC PROC [operator: PROC [Context], m: Transformation, boxAction: SF.BoxAction, checkColor: BOOL, parameters: Parameters] ~ { p: ImagerManhattan.Polygon ~ CaptureManhattan[operator, m, checkColor, parameters]; FOR each: LIST OF SF.Box ¬ p, each.rest UNTIL each = NIL DO boxAction[each.first]; ENDLOOP; ImagerManhattan.Destroy[p]; }; CaptureBitmap: PUBLIC PROC [operator: PROC [Context], m: Transformation, checkColor: BOOL, parameters: Parameters] RETURNS [SampleMap] ~ { p: ImagerManhattan.Polygon ~ CaptureManhattan[operator, m, checkColor, parameters]; bitmap: SampleMap ~ ImagerSample.NewSampleMap[ImagerManhattan.BoundingBox[p]]; ImagerSample.Clear[bitmap]; FOR each: LIST OF SF.Box ¬ p, each.rest UNTIL each = NIL DO ImagerSample.Fill[map: bitmap, box: each.first, value: 1]; ENDLOOP; ImagerManhattan.Destroy[p]; RETURN [bitmap] }; CaptureManhattan: PUBLIC PROC [operator: PROC [Context], m: Transformation, checkColor: BOOL, parameters: Parameters] RETURNS [p: ImagerManhattan.Polygon ¬ NIL] ~ { context: Context ~ GetContext[parameters]; device: Device ~ ImagerRaster.GetDevice[context: context]; data: Data ~ NARROW[device.data]; proc: PROC ~ { Imager.ConcatT[context, m]; operator[context] }; data.boundsOnly ¬ FALSE; data.checkColor ¬ checkColor; data.bounds ¬ [min: SF.maxVec, max: SF.minVec]; data.boxes ¬ NIL; Imager.DoSaveAll[context, proc]; ImagerManhattan.Shift[data.boxes, -viewOrigin, -viewOrigin]; p ¬ data.boxes; data.boxes ¬ NIL; FreeContext[context]; }; CaptureSetColor: PROC [device: Device, color: Color, viewToDevice: Transformation] ~ { data: Data ~ NARROW[device.data]; IF data.checkColor AND color # unsetColor THEN SIGNAL Cant[$SetColor]; device.state.allow ¬ [unorderedBoxes: TRUE, multipleCoverage: allowMultipleCoverage]; }; CaptureMaskBoxes: PROC [device: Device, bounds: SF.Box, boxes: SF.BoxGenerator] ~ { data: Data ~ NARROW[device.data]; data.bounds ¬ [min: SF.Min[data.bounds.min, bounds.min], max: SF.Max[data.bounds.max, bounds.max]]; IF NOT data.boundsOnly THEN { new: ImagerManhattan.Polygon ~ ImagerManhattan.DestructiveUnion[ImagerManhattan.CreateFromBoxes[boxes], data.boxes]; ImagerManhattan.Destroy[data.boxes]; data.boxes ¬ new; }; }; MySetT: PROC [context: Context, m: Transformation] ~ {SIGNAL Cant[$SetT]}; MyGetInt: PROC [context: Context, key: IntKey] RETURNS [INT] ~ { i: INT ~ ImagerState.StateGetInt[context, key]; IF i = INT.LAST THEN SIGNAL Cant[$UninitializedState]; RETURN [i] }; MyGetReal: PROC [context: Context, key: RealKey] RETURNS [REAL] ~ { r: REAL ~ ImagerState.StateGetReal[context, key]; IF r = nullReal THEN SIGNAL Cant[$UninitializedState]; IF key = DCScpx OR key = DCScpy THEN SIGNAL Cant[$GetDCScp]; RETURN [r] }; MyGetFont: PROC [context: Context] RETURNS [Font] ~ { font: Font ~ ImagerState.StateGetFont[context]; IF font = NIL THEN SIGNAL Cant[$UninitializedState]; RETURN [font]; }; MyGetColor: PROC [context: Context] RETURNS [Color] ~ { ERROR Cant[$GetColor] }; MyGetClipper: PROC [context: Context] RETURNS [Clipper] ~ { ERROR Cant[$GetClipper] }; MySpace: PROC [context: Context, x: REAL] ~ { IF ImagerState.StateGetReal[context, amplifySpace] = nullReal THEN ERROR Cant[$UninitializedState]; ImagerState.StateSpace[context, x]; }; RasterShow: PROC [context: Context, string: ImagerFont.XStringProc, xrel: BOOL] ¬ NIL; MyShow: PROC [context: Context, string: ImagerFont.XStringProc, xrel: BOOL] ~ { IF ImagerState.StateGetFont[context] = NIL THEN ERROR Cant[$UninitializedState]; RasterShow[context, string, xrel]; }; RasterMaskUnderline: PROC [context: Context, dy: REAL, h: REAL] ¬ NIL; MyMaskUnderline: PROC [context: Context, dy: REAL, h: REAL] ~ { IF ImagerState.StateGetReal[context, underlineStart] = nullReal THEN ERROR Cant[$UninitializedState]; RasterMaskUnderline[context, dy, h]; }; MyCorrect: PROC [context: Context, action: PROC] ~ { SIGNAL Cant[$Correct]; Imager.DoSaveAll[context, action]; }; MyDontCorrect: PROC [context: Context, action: PROC, saveCP: BOOL] ~ { SIGNAL Cant[$Correct]; IF saveCP THEN Imager.DoSaveAll[context, action] ELSE Imager.DoSave[context, action]; }; RasterMaskStroke: PROC [context: Context, path: PathProc, closed: BOOL] ¬ NIL; MyMaskStroke: PROC [context: Context, path: PathProc, closed: BOOL] ~ { IF ImagerState.StateGetInt[context, strokeEnd] = INT.LAST OR ImagerState.StateGetInt[context, strokeJoint] = INT.LAST OR ImagerState.StateGetReal[context, strokeWidth] = nullReal THEN ERROR Cant[$UninitializedState]; RasterMaskStroke[context, path, closed]; }; MyGetBounds: PROC [context: Context] RETURNS [Rectangle] ~ {ERROR Cant[$GetBounds]}; deviceClass: ImagerDevice.DeviceClass ~ NEW[ImagerDevice.DeviceClassRep ¬ [ SetColor: CaptureSetColor, MaskBoxes: CaptureMaskBoxes ]]; contextClass: ImagerPrivate.Class ~ MakeClass[]; MakeClass: PROC RETURNS [ImagerPrivate.Class] ~ { new: ImagerPrivate.Class ~ ImagerRaster.CreateClass[type: $Capture]; new.SetT ¬ MySetT; new.GetInt ¬ MyGetInt; new.GetReal ¬ MyGetReal; new.GetFont ¬ MyGetFont; new.GetColor ¬ MyGetColor; new.GetClipper ¬ MyGetClipper; new.Space ¬ MySpace; RasterMaskUnderline ¬ new.MaskUnderline; new.MaskUnderline ¬ MyMaskUnderline; RasterShow ¬ new.Show; new.Show ¬ MyShow; new.Correct ¬ MyCorrect; new.DontCorrect ¬ MyDontCorrect; RasterMaskStroke ¬ new.MaskStroke; new.MaskStroke ¬ MyMaskStroke; new.GetBounds ¬ MyGetBounds; RETURN [new] }; END. z ImagerMaskCaptureImpl.mesa Copyright Σ 1986, 1987, 1989, 1990, 1991 by Xerox Corporation. All rights reserved. Michael Plass, October 11, 1991 1:36 pm PDT Russ Atkinson (RRA) September 5, 1990 5:43 pm PDT The view origin away from the origin of device coords. Smaller than 16K to hit integerTrans often. Context Cache Public Procs Device Class Procs Context Class Procs Κ ΰ–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ΟeœI™TK™+K™1—K˜šΟk ˜ KšœžœW˜cKšœžœ=˜QKšœ žœ ˜Kšœ žœ0˜AKšœ žœQ˜cKšœ žœ˜%KšœžœK˜`Kšœžœ˜2Kšœžœ˜Kšœžœ ˜Kšœ žœ4˜FKšœ žœ(˜:Kšœ žœ7˜HKšœžœ˜,Kšœžœ˜KšžœžœN˜VKšœžœžœ˜—K˜KšΠblœž ˜$Kšžœaž˜jKšžœ˜šœž˜K˜šœžœžœ˜$K˜—Kšœ žœ˜'Kšœžœžœ˜ Kšœ žœ žœ˜Kšœžœ˜#Kšœžœ žœ˜Kšœžœ˜%Kšœ žœžœ ˜.Kšœ žœ žœ ˜!Kšœ žœ žœ ˜%Kšœ žœ˜'Kšœ žœ žœ ˜&Kšœ žœ˜)Kšœžœ'˜;šžœžœ žœ˜K˜K˜—šœ žœ ˜Kšœ6™6K™+K˜—šœ'žœOžœžœ˜’K˜—Kšœžœžœ ˜šœ žœžœ˜Kšœ žœžœ˜Kšœ žœžœ˜Kšœžœ ˜Kšœ!ž˜$Kšœ˜K˜—šœ žœ˜$K˜—š œžœžœžœžœ˜'K˜—šΟn œžœžœ˜)Kšœ žœ˜ šœB˜BKšœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœ"˜"Kšœ˜Kšœ˜—Kšœ†žœ˜ŒKš œ.žœžœžœžœ˜LKšœ?˜?šžœ žœ ž˜4Kšœ$žœžœ˜.Kšžœ˜—šžœžœ!ž˜6Kšœ/˜/Kšžœ˜—Kšœ%˜%Kšœžœ˜Kšœ˜Kšžœ ˜Kšœ˜——head™ šœ žœ%˜HK˜—š  œžœžœ˜HKšœ˜Kšžœ žœžœ˜0Kšžœžœžœ ˜8Kšœ=˜=Kšœ˜K˜—Kšœžœ˜Kšœžœ˜š   œžœžœžœžœ˜?Kšžœžœžœžœ˜'Kš žœžœžœžœžœ˜,Kšžœ žœ˜Kšœ˜K˜—š  œžœžœžœ˜5Kšžœžœžœžœ˜0Kšœ˜K˜——™ K˜š   œžœžœ žœ7žœžœ ˜zKšœ*˜*K•StartOfExpansionontext: Imager.Context]šœ:˜:Kšœ žœ˜!Kšœžœ5˜?Kšœžœ˜Kšœžœ˜Kšœžœžœ ˜/Kšœ ˜ Kšœ˜Kšžœžœžœžœ+˜LKšœ˜Kšžœ˜ Kšœ˜K˜—š   œžœžœ žœ*žœžœ˜ŽKšœS˜Sš žœžœžœžœžœžœž˜;Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜K˜—š   œžœžœ žœ+žœžœ˜ŠKšœS˜SKšœN˜NKšœ˜š žœžœžœžœžœžœž˜;K–α[map: IISample.SampleMap, box: SF.Box _ [min: [s: -32768, f: -32768], max: [s: 32767, f: 32767]], value: IISample.Sample _ 177777B (65535), function: IISample.Function _ [dstFunc: null, srcFunc: null]]šœ:˜:Kšžœ˜—Kšœ˜Kšžœ ˜Kšœ˜K˜—š œžœžœ žœ+žœžœžœ˜€Kšœ*˜*K–ontext: Imager.Context]šœ:˜:Kšœ žœ˜!Kšœžœ5˜?Kšœžœ˜Kšœ˜Kšœžœžœ ˜/Kšœ žœ˜Kšœ ˜ Kšœ<˜žœžœ˜eKšœ$˜$Kšœ˜K˜—š  œžœžœ˜4Kšžœ˜Kšœ"˜"Kšœ˜K˜—š  œžœžœ žœ˜FKšžœ˜Kšžœžœ#žœ ˜UKšœ˜K˜—Kš œžœ,žœžœ˜Nš  œžœ,žœ˜GKšžœ/žœžœžœ1žœžœžœ;žœžœ˜ΨKšœ(˜(Kšœ˜K˜—š  œžœžœžœ˜TK˜—šœ)žœ ˜LKš œ˜Kš  œ˜Kšœ˜K˜—Kšœ0˜0š  œžœžœ˜1KšœD˜DKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ(˜(Kšœ$˜$Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ"˜"Kšœ˜Kšœ˜Kšžœ˜ Kšœ˜—K˜—K˜Kšžœ˜K˜—…—%ς4L