Owen Taylor <[EMAIL PROTECTED]> wrote:
> I've put up some screenshots at:
>
> http://people.redhat.com/otaylor/fonts/gamma-screenshots/
>
> I also discovered a major one-character bug in my last patch
> (*, /, what's the difference...) that prevented it from
> working with anything but a black foreground. New fixed
> version is attached.
Ahem. I also discovered a cut-n-paste error that prevented it
from working with anything other than gray... ;)
Here's the patch to the patch, and the patched patch.
--- gamma.diff Tue Jul 23 14:39:46 2002
+++ gammafixed.diff Tue Jul 23 14:35:25 2002
@@ -177,8 +177,8 @@
+ if (src_a)
+ {
+ *dst_r = fromDouble(src_a, (double)color->color.red / color->color.alpha, t);
-+ *dst_g = fromDouble(src_a, (double)color->color.red / color->color.alpha, t);
-+ *dst_b = fromDouble(src_a, (double)color->color.red / color->color.alpha, t);
++ *dst_g = fromDouble(src_a, (double)color->color.green / color->color.alpha, t);
++ *dst_b = fromDouble(src_a, (double)color->color.blue / color->color.alpha, t);
+ }
+ else
+ *dst_r = *dst_g = *dst_b = 0;
--- fcpackage.02-06-21.10-39/Xft/xftcore.c.gamma Sun Jun 23 10:35:12 2002
+++ fcpackage.02-06-21.10-39/Xft/xftcore.c Sun Jun 23 17:00:05 2002
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include "xftint.h"
#include <X11/Xmd.h>
+#include <math.h>
void
XftRectCore (XftDraw *draw,
@@ -367,6 +368,64 @@
}
/*
+ * These functions define the sRGB curve that we use for gamma correction;
+ * because of the linear ramp at the beginning, the sRGB curve allows
+ * a much more manageable lookup table than a straight x**2.2 gamma curve
+ *
+ * Apparently, the values of ADJGAMA and OFFSET were chosen to minimize
+ * the difference between the sRGB function and X**2.2; the free parameters
+ * here really are GAMMA (=2.2) and THRESHOLD.
+ */
+#define THRESHOLD 0.03928 /* Very close to 10./255 */
+#define OFFSET 0.055
+#define ADJGAMMA 2.4
+#define SLOPE 12.92 /* gammaCurve (THRESHOLD) / THRESHOLD */
+
+static double
+gammaCurve(double x)
+{
+ if (x <= THRESHOLD)
+ return x / SLOPE;
+ else
+ return pow(((OFFSET + x) / (1 + OFFSET)), ADJGAMMA);
+}
+
+static double
+gammaCurveInv(double y)
+{
+ if (y <= THRESHOLD / SLOPE)
+ return y * SLOPE;
+ else
+ return pow(y, 1/ADJGAMMA) * (1 + OFFSET) - OFFSET;
+}
+
+static CARD16 gammaTable5[32];
+static CARD16 gammaTable6[64];
+static CARD16 gammaTable8[256];
+static CARD8 gammaTableInv[4096];
+
+static void
+gammaTablePrepare(void)
+{
+ static int prepared = 0;
+ int i;
+
+ if (!prepared)
+ {
+ for (i = 0; i < 32; i++)
+ gammaTable5[i] = 4095 * gammaCurve(i/31.) + 0.5;
+ for (i = 0; i < 64; i++)
+ gammaTable6[i] = 4095 * gammaCurve(i/63.) + 0.5;
+ for (i = 0; i < 256; i++)
+ gammaTable8[i] = 4095 * gammaCurve(i/255.) + 0.5;
+ for (i = 0; i < 4096; i++)
+ gammaTableInv[i] = 255 * gammaCurveInv(i/4095.) + 0.5;
+
+ prepared = 1;
+ }
+}
+
+/*
* As simple anti-aliasing is likely to be common, there are three
* optimized versions for the usual true color pixel formats (888, 565, 555).
* Other formats are handled by the general case
@@ -387,13 +446,35 @@
#define cvt0555to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
((((s) << 6) & 0xf800) | (((s) >> 0) & 0x300)) | \
((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000)))
+#define cvt0555to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
+ ((((s) << 6) & 0xf800) | (((s) >> 0) & 0x300)) | \
+ ((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000)))
+
+#define XftGet8(v,i) ((CARD16) (CARD8) ((v) >> i))
+#define cvt0888toGamma12(d,s) (d##_r = gammaTable8[XftGet8(s,16)], \
+ d##_g = gammaTable8[XftGet8(s,8)], \
+ d##_b = gammaTable8[XftGet8(s,0)])
+#define cvt0565toGamma12(d,s) (d##_r = gammaTable5[((s) & 0xf800) >> 11], \
+ d##_g = gammaTable6[((s) & 0x07e0) >> 5], \
+ d##_b = gammaTable5[((s) & 0x1f)])
+#define cvt0555toGamma12(d,s) (d##_r = gammaTable5[((s) & 0x7c00) >> 10], \
+ d##_g = gammaTable5[((s) & 0x03e0) >> 5], \
+ d##_b = gammaTable5[((s) & 0x001f)])
+
+#define cvtGamma12to0888(s) (gammaTableInv[s##_r] << 16 | \
+ gammaTableInv[s##_g] << 8| \
+ gammaTableInv[s##_b]);
+#define cvtGamma12to0565(s) (((gammaTableInv[s##_r] << 8) & 0xf800) | \
+ ((gammaTableInv[s##_g] << 3) & 0x07e0) | \
+ ((gammaTableInv[s##_b] >> 3)))
+#define cvtGamma12to0555(s) (((gammaTableInv[s##_r] << 7) & 0x7c00) | \
+ ((gammaTableInv[s##_g] << 3) & 0x03e0) | \
+ ((gammaTableInv[s##_b] >> 3)))
#define XftIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
#define XftIntDiv(a,b) (((CARD16) (a) * 255) / (b))
-#define XftGet8(v,i) ((CARD16) (CARD8) ((v) >> i))
-
/*
* There are two ways of handling alpha -- either as a single unified value or
* a separate value for each component, hence each macro must have two
@@ -402,16 +483,48 @@
* this difference will have two versions using the same convention.
*/
+#define XftDeclare3(var) CARD32 var##_r, var##_g, var##_b
+#define XftDeclare4(var) CARD32 var##_a, var##_r, var##_g, var##_b
+#define XftAssign3(dst,src) (dst##_r = src##_r, \
+ dst##_b = src##_b, \
+ dst##_g = src##_g)
+#define XftAssignRGB(dst,r,g,b) (dst##_r = r, \
+ dst##_b = b, \
+ dst##_g = g)
+
#define XftOverU(x,y,i,a,t) ((t) = XftIntMult(XftGet8(y,i),(a),(t)) + XftGet8(x,i),\
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
#define XftOverC(x,y,i,a,t) ((t) = XftIntMult(XftGet8(y,i),XftGet8(a,i),(t)) +
XftGet8(x,i),\
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
+#define XftOverO(x,y,a,t) ((t) = XftIntMult(y,255-(a),(t)) + x,\
+ (0xfff & ((t) | (0 - ((t) >> 12)))))
+
+#define XftOver3U(d,x,y,a,t) (d##_r = XftOverO(x##_r,y##_r,a,t##_r), \
+ d##_g = XftOverO(x##_g,y##_g,a,t##_g), \
+ d##_b = XftOverO(x##_b,y##_r,a,t##_b))
+#define XftOver3C(d,x,y,a,t) (d##_r = XftOverO(x##_r,y##_r,a##_r,t##_r), \
+ d##_g = XftOverO(x##_g,y##_g,a##_g,t##_g), \
+ d##_b = XftOverO(x##_b,y##_r,a##_b,t##_b))
+
#define XftInU(x,i,a,t) ((CARD32) XftIntMult(XftGet8(x,i),(a),(t)) << (i))
#define XftInC(x,i,a,t) ((CARD32) XftIntMult(XftGet8(x,i),XftGet8(a,i),(t)) << (i))
+#define XftInO(x,a,t) (XftIntMult(x,a,t))
+
+#define XftIn4U(d,x,a,t) (d##_a = XftInO(x##_a,a,t##_a), \
+ d##_r = XftInO(x##_r,a,t##_r), \
+ d##_g = XftInO(x##_g,a,t##_g), \
+ d##_b = XftInO(x##_b,a,t##_b))
+#define XftIn3C(dc,da,x,a,m,t1,t2) (dc##_r = XftInO(x##_r,XftGet8(m,16),t1##_r), \
+ da##_r = XftInO(a,XftGet8(m,16),t2##_r), \
+ dc##_g = XftInO(x##_g,XftGet8(m,8),t1##_g), \
+ da##_g = XftInO(a,XftGet8(m,8),t2##_g), \
+ dc##_b = XftInO(x##_b,XftGet8(m,0),t1##_b), \
+ da##_b = XftInO(a,XftGet8(m,0),t2##_b))
+
#define XftGen(x,y,i,ax,ay,t,u,v) ((t) = (XftIntMult(XftGet8(y,i),ay,(u)) + \
XftIntMult(XftGet8(x,i),ax,(v))),\
(CARD32) ((CARD8) ((t) | \
@@ -449,36 +562,69 @@
}
static void
+colorToGamma12 (XftColor *color,
+ CARD32 *dst_r,
+ CARD32 *dst_g,
+ CARD32 *dst_b)
+{
+ CARD32 src_a = color->color.alpha >> 8;
+ CARD32 t;
+
+#define fromDouble(a,d,t) XftIntMult(a,(gammaCurve(d) + (0.5 / 4095.)) * 4095, t)
+
+ if (src_a)
+ {
+ *dst_r = fromDouble(src_a, (double)color->color.red / color->color.alpha, t);
+ *dst_g = fromDouble(src_a, (double)color->color.green / color->color.alpha, t);
+ *dst_b = fromDouble(src_a, (double)color->color.blue / color->color.alpha, t);
+ }
+ else
+ *dst_r = *dst_g = *dst_b = 0;
+}
+
+#define cvtColorToGamma12(dst,color) colorToGamma12(color, &dst##_r, &dst##_g,
+&dst##_b)
+#define cvtColorToGamma12r(dst,color) colorToGamma12(color, &dst##_b, &dst##_g,
+&dst##_r)
+
+static void
_XftSmoothGlyphGray8888 (XImage *image,
XftGlyph *xftg,
int x,
int y,
XftColor *color)
{
- CARD32 src, srca;
- CARD32 r, g, b;
- CARD32 *dstLine, *dst, d;
+ XftDeclare4(src);
+ XftDeclare3(dst);
+ CARD32 src;
+ CARD32 r, g, b;
+ CARD32 *dstLine, *dst;
CARD8 *maskLine, *mask, m;
int dstStride, maskStride;
int width, height;
int w;
- srca = color->color.alpha >> 8;
+ gammaTablePrepare();
+
+ src_a = color->color.alpha >> 8;
/* This handles only RGB and BGR */
- g = (color->color.green & 0xff00);
+ src_g = gammaTable8[color->color.green >> 8];
+ g = color->color.green & 0xff00;
if (image->red_mask == 0xff0000)
{
r = (color->color.red & 0xff00) << 8;
b = color->color.blue >> 8;
+
+ cvtColorToGamma12(src, color);
}
else
{
- r = color->color.red >> 8;
b = (color->color.blue & 0xff00) << 8;
+ r = color->color.red >> 8;
+
+ cvtColorToGamma12r(src, color);
}
- src = (srca << 24) | r | g | b;
-
+ src = r | g | b;
+
width = xftg->metrics.width;
height = xftg->metrics.height;
@@ -503,15 +649,29 @@
m = *mask++;
if (m == 0xff)
{
- if (srca == 0xff)
+ if (src_a == 0xff)
*dst = src;
else
- *dst = fbOver24 (src, *dst);
+ {
+ XftDeclare3(tmpdst);
+ XftDeclare3(scratch1);
+
+ cvt0888toGamma12(tmpdst, *dst);
+ XftOver3U(dst, src, tmpdst, src_a, scratch1);
+ *dst = cvtGamma12to0888(dst);
+ }
}
else if (m)
{
- d = fbIn (src, m);
- *dst = fbOver24 (d, *dst);
+ XftDeclare3(tmpdst);
+ XftDeclare4(tmpsrc);
+ XftDeclare4(scratch1);
+ XftDeclare3(scratch2);
+
+ cvt0888toGamma12(tmpdst, *dst);
+ XftIn4U(tmpsrc, src, m, scratch1);
+ XftOver3U(dst, tmpsrc, tmpdst, tmpsrc_a, scratch2);
+ *dst = cvtGamma12to0888(dst);
}
dst++;
}
@@ -525,16 +685,19 @@
int y,
XftColor *color)
{
- CARD32 src, srca;
+ XftDeclare4(src);
+ XftDeclare3(dst);
+ CARD16 src;
CARD32 r, g, b;
- CARD32 d;
CARD16 *dstLine, *dst;
CARD8 *maskLine, *mask, m;
int dstStride, maskStride;
int width, height;
int w;
- srca = color->color.alpha >> 8;
+ gammaTablePrepare();
+
+ src_a = color->color.alpha >> 8;
/* This handles only RGB and BGR */
g = (color->color.green & 0xff00);
@@ -542,13 +705,17 @@
{
r = (color->color.red & 0xff00) << 8;
b = color->color.blue >> 8;
+
+ cvtColorToGamma12(src, color);
}
else
{
r = color->color.red >> 8;
b = (color->color.blue & 0xff00) << 8;
+
+ cvtColorToGamma12r(src, color);
}
- src = (srca << 24) | r | g | b;
+ src = cvt8888to0565(r | g | b);
width = xftg->metrics.width;
height = xftg->metrics.height;
@@ -574,20 +741,29 @@
m = *mask++;
if (m == 0xff)
{
- if (srca == 0xff)
- d = src;
+ if (src_a == 0xff)
+ *dst = src;
else
{
- d = *dst;
- d = fbOver24 (src, cvt0565to8888(d));
+ XftDeclare3(tmpdst);
+ XftDeclare3(scratch1);
+
+ cvt0565toGamma12(tmpdst, *dst);
+ XftOver3U(dst, src, tmpdst, src_a, scratch1);
+ *dst = cvtGamma12to0565(dst);
}
- *dst = cvt8888to0565(d);
}
else if (m)
{
- d = *dst;
- d = fbOver24 (fbIn(src,m), cvt0565to8888(d));
- *dst = cvt8888to0565(d);
+ XftDeclare3(tmpdst);
+ XftDeclare4(tmpsrc);
+ XftDeclare4(scratch1);
+ XftDeclare3(scratch2);
+
+ cvt0565toGamma12(tmpdst, *dst);
+ XftIn4U(tmpsrc, src, m, scratch1);
+ XftOver3U(dst, tmpsrc, tmpdst, tmpsrc_a, scratch2);
+ *dst = cvtGamma12to0565(dst);
}
dst++;
}
@@ -601,16 +777,19 @@
int y,
XftColor *color)
{
- CARD32 src, srca;
+ XftDeclare4(src);
+ XftDeclare3(dst);
+ CARD16 src;
CARD32 r, g, b;
- CARD32 d;
CARD16 *dstLine, *dst;
CARD8 *maskLine, *mask, m;
int dstStride, maskStride;
int width, height;
int w;
- srca = color->color.alpha >> 8;
+ gammaTablePrepare();
+
+ src_a = color->color.alpha >> 8;
/* This handles only RGB and BGR */
g = (color->color.green & 0xff00);
@@ -618,13 +797,17 @@
{
r = (color->color.red & 0xff00) << 8;
b = color->color.blue >> 8;
+
+ cvtColorToGamma12(src, color);
}
else
{
r = color->color.red >> 8;
b = (color->color.blue & 0xff00) << 8;
+
+ cvtColorToGamma12r(src, color);
}
- src = (srca << 24) | r | g | b;
+ src = cvt8888to0555(r | g | b);
width = xftg->metrics.width;
height = xftg->metrics.height;
@@ -650,20 +833,29 @@
m = *mask++;
if (m == 0xff)
{
- if (srca == 0xff)
- d = src;
+ if (src_a == 0xff)
+ *dst = src;
else
{
- d = *dst;
- d = fbOver24 (src, cvt0555to8888(d));
+ XftDeclare3(tmpdst);
+ XftDeclare3(scratch1);
+
+ cvt0555toGamma12(tmpdst, *dst);
+ XftOver3U(dst, src, tmpdst, src_a, scratch1);
+ *dst = cvtGamma12to0555(dst);
}
- *dst = cvt8888to0555(d);
}
else if (m)
{
- d = *dst;
- d = fbOver24 (fbIn(src,m), cvt0555to8888(d));
- *dst = cvt8888to0555(d);
+ XftDeclare3(tmpdst);
+ XftDeclare4(tmpsrc);
+ XftDeclare4(scratch1);
+ XftDeclare3(scratch2);
+
+ cvt0555toGamma12(tmpdst, *dst);
+ XftIn4U(tmpsrc, src, m, scratch1);
+ XftOver3U(dst, tmpsrc, tmpdst, tmpsrc_a, scratch2);
+ *dst = cvtGamma12to0555(dst);
}
dst++;
}
@@ -677,22 +869,22 @@
int y,
XftColor *color)
{
- CARD32 src, srca;
+ XftDeclare4(src);
+ XftDeclare3(dst);
int r_shift, r_len;
int g_shift, g_len;
int b_shift, b_len;
CARD8 *maskLine, *mask, m;
int maskStride;
- CARD32 d;
unsigned long pixel;
int width, height;
int w, tx;
- srca = color->color.alpha >> 8;
- src = (srca << 24 |
- (color->color.red & 0xff00) << 8 |
- (color->color.green & 0xff00) |
- (color->color.blue) >> 8);
+ gammaTablePrepare();
+
+ src_a = color->color.alpha >> 8;
+ cvtColorToGamma12 (src, color);
+
x -= xftg->metrics.x;
y -= xftg->metrics.y;
width = xftg->metrics.width;
@@ -716,31 +908,42 @@
m = *mask++;
if (m == 0xff)
{
- if (srca == 0xff)
- d = src;
+ if (src_a == 0xff)
+ XftAssign3(dst,src);
else
{
+ XftDeclare3(tmpdst);
+ XftDeclare3(scratch1);
+
pixel = XGetPixel (image, tx, y);
- d = (_XftGetField (pixel, r_shift, r_len) << 16 |
- _XftGetField (pixel, g_shift, g_len) << 8 |
- _XftGetField (pixel, b_shift, b_len));
- d = fbOver24 (src, d);
+ XftAssignRGB(tmpdst,
+ gammaTable8[_XftGetField (pixel, r_shift, r_len)],
+ gammaTable8[_XftGetField (pixel, g_shift, g_len)],
+ gammaTable8[_XftGetField (pixel, b_shift, b_len)]);
+ XftOver3U(dst, src, tmpdst, src_a, scratch1);
}
- pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
- _XftPutField ((d >> 8) & 0xff, g_shift, g_len) |
- _XftPutField ((d ) & 0xff, b_shift, b_len));
+ pixel = (_XftPutField (gammaTableInv[dst_r], r_shift, r_len) |
+ _XftPutField (gammaTableInv[dst_g], g_shift, g_len) |
+ _XftPutField (gammaTableInv[dst_b], b_shift, b_len));
XPutPixel (image, tx, y, pixel);
}
else if (m)
{
+ XftDeclare3(tmpdst);
+ XftDeclare4(tmpsrc);
+ XftDeclare4(scratch1);
+ XftDeclare3(scratch2);
+
pixel = XGetPixel (image, tx, y);
- d = (_XftGetField (pixel, r_shift, r_len) << 16 |
- _XftGetField (pixel, g_shift, g_len) << 8 |
- _XftGetField (pixel, b_shift, b_len));
- d = fbOver24 (fbIn(src,m), d);
- pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
- _XftPutField ((d >> 8) & 0xff, g_shift, g_len) |
- _XftPutField ((d ) & 0xff, b_shift, b_len));
+ XftAssignRGB(tmpdst,
+ gammaTable8[_XftGetField (pixel, r_shift, r_len)],
+ gammaTable8[_XftGetField (pixel, g_shift, g_len)],
+ gammaTable8[_XftGetField (pixel, b_shift, b_len)]);
+ XftIn4U(tmpsrc, src, m, scratch1);
+ XftOver3U(dst, tmpsrc, tmpdst, tmpsrc_a, scratch2);
+ pixel = (_XftPutField (gammaTableInv[dst_r], r_shift, r_len) |
+ _XftPutField (gammaTableInv[dst_g], g_shift, g_len) |
+ _XftPutField (gammaTableInv[dst_b], b_shift, b_len));
XPutPixel (image, tx, y, pixel);
}
tx++;
@@ -756,21 +959,22 @@
int y,
XftColor *color)
{
- CARD32 src, srca;
+ XftDeclare3(src);
+ XftDeclare3(dst);
+ CARD32 src_a;
int r_shift, r_len;
int g_shift, g_len;
int b_shift, b_len;
CARD32 *mask, ma;
- CARD32 d;
unsigned long pixel;
int width, height;
int w, tx;
- srca = color->color.alpha >> 8;
- src = (srca << 24 |
- (color->color.red & 0xff00) << 8 |
- (color->color.green & 0xff00) |
- (color->color.blue) >> 8);
+ gammaTablePrepare();
+
+ src_a = color->color.alpha >> 8;
+ cvtColorToGamma12(src, color);
+
x -= xftg->metrics.x;
y -= xftg->metrics.y;
width = xftg->metrics.width;
@@ -791,45 +995,45 @@
ma = *mask++;
if (ma == 0xffffffff)
{
- if (srca == 0xff)
- d = src;
+ if (src_a == 0xff)
+ XftAssign3(dst,src);
else
{
+ XftDeclare3(tmpdst);
+ XftDeclare3(scratch1);
+
pixel = XGetPixel (image, tx, y);
- d = (_XftGetField (pixel, r_shift, r_len) << 16 |
- _XftGetField (pixel, g_shift, g_len) << 8 |
- _XftGetField (pixel, b_shift, b_len));
- d = fbOver24 (src, d);
+ XftAssignRGB(tmpdst,
+ gammaTable8[_XftGetField (pixel, r_shift, r_len)],
+ gammaTable8[_XftGetField (pixel, g_shift, g_len)],
+ gammaTable8[_XftGetField (pixel, b_shift, b_len)]);
+ XftOver3U(dst, src, tmpdst, src_a, scratch1);
}
- pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
- _XftPutField ((d >> 8) & 0xff, g_shift, g_len) |
- _XftPutField ((d ) & 0xff, b_shift, b_len));
+ pixel = (_XftPutField (gammaTableInv[dst_r], r_shift, r_len) |
+ _XftPutField (gammaTableInv[dst_g], g_shift, g_len) |
+ _XftPutField (gammaTableInv[dst_b], b_shift, b_len));
XPutPixel (image, tx, y, pixel);
}
else if (ma)
{
- CARD32 m,n,o;
+ XftDeclare3(tmpdst);
+ XftDeclare3(tmpsrc);
+ XftDeclare3(tmpa);
+ XftDeclare3(scratch1);
+ XftDeclare3(scratch2);
+ XftDeclare3(scratch3);
+
pixel = XGetPixel (image, tx, y);
- d = (_XftGetField (pixel, r_shift, r_len) << 16 |
- _XftGetField (pixel, g_shift, g_len) << 8 |
- _XftGetField (pixel, b_shift, b_len));
-#define XftInOverC(src,srca,msk,dst,i,result) { \
- CARD16 __a = XftGet8(msk,i); \
- CARD32 __t, __ta; \
- CARD32 __i; \
- __t = XftIntMult (XftGet8(src,i), __a,__i); \
- __ta = (CARD8) ~XftIntMult (srca, __a,__i); \
- __t = __t + XftIntMult(XftGet8(dst,i),__ta,__i); \
- __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \
- result = __t << (i); \
-}
- XftInOverC(src,srca,ma,d,0,m);
- XftInOverC(src,srca,ma,d,8,n);
- XftInOverC(src,srca,ma,d,16,o);
- d = m | n | o;
- pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
- _XftPutField ((d >> 8) & 0xff, g_shift, g_len) |
- _XftPutField ((d ) & 0xff, b_shift, b_len));
+ XftAssignRGB(tmpdst,
+ gammaTable8[_XftGetField (pixel, r_shift, r_len)],
+ gammaTable8[_XftGetField (pixel, g_shift, g_len)],
+ gammaTable8[_XftGetField (pixel, b_shift, b_len)]);
+ XftIn3C(tmpsrc, tmpa, src, src_a, ma, scratch1, scratch2);
+ XftOver3C(dst, tmpsrc, tmpdst, tmpa, scratch3);
+
+ pixel = (_XftPutField (gammaTableInv[dst_r], r_shift, r_len) |
+ _XftPutField (gammaTableInv[dst_g], g_shift, g_len) |
+ _XftPutField (gammaTableInv[dst_b], b_shift, b_len));
XPutPixel (image, tx, y, pixel);
}
tx++;