Optimize color handling by passing pointers instead of device_color_t structures.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@14329 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Alexander Malmberg 2002-08-25 18:54:07 +00:00
parent 1ce93d80c8
commit fe197f6b45
8 changed files with 200 additions and 164 deletions

View file

@ -1,3 +1,11 @@
2002-08-25 20:48 Alexander Malmberg <alexander@malmberg.org>
* Headers/gsc/GSGState.h, Headers/gsc/gscolors.h,
Source/art/ARTContext.m, Source/gsc/GSGState.m, Source/gsc/gscolors.c,
Source/winlib/WIN32GState.m, Source/xlib/XGGState.m: Optimize color
handling by passing around pointers to device_color_t structures
(instead of the structures themselves).
2002-08-23 01:54 Alexander Malmberg <alexander@malmberg.org>
* Source/art/ARTWindowBuffer.m (+artWindowBufferForWindow:): Mark

View file

@ -73,7 +73,7 @@ typedef enum {
- (void) setOffset: (NSPoint)theOffset;
- (NSPoint) offset;
- (void) setColor: (device_color_t)color state: (color_state_t)cState;
- (void) setColor: (device_color_t *)color state: (color_state_t)cState;
- (void) compositeGState: (GSGState *)source
fromRect: (NSRect)aRect

View file

@ -37,12 +37,12 @@ typedef struct _device_color {
} device_color_t;
/* Internal conversion of colors to pixels values */
extern device_color_t gsMakeColor(device_colorspace_t space,
extern void gsMakeColor(device_color_t *dst, device_colorspace_t space,
float a, float b, float c, float d);
extern device_color_t gsColorToRGB(device_color_t color);
extern device_color_t gsColorToGray(device_color_t color);
extern device_color_t gsColorToCMYK(device_color_t color);
extern device_color_t gsColorToHSB(device_color_t color);
extern void gsColorToRGB(device_color_t *color);
extern void gsColorToGray(device_color_t *color);
extern void gsColorToCMYK(device_color_t *color);
extern void gsColorToHSB(device_color_t *color);
#endif

View file

@ -910,53 +910,80 @@ if necessary. Returns new operation, op==-1 means noop. */
optimize all this. passing device_color_t structures around by value is
very expensive
*/
-(void) setColor: (device_color_t)color state: (color_state_t)cState
-(void) setColor: (device_color_t *)color state: (color_state_t)cState
{
device_color_t c;
unsigned char r,g,b;
[super setColor: color state: cState];
if (cState&(COLOR_FILL|COLOR_STROKE))
{
c=gsColorToRGB(fillColor);
c=fillColor;
gsColorToRGB(&c); /* TODO: check this */
if (c.field[0]>1.0) c.field[0]=1.0;
if (c.field[0]<0.0) c.field[0]=0.0;
c.field[0]*=255;
r=c.field[0]*255;
if (c.field[1]>1.0) c.field[1]=1.0;
if (c.field[1]<0.0) c.field[1]=0.0;
c.field[1]*=255;
g=c.field[1]*255;
if (c.field[2]>1.0) c.field[2]=1.0;
if (c.field[2]<0.0) c.field[2]=0.0;
c.field[2]*=255;
}
b=c.field[2]*255;
if (cState&COLOR_FILL)
{
fill_color[0]=c.field[0];
fill_color[1]=c.field[1];
fill_color[2]=c.field[2];
fill_color[3]=fillColor.field[AINDEX]*255;
}
if (cState&COLOR_STROKE)
{
stroke_color[0]=c.field[0];
stroke_color[1]=c.field[1];
stroke_color[2]=c.field[2];
stroke_color[3]=strokeColor.field[AINDEX]*255;
if (cState&COLOR_FILL)
{
fill_color[0]=r;
fill_color[1]=g;
fill_color[2]=b;
fill_color[3]=fillColor.field[AINDEX]*255;
}
if (cState&COLOR_STROKE)
{
stroke_color[0]=r;
stroke_color[1]=g;
stroke_color[2]=b;
stroke_color[3]=strokeColor.field[AINDEX]*255;
}
}
}
/* TODO: optimize the others? optimize the gsc code instead? */
- (void) DPSsetgray: (float)gray
/* specially optimized versions (since these are common and simple) */
-(void) DPSsetgray: (float)gray
{
if (gray < 0.0) gray = 0.0;
if (gray > 1.0) gray = 1.0;
fillColor.space = strokeColor.space = gray_colorspace;
fillColor.field[0] = strokeColor.field[0] = gray;
cstate = COLOR_FILL|COLOR_STROKE;
cstate = COLOR_FILL | COLOR_STROKE;
stroke_color[0] = stroke_color[1] = stroke_color[2] =
fill_color[0] = fill_color[1] = fill_color[2] = gray*255;
fill_color[0] = fill_color[1] = fill_color[2] = gray * 255;
}
-(void) DPSsetalpha: (float)a
{
if (a < 0.0) a = 0.0;
if (a > 1.0) a = 1.0;
fillColor.field[AINDEX] = strokeColor.field[AINDEX] = a;
stroke_color[3] = fill_color[3] = a * 255;
}
- (void) DPSsetrgbcolor: (float)r : (float)g : (float)b
{
if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0;
if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0;
if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0;
fillColor.space = strokeColor.space = rgb_colorspace;
fillColor.field[0] = strokeColor.field[0] = r;
fillColor.field[1] = strokeColor.field[1] = g;
fillColor.field[2] = strokeColor.field[2] = b;
cstate = COLOR_FILL | COLOR_STROKE;
stroke_color[0] = fill_color[0] = r * 255;
stroke_color[1] = fill_color[1] = g * 255;
stroke_color[2] = fill_color[2] = b * 255;
}

View file

@ -132,16 +132,16 @@
/** Subclasses should override this method to be notified of changes
in the current color */
- (void) setColor: (device_color_t)color state: (color_state_t)cState
- (void) setColor: (device_color_t *)color state: (color_state_t)cState
{
float alpha;
alpha = fillColor.field[AINDEX];
if (cState & COLOR_FILL)
fillColor = color;
fillColor = *color;
fillColor.field[AINDEX] = alpha;
alpha = strokeColor.field[AINDEX];
if (cState & COLOR_STROKE)
strokeColor = color;
strokeColor = *color;
strokeColor.field[AINDEX] = alpha;
cstate = cState;
}
@ -198,7 +198,7 @@
- (void) DPScurrentcmykcolor: (float*)c : (float*)m : (float*)y : (float*)k
{
device_color_t new = fillColor;
new = gsColorToCMYK(new);
gsColorToCMYK(&new);
*c = new.field[0];
*m = new.field[1];
*y = new.field[2];
@ -207,22 +207,22 @@
- (void) DPScurrentgray: (float*)gray
{
device_color_t gcolor;
gcolor = gsColorToGray(fillColor);
device_color_t gcolor = fillColor;
gsColorToGray(&gcolor);
*gray = gcolor.field[0];
}
- (void) DPScurrenthsbcolor: (float*)h : (float*)s : (float*)b
{
device_color_t gcolor;
gcolor = gsColorToHSB(fillColor);
device_color_t gcolor = fillColor;
gsColorToHSB(&gcolor);
*h = gcolor.field[0]; *s = gcolor.field[1]; *b = gcolor.field[2];
}
- (void) DPScurrentrgbcolor: (float*)r : (float*)g : (float*)b
{
device_color_t gcolor;
gcolor = gsColorToRGB(fillColor);
device_color_t gcolor = fillColor;
gsColorToRGB(&gcolor);
*r = gcolor.field[0]; *g = gcolor.field[1]; *b = gcolor.field[2];
}
@ -234,44 +234,53 @@
{
CLAMP(a)
fillColor.field[AINDEX] = strokeColor.field[AINDEX] = a;
[self setColor: fillColor state: COLOR_FILL];
[self setColor: strokeColor state: COLOR_STROKE];
[self setColor: &fillColor state: COLOR_FILL];
[self setColor: &strokeColor state: COLOR_STROKE];
}
- (void) DPSsetcmykcolor: (float)c : (float)m : (float)y : (float)k
{
device_color_t col;
CLAMP(c)
CLAMP(m)
CLAMP(y)
CLAMP(k)
[self setColor: gsMakeColor(cmyk_colorspace, c, m, y, k) state: COLOR_BOTH];
gsMakeColor(&col, cmyk_colorspace, c, m, y, k);
[self setColor: &col state: COLOR_BOTH];
}
- (void) DPSsetgray: (float)gray
{
device_color_t col;
CLAMP(gray)
[self setColor: gsMakeColor(gray_colorspace, gray, 0, 0, 0) state: COLOR_BOTH];
gsMakeColor(&col, gray_colorspace, gray, 0, 0, 0);
[self setColor: &col state: COLOR_BOTH];
}
- (void) DPSsethsbcolor: (float)h : (float)s : (float)b
{
device_color_t col;
CLAMP(h)
CLAMP(s)
CLAMP(b)
[self setColor: gsMakeColor(hsb_colorspace, h, s, b, 0) state: COLOR_BOTH];
gsMakeColor(&col, hsb_colorspace, h, s, b, 0);
[self setColor: &col state: COLOR_BOTH];
}
- (void) DPSsetrgbcolor: (float)r : (float)g : (float)b
{
device_color_t col;
CLAMP(r)
CLAMP(g)
CLAMP(b)
[self setColor: gsMakeColor(rgb_colorspace, r, g, b, 0) state: COLOR_BOTH];
gsMakeColor(&col, rgb_colorspace, r, g, b, 0);
[self setColor: &col state: COLOR_BOTH];
}
- (void) GSSetFillColorspace: (NSDictionary *)dict
{
device_color_t col;
float values[6];
NSString *colorSpace = [dict objectForKey: GSColorSpaceName];
if (fillColorS)
@ -279,11 +288,13 @@
memset(values, 0, sizeof(float)*6);
fillColorS = [NSColor colorWithValues: values colorSpaceName:colorSpace];
RETAIN(fillColorS);
[self setColor: gsMakeColor(rgb_colorspace, 0, 0, 0, 0) state: COLOR_FILL];
gsMakeColor(&col, rgb_colorspace, 0, 0, 0, 0);
[self setColor: &col state: COLOR_FILL];
}
- (void) GSSetStrokeColorspace: (NSDictionary *)dict
{
device_color_t col;
float values[6];
NSString *colorSpace = [dict objectForKey: GSColorSpaceName];
if (strokeColorS)
@ -291,7 +302,8 @@
memset(values, 0, sizeof(float)*6);
strokeColorS = [NSColor colorWithValues: values colorSpaceName:colorSpace];
RETAIN(strokeColorS);
[self setColor: gsMakeColor(rgb_colorspace, 0, 0, 0, 0) state: COLOR_STROKE];
gsMakeColor(&col, rgb_colorspace, 0, 0, 0, 0);
[self setColor: &col state: COLOR_STROKE];
}
- (void) GSSetFillColor: (float *)values
@ -314,7 +326,7 @@
green: &dcolor.field[1]
blue: &dcolor.field[2]
alpha: &dcolor.field[AINDEX]];
[self setColor: dcolor state: COLOR_FILL];
[self setColor: &dcolor state: COLOR_FILL];
}
- (void) GSSetStrokeColor: (float *)values
@ -337,7 +349,7 @@
green: &dcolor.field[1]
blue: &dcolor.field[2]
alpha: &dcolor.field[AINDEX]];
[self setColor: dcolor state: COLOR_STROKE];
[self setColor: &dcolor state: COLOR_STROKE];
}
/* ----------------------------------------------------------------------- */
@ -457,10 +469,10 @@
/* Initialize colors. By default the same color is used for filling and
stroking unless fill and/or stroke color is set explicitly */
fillColor = gsMakeColor(gray_colorspace, 0, 0, 0, 0);
gsMakeColor(&fillColor, gray_colorspace, 0, 0, 0, 0);
fillColor.field[AINDEX] = 1.0;
strokeColor.field[AINDEX] = 1.0;
[self setColor: fillColor state: COLOR_BOTH];
[self setColor: &fillColor state: COLOR_BOTH];
charSpacing = 0;
textMode = GSTextFill;

View file

@ -28,39 +28,40 @@
#include <math.h>
#include "gsc/gscolors.h"
device_color_t
gsMakeColor(device_colorspace_t space, float a, float b, float c, float d)
void
gsMakeColor(device_color_t *dst, device_colorspace_t space, float a, float b, float c, float d)
{
device_color_t color;
color.space = space;
color.field[0] = a;
color.field[1] = b;
color.field[2] = c;
color.field[3] = d;
return color;
dst->space = space;
dst->field[0] = a;
dst->field[1] = b;
dst->field[2] = c;
dst->field[3] = d;
}
device_color_t
gsGrayToRGB(device_color_t color)
void
gsGrayToRGB(device_color_t *color)
{
return gsMakeColor(rgb_colorspace, color.field[0], color.field[0],
color.field[0], 0);
gsMakeColor(color, rgb_colorspace, color->field[0], color->field[0],
color->field[0], 0);
}
device_color_t
gsHSBToRGB(device_color_t color)
void
gsHSBToRGB(device_color_t *color)
{
int i;
float h, s, v;
float f, p, q, t;
float red, green, blue;
h = color.field[0];
s = color.field[1];
v = color.field[2];
h = color->field[0];
s = color->field[1];
v = color->field[2];
if (s == 0)
return gsMakeColor(rgb_colorspace, v, v, v, 0);
if (s == 0)
{
gsMakeColor(color, rgb_colorspace, v, v, v, 0);
return;
}
h = h * 6;
i = (int)h;
@ -103,21 +104,21 @@ gsHSBToRGB(device_color_t color)
blue = q;
break;
}
return gsMakeColor(rgb_colorspace, red, green, blue, 0);
gsMakeColor(color, rgb_colorspace, red, green, blue, 0);
}
/* FIXME */
device_color_t
gsCMYKToRGB(device_color_t color)
void
gsCMYKToRGB(device_color_t *color)
{
float c, m, y, k;
float red, green, blue;
double white;
c = color.field[0];
m = color.field[1];
y = color.field[2];
k = color.field[3];
c = color->field[0];
m = color->field[1];
y = color->field[2];
k = color->field[3];
white = 1 - k;
if (k == 0)
@ -138,139 +139,124 @@ gsCMYKToRGB(device_color_t color)
green = (m > white ? 0 : white - m);
blue = (y > white ? 0 : white - y);
}
return gsMakeColor(rgb_colorspace, red, green, blue, 0);
gsMakeColor(color, rgb_colorspace, red, green, blue, 0);
}
device_color_t
gsColorToRGB(device_color_t color)
void
gsColorToRGB(device_color_t *color)
{
device_color_t new;
switch(color.space)
switch(color->space)
{
case gray_colorspace:
new = gsGrayToRGB(color);
gsGrayToRGB(color);
break;
case rgb_colorspace:
new = color;
break;
case hsb_colorspace:
new = gsHSBToRGB(color);
gsHSBToRGB(color);
break;
case cmyk_colorspace:
new = gsCMYKToRGB(color);
gsCMYKToRGB(color);
break;
default:
break;
}
return new;
}
device_color_t
gsColorToGray(device_color_t color)
void
gsColorToGray(device_color_t *color)
{
device_color_t new;
new.space = gray_colorspace;
switch(color.space)
switch(color->space)
{
case gray_colorspace:
new = color;
break;
case hsb_colorspace:
case cmyk_colorspace:
color = gsColorToRGB(color);
gsColorToRGB(color);
/* NO BREAK */
case rgb_colorspace:
new.field[0] =
((0.3*color.field[0]) + (0.59*color.field[1]) + (0.11*color.field[2]));
color->field[0] =
((0.3*color->field[0]) + (0.59*color->field[1]) + (0.11*color->field[2]));
break;
default:
break;
}
return new;
color->space = gray_colorspace;
}
device_color_t
gsColorToCMYK(device_color_t color)
void
gsColorToCMYK(device_color_t *color)
{
device_color_t new;
new.space = cmyk_colorspace;
switch(color.space)
switch(color->space)
{
case gray_colorspace:
new.field[0] = 0.0;
new.field[1] = 0.0;
new.field[2] = 0.0;
new.field[3] = color.field[0];
color->field[3] = color->field[0];
color->field[0] = 0.0;
color->field[1] = 0.0;
color->field[2] = 0.0;
break;
case hsb_colorspace:
color = gsColorToRGB(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;
color->field[0] = 1.0 - color->field[0];
color->field[1] = 1.0 - color->field[1];
color->field[2] = 1.0 - color->field[2];
color->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])
color->field[3] = color->field[0];
color->field[0] = 0.0;
color->field[1] -= color->field[3];
color->field[2] -= color->field[3];
if (color->field[1] > color->field[2])
{
if (new.field[2] < 0.0)
if (color->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;
color->field[0] -= color->field[2];
color->field[1] -= color->field[2];
color->field[3] += color->field[2];
color->field[2] = 0;
}
}
else
{
if (new.field[1] < 0.0)
if (color->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;
color->field[0] -= color->field[1];
color->field[2] -= color->field[1];
color->field[3] += color->field[1];
color->field[1] = 0;
}
}
break;
case cmyk_colorspace:
new = color;
break;
default:
break;
}
return new;
color->space = cmyk_colorspace;
}
device_color_t
gsColorToHSB(device_color_t color)
void
gsColorToHSB(device_color_t *color)
{
device_color_t new;
new.space = hsb_colorspace;
switch(color.space)
switch(color->space)
{
case gray_colorspace:
new.field[0] = 0.0;
new.field[1] = 0.0;
new.field[2] = color.field[0];
color->field[2] = color->field[0];
color->field[0] = 0.0;
color->field[1] = 0.0;
break;
case cmyk_colorspace:
color = gsColorToRGB(color);
gsColorToRGB(color);
/* NO BREAK */
case rgb_colorspace:
{
float r = color.field[0];
float g = color.field[1];
float b = color.field[2];
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)
@ -311,16 +297,15 @@ gsColorToHSB(device_color_t color)
_saturation_component = diff/V;
_brightness_component = V;
}
new.field[0] = _hue_component;
new.field[1] = _saturation_component;
new.field[2] = _brightness_component;
color->field[0] = _hue_component;
color->field[1] = _saturation_component;
color->field[2] = _brightness_component;
}
break;
case hsb_colorspace:
new = color = gsColorToRGB(color);
break;
default:
break;
}
return new;
color->space = hsb_colorspace;
}

View file

@ -149,10 +149,12 @@ RECT GSViewRectToWin(WIN32GState *s, NSRect r)
return window;
}
- (void) setColor: (device_color_t)color state: (color_state_t)cState
- (void) setColor: (device_color_t *)acolor state: (color_state_t)cState
{
[super setColor: color state: cState];
color = gsColorToRGB(color);
device_color_t color;
[super setColor: acolor state: cState];
color = *acolor;
gsColorToRGB(&color);
if (cState & COLOR_FILL)
wfcolor = RGB(color.field[0]*255, color.field[1]*255, color.field[2]*255);
if (cState & COLOR_STROKE)

View file

@ -239,16 +239,18 @@ static Region emptyRegion;
return region;
}
- (void) setColor: (device_color_t)color state: (color_state_t)cState
- (void) setColor: (device_color_t *)color state: (color_state_t)cState
{
device_color_t c;
[super setColor: color state: cState];
if (context == NULL)
{
/* Window device isn't set yet */
return;
}
color = gsColorToRGB(color);
gcv.foreground = xrRGBToPixel(context, color);
c = *color;
gsColorToRGB(&c);
gcv.foreground = xrRGBToPixel(context, c);
[self setGCValues: gcv withMask: GCForeground];
}
@ -260,7 +262,7 @@ static Region emptyRegion;
/* Window device isn't set yet */
return;
}
color = gsMakeColor(rgb_colorspace, value, value, value, 0);
gsMakeColor(&color, rgb_colorspace, value, value, value, 0);
gcv.foreground = xrRGBToPixel(context, color);
if (agcntxt == None)
agcntxt = XCreateGC(XDPY, draw, GCForeground, &gcv);
@ -1209,7 +1211,7 @@ typedef enum {
}
if ((cstate & COLOR_FILL) == 0)
[self setColor: fillColor state: COLOR_FILL];
[self setColor: &fillColor state: COLOR_FILL];
/* Use only delta transformations (no offset) */
len = strlen(s);
@ -1319,7 +1321,7 @@ typedef enum {
}
if ((cstate & COLOR_FILL) == 0)
[self setColor: fillColor state: COLOR_FILL];
[self setColor: &fillColor state: COLOR_FILL];
len = strlen(s);
width = [font_info widthOf: s lenght: len];
@ -1498,7 +1500,7 @@ typedef enum {
- (void)DPSeofill
{
if ((cstate & COLOR_FILL) == 0)
[self setColor: fillColor state: COLOR_FILL];
[self setColor: &fillColor state: COLOR_FILL];
[self _paintPath: path_eofill];
}
@ -1506,7 +1508,7 @@ typedef enum {
- (void)DPSfill
{
if ((cstate & COLOR_FILL) == 0)
[self setColor: fillColor state: COLOR_FILL];
[self setColor: &fillColor state: COLOR_FILL];
[self _paintPath: path_fill];
}
@ -1555,7 +1557,7 @@ typedef enum {
}
if ((cstate & COLOR_FILL) == 0)
[self setColor: fillColor state: COLOR_FILL];
[self setColor: &fillColor state: COLOR_FILL];
bounds = XGViewRectToX(self, NSMakeRect(x, y, w, h));
// Hack: Only draw when alpha is not zero
@ -1586,7 +1588,7 @@ typedef enum {
}
if ((cstate & COLOR_STROKE) == 0)
[self setColor: fillColor state: COLOR_STROKE];
[self setColor: &fillColor state: COLOR_STROKE];
bounds = XGViewRectToX(self, NSMakeRect(x, y, w, h));
if (bounds.width > 0)
@ -1612,7 +1614,7 @@ typedef enum {
- (void)DPSstroke
{
if ((cstate & COLOR_STROKE) == 0)
[self setColor: fillColor state: COLOR_STROKE];
[self setColor: &fillColor state: COLOR_STROKE];
[self _paintPath: path_stroke];
}