DIRECTORY FunctionCache USING [Cache, CompareProc, GlobalCache, Insert, Lookup], ImagerBrick USING [Brick, BrickRep, ThresholdsFromBrick], ImagerColor, ImagerDevice, ImagerDeviceBitmapPrivate USING [Case, Data, DataRep], ImagerMask USING [RunsFromBits, RunsFromBox], ImagerPixelArray, ImagerRaster USING [], ImagerSample, ImagerTransformation, PrincOps, PrincOpsUtils, Real USING [RoundC], Vector2 USING [VEC]; ImagerDeviceBitmapImpl: CEDAR PROGRAM IMPORTS FunctionCache, ImagerBrick, ImagerColor, ImagerDevice, ImagerMask, ImagerPixelArray, ImagerSample, ImagerTransformation, Real EXPORTS ImagerRaster ~ BEGIN OPEN ImagerDevice, ImagerDeviceBitmapPrivate; VEC: TYPE ~ Vector2.VEC; Transformation: TYPE ~ ImagerTransformation.Transformation; Color: TYPE ~ ImagerColor.Color; ConstantColor: TYPE ~ ImagerColor.ConstantColor; SampledColor: TYPE ~ ImagerColor.SampledColor; ColorOperator: TYPE ~ ImagerColor.ColorOperator; PixelArray: TYPE ~ ImagerPixelArray.PixelArray; Sample: TYPE ~ ImagerSample.Sample; SampleBuffer: TYPE ~ ImagerSample.SampleBuffer; SampleMap: TYPE ~ ImagerSample.SampleMap; me: REF TEXT ~ "BitDev"; -- a globally unique REF for use as a clientID in the global cache. classBitmap: ImagerDevice.DeviceClass ~ ImagerDevice.NewClass[ type: $Bitmap, SetColor: SetColorBitmap, SetPriority: SetPriorityBitmap, SetHalftone: SetHalftoneBitmap, MaskBoxes: MaskBoxesBitmap, MaskBits: MaskBitsBitmap, DrawBits: DrawBitsBitmap, MoveBoxes: MoveBoxesBitmap ]; NewBitmapDevice: PUBLIC PROC [frame: SampleMap, pixelsPerInch: REAL] RETURNS [Device] ~ { data: Data ~ NEW[DataRep _ [frame: frame, paToDevice: ImagerTransformation.Scale[0]]]; surfaceToDevice: Transformation ~ ImagerTransformation.XYToSF[ scanMode: [slow: down, fast: right], sSize: frame.size.s, fSize: frame.size.f]; RETURN[NEW[ImagerDevice.DeviceRep _ [class: classBitmap, data: data, box: [min: [0, 0], max: frame.size], surfaceToDevice: surfaceToDevice, surfaceUnitsPerInch: [pixelsPerInch, pixelsPerInch], surfaceUnitsPerPixel: 1 ]]]; }; defaultBrick: ImagerBrick.Brick _ InitDefaultBrick[]; InitDefaultBrick: PROC RETURNS [ImagerBrick.Brick] ~ { brick: ImagerBrick.Brick ~ NEW[ImagerBrick.BrickRep[16] _ [ sSize: 4, fSize: 4, phase: 0, u: 1, v: 1, samples: ]]; Val: PROC[n: [1..16]] RETURNS [REAL] ~ { RETURN[(n-0.5)/16.0] }; brick[00] _ Val[01]; brick[01] _ Val[09]; brick[02] _ Val[03]; brick[03] _ Val[11]; brick[04] _ Val[15]; brick[05] _ Val[05]; brick[06] _ Val[13]; brick[07] _ Val[07]; brick[08] _ Val[04]; brick[09] _ Val[12]; brick[10] _ Val[02]; brick[11] _ Val[10]; brick[12] _ Val[14]; brick[13] _ Val[08]; brick[14] _ Val[16]; brick[15] _ Val[06]; RETURN[brick]; }; stippleTableMax: NAT ~ 16; stippleTable: ARRAY [0..stippleTableMax] OF WORD _ [ 0FFFFH, 07FFFH, 07FDFH, 05FDFH, 05F5FH, 05B5FH, 05B5EH, 05A5EH, 05A5AH, 01A5AH, 01A4AH, 00A4AH, 00A0AH, 0080AH, 00802H, 00002H, 00000H ]; StippleFromIntensity: PROC [Y: REAL] RETURNS [WORD] ~ { IF Y<=0 THEN RETURN[WORD.LAST]; -- black IF Y>=1 THEN RETURN[0]; -- white RETURN[stippleTable[Real.RoundC[Y*stippleTableMax]]]; }; maxSourceSample: Sample ~ 255; SetColorBitmap: PROC[self: Device, color: Color, viewToDevice: Transformation] ~ { data: Data ~ NARROW[self.data]; WITH color SELECT FROM color: ImagerColor.ConstantColor => { Y: REAL ~ ImagerColor.SignalFromColor[color]; stipple: WORD ~ StippleFromIntensity[Y]; IF stipple=WORD.LAST OR stipple=0 THEN { data.value _ IF stipple=0 THEN 0 ELSE 1; data.case _ fill; } ELSE { data.tile _ ImagerSample.TileFromStipple[stipple]; data.s0 _ data.f0 _ 0; data.phase _ 0; data.case _ tile; }; data.function _ [null, null]; data.src _ NIL; }; color: ImagerColor.SampledBlack => { data.tile _ color.pa.MapFromLayer[0]; data.paToDevice.ApplyCat[color.pa.m, color.um, viewToDevice]; data.function _ IF color.clear THEN [or, null] ELSE [null, null]; IF data.srcToDevice.form=3 THEN { data.s0 _ data.f0 _ 0; data.phase _ 0; data.case _ tile; } ELSE data.case _ sampledBlack; }; color: ImagerColor.SampledColor => { maxOut: PixelProc ~ { check: [0..1) ~ i; RETURN[maxSourceSample] }; data.pixelMap _ ImagerColor.Translate[self: color.colorOperator, output: outputIntensity, pa: color.pa, maxOut: maxOut]; data.paToDevice.ApplyCat[color.pa.m, color.um, viewToDevice]; data.case _ sampledColor; }; color: ImagerColor.SpecialColor => SELECT color.type FROM $Invert => { data.value _ 1; data.function _ [xor, null]; data.case _ fill; }; $Stipple => { stipple: StippleData ~ NARROW[color.data]; data.tile _ stipple.tile; data.function _ stipple.function; data.s0 _ data.f0 _ 0; data.phase _ 0; data.case _ tile; }; ENDCASE => SetColorBitmap[self, color.substitute, viewToDevice]; ENDCASE => ERROR; -- unknown color variant }; SetPriorityBitmap: PROC[self: Device, priorityImportant: BOOL] ~ { }; SetHalftoneBitmap: PROC[self: Device, halftone: HalftoneParameters] ~ { data: Data ~ NARROW[self.data]; }; MaskBoxesBitmap: PROC [data: Data, bounds: Box, boxes: BoxGenerator] ~ { SELECT data.case FROM nil => ERROR; -- color not initialized fill => { ImagerSample.FillBoxes[self: data.frame, boxes: boxes, value: data.value, function: data.function]; }; tile => { ImagerSample.TileBoxes[self: data.frame, boxes: boxes, tile: data.src, s0: data.s0, f0: data.f0, phase: data.phase, function: data.function]; }; sampledBlack => { sampledBlackAction: PROC [samples: SampleBuffer, min: Vec] ~ { ImagerSample.PutSamples[self: data.frame, min: min, samples: samples, function: data.function]; }; ImagerSample.Resample[self: data.tile, m: data.srcToDevice, interpolate: FALSE, boxes: boxes, bounds: bounds, action: sampledBlackAction]; }; sampledColor => { sampledColorAction: PROC [samples: SampleBuffer, min: Vec] ~ { ImagerSample.PutSamples[self: data.frame, min: min, samples: samples, function: data.function]; }; ImagerSample.Resample[self: data.src, m: data.srcToDevice, boxes: boxes, bounds: bounds, action: sampledColorAction]; }; ENDCASE => ERROR; -- bogus case }; MaskBitsOp: TYPE ~ {null, set1, set0, neg}; mop1: ARRAY PrincOps.DstFunc OF MaskBitsOp _ [null: set1, and: null, or: set1, xor: neg]; mop0: ARRAY PrincOps.DstFunc OF MaskBitsOp _ [null: set0, and: set0, or: null, xor: null]; MaskBitsBitmap: PROC [self: Device, bounds: Box, boxes: BoxGenerator, mask: SampleMap, offset: Vec] ~ { data: Data ~ NARROW[self.data]; IF data.case=fill THEN { value1: BOOL ~ (data.value MOD 2=0)#(data.function.srcFunc=null); op: MaskBitsOp ~ (IF value1 THEN mop1 ELSE mop0)[data.function.dstFunc]; function: Function _ nullFunction; SELECT op FROM null => NULL; set1 => function _ [dstFunc: or, srcFunc: null]; set0 => function _ [dstFunc: and, srcFunc: complement]; neg => function _ [dstFunc: xor, srcFunc: null]; ENDCASE => ERROR; IF op#null THEN ImagerSample.TransferBoxes[dst: data.frame, src: mask, boxes: boxes, srcOffset: offset, function: function]; } ELSE { bitsToBoxes: BoxGenerator ~ { ImagerMask.BitsToBoxes[mask, offset, boxes] }; MaskBoxesBitmap[self, bitsToBoxes, bounds]; } }; MoveBoxesBitmap: PROC [self: Device, boxes: BoxGenerator, offset: Vec] ~ { data: Data ~ NARROW[self.data]; ImagerSample.MoveBoxes[self: data.frame, boxes: boxes, srcOffset: offset]; }; END. βImagerDeviceBitmapImpl.mesa Copyright c 1984, 1985, 1986 by Xerox Corporation. All rights reserved. Michael Plass, September 16, 1985 3:37:29 pm PDT Doug Wyatt, March 20, 1986 2:50:24 pm PST data.halftone _ halftone; Κ˜˜codešœ™Kšœ Οmœ=™HK™0K™)—K˜šΟk ˜ Kšœžœ3˜FKšœ žœ(˜9Kšœ ˜ Kšœ ˜ Kšœžœ˜6Kšœ žœ˜-Kšœ˜Kšœ žœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœžœ ˜Kšœžœžœ˜—K˜KšΠblœžœž˜%Kšžœ~˜…Kšžœ ˜Kšœžœžœ)˜5K˜Kšžœžœ žœ˜Kšœžœ'˜;Kšœžœ˜ Kšœžœ˜0Kšœžœ˜.Kšœžœ˜0Kšœ žœ˜/Kšœžœ˜#Kšœžœ˜/Kšœ žœ˜)K˜šœžœžœ ΟcC˜\K™—šœ>˜>Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—š Οnœžœžœ#žœžœ ˜ZKšœ žœF˜VKšœŽ˜Žšžœžœ:˜DKšœ$˜$Kšœ!˜!Kšœ4˜4Kšœ˜Kšœ˜—K˜K˜—Kšœ5˜5š‘œžœžœ˜6KšœžœT˜rKš ‘œžœ žœžœžœ˜@K˜SK˜SK˜SK˜SKšžœ˜K˜—K˜Jšœžœ˜šœžœžœžœ˜4JšΟf@˜@Jš’F˜FJ˜J˜—š ‘œžœžœžœžœ˜7Kš žœžœžœžœžœ ˜(Kšžœžœžœ ˜ Kšžœ/˜5K˜K˜—˜K˜—š‘œžœ>˜RKšœ žœ ˜šžœžœž˜˜%Kšœžœ&˜-Kšœ žœ˜(š žœ žœžœžœ žœ˜(Kšœ žœ žœžœ˜(Kšœ˜Kšœ˜—šžœ˜Kšœ2˜2K˜&Kšœ˜Kšœ˜—Kšœ˜Kšœ žœ˜K˜—šœ$˜$Kšœ%˜%Kšœ=˜=Kšœžœ žœ žœ˜Ašžœžœ˜!K˜K˜Kšœ˜K˜—Kšžœ˜K˜—šœ$˜$Kšœ)žœ˜CKšœy˜yKšœ=˜=K˜K˜—šœ#žœ ž˜9˜ K˜K˜K˜K˜—˜ Kšœžœ ˜*K˜K˜!K˜&K˜K˜—Kšžœ9˜@—Kšžœžœ ˜*—Kšœ˜K˜—š‘œžœ"žœ˜BKšœ˜K˜—š‘œžœ0˜GKšœ žœ ˜K™K˜K˜—š‘œžœ3˜Hšžœ ž˜Kšœžœ ˜&˜ K˜dK˜—˜ K˜ŽK˜—˜šœžœ&˜>K˜`K˜—KšœIžœ<˜ŠK˜—˜šœžœ&˜>K˜`K˜—Kšœv˜vK˜—Kšžœžœ  ˜—K˜K˜—Kšœ žœ˜+Kšœžœžœ:˜Yšœžœžœ;˜ZK˜—š‘œžœS˜gKšœ žœ ˜šžœžœ˜Kšœžœžœ#˜AKšœžœžœžœ˜HKšœ"˜"šžœž˜Kšœžœ˜ Kšœ0˜0Kšœ7˜7Kšœ0˜0Kšžœžœ˜—Kšžœ žœn˜}K˜—šžœ˜K˜LK˜+K˜—K˜K˜—š‘œžœ5˜JKšœ žœ ˜KšœJ˜JK˜K˜—K™Kšžœ˜—…—#|