CNSColorImpl.mesa
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
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 [hue, saturation, lightness: Rope.
ROPE]
RETURNS [c: CSLChroma, s: CSLSaturation, l: CSLLightness] = {
hueAtom, saturationAtom, lightnessAtom: ATOM;
hueAtom ← Atom.MakeAtom[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[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[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 [c: CSLChroma, s: CSLSaturation, l: CSLLightness]
RETURNS [hue, saturation, lightness: Rope.
ROPE] = {
IF c = achromatic
THEN {
saturation ← "";
SELECT l
FROM
black => {
hue ← "Black";
lightness ← "";
};
white => {
hue ← "White";
lightness ← "";
};
ENDCASE => {
hue ← "Gray";
lightness ← Atom.GetPName[lightnessMapping[l].name];
};
}
ELSE {
hue ← Atom.GetPName[hueMapping[c].name];
saturation ← Atom.GetPName[saturationMapping[s].name];
lightness ← Atom.GetPName[lightnessMapping[l].name];
};
RETURN[hue, saturation, lightness];
};
HSLFromCSL:
PUBLIC PROCEDURE [c: CSLChroma, s: CSLSaturation, l: CSLLightness]
RETURNS [hue, saturation, lightness:
REAL] = {
IF c = achromatic
THEN {
hue ← 0.0;
saturation ← 0.0;
lightness ← lightnessMapping[l].value;
}
ELSE {
hue ← hueMapping[c].value;
saturation ← saturationMapping[s].value;
lightness ← lightnessMapping[l].value;
};
RETURN[hue, saturation, lightness];
};
CSLFromHSL:
PUBLIC PROCEDURE [hue, saturation, lightness:
REAL]
RETURNS [c: CSLChroma, s: CSLSaturation, l: CSLLightness] = {
FOR s
IN [noSaturation..vivid]
DO
IF s = vivid THEN EXIT;
IF saturation <= saturationMapping[s].value + (saturationMapping[s+1].value - saturationMapping[s].value)/2 THEN EXIT;
ENDLOOP;
IF s = noSaturation
THEN {
c ← achromatic;
FOR l
IN [black..white]
DO
IF l = white THEN EXIT;
IF lightness <= lightnessMapping[l].value + (lightnessMapping[l+1].value - lightnessMapping[l].value)/2 THEN EXIT;
ENDLOOP;
}
ELSE {
FOR c
IN [red..purplishRed]
DO
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+1].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+1].value - lightnessMapping[l].value)/2 THEN EXIT;
ENDLOOP;
};
RETURN[c, s, l];
};
END.