summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Bosveld <Joel.Bosveld@gmail.com>2009-07-07 22:16:41 +0800
committerJoel Bosveld <Joel.Bosveld@gmail.com>2009-07-07 22:16:41 +0800
commite78d59c3acd6886101add2e227ff205091361a85 (patch)
tree2703a4bed6afd95a139073c3a875cbe6de9fec67
parent21f3daebe3c049cca2753fae9b56d28958647543 (diff)
sub: draw the redirected subwindows using the mesh
-rw-r--r--sub/sub.c76
1 files changed, 63 insertions, 13 deletions
diff --git a/sub/sub.c b/sub/sub.c
index 6a2425c..ece0e07 100644
--- a/sub/sub.c
+++ b/sub/sub.c
@@ -16,6 +16,7 @@ typedef struct
Pixmap p;
int width, height;
XTriangle *mesh;
+ cairo_matrix_t *m;
int nNormTri;
int nTotal;
bool drawing;
@@ -67,6 +68,7 @@ meshWindow (XTriangle *t, int px1, int py1, int px2, int py2,
int cx1, int cy1, int cx2, int cy2)
{
meshSquare (&t[0], px1, py1, px2, py2, cx1, cy1, cx2, cy2);
+
/* Top Row */
meshSquare (&t[4], SHRT_MIN, SHRT_MIN, px1, py1, SHRT_MIN, SHRT_MIN, cx1, cy1);
meshSquare (&t[8], px1, SHRT_MIN, px2, py1, cx1, SHRT_MIN, cx2, cy1);
@@ -89,23 +91,61 @@ static SubWindow
return NULL;
}
-static void
-paintTri (cairo_t *cr, cairo_surface_t *s, XTriangle p, XTriangle c)
+/* http://www.nsa.gov/academia/_files/collected_learning/high_school/algebra/fractal_fern.pdf */
+static cairo_matrix_t
+setupMatrix (int xp1, int yp1, int xp2, int yp2, int xp3, int yp3,
+ int xc1, int yc1, int xc2, int yc2, int xc3, int yc3)
{
+ cairo_matrix_t m;
+ cairo_matrix_t inv;
+ double b6, b7, b8, b9, f6, f7, f8, f9;
+ double det;
+
+ b6 = xc1*(yc2 - yc3) + xc2*(yc3-yc1) + xc3*(yc1-yc2);
+ b7 = xp1*(yc2 - yc3) + xp2*(yc3-yc1) + xp3*(yc1-yc2);
+ b8 = xc1*(xp2 - xp3) + xc2*(xp3-xp1) + xc3*(xp1-xp2);
+ b9 = xc1*(yc2*xp3 - yc3*xp2) + xc2*(yc3*xp1-yc1*xp3) + xc3*(yc1*xp2-yc2*xp1);
+ f6 = b6;
+ f7 = yp1*(yc2 - yc3) + yp2*(yc3-yc1) + yp3*(yc1-yc2);
+ f8 = xc1*(yp2 - yp3) + xc2*(yp3-yp1) + xc3*(yp1-yp2);
+ f9 = xc1*(yc2*yp3 - yc3*yp2) + xc2*(yc3*yp1-yc1*yp3) + xc3*(yc1*yp2-yc2*yp1);
+
+ m.xx = b7/b6;
+ m.xy = b8/b6;
+ m.x0 = b9/b6;
+ m.yx = f7/f6;
+ m.yy = f8/f6;
+ m.y0 = f9/f6;
+
+ det = (m.xx*m.yy-m.xy*m.yx);
+ inv.xx = 1/det * m.yy;
+ inv.yy = 1/det * m.xx;
+ inv.xy = -1/det * m.xy;
+ inv.yx = -1/det * m.yx;
+ inv.x0 = -1/det * (m.yy*m.x0 - m.xy*m.y0);
+ inv.y0 = -1/det * (m.xx*m.y0 - m.yx*m.x0);
+ return inv;
+}
+
+static void
+paintTri (cairo_t *cr, SubWindow *s, int i)
+{
+ cairo_pattern_t *pattern = cairo_pattern_create_for_surface (s->s);
+ cairo_pattern_set_matrix (pattern, &s->m[i]);
+ cairo_set_source (cr, pattern);
+ cairo_move_to (cr, s->mesh[2*i].p1.x >> 16, s->mesh[2*i].p1.y >> 16);
+ cairo_line_to (cr, s->mesh[2*i].p2.x >> 16, s->mesh[2*i].p2.y >> 16);
+ cairo_line_to (cr, s->mesh[2*i].p3.x >> 16, s->mesh[2*i].p3.y >> 16);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
}
static void
drawSubWindow (cairo_t *cr, SubWindow *s)
{
- /* The next two lines are just temporary, until I write proper code to draw
- * arbitrary triangles in the mesh - which will allow for more exotic
- * meshes to be used, and really neat effects to be done
- */
- cairo_set_source_surface (cr, s->s, s->mesh[0].p1.x>>16, s->mesh[0].p1.y>>16);
- cairo_paint (cr);
for (int i = 0; i+1 < s->nNormTri; i+=2)
- paintTri (cr, s->s, s->mesh[i], s->mesh[i+1]);
+ paintTri (cr, s, i/2);
}
static void
@@ -195,12 +235,22 @@ main (int argc, char **argv)
for (int i = 0; i < N_SUB; i++)
{
sub[i].nTotal = 36;
- sub[i].mesh = malloc (sizeof(XTriangle) * sub[i].nTotal);
sub[i].nNormTri = 4;
+ sub[i].mesh = malloc (sizeof(XTriangle) * sub[i].nTotal);
+ sub[i].m = malloc (sizeof(cairo_matrix_t) * sub[i].nNormTri / 2);
meshWindow (&sub[i].mesh[0], CSIZE*i, CSIZE*i, CSIZE*(i+1), CSIZE*(i+1), 0, 0, CSIZE, CSIZE);
XCompositeSetTriangularCoordinateMesh (d, sub[i].id, sub[i].mesh, sub[i].nNormTri, sub[i].nTotal - sub[i].nNormTri);
sub[i].p = XCompositeNameWindowPixmap (d, sub[i].id);
+ for (int j = 0; j < sub[i].nNormTri; j+=2)
+ {
+ XTriangle p = sub[i].mesh[j];
+ XTriangle c = sub[i].mesh[j+1];
+ sub[i].m[j/2] = setupMatrix (p.p1.x>>16, p.p1.y>>16, p.p2.x>>16, p.p2.y>>16, p.p3.x>>16, p.p3.y>>16,
+ c.p1.x>>16, c.p1.y>>16, c.p2.x>>16, c.p2.y>>16, c.p3.x>>16, c.p3.y>>16);
+
+ }
+
sub[i].s = cairo_xlib_surface_create (d, sub[i].id, v, CSIZE, CSIZE);
sub[i].cr = cairo_create (sub[i].s);
@@ -229,7 +279,7 @@ main (int argc, char **argv)
}
break;
case MotionNotify:
- if ( ev.xany.window == w ) continue;
+ if ( ev.xany.window == w ){fprintf(stderr,"(%d %d) (%d %d)\n",ev.xbutton.x_root, ev.xbutton.y_root, ev.xbutton.x, ev.xbutton.y); continue;}
SubWindow *s = findSubwindow (ev.xany.window);
if(s->drawing)
{
@@ -240,7 +290,7 @@ main (int argc, char **argv)
cairo_stroke (s->cr);
drawWindow (cr);
fprintf(stderr,"ev - w:0x%x\t(%d %d)\t(%d %d)\n",(unsigned)ev.xany.window,ev.xbutton.x_root, ev.xbutton.y_root,ev.xbutton.x, ev.xbutton.y);
-int x, y, rx, ry;
+/*int x, y, rx, ry;
Window child, root;
unsigned mask;
XTranslateCoordinates (d, RootWindow(d, 0), s->id, ev.xbutton.x_root, ev.xbutton.y_root, &x, &y, &child);
@@ -248,7 +298,7 @@ XTranslateCoordinates (d, s->id, RootWindow(d, 0), ev.xbutton.x, ev.xbutton.y, &
fprintf(stderr,"tr - w:0x%x\t(%d %d)\t(%d %d)\n",(unsigned)ev.xany.window,rx,ry,x,y);
XQueryPointer (d, s->id, &root, &child, &rx, &ry, &x, &y, &mask);
fprintf(stderr,"qu - w:0x%x\t(%d %d)\t(%d %d)\n\n",(unsigned)ev.xany.window,rx,ry,x,y);
- }
+*/ }
s->x = ev.xbutton.x;
s->y = ev.xbutton.y;
break;