Built the framework for matrices and transformations and implemented it on the GTK+ backend. Tests to come next.

This commit is contained in:
Pietro Gagliardi 2015-10-11 11:13:01 -04:00
parent f3a2635f8c
commit 87680a6470
6 changed files with 173 additions and 0 deletions

View File

@ -25,6 +25,7 @@ baseHFILES = \
baseCFILES = \
areaevents.c \
control.c \
matrix.c \
menu.c \
ptrarray.c \
shouldquit.c \

View File

@ -1,3 +1,5 @@
- make sure graphics state is saved and restored around each draw call
- all ports: update state when adding a control to a parent
- should uiWindowsSizing be computed against the window handle, not the parent?

17
matrix.c Normal file
View File

@ -0,0 +1,17 @@
// 11 october 2015
#include "ui.h"
#include "uipriv.h"
void setIdentity(uiDrawMatrix *m)
{
m->M11 = 1;
m->M12 = 0;
m->M21 = 0;
m->M22 = 1;
m->M31 = 0;
m->M32 = 0;
}
// TODO skew
// see windows/draw.c for more information

25
ui.h
View File

@ -295,6 +295,7 @@ struct uiAreaDrawParams {
typedef struct uiDrawPath uiDrawPath;
typedef struct uiDrawBrush uiDrawBrush;
typedef struct uiDrawStrokeParams uiDrawStrokeParams;
typedef struct uiDrawMatrix uiDrawMatrix;
typedef enum uiDrawBrushType uiDrawBrushType;
typedef struct uiDrawBrushGradientStop uiDrawBrushGradientStop;
@ -332,6 +333,15 @@ enum uiDrawFillMode {
uiDrawFillModeAlternate,
};
struct uiDrawMatrix {
double M11;
double M12;
double M21;
double M22;
double M31;
double M32;
};
struct uiDrawBrush {
uiDrawBrushType Type;
@ -402,6 +412,21 @@ _UI_EXTERN void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b);
// - elliptical arcs
// - quadratic bezier curves
_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 uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src);
_UI_EXTERN int uiDrawMatrixInvertible(uiDrawMatrix *m);
_UI_EXTERN int uiDrawMatrixInvert(uiDrawMatrix *m);
_UI_EXTERN void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y);
_UI_EXTERN void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y);
_UI_EXTERN void uiDrawSave(uiDrawContext *c);
_UI_EXTERN void uiDrawRestore(uiDrawContext *c);
_UI_EXTERN void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m);
typedef enum uiModifiers uiModifiers;
enum uiModifiers {

View File

@ -59,3 +59,6 @@ struct clickCounter {
extern uintmax_t clickCounterClick(clickCounter *, uintmax_t, intmax_t, intmax_t, uintptr_t, uintptr_t, intmax_t, intmax_t);
extern void clickCounterReset(clickCounter *);
extern int fromScancode(uintptr_t, uiAreaKeyEvent *);
// matrix.c
extern void setIdentity(uiDrawMatrix *);

View File

@ -296,3 +296,128 @@ void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b)
cairo_fill(c->cr);
cairo_pattern_destroy(pat);
}
static void m2c(uiDrawMatrix *m, cairo_matrix_t *c)
{
c->xx = m->M11;
c->yx = m->M12;
c->xy = m->M21;
c->yy = m->M22;
c->x0 = m->M31;
c->y0 = m->M32;
}
static void c2m(cairo_matrix_t *c, uiDrawMatrix *m)
{
m->M11 = c->xx;
m->M12 = c->yx;
m->M21 = c->xy;
m->M22 = c->yy;
m->M31 = c->x0;
m->M32 = c->y0;
}
void uiDrawMatrixSetIdentity(uiDrawMatrix *m)
{
setIdentity(m);
}
void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y)
{
cairo_matrix_t c;
m2c(m, &c);
cairo_matrix_translate(&c, x, y);
c2m(&c, m);
}
void uiDrawMatrixScale(uiDrawMatrix *m, double x, double y)
{
cairo_matrix_t c;
m2c(m, &c);
cairo_matrix_scale(&c, x, y);
c2m(&c, m);
}
void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount)
{
cairo_matrix_t c;
m2c(m, &c);
// TODO verify this
cairo_matrix_translate(&c, x, y);
// TODO explain this
cairo_matrix_rotate(&c, -amount);
cairo_matrix_translate(&c, -x, -y);
c2m(&c, m);
}
void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double amount)
{
complain("TODO");
}
void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src)
{
cairo_matrix_t c;
cairo_matrix_t d;
m2c(dest, &c);
m2c(src, &d);
cairo_matrix_multiply(&c, &c, &d);
c2m(&c, dest);
}
int uiDrawMatrixInvertible(uiDrawMatrix *m)
{
cairo_matrix_t c;
m2c(m, &c);
return cairo_matrix_invert(&c) == CAIRO_STATUS_SUCCESS;
}
int uiDrawMatrixInvert(uiDrawMatrix *m)
{
cairo_matrix_t c;
m2c(m, &c);
if (cairo_matrix_invert(&c) != CAIRO_STATUS_SUCCESS)
return 0;
c2m(&c, m);
return 1;
}
void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y)
{
cairo_matrix_t c;
m2c(m, &c);
cairo_matrix_transform_point(&c, x, y);
}
void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y)
{
cairo_matrix_t c;
m2c(m, &c);
cairo_matrix_transform_distance(&c, x, y);
}
void uiDrawSave(uiDrawContext *c)
{
cairo_save(c->cr);
}
void uiDrawRestore(uiDrawContext *c)
{
cairo_restore(c->cr);
}
void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m)
{
cairo_matrix_t cm;
m2c(m, &cm);
cairo_transform(c->cr, &cm);
}