


## rgb.pkg
#
# RGB colors
#
# See also:
# src/lib/x-kit/xclient/pkg/color/hue-saturation-value.pkg# src/lib/x-kit/xclient/pkg/color/rgb8.pkg# Compiled by:
# src/lib/x-kit/xclient/xclient-internals.sublibstipulate
include rw_float_vector; # Enable vec[i] and vec[i] := f notations.
#
package f8b = eight_byte_float; # eight_byte_float is from src/lib/std/eight-byte-float.pkg package fv = rw_float_vector; # rw_float_vector is from src/lib/std/rw-float-vector.pkgherein
package rgb
: Rgb # Rgb is from src/lib/x-kit/xclient/pkg/color/rgb.api {
# We represent an RGB color value by a
# record of 64-bit floats holding
# red, green, blue in that order.
# (The compiler will optimize this to
# a very efficient packed representation.)
#
Rgb = { red: Float,
green: Float,
blue: Float
};
fun rgb_from_floats (red, green, blue) # Should do some sort of validation (restriction to [0,1) interval). What exception should we throw? Or should we silently truncate? XXX BUGGO FIXME.
=
{ red, green, blue };
fun rgb_to_floats (rgb: Rgb)
=
(rgb.red, rgb.green, rgb.blue); # Eventually we'll probably want to suppress index checking here for speed, using unsafe:: operations or whatever. XXX BUGGO FIXME.
fun rgb_from_unts (red, green, blue)
=
{ red => unt_to_float red,
green => unt_to_float green,
blue => unt_to_float blue
}
where
fun unt_to_float u
=
{ i = unt::to_int u;
f = f8b::from_int i;
f = f // 65535.0; # Our unts run 0 -> 65535.
f;
};
end;
fun rgb_to_unts { red, green, blue }
=
( float_to_unt red,
float_to_unt green,
float_to_unt blue
)
where
fun float_to_unt f
=
{ f = (f < 0.0) ?? 0.0 :: f;
f = (f > 1.0) ?? 1.0 :: f;
f = f * 65535.99; # Our unts run 0 -> 65535.
unt::from_int (f8b::truncate f);
};
end;
fun same_rgb (a: Rgb, b: Rgb)
= f8b::(====) (a.red, b.red )
and f8b::(====) (a.green, b.green)
and f8b::(====) (a.blue, b.blue )
;
# Ensure that all color components
# are in 0.0 -> 1.0 inclusive:
#
fun rgb_normalize (rgb as { red, green, blue })
=
{ if (red >= 0.0 and red <= 0.0
and green >= 0.0 and green <= 0.0
and blue >= 0.0 and blue <= 0.0
)
rgb;
else
red = red >= 0.0 ?? red :: 0.0;
red = red <= 1.0 ?? red :: 1.0;
#
green = green >= 0.0 ?? green :: 0.0;
green = green <= 1.0 ?? green :: 1.0;
#
blue = blue >= 0.0 ?? blue :: 0.0;
blue = blue <= 1.0 ?? blue :: 1.0;
#
{ red, green, blue };
fi;
};
fun rgb_from_name colorname
=
rgb_from_floats (x11_color_name::to_floats colorname);
# Predefine a few common colors for convenience:
#
black = rgb_from_floats (0.0, 0.0, 0.0);
white = rgb_from_floats (1.0, 1.0, 1.0);
red = rgb_from_floats (1.0, 0.0, 0.0);
green = rgb_from_floats (0.0, 1.0, 0.0);
blue = rgb_from_floats (0.0, 0.0, 1.0);
cyan = rgb_from_floats (0.0, 1.0, 1.0);
magenta = rgb_from_floats (1.0, 0.0, 1.0);
yellow = rgb_from_floats (1.0, 1.0, 0.0);
};
end;
## COPYRIGHT (c) 1994 by AT&T Bell Laboratories
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2012,
## released under Gnu Public Licence version 3.


