DIRECTORY Basics USING [bitsPerWord, LongMult], Imager USING [ClassRep, Color, ColorOperator, ConcatT, Context, ContextRep, DoSave, MaskUnderline, PathProc, PixelArray, SetXY, StartUnderline], ImagerBackdoor USING [Clipper, GetCP, IntKey, RealKey], ImagerDevice USING [BoxProc, CharMask, CharMaskRep, Class, ClassRep, Device, DeviceBox, DeviceRep, HalftoneParameters, Run, RunProc], ImagerFont USING [CorrectionType, Font, XChar, XStringProc], ImagerManhattan USING [BoundingBox, CreateFromBox, CreateFromRuns, Destroy, MapRuns, Polygon, Shift, Union], ImagerMask USING [RunsFromBits], ImagerMaskCapture USING [], ImagerPixelMap USING [Clear, Create, CreateFrameBuffer, DeviceRectangle, Fill, PixelMap, ShiftMap], ImagerPrivate USING [ClassRep, StrokeDashes], ImagerRaster USING [Create], ImagerTransformation USING [Rectangle, Transformation, Translate], Real USING [LargestNumber], SafeStorage USING [GetPermanentZone, GetSystemZone], Scaled USING [FromReal], Vector2 USING [VEC]; ImagerMaskCaptureImpl: CEDAR MONITOR IMPORTS Basics, Imager, ImagerRaster, ImagerMask, ImagerManhattan, ImagerTransformation, ImagerPixelMap, ImagerBackdoor, SafeStorage, Scaled EXPORTS ImagerMaskCapture, Imager ~ BEGIN smallestBitmap: NAT _ 10; permanentThreshold: NAT _ 0; PixelMap: TYPE ~ ImagerPixelMap.PixelMap; Manhattan: TYPE ~ ImagerManhattan.Polygon; DeviceBox: TYPE ~ ImagerDevice.DeviceBox; DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle; Class: TYPE ~ REF ClassRep; ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; -- export to Imager.ClassRep Context: TYPE ~ Imager.Context; Color: TYPE ~ Imager.Color; ColorOperator: TYPE ~ Imager.ColorOperator; Device: TYPE ~ ImagerDevice.Device; Font: TYPE ~ ImagerFont.Font; PathProc: TYPE ~ Imager.PathProc; PixelArray: TYPE ~ Imager.PixelArray; Rectangle: TYPE ~ ImagerTransformation.Rectangle; Transformation: TYPE ~ ImagerTransformation.Transformation; VEC: TYPE ~ Vector2.VEC; StrokeDashes: TYPE ~ ImagerPrivate.StrokeDashes; Clipper: TYPE ~ ImagerBackdoor.Clipper; IntKey: TYPE ~ ImagerBackdoor.IntKey; RealKey: TYPE ~ ImagerBackdoor.RealKey; XChar: TYPE ~ ImagerFont.XChar; CorrectionType: TYPE ~ ImagerFont.CorrectionType; CharMask: TYPE ~ ImagerDevice.CharMask; RunProc: TYPE ~ ImagerDevice.RunProc; BoxProc: TYPE ~ ImagerDevice.BoxProc; surfaceOrigin: NAT ~ 10000; DeviceData: TYPE ~ REF DeviceDataRep; DeviceDataRep: TYPE ~ RECORD [ rectangles: Manhattan ]; CreateDevice: PROC RETURNS [Device] ~ { deviceData: DeviceData ~ NEW[DeviceDataRep _ [ rectangles: NIL ]]; device: Device ~ NEW[ImagerDevice.DeviceRep _ [ class: deviceClass, data: deviceData, box: [smin: 0, fmin: 0, smax: 2*surfaceOrigin-1, fmax: 2*surfaceOrigin-1], surfaceToDevice: ImagerTransformation.Translate[[surfaceOrigin, surfaceOrigin]], surfaceUnitsPerInch: [1,1], -- doesn't really matter surfaceUnitsPerPixel: 1 ]]; RETURN [device]; }; deviceClass: ImagerDevice.Class ~ NEW[ImagerDevice.ClassRep _ [ type: $RasterCapture, SetColor: NullSetColor, SetPriority: NullSetPriority, SetHalftone: NullSetHalftone, MaskRuns: MaskRuns, MaskBoxes: MaskBoxes, MaskBits: MaskBits ]]; NullSetColor: PROC[device: Device, color: Color, viewToDevice: Transformation] ~ {}; NullSetPriority: PROC[device: Device, priorityImportant: BOOL] ~ {}; NullSetHalftone: PROC[device: Device, halftone: ImagerDevice.HalftoneParameters] ~ {}; MaskManhattan: PROC[device: Device, addition: Manhattan] ~ { deviceData: DeviceData ~ NARROW[device.data]; new: Manhattan ~ ImagerManhattan.Union[addition, deviceData.rectangles]; ImagerManhattan.Destroy[addition]; ImagerManhattan.Destroy[deviceData.rectangles]; deviceData.rectangles _ new; }; MaskRuns: PROC[device: Device, bounds: DeviceBox, runs: PROC[RunProc]] ~ { Runs: PROC[run: RunProc, repeat: PROC[NAT]] ~ {runs[run]}; MaskManhattan[device, ImagerManhattan.CreateFromRuns[Runs]]; }; MaskBoxes: PROC[device: Device, bounds: DeviceBox, boxes: PROC[BoxProc]] ~ { Box: PROC[b: DeviceBox] ~ { MaskManhattan[device, ImagerManhattan.CreateFromBox[[b.smin, b.fmin, b.smax-b.smin, b.fmax-b.fmin]]]; }; boxes[Box]; }; MaskBits: PROC[device: Device, srcBase: LONG POINTER, srcWordsPerLine: NAT, ts, tf: INTEGER, boxes: PROC[BoxProc]] ~ { Box: PROC[b: DeviceBox] ~ { ManhattanRuns: PROC[run: RunProc, repeat: PROC[NAT]] ~ { ImagerMask.RunsFromBits[ base: srcBase, wordsPerLine: srcWordsPerLine, sBits: b.smin-ts, fBits: b.fmin-tf, sSize: b.smax-b.smin, fSize: b.fmax-b.fmin, sRuns: b.smin, fRuns: b.fmin, run: run ]; }; MaskManhattan[device, ImagerManhattan.CreateFromRuns[ManhattanRuns]]; }; boxes[Box]; }; CreateContext: PROC RETURNS [Context] ~ { ctxData: CtxData ~ NEW[CtxDataRep]; device: Device ~ CreateDevice[]; ctxData.rasterContext _ ImagerRaster.Create[device: device, pixelUnits: TRUE, fontCache: NIL]; ctxData.deviceData _ NARROW[device.data]; ctxData.smin _ ctxData.fmin _ Real.LargestNumber; ctxData.smax _ ctxData.smax _ -Real.LargestNumber; RETURN [NEW[Imager.ContextRep _ [class: captureClass, state: NIL, data: ctxData]]]; }; c1: Context _ NIL; c2: Context _ NIL; GetContext: ENTRY PROC RETURNS [context: Context] ~ { IF c1#NIL THEN {context _ c1; c1 _ NIL} ELSE IF c2#NIL THEN {context _ c2; c2 _ NIL} ELSE context _ CreateContext[]; }; FreeContext: ENTRY PROC [context: Context] ~ { ctxData: CtxData ~ NARROW[context.data]; rasterContext: Context ~ ctxData.rasterContext; deviceData: DeviceData ~ ctxData.deviceData; ctxData^ _ [rasterContext: rasterContext, deviceData: deviceData, firstFont: NIL, firstChar: [0,0], smin: Real.LargestNumber, fmin: Real.LargestNumber, smax: Real.LargestNumber, fmax: -Real.LargestNumber]; deviceData.rectangles _ NIL; IF c1=NIL THEN {c1 _ context} ELSE c2 _ context; }; GetRectangles: PROC [context: Context] RETURNS [p: Manhattan] ~ { ctxData: CtxData ~ NARROW[context.data]; p _ ctxData.deviceData.rectangles; ctxData.deviceData.rectangles _ NIL; }; RasterCharMaskFromManhattan: PROC [p: Manhattan, bb: DeviceRectangle] RETURNS [mask: REF ImagerDevice.CharMaskRep.raster] ~ TRUSTED { rast: NAT ~ (bb.fSize+(Basics.bitsPerWord-1))/Basics.bitsPerWord; bitmapWords: LONG CARDINAL ~ Basics.LongMult[bb.sSize, rast]; pixelMap: PixelMap; zone: ZONE ~ IF bitmapWords < permanentThreshold THEN SafeStorage.GetPermanentZone[] ELSE SafeStorage.GetSystemZone[]; IF bitmapWords > NAT.LAST THEN RETURN [NIL]; mask _ NEW[ImagerDevice.CharMaskRep.raster[MAX[NAT[bitmapWords], smallestBitmap]]]; mask.flag _ ALL[0]; IF bb.sSize = 0 OR bb.fSize = 0 THEN { mask.sMinBB _ mask.fMinBB _ mask.sSizeBB _ mask.fSizeBB _ 0; } ELSE { mask.sMinBB _ INTEGER[bb.sMin]-surfaceOrigin; mask.fMinBB _ INTEGER[bb.fMin]-surfaceOrigin; mask.sSizeBB _ bb.sSize; mask.fSizeBB _ bb.fSize; }; pixelMap _ ImagerPixelMap.CreateFrameBuffer[pointer: @mask[0], words: bitmapWords, lgBitsPerPixel: 0, rast: rast, lines: bb.sSize, ref: mask]; pixelMap _ pixelMap.ShiftMap[bb.sMin, bb.fMin]; pixelMap.Clear[]; WHILE p # NIL DO pixelMap.Fill[p.first, 1]; p _ p.rest; ENDLOOP; }; RunsCharMaskFromManhattan: PROC [p: Manhattan, bb: DeviceRectangle, nRuns: INT] RETURNS [mask: REF ImagerDevice.CharMaskRep.runs] ~ { i: NAT _ 0; s: NAT _ 0; sMinBB: INTEGER ~ INTEGER[bb.sMin]-surfaceOrigin; fMinBB: INTEGER ~ INTEGER[bb.fMin]-surfaceOrigin; Run: PROC [sMin, fMin: INTEGER, fSize: NAT] ~ { smin: NAT ~ sMin-sMinBB-surfaceOrigin; fmin: NAT ~ fMin-fMinBB-surfaceOrigin; IF smin # s THEN { mask[i-1].lastRun _ TRUE; s _ s + 1; WHILE smin > s DO mask[i] _ [fMin: 0, lastRun: TRUE, fSize: 0]; i _ i + 1; s _ s + 1; ENDLOOP; }; mask[i] _ [fMin: fmin, lastRun: FALSE, fSize: fSize]; i _ i + 1; }; IF nRuns = 0 OR nRuns > NAT.LAST/2 THEN RETURN [NIL]; mask _ NEW[ImagerDevice.CharMaskRep.runs[nRuns]]; mask.flag _ ALL[0]; mask.sMinBB _ sMinBB; mask.fMinBB _ fMinBB; mask.sSizeBB _ bb.sSize; mask.fSizeBB _ bb.fSize; ImagerManhattan.MapRuns[p, Run]; IF i#nRuns THEN ERROR; IF s+1 # bb.sSize THEN ERROR; mask[i-1].lastRun _ TRUE; }; CountRuns: PROC [p: Manhattan] RETURNS [runs: INT _ 0] ~ { s: INTEGER _ IF p # NIL THEN p.first.sMin ELSE 0; WHILE p # NIL DO sMin: INTEGER ~ p.first.sMin; sSize: INTEGER ~ p.first.sSize; IF sMin > s THEN {runs _ runs + (sMin - s)}; s _ sMin+sSize; runs _ runs + sSize; p _ p.rest; ENDLOOP; }; Capture: PUBLIC PROC [operator: PROC[Context], m: Transformation, r: REAL] RETURNS [charMask: CharMask _ NIL] ~ { context: Context ~ GetContext[]; ctxData: CtxData ~ NARROW[context.data]; complete: BOOL _ TRUE; proc: PROC ~ { Imager.ConcatT[context, m]; operator[context ! Cant => {complete _ FALSE; CONTINUE}]; }; Imager.SetXY[context, [0,0]]; Imager.DoSave[context, proc]; IF NOT complete THEN { ImagerManhattan.Destroy[GetRectangles[context]]; } ELSE { width: VEC _ ImagerBackdoor.GetCP[ctxData.rasterContext]; p: Manhattan ~ GetRectangles[context]; IF ABS[width.x] <= 16383.0 AND ABS[width.y] <= 16383.0 THEN { bb: DeviceRectangle ~ ImagerManhattan.BoundingBox[p]; bitmapWords: REAL ~ REAL[bb.sSize]*REAL[(bb.fSize+15)/16]; nRuns: INT ~ CountRuns[p]; charMask _ ( IF nRuns*2*r >= bitmapWords THEN RasterCharMaskFromManhattan[p, bb] ELSE RunsCharMaskFromManhattan[p, bb, nRuns]); IF charMask#NIL THEN { charMask.amplified _ ctxData.amplified; charMask.correction _ ctxData.correction; charMask.metricsValid _ TRUE; charMask.sWidth _ Scaled.FromReal[width.x]; charMask.fWidth _ Scaled.FromReal[width.y]; }; }; ImagerManhattan.Destroy[p]; }; FreeContext[context]; }; CaptureBounds: PUBLIC PROC [operator: PROC[Context], m: Transformation] RETURNS [Rectangle] ~ { p: Manhattan _ CaptureManhattan[operator, m ! Cant => { SELECT why FROM $GetT, $GetColor, $GetClipper, $GetBoundingRectangle => REJECT; ENDCASE => RESUME; }]; d: DeviceRectangle ~ ImagerManhattan.BoundingBox[p]; ImagerManhattan.Destroy[p]; RETURN [[x: d.sMin, y: d.fMin, w: d.sSize, h: d.fSize]] }; CaptureManhattan: PUBLIC PROC [operator: PROC[Context], m: Transformation] RETURNS [p: Manhattan _ NIL] ~ { context: Context ~ GetContext[]; ctxData: CtxData ~ NARROW[context.data]; complete: BOOL _ TRUE; proc: PROC ~ { Imager.ConcatT[context, m]; operator[context]; }; Imager.SetXY[context, [0,0]]; Imager.DoSave[context, proc]; p _ GetRectangles[context]; ImagerManhattan.Shift[p, -surfaceOrigin, -surfaceOrigin]; FreeContext[context]; }; CaptureRuns: PUBLIC PROC [operator: PROC[Context], m: Transformation, run: RunProc] ~ { p: Manhattan _ CaptureManhattan[operator, m]; ImagerManhattan.MapRuns[p, run]; ImagerManhattan.Destroy[p]; }; CaptureBitmap: PUBLIC PROC [operator: PROC[Context], m: Transformation] RETURNS [pixelMap: PixelMap] ~ { p: Manhattan _ CaptureManhattan[operator, m]; pixelMap _ ImagerPixelMap.Create[0, p.BoundingBox]; pixelMap.Clear; FOR t: Manhattan _ p, t.rest UNTIL t = NIL DO pixelMap.Fill[t.first, 1]; ENDLOOP; ImagerManhattan.Destroy[p]; }; OK: TYPE ~ RECORD [ int: PACKED ARRAY IntKey OF BOOL _ ALL[FALSE], real: PACKED ARRAY RealKey OF BOOL _ ALL[FALSE], font: BOOL _ FALSE, strokeDashes: BOOL _ FALSE ]; CtxData: TYPE ~ REF CtxDataRep; CtxDataRep: TYPE ~ RECORD [ rasterContext: Context, deviceData: DeviceData, ok: OK, amplified: BOOLEAN _ FALSE, correction: CorrectionType _ none, nChars: INT _ 0, firstFont: REF, firstChar: XChar, smin, fmin, smax, fmax: REAL ]; Cant: PUBLIC SIGNAL [why: ATOM] ~ CODE; MyDoSave: PROC[context: Context, action: PROC, all: BOOL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; ok: OK ~ ctxData.ok; class.DoSave[ctxData.rasterContext, action, all ! UNWIND => {ctxData.ok _ ok}]; ctxData.ok _ ok; }; MySetInt: PROC[context: Context, key: IntKey, val: INT] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; ctxData.ok.int[key] _ TRUE; class.SetInt[context: ctxData.rasterContext, key: key, val: val]; }; MySetReal: PROC[context: Context, key: RealKey, val: REAL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; ctxData.ok.real[key] _ TRUE; class.SetReal[context: ctxData.rasterContext, key: key, val: val]; }; MySetT: PROC[context: Context, m: Transformation] ~ {SIGNAL Cant[$SetT]}; MySetFont: PROC[context: Context, font: Font] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; ctxData.ok.font _ TRUE; class.SetFont[ctxData.rasterContext, font]; }; MySetColor: PROC[context: Context, color: Color] ~ {SIGNAL Cant[$SetColor]}; MySetClipper: PROC[context: Context, clipper: Clipper] ~ {SIGNAL Cant[$SetClipper]}; MySetStrokeDashes: PROC[context: Context, strokeDashes: StrokeDashes] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; ctxData.ok.strokeDashes _ TRUE; class.SetStrokeDashes[ctxData.rasterContext, strokeDashes]; }; MyGetInt: PROC[context: Context, key: IntKey] RETURNS[INT] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF NOT ctxData.ok.int[key] THEN SIGNAL Cant[$UninitializedState]; RETURN [class.GetInt[ctxData.rasterContext, key]]; }; MyGetReal: PROC[context: Context, key: RealKey] RETURNS[REAL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF key=amplifySpace AND NOT ctxData.ok.real[key] THEN { ctxData.amplified _ TRUE; RETURN [1.0]; }; IF NOT ctxData.ok.real[key] THEN SIGNAL Cant[$UninitializedState]; RETURN [class.GetReal[ctxData.rasterContext, key]]; }; MyGetT: PROC[context: Context] RETURNS[Transformation] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; RETURN [class.GetT[ctxData.rasterContext]]; }; MyGetFont: PROC[context: Context] RETURNS[Font] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF NOT ctxData.ok.font THEN SIGNAL Cant[$UninitializedState]; RETURN [class.GetFont[ctxData.rasterContext]]; }; MyGetColor: PROC[context: Context] RETURNS[Color] ~ {ERROR Cant[$GetColor]}; MyGetClipper: PROC[context: Context] RETURNS[Clipper] ~ {ERROR Cant[$GetClipper]}; MyGetStrokeDashes: PROC[context: Context] RETURNS[StrokeDashes] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF NOT ctxData.ok.strokeDashes THEN SIGNAL Cant[$GetStrokeDashes]; RETURN [class.GetStrokeDashes[ctxData.rasterContext]]; }; MyConcatT: PROC[context: Context, m: Transformation] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.ConcatT[ctxData.rasterContext, m]; }; MyScale2T: PROC[context: Context, s: VEC] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.Scale2T[ctxData.rasterContext, s]; }; MyRotateT: PROC[context: Context, a: REAL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.RotateT[ctxData.rasterContext, a]; }; MyTranslateT: PROC[context: Context, t: VEC] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.TranslateT[ctxData.rasterContext, t]; }; MyMove: PROC[context: Context, rounded: BOOL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.Move[ctxData.rasterContext, rounded]; }; MySetXY: PROC[context: Context, p: VEC] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.SetXY[ctxData.rasterContext, p]; }; MySetXYRel: PROC[context: Context, v: VEC] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.SetXYRel[ctxData.rasterContext, v]; }; MyShow: PROC[context: Context, string: ImagerFont.XStringProc, xrel: BOOL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.Show[ctxData.rasterContext, string, xrel]; }; MyShowText: PROC[context: Context, text: REF READONLY TEXT, start, len: NAT, xrel: BOOL]~{ ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.ShowText[ctxData.rasterContext, text, start, len, xrel]; }; MyGetCP: PROC[context: Context, rounded: BOOL] RETURNS[VEC] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; RETURN [class.GetCP[ctxData.rasterContext, rounded]]; }; MyGetBoundingRectangle: PROC[context: Context] RETURNS [Rectangle] ~ {ERROR Cant[$GetBoundingRectangle]}; MyStartUnderline: PROC[context: Context] ~ { ctxData: CtxData ~ NARROW[context.data]; ctxData.ok.real[underlineStart] _ TRUE; Imager.StartUnderline[ctxData.rasterContext]; }; MyMaskUnderline: PROC[context: Context, dy, h: REAL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF NOT ctxData.ok.real[underlineStart] THEN SIGNAL Cant[$UninitializedState]; Imager.MaskUnderline[ctxData.rasterContext, dy, h]; }; MyCorrectMask: PROC[context: Context] ~ { ctxData: CtxData ~ NARROW[context.data]; IF ctxData.correction#none THEN SIGNAL Cant[$CorrectMask]; ctxData.correction _ mask; }; MyCorrectSpace: PROC[context: Context, v: VEC] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF ctxData.correction#none THEN SIGNAL Cant[$CorrectSpace]; ctxData.correction _ space; class.CorrectSpace[ctxData.rasterContext, v]; }; MySpace: PROC[context: Context, x: REAL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF ctxData.correction#none THEN SIGNAL Cant[$CorrectSpace]; ctxData.correction _ space; class.Space[ctxData.rasterContext, x]; }; MySetCorrectMeasure: PROC[context: Context, v: VEC] ~ {}; MySetCorrectTolerance: PROC[context: Context, v: VEC] ~ {}; MyCorrect: PROC[context: Context, action: PROC] ~ {SIGNAL Cant[$Correct]; MyDoSave[context, action, TRUE]}; MyDontCorrect: PROC[context: Context, action: PROC, saveCP: BOOL] ~ {SIGNAL Cant[$Correct]; MyDoSave[context, action, saveCP]}; MySetGray: PROC[context: Context, f: REAL] ~ {SIGNAL Cant[$SetColor]}; MySetSampledColor: PROC[context: Context, pa: PixelArray, m: Transformation, colorOperator: ColorOperator] ~ {SIGNAL Cant[$SetColor]}; MySetSampledBlack: PROC[context: Context, pa: PixelArray, m: Transformation, clear: BOOL] ~ {SIGNAL Cant[$SetColor]}; MyMaskFill: PROC[context: Context, path: PathProc, parity: BOOL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.MaskFill[ctxData.rasterContext, path, parity]; }; MyMaskRectangle: PROC[context: Context, r: Rectangle] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.MaskRectangle[ctxData.rasterContext, r]; }; MyMaskRectangleI: PROC[context: Context, x, y, w, h: INTEGER] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.MaskRectangleI[ctxData.rasterContext, x, y, w, h]; }; MyMaskStroke: PROC[context: Context, path: PathProc, closed: BOOL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF NOT (ctxData.ok.real[strokeWidth] AND ctxData.ok.int[strokeEnd] AND ctxData.ok.int[strokeJoint] AND ctxData.ok.strokeDashes) THEN SIGNAL Cant[$UninitializedState]; class.MaskStroke[ctxData.rasterContext, path, closed]; }; MyMaskVector: PROC[context: Context, p1, p2: VEC] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; IF NOT (ctxData.ok.real[strokeWidth] AND ctxData.ok.int[strokeEnd] AND ctxData.ok.strokeDashes) THEN SIGNAL Cant[$UninitializedState]; class.MaskVector[ctxData.rasterContext, p1, p2]; }; MyMaskPixel: PROC[context: Context, pa: PixelArray] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.MaskPixel[ctxData.rasterContext, pa]; }; MyMaskBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.MaskBits[ctxData.rasterContext, base, wordsPerLine, sMin, fMin, sSize, fSize, tx, ty]; }; MyClip: PROC[context: Context, path: PathProc, parity: BOOL, exclude: BOOL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.Clip[ctxData.rasterContext, path, parity, exclude]; }; MyClipRectangle: PROC[context: Context, r: Rectangle, exclude: BOOL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.ClipRectangle[ctxData.rasterContext, r, exclude]; }; MyClipRectangleI: PROC[context: Context, x, y, w, h: INTEGER, exclude: BOOL] ~ { ctxData: CtxData ~ NARROW[context.data]; class: Class ~ ctxData.rasterContext.class; class.ClipRectangleI[ctxData.rasterContext, x, y, w, h, exclude]; }; captureClass: Class ~ NEW[ClassRep _ [ type: $Capture, DoSave: MyDoSave, SetInt: MySetInt, SetReal: MySetReal, SetT: MySetT, SetFont: MySetFont, SetColor: MySetColor, SetClipper: MySetClipper, SetStrokeDashes: MySetStrokeDashes, GetInt: MyGetInt, GetReal: MyGetReal, GetT: MyGetT, GetFont: MyGetFont, GetColor: MyGetColor, GetClipper: MyGetClipper, GetStrokeDashes: MyGetStrokeDashes, ConcatT: MyConcatT, Scale2T: MyScale2T, RotateT: MyRotateT, TranslateT: MyTranslateT, Move: MyMove, SetXY: MySetXY, SetXYRel: MySetXYRel, Show: MyShow, ShowText: MyShowText, StartUnderline: MyStartUnderline, MaskUnderline: MyMaskUnderline, CorrectMask: MyCorrectMask, CorrectSpace: MyCorrectSpace, Space: MySpace, SetCorrectMeasure: MySetCorrectMeasure, SetCorrectTolerance: MySetCorrectTolerance, Correct: MyCorrect, DontCorrect: MyDontCorrect, SetGray: MySetGray, SetSampledColor: MySetSampledColor, SetSampledBlack: MySetSampledBlack, MaskFill: MyMaskFill, MaskStroke: MyMaskStroke, MaskRectangle: MyMaskRectangle, MaskRectangleI: MyMaskRectangleI, MaskVector: MyMaskVector, MaskPixel: MyMaskPixel, MaskBits: MyMaskBits, Clip: MyClip, ClipRectangle: MyClipRectangle, ClipRectangleI: MyClipRectangleI, GetCP: MyGetCP, GetBoundingRectangle: MyGetBoundingRectangle, propList: NIL ]]; END. rImagerMaskCaptureImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Michael Plass, March 6, 1986 1:41:58 pm PST Doug Wyatt, May 19, 1985 5:21:35 pm PDT All bitmaps will be at least this big, in an attempt to improve locality. Bitmaps smaller than this will be allocated from the permanent zone. The surface origin away from the origin of device coords, since DeviceBox uses cardinals. Smaller than 16K to hit integerTrans often. This version includes zero-length runs needed to get the PD run representation to work. Assume the operator is a good guy and will use this to amplify the width vector. ΚΞ˜codešœ™Kšœ Οmœ1™Kšœžœ˜(Kšœ+˜+Kšœžœ˜KšœB˜BKšœ˜—Kš‘œžœ)žœ˜Iš‘ œžœ"˜1Kšœžœ˜(Kšœ+˜+Kšœžœ˜Kšœ+˜+Kšœ˜—Kš‘ œžœ$žœ˜LKš‘ œžœ(žœ˜Tš‘œžœ2˜IKšœžœ˜(Kšœ+˜+Kšœžœ˜Kšœ;˜;Kšœ˜—š‘œžœ žœžœ˜>Kšœžœ˜(Kšœ+˜+Kšžœžœžœžœ˜AKšžœ,˜2Kšœ˜—š‘ œžœ!žœžœ˜AKšœžœ˜(Kšœ+˜+šžœžœžœžœ˜7šœžœ˜J™P—Jšžœ˜ Jšœ˜—Kšžœžœžœžœ˜BKšžœ-˜3Kšœ˜—š‘œžœžœ˜:Kšœžœ˜(Kšœ+˜+Kšžœ%˜+Kšœ˜—š‘ œžœžœ ˜3Kšœžœ˜(Kšœ+˜+Kšžœžœžœžœ˜=Kšžœ(˜.Kšœ˜—Kš‘ œžœžœ žœ˜LKš‘ œžœžœ žœ˜Rš‘œžœžœ˜CKšœžœ˜(Kšœ+˜+Kšžœžœžœžœ˜BKšžœ0˜6Kšœ˜—š‘ œžœ)˜8Kšœžœ˜(Kšœ+˜+Kšœ(˜(Kšœ˜—š‘ œžœžœ˜-Kšœžœ˜(Kšœ+˜+Kšœ(˜(Kšœ˜—š‘ œžœžœ˜.Kšœžœ˜(Kšœ+˜+Kšœ(˜(Kšœ˜—š‘ œžœžœ˜0Kšœžœ˜(Kšœ+˜+Kšœ+˜+Kšœ˜—š‘œžœžœ˜1Kšœžœ˜(Kšœ+˜+Kšœ+˜+Kšœ˜—š‘œžœžœ˜+Kšœžœ˜(Kšœ+˜+Kšœ&˜&Kšœ˜—š‘ œžœžœ˜.Kšœžœ˜(Kšœ+˜+Kšœ)˜)Kšœ˜—š‘œžœ9žœ˜NKšœžœ˜(Kšœ+˜+Kšœ0˜0Kšœ˜—š‘ œžœžœžœžœžœžœ˜ZKšœžœ˜(Kšœ+˜+Kšœ>˜>Kšœ˜—š ‘œžœžœžœžœ˜?Kšœžœ˜(Kšœ+˜+Kšžœ/˜5Kšœ˜—Kš‘œžœžœžœ˜iš‘œžœ˜,Kšœžœ˜(Kšœ"žœ˜'Kšœ-˜-Kšœ˜—š‘œžœžœ˜8Kšœžœ˜(Kšœ+˜+Kšžœžœ!žœžœ˜MKšœ3˜3Kšœ˜—š‘ œžœ˜)Kšœžœ˜(Kšžœžœžœ˜:Kšœ˜Kšœ˜—š‘œžœžœ˜2Kšœžœ˜(Kšœ+˜+Kšžœžœžœ˜;Kšœ˜Kšœ-˜-Kšœ˜—š‘œžœžœ˜,Kšœžœ˜(Kšœ+˜+Kšžœžœžœ˜;Kšœ˜Kšœ&˜&Kšœ˜—Kš‘œžœžœ˜9Kš‘œžœžœ˜;Kš ‘ œžœžœžœ+žœ˜kKš ‘ œžœžœ žœžœ4˜Kš‘ œžœžœžœ˜FKš‘œžœXžœ˜‡Kš‘œžœ>žœžœ˜vš‘ œžœ+žœ˜DKšœžœ˜(Kšœ+˜+Kšœ4˜4Kšœ˜—š‘œžœ$˜9Kšœžœ˜(Kšœ+˜+Kšœ.˜.Kšœ˜—š‘œžœžœ˜AKšœžœ˜(Kšœ+˜+Kšœ8˜8Kšœ˜—š‘ œžœ+žœ˜FKšœžœ˜(Kšœ+˜+Kšžœžœžœžœžœžœžœ˜¦Kšœ6˜6Kšœ˜—š‘ œžœžœ˜5Kšœžœ˜(Kšœ+˜+Kš žœžœžœžœžœžœ˜†Kšœ0˜0Kšœ˜—š‘ œžœ&˜7Kšœžœ˜(Kšœ+˜+Kšœ+˜+Kšœ˜—š‘ œžœžœžœžœžœ žœ˜~Kšœžœ˜(Kšœ+˜+Kšœ\˜\Kšœ˜—š‘œžœ+žœ žœ˜OKšœžœ˜(Kšœ+˜+Kšœ9˜9Kšœ˜—š‘œžœ*žœ˜HKšœžœ˜(Kšœ+˜+Kšœ7˜7Kšœ˜—š‘œžœžœ žœ˜PKšœžœ˜(Kšœ+˜+KšœA˜AKšœ˜K˜—šœžœ ˜&Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ'˜'Kšœ+˜+Kšœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ#˜#Kšœ˜Kšœ˜Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ!˜!Kšœ˜Kšœ-˜-Kšœ ž˜ Jšœ˜J˜——Jšžœ˜J˜—…—UpV