diff options
author | Joel Bosveld <Joel.Bosveld@gmail.com> | 2009-07-07 22:16:41 +0800 |
---|---|---|
committer | Joel Bosveld <Joel.Bosveld@gmail.com> | 2009-07-07 22:16:41 +0800 |
commit | e78d59c3acd6886101add2e227ff205091361a85 (patch) | |
tree | 2703a4bed6afd95a139073c3a875cbe6de9fec67 | |
parent | 21f3daebe3c049cca2753fae9b56d28958647543 (diff) |
sub: draw the redirected subwindows using the mesh
-rw-r--r-- | sub/sub.c | 76 |
1 files changed, 63 insertions, 13 deletions
@@ -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; |