DIRECTORY Imager USING [Error, Context], ImagerBasic USING [DeviceRectangle, Color, ConstantColor], ImagerDisplay USING [DisplayClass, DisplayClassRep, DisplayData, CreateImagerClass], ImagerStdColorDisplay USING [SetUpMapProc, CachedColorProc, Create, ApplyMask, LoadColorMap, LoadColorProc, DoUnderLock, ColorMapData, MoveOverlay, ColorSequence, PinPixelMap, ReleasePixelMap ], ImagerMasks USING [Mask], ImagerPrivate USING [Class, RegisterDevice], ColorModels USING [Calibration], ConstantColors USING [ColorToRGB, NameToColor, 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]; ImagerStd8BitDisplayImpl: CEDAR MONITOR IMPORTS Imager, ImagerDisplay, ImagerPrivate, ConstantColors, Terminal, Real, Atom, ImagerStdColorDisplay, RealFns ~ BEGIN DisplayClass: TYPE ~ ImagerDisplay.DisplayClass; DisplayClassRep: TYPE ~ ImagerDisplay.DisplayClassRep; DisplayData: TYPE ~ ImagerDisplay.DisplayData; Color: TYPE ~ ImagerBasic.Color; ConstantColor: TYPE ~ ImagerBasic.ConstantColor; Mask: TYPE ~ ImagerMasks.Mask; on: BOOLEAN ~ TRUE; off: BOOLEAN ~ FALSE; bitsPerPixel: NAT ~ 10; colorAccuracy: NAT ~ 8192; vt: Terminal.Virtual; mode: Terminal.ColorMode ~ [full: FALSE, bitsPerPixelChannelA: 8, bitsPerPixelChannelB: 2]; std8BitDisplayClass: ImagerDisplay.DisplayClass ~ NEW[ImagerDisplay.DisplayClassRep _ [ displayType: $Std8bpp, 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 _ NIL] 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 ]; -- reload color map and cache it ENDCASE => Imager.Error[$UnimplementedSpecialOp]; RETURN[ NIL ]; }; SetUpColorMap: ImagerStdColorDisplay.SetUpMapProc ~ { color: ConstantColor ~ ConstantColors.NameToColor["Very Weak Light Green"]; -- pea green colorData: REF ImagerStdColorDisplay.ColorMapData _ NARROW[displayData.cachedColorData]; colorMap: REF ImagerStdColorDisplay.ColorSequence _ NEW[ImagerStdColorDisplay.ColorSequence[256]]; FOR i: NAT IN [0..256) DO colorMap[i] _ color; -- set primary map pea green ENDLOOP; colorMap[0] _ ConstantColors.black; colorMap[255] _ ConstantColors.white; colorMap[1] _ ConstantColors.red; colorMap[254] _ ConstantColors.cyan; colorMap[2] _ ConstantColors.green; colorMap[253] _ ConstantColors.magenta; colorMap[3] _ ConstantColors.blue; colorMap[252] _ ConstantColors.yellow; colorMap[4] _ ConstantColors.orange; colorMap[251] _ ConstantColors.purple; colorMap[5] _ ConstantColors.brown; colorMap[250] _ ConstantColors.grey; colorMap[6] _ ConstantColors.darkGrey; colorMap[249] _ ConstantColors.veryLightGrey; colorMap[7] _ ConstantColors.lightGrey; colorMap[248] _ ConstantColors.veryDarkGrey; colorData.nextEntry _ 8; colorData.map _ colorMap; -- plug the map into the colorData record IF Atom.GetPropFromList[displayData.props, $PixelMapStatus] = $Displayed THEN FOR i: NAT IN [0..256) DO LoadColor[colorData.map[i], colorData.colorCalibration, i]; ENDLOOP; }; LoadColor: ImagerStdColorDisplay.LoadColorProc ~ { r, g, b: REAL; mr, mg, mb: [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]]; mr _ Real.FixC[255.0 * RealFns.Power[r, .43]]; mg _ Real.FixC[255.0 * RealFns.Power[g, .43]]; mb _ Real.FixC[255.0 * RealFns.Power[b, .43]]; vt.SetColor[ mapEntry, 3, 255, 255, 255]; -- set 4th map white vt.SetColor[ mapEntry, 2, 0, 0, 0]; -- set 3rd map black vt.SetColor[ mapEntry, 1, 255 - mr, 255 - mg, 255 - mb]; -- set inverted color in 2nd map vt.SetColor[ mapEntry, 0, mr, mg, mb]; }; 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) AND (colorData.nextEntry < 248) THEN { colorData.pixelValueList _ LIST[ colorData.nextEntry ]; colorData.map[colorData.nextEntry] _ constantColor; IF Atom.GetPropFromList[displayData.props, $PixelMapStatus] = $Displayed THEN LoadColor[constantColor, colorData.colorCalibration, colorData.nextEntry]; colorData.nextEntry _ colorData.nextEntry + 1; displayData.cachedColor _ color; }; IF displayData.cachedColor = NIL THEN { minDist, minIndex: INT _ LAST[INT]; -- min. summed-squares distance in CIE 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[] ~ { std8BitImagerClass: ImagerPrivate.Class ~ ImagerDisplay.CreateImagerClass[std8BitDisplayClass]; -- pick up Imager class record std8BitImagerClass.SpecialOp _ SpecialOp; -- modify procedure bindings ImagerPrivate.RegisterDevice[std8BitImagerClass]; -- register device class vt _ Terminal.Current[]; }; Init[]; END. 2ImagerStd8BitDisplayImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Frank Crow, April 19, 1984 3:39:45 pm PST This implements an 8-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. If not there, enter in cache and set the color map if this context currently displayed Not in color map, enter it if there is room Failed completely, find closest color Κ,˜Ihead1™šœ Οmœ1™Ÿ˜SJšœ>˜>Jšœ žœ*˜˜>Jšžœ˜——Jšœ˜J˜—š  œ)˜2JšžœX™\Jšœ žœ˜Jšœ˜Jšœ?˜?Jš œžœžœžœžœžœžœ ˜WJšœ1˜1Jšœ/˜/Jšœ.˜.Jšœ/Ÿ˜CJšœ$Ÿ˜?Jšœ9Ÿ ˜YJšœ&˜&Jšœ˜J˜—šΟb œ+˜5Jšžœ)™-J™ŒJšœ žœ&žœ˜XJšœžœ˜šžœžœž˜šœ!˜!š žœžœžœžœžœžœ˜NJšœžœ˜%Jšœ"Ÿ˜?J˜Jšžœ˜—š žœžœžœžœžœžœž˜Pšž œ žœžœŸ)˜ZJšžœ&˜)Jšžœžœžœ˜+—šžŸ%˜,Jšœžœ˜%Jšœ ˜ J˜—Jšžœ˜JšŸ+™+—šžœžœžœžœ˜JJšœžœ˜7Jšœ3˜3šžœG˜IJšžœK˜O—Jšœ.˜.Jšœ ˜ J˜JšŸ%™%—šžœžœžœ˜'JšœžœžœžœŸ,˜Pšžœžœžœž˜*Jšœžœžœ˜Jšžœ˜—šžœžœ˜!Jšœžœ ˜,Jšœ ˜ J˜—Jšœ˜—Jšœ˜—Jšžœ(˜/Jšžœžœžœ Ÿ ˜O—Jšœ˜J˜—š œžœ˜Jšœ`Ÿ˜Jšœ-Ÿ˜JJšœ3Ÿ˜LMšœ˜J˜J˜—˜J˜—Jšžœ˜—…—ͺ'