Implemented the matrix stuff on Windows. Also fixed the signature of uiDrawMatrixSkew().
This commit is contained in:
parent
3d8f8f0756
commit
0ae3ef918d
64
matrix.c
64
matrix.c
|
@ -15,3 +15,67 @@ void setIdentity(uiDrawMatrix *m)
|
|||
// TODO skew
|
||||
|
||||
// see windows/draw.c for more information
|
||||
// TODO we don't need to do this if we can bypass the multiplication somehow
|
||||
|
||||
void fallbackTranslate(uiDrawMatrix *m, double x, double y)
|
||||
{
|
||||
uiDrawMatrix m2;
|
||||
|
||||
setIdentity(&m2);
|
||||
m2.M31 = x;
|
||||
m2.M32 = y;
|
||||
fallbackMultiply(m, &m2);
|
||||
}
|
||||
|
||||
// TODO the Direct2D version takes a center argument; investigate it
|
||||
void fallbackScale(uiDrawMatrix *m, double x, double y)
|
||||
{
|
||||
uiDrawMatrix m2;
|
||||
|
||||
setIdentity(&m2);
|
||||
m2.M11 = x;
|
||||
m2.M22 = y;
|
||||
fallbackMultiply(m, &m2);
|
||||
}
|
||||
|
||||
void fallbackMultiply(uiDrawMatrix *dest, uiDrawMatrix *src)
|
||||
{
|
||||
uiDrawMatrix out;
|
||||
|
||||
out.M11 = (dest->M11 * src->M11) +
|
||||
(dest->M12 * src->M21);
|
||||
out.M12 = (dest->M11 * src->M12) +
|
||||
(dest->M12 * src->M22);
|
||||
out.M21 = (dest->M21 * src->M11) +
|
||||
(dest->M22 * src->M21);
|
||||
out.M22 = (dest->M21 * src->M12) +
|
||||
(dest->M22 * src->M22);
|
||||
out.M31 = (dest->M31 * src->M11) +
|
||||
(dest->M32 * src->M21) +
|
||||
src->M31;
|
||||
out.M32 = (dest->M31 * src->M12) +
|
||||
(dest->M32 * src->M22) +
|
||||
src->M32;
|
||||
*dest = out;
|
||||
}
|
||||
|
||||
void fallbackTransformPoint(uiDrawMatrix *m, double *x, double *y)
|
||||
{
|
||||
double xout, yout;
|
||||
|
||||
xout = (*x * m->M11) + (*y * m->M21) + m->M31;
|
||||
yout = (*x * m->M12) + (*y * m->M22) + m->M32;
|
||||
*x = xout;
|
||||
*y = yout;
|
||||
}
|
||||
|
||||
// and this algorithm is according to cairo
|
||||
void fallbackTransformSize(uiDrawMatrix *m, double *x, double *y)
|
||||
{
|
||||
double xout, yout;
|
||||
|
||||
xout = (*x * m->M11) + (*y * m->M21);
|
||||
yout = (*x * m->M12) + (*y * m->M22);
|
||||
*x = xout;
|
||||
*y = yout;
|
||||
}
|
||||
|
|
2
ui.h
2
ui.h
|
@ -416,7 +416,7 @@ _UI_EXTERN void uiDrawMatrixSetIdentity(uiDrawMatrix *m);
|
|||
_UI_EXTERN void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y);
|
||||
_UI_EXTERN void uiDrawMatrixScale(uiDrawMatrix *m, double x, double y);
|
||||
_UI_EXTERN void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount);
|
||||
_UI_EXTERN void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double amount);
|
||||
_UI_EXTERN void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount);
|
||||
_UI_EXTERN void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src);
|
||||
_UI_EXTERN int uiDrawMatrixInvertible(uiDrawMatrix *m);
|
||||
_UI_EXTERN int uiDrawMatrixInvert(uiDrawMatrix *m);
|
||||
|
|
5
uipriv.h
5
uipriv.h
|
@ -62,3 +62,8 @@ extern int fromScancode(uintptr_t, uiAreaKeyEvent *);
|
|||
|
||||
// matrix.c
|
||||
extern void setIdentity(uiDrawMatrix *);
|
||||
extern void fallbackTranslate(uiDrawMatrix *, double, double);
|
||||
extern void fallbackScale(uiDrawMatrix *, double, double);
|
||||
extern void fallbackMultiply(uiDrawMatrix *, uiDrawMatrix *);
|
||||
extern void fallbackTransformPoint(uiDrawMatrix *, double *, double *);
|
||||
extern void fallbackTransformSize(uiDrawMatrix *, double *, double *);
|
||||
|
|
|
@ -178,7 +178,7 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
|
|||
dp.HScrollPos = gtk_adjustment_get_value(ap->ha);
|
||||
dp.VScrollPos = gtk_adjustment_get_value(ap->va);
|
||||
|
||||
// no need to save or restore the graphics state; GTK+ does that for us
|
||||
// no need to save or restore the graphics state to reset transformations; GTK+ does that for us
|
||||
(*(ap->ah->Draw))(ap->ah, ap->a, &dp);
|
||||
|
||||
freeContext(dp.Context);
|
||||
|
|
|
@ -353,7 +353,7 @@ void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount)
|
|||
c2m(&c, m);
|
||||
}
|
||||
|
||||
void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double amount)
|
||||
void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double amount, double yamount)
|
||||
{
|
||||
complain("TODO");
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *client, RECT *cli
|
|||
bgcolor.a = 1.0;
|
||||
ID2D1RenderTarget_Clear(rt, &bgcolor);
|
||||
|
||||
// no need to save or restore the graphics state to reset transformations; it's handled by resetTarget() in draw.c, called by newContext() above
|
||||
(*(ah->Draw))(ah, a, &dp);
|
||||
|
||||
freeContext(dp.Context);
|
||||
|
|
138
windows/draw.c
138
windows/draw.c
|
@ -294,12 +294,25 @@ struct uiDrawContext {
|
|||
ID2D1RenderTarget *rt;
|
||||
};
|
||||
|
||||
static void resetTarget(ID2D1RenderTarget *rt)
|
||||
{
|
||||
D2D1_MATRIX_3X2_F dm;
|
||||
|
||||
// transformations persist
|
||||
// reset to the identity matrix
|
||||
ZeroMemory(&dm, sizeof (D2D1_MATRIX_3X2_F));
|
||||
dm._11 = 1;
|
||||
dm._22 = 1;
|
||||
ID2D1RenderTarget_SetTransform(rt, &dm);
|
||||
}
|
||||
|
||||
uiDrawContext *newContext(ID2D1RenderTarget *rt)
|
||||
{
|
||||
uiDrawContext *c;
|
||||
|
||||
c = uiNew(uiDrawContext);
|
||||
c->rt = rt;
|
||||
resetTarget(c->rt);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -512,3 +525,128 @@ void uiDrawFill(uiDrawContext *c, uiDrawPath *p, uiDrawBrush *b)
|
|||
NULL);
|
||||
ID2D1Brush_Release(brush);
|
||||
}
|
||||
|
||||
static void m2d(uiDrawMatrix *m, D2D1_MATRIX_3X2_F *d)
|
||||
{
|
||||
d->_11 = m->M11;
|
||||
d->_12 = m->M12;
|
||||
d->_21 = m->M21;
|
||||
d->_22 = m->M22;
|
||||
d->_31 = m->M31;
|
||||
d->_32 = m->M32;
|
||||
}
|
||||
|
||||
static void d2m(D2D1_MATRIX_3X2_F *d, uiDrawMatrix *m)
|
||||
{
|
||||
m->M11 = d->_11;
|
||||
m->M12 = d->_12;
|
||||
m->M21 = d->_21;
|
||||
m->M22 = d->_22;
|
||||
m->M31 = d->_31;
|
||||
m->M32 = d->_32;
|
||||
}
|
||||
|
||||
void uiDrawMatrixSetIdentity(uiDrawMatrix *m)
|
||||
{
|
||||
setIdentity(m);
|
||||
}
|
||||
|
||||
// frustratingly all of the operations on a matrix except rotation and skeweing are provided by the C++-only d2d1helper.h
|
||||
// we'll have to recreate their functionalities here
|
||||
// the implementations are all in the main matrix.c file
|
||||
|
||||
void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y)
|
||||
{
|
||||
fallbackTranslate(m, x, y);
|
||||
}
|
||||
|
||||
void uiDrawMatrixScale(uiDrawMatrix *m, double x, double y)
|
||||
{
|
||||
fallbackScale(m, x, y);
|
||||
}
|
||||
|
||||
void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount)
|
||||
{
|
||||
D2D1_POINT_2F center;
|
||||
D2D1_MATRIX_3X2_F dm;
|
||||
uiDrawMatrix rm;
|
||||
|
||||
amount *= 180 / M_PI; // must be in degrees
|
||||
center.x = x;
|
||||
center.y = y;
|
||||
// TODO explain this
|
||||
D2D1MakeRotateMatrix(-amount, center, &dm);
|
||||
d2m(&dm, &rm);
|
||||
uiDrawMatrixMultiply(m, &rm);
|
||||
}
|
||||
|
||||
void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount)
|
||||
{
|
||||
D2D1_POINT_2F center;
|
||||
D2D1_MATRIX_3X2_F dm;
|
||||
uiDrawMatrix sm;
|
||||
|
||||
xamount *= 180 / M_PI; // must be in degrees
|
||||
yamount *= 180 / M_PI; // must be in degrees
|
||||
center.x = x;
|
||||
center.y = y;
|
||||
D2D1MakeSkewMatrix(xamount, yamount, center, &dm);
|
||||
d2m(&dm, &sm);
|
||||
uiDrawMatrixMultiply(m, &sm);
|
||||
}
|
||||
|
||||
void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src)
|
||||
{
|
||||
fallbackMultiply(dest, src);
|
||||
}
|
||||
|
||||
int uiDrawMatrixInvertible(uiDrawMatrix *m)
|
||||
{
|
||||
D2D1_MATRIX_3X2_F d;
|
||||
|
||||
m2d(m, &d);
|
||||
return D2D1IsMatrixInvertible(&d) != FALSE;
|
||||
}
|
||||
|
||||
int uiDrawMatrixInvert(uiDrawMatrix *m)
|
||||
{
|
||||
D2D1_MATRIX_3X2_F d;
|
||||
|
||||
m2d(m, &d);
|
||||
if (D2D1InvertMatrix(&d) == FALSE)
|
||||
return 0;
|
||||
d2m(&d, m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y)
|
||||
{
|
||||
fallbackTransformPoint(m, x, y);
|
||||
}
|
||||
|
||||
void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y)
|
||||
{
|
||||
fallbackTransformSize(m, x, y);
|
||||
}
|
||||
|
||||
void uiDrawSave(uiDrawContext *c)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void uiDrawRestore(uiDrawContext *c)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m)
|
||||
{
|
||||
D2D1_MATRIX_3X2_F dm;
|
||||
uiDrawMatrix already;
|
||||
|
||||
ID2D1RenderTarget_GetTransform(c->rt, &dm);
|
||||
d2m(&dm, &already);
|
||||
uiDrawMatrixMultiply(&already, m);
|
||||
m2d(&already, &dm);
|
||||
ID2D1RenderTarget_SetTransform(c->rt, &dm);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue