From: ellson Date: Mon, 27 Jun 2005 13:23:53 +0000 (+0000) Subject: fix linewidth in gd output under viewport zooming X-Git-Tag: LAST_LIBGRAPH~32^2~7492 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2e015580449396e876808ddcd299c3845598cf3f;p=graphviz fix linewidth in gd output under viewport zooming add hooks to allow plugins to use their own point transformation facilities, instead of pre multiplying coordinates. --- diff --git a/lib/common/gdgen.c b/lib/common/gdgen.c index 8dde016bd..acce5c751 100644 --- a/lib/common/gdgen.c +++ b/lib/common/gdgen.c @@ -779,11 +779,11 @@ static void gd_polygon(point * A, int n, int filled) } else { pen = cstk[SP].pencolor; } + width = cstk[SP].penwidth * CompScale; + gdImageSetThickness(im, WIDTH_NORMAL); #if 1 /* use brush instead of Thickness to improve end butts */ - gdImageSetThickness(im, WIDTH_NORMAL); - if (cstk[SP].penwidth != WIDTH_NORMAL) { - width = cstk[SP].penwidth * CompScale; + if (width != WIDTH_NORMAL) { brush = gdImageCreate(width, width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, @@ -795,9 +795,6 @@ static void gd_polygon(point * A, int n, int filled) else pen = gdBrushed; } -#else - width = cstk[SP].penwidth; - gdImageSetThickness(im, width); #endif points = N_GNEW(n, gdPoint); for (i = 0; i < n; i++) { @@ -847,11 +844,11 @@ static void gd_ellipse(point p, int rx, int ry, int filled) } else { pen = cstk[SP].pencolor; } + width = cstk[SP].penwidth * CompScale; + gdImageSetThickness(im, width); #if 1 /* use brush instead of Thickness to improve outline appearance */ - gdImageSetThickness(im, WIDTH_NORMAL); - if (cstk[SP].penwidth != WIDTH_NORMAL) { - width = cstk[SP].penwidth; + if (width != WIDTH_NORMAL) { brush = gdImageCreate(width, width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, @@ -863,9 +860,6 @@ static void gd_ellipse(point p, int rx, int ry, int filled) else pen = gdBrushed; } -#else - width = cstk[SP].penwidth; - gdImageSetThickness(im, width); #endif if (Rot) { int t; @@ -919,9 +913,10 @@ static void gd_polyline(point * A, int n) } else { pen = cstk[SP].pencolor; } -#if 0 - if (cstk[SP].penwidth != WIDTH_NORMAL) { - width = cstk[SP].penwidth; + width = cstk[SP].penwidth * CompScale; + gdImageSetThickness(im, width); +#if 1 + if (width != WIDTH_NORMAL) { brush = gdImageCreate(width, width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, @@ -933,9 +928,6 @@ static void gd_polyline(point * A, int n) else pen = gdBrushed; } -#else - width = cstk[SP].penwidth; - gdImageSetThickness(im, width); #endif p.x = A[0].x; p.y = A[0].y; diff --git a/lib/gvc/gvcint.h b/lib/gvc/gvcint.h index f0f31f7d7..e66b78996 100644 --- a/lib/gvc/gvcint.h +++ b/lib/gvc/gvcint.h @@ -56,6 +56,7 @@ extern "C" { #define GVRENDER_DOES_TRUECOLOR (1<<8) #define GVRENDER_Y_GOES_DOWN (1<<9) #define GVRENDER_X11_EVENTS (1<<10) +#define GVRENDER_DOES_TRANSFORM (1<<11) typedef struct { int flags; @@ -71,6 +72,18 @@ extern "C" { int flags; } gvdevice_features_t; + /* + * gv_matrix_t: (compat with cairo_matrix_t) + * + * A #gv_matrix_t holds an affine transformation, such as a scale, + * rotation, or shear, or a combination of those. + */ + typedef struct gv_matrix_s { + double xx; double yx; + double xy; double yy; + double x0; double y0; + } gv_matrix_t; + struct GVJ_s { GVJ_t *next; /* linked list of jobs */ GVJ_t *next_active; /* linked list of active jobs (e.g. multiple windows) */ @@ -132,6 +145,7 @@ extern "C" { boxf clip; /* clip region in graph units */ boxf pageBoxClip; /* intersection of clip and pageBox */ + gv_matrix_t transform; /* transformation matrix for renderers that can use it */ pointf compscale; /* composite device scale incl: scale, zoom, dpi, y_goes_down */ pointf offset; /* composite translation */ diff --git a/lib/gvc/gvrender.c b/lib/gvc/gvrender.c index 11de867b5..a664fa7ea 100644 --- a/lib/gvc/gvrender.c +++ b/lib/gvc/gvrender.c @@ -158,15 +158,9 @@ static pointf gvrender_ptf(GVJ_t *job, pointf p) { pointf rv; -#if 0 - if (job->rotation) { - rv.x = -(p.y - job->focus.y) * job->compscale.x + job->width / 2.; - rv.y = (p.x - job->focus.x) * job->compscale.y + job->height / 2.; - } else { - rv.x = (p.x - job->focus.x) * job->compscale.x + job->width / 2.; - rv.y = (p.y - job->focus.y) * job->compscale.y + job->height / 2.; - } -#else + if (job->render_features->flags & GVRENDER_DOES_TRANSFORM) + return p; + if (job->rotation) { rv.x = -p.y * job->compscale.x + job->offset.x; rv.y = p.x * job->compscale.y + job->offset.y; @@ -174,7 +168,6 @@ static pointf gvrender_ptf(GVJ_t *job, pointf p) rv.x = p.x * job->compscale.x + job->offset.x; rv.y = p.y * job->compscale.y + job->offset.y; } -#endif return rv; } @@ -228,6 +221,13 @@ void gvrender_begin_graph(GVJ_t * job, graph_t * g) job->clip.LL.y = job->focus.y - sx - EPSILON; job->offset.x = -job->focus.y * job->compscale.x + job->width / 2.; job->offset.y = -job->focus.x * job->compscale.y + job->height / 2.; + + job->transform.xx = 0; + job->transform.yy = 0; + job->transform.xy = job->compscale.x; + job->transform.yx = job->compscale.y; + job->transform.x0 = job->offset.y; + job->transform.y0 = job->offset.x; } else { job->clip.UR.x = job->focus.x + sx + EPSILON; job->clip.UR.y = job->focus.y + sy + EPSILON; @@ -235,6 +235,13 @@ void gvrender_begin_graph(GVJ_t * job, graph_t * g) job->clip.LL.y = job->focus.y - sy - EPSILON; job->offset.x = -job->focus.x * job->compscale.x + job->width / 2.; job->offset.y = -job->focus.y * job->compscale.y + job->height / 2.; + + job->transform.xx = job->compscale.x; + job->transform.yy = job->compscale.y; + job->transform.xy = 0; + job->transform.yx = 0; + job->transform.x0 = job->offset.x; + job->transform.y0 = job->offset.y; } if (gvre) {