From: ellson Date: Tue, 13 Jun 2006 21:34:53 +0000 (+0000) Subject: factor out all coordinate transformations into single calculaton X-Git-Tag: LAST_LIBGRAPH~32^2~6441 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=798b253ec0d5e5c3de6ba1298bd1eb85ddfb2da9;p=graphviz factor out all coordinate transformations into single calculaton --- diff --git a/lib/common/emit.c b/lib/common/emit.c index db2f5e59e..a9e12e273 100644 --- a/lib/common/emit.c +++ b/lib/common/emit.c @@ -259,17 +259,17 @@ static void init_job_pagination(GVJ_t * job, graph_t *g) margin.y += (pageSize.y - imageSize.y) / 2; } - job->boundingBox.LL.x = margin.x; - job->boundingBox.LL.y = margin.y; - job->boundingBox.UR.x = margin.x + imageSize.x; - job->boundingBox.UR.y = margin.y + imageSize.y; + job->canvasBox.LL.x = margin.x; + job->canvasBox.LL.y = margin.y; + job->canvasBox.UR.x = margin.x + imageSize.x; + job->canvasBox.UR.y = margin.y + imageSize.y; #if 0 -fprintf(stderr,"margin = %d,%d imageSize = %d,%d boundingBox = %d,%d %d,%d\n", +fprintf(stderr,"margin = %d,%d imageSize = %d,%d pageBoundingBox = %d,%d %d,%d\n", margin.x, margin.y, imageSize.x, imageSize.x, - job->boundingBox.LL.x, job->boundingBox.LL.y, - job->boundingBox.UR.x, job->boundingBox.UR.x); + job->pageBoundingBox.LL.x, job->pageBoundingBox.LL.y, + job->pageBoundingBox.UR.x, job->pageBoundingBox.UR.x); #endif /* set up pagedir */ @@ -294,11 +294,11 @@ fprintf(stderr,"job->pageSize= %g,%g (graph units)\n", job->pageSize.x, job->pageSize.y); fprintf(stderr,"dpi = %g,%g zoom = %g rotation = %d\n", job->dpi.x, job->dpi.y, job->zoom, job->rotation); -fprintf(stderr,"boundingBox = %d,%d %d,%d (device units)\n", - job->boundingBox.LL.x, - job->boundingBox.LL.y, - job->boundingBox.UR.x, - job->boundingBox.UR.y); +fprintf(stderr,"pageBoundingBox = %d,%d %d,%d (device units)\n", + job->pageBoundingBox.LL.x, + job->pageBoundingBox.LL.y, + job->pageBoundingBox.UR.x, + job->pageBoundingBox.UR.y); fprintf(stderr,"width,height = %d,%d (device units)\n", job->width, job->height); @@ -394,20 +394,55 @@ static void setup_page(GVJ_t * job, graph_t * g) job->pageBox.UR.y = job->pageBox.LL.y + job->pageSize.y; /* establish pageOffset to be applied, in graph coordinates */ - if (job->rotation == 0) { - job->pageOffset.x = pad.x - job->pageSize.x * job->pagesArrayElem.x; - job->pageOffset.y = pad.y - job->pageSize.y * job->pagesArrayElem.y; - } - else { + if (job->rotation) { job->pageOffset.x = -pad.x + job->pageSize.y * (job->pagesArrayElem.y +1); job->pageOffset.y = pad.y - job->pageSize.x * job->pagesArrayElem.x; } + else { + job->pageOffset.x = pad.x - job->pageSize.x * job->pagesArrayElem.x; + job->pageOffset.y = pad.y - job->pageSize.y * job->pagesArrayElem.y; + } job->pageBoxClip.UR.x = MIN(job->clip.UR.x, job->pageBox.UR.x); job->pageBoxClip.UR.y = MIN(job->clip.UR.y, job->pageBox.UR.y); job->pageBoxClip.LL.x = MAX(job->clip.LL.x, job->pageBox.LL.x); job->pageBoxClip.LL.y = MAX(job->clip.LL.y, job->pageBox.LL.y); + if (job->rotation) { + job->pageBoundingBox.LL.x = job->canvasBox.LL.y; + job->pageBoundingBox.LL.y = job->canvasBox.LL.x; + job->pageBoundingBox.UR.x = job->canvasBox.UR.y; + job->pageBoundingBox.UR.y = job->canvasBox.UR.x; + } + else { + job->pageBoundingBox = job->canvasBox; + } + + if (job->common->viewNum == 0) + job->boundingBox = job->pageBoundingBox; + else + EXPANDBB(job->boundingBox, job->pageBoundingBox); + + if (job->rotation) { + if (job->flags & GVRENDER_Y_GOES_DOWN) { + job->translation.x = -job->pageBox.UR.x - job->pageBoundingBox.LL.y / job->scale.y; + job->translation.y = job->pageBox.UR.y + job->pageBoundingBox.LL.x / job->scale.x; + } + else { + job->translation.x = -job->pageBox.LL.x + job->pageBoundingBox.LL.y / job->scale.y; + } + } + else { + job->translation.x = -job->pageBox.LL.x + job->pageBoundingBox.LL.x / job->scale.x; + if (job->flags & GVRENDER_Y_GOES_DOWN) + job->translation.y = job->pageBox.UR.y + job->pageBoundingBox.LL.y / job->scale.y; + else + job->translation.y = -job->pageBox.LL.y + job->pageBoundingBox.LL.y / job->scale.y; + } + job->comptrans = job->translation; + job->comptrans.y *= (job->flags & GVRENDER_Y_GOES_DOWN) ? -1: 1; + + #if 0 fprintf(stderr,"pagesArrayElem = %d,%d pageSize = %g,%g pageOffset = %g,%g\n", job->pagesArrayElem.x, job->pagesArrayElem.y, @@ -1186,7 +1221,7 @@ static void init_job_viewport(GVJ_t * job, graph_t * g) job->zoom = Z; /* scaling factor */ job->focus.x = x; /* graph coord of focus - points */ job->focus.y = y; - job->rotation = job->gvc->rotation; + job->rotation = job->gvc->rotation * ((job->flags & GVRENDER_Y_GOES_DOWN) ? -1 : 1); #if 0 fprintf(stderr,"bb = %d,%d %d,%d size %d,%d (graph units)\n", diff --git a/lib/common/ps.h b/lib/common/ps.h index c28c7a446..dc1db3a40 100644 --- a/lib/common/ps.h +++ b/lib/common/ps.h @@ -1,200 +1,169 @@ -/* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ - -/********************************************************** -* This software is part of the graphviz package * -* http://www.graphviz.org/ * -* * -* Copyright (c) 1994-2004 AT&T Corp. * -* and is licensed under the * -* Common Public License, Version 1.0 * -* by AT&T Corp. * -* * -* Information and Software Systems Research * -* AT&T Research, Florham Park NJ * -**********************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - - char *ps_txt[] = { - "%%BeginProlog", - "/DotDict 200 dict def", - "DotDict begin", - "", - "/setupLatin1 {", - "mark", - "/EncodingVector 256 array def", - " EncodingVector 0", - "", - "ISOLatin1Encoding 0 255 getinterval putinterval", - "EncodingVector 45 /hyphen put", - "", - "% Set up ISO Latin 1 character encoding", - "/starnetISO {", - " dup dup findfont dup length dict begin", - " { 1 index /FID ne { def }{ pop pop } ifelse", - " } forall", - " /Encoding EncodingVector def", - " currentdict end definefont", - "} def", - "/Times-Roman starnetISO def", - "/Times-Italic starnetISO def", - "/Times-Bold starnetISO def", - "/Times-BoldItalic starnetISO def", - "/Helvetica starnetISO def", - "/Helvetica-Oblique starnetISO def", - "/Helvetica-Bold starnetISO def", - "/Helvetica-BoldOblique starnetISO def", - "/Courier starnetISO def", - "/Courier-Oblique starnetISO def", - "/Courier-Bold starnetISO def", - "/Courier-BoldOblique starnetISO def", - "cleartomark", - "} bind def", - "", - "%%BeginResource: procset graphviz 0 0", - "/coord-font-family /Times-Roman def", - "/default-font-family /Times-Roman def", - "/coordfont coord-font-family findfont 8 scalefont def", - "", - "/InvScaleFactor 1.0 def", - "/set_scale {", - " dup 1 exch div /InvScaleFactor exch def", - " dup scale", - "} bind def", - "", - "% styles", - "/solid { [] 0 setdash } bind def", - "/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def", - "/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def", - "/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def", - "/bold { 2 setlinewidth } bind def", - "/filled { } bind def", - "/unfilled { } bind def", - "/rounded { } bind def", - "/diagonals { } bind def", - "", - "% hooks for setting color ", - "/nodecolor { sethsbcolor } bind def", - "/edgecolor { sethsbcolor } bind def", - "/graphcolor { sethsbcolor } bind def", - "/nopcolor {pop pop pop} bind def", - "", - "/beginpage { % i j npages", - " /npages exch def", - " /j exch def", - " /i exch def", - " /str 10 string def", - " npages 1 gt {", - " gsave", - " coordfont setfont", - " 0 0 moveto", - " (\\() show i str cvs show (,) show j str cvs show (\\)) show", - " grestore", - " } if", - "} bind def", - "", - "/set_font {", - " findfont exch", - " scalefont setfont", - "} def", - "", - "% draw aligned label in bounding box aligned to current point", - "/alignedtext { % width adj text", - " /text exch def", - " /adj exch def", - " /width exch def", - " gsave", - " width 0 gt {", - " text stringwidth pop adj mul 0 rmoveto", - " } if", - " [] 0 setdash", - " text show", - " grestore", - "} def", - "", - "/boxprim { % xcorner ycorner xsize ysize", - " 4 2 roll", - " moveto", - " 2 copy", - " exch 0 rlineto", - " 0 exch rlineto", - " pop neg 0 rlineto", - " closepath", - "} bind def", - "", - "/ellipse_path {", - " /ry exch def", - " /rx exch def", - " /y exch def", - " /x exch def", - " matrix currentmatrix", - " newpath", - " x y translate", - " rx ry scale", - " 0 0 1 0 360 arc", - " setmatrix", - "} bind def", - "", - "/endpage { showpage } bind def", - "/showpage { } def", - "", - "/layercolorseq", - " [ % layer color sequence - darkest to lightest", - " [0 0 0]", - " [.2 .8 .8]", - " [.4 .8 .8]", - " [.6 .8 .8]", - " [.8 .8 .8]", - " ]", - "def", - "", - "/layerlen layercolorseq length def", - "", - "/setlayer {/maxlayer exch def /curlayer exch def", - " layercolorseq curlayer 1 sub layerlen mod get", - " aload pop sethsbcolor", - " /nodecolor {nopcolor} def", - " /edgecolor {nopcolor} def", - " /graphcolor {nopcolor} def", - "} bind def", - "", - "/onlayer { curlayer ne {invis} if } def", - "", - "/onlayers {", - " /myupper exch def", - " /mylower exch def", - " curlayer mylower lt", - " curlayer myupper gt", - " or", - " {invis} if", - "} def", - "", - "/curlayer 0 def", - "", - "%%EndResource", - "%%EndProlog", - "%%BeginSetup", - "14 default-font-family set_font", - "1 setmiterlimit", - "% /arrowlength 10 def", - "% /arrowwidth 5 def", - "", - "% make sure pdfmark is harmless for PS-interpreters other than Distiller", - "/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse", - "% make '<<' and '>>' safe on PS Level 1 devices", - "/languagelevel where {pop languagelevel}{1} ifelse", - "2 lt {", - " userdict (<<) cvn ([) cvn load put", - " userdict (>>) cvn ([) cvn load put", - "} if", - "", - "%%EndSetup", - (char *) 0 - }; - -#ifdef __cplusplus -} -#endif +char *ps_txt[] = { +"%%BeginProlog", +"/DotDict 200 dict def", +"DotDict begin", +"", +"/setupLatin1 {", +"mark", +"/EncodingVector 256 array def", +" EncodingVector 0", +"", +"ISOLatin1Encoding 0 255 getinterval putinterval", +"EncodingVector 45 /hyphen put", +"", +"% Set up ISO Latin 1 character encoding", +"/starnetISO {", +" dup dup findfont dup length dict begin", +" { 1 index /FID ne { def }{ pop pop } ifelse", +" } forall", +" /Encoding EncodingVector def", +" currentdict end definefont", +"} def", +"/Times-Roman starnetISO def", +"/Times-Italic starnetISO def", +"/Times-Bold starnetISO def", +"/Times-BoldItalic starnetISO def", +"/Helvetica starnetISO def", +"/Helvetica-Oblique starnetISO def", +"/Helvetica-Bold starnetISO def", +"/Helvetica-BoldOblique starnetISO def", +"/Courier starnetISO def", +"/Courier-Oblique starnetISO def", +"/Courier-Bold starnetISO def", +"/Courier-BoldOblique starnetISO def", +"cleartomark", +"} bind def", +"", +"%%BeginResource: procset graphviz 0 0", +"/coord-font-family /Times-Roman def", +"/default-font-family /Times-Roman def", +"/coordfont coord-font-family findfont 8 scalefont def", +"", +"% styles", +"/solid { [] 0 setdash } bind def", +"/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def", +"/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def", +"/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def", +"/bold { 2 setlinewidth } bind def", +"/filled { } bind def", +"/unfilled { } bind def", +"/rounded { } bind def", +"/diagonals { } bind def", +"", +"% hooks for setting color ", +"/nodecolor { sethsbcolor } bind def", +"/edgecolor { sethsbcolor } bind def", +"/graphcolor { sethsbcolor } bind def", +"/nopcolor {pop pop pop} bind def", +"", +"/beginpage { % i j npages", +" /npages exch def", +" /j exch def", +" /i exch def", +" /str 10 string def", +" npages 1 gt {", +" gsave", +" coordfont setfont", +" 0 0 moveto", +" (\\() show i str cvs show (,) show j str cvs show (\\)) show", +" grestore", +" } if", +"} bind def", +"", +"/set_font {", +" findfont exch", +" scalefont setfont", +"} def", +"", +"% draw aligned label in bounding box aligned to current point", +"/alignedtext { % width adj text", +" /text exch def", +" /adj exch def", +" /width exch def", +" gsave", +" width 0 gt {", +" text stringwidth pop adj mul 0 rmoveto", +" } if", +" [] 0 setdash", +" text show", +" grestore", +"} def", +"", +"/boxprim { % xcorner ycorner xsize ysize", +" 4 2 roll", +" moveto", +" 2 copy", +" exch 0 rlineto", +" 0 exch rlineto", +" pop neg 0 rlineto", +" closepath", +"} bind def", +"", +"/ellipse_path {", +" /ry exch def", +" /rx exch def", +" /y exch def", +" /x exch def", +" matrix currentmatrix", +" newpath", +" x y translate", +" rx ry scale", +" 0 0 1 0 360 arc", +" setmatrix", +"} bind def", +"", +"/endpage { showpage } bind def", +"/showpage { } def", +"", +"/layercolorseq", +" [ % layer color sequence - darkest to lightest", +" [0 0 0]", +" [.2 .8 .8]", +" [.4 .8 .8]", +" [.6 .8 .8]", +" [.8 .8 .8]", +" ]", +"def", +"", +"/layerlen layercolorseq length def", +"", +"/setlayer {/maxlayer exch def /curlayer exch def", +" layercolorseq curlayer 1 sub layerlen mod get", +" aload pop sethsbcolor", +" /nodecolor {nopcolor} def", +" /edgecolor {nopcolor} def", +" /graphcolor {nopcolor} def", +"} bind def", +"", +"/onlayer { curlayer ne {invis} if } def", +"", +"/onlayers {", +" /myupper exch def", +" /mylower exch def", +" curlayer mylower lt", +" curlayer myupper gt", +" or", +" {invis} if", +"} def", +"", +"/curlayer 0 def", +"", +"%%EndResource", +"%%EndProlog", +"%%BeginSetup", +"14 default-font-family set_font", +"1 setmiterlimit", +"% /arrowlength 10 def", +"% /arrowwidth 5 def", +"", +"% make sure pdfmark is harmless for PS-interpreters other than Distiller", +"/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse", +"% make '<<' and '>>' safe on PS Level 1 devices", +"/languagelevel where {pop languagelevel}{1} ifelse", +"2 lt {", +" userdict (<<) cvn ([) cvn load put", +" userdict (>>) cvn ([) cvn load put", +"} if", +"", +"%%EndSetup", +(char*)0 }; diff --git a/lib/common/ps.txt b/lib/common/ps.txt index 59c2dfc48..168c3852d 100644 --- a/lib/common/ps.txt +++ b/lib/common/ps.txt @@ -38,12 +38,6 @@ cleartomark /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def -/InvScaleFactor 1.0 def -/set_scale { - dup 1 exch div /InvScaleFactor exch def - dup scale -} bind def - % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def diff --git a/lib/common/psgen.c b/lib/common/psgen.c index 2a6644e16..dd25e254c 100644 --- a/lib/common/psgen.c +++ b/lib/common/psgen.c @@ -27,7 +27,6 @@ #ifdef HAVE_LIBGD #include "gd.h" #endif -#include "ps.h" #ifndef MSWIN32 #include @@ -116,7 +115,7 @@ static void ps_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) PB = bb; if (onetime) { - cat_libfile(Output_file, U_lib, ps_txt); + cat_preamble(gvc->job, U_lib); epsf_define(Output_file); if (Show_boxes) { char* args[2]; @@ -193,7 +192,7 @@ ps_begin_page(graph_t * g, point page, double scale, int rot, point offset) fprintf(Output_file, "%d %d %d beginpage\n", page.x, page.y, N_pages); if (rot) fprintf(Output_file, "grestore\n"); - fprintf(Output_file, "%.4f set_scale\n", scale); + fprintf(Output_file, "%g %g scale\n", scale, scale); fprintf(Output_file, "%d %d translate %d rotate\n", offset.x, offset.y, rot); assert(SP == 0); diff --git a/lib/common/utils.c b/lib/common/utils.c index 71ebbc495..9bdef0ce1 100644 --- a/lib/common/utils.c +++ b/lib/common/utils.c @@ -18,6 +18,7 @@ #include "agxbuf.h" #include "htmltable.h" #include "entities.h" +#include "ps.h" #ifndef MSWIN32 #include @@ -426,6 +427,11 @@ void cat_libfile(FILE * ofp, char **arglib, char **stdlib) } } +void cat_preamble(GVJ_t *job, char **arglib) +{ + cat_libfile(job->output_file, arglib, ps_txt); +} + int maptoken(char *p, char **name, int *val) { int i; diff --git a/lib/common/utils.h b/lib/common/utils.h index 239c6c73b..6a8773f0c 100644 --- a/lib/common/utils.h +++ b/lib/common/utils.h @@ -44,7 +44,8 @@ extern "C" { extern void UF_setname(Agnode_t *, Agnode_t *); extern char *safefile(char *shapefilename); - extern void cat_libfile(FILE *, char **, char **); + extern void cat_libfile(FILE *of, char **arglib, char **stdlib); + extern void cat_preamble(GVJ_t *job, char **arglib); extern int mapbool(char *); extern int maptoken(char *, char **, int *); diff --git a/lib/gvc/gvcjob.h b/lib/gvc/gvcjob.h index 766722d2d..c04847cf9 100644 --- a/lib/gvc/gvcjob.h +++ b/lib/gvc/gvcjob.h @@ -166,20 +166,28 @@ extern "C" { unsigned int width; /* device width in device units */ unsigned int height; /* device height in device units */ - box boundingBox; /* drawable region in device units */ + box canvasBox; /* drawable region in device units */ + box pageBoundingBox; /* rotated boundingBox in device units */ + box boundingBox; /* cumulative boundingBox over all pages in device units */ + pointf dpi; /* device resolution device-units-per-inch */ boxf bb; /* bb in graph units */ pointf pad; /* padding around bb in graph units */ double zoom; /* viewport zoom factor */ - int rotation; /* viewport rotation 0=portrait, 1=landscape */ pointf focus; /* viewport focus in graph units */ boxf clip; /* clip region in graph units */ boxf pageBoxClip; /* intersection of clip and pageBox */ - pointf compscale; /* composite device scale incl: scale, zoom, dpi, y_goes_down */ - pointf offset; /* composite translation */ + pointf scale; /* composite device scale (zoom and dpi) */ + int rotation; /* viewport rotation (degrees) 0=portrait, 90=landscape */ + pointf translation; /* composite translation */ + + + pointf compscale; /* composite device scale incl: zoom, dpi, y_goes_down */ + pointf comptrans; /* composite translation */ + pointf offset; /* composite translation (used by codegens) */ bool fit_mode, needs_refresh, diff --git a/lib/gvc/gvevent.c b/lib/gvc/gvevent.c index 6594728d1..23fcd2eeb 100644 --- a/lib/gvc/gvevent.c +++ b/lib/gvc/gvevent.c @@ -295,15 +295,24 @@ static void gvevent_find_current_obj(GVJ_t * job, pointf pointer) boxf b; double closeenough; - /* convert window point to graph coordinates */ if (job->rotation) { - p.x = job->focus.y - (pointer.y - job->height / 2. - job->margin.y) / job->compscale.x; - p.y = job->focus.x + (pointer.x - job->width / 2. - job->margin.x) / job->compscale.y; + p.x = pointer.y / job->compscale.y - job->comptrans.x; + p.y = -pointer.x / job->compscale.x - job->comptrans.y; } else { - p.x = job->focus.x + (pointer.x - job->width / 2. - job->margin.x) / job->compscale.x; - p.y = job->focus.y + (pointer.y - job->height / 2. - job->margin.y) / job->compscale.y; + p.x = pointer.x / job->compscale.x - job->comptrans.x; + p.y = pointer.y / job->compscale.y - job->comptrans.y; } + +#if 0 +fprintf(stderr,"pointer = %g,%g compscale = %g,%g comptrans = %g,%g, graphpoint = %g,%g\n", + pointer.x, pointer.y, + job->compscale.x, job->compscale.y, + job->comptrans.x, job->comptrans.y, + p.x, p.y); +#endif + + /* convert window point to graph coordinates */ closeenough = CLOSEENOUGH / job->compscale.x; b.UR.x = p.x + closeenough; diff --git a/lib/gvc/gvrender.c b/lib/gvc/gvrender.c index e8bbe857b..90ccfcd19 100644 --- a/lib/gvc/gvrender.c +++ b/lib/gvc/gvrender.c @@ -182,11 +182,11 @@ static pointf gvrender_ptf(GVJ_t *job, pointf p) return p; if (job->rotation) { - rv.x = -(p.y - job->focus.y) * job->compscale.x + job->width / 2. + job->margin.x * job->dpi.x / POINTS_PER_INCH; - rv.y = -(p.x - job->focus.x) * job->compscale.y + job->height / 2. + job->margin.y * job->dpi.y / POINTS_PER_INCH; + rv.x = -(p.y + job->comptrans.y) * job->compscale.x; + rv.y = (p.x + job->comptrans.x) * job->compscale.y; } else { - rv.x = (p.x - job->focus.x) * job->compscale.x + job->width / 2. + job->margin.x * job->dpi.x / POINTS_PER_INCH; - rv.y = (p.y - job->focus.y) * job->compscale.y + job->height / 2. + job->margin.y * job->dpi.y / POINTS_PER_INCH; + rv.x = (p.x + job->comptrans.x) * job->compscale.x; + rv.y = (p.y + job->comptrans.y) * job->compscale.y; } return rv; } @@ -246,8 +246,8 @@ void gvrender_begin_graph(GVJ_t * job, graph_t * g) job->common->objtype = "graph"; job->g = g; /* current graph */ - job->compscale.x = job->zoom * job->dpi.x / POINTS_PER_INCH; - job->compscale.y = job->zoom * job->dpi.y / POINTS_PER_INCH; + job->compscale.x = job->scale.x = job->zoom * job->dpi.x / POINTS_PER_INCH; + job->compscale.y = job->scale.y = job->zoom * job->dpi.y / POINTS_PER_INCH; job->compscale.y *= (job->flags & GVRENDER_Y_GOES_DOWN) ? -1. : 1.; if (job->rotation) { job->clip.UR.x = job->focus.x + sy + EPSILON; @@ -295,7 +295,7 @@ void gvrender_begin_graph(GVJ_t * job, graph_t * g) codegen_t *cg = job->codegen; if (cg && cg->begin_graph) - cg->begin_graph(gvc, g, job->boundingBox, gvc->pb); + cg->begin_graph(gvc, g, job->canvasBox, gvc->pb); } #endif } @@ -327,12 +327,12 @@ void gvrender_begin_page(GVJ_t * job) #ifdef WITH_CODEGENS else { codegen_t *cg = job->codegen; - point offset; + point offset; - PF2P(job->pageOffset, offset); - if (cg && cg->begin_page) - cg->begin_page(job->gvc->g, job->pagesArrayElem, - job->zoom, job->rotation, offset); + PF2P(job->pageOffset, offset); + if (cg && cg->begin_page) + cg->begin_page(job->gvc->g, job->pagesArrayElem, + job->zoom, job->rotation, offset); } #endif } diff --git a/plugin/core/gvrender_core_ps.c b/plugin/core/gvrender_core_ps.c index b639399d5..18afc7555 100644 --- a/plugin/core/gvrender_core_ps.c +++ b/plugin/core/gvrender_core_ps.c @@ -33,18 +33,17 @@ #include "gvplugin_render.h" #include "graph.h" +#include "agxbuf.h" +#include "utils.h" #ifdef HAVE_LIBGD #include "gd.h" #endif -extern void cat_libfile(FILE * ofp, char **arglib, char **stdlib); extern void epsf_define(FILE * of); extern char *ps_string(char *ins, int latin); -extern char **ps_txt; typedef enum { FORMAT_PS, FORMAT_PS2, } format_type; -static box DBB; static int isLatin1; static char setupLatin1; @@ -72,7 +71,8 @@ static void psgen_end_job(GVJ_t * job) fprintf(job->output_file, "%%%%Pages: %d\n", job->common->viewNum); if (job->common->show_boxes == NULL) fprintf(job->output_file, "%%%%BoundingBox: %d %d %d %d\n", - DBB.LL.x, DBB.LL.y, DBB.UR.x, DBB.UR.y); + job->boundingBox.LL.x, job->boundingBox.LL.y, + job->boundingBox.UR.x, job->boundingBox.UR.y); fprintf(job->output_file, "end\nrestore\n"); fprintf(job->output_file, "%%%%EOF\n"); } @@ -87,7 +87,7 @@ static void psgen_begin_graph(GVJ_t * job) if (job->common->show_boxes == NULL) fprintf(job->output_file, "%%%%BoundingBox: (atend)\n"); fprintf(job->output_file, "%%%%EndComments\nsave\n"); - cat_libfile(job->output_file, job->common->lib, ps_txt); + cat_preamble(job, job->common->lib); epsf_define(job->output_file); } #ifdef FIXME @@ -124,35 +124,9 @@ static void psgen_begin_layer(GVJ_t * job, char *layername, int layerNum, int nu fprintf(job->output_file, "%d %d setlayer\n", layerNum, numLayers); } -static point sub_points(point p0, point p1) -{ - p0.x -= p1.x; - p0.y -= p1.y; - return p0; -} - static void psgen_begin_page(GVJ_t * job) { - point sz; - box PB, pbr; - - BF2B(job->boundingBox, PB); - - sz = sub_points(PB.UR, PB.LL); - if (job->rotation) { - pbr.LL.x = PB.LL.y; - pbr.LL.y = PB.LL.x; - pbr.UR.x = PB.UR.y; - pbr.UR.y = PB.UR.x; - } - else { - pbr = PB; - } - - if (job->common->viewNum == 0) - DBB = pbr; - else - EXPANDBB(DBB, pbr); + box pbr = job->pageBoundingBox; fprintf(job->output_file, "%%%%Page: %d %d\n", job->common->viewNum + 1, job->common->viewNum + 1); @@ -164,17 +138,10 @@ static void psgen_begin_page(GVJ_t * job) if (job->common->show_boxes == NULL) fprintf(job->output_file, "gsave\n%d %d %d %d boxprim clip newpath\n", pbr.LL.x, pbr.LL.y, pbr.UR.x, pbr.UR.y); - fprintf(job->output_file, "gsave %g set_scale\n", job->zoom); - if (job->rotation) { - fprintf(job->output_file, "%d rotate\n", job->rotation); - fprintf(job->output_file, "%g %g translate\n", - -job->pageBox.LL.x + pbr.LL.y / job->zoom, - -job->pageBox.UR.y - pbr.LL.x / job->zoom); - } - else - fprintf(job->output_file, "%g %g translate\n", - -job->pageBox.LL.x + pbr.LL.x / job->zoom, - -job->pageBox.LL.y + pbr.LL.y / job->zoom); + fprintf(job->output_file, "gsave %g %g scale %d rotate %g %g translate\n", + job->scale.x, job->scale.y, + job->rotation, + job->translation.x, job->translation.y); #if 0 /* Define the size of the PS canvas */ diff --git a/plugin/core/gvrender_core_svg.c b/plugin/core/gvrender_core_svg.c index 664593e11..c7ea15ef3 100644 --- a/plugin/core/gvrender_core_svg.c +++ b/plugin/core/gvrender_core_svg.c @@ -415,7 +415,7 @@ static void svggen_textpara(GVJ_t * job, pointf p, textpara_t * para) svggen_printf(job, "rotation) - svggen_printf(job, " transform=\"rotate(-%d %g %g)\"", job->rotation, p.x, p.y); + svggen_printf(job, " transform=\"rotate(%d %g %g)\"", job->rotation, p.x, p.y); svggen_printf(job, " x=\"%g\" y=\"%g\"", p.x, p.y); svggen_font(job); svggen_fputs(job, ">"); @@ -492,13 +492,13 @@ svggen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled) svggen_fputs(job, "name); if (job->rotation) { - svggen_printf (job, "\" width=\"%gpx\" height=\"%fpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"", + svggen_printf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"", b.UR.y - b.LL.y, b.UR.x - b.LL.x, b.LL.x, b.UR.y); - svggen_printf (job, " transform=\"rotate(-%d %g %g)\"", + svggen_printf (job, " transform=\"rotate(%d %g %g)\"", job->rotation, b.LL.x, b.UR.y); } else { - svggen_printf (job, "\" width=\"%gpx\" height=\"%fpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"", + svggen_printf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"", b.UR.x - b.LL.x, b.UR.y - b.LL.y, b.LL.x, b.LL.y); } svggen_fputs(job, "/>\n"); diff --git a/plugin/gd/gvrender_gd.c b/plugin/gd/gvrender_gd.c index 13206c273..f480d954f 100644 --- a/plugin/gd/gvrender_gd.c +++ b/plugin/gd/gvrender_gd.c @@ -100,7 +100,7 @@ static void gdgen_resolve_color(GVJ_t * job, gvcolor_t * color) static int white, black, transparent, basecolor; -static void gdgen_begin_graph(GVJ_t * job) +static void gdgen_begin_page(GVJ_t * job) { char *bgcolor_str = NULL, *truecolor_str = NULL; bool truecolor_p = FALSE; /* try to use cheaper paletted mode */ @@ -132,8 +132,9 @@ static void gdgen_begin_graph(GVJ_t * job) im = (gdImagePtr) (job->output_file); } else { /* device size with margins all around */ - width = job->width + 2 * ROUND(job->margin.x * job->dpi.x / POINTS_PER_INCH); - height = job->height + 2 * ROUND(job->margin.y * job->dpi.y / POINTS_PER_INCH); + width = job->pageBoundingBox.UR.x + job->pageBoundingBox.LL.x; + height = job->pageBoundingBox.UR.y + job->pageBoundingBox.LL.y; + if (truecolor_p) { if (job->common->verbose) fprintf(stderr, @@ -194,7 +195,7 @@ static void gdgen_begin_graph(GVJ_t * job) gdImageAlphaBlending(im, TRUE); } -static void gdgen_end_graph(GVJ_t * job) +static void gdgen_end_page(GVJ_t * job) { gdImagePtr im = (gdImagePtr) job->surface; @@ -316,7 +317,7 @@ static void gdgen_textpara(GVJ_t * job, pointf p, textpara_t * para) { gdImagePtr im = (gdImagePtr) job->surface; pointf mp, ep; - double parawidth = para->width * job->compscale.x; + double parawidth = para->width * job->scale.x; gdFTStringExtra strex; #if defined(HAVE_LIBFREETYPE) && defined(HAVE_GD_FREETYPE) char *err; @@ -327,7 +328,7 @@ static void gdgen_textpara(GVJ_t * job, pointf p, textpara_t * para) return; strex.flags = gdFTEX_RESOLUTION; - strex.hdpi = strex.vdpi = POINTS_PER_INCH * job->compscale.x; + strex.hdpi = strex.vdpi = POINTS_PER_INCH * job->scale.x; if (strstr(para->fontname, "/")) strex.flags |= gdFTEX_FONTPATHNAME; @@ -532,7 +533,7 @@ static void gdgen_polygon(GVJ_t * job, pointf * A, int n, int filled) pen = style->pencolor.u.index; } - width = style->penwidth * job->compscale.x; + width = style->penwidth * job->scale.x; if (width < PENWIDTH_NORMAL) width = PENWIDTH_NORMAL; /* gd can't do thin lines */ gdImageSetThickness(im, width); @@ -593,7 +594,7 @@ static void gdgen_ellipse(GVJ_t * job, pointf * A, int filled) pen = style->pencolor.u.index; } - width = style->penwidth * job->compscale.x; + width = style->penwidth * job->scale.x; if (width < PENWIDTH_NORMAL) width = PENWIDTH_NORMAL; /* gd can't do thin lines */ gdImageSetThickness(im, width); @@ -652,7 +653,7 @@ static void gdgen_polyline(GVJ_t * job, pointf * A, int n) } else { pen = style->pencolor.u.index; } - width = style->penwidth * job->compscale.x; + width = style->penwidth * job->scale.x; if (width < PENWIDTH_NORMAL) width = PENWIDTH_NORMAL; /* gd can't do thin lines */ gdImageSetThickness(im, width); @@ -741,12 +742,12 @@ gdgen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled) static gvrender_engine_t gdgen_engine = { 0, /* gdgen_begin_job */ 0, /* gdgen_end_job */ - gdgen_begin_graph, - gdgen_end_graph, + 0, /* gdgen_begin_graph */ + 0, /* gdgen_end_graph */ 0, /* gdgen_begin_layer */ 0, /* gdgen_end_layer */ - 0, /* gdgen_begin_page */ - 0, /* gdgen_end_page */ + gdgen_begin_page, + gdgen_end_page, 0, /* gdgen_begin_cluster */ 0, /* gdgen_end_cluster */ 0, /* gdgen_begin_nodes */ diff --git a/plugin/pango/gvrender_pango.c b/plugin/pango/gvrender_pango.c index a7e50ee85..eb1bf74b6 100644 --- a/plugin/pango/gvrender_pango.c +++ b/plugin/pango/gvrender_pango.c @@ -124,7 +124,7 @@ reader (void *closure, unsigned char *data, unsigned int length) return CAIRO_STATUS_READ_ERROR; } -static void cairogen_begin_graph(GVJ_t * job) +static void cairogen_begin_page(GVJ_t * job) { cairo_t *cr; cairo_surface_t *surface; @@ -142,8 +142,8 @@ static void cairogen_begin_graph(GVJ_t * job) cr = (cairo_t *) job->surface; /* might be NULL */ /* device size with margins all around */ - width = job->width + 2 * ROUND(job->margin.x * job->dpi.x / POINTS_PER_INCH); - height = job->height + 2 * ROUND(job->margin.y * job->dpi.y / POINTS_PER_INCH); + width = job->pageBoundingBox.UR.x + job->pageBoundingBox.LL.x; + height = job->pageBoundingBox.UR.y + job->pageBoundingBox.LL.y; switch (job->render.id) { #ifdef CAIRO_HAS_PNG_FUNCTIONS @@ -208,9 +208,13 @@ static void cairogen_begin_graph(GVJ_t * job) break; } job->surface = (void *) cr; + + cairo_scale(cr, job->scale.x, job->scale.y); + cairo_rotate(cr, job->rotation * M_PI / 180.); + cairo_translate(cr, job->translation.x, job->translation.y); } -static void cairogen_end_graph(GVJ_t * job) +static void cairogen_end_page(GVJ_t * job) { cairo_t *cr = (cairo_t *) job->surface; cairo_surface_t *surface; @@ -221,44 +225,6 @@ static void cairogen_end_graph(GVJ_t * job) surface = cairo_get_target(cr); cairo_surface_write_to_png_stream(surface, writer, job->output_file); #endif - default: - break; - } - if (!job->external_surface) - cairo_destroy(cr); - -#if defined HAVE_FENV_H && defined HAVE_FESETENV && defined HAVE_FEGETENV && defined(HAVE_FEENABLEEXCEPT) - /* Restore FP environment */ - fesetenv(&fenv); -#endif -} - -static void cairogen_begin_page(GVJ_t * job) -{ - cairo_t *cr = (cairo_t *) job->surface; - - cairo_save(cr); - cairo_scale(cr, job->zoom * job->dpi.x / POINTS_PER_INCH, - job->zoom * job->dpi.y / POINTS_PER_INCH); - if (job->rotation) { - cairo_rotate(cr, job->rotation * -M_PI / 180.); - cairo_translate(cr, - -job->margin.y / job->zoom - job->pageBox.UR.x, - job->margin.x / job->zoom + job->pageBox.UR.y); - } - else - cairo_translate(cr, - job->margin.x / job->zoom - job->pageBox.LL.x, - job->margin.y / job->zoom + job->pageBox.UR.y); -} - -static void cairogen_end_page(GVJ_t * job) -{ - cairo_t *cr = (cairo_t *) job->surface; - - cairo_restore(cr); - - switch (job->render.id) { #ifdef CAIRO_HAS_PS_SURFACE case FORMAT_PS: cairo_show_page(cr); @@ -277,6 +243,13 @@ static void cairogen_end_page(GVJ_t * job) default: break; } + if (!job->external_surface) + cairo_destroy(cr); + +#if defined HAVE_FENV_H && defined HAVE_FESETENV && defined HAVE_FEGETENV && defined(HAVE_FEENABLEEXCEPT) + /* Restore FP environment */ + fesetenv(&fenv); +#endif } static void cairogen_textpara(GVJ_t * job, pointf p, textpara_t * para) @@ -324,7 +297,7 @@ static void cairogen_ellipse(GVJ_t * job, pointf * A, int filled) } else { cairo_set_dash (cr, dashed, 0, 0.0); } - cairo_set_line_width (cr, style->penwidth * job->compscale.x); + cairo_set_line_width (cr, style->penwidth * job->scale.x); cairo_get_matrix(cr, &matrix); cairo_translate(cr, A[0].x, -A[0].y); @@ -360,7 +333,7 @@ cairogen_polygon(GVJ_t * job, pointf * A, int n, int filled) } else { cairo_set_dash (cr, dashed, 0, 0.0); } - cairo_set_line_width (cr, style->penwidth * job->compscale.x); + cairo_set_line_width (cr, style->penwidth * job->scale.x); cairo_move_to(cr, A[0].x, -A[0].y); for (i = 1; i < n; i++) cairo_line_to(cr, A[i].x, -A[i].y); @@ -388,7 +361,7 @@ cairogen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, } else { cairo_set_dash (cr, dashed, 0, 0.0); } - cairo_set_line_width (cr, style->penwidth * job->compscale.x); + cairo_set_line_width (cr, style->penwidth * job->scale.x); cairo_move_to(cr, A[0].x, -A[0].y); for (i = 1; i < n; i += 3) cairo_curve_to(cr, A[i].x, -A[i].y, A[i + 1].x, -A[i + 1].y, @@ -411,7 +384,7 @@ cairogen_polyline(GVJ_t * job, pointf * A, int n) } else { cairo_set_dash (cr, dashed, 0, 0.0); } - cairo_set_line_width (cr, style->penwidth * job->compscale.x); + cairo_set_line_width (cr, style->penwidth * job->scale.x); cairo_move_to(cr, A[0].x, -A[0].y); for (i = 1; i < n; i++) cairo_line_to(cr, A[i].x, -A[i].y); @@ -469,8 +442,8 @@ cairogen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled) static gvrender_engine_t cairogen_engine = { 0, /* cairogen_begin_job */ 0, /* cairogen_end_job */ - cairogen_begin_graph, - cairogen_end_graph, + 0, /* cairogen_begin_graph */ + 0, /* cairogen_end_graph */ 0, /* cairogen_begin_layer */ 0, /* cairogen_end_layer */ cairogen_begin_page, @@ -499,6 +472,7 @@ static gvrender_engine_t cairogen_engine = { static gvrender_features_t cairogen_features = { GVRENDER_DOES_TRUECOLOR + | GVRENDER_Y_GOES_DOWN | GVRENDER_DOES_TRANSFORM, /* flags */ 0, /* default margin - points */ {96.,96.}, /* default dpi */ @@ -510,6 +484,7 @@ static gvrender_features_t cairogen_features = { static gvrender_features_t cairogen_features_ps = { GVRENDER_DOES_TRUECOLOR + | GVRENDER_Y_GOES_DOWN | GVRENDER_DOES_TRANSFORM, /* flags */ 36, /* default margin - points */ {72.,72.}, /* postscript 72 dpi */ @@ -522,6 +497,7 @@ static gvrender_features_t cairogen_features_ps = { #if 0 static gvrender_features_t cairogen_features_x = { GVRENDER_DOES_TRUECOLOR + | GVRENDER_Y_GOES_DOWN | GVRENDER_DOES_TRANSFORM | GVRENDER_X11_EVENTS, /* flags */ 0, /* default margin - points */ @@ -534,6 +510,7 @@ static gvrender_features_t cairogen_features_x = { static gvrender_features_t cairogen_features_gtk = { GVRENDER_DOES_TRUECOLOR + | GVRENDER_Y_GOES_DOWN | GVRENDER_DOES_TRANSFORM | GVRENDER_X11_EVENTS, /* flags */ 0, /* default margin - points */