[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Color handling implemented in GSGState
From: |
Alexander Malmberg |
Subject: |
Re: Color handling implemented in GSGState |
Date: |
Mon, 13 May 2002 01:00:54 +0200 |
[snip]
> There seems to be a few problems with color conversions and out-of-range
> inputs to the color functions; I'll probably send a patch for that soon.
And here it is. Inputs to the color-setting functions are now clamped
properly. Hue==1.0 is converted to rgb properly (wasn't being caught in
the switch since i==6). Color conversions to cmyk and hsb are
implemented (I took the hsb code from NSColor; the cmyk black component
part is a bit of a hack, but it shows how it can be done it it's
necessary).
- Alexander Malmberg
Index: Source/gsc/GSGState.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Source/gsc/GSGState.m,v
retrieving revision 1.4
diff -u -r1.4 GSGState.m
--- Source/gsc/GSGState.m 10 May 2002 15:06:17 -0000 1.4
+++ Source/gsc/GSGState.m 12 May 2002 22:43:24 -0000
@@ -236,32 +238,46 @@
*r = gcolor.field[0]; *g = gcolor.field[1]; *b = gcolor.field[2];
}
+#define CLAMP(x) \
+ if (x < 0.0) x = 0.0; \
+ if (x > 1.0) x = 1.0;
+
- (void) DPSsetalpha: (float)a
{
+ CLAMP(a)
fillColor.field[AINDEX] = strokeColor.field[AINDEX] = a;
- /* Is this necessary?
[self setColor: fillColor state: COLOR_FILL];
[self setColor: strokeColor state: COLOR_STROKE];
- */
}
- (void) DPSsetcmykcolor: (float)c : (float)m : (float)y : (float)k
{
+ CLAMP(c)
+ CLAMP(m)
+ CLAMP(y)
+ CLAMP(k)
[self setColor: gsMakeColor(cmyk_colorspace, c, m, y, k) state: COLOR_BOTH];
}
- (void) DPSsetgray: (float)gray
{
+ CLAMP(gray)
[self setColor: gsMakeColor(gray_colorspace, gray, 0, 0, 0) state:
COLOR_BOTH];
}
- (void) DPSsethsbcolor: (float)h : (float)s : (float)b
{
+ CLAMP(h)
+ CLAMP(s)
+ CLAMP(b)
[self setColor: gsMakeColor(hsb_colorspace, h, s, b, 0) state: COLOR_BOTH];
}
- (void) DPSsetrgbcolor: (float)r : (float)g : (float)b
{
+ CLAMP(r)
+ CLAMP(g)
+ CLAMP(b)
[self setColor: gsMakeColor(rgb_colorspace, r, g, b, 0) state: COLOR_BOTH];
}
Index: Source/gsc/gscolors.c
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Source/gsc/gscolors.c,v
retrieving revision 1.1
diff -u -r1.1 gscolors.c
--- Source/gsc/gscolors.c 10 May 2002 15:06:17 -0000 1.1
+++ Source/gsc/gscolors.c 12 May 2002 22:43:24 -0000
@@ -71,6 +71,7 @@
switch (i)
{
+ default: /* catch h==1.0 */
case 0:
red = v;
green = t;
@@ -118,7 +119,7 @@
y = color.field[2];
k = color.field[3];
white = 1 - k;
-
+
if (k == 0)
{
red = 1 - c;
@@ -190,7 +191,6 @@
return new;
}
-/* FIXME: Not implemented */
device_color_t
gsColorToCMYK(device_color_t color)
{
@@ -200,10 +200,46 @@
switch(color.space)
{
case gray_colorspace:
- break;
- case rgb_colorspace:
+ new.field[0] = 0.0;
+ new.field[1] = 0.0;
+ new.field[2] = 0.0;
+ new.field[3] = color.field[0];
break;
case hsb_colorspace:
+ color = gsColorToRGB(color);
+ /* NO BREAK */
+ case rgb_colorspace:
+ new.field[0] = 1.0 - color.field[0];
+ new.field[1] = 1.0 - color.field[1];
+ new.field[2] = 1.0 - color.field[2];
+ new.field[3] = 0;
+
+ /* Add a bit of black if possible (for no reason, really). */
+ new.field[3] = new.field[0];
+ new.field[0] = 0.0;
+ new.field[1] -= new.field[3];
+ new.field[2] -= new.field[3];
+ if (new.field[1] > new.field[2])
+ {
+ if (new.field[2] < 0.0)
+ {
+ new.field[0] -= new.field[2];
+ new.field[1] -= new.field[2];
+ new.field[3] += new.field[2];
+ new.field[2] = 0;
+ }
+ }
+ else
+ {
+ if (new.field[1] < 0.0)
+ {
+ new.field[0] -= new.field[1];
+ new.field[2] -= new.field[1];
+ new.field[3] += new.field[1];
+ new.field[1] = 0;
+ }
+ }
+
break;
case cmyk_colorspace:
new = color;
@@ -214,7 +250,6 @@
return new;
}
-/* FIXME: Not implemented */
device_color_t
gsColorToHSB(device_color_t color)
{
@@ -224,13 +259,65 @@
switch(color.space)
{
case gray_colorspace:
+ new.field[0] = 0.0;
+ new.field[1] = 0.0;
+ new.field[2] = color.field[0];
break;
+ case cmyk_colorspace:
+ color = gsColorToRGB(color);
+ /* NO BREAK */
case rgb_colorspace:
+ {
+ float r = color.field[0];
+ float g = color.field[1];
+ float b = color.field[2];
+ float _hue_component, _saturation_component, _brightness_component;
+
+ if (r == g && r == b)
+ {
+ _hue_component = 0;
+ _saturation_component = 0;
+ _brightness_component = r;
+ }
+ else
+ {
+ double H;
+ double V;
+ double Temp;
+ double diff;
+
+ V = (r > g ? r : g);
+ V = (b > V ? b : V);
+ Temp = (r < g ? r : g);
+ Temp = (b < Temp ? b : Temp);
+ diff = V - Temp;
+ if (V == r)
+ {
+ H = (g - b)/diff;
+ }
+ else if (V == g)
+ {
+ H = (b - r)/diff + 2;
+ }
+ else
+ {
+ H = (r - g)/diff + 4;
+ }
+ if (H < 0)
+ {
+ H += 6;
+ }
+ _hue_component = H/6;
+ _saturation_component = diff/V;
+ _brightness_component = V;
+ }
+ new.field[0] = _hue_component;
+ new.field[1] = _saturation_component;
+ new.field[2] = _brightness_component;
+ }
break;
case hsb_colorspace:
- new = color;
- break;
- case cmyk_colorspace:
+ new = color = gsColorToRGB(color);
break;
default:
break;