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.