CNSColorImpl.mesa
Copyright Ó 1983, 1985, 1989, 1992 by Xerox Corporation. All rights reserved.
Written by Darlene Plebon on June 23, 1983 11:48 am
Last Edited by: Beach, June 22, 1983 2:52 pm
Last Edited by: Stone, June 20, 1985 4:38:58 pm PDT
Doug Wyatt, April 10, 1992 4:54 pm PDT
DIRECTORY
Atom USING [GetPName, MakeAtom],
CNSColor,
Rope USING [ROPE];
CNSColorImpl: CEDAR PROGRAM
IMPORTS Atom
EXPORTS CNSColor =
BEGIN OPEN CNSColor;
hueRecord: TYPE = RECORD [
name: ATOM,
value: REAL
];
hueMapping: ARRAY CSLChroma OF hueRecord ¬ [
[$Achromatic,  0.0],
[$Red,  0.0],
[$OrangishRed,  0.01],
[$RedOrange,  0.02],
[$ReddishOrange,  0.03],
[$Orange,  0.04],
[$YellowishOrange,  0.07],
[$OrangeYellow,  0.10],
[$OrangishYellow,  0.13],
[$Yellow,  0.1673],
[$GreenishYellow,  0.2073],
[$YellowGreen,  0.2473],
[$YellowishGreen,  0.2873],
[$Green,  0.3333],
[$BluishGreen,  0.4133],
[$GreenBlue,  0.4933],
[$GreenishBlue,  0.5733],
[$Blue,  0.6666],
[$PurplishBlue,  0.6816],
[$BluePurple,  0.6966],
[$BluishPurple,  0.7116],
[$Purple,  0.73],
[$ReddishPurple,  0.80],
[$PurpleRed,  0.87],
[$PurplishRed,  0.94],
[$BrownishRed,  0.01],
[$RedBrown,  0.02],
[$ReddishBrown,  0.03],
[$Brown,  0.04],
[$YellowishBrown,  0.07],
[$BrownYellow,  0.10],
[$BrownishYellow,  0.13]
];
saturationRecord: TYPE = RECORD [
name: ATOM,
value: REAL
];
saturationMapping: ARRAY CSLSaturation OF saturationRecord ¬ [
[$NoSaturation,  0.0],
[$Grayish,  0.25],
[$Moderate,  0.50],
[$Strong,  0.75],
[$Vivid,  1.0]
];
lightnessRecord: TYPE = RECORD [
name: ATOM,
value: REAL
];
lightnessMapping: ARRAY CSLLightness OF lightnessRecord ¬ [
[$Black,  0.0],
[$VeryDark,  0.1666],
[$Dark,  0.3333],
[$Medium,  0.5],
[$Light,  0.6666],
[$VeryLight,  0.8333],
[$White,  1.0]
];
CSLFromCNS: PUBLIC PROCEDURE [cns: CNS] RETURNS [CSL] = {
hueAtom, saturationAtom, lightnessAtom: ATOM;
c: CSLChroma; s: CSLSaturation; l: CSLLightness;
hueAtom ¬ Atom.MakeAtom[cns.hue];
FOR c IN [red..brownishYellow] DO
IF hueAtom = hueMapping[c].name THEN EXIT;
REPEAT
FINISHED => c ¬ achromatic;
ENDLOOP;
IF c = achromatic THEN s ¬ noSaturation
ELSE {
saturationAtom ¬ Atom.MakeAtom[cns.saturation];
FOR s IN [grayish..vivid] DO
IF saturationAtom = saturationMapping[s].name THEN EXIT;
REPEAT
FINISHED => s ¬ vivid;
ENDLOOP;
};
SELECT hueAtom FROM
$Black => l ¬ black;
$White => l ¬ white;
ENDCASE => {
lightnessAtom ¬ Atom.MakeAtom[cns.lightness];
FOR l IN [veryDark..veryLight] DO
IF lightnessAtom = lightnessMapping[l].name THEN EXIT;
REPEAT
FINISHED => l ¬ medium;
ENDLOOP;
};
RETURN[[c, s, l]];
};
CNSFromCSL: PUBLIC PROCEDURE [csl: CSL] RETURNS [CNS] = {
hue, saturation, lightness: Rope.ROPE ¬ "";
IF csl.c = achromatic THEN {
SELECT csl.l FROM
black => {
hue ¬ "Black";
};
white => {
hue ¬ "White";
};
ENDCASE => {
hue ¬ "Gray";
lightness ¬ Atom.GetPName[lightnessMapping[csl.l].name];
};
}
ELSE {
hue ¬ Atom.GetPName[hueMapping[csl.c].name];
saturation ¬ Atom.GetPName[saturationMapping[csl.s].name];
lightness ¬ Atom.GetPName[lightnessMapping[csl.l].name];
};
RETURN[[hue, saturation, lightness]];
};
HSLFromCSL: PUBLIC PROCEDURE [csl: CSL] RETURNS [HSL] = {
hue, saturation, lightness: REAL ¬ 0.0;
IF csl.c = achromatic THEN {
lightness ¬ lightnessMapping[csl.l].value;
}
ELSE {
hue ¬ hueMapping[csl.c].value;
saturation ¬ saturationMapping[csl.s].value;
lightness ¬ lightnessMapping[csl.l].value;
};
RETURN[[hue, saturation, lightness]];
};
CSLFromHSL: PUBLIC PROCEDURE [hsl: HSL] RETURNS [CSL] = {
hue, saturation, lightness: REAL;
c: CSLChroma; s: CSLSaturation; l: CSLLightness;
[hue, saturation, lightness] ← hsl;
FOR s IN CSLSaturation DO
IF s = CSLSaturation.LAST THEN EXIT;
IF saturation <= saturationMapping[s].value + (saturationMapping[s.SUCC].value - saturationMapping[s].value)/2 THEN EXIT;
ENDLOOP;
IF s = noSaturation THEN {
c ¬ achromatic;
FOR l IN CSLLightness DO
IF l = CSLLightness.LAST THEN EXIT;
IF lightness <= lightnessMapping[l].value + (lightnessMapping[l.SUCC].value - lightnessMapping[l].value)/2 THEN EXIT;
ENDLOOP;
}
ELSE {
FOR cc: CSLChroma IN [red..purplishRed] DO
c ¬ cc; -- to satisfy fussier Mimosa compiler (if c is the loop variable, can't assign to it)
IF c = purplishRed THEN {
IF hue > hueMapping[c].value + (1.0 - hueMapping[c].value)/2 THEN c ¬ red;
EXIT;
};
IF hue <= hueMapping[c].value + (hueMapping[c.SUCC].value - hueMapping[c].value)/2 THEN EXIT;
ENDLOOP;
FOR l IN [veryDark..veryLight] DO
IF l = veryLight THEN EXIT;
IF lightness <= lightnessMapping[l].value + (lightnessMapping[l.SUCC].value - lightnessMapping[l].value)/2 THEN EXIT;
ENDLOOP;
};
RETURN[[c, s, l]];
};
END.