DIRECTORY Imager USING [Error, Context], ImagerBasic USING [DeviceRectangle, Color, ColorRep], ImagerDisplay USING [DisplayClass, DisplayClassRep, DisplayData, CreateImagerClass], ImagerStdColorDisplay USING [SetUpMapProc, CachedColorProc, Create, ApplyMask, LoadColorMap, DoUnderLock, ColorMapData, MoveOverlay, ColorSequence, PinPixelMap, ReleasePixelMap, LoadColorProc], ImagerMasks USING [Mask], ImagerPrivate USING [Class, RegisterDevice], ColorModels USING [Calibration], ConstantColors USING [ColorToRGB, black, white, red, cyan, green, magenta, blue, yellow, orange, purple, brown, grey, darkGrey, veryLightGrey, lightGrey, veryDarkGrey], Terminal USING [ColorMode, Current, SetColor, Virtual], Atom USING [GetPropFromList], Real USING [FixC], RealFns USING [Power]; ImagerStd4BitDisplayImpl: CEDAR MONITOR IMPORTS Imager, ImagerDisplay, ImagerPrivate, ConstantColors, Terminal, Real, RealFns, Atom, ImagerStdColorDisplay ~ BEGIN DisplayClass: TYPE ~ ImagerDisplay.DisplayClass; DisplayClassRep: TYPE ~ ImagerDisplay.DisplayClassRep; DisplayData: TYPE ~ ImagerDisplay.DisplayData; Color: TYPE ~ ImagerBasic.Color; ColorRep: TYPE ~ ImagerBasic.ColorRep; ConstantColor: TYPE = REF ColorRep.constant; Mask: TYPE ~ ImagerMasks.Mask; on: BOOLEAN ~ TRUE; off: BOOLEAN ~ FALSE; bitsPerPixel: NAT _ 6; colorAccuracy: NAT ~ 8192; vt: Terminal.Virtual; mode: Terminal.ColorMode ~ [full: FALSE, bitsPerPixelChannelA: 4, bitsPerPixelChannelB: 2]; std4BitDisplayClass: ImagerDisplay.DisplayClass ~ NEW[ImagerDisplay.DisplayClassRep _ [ displayType: $Std4bpp, viewUnitsPerPixel: 1, Create: Create, ApplyMask: ApplyMask, DoUnderLock: ImagerStdColorDisplay.DoUnderLock ]]; ColorDisplayError: PUBLIC ERROR [reason: ATOM] ~ CODE; Sqr: PROCEDURE [number: INT] RETURNS [INT] ~ INLINE { RETURN[number * number]; }; Create: PROC [displayClass: DisplayClass, creationData: REF] RETURNS [displayData: DisplayData] ~ { displayData _ ImagerStdColorDisplay.Create[ vt, mode, displayClass, creationData, bitsPerPixel, SetUpColorMap]; }; ApplyMask: PROC [displayData: DisplayData, color: Color, mask: Mask, sTranslate, fTranslate: INTEGER] ~ { ImagerStdColorDisplay.ApplyMask[displayData, color, mask, sTranslate, fTranslate, CacheColor]; }; SpecialOp: PROC[context: Imager.Context, op: ATOM, data: REF] RETURNS[REF] ~ { SELECT op FROM $DisplayContext => { -- Pin a pixel map to the color display, replace what was there before. ImagerStdColorDisplay.PinPixelMap[vt, NARROW[context.data, ImagerDisplay.DisplayData], mode ]; }; $UnDisplayContext => ImagerStdColorDisplay.ReleasePixelMap[vt, NARROW[context.data, ImagerDisplay.DisplayData]]; $MoveOverlay => ImagerStdColorDisplay.MoveOverlay[vt, data]; -- change DCB offsets $LoadColorMap => ImagerStdColorDisplay.LoadColorMap[vt, data, NARROW[context.data, ImagerDisplay.DisplayData], LoadColor ]; ENDCASE => Imager.Error[$UnimplementedSpecialOp]; RETURN[ NIL ]; }; SetUpColorMap: ImagerStdColorDisplay.SetUpMapProc ~ { colorData: REF ImagerStdColorDisplay.ColorMapData _ NARROW[displayData.cachedColorData]; colorMap: REF ImagerStdColorDisplay.ColorSequence _ NEW[ImagerStdColorDisplay.ColorSequence[16]]; colorMap[0] _ ConstantColors.black; colorMap[15] _ ConstantColors.white; colorMap[1] _ ConstantColors.red; colorMap[14] _ ConstantColors.cyan; colorMap[2] _ ConstantColors.green; colorMap[13] _ ConstantColors.magenta; colorMap[3] _ ConstantColors.blue; colorMap[12] _ ConstantColors.yellow; colorMap[4] _ ConstantColors.orange; colorMap[11] _ ConstantColors.purple; colorMap[5] _ ConstantColors.brown; colorMap[10] _ ConstantColors.grey; colorMap[6] _ ConstantColors.darkGrey; colorMap[ 9] _ ConstantColors.veryLightGrey; colorMap[7] _ ConstantColors.lightGrey; colorMap[ 8] _ ConstantColors.veryDarkGrey; colorData.map _ colorMap; -- plug the map into the colorData record IF Atom.GetPropFromList[displayData.props, $PixelMapStatus] = $Displayed THEN FOR i: NAT IN [0..16) DO LoadColor[colorData.map[i], colorData.colorCalibration, i]; ENDLOOP; }; LoadColor: ImagerStdColorDisplay.LoadColorProc ~ { r, g, b: REAL; nr, ng, nb: [0..256); [r, g, b] _ ConstantColors.ColorToRGB[color, colorCalibration]; r _ MIN[1.0, MAX[0.0, r]]; g _ MIN[1.0, MAX[0.0, g]]; b _ MIN[1.0, MAX[0.0, b]]; nr _ Real.FixC[255.0 * RealFns.Power[r, .43]]; ng _ Real.FixC[255.0 * RealFns.Power[g, .43]]; nb _ Real.FixC[255.0 * RealFns.Power[b, .43]]; vt.SetColor[ mapEntry, 0, nr, ng, nb]; }; CacheColor: ImagerStdColorDisplay.CachedColorProc ~ { colorData: REF ImagerStdColorDisplay.ColorMapData _ NARROW[displayData.cachedColorData]; displayData.cachedColor _ NIL; WITH color SELECT FROM constantColor: ConstantColor => { FOR i: NAT IN [0..colorData.map.length) DO IF color = colorData.map[i] THEN { colorData.pixelValueList _ LIST[ i ]; displayData.cachedColor _ color; -- already in colormap }; ENDLOOP; IF displayData.cachedColor = NIL THEN FOR i: NAT IN [0..colorData.map.length) DO IF constantColor.x = colorData.map[i].x -- check if identical to a previous color AND constantColor.y = colorData.map[i].y AND constantColor.Y = colorData.map[i].Y THEN { -- already in colormap colorData.pixelValueList _ LIST[ i ]; displayData.cachedColor _ color; }; ENDLOOP; IF displayData.cachedColor = NIL THEN { minDist, minIndex: INT _ LAST[INT]; -- min. summed-squares distance in r, g, b space FOR i: NAT IN [0..colorData.map.length) DO dist: INT _ Sqr[constantColor.x - INT[colorData.map[i].x]] + Sqr[constantColor.y - INT[colorData.map[i].y]] + Sqr[constantColor.Y - INT[colorData.map[i].Y]]; IF dist < minDist THEN { minIndex _ i; minDist _ dist; }; ENDLOOP; IF minDist < colorAccuracy THEN { colorData.pixelValueList _ LIST[ minIndex ]; displayData.cachedColor _ color; }; }; }; ENDCASE => Imager.Error[$UnsupportedColorType]; IF displayData.cachedColor = NIL THEN Imager.Error[$CantMatchColor]; -- sorry! }; Init: PROC[] ~ { std4BitImagerClass: ImagerPrivate.Class ~ ImagerDisplay.CreateImagerClass[std4BitDisplayClass]; -- pick up Imager class record std4BitImagerClass.SpecialOp _ SpecialOp; -- modify procedure bindings ImagerPrivate.RegisterDevice[std4BitImagerClass]; -- register device class vt _ Terminal.Current[]; }; Init[]; END. ¬ImagerStd4BitDisplayImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Frank Crow, May 11, 1984 4:43:23 pm PDT This implements a 4-bit-per-pixel color-mapped display with no antialiasing. Maximum summed-squares distance allowed in color matching. Determined by trial to allow hits with 2-level color names (eg. "vivid dark bluish green") PROC[displayData: DisplayData] Set up 16 standard colors so that complements contrast PROC [ color: ConstantColor, colorCalibration: ColorModels.Calibration, mapEntry: [0..256) ] PROC [displayData: DisplayData, color: Color] Check for presence of color in this context's cache. Failed completely, find closest color Κ‹˜Ihead1™šœ Οmœ1™Ÿ˜SJšœ=˜=Jšœ žœ*˜˜>Jšžœ˜——J˜J˜—š  œ)˜2JšžœX™\Jšœ žœ˜Jšœ˜Jšœ?˜?Jš œžœžœžœžœžœžœ ˜WJšœ1˜1Jšœ/˜/Jšœ.˜.Jšœ&˜&Jšœ˜J˜—šΟb œ+˜5Jšžœ)™-J™4Jšœ žœ&žœ˜XJšœžœ˜šžœžœž˜šœ!˜!š žœžœžœžœžœžœ˜NJšœžœ˜%Jšœ"Ÿ˜?J˜Jšžœ˜—š žœžœžœžœžœžœž˜Pšž œ žœžœŸ)˜ZJšžœ žœž˜)Jšžœžœžœ˜+—šžŸ%˜,Jšœžœ˜%Jšœ ˜ J˜—Jšžœ˜—JšŸ%™%—šžœžœžœ˜'JšœžœžœžœŸ0˜Tšžœžœžœž˜*Jšœžœžœ˜Jšžœ˜—šžœžœ˜!Jšœžœ ˜,Jšœ ˜ J˜—Jšœ˜—Jšœ˜Jšžœ(˜/Jšžœžœžœ Ÿ ˜O—Jšœ˜J˜—š œžœ˜Jšœ`Ÿ˜Jšœ-Ÿ˜JJšœ3Ÿ˜LMšœ˜J˜J˜—˜J˜—Jšžœ˜J˜—…—6"m