Add support for gradients and solid fills to Render.

Changed the semantics of the Convolution filter a bit. It now doesn't try
    to normalize the filter values but leaves this to the client. This
    gives more reasonable behaviour in the limit where the filter
    parameters sum up to 0.
This commit is contained in:
Lars Knoll 2005-07-01 10:05:43 +00:00
parent 30c019e847
commit b5b2a0522e
8 changed files with 989 additions and 99 deletions

View File

@ -34,6 +34,7 @@
#include "picturestr.h"
#include "mipict.h"
#include "fbpict.h"
#include <math.h>
#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
@ -2636,6 +2637,219 @@ static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread)
{
int ipos = (pos * PICT_GRADIENT_STOPTABLE_SIZE - 1) >> 16;
/* calculate the actual offset. */
if (ipos < 0 || ipos >= PICT_GRADIENT_STOPTABLE_SIZE) {
if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal) {
ipos = ipos % PICT_GRADIENT_STOPTABLE_SIZE;
ipos = ipos < 0 ? PICT_GRADIENT_STOPTABLE_SIZE + ipos : ipos;
} else if (spread == RepeatReflect) {
const int limit = PICT_GRADIENT_STOPTABLE_SIZE * 2 - 1;
ipos = ipos % limit;
ipos = ipos < 0 ? limit + ipos : ipos;
ipos = ipos >= PICT_GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos;
} else if (spread == RepeatPad) {
if (ipos < 0)
ipos = 0;
else if (ipos >= PICT_GRADIENT_STOPTABLE_SIZE)
ipos = PICT_GRADIENT_STOPTABLE_SIZE-1;
} else { /* RepeatNone */
return 0;
}
}
assert(ipos >= 0);
assert(ipos < PICT_GRADIENT_STOPTABLE_SIZE);
return pGradient->linear.colorTable[ipos];
}
static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
{
SourcePictPtr pGradient = pict->pSourcePict;
CARD32 *end = buffer + width;
if (pGradient->type == SourcePictTypeSolidFill) {
register CARD32 color = pGradient->solidFill.color;
while (buffer < end) {
*buffer++ = color;
}
} else if (pGradient->type == SourcePictTypeLinear) {
PictVector v, unit;
xFixed_32_32 l;
xFixed_48_16 dx, dy, a, b, off;
v.vector[0] = IntToxFixed(x);
v.vector[1] = IntToxFixed(y);
v.vector[2] = xFixed1;
if (pict->transform) {
if (!PictureTransformPoint3d (pict->transform, &v))
return;
unit.vector[0] = pict->transform->matrix[0][0];
unit.vector[1] = pict->transform->matrix[1][0];
unit.vector[2] = pict->transform->matrix[2][0];
} else {
unit.vector[0] = xFixed1;
unit.vector[1] = 0;
unit.vector[2] = 0;
}
dx = pGradient->linear.p2.x - pGradient->linear.p1.x;
dy = pGradient->linear.p2.y - pGradient->linear.p1.y;
l = dx*dx + dy*dy;
if (l != 0) {
a = (dx << 32) / l;
b = (dy << 32) / l;
off = (-a*pGradient->linear.p1.x - b*pGradient->linear.p1.y)>>16;
}
if (l == 0 || (unit.vector[2] == 0 && v.vector[2] == xFixed1)) {
xFixed_48_16 inc, t;
/* affine transformation only */
if (l == 0) {
t = 0;
inc = 0;
} else {
t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
}
while (buffer < end) {
*buffer++ = gradientPixel(pGradient, t, pict->repeat);
t += inc;
}
} else {
/* projective transformation */
while (buffer < end) {
xFixed_48_16 t;
if (v.vector[2] == 0) {
t = 0;
} else {
xFixed_48_16 x, y;
x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
t = ((a*x + b*y) >> 16) + off;
}
*buffer++ = gradientPixel(pGradient, t, pict->repeat);
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
} else {
/* radial or conical */
Bool projective = FALSE;
double cx = 1.;
double cy = 0.;
double cz = 0.;
double rx = x;
double ry = y;
double rz = 1.;
if (pict->transform) {
PictVector v;
v.vector[0] = IntToxFixed(x);
v.vector[1] = IntToxFixed(y);
v.vector[2] = xFixed1;
if (!PictureTransformPoint3d (pict->transform, &v))
return;
cx = pict->transform->matrix[0][0]/65536.;
cy = pict->transform->matrix[1][0]/65536.;
cz = pict->transform->matrix[2][0]/65536.;
rx = v.vector[0]/65536.;
ry = v.vector[1]/65536.;
rz = v.vector[2]/65536.;
projective = pict->transform->matrix[2][0] != 0 || v.vector[2] != xFixed1;
}
if (pGradient->type == SourcePictTypeRadial) {
if (!projective) {
rx -= pGradient->radial.fx;
ry -= pGradient->radial.fy;
while (buffer < end) {
double b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
double c = -(rx*rx + ry*ry);
double det = (b * b) - (4 * pGradient->radial.a * c);
double s = (-b + sqrt(det))/(2. * pGradient->radial.a);
*buffer = gradientPixel(pGradient,
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
pict->repeat);
++buffer;
rx += cx;
ry += cy;
}
} else {
while (buffer < end) {
double x, y;
double b, c, det, s;
if (rz != 0) {
x = rx/rz;
y = ry/rz;
} else {
x = y = 0.;
}
x -= pGradient->radial.fx;
y -= pGradient->radial.fy;
b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
c = -(x*x + y*y);
det = (b * b) - (4 * pGradient->radial.a * c);
s = (-b + sqrt(det))/(2. * pGradient->radial.a);
*buffer = gradientPixel(pGradient,
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
pict->repeat);
++buffer;
rx += cx;
ry += cy;
rz += cz;
}
}
} else /* SourcePictTypeConical */ {
double a = pGradient->conical.angle/(180.*65536);
if (!projective) {
rx -= pGradient->conical.center.x/65536.;
ry -= pGradient->conical.center.y/65536.;
while (buffer < end) {
double angle = atan2(ry, rx) + a;
*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
pict->repeat);
++buffer;
rx += cx;
ry += cy;
}
} else {
while (buffer < end) {
double x, y, angle;
if (rz != 0) {
x = rx/rz;
y = ry/rz;
} else {
x = y = 0.;
}
x -= pGradient->conical.center.x/65536.;
y -= pGradient->conical.center.y/65536.;
angle = atan2(y, x) + a;
*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
pict->repeat);
++buffer;
rx += cx;
ry += cy;
rz += cz;
}
}
}
}
}
static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
{
FbBits *bits;
@ -2674,7 +2888,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (pict->filter == PictFilterNearest)
{
if (pict->repeat) {
if (pict->repeat == RepeatNormal) {
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
box = pict->pCompositeClip->extents;
for (i = 0; i < width; ++i) {
@ -2741,7 +2955,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
}
}
} else if (pict->filter == PictFilterBilinear) {
if (pict->repeat) {
if (pict->repeat == RepeatNormal) {
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
box = pict->pCompositeClip->extents;
for (i = 0; i < width; ++i) {
@ -2943,7 +3157,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
params += 2;
for (i = 0; i < width; ++i) {
int x1, x2, y1, y2, x, y;
INT32 srtot, sgtot, sbtot, satot, sum;
INT32 srtot, sgtot, sbtot, satot;
xFixed *p = params;
xFixed_48_16 tmp;
@ -2962,13 +3176,13 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
y1 = xFixedToInt(tmp);
y2 = y1 + cheight;
srtot = sgtot = sbtot = satot = sum = 0;
srtot = sgtot = sbtot = satot = 0;
for (y = y1; y < y2; y++) {
int ty = (pict->repeat) ? MOD (y, pict->pDrawable->height) : y;
int ty = (pict->repeat == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
for (x = x1; x < x2; x++) {
if (*p) {
int tx = (pict->repeat) ? MOD (x, pict->pDrawable->width) : x;
int tx = (pict->repeat == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
if (POINT_IN_REGION (0, pict->pCompositeClip, tx, ty, &box)) {
FbBits *b = bits + (ty + pict->pDrawable->y)*stride;
CARD32 c = fetch(b, tx + pict->pDrawable->x, indexed);
@ -2978,22 +3192,15 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
sbtot += Blue(c) * *p;
satot += Alpha(c) * *p;
}
sum += *p;
}
p++;
}
}
if (sum) {
satot /= sum;
srtot /= sum;
sgtot /= sum;
sbtot /= sum;
}
if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
if (srtot < 0) srtot = 0; else if (srtot > satot) srtot = satot;
if (sgtot < 0) sgtot = 0; else if (sgtot > satot) sgtot = satot;
if (sbtot < 0) sbtot = 0; else if (sbtot > satot) sbtot = satot;
buffer[i] = ((satot << 24) |
(srtot << 16) |
@ -3094,13 +3301,17 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
CARD32 *dest_buffer = src_buffer + data->width;
int i;
scanStoreProc store;
scanFetchProc fetchSrc, fetchMask, fetchDest;
scanFetchProc fetchSrc = 0, fetchMask = 0, fetchDest = 0;
if (data->op == PictOpClear)
fetchSrc = 0;
else if (data->src->alphaMap)
else if (!data->src->pDrawable) {
if (data->src->pSourcePict)
fetchSrc = fbFetchSourcePict;
} else if (data->src->alphaMap)
fetchSrc = fbFetchExternalAlpha;
else if (data->src->repeat && data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
else if (data->src->repeat == RepeatNormal &&
data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
fetchSrc = fbFetchSolid;
else if (!data->src->transform && data->src->filter != PictFilterConvolution)
fetchSrc = fbFetch;
@ -3108,9 +3319,13 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
fetchSrc = fbFetchTransformed;
if (data->mask && data->op != PictOpClear) {
if (data->mask->alphaMap)
if (!data->mask->pDrawable) {
if (data->mask->pSourcePict)
fetchMask = fbFetchSourcePict;
} else if (data->mask->alphaMap)
fetchMask = fbFetchExternalAlpha;
else if (data->mask->repeat && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
else if (data->mask->repeat == RepeatNormal
&& data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
fetchMask = fbFetchSolid;
else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
fetchMask = fbFetch;
@ -3211,17 +3426,19 @@ fbCompositeGeneral (CARD8 op,
RegionRec region;
int n;
BoxPtr pbox;
Bool srcRepeat = pSrc->repeat && !pSrc->transform
&& (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
Bool srcRepeat = FALSE;
Bool maskRepeat = FALSE;
int w, h;
CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH*3];
CARD32 *scanline_buffer = _scanline_buffer;
FbComposeData compose_data;
if (pSrc->pDrawable)
srcRepeat = pSrc->repeat == RepeatNormal && !pSrc->transform
&& (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
if (pMask)
maskRepeat = pMask->repeat && !pMask->transform
if (pMask && pMask->pDrawable)
maskRepeat = pMask->repeat == RepeatNormal && !pMask->transform
&& (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
if (op == PictOpOver && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format))

View File

@ -838,7 +838,7 @@ fbComposite (CARD8 op,
int n;
BoxPtr pbox;
CompositeFunc func = 0;
Bool srcRepeat = pSrc->repeat;
Bool srcRepeat = pSrc->pDrawable && pSrc->repeat == RepeatNormal;
Bool maskRepeat = FALSE;
Bool srcAlphaMap = pSrc->alphaMap != 0;
Bool maskAlphaMap = FALSE;
@ -848,20 +848,23 @@ fbComposite (CARD8 op,
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
if (pMask)
if (pSrc->pDrawable) {
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
}
if (pMask && pMask->pDrawable)
{
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
maskRepeat = pMask->repeat;
maskRepeat = pMask->repeat == RepeatNormal;
maskAlphaMap = pMask->alphaMap != 0;
}
if (!pSrc->transform && !(pMask && pMask->transform)
&& !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
&& (pSrc->filter != PictFilterConvolution)
&& (!pMask || pMask->filter != PictFilterConvolution))
if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
&& !pSrc->transform && !(pMask && pMask->transform)
&& !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
&& (pSrc->filter != PictFilterConvolution)
&& (!pMask || pMask->filter != PictFilterConvolution))
switch (op) {
case PictOpSrc:
#ifdef USE_MMX

View File

@ -224,11 +224,11 @@
#define FbByteAdd(x, y) do { \
CARD32 t; \
CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \
r |= 0 - ((r >> 8) & 0xff00ff); \
r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
r &= 0xff00ff; \
\
t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \
t |= 0 - ((t >> 8) & 0xff00ff); \
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
r |= (t & 0xff00ff) << 8; \
x = r; \
} while (0)

View File

@ -504,21 +504,22 @@ XAAComposite (CARD8 op,
if((op == PictOpSrc) && !pMask && infoRec->pScrn->vtSema &&
infoRec->ScreenToScreenBitBlt &&
pSrc->pDrawable &&
DRAWABLE_IS_ON_CARD(pSrc->pDrawable) &&
DRAWABLE_IS_ON_CARD(pDst->pDrawable) &&
!pSrc->transform && !pSrc->repeat && (pSrc->format == pDst->format))
{
XAACompositeSrcCopy(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height);
} else if(!infoRec->Composite ||
!(*infoRec->Composite)(op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height))
} else if(!pSrc->pDrawable || (pMask && !pMask->pDrawable) ||
!infoRec->Composite ||
!(*infoRec->Composite)(op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height))
{
if((pSrc->pDrawable->type == DRAWABLE_WINDOW ||
pDst->pDrawable->type == DRAWABLE_WINDOW ||
IS_OFFSCREEN_PIXMAP(pSrc->pDrawable) ||
IS_OFFSCREEN_PIXMAP(pDst->pDrawable))
&& infoRec->pScrn->vtSema) {
if(infoRec->pScrn->vtSema &&
((pSrc->pDrawable &&
(pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
SYNC_CHECK(pDst->pDrawable);
}
(*GetPictureScreen(pScreen)->Composite) (op,
@ -745,17 +746,16 @@ XAAGlyphs (CARD8 op,
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
XAA_RENDER_PROLOGUE(pScreen, Glyphs);
if(!infoRec->Glyphs ||
if(!pSrc->pDrawable || !infoRec->Glyphs ||
!(*infoRec->Glyphs)(op, pSrc, pDst, maskFormat,
xSrc, ySrc, nlist, list, glyphs))
xSrc, ySrc, nlist, list, glyphs))
{
if(((pSrc->pDrawable->type == DRAWABLE_WINDOW) ||
(pDst->pDrawable->type == DRAWABLE_WINDOW) ||
IS_OFFSCREEN_PIXMAP(pSrc->pDrawable) ||
IS_OFFSCREEN_PIXMAP(pDst->pDrawable))
&& infoRec->pScrn->vtSema) {
SYNC_CHECK(pDst->pDrawable);
}
if(infoRec->pScrn->vtSema &&
((pSrc->pDrawable &&
(pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
SYNC_CHECK(pDst->pDrawable);
}
(*GetPictureScreen(pScreen)->Glyphs) (op, pSrc, pDst, maskFormat,
xSrc, ySrc, nlist, list, glyphs);
}

View File

@ -296,7 +296,7 @@ miClipPictureSrc (RegionPtr pRegion,
int dy)
{
/* XXX what to do with clipping from transformed pictures? */
if (pPicture->transform)
if (pPicture->transform || !pPicture->pDrawable)
return TRUE;
if (pPicture->repeat)
{
@ -331,7 +331,12 @@ miCompositeSourceValidate (PicturePtr pPicture,
CARD16 height)
{
DrawablePtr pDrawable = pPicture->pDrawable;
ScreenPtr pScreen = pDrawable->pScreen;
ScreenPtr pScreen;
if (!pDrawable)
return;
pScreen = pDrawable->pScreen;
if (pScreen->SourceValidate)
{
@ -521,8 +526,13 @@ miFillColor (CARD32 pixel, int bits)
Bool
miIsSolidAlpha (PicturePtr pSrc)
{
ScreenPtr pScreen = pSrc->pDrawable->pScreen;
ScreenPtr pScreen;
char line[1];
if (!pSrc->pDrawable)
return FALSE;
pScreen = pSrc->pDrawable->pScreen;
/* Alpha-only */
if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A)

View File

@ -762,6 +762,7 @@ SetPictureToDefaults (PicturePtr pPicture)
pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
pPicture->pSourcePict = 0;
}
PicturePtr
@ -845,6 +846,301 @@ CreatePicture (Picture pid,
return pPicture;
}
static CARD32 xRenderColorToCard32(xRenderColor c)
{
return
(c.alpha >> 8 << 24) |
(c.red >> 8 << 16) |
(c.green & 0xff00) |
(c.blue >> 8);
}
static uint premultiply(uint x)
{
uint a = x >> 24;
uint t = (x & 0xff00ff) * a;
t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
t &= 0xff00ff;
x = ((x >> 8) & 0xff) * a;
x = (x + ((x >> 8) & 0xff) + 0x80);
x &= 0xff00;
x |= t | (a << 24);
return x;
}
static uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b)
{
CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
t >>= 8;
t &= 0xff00ff;
x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
x &= 0xff00ff00;
x |= t;
return x;
}
static void initGradientColorTable(SourcePictPtr pGradient, int *error)
{
int begin_pos, end_pos;
xFixed incr, dpos;
int pos, current_stop;
PictGradientStopPtr stops = pGradient->linear.stops;
int nstops = pGradient->linear.nstops;
/* The position where the gradient begins and ends */
begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
pos = 0; /* The position in the color table. */
/* Up to first point */
while (pos <= begin_pos) {
pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
++pos;
}
incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
dpos = incr * pos; /* The position in terms of 0-1. */
current_stop = 0; /* We always interpolate between current and current + 1. */
/* Gradient area */
while (pos < end_pos) {
uint current_color = xRenderColorToCard32(stops[current_stop].color);
uint next_color = xRenderColorToCard32(stops[current_stop + 1].color);
int dist = (int)(256*(dpos - stops[current_stop].x)
/ (stops[current_stop+1].x - stops[current_stop].x));
int idist = 256 - dist;
pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
++pos;
dpos += incr;
if (dpos > stops[current_stop + 1].x)
++current_stop;
}
/* After last point */
while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
++pos;
}
}
static void initGradient(SourcePictPtr pGradient, int stopCount,
xFixed *stopPoints, xRenderColor *stopColors, int *error)
{
int i;
xFixed dpos;
if (stopCount <= 0) {
*error = BadValue;
return;
}
dpos = -1;
for (i = 0; i < stopCount; ++i) {
if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
*error = BadValue;
return;
}
dpos = stopPoints[i];
}
pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
if (!pGradient->linear.stops) {
*error = BadAlloc;
return;
}
pGradient->linear.nstops = stopCount;
for (i = 0; i < stopCount; ++i) {
pGradient->linear.stops[i].x = stopPoints[i];
pGradient->linear.stops[i].color = stopColors[i];
}
initGradientColorTable(pGradient, error);
}
static PicturePtr createSourcePicture(void)
{
PicturePtr pPicture;
pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
pPicture->pDrawable = 0;
pPicture->pFormat = 0;
pPicture->pNext = 0;
SetPictureToDefaults(pPicture);
return pPicture;
}
PicturePtr
CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
{
PicturePtr pPicture;
pPicture = createSourcePicture();
if (!pPicture) {
*error = BadAlloc;
return 0;
}
pPicture->id = pid;
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
if (!pPicture->pSourcePict) {
*error = BadAlloc;
xfree(pPicture);
return 0;
}
pPicture->pSourcePict->type = SourcePictTypeSolidFill;
pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
return pPicture;
}
PicturePtr
CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
int nStops, xFixed *stops, xRenderColor *colors, int *error)
{
PicturePtr pPicture;
if (nStops < 2) {
*error = BadValue;
return 0;
}
pPicture = createSourcePicture();
if (!pPicture) {
*error = BadAlloc;
return 0;
}
if (p1->x == p2->x && p1->y == p2->y) {
*error = BadValue;
return 0;
}
pPicture->id = pid;
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
if (!pPicture->pSourcePict) {
*error = BadAlloc;
xfree(pPicture);
return 0;
}
pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
pPicture->pSourcePict->linear.p1 = *p1;
pPicture->pSourcePict->linear.p2 = *p2;
initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
if (*error) {
xfree(pPicture);
return 0;
}
return pPicture;
}
#define FixedToDouble(x) ((x)/65536.)
PicturePtr
CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
xFixed innerRadius, xFixed outerRadius,
int nStops, xFixed *stops, xRenderColor *colors, int *error)
{
PicturePtr pPicture;
PictRadialGradient *radial;
if (nStops < 2) {
*error = BadValue;
return 0;
}
pPicture = createSourcePicture();
if (!pPicture) {
*error = BadAlloc;
return 0;
}
{
double dx = (double)(inner->x - outer->x);
double dy = (double)(inner->y - outer->y);
if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
*error = BadValue;
return 0;
}
}
pPicture->id = pid;
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
if (!pPicture->pSourcePict) {
*error = BadAlloc;
xfree(pPicture);
return 0;
}
radial = &pPicture->pSourcePict->radial;
radial->type = SourcePictTypeRadial;
{
double x = (double)innerRadius / (double)outerRadius;
radial->dx = (outer->x - inner->x);
radial->dy = (outer->y - inner->y);
radial->fx = (inner->x) - x*radial->dx;
radial->fy = (inner->y) - x*radial->dy;
radial->m = 1./(1+x);
radial->b = -x*radial->m;
radial->dx /= 65536.;
radial->dy /= 65536.;
radial->fx /= 65536.;
radial->fy /= 65536.;
x = outerRadius/65536.;
radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
}
initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
if (*error) {
xfree(pPicture);
return 0;
}
return pPicture;
}
PicturePtr
CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
int nStops, xFixed *stops, xRenderColor *colors, int *error)
{
PicturePtr pPicture;
if (nStops < 2) {
*error = BadValue;
return 0;
}
pPicture = createSourcePicture();
if (!pPicture) {
*error = BadAlloc;
return 0;
}
pPicture->id = pid;
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
if (!pPicture->pSourcePict) {
*error = BadAlloc;
xfree(pPicture);
return 0;
}
pPicture->pSourcePict->conical.type = SourcePictTypeConical;
pPicture->pSourcePict->conical.center = *center;
pPicture->pSourcePict->conical.angle = angle;
initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
if (*error) {
xfree(pPicture);
return 0;
}
return pPicture;
}
#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
#define NEXT_PTR(_type) ((_type) ulist++->ptr)
@ -856,8 +1152,8 @@ ChangePicture (PicturePtr pPicture,
DevUnion *ulist,
ClientPtr client)
{
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
BITS32 index2;
int error = 0;
BITS32 maskQ;
@ -875,7 +1171,7 @@ ChangePicture (PicturePtr pPicture,
{
unsigned int newr;
newr = NEXT_VAL(unsigned int);
if (newr <= xTrue)
if (newr <= RepeatReflect)
pPicture->repeat = newr;
else
{
@ -943,6 +1239,8 @@ ChangePicture (PicturePtr pPicture,
Pixmap pid;
PixmapPtr pPixmap;
int clipType;
if (!pScreen)
return BadDrawable;
if (vlist)
{
@ -1069,7 +1367,8 @@ ChangePicture (PicturePtr pPicture,
break;
}
}
(*ps->ChangePicture) (pPicture, maskQ);
if (ps)
(*ps->ChangePicture) (pPicture, maskQ);
return error;
}
@ -1268,7 +1567,7 @@ CopyPicture (PicturePtr pSrc,
static void
ValidateOnePicture (PicturePtr pPicture)
{
if (pPicture->serialNumber != pPicture->pDrawable->serialNumber)
if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
{
PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
@ -1294,35 +1593,43 @@ FreePicture (pointer value,
if (--pPicture->refcnt == 0)
{
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
if (pPicture->alphaMap)
FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
(*ps->DestroyPicture) (pPicture);
(*ps->DestroyPictureClip) (pPicture);
if (pPicture->transform)
xfree (pPicture->transform);
if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
{
WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
PicturePtr *pPrev;
if (!pPicture->pDrawable) {
if (pPicture->pSourcePict) {
if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
xfree(pPicture->pSourcePict->linear.stops);
xfree(pPicture->pSourcePict);
}
} else {
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
if (pPicture->alphaMap)
FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
(*ps->DestroyPicture) (pPicture);
(*ps->DestroyPictureClip) (pPicture);
if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
{
WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
PicturePtr *pPrev;
for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
*pPrev;
pPrev = &(*pPrev)->pNext)
{
if (*pPrev == pPicture)
{
*pPrev = pPicture->pNext;
break;
}
}
}
else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
{
(*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
}
for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
*pPrev;
pPrev = &(*pPrev)->pNext)
{
if (*pPrev == pPicture)
{
*pPrev = pPicture->pNext;
break;
}
}
}
else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
{
(*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
}
}
xfree (pPicture);
}
return Success;

View File

@ -62,6 +62,70 @@ typedef struct _PictTransform {
xFixed matrix[3][3];
} PictTransform, *PictTransformPtr;
#define PICT_GRADIENT_STOPTABLE_SIZE 1024
#define SourcePictTypeSolidFill 0
#define SourcePictTypeLinear 1
#define SourcePictTypeRadial 2
#define SourcePictTypeConical 3
typedef struct _PictSolidFill {
unsigned int type;
CARD32 color;
} PictSolidFill, *PictSolidFillPtr;
typedef struct _PictGradientStop {
xFixed x;
xRenderColor color;
} PictGradientStop, *PictGradientStopPtr;
typedef struct _PictGradient {
unsigned int type;
int nstops;
PictGradientStopPtr stops;
CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
} PictGradient, *PictGradientPtr;
typedef struct _PictLinearGradient {
unsigned int type;
int nstops;
PictGradientStopPtr stops;
CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
xPointFixed p1;
xPointFixed p2;
} PictLinearGradient, *PictLinearGradientPtr;
typedef struct _PictRadialGradient {
unsigned int type;
int nstops;
PictGradientStopPtr stops;
CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
double fx;
double fy;
double dx;
double dy;
double a;
double m;
double b;
} PictRadialGradient, *PictRadialGradientPtr;
typedef struct _PictConicalGradient {
unsigned int type;
int nstops;
PictGradientStopPtr stops;
CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
xPointFixed center;
xFixed angle;
} PictConicalGradient, *PictConicalGradientPtr;
typedef union _SourcePict {
unsigned int type;
PictSolidFill solidFill;
PictGradient gradient;
PictLinearGradient linear;
PictRadialGradient radial;
PictConicalGradient conical;
} SourcePict, *SourcePictPtr;
typedef struct _Picture {
DrawablePtr pDrawable;
PictFormatPtr pFormat;
@ -70,7 +134,7 @@ typedef struct _Picture {
CARD32 id;
PicturePtr pNext; /* chain on same drawable */
unsigned int repeat : 1;
unsigned int repeat : 2;
unsigned int graphicsExposures : 1;
unsigned int subWindowMode : 1;
unsigned int polyEdge : 1;
@ -78,7 +142,7 @@ typedef struct _Picture {
unsigned int freeCompClip : 1;
unsigned int clientClipType : 2;
unsigned int componentAlpha : 1;
unsigned int unused : 23;
unsigned int unused : 22;
PicturePtr alphaMap;
DDXPointRec alphaOrigin;
@ -100,6 +164,7 @@ typedef struct _Picture {
int filter;
xFixed *filter_params;
int filter_nparams;
SourcePictPtr pSourcePict;
} PictureRec;
typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
@ -546,6 +611,40 @@ AddTraps (PicturePtr pPicture,
int ntraps,
xTrap *traps);
PicturePtr
CreateSolidPicture (Picture pid,
xRenderColor *color,
int *error);
PicturePtr
CreateLinearGradientPicture (Picture pid,
xPointFixed *p1,
xPointFixed *p2,
int nStops,
xFixed *stops,
xRenderColor *colors,
int *error);
PicturePtr
CreateRadialGradientPicture (Picture pid,
xPointFixed *inner,
xPointFixed *outer,
xFixed innerRadius,
xFixed outerRadius,
int nStops,
xFixed *stops,
xRenderColor *colors,
int *error);
PicturePtr
CreateConicalGradientPicture (Picture pid,
xPointFixed *center,
xFixed angle,
int nStops,
xFixed *stops,
xRenderColor *colors,
int *error);
#ifdef PANORAMIX
void PanoramiXRenderInit (void);
void PanoramiXRenderReset (void);

View File

@ -79,6 +79,10 @@ static int ProcRenderQueryFilters (ClientPtr pClient);
static int ProcRenderSetPictureFilter (ClientPtr pClient);
static int ProcRenderCreateAnimCursor (ClientPtr pClient);
static int ProcRenderAddTraps (ClientPtr pClient);
static int ProcRenderCreateSolidFill (ClientPtr pClient);
static int ProcRenderCreateLinearGradient (ClientPtr pClient);
static int ProcRenderCreateRadialGradient (ClientPtr pClient);
static int ProcRenderCreateConicalGradient (ClientPtr pClient);
static int ProcRenderDispatch (ClientPtr pClient);
@ -113,6 +117,10 @@ static int SProcRenderQueryFilters (ClientPtr pClient);
static int SProcRenderSetPictureFilter (ClientPtr pClient);
static int SProcRenderCreateAnimCursor (ClientPtr pClient);
static int SProcRenderAddTraps (ClientPtr pClient);
static int SProcRenderCreateSolidFill (ClientPtr pClient);
static int SProcRenderCreateLinearGradient (ClientPtr pClient);
static int SProcRenderCreateRadialGradient (ClientPtr pClient);
static int SProcRenderCreateConicalGradient (ClientPtr pClient);
static int SProcRenderDispatch (ClientPtr pClient);
@ -150,6 +158,10 @@ int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
ProcRenderSetPictureFilter,
ProcRenderCreateAnimCursor,
ProcRenderAddTraps,
ProcRenderCreateSolidFill,
ProcRenderCreateLinearGradient,
ProcRenderCreateRadialGradient,
ProcRenderCreateConicalGradient
};
int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
@ -186,6 +198,10 @@ int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
SProcRenderSetPictureFilter,
SProcRenderCreateAnimCursor,
SProcRenderAddTraps,
SProcRenderCreateSolidFill,
SProcRenderCreateLinearGradient,
SProcRenderCreateRadialGradient,
SProcRenderCreateConicalGradient
};
static void
@ -647,6 +663,7 @@ ProcRenderChangePicture (ClientPtr client)
REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
if (Ones(stuff->mask) != len)
return BadLength;
@ -666,6 +683,9 @@ ProcRenderSetPictureClipRectangles (ClientPtr client)
REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (!pPicture->pDrawable)
return BadDrawable;
nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
if (nr & 4)
return BadLength;
@ -717,14 +737,16 @@ ProcRenderComposite (ClientPtr client)
client->errorValue = stuff->op;
return BadValue;
}
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (!pDst->pDrawable)
return BadDrawable;
VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
RenderErrBase + BadPicture);
VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess,
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen ||
(pMask && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
return BadMatch;
CompositePicture (stuff->op,
pSrc,
@ -765,7 +787,9 @@ ProcRenderTrapezoids (ClientPtr client)
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
if (!pDst->pDrawable)
return BadDrawable;
if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@ -810,7 +834,9 @@ ProcRenderTriangles (ClientPtr client)
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
if (!pDst->pDrawable)
return BadDrawable;
if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@ -855,7 +881,9 @@ ProcRenderTriStrip (ClientPtr client)
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
if (!pDst->pDrawable)
return BadDrawable;
if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@ -900,7 +928,9 @@ ProcRenderTriFan (ClientPtr client)
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
if (!pDst->pDrawable)
return BadDrawable;
if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@ -1226,7 +1256,9 @@ ProcRenderCompositeGlyphs (ClientPtr client)
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
if (!pDst->pDrawable)
return BadDrawable;
if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@ -1391,6 +1423,8 @@ ProcRenderFillRectangles (ClientPtr client)
}
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (!pDst->pDrawable)
return BadDrawable;
things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
if (things & 4)
@ -1455,6 +1489,8 @@ ProcRenderCreateCursor (ClientPtr client)
VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
RenderErrBase + BadPicture);
if (!pSrc->pDrawable)
return BadDrawable;
pScreen = pSrc->pDrawable->pScreen;
width = pSrc->pDrawable->width;
height = pSrc->pDrawable->height;
@ -1826,6 +1862,8 @@ ProcRenderAddTraps (ClientPtr client)
REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
if (!pPicture->pDrawable)
return BadDrawable;
ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
if (ntraps % sizeof (xTrap))
return BadLength;
@ -1837,6 +1875,113 @@ ProcRenderAddTraps (ClientPtr client)
return client->noClientException;
}
static int ProcRenderCreateSolidFill(ClientPtr client)
{
PicturePtr pPicture;
int error = 0;
REQUEST(xRenderCreateSolidFillReq);
REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
LEGAL_NEW_RESOURCE(stuff->pid, client);
pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
if (!pPicture)
return error;
if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
return BadAlloc;
return Success;
}
static int ProcRenderCreateLinearGradient (ClientPtr client)
{
PicturePtr pPicture;
int len;
int error = 0;
xFixed *stops;
xRenderColor *colors;
REQUEST(xRenderCreateLinearGradientReq);
REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
LEGAL_NEW_RESOURCE(stuff->pid, client);
len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
return BadLength;
stops = (xFixed *)(stuff + 1);
colors = (xRenderColor *)(stops + stuff->nStops);
pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
stuff->nStops, stops, colors, &error);
if (!pPicture)
return error;
if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
return BadAlloc;
return Success;
}
static int ProcRenderCreateRadialGradient (ClientPtr client)
{
PicturePtr pPicture;
int len;
int error = 0;
xFixed *stops;
xRenderColor *colors;
REQUEST(xRenderCreateRadialGradientReq);
REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
LEGAL_NEW_RESOURCE(stuff->pid, client);
len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
return BadLength;
stops = (xFixed *)(stuff + 1);
colors = (xRenderColor *)(stops + stuff->nStops);
pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
stuff->inner_radius, stuff->outer_radius,
stuff->nStops, stops, colors, &error);
if (!pPicture)
return error;
if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
return BadAlloc;
return Success;
}
static int ProcRenderCreateConicalGradient (ClientPtr client)
{
PicturePtr pPicture;
int len;
int error = 0;
xFixed *stops;
xRenderColor *colors;
REQUEST(xRenderCreateConicalGradientReq);
REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
LEGAL_NEW_RESOURCE(stuff->pid, client);
len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
return BadLength;
stops = (xFixed *)(stuff + 1);
colors = (xRenderColor *)(stops + stuff->nStops);
pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
stuff->nStops, stops, colors, &error);
if (!pPicture)
return error;
if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
return BadAlloc;
return Success;
}
static int
ProcRenderDispatch (ClientPtr client)
{
@ -2317,6 +2462,115 @@ SProcRenderAddTraps (ClientPtr client)
return (*ProcRenderVector[stuff->renderReqType]) (client);
}
static int
SProcRenderCreateSolidFill(ClientPtr client)
{
register int n;
REQUEST (xRenderCreateSolidFillReq);
REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
swaps(&stuff->length, n);
swapl(&stuff->pid, n);
swaps(&stuff->color.alpha, n);
swaps(&stuff->color.red, n);
swaps(&stuff->color.green, n);
swaps(&stuff->color.blue, n);
return (*ProcRenderVector[stuff->renderReqType]) (client);
}
static void swapStops(void *stuff, int n)
{
int i;
CARD32 *stops;
CARD16 *colors;
stops = (CARD32 *)(stuff);
for (i = 0; i < n; ++i) {
swapl(stops, n);
++stops;
}
colors = (CARD16 *)(stops);
for (i = 0; i < 4*n; ++i) {
swaps(stops, n);
++stops;
}
}
static int
SProcRenderCreateLinearGradient (ClientPtr client)
{
register int n;
int len;
REQUEST (xRenderCreateLinearGradientReq);
REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
swaps(&stuff->length, n);
swapl(&stuff->pid, n);
swapl(&stuff->p1.x, n);
swapl(&stuff->p1.y, n);
swapl(&stuff->p2.x, n);
swapl(&stuff->p2.y, n);
swapl(&stuff->nStops, n);
len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
return BadLength;
swapStops(stuff+1, stuff->nStops);
return (*ProcRenderVector[stuff->renderReqType]) (client);
}
static int
SProcRenderCreateRadialGradient (ClientPtr client)
{
register int n;
int len;
REQUEST (xRenderCreateRadialGradientReq);
REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
swaps(&stuff->length, n);
swapl(&stuff->pid, n);
swapl(&stuff->inner.x, n);
swapl(&stuff->inner.y, n);
swapl(&stuff->outer.x, n);
swapl(&stuff->outer.y, n);
swapl(&stuff->inner_radius, n);
swapl(&stuff->outer_radius, n);
swapl(&stuff->nStops, n);
len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
return BadLength;
swapStops(stuff+1, stuff->nStops);
return (*ProcRenderVector[stuff->renderReqType]) (client);
}
static int
SProcRenderCreateConicalGradient (ClientPtr client)
{
register int n;
int len;
REQUEST (xRenderCreateConicalGradientReq);
REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
swaps(&stuff->length, n);
swapl(&stuff->pid, n);
swapl(&stuff->center.x, n);
swapl(&stuff->center.y, n);
swapl(&stuff->angle, n);
swapl(&stuff->nStops, n);
len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
return BadLength;
swapStops(stuff+1, stuff->nStops);
return (*ProcRenderVector[stuff->renderReqType]) (client);
}
static int
SProcRenderDispatch (ClientPtr client)
{