mirror of
https://github.com/X11Libre/xserver.git
synced 2026-03-24 05:54:08 +00:00
Move matrix operations from X server to pixman 0.13.2
pixman 0.13.2 now holds all of the matrix operations. This leaves the protocol conversion routines and some ABI stubs in place Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
559
render/matrix.c
559
render/matrix.c
@@ -39,314 +39,6 @@
|
||||
#include "servermd.h"
|
||||
#include "picturestr.h"
|
||||
|
||||
#define F(x) IntToxFixed(x)
|
||||
|
||||
_X_EXPORT void
|
||||
PictureTransformInitIdentity (PictTransformPtr matrix)
|
||||
{
|
||||
int i;
|
||||
memset (matrix, '\0', sizeof (PictTransform));
|
||||
for (i = 0; i < 3; i++)
|
||||
matrix->matrix[i][i] = F(1);
|
||||
}
|
||||
|
||||
typedef xFixed_32_32 xFixed_34_30;
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformPoint3d (PictTransformPtr transform,
|
||||
PictVectorPtr vector)
|
||||
{
|
||||
PictVector result;
|
||||
int i, j;
|
||||
xFixed_32_32 partial;
|
||||
xFixed_48_16 v;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
v = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
partial = ((xFixed_48_16) transform->matrix[j][i] *
|
||||
(xFixed_48_16) vector->vector[i]);
|
||||
v += partial >> 16;
|
||||
}
|
||||
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
|
||||
return FALSE;
|
||||
result.vector[j] = (xFixed) v;
|
||||
}
|
||||
*vector = result;
|
||||
if (!result.vector[2])
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformPoint (PictTransformPtr transform,
|
||||
PictVectorPtr vector)
|
||||
{
|
||||
int i, j;
|
||||
xFixed_32_32 partial;
|
||||
xFixed_34_30 v[3];
|
||||
xFixed_48_16 quo;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
v[j] = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
partial = ((xFixed_32_32) transform->matrix[j][i] *
|
||||
(xFixed_32_32) vector->vector[i]);
|
||||
v[j] += partial >> 2;
|
||||
}
|
||||
}
|
||||
if (!v[2])
|
||||
return FALSE;
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
quo = v[j] / (v[2] >> 16);
|
||||
if (quo > MAX_FIXED_48_16 || quo < MIN_FIXED_48_16)
|
||||
return FALSE;
|
||||
vector->vector[j] = (xFixed) quo;
|
||||
}
|
||||
vector->vector[2] = xFixed1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformMultiply (PictTransformPtr dst, PictTransformPtr l, PictTransformPtr r)
|
||||
{
|
||||
PictTransform d;
|
||||
int dx, dy;
|
||||
int o;
|
||||
|
||||
for (dy = 0; dy < 3; dy++)
|
||||
for (dx = 0; dx < 3; dx++)
|
||||
{
|
||||
xFixed_48_16 v;
|
||||
xFixed_32_32 partial;
|
||||
v = 0;
|
||||
for (o = 0; o < 3; o++)
|
||||
{
|
||||
partial = (xFixed_32_32) l->matrix[dy][o] * (xFixed_32_32) r->matrix[o][dx];
|
||||
v += partial >> 16;
|
||||
}
|
||||
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
|
||||
return FALSE;
|
||||
d.matrix[dy][dx] = (xFixed) v;
|
||||
}
|
||||
*dst = d;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
PictureTransformInitScale (PictTransformPtr t, xFixed sx, xFixed sy)
|
||||
{
|
||||
memset (t, '\0', sizeof (PictTransform));
|
||||
t->matrix[0][0] = sx;
|
||||
t->matrix[1][1] = sy;
|
||||
t->matrix[2][2] = F (1);
|
||||
}
|
||||
|
||||
static xFixed
|
||||
fixed_inverse (xFixed x)
|
||||
{
|
||||
return (xFixed) ((((xFixed_48_16) F(1)) * F(1)) / x);
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformScale (PictTransformPtr forward,
|
||||
PictTransformPtr reverse,
|
||||
xFixed sx, xFixed sy)
|
||||
{
|
||||
PictTransform t;
|
||||
|
||||
if (sx == 0 || sy == 0)
|
||||
return FALSE;
|
||||
|
||||
PictureTransformInitScale (&t, sx, sy);
|
||||
if (!PictureTransformMultiply (forward, &t, forward))
|
||||
return FALSE;
|
||||
PictureTransformInitScale (&t, fixed_inverse (sx), fixed_inverse (sy));
|
||||
if (!PictureTransformMultiply (reverse, reverse, &t))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
PictureTransformInitRotate (PictTransformPtr t, xFixed c, xFixed s)
|
||||
{
|
||||
memset (t, '\0', sizeof (PictTransform));
|
||||
t->matrix[0][0] = c;
|
||||
t->matrix[0][1] = -s;
|
||||
t->matrix[1][0] = s;
|
||||
t->matrix[1][1] = c;
|
||||
t->matrix[2][2] = F (1);
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformRotate (PictTransformPtr forward,
|
||||
PictTransformPtr reverse,
|
||||
xFixed c, xFixed s)
|
||||
{
|
||||
PictTransform t;
|
||||
PictureTransformInitRotate (&t, c, s);
|
||||
if (!PictureTransformMultiply (forward, &t, forward))
|
||||
return FALSE;
|
||||
|
||||
PictureTransformInitRotate (&t, c, -s);
|
||||
if (!PictureTransformMultiply (reverse, reverse, &t))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
PictureTransformInitTranslate (PictTransformPtr t, xFixed tx, xFixed ty)
|
||||
{
|
||||
memset (t, '\0', sizeof (PictTransform));
|
||||
t->matrix[0][0] = F (1);
|
||||
t->matrix[0][2] = tx;
|
||||
t->matrix[1][1] = F (1);
|
||||
t->matrix[1][2] = ty;
|
||||
t->matrix[2][2] = F (1);
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformTranslate (PictTransformPtr forward,
|
||||
PictTransformPtr reverse,
|
||||
xFixed tx, xFixed ty)
|
||||
{
|
||||
PictTransform t;
|
||||
PictureTransformInitTranslate (&t, tx, ty);
|
||||
if (!PictureTransformMultiply (forward, &t, forward))
|
||||
return FALSE;
|
||||
|
||||
PictureTransformInitTranslate (&t, -tx, -ty);
|
||||
if (!PictureTransformMultiply (reverse, reverse, &t))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformBounds (BoxPtr b, PictTransformPtr matrix)
|
||||
{
|
||||
PictVector v[4];
|
||||
int i;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
v[0].vector[0] = F (b->x1); v[0].vector[1] = F (b->y1); v[0].vector[2] = F(1);
|
||||
v[1].vector[0] = F (b->x2); v[1].vector[1] = F (b->y1); v[1].vector[2] = F(1);
|
||||
v[2].vector[0] = F (b->x2); v[2].vector[1] = F (b->y2); v[2].vector[2] = F(1);
|
||||
v[3].vector[0] = F (b->x1); v[3].vector[1] = F (b->y2); v[3].vector[2] = F(1);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!PictureTransformPoint (matrix, &v[i]))
|
||||
return FALSE;
|
||||
x1 = xFixedToInt (v[i].vector[0]);
|
||||
y1 = xFixedToInt (v[i].vector[1]);
|
||||
x2 = xFixedToInt (xFixedCeil (v[i].vector[0]));
|
||||
y2 = xFixedToInt (xFixedCeil (v[i].vector[1]));
|
||||
if (i == 0)
|
||||
{
|
||||
b->x1 = x1; b->y1 = y1;
|
||||
b->x2 = x2; b->y2 = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x1 < b->x1) b->x1 = x1;
|
||||
if (y1 < b->y1) b->y1 = y1;
|
||||
if (x2 > b->x2) b->x2 = x2;
|
||||
if (y2 > b->y2) b->y2 = y2;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformInvert (PictTransformPtr dst, const PictTransformPtr src)
|
||||
{
|
||||
struct pict_f_transform m, r;
|
||||
|
||||
pict_f_transform_from_pixman_transform (&m, src);
|
||||
if (!pict_f_transform_invert (&r, &m))
|
||||
return FALSE;
|
||||
if (!pixman_transform_from_pict_f_transform (dst, &r))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
within_epsilon (xFixed a, xFixed b, xFixed epsilon)
|
||||
{
|
||||
xFixed t = a - b;
|
||||
if (t < 0) t = -t;
|
||||
return t <= epsilon;
|
||||
}
|
||||
|
||||
#define epsilon (xFixed) (2)
|
||||
|
||||
#define IsSame(a,b) (within_epsilon (a, b, epsilon))
|
||||
#define IsZero(a) (within_epsilon (a, 0, epsilon))
|
||||
#define IsOne(a) (within_epsilon (a, F(1), epsilon))
|
||||
#define IsUnit(a) (within_epsilon (a, F( 1), epsilon) || \
|
||||
within_epsilon (a, F(-1), epsilon) || \
|
||||
IsZero (a))
|
||||
#define IsInt(a) (IsZero (xFixedFrac(a)))
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformIsIdentity(PictTransform *t)
|
||||
{
|
||||
return (IsSame (t->matrix[0][0], t->matrix[1][1]) &&
|
||||
IsSame (t->matrix[0][0], t->matrix[2][2]) &&
|
||||
!IsZero (t->matrix[0][0]) &&
|
||||
IsZero (t->matrix[0][1]) &&
|
||||
IsZero (t->matrix[0][2]) &&
|
||||
IsZero (t->matrix[1][0]) &&
|
||||
IsZero (t->matrix[1][2]) &&
|
||||
IsZero (t->matrix[2][0]) &&
|
||||
IsZero (t->matrix[2][1]));
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformIsScale(PictTransform *t)
|
||||
{
|
||||
return (!IsZero (t->matrix[0][0]) &&
|
||||
IsZero (t->matrix[0][1]) &&
|
||||
IsZero (t->matrix[0][2]) &&
|
||||
|
||||
IsZero (t->matrix[1][0]) &&
|
||||
!IsZero (t->matrix[1][1]) &&
|
||||
IsZero (t->matrix[1][2]) &&
|
||||
|
||||
IsZero (t->matrix[2][0]) &&
|
||||
IsZero (t->matrix[2][1]) &&
|
||||
!IsZero (t->matrix[2][2]));
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformIsIntTranslate(PictTransform *t)
|
||||
{
|
||||
return ( IsOne (t->matrix[0][0]) &&
|
||||
IsZero (t->matrix[0][1]) &&
|
||||
IsInt (t->matrix[0][2]) &&
|
||||
|
||||
IsZero (t->matrix[1][0]) &&
|
||||
IsOne (t->matrix[1][1]) &&
|
||||
IsInt (t->matrix[1][2]) &&
|
||||
|
||||
IsZero (t->matrix[2][0]) &&
|
||||
IsZero (t->matrix[2][1]) &&
|
||||
IsOne (t->matrix[2][2]));
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
PictureTransformIsInverse (PictTransform *a, PictTransform *b)
|
||||
{
|
||||
PictTransform t;
|
||||
|
||||
PictureTransformMultiply (&t, a, b);
|
||||
return PictureTransformIsIdentity (&t);
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
PictTransform_from_xRenderTransform (PictTransformPtr pict,
|
||||
xRenderTransform *render)
|
||||
@@ -364,7 +56,7 @@ PictTransform_from_xRenderTransform (PictTransformPtr pict,
|
||||
pict->matrix[2][2] = render->matrix33;
|
||||
}
|
||||
|
||||
void
|
||||
_X_EXPORT void
|
||||
xRenderTransform_from_PictTransform (xRenderTransform *render,
|
||||
PictTransformPtr pict)
|
||||
{
|
||||
@@ -381,251 +73,16 @@ xRenderTransform_from_PictTransform (xRenderTransform *render,
|
||||
render->matrix33 = pict->matrix[2][2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Floating point matrix interfaces
|
||||
*/
|
||||
|
||||
_X_EXPORT void
|
||||
pict_f_transform_from_pixman_transform (struct pict_f_transform *ft,
|
||||
struct pixman_transform *t)
|
||||
_X_EXPORT Bool
|
||||
PictureTransformPoint (PictTransformPtr transform,
|
||||
PictVectorPtr vector)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
for (i = 0; i < 3; i++)
|
||||
ft->m[j][i] = pixman_fixed_to_double (t->matrix[j][i]);
|
||||
return pixman_transform_point(transform, vector);
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
pixman_transform_from_pict_f_transform (struct pixman_transform *t,
|
||||
struct pict_f_transform *ft)
|
||||
PictureTransformPoint3d (PictTransformPtr transform,
|
||||
PictVectorPtr vector)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
double d = ft->m[j][i];
|
||||
if (d < -32767.0 || d > 32767.0)
|
||||
return FALSE;
|
||||
d = d * 65536.0 + 0.5;
|
||||
t->matrix[j][i] = (xFixed) floor (d);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const int a[3] = { 3, 3, 2 };
|
||||
static const int b[3] = { 2, 1, 1 };
|
||||
|
||||
_X_EXPORT Bool
|
||||
pict_f_transform_invert (struct pict_f_transform *r,
|
||||
struct pict_f_transform *m)
|
||||
{
|
||||
double det;
|
||||
int i, j;
|
||||
static int a[3] = { 2, 2, 1 };
|
||||
static int b[3] = { 1, 0, 0 };
|
||||
|
||||
det = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
double p;
|
||||
int ai = a[i];
|
||||
int bi = b[i];
|
||||
p = m->m[i][0] * (m->m[ai][2] * m->m[bi][1] - m->m[ai][1] * m->m[bi][2]);
|
||||
if (i == 1)
|
||||
p = -p;
|
||||
det += p;
|
||||
}
|
||||
if (det == 0)
|
||||
return FALSE;
|
||||
det = 1/det;
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
double p;
|
||||
int ai = a[i];
|
||||
int aj = a[j];
|
||||
int bi = b[i];
|
||||
int bj = b[j];
|
||||
|
||||
p = m->m[ai][aj] * m->m[bi][bj] - m->m[ai][bj] * m->m[bi][aj];
|
||||
if (((i + j) & 1) != 0)
|
||||
p = -p;
|
||||
r->m[j][i] = det * p;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
pict_f_transform_point (struct pict_f_transform *t,
|
||||
struct pict_f_vector *v)
|
||||
{
|
||||
struct pict_f_vector result;
|
||||
int i, j;
|
||||
double a;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
a = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
a += t->m[j][i] * v->v[i];
|
||||
result.v[j] = a;
|
||||
}
|
||||
if (!result.v[2])
|
||||
return FALSE;
|
||||
for (j = 0; j < 2; j++)
|
||||
v->v[j] = result.v[j] / result.v[2];
|
||||
v->v[2] = 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
pict_f_transform_point_3d (struct pict_f_transform *t,
|
||||
struct pict_f_vector *v)
|
||||
{
|
||||
struct pict_f_vector result;
|
||||
int i, j;
|
||||
double a;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
a = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
a += t->m[j][i] * v->v[i];
|
||||
result.v[j] = a;
|
||||
}
|
||||
*v = result;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
pict_f_transform_multiply (struct pict_f_transform *dst,
|
||||
struct pict_f_transform *l, struct pict_f_transform *r)
|
||||
{
|
||||
struct pict_f_transform d;
|
||||
int dx, dy;
|
||||
int o;
|
||||
|
||||
for (dy = 0; dy < 3; dy++)
|
||||
for (dx = 0; dx < 3; dx++)
|
||||
{
|
||||
double v = 0;
|
||||
for (o = 0; o < 3; o++)
|
||||
v += l->m[dy][o] * r->m[o][dx];
|
||||
d.m[dy][dx] = v;
|
||||
}
|
||||
*dst = d;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
pict_f_transform_init_scale (struct pict_f_transform *t, double sx, double sy)
|
||||
{
|
||||
t->m[0][0] = sx; t->m[0][1] = 0; t->m[0][2] = 0;
|
||||
t->m[1][0] = 0; t->m[1][1] = sy; t->m[1][2] = 0;
|
||||
t->m[2][0] = 0; t->m[2][1] = 0; t->m[2][2] = 1;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
pict_f_transform_scale (struct pict_f_transform *forward,
|
||||
struct pict_f_transform *reverse,
|
||||
double sx, double sy)
|
||||
{
|
||||
struct pict_f_transform t;
|
||||
|
||||
if (sx == 0 || sy == 0)
|
||||
return FALSE;
|
||||
|
||||
pict_f_transform_init_scale (&t, sx, sy);
|
||||
pict_f_transform_multiply (forward, &t, forward);
|
||||
pict_f_transform_init_scale (&t, 1/sx, 1/sy);
|
||||
pict_f_transform_multiply (reverse, reverse, &t);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
pict_f_transform_init_rotate (struct pict_f_transform *t, double c, double s)
|
||||
{
|
||||
t->m[0][0] = c; t->m[0][1] = -s; t->m[0][2] = 0;
|
||||
t->m[1][0] = s; t->m[1][1] = c; t->m[1][2] = 0;
|
||||
t->m[2][0] = 0; t->m[2][1] = 0; t->m[2][2] = 1;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
pict_f_transform_rotate (struct pict_f_transform *forward,
|
||||
struct pict_f_transform *reverse,
|
||||
double c, double s)
|
||||
{
|
||||
struct pict_f_transform t;
|
||||
|
||||
pict_f_transform_init_rotate (&t, c, s);
|
||||
pict_f_transform_multiply (forward, &t, forward);
|
||||
pict_f_transform_init_rotate (&t, c, -s);
|
||||
pict_f_transform_multiply (reverse, reverse, &t);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
pict_f_transform_init_translate (struct pict_f_transform *t, double tx, double ty)
|
||||
{
|
||||
t->m[0][0] = 1; t->m[0][1] = 0; t->m[0][2] = tx;
|
||||
t->m[1][0] = 0; t->m[1][1] = 1; t->m[1][2] = ty;
|
||||
t->m[2][0] = 0; t->m[2][1] = 0; t->m[2][2] = 1;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
pict_f_transform_translate (struct pict_f_transform *forward,
|
||||
struct pict_f_transform *reverse,
|
||||
double tx, double ty)
|
||||
{
|
||||
struct pict_f_transform t;
|
||||
|
||||
pict_f_transform_init_translate (&t, tx, ty);
|
||||
pict_f_transform_multiply (forward, &t, forward);
|
||||
pict_f_transform_init_translate (&t, -tx, -ty);
|
||||
pict_f_transform_multiply (reverse, reverse, &t);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
pict_f_transform_bounds (struct pict_f_transform *t, BoxPtr b)
|
||||
{
|
||||
struct pict_f_vector v[4];
|
||||
int i;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
v[0].v[0] = b->x1; v[0].v[1] = b->y1; v[0].v[2] = 1;
|
||||
v[1].v[0] = b->x2; v[1].v[1] = b->y1; v[1].v[2] = 1;
|
||||
v[2].v[0] = b->x2; v[2].v[1] = b->y2; v[2].v[2] = 1;
|
||||
v[3].v[0] = b->x1; v[3].v[1] = b->y2; v[3].v[2] = 1;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!pict_f_transform_point (t, &v[i]))
|
||||
return FALSE;
|
||||
x1 = floor (v[i].v[0]);
|
||||
y1 = floor (v[i].v[1]);
|
||||
x2 = ceil (v[i].v[0]);
|
||||
y2 = ceil (v[i].v[1]);
|
||||
if (i == 0)
|
||||
{
|
||||
b->x1 = x1; b->y1 = y1;
|
||||
b->x2 = x2; b->y2 = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x1 < b->x1) b->x1 = x1;
|
||||
if (y1 < b->y1) b->y1 = y1;
|
||||
if (x2 > b->x2) b->x2 = x2;
|
||||
if (y2 > b->y2) b->y2 = y2;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
pict_f_transform_init_identity (struct pict_f_transform *t)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
for (i = 0; i < 3; i++)
|
||||
t->m[j][i] = i == j ? 1 : 0;
|
||||
return pixman_transform_point_3d(transform, vector);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user