X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fgfxtools.c;h=239368a257ce9fbf59aec8dc844b14eff5120b50;hb=6fdab3c4ec7ca7ad9161136a33ff465e227d9661;hp=938f6e459a847d43e86dedbc249aeeab6ecc7c0b;hpb=dfd8a7513517382f581d82581152f66a3d6c1faa;p=swftools.git diff --git a/lib/gfxtools.c b/lib/gfxtools.c index 938f6e4..239368a 100644 --- a/lib/gfxtools.c +++ b/lib/gfxtools.c @@ -56,9 +56,17 @@ static void linedraw_lineTo(gfxdrawer_t*d, gfxcoord_t x, gfxcoord_t y) { linedraw_internal_t*i = (linedraw_internal_t*)d->internal; gfxline_t*l = rfx_alloc(sizeof(gfxline_t)); + + if(!i->start) { + /* starts with a line, not with a moveto. That needs we first + need an explicit moveto to (0,0) */ + linedraw_moveTo(d, 0, 0); + } + l->type = gfx_lineTo; d->x = l->x = x; d->y = l->y = y; + l->next = 0; if(i->next) i->next->next = l; @@ -70,6 +78,13 @@ static void linedraw_splineTo(gfxdrawer_t*d, gfxcoord_t sx, gfxcoord_t sy, gfxco { linedraw_internal_t*i = (linedraw_internal_t*)d->internal; gfxline_t*l = rfx_alloc(sizeof(gfxline_t)); + + if(!i->start) { + /* starts with a line, not with a moveto. That needs we first + need an explicit moveto to (0,0) */ + linedraw_moveTo(d, 0, 0); + } + l->type = gfx_splineTo; d->x = l->x = x; d->y = l->y = y; @@ -94,6 +109,8 @@ static void* linedraw_result(gfxdrawer_t*d) void gfxdrawer_target_gfxline(gfxdrawer_t*d) { linedraw_internal_t*i = (linedraw_internal_t*)rfx_calloc(sizeof(linedraw_internal_t)); + d->x = 0x7fffffff; + d->y = 0x7fffffff; d->internal = i; d->moveTo = linedraw_moveTo; d->lineTo = linedraw_lineTo; @@ -312,13 +329,13 @@ gfxline_t* gfxtool_dash_line(gfxline_t*line, float*dashes, float phase) void gfxline_show(gfxline_t*l, FILE*fi) { while(l) { - if(l->type == moveTo) { + if(l->type == gfx_moveTo) { fprintf(fi, "moveTo %.2f,%.2f\n", l->x, l->y); } - if(l->type == lineTo) { + if(l->type == gfx_lineTo) { fprintf(fi, "lineTo %.2f,%.2f\n", l->x, l->y); } - if(l->type == splineTo) { + if(l->type == gfx_splineTo) { fprintf(fi, "splineTo %.2f,%.2f %.2f,%.2f\n", l->sx, l->sy, l->x, l->y); } l = l->next; @@ -411,7 +428,7 @@ static int approximate3(const cspline_t*s, qspline_t*q, int size, double quality test.control.y += test.end.y; } -#define PROBES +//#define PROBES #ifdef PROBES /* measure the spline's accurancy, by taking a number of probes */ for(t=0;tend.x - s->control2.x*3 + s->control1.x*3 - s->start.x; dy= s->end.y - s->control2.y*3 + s->control1.y*3 - s->start.y; + /* we need to do this for the subspline between [start,end], not [0,1] + as a transformation of t->a*t+b does nothing to highest coefficient + of the spline except multiply it with a^3, we just need to modify + d here. */ + {double m = end-start; + dx*=m*m*m; + dy*=m*m*m; + } + /* use the integral over (f(x)-g(x))^2 between 0 and 1 to measure the approximation quality. - (it boils down to const*d^2) - */ + (it boils down to const*d^2) */ recurse = (dx*dx + dy*dy > quality2); #endif @@ -473,21 +495,21 @@ static int approximate3(const cspline_t*s, qspline_t*q, int size, double quality return num; } -void gfxdraw_conicTo(gfxdrawer_t*draw, double cx, double cy, double tox, double toy) +void gfxdraw_conicTo(gfxdrawer_t*draw, double cx, double cy, double tox, double toy, double quality) { double c1x = (draw->x + 2 * cx) / 3; double c1y = (draw->y + 2 * cy) / 3; double c2x = (2 * cx + tox) / 3; double c2y = (2 * cy + toy) / 3; - gfxdraw_cubicTo(draw, c1x, c1y, c2x, c2y, tox, toy); + gfxdraw_cubicTo(draw, c1x, c1y, c2x, c2y, tox, toy, quality); } -void gfxdraw_cubicTo(gfxdrawer_t*draw, double c1x, double c1y, double c2x, double c2y, double x, double y) +void gfxdraw_cubicTo(gfxdrawer_t*draw, double c1x, double c1y, double c2x, double c2y, double x, double y, double quality) { qspline_t q[128]; cspline_t c; - double maxerror = 0.01; + double maxerror = quality>0 ? quality : 1.0; int t,num; c.start.x = draw->x; @@ -606,3 +628,24 @@ void gfxmatrix_dump(gfxmatrix_t*m, FILE*fi, char*prefix) fprintf(fi, "%f %f | %f\n", m->m00, m->m10, m->tx); fprintf(fi, "%f %f | %f\n", m->m01, m->m11, m->ty); } + +void gfxmatrix_transform(gfxmatrix_t*m, double* v, double*dest) +{ + dest[0] = m->m00*v[0] + m->m10*v[1] + m->tx; + dest[1] = m->m01*v[0] + m->m11*v[1] + m->ty; +} +void gfxmatrix_invert(gfxmatrix_t*m, gfxmatrix_t*dest) +{ + double det = m->m00 * m->m11 - m->m10 * m->m01; + if(!det) { + memset(dest, 0, sizeof(gfxmatrix_t)); + return; + } + det = 1/det; + dest->m00 = m->m11 * det; + dest->m01 = -m->m01 * det; + dest->m10 = -m->m10 * det; + dest->m11 = m->m00 * det; + dest->tx = -(dest->m00 * m->tx + dest->m10 * m->ty); + dest->ty = -(dest->m01 * m->tx + dest->m11 * m->ty); +}