/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/common/picgen.c

Go to the documentation of this file.
00001 /* $Id: picgen.c,v 1.14 2006/12/07 22:49:36 erg Exp $ $Revision: 1.14 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 
00018 #include "render.h"
00019 
00020 #define PIC_COORDS_PER_LINE (16)        /* to avoid stdio BUF overflow */
00021 
00022 static box BB;
00023 static int BezierSubdivision = 10;
00024 static int Rot;
00025 static int onetime = TRUE;
00026 static double Scale;
00027 static double Fontscale;
00028 
00029 /* static char  **U_lib,*User,*Vers; */
00030 static const char *EscComment = ".\\\" ";       /* troff comment */
00031 
00032 typedef struct grcontext_t {
00033     char *color, *font;
00034     double size;
00035 } grcontext_t;
00036 
00037 #define STACKSIZE 8
00038 static grcontext_t S[STACKSIZE];
00039 static int SP = 0;
00040 
00041 static char picgen_msghdr[] = "dot picgen: ";
00042 static void unsupported(char *s)
00043 {
00044     agerr(AGWARN, "%s%s unsupported\n", picgen_msghdr, s);
00045 }
00046 static void warn(char *s)
00047 {
00048     agerr(AGWARN, "%s%s\n", picgen_msghdr, s);
00049 }
00050 
00051 #undef  MAX
00052 #ifndef MAX
00053 # define        MAX(a,b)        (((a)>(b))? (a) : (b))
00054 #endif
00055 #undef  MIN
00056 #ifndef MIN
00057 # define        MIN(a,b)        (((a)<(b))? (a) : (b))
00058 #endif
00059 
00060 /* There are a couple of ways to generate output: 
00061     1. generate for whatever size is given by the bounding box
00062        - the drawing at its "natural" size might not fit on a physical page
00063          ~ dot size specification can be used to scale the drawing
00064          ~ and it's not difficult for user to scale the pic output to fit (multiply 4 (3 distinct) numbers on 3 lines by a scale factor)
00065        - some troff implementations may clip large graphs
00066          ~ handle by scaling to manageable size
00067        - give explicit width and height as parameters to .PS
00068        - pic scale variable is reset to 1.0
00069        - fonts are printed as size specified by caller, modified by user scaling
00070     2. scale to fit on a physical page
00071        - requires an assumption of page size (GNU pic assumes 8.5x11.0 inches)
00072          ~ any assumption is bound to be wrong more often than right
00073        - requires separate scaling of font point sizes since pic's scale variable doesn't affect text
00074          ~ possible, as above
00075        - likewise for line thickness
00076        - GNU pic does this (except for fonts) if .PS is used without explicit width or height; DWB pic does not
00077          ~ pic variants likely to cause trouble
00078   The first approach is used here.
00079 */
00080 
00081 /* troff font mapping */
00082 typedef struct {
00083     char trname[3], *psname;
00084 } fontinfo;
00085 
00086 static fontinfo fonttab[] = {
00087     {"AB", "AvantGarde-Demi"},
00088     {"AI", "AvantGarde-BookOblique"},
00089     {"AR", "AvantGarde-Book"},
00090     {"AX", "AvantGarde-DemiOblique"},
00091     {"B ", "Times-Bold"},
00092     {"BI", "Times-BoldItalic"},
00093     {"CB", "Courier-Bold"},
00094     {"CO", "Courier"},
00095     {"CX", "Courier-BoldOblique"},
00096     {"H ", "Helvetica"},
00097     {"HB", "Helvetica-Bold"},
00098     {"HI", "Helvetica-Oblique"},
00099     {"HX", "Helvetica-BoldOblique"},
00100     {"Hb", "Helvetica-Narrow-Bold"},
00101     {"Hi", "Helvetica-Narrow-Oblique"},
00102     {"Hr", "Helvetica-Narrow"},
00103     {"Hx", "Helvetica-Narrow-BoldOblique"},
00104     {"I ", "Times-Italic"},
00105     {"KB", "Bookman-Demi"},
00106     {"KI", "Bookman-LightItalic"},
00107     {"KR", "Bookman-Light"},
00108     {"KX", "Bookman-DemiItalic"},
00109     {"NB", "NewCenturySchlbk-Bold"},
00110     {"NI", "NewCenturySchlbk-Italic"},
00111     {"NR", "NewCenturySchlbk-Roman"},
00112     {"NX", "NewCenturySchlbk-BoldItalic"},
00113     {"PA", "Palatino-Roman"},
00114     {"PB", "Palatino-Bold"},
00115     {"PI", "Palatino-Italic"},
00116     {"PX", "Palatino-BoldItalic"},
00117     {"R ", "Times-Roman"},
00118     {"S ", "Symbol"},
00119     {"ZD", "ZapfDingbats"},
00120     {"\000\000", (char *) 0}
00121 };
00122 
00123 static char *picfontname(char *psname)
00124 {
00125     char *rv;
00126     fontinfo *p;
00127 
00128     for (p = fonttab; p->psname; p++)
00129         if (streq(p->psname, psname))
00130             break;
00131     if (p->psname)
00132         rv = p->trname;
00133     else {
00134         agerr(AGERR, "%s%s is not a troff font\n", picgen_msghdr, psname);
00135         /* try base font names, e.g. Helvetica-Outline-Oblique -> Helvetica-Outline -> Helvetica */
00136         if ((rv = strrchr(psname, '-'))) {
00137             *rv = '\0';         /* psname is not specified as const ... */
00138             rv = picfontname(psname);
00139         } else
00140             rv = "R";
00141     }
00142     return rv;
00143 }
00144 
00145 static char *pic_fcoord(char *buf, pointf pf)
00146 {
00147     sprintf(buf, "(%.5f,%.5f)", Scale * pf.x, Scale * pf.y);
00148     return buf;
00149 }
00150 
00151 static char *pic_coord(char *buf, point p)
00152 {
00153     return pic_fcoord(buf, cvt2ptf(p));
00154 }
00155 
00156 static void pic_reset(void)
00157 {
00158     onetime = TRUE;
00159 }
00160 
00161 static void pic_begin_job(FILE * ofp, graph_t * g, char **lib, char *user,
00162                           char *info[], point pages)
00163 {
00164     /* U_lib = lib; */
00165     if (onetime && (pages.x * pages.y > 1)) {
00166         unsupported("pagination");
00167         onetime = FALSE;
00168     }
00169     fprintf(Output_file, "%s Creator: %s version %s (%s)\n",
00170             EscComment, info[0], info[1], info[2]);
00171     fprintf(Output_file, "%s For: %s\n", EscComment, user);
00172     fprintf(Output_file, "%s Title: %s\n", EscComment, g->name);
00173 }
00174 
00175 static void pic_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb)
00176 {
00177     BB = bb;
00178 
00179     fprintf(Output_file,
00180             "%s save point size and font\n.nr .S \\n(.s\n.nr DF \\n(.f\n",
00181             EscComment);
00182 }
00183 
00184 static void pic_end_graph(void)
00185 {
00186     fprintf(Output_file,
00187             "%s restore point size and font\n.ps \\n(.S\n.ft \\n(DF\n",
00188             EscComment);
00189 }
00190 
00191 static void pic_begin_page(graph_t * g, point page, double scale, int rot,
00192                            point offset)
00193 {
00194     double height, width;
00195 
00196     if (onetime && rot && (rot != 90)) {
00197         unsupported("rotation");
00198         onetime = FALSE;
00199     }
00200     Rot = rot;
00201     height = PS2INCH((double) (BB.UR.y) - (double) (BB.LL.y));
00202     width = PS2INCH((double) (BB.UR.x) - (double) (BB.LL.x));
00203     Scale = scale;
00204     if (Rot == 90) {
00205         double temp = width;
00206         width = height;
00207         height = temp;
00208     }
00209     fprintf(Output_file, ".PS %.5f %.5f\n", width, height);
00210     EscComment = "#";           /* pic comment */
00211     fprintf(Output_file,
00212             "%s to change drawing size, multiply the width and height on the .PS line above and the number on the two lines below (rounded to the nearest integer) by a scale factor\n",
00213             EscComment);
00214     if (width > 0.0) {
00215         Fontscale = log10(width);
00216         Fontscale += 3.0 - (int) Fontscale;     /* between 3.0 and 4.0 */
00217     } else
00218         Fontscale = 3.0;
00219     Fontscale = pow(10.0, Fontscale);   /* a power of 10 times width, between 1000 and 10000 */
00220     fprintf(Output_file, ".nr SF %.0f\nscalethickness = %.0f\n", Fontscale,
00221             Fontscale);
00222     fprintf(Output_file,
00223             "%s don't change anything below this line in this drawing\n",
00224             EscComment);
00225     fprintf(Output_file,
00226             "%s non-fatal run-time pic version determination, version 2\n",
00227             EscComment);
00228     fprintf(Output_file,
00229             "boxrad=2.0 %s will be reset to 0.0 by gpic only\n",
00230             EscComment);
00231     fprintf(Output_file, "scale=1.0 %s required for comparisons\n",
00232             EscComment);
00233     fprintf(Output_file,
00234             "%s boxrad is now 0.0 in gpic, else it remains 2.0\n",
00235             EscComment);
00236     fprintf(Output_file,
00237             "%s dashwid is 0.1 in 10th Edition, 0.05 in DWB 2 and in gpic\n",
00238             EscComment);
00239     fprintf(Output_file,
00240             "%s fillval is 0.3 in 10th Edition (fill 0 means black), 0.5 in gpic (fill 0 means white), undefined in DWB 2\n",
00241             EscComment);
00242     fprintf(Output_file,
00243             "%s fill has no meaning in DWB 2, gpic can use fill or filled, 10th Edition uses fill only\n",
00244             EscComment);
00245     fprintf(Output_file,
00246             "%s DWB 2 doesn't use fill and doesn't define fillval\n",
00247             EscComment);
00248     fprintf(Output_file,
00249             "%s reset works in gpic and 10th edition, but isn't defined in DWB 2\n",
00250             EscComment);
00251     fprintf(Output_file, "%s DWB 2 compatibility definitions\n",
00252             EscComment);
00253     fprintf(Output_file,
00254             "if boxrad > 1.0 && dashwid < 0.075 then X\n\tfillval = 1;\n\tdefine fill Y Y;\n\tdefine solid Y Y;\n\tdefine reset Y scale=1.0 Y;\nX\n");
00255     fprintf(Output_file, "reset %s set to known state\n", EscComment);
00256     fprintf(Output_file, "%s GNU pic vs. 10th Edition d\\(e'tente\n",
00257             EscComment);
00258     fprintf(Output_file,
00259             "if fillval > 0.4 then X\n\tdefine setfillval Y fillval = 1 - Y;\n\tdefine bold Y thickness 2 Y;\n");
00260     fprintf(Output_file,
00261             "\t%s if you use gpic and it barfs on encountering \"solid\",\n",
00262             EscComment);
00263     fprintf(Output_file,
00264             "\t%s\tinstall a more recent version of gpic or switch to DWB or 10th Edition pic;\n",
00265             EscComment);
00266     fprintf(Output_file,
00267             "\t%s\tsorry, the groff folks changed gpic; send any complaint to them;\n",
00268             EscComment);
00269     fprintf(Output_file,
00270             "X else Z\n\tdefine setfillval Y fillval = Y;\n\tdefine bold Y Y;\n\tdefine filled Y fill Y;\nZ\n");
00271     fprintf(Output_file,
00272             "%s arrowhead has no meaning in DWB 2, arrowhead = 7 makes filled arrowheads in gpic and in 10th Edition\n",
00273             EscComment);
00274     fprintf(Output_file,
00275             "%s arrowhead is undefined in DWB 2, initially 1 in gpic, 2 in 10th Edition\n",
00276             EscComment);
00277     fprintf(Output_file, "arrowhead = 7 %s not used by graphviz\n",
00278             EscComment);
00279     fprintf(Output_file,
00280             "%s GNU pic supports a boxrad variable to draw boxes with rounded corners; DWB and 10th Ed. do not\n",
00281             EscComment);
00282     fprintf(Output_file, "boxrad = 0 %s no rounded corners in graphviz\n",
00283             EscComment);
00284     fprintf(Output_file,
00285             "%s GNU pic supports a linethick variable to set line thickness; DWB and 10th Ed. do not\n",
00286             EscComment);
00287     fprintf(Output_file, "linethick = 0; oldlinethick = linethick\n");
00288     fprintf(Output_file,
00289             "%s .PS w/o args causes GNU pic to scale drawing to fit 8.5x11 paper; DWB does not\n",
00290             EscComment);
00291     fprintf(Output_file,
00292             "%s maxpsht and maxpswid have no meaning in DWB 2.0, set page boundaries in gpic and in 10th Edition\n",
00293             EscComment);
00294     fprintf(Output_file,
00295             "%s maxpsht and maxpswid are predefined to 11.0 and 8.5 in gpic\n",
00296             EscComment);
00297     fprintf(Output_file, "maxpsht = %f\nmaxpswid = %f\n", height, width);
00298     fprintf(Output_file, "Dot: [\n");
00299     fprintf(Output_file,
00300             "define attrs0 %% %%; define unfilled %% %%; define rounded %% %%; define diagonals %% %%\n");
00301 }
00302 
00303 static void pic_end_page(void)
00304 {
00305     fprintf(Output_file, "]\n.PE\n");
00306     EscComment = ".\\\" ";      /* troff comment */
00307     assert(SP == 0);
00308 }
00309 
00310 static void pic_begin_node(node_t * n)
00311 {
00312     fprintf(Output_file, "%s\t%s\n", EscComment, n->name);
00313 }
00314 
00315 static void pic_begin_edge(edge_t * e)
00316 {
00317     fprintf(Output_file, "%s\t%s -> %s\n", EscComment, e->tail->name,
00318             e->head->name);
00319 }
00320 
00321 static void pic_begin_context(void)
00322 {
00323     fprintf(Output_file, "{\n");
00324     if (SP == STACKSIZE - 1)
00325         warn("stk ovfl");
00326     else {
00327         SP++;
00328         S[SP] = S[SP - 1];
00329         fprintf(Output_file, "define attrs%d %% %%\n", SP);     /* ensure plain (no attributes) style at start of context */
00330     }
00331 }
00332 
00333 static void pic_end_context(void)
00334 {
00335     if (SP == 0)
00336         warn("stk undfl");
00337     else {
00338         SP--;
00339         fprintf(Output_file, "}\n");    /* end context group */
00340         /* restore correct font and size for context */
00341         if (S[SP + 1].font
00342             && (!(S[SP].font) || strcmp(S[SP + 1].font, S[SP].font)))
00343             fprintf(Output_file, ".ft %s\n", picfontname(S[SP].font));
00344         if (S[SP + 1].size != S[SP].size) {
00345             int sz;
00346 
00347             if ((sz = (int) (S[SP].size * Scale)) < 1)
00348                 sz = 1;
00349             fprintf(Output_file, ".ps %d*\\n(SFu/%.0fu\n", sz, Fontscale);
00350         }
00351         fprintf(Output_file, "linethick = oldlinethick\n");
00352     }
00353 }
00354 
00355 static void pic_set_font(char *name, double size)
00356 {
00357     if (name && (!(S[SP].font) || strcmp(S[SP].font, name))) {
00358         S[SP].font = name;
00359         fprintf(Output_file, ".ft %s\n", picfontname(name));
00360     }
00361     if (size != S[SP].size) {
00362         int sz;
00363 
00364         S[SP].size = size;
00365         if ((sz = (int) (size * Scale)) < 1)
00366             sz = 1;
00367         fprintf(Output_file, ".ps %d*\\n(SFu/%.0fu\n", sz, Fontscale);
00368     }
00369 }
00370 
00371 static char *pic_string(char *s)
00372 {
00373     static char *buf = NULL;
00374     static int bufsize = 0;
00375     int pos = 0;
00376     char *p;
00377 
00378     if (!buf) {
00379         bufsize = 64;
00380         buf = N_GNEW(bufsize, char);
00381     }
00382 
00383     p = buf;
00384     while (*s) {
00385         if (pos > (bufsize - 8)) {
00386             bufsize *= 2;
00387             buf = grealloc(buf, bufsize);
00388             p = buf + pos;
00389         }
00390         if (*s == '\015') {     /* GACK, PTUI! Fire up the teletype, boys;
00391                                    somebody's sending an old-fashioned mechanical
00392                                    "carriage return" control character. */
00393             s++;
00394             continue;
00395         }
00396         if (*s == '\\') {
00397             strcpy(p, "\\(rs"); /* e.g. man 5 groff_char from mkssoftware.com */
00398             p += 4;
00399             pos += 4;
00400             s++;
00401             continue;
00402         }
00403         *p++ = *s++;
00404         pos++;
00405     }
00406     *p = '\0';
00407     return buf;
00408 }
00409 
00410 static void pic_textpara(point p, textpara_t * para)
00411 {
00412     pointf pf;
00413     short flag = 0;
00414     double fontsz = S[SP].size;
00415 
00416     switch (para->just) {
00417     case 'l':
00418         p.x = p.x;
00419         break;
00420     case 'r':
00421         p.x = p.x - para->width;
00422         break;
00423     default:
00424     case 'n':
00425         p.x = p.x - para->width / 2;
00426         break;
00427     }
00428     pf = cvt2ptf(p);
00429 #ifdef NOTDEF
00430     /* Why on earth would we want this? SCN  11/29/2001 */
00431     pf.y -= fontsz / (5.0 * POINTS_PER_INCH);
00432 #endif
00433     /* Why on earth would we do this either. But it works. SCN 2/26/2002 */
00434     pf.y += fontsz / (3.0 * POINTS_PER_INCH);
00435     pf.x += para->width / (2.0 * POINTS_PER_INCH);
00436     if (!(S[SP].size)) {        /* size was never set in this or hierarchically higher context */
00437         pic_set_font(S[SP].font, fontsz);       /* primarily to output font and/or size directives */
00438         for (flag = SP; ((S[flag].size = fontsz), flag); flag--)        /* set size in contexts */
00439             ;                   /* flag is zero again at loop termination */
00440     }
00441     if (fontsz != S[SP].size) { /* size already set in context,
00442                                    but different from request; start new context */
00443         flag = 1;
00444         pic_begin_context();
00445         pic_set_font(S[SP - 1].font, fontsz);
00446     }
00447     fprintf(Output_file, "\"%s\" at (%.5f,%.5f);\n",
00448             pic_string(para->str), Scale * pf.x, Scale * pf.y);
00449     if (flag)
00450         pic_end_context();
00451 }
00452 
00453 static void pic_set_color(char *name)
00454 {
00455     gvcolor_t color;
00456 
00457     S[SP].color = name;
00458     colorxlate(name, &color, HSVA_DOUBLE);
00459     /* just v used to set grayscale value */
00460     fprintf(Output_file, "setfillval %f\n", color.u.HSVA[2]);
00461 }
00462 
00463 static void pic_set_style(char **s)
00464 {
00465     const char *line, *p;
00466     char skip = 0;
00467     char buf[BUFSIZ];
00468 
00469     buf[0] = '\0';
00470     fprintf(Output_file, "define attrs%d %%", SP);
00471     while ((p = line = *s++)) {
00472         while (*p)
00473             p++;
00474         p++;
00475         while (*p) {
00476             if (!strcmp(line, "setlinewidth")) {        /* a hack to handle the user-defined (PS) style spec in proc3d.dot */
00477                 long n = atol(p);
00478 
00479                 sprintf(buf,
00480                         "oldlinethick = linethick;linethick = %ld * scalethickness / %.0f\n",
00481                         n, Fontscale / Scale);
00482                 skip = 1;
00483             } else
00484                 fprintf(Output_file, " %s", p);
00485             while (*p)
00486                 p++;
00487             p++;
00488         }
00489         if (!skip)
00490             fprintf(Output_file, " %s", line);
00491         skip = 0;
00492     }
00493     fprintf(Output_file, " %%\n");
00494     fprintf(Output_file, "%s", buf);
00495 }
00496 
00497 static void pic_ellipse(point p, int rx, int ry, int filled)
00498 {
00499     pointf pf;
00500 
00501     pf = cvt2ptf(p);
00502     fprintf(Output_file,
00503             "ellipse attrs%d %swid %.5f ht %.5f at (%.5f,%.5f);\n", SP,
00504             filled ? "fill " : "", Scale * PS2INCH(2 * rx),
00505             Scale * PS2INCH(2 * ry), Scale * pf.x, Scale * pf.y);
00506 }
00507 
00508 static void point_list_out(point * A, int n, int close)
00509 {
00510     int j;
00511     char buf[SMALLBUF];
00512 
00513     for (j = 0; j < n; j++)
00514         fprintf(Output_file, "P%d: %s\n", j, pic_coord(buf, A[j]));
00515     for (j = 0; j + 1 < n; j++)
00516         fprintf(Output_file, "move to P%d; line attrs%d to P%d\n", j, SP,
00517                 j + 1);
00518     if (close)
00519         fprintf(Output_file, "move to P%d; line attrs%d to P0\n", n - 1,
00520                 SP);
00521 }
00522 
00523 static void pic_polygon(point * A, int n, int filled)
00524 {
00525     /* test for special case: rectangle oriented with page */
00526     if ((n == 4) && (((A[0].x == A[1].x) && (A[0].y == A[3].y)
00527                       && (A[1].y == A[2].y) && (A[2].x == A[3].x))
00528                      || ((A[0].y == A[1].y) && (A[0].x == A[3].x)
00529                          && (A[1].x == A[2].x) && (A[2].y == A[3].y))
00530         )) {
00531         pointf pf1, pf2;
00532 
00533         pf1 = cvt2ptf(A[0]);    /* opposite */
00534         pf2 = cvt2ptf(A[2]);    /* corners  */
00535         if (filled) {
00536             gvcolor_t color;
00537 
00538             colorxlate(S[SP].color, &color, HSVA_DOUBLE);
00539             fprintf(Output_file, "setfillval %f\n", color.u.HSVA[2]);
00540         }
00541         fprintf(Output_file, "box attrs%d %swid %.5f ht %.5f at (%.5f,%.5f);\n", SP, filled ? "fill " : "", Scale * fabs(pf1.x - pf2.x), Scale * fabs(pf1.y - pf2.y),   /* width, height */
00542                 Scale * (pf1.x + pf2.x) / 2.0, Scale * (pf1.y + pf2.y) / 2.0);  /* center coordinates */
00543         return;
00544     }
00545     if (onetime && filled) {
00546         unsupported("shape fill");
00547         onetime = FALSE;
00548     }
00549     point_list_out(A, n, TRUE);
00550 }
00551 
00552 static void pic_polyline(point * A, int n)
00553 {
00554     point_list_out(A, n, FALSE);
00555 }
00556 
00557 static void pic_usershape(usershape_t *us, boxf b, point *A, int n, boolean filled)
00558 {
00559 /* FIXME */
00560     /* it's not at all clear what xxx_user_shape is supposed to do; in most xxxgen.c files it emits a message */
00561     /* this defines the shape as a macro and then invokes the macro */
00562     fprintf(Output_file, "define %s {\n", us->name);
00563     fprintf(Output_file, "}\n%s\n", us->name);
00564 }
00565 
00566 static void pic_bezier(point * A, int n, int arrow_at_start,
00567                        int arrow_at_end, int filled)
00568 {
00569     pointf V[4], p;
00570     int i, j, m, step;
00571     char buf[SMALLBUF];
00572 
00573     if (arrow_at_start || arrow_at_end)
00574         warn("not supposed to be making arrows here!");
00575     V[3] = cvt2ptf(A[0]);       /* initial cond */
00576     for (i = m = 0; i + 3 < n; i += 3) {
00577         V[0] = V[3];
00578         for (j = 1; j <= 3; j++)
00579             V[j] = cvt2ptf(A[i + j]);
00580         p = Bezier(V, 3, 0.0, NULL, NULL);
00581         if (!i)
00582             fprintf(Output_file, "P0: %s\n", pic_fcoord(buf, p));
00583         for (step = 1; step <= BezierSubdivision; step++) {
00584             p = Bezier(V, 3, (double) step / BezierSubdivision, NULL,
00585                        NULL);
00586             ++m;
00587             fprintf(Output_file, "P%d: %s\n", m, pic_fcoord(buf, p));
00588         }
00589     }
00590     for (i = 0; i + 2 <= m; i += 2)     /* DWB 2 pic suffers from severe roundoff errors if too many steps are plotted at once */
00591         fprintf(Output_file, "move to P%d; line attrs%d to P%d then to P%d\n", i, SP, i + 1, i + 2);    /* use line, as splines can't be dotted or dashed */
00592 }
00593 
00594 static void pic_comment(char *str)
00595 {
00596     fprintf(Output_file, "'\\\" %s\n", str);
00597 }
00598 
00599 codegen_t PIC_CodeGen = {
00600     pic_reset,
00601     pic_begin_job, 0,           /* pic_end_job */
00602     pic_begin_graph, pic_end_graph,
00603     pic_begin_page, pic_end_page,
00604     0, /* pic_begin_layer */ 0, /* pic_end_layer */
00605     0, /* pic_begin_cluster */ 0,       /* pic_end_cluster */
00606     0, /* pic_begin_nodes */ 0, /* pic_end_nodes */
00607     0, /* pic_begin_edges */ 0, /* pic_end_edges */
00608     pic_begin_node, 0,          /* pic_end_node */
00609     pic_begin_edge, 0,          /* pic_end_edge */
00610     pic_begin_context, pic_end_context,
00611     0, /* pic_begin_anchor */ 0,        /* pic_end_anchor */
00612     pic_set_font, pic_textpara,
00613     pic_set_color, pic_set_color, pic_set_style,
00614     pic_ellipse, pic_polygon,
00615     pic_bezier, pic_polyline,
00616     0,                          /* bezier_has_arrows */
00617     pic_comment,
00618     pic_usershape
00619 };

Generated on Mon Mar 31 19:03:24 2008 for Graphviz by  doxygen 1.5.1