X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fgfxtools.c;h=cd08a42a5a1d825b01687cd37cfd0106b60ae87d;hb=d320fe6202257cc281bbd0f3e45895b3bc4f2ef9;hp=1e3c1aaf1012e97e9afd786b38e87c9f0a4b7735;hpb=dbe6ea0f365d5126d60736531b03b9a7f4feab4f;p=swftools.git diff --git a/lib/gfxtools.c b/lib/gfxtools.c index 1e3c1aa..cd08a42 100644 --- a/lib/gfxtools.c +++ b/lib/gfxtools.c @@ -280,6 +280,25 @@ void gfxtool_draw_dashed_line(gfxdrawer_t*d, gfxline_t*line, float*r, float phas } } +gfxline_t * gfxline_clone(gfxline_t*line) +{ + gfxline_t*dest = 0; + gfxline_t*pos = 0; + while(line) { + gfxline_t*n = rfx_calloc(sizeof(gfxline_t)); + *n = *line; + n->next = 0; + if(!pos) { + dest = pos = n; + } else { + pos->next = n; + pos = n; + } + line = line->next; + } + return dest; +} + gfxline_t* gfxtool_dash_line(gfxline_t*line, float*dashes, float phase) { gfxdrawer_t d; @@ -392,7 +411,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 @@ -454,11 +478,21 @@ static int approximate3(const cspline_t*s, qspline_t*q, int size, double quality return num; } -void gfxdraw_cubicTo(gfxdrawer_t*draw, double c1x, double c1y, double c2x, double c2y, double x, double y) +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, quality); +} + + +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.04; + double maxerror = quality>0 ? quality : 1.0; int t,num; c.start.x = draw->x; @@ -470,11 +504,11 @@ void gfxdraw_cubicTo(gfxdrawer_t*draw, double c1x, double c1y, double c2x, doubl c.end.x = x; c.end.y = y; - num = approximate3(&c, q, 128, maxerror*maxerror); + num = approximate3(&c, q, 128, maxerror); for(t=0;tx; - y = line->x; + y = line->y; line = line->next; } return bbox; @@ -543,3 +577,37 @@ void gfxline_dump(gfxline_t*line, FILE*fi, char*prefix) } } +gfxline_t* gfxline_append(gfxline_t*line1, gfxline_t*line2) +{ + gfxline_t*l = line1;; + if(!l) + return line2; + while(l->next) { + l = l->next; + } + l->next = line2; + return line1; +} + +void gfxline_transform(gfxline_t*line, gfxmatrix_t*matrix) +{ + while(line) { + double x = matrix->m00*line->x + matrix->m10*line->y + matrix->tx; + double y = matrix->m01*line->x + matrix->m11*line->y + matrix->ty; + line->x = x; + line->y = y; + if(line->type == gfx_splineTo) { + double sx = matrix->m00*line->sx + matrix->m10*line->sy + matrix->tx; + double sy = matrix->m01*line->sx + matrix->m11*line->sy + matrix->ty; + line->sx = sx; + line->sy = sy; + } + line = line->next; + } +} + +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); +}