ImagerStd24BitDisplayImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Frank Crow, July 30, 1984 5:50:05 pm PDT
DIRECTORY
Imager    USING [Error, Context],
ImagerBasic   USING [DeviceRectangle, Color, ColorRep],
ImagerDisplay  USING [DisplayClass, DisplayClassRep, DisplayData, CreateImagerClass],
ImagerStdColorDisplay USING [SetUpMapProc, CachedColorProc, Create, ApplyMask,
          PinPixelMap, ReleasePixelMap, LoadColorMap, DoUnderLock,
          ColorMapData, LoadColorProc],
ImagerManhattan USING [Polygon],
ImagerMasks   USING [Mask],
ImagerPrivate  USING [Class, RegisterDevice],
ImagerPixelMapsExtras USING[MergeMaps],
ColorModels   USING [Calibration],
ConstantColors  USING [ColorToRGB],
Terminal    USING [ColorMode, Current, SetRedMap, SetGreenMap, SetBlueMap, Virtual],
Atom     USING [GetPropFromList],
Real     USING [FixC],
RealFns    USING [Power];
ImagerStd24BitDisplayImpl: CEDAR MONITOR
IMPORTS Imager, ImagerDisplay, ImagerPrivate, ConstantColors, Terminal, Real, RealFns, Atom,
   ImagerStdColorDisplay, ImagerPixelMapsExtras
~ BEGIN
This implements an 24-bit-per-pixel color display with no antialiasing.
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 ~ 24;    -- truncated value, ImagerStdColorDisplayImpl expects this
vt: Terminal.Virtual;
mode: Terminal.ColorMode ~ [full: TRUE, bitsPerPixelChannelA: 8, bitsPerPixelChannelB: 8];
std24BitDisplayClass: ImagerDisplay.DisplayClass ~ NEW[ImagerDisplay.DisplayClassRep ← [
displayType: $Std24bpp,
viewUnitsPerPixel: 1,
Create: Create,
ApplyMask: ApplyMask,
DoUnderLock: ImagerStdColorDisplay.DoUnderLock
]];
ColorDisplayError: PUBLIC ERROR [reason: ATOM] ~ CODE;
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]];
$LoadColorMap => ImagerStdColorDisplay.LoadColorMap[vt, data,
            NARROW[context.data, ImagerDisplay.DisplayData],
            LoadColor ];
$MergeRGMaps => MergeRGMaps[NARROW[context.data, ImagerDisplay.DisplayData]];
ENDCASE => Imager.Error[$UnimplementedSpecialOp];
RETURN[ NIL ];
};
MergeRGMaps: PROC[displayData: ImagerDisplay.DisplayData] ~ {
ImagerPixelMapsExtras.MergeMaps[displayData[0], displayData[1], 8, 8];
};
LoadColor: ImagerStdColorDisplay.LoadColorProc ~ {
PROC [ color: ConstantColor, colorCalibration: ColorModels.Calibration, mapEntry: [0..1024) ]
r, g, b: REAL;
mr, mg, mb: [0..256);
IF mapEntry < 256 THEN {
[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.SetRedMap[mapEntry, mr];
vt.SetGreenMap[mapEntry, mg];
vt.SetBlueMap[mapEntry, mb];
};
};
SetUpColorMap: ImagerStdColorDisplay.SetUpMapProc ~ {
PROC[displayData: DisplayData]
IF Atom.GetPropFromList[displayData.props, $PixelMapStatus] = $Displayed THEN
FOR i: NAT IN [0..256) DO
j: NAT ← Real.FixC[RealFns.Power[i/256.0, .43] * 256.0]; -- Linearize power law display   
vt.SetRedMap[i, j];
vt.SetGreenMap[i, j];
vt.SetBlueMap[i, j];
ENDLOOP;
};
CacheColor: ImagerStdColorDisplay.CachedColorProc ~ {
PROC [displayData: DisplayData, color: Color]
Convert color to RGB and cache merged RG value plus blue for subsequent writes
colorData: REF ImagerStdColorDisplay.ColorMapData ← NARROW[displayData.cachedColorData];
WITH color SELECT FROM
constantColor: ConstantColor => {
r, g, b: REAL;
nr, ng, nb: CARDINAL;
[r, g, b] ← ConstantColors.ColorToRGB[constantColor, colorData.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 * r];  ng ← Real.FixC[255.0 * g];  nb ← Real.FixC[255.0 * b];
displayData.cachedColor ← color;
colorData.pixelValueList ← LIST[ nr * 256 + ng, nb];
};
ENDCASE => Imager.Error[$UnsupportedColorType];
};
Init: PROC[] ~ {
std24BitImagerClass: ImagerPrivate.Class ~ ImagerDisplay.CreateImagerClass[std24BitDisplayClass];  -- pick up Imager class record
std24BitImagerClass.SpecialOp ← SpecialOp;     -- modify procedure bindings
ImagerPrivate.RegisterDevice[std24BitImagerClass];   -- register device class
vt ← Terminal.Current[];
};
Init[];
END.