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

Go to the documentation of this file.
00001 /* $Id: hpglgen.c,v 1.16 2006/12/07 22:49:35 erg Exp $ $Revision: 1.16 $ */
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 /* TODO:
00019  *  Use encoded form for polyline and polygon
00020  */
00021 #include <ctype.h>
00022 #include "render.h"
00023 
00024 #define SOLID  0
00025 #define DOTTED 1
00026 #define DASHED 2
00027 #define INVIS  3
00028   /* Convert point (1/72 inch) to hpgl units (0.025 mm) */
00029 #define PT2UNIT(p)  ((p)*(double)14.111)
00030 #define PENW 0.0138
00031 #define NPENS  32
00032 #define CX(_x)   ((int)(_x))
00033 #define CY(_y)   ((int)(_y))
00034 
00035     /* Origin of HP plotter from lower left corner, in points
00036      * This varies from plotter to plotter. We assume 1/4" and 
00037      * hope for the best.
00038      */
00039 #define HP_OX     18
00040 #define HP_OY     18
00041 
00042 static char *raw_prefix = "";
00043 static char *raw_suffix = "";
00044 #ifdef NOTUSED_ERG_MUST_KNOW_WHY
00045 static char *clr_prefix = "\033%-12345X@PJL ENTER LANGUAGE = HPGL2\n";
00046 static char *clr_suffix = "\033%-12345X\n";
00047 #endif
00048 static char *pcl_prefix = "\033E\n\033%%0B\n";
00049 static char *pcl_suffix = "\033%%0A\n";
00050 
00051 static int N_pages;
00052 /* static       point   Pages; */
00053 static double Scale;
00054 static point Origin;
00055 static box PB;
00056 static int CurrentPen;
00057 static int ColorsUsed;
00058 static char *Sep = ";";
00059 static int PageWidth;           /* Width of page, in points. */
00060 static char *prefix;            /* Machine-dependent prefix and suffix */
00061 static char *suffix;
00062 /* static boolean       onetime = TRUE; */
00063 
00064 #define MAXLINELEN   80
00065 static int bufcnt;              /* Number of characters output on current line */
00066 static char *text_hdr = "LB";
00067 static void output(char *str)
00068 {
00069     char *ptr = str;
00070     int len;
00071 
00072     while (*ptr != '\0')
00073         ptr++;
00074     len = ptr - str;
00075     if (bufcnt + len > MAXLINELEN) {
00076         fputs("\n", Output_file);
00077         bufcnt = 0;
00078     }
00079     fputs(str, Output_file);
00080     if ((len > 0) && (*(ptr - 1) == '\n'))
00081         bufcnt = 0;
00082     else
00083         bufcnt += len;
00084 }
00085 
00086 static void output_text(char *str)
00087 {
00088     char *ptr = str;
00089     int len;
00090     char text_tail[32];
00091 
00092     sprintf(text_tail, "\03%s\n", Sep);
00093     while (*ptr != '\0')
00094         ptr++;
00095     len = (ptr - str) + strlen(text_tail) + strlen(text_hdr);
00096     if (bufcnt + len > MAXLINELEN) {
00097         fputs("\n", Output_file);
00098     }
00099     fputs(text_hdr, Output_file);
00100     fputs(str, Output_file);
00101     fputs(text_tail, Output_file);
00102     bufcnt = 0;
00103 }
00104 
00105 #ifdef SMILE
00106 void doSmile(void)
00107 {
00108     fprintf(Output_file,
00109             "SP1SD1,341,2,1,4,14,5,0,6,0,7,5SSLO7PA%d,0LB\001\003IN\n",
00110             (int) PT2UNIT(PageWid - 2 * HP_OX));
00111 
00112 }
00113 #endif
00114 
00115 static void setPen(int p)
00116 {
00117     char buffer[32];
00118     sprintf(buffer, "SP%d%s", p, Sep);
00119     output(buffer);
00120 #ifdef HPDEBUG
00121     fprintf(stderr, "set pen %d\n", p);
00122 #endif
00123     CurrentPen = p;
00124 }
00125 
00126 typedef struct {
00127     int symbol;
00128     int spacing;
00129     int face;
00130     int bold;
00131     int italic;
00132     double size;
00133 } FontInfo;
00134 static FontInfo dfltFont = { 277, 1, 5, 0, 0, 14.0 };
00135 static FontInfo coordFont = { 277, 1, 5, 0, 0, 8.0 };
00136 static FontInfo nullFont = { 0, 0, 0, 0, 0, 0.0 };
00137 
00138   /* Font 0 is the stdfont; font 1 is the alt font */
00139 typedef struct {
00140     FontInfo fonts[2];
00141     int curfont;
00142 } FontState;
00143 static FontState fontState;
00144 
00145 static int eqFontInfo(FontInfo * fi1, FontInfo * fi2)
00146 {
00147     return ((fi1->face == fi2->face) &&
00148             (fi1->spacing == fi2->spacing) &&
00149             (fi1->bold == fi2->bold) &&
00150             (fi1->italic == fi2->italic) &&
00151             (fi1->size == fi2->size) && (fi1->symbol == fi2->symbol));
00152 }
00153 
00154 typedef struct {
00155     unsigned char r, g, b;
00156 } Color;
00157 
00158 static int eqColor(Color * c1, Color * c2)
00159 {
00160     return ((c1->r == c2->r) && (c1->g == c2->g) && (c1->b == c2->b));
00161 }
00162 
00163 static Color black = { 0, 0, 0 };
00164 static Color white = { 255, 255, 255 };
00165 static Color *colorlist;
00166 
00167 typedef struct GC_s {
00168     int bold;
00169     int style;
00170     Color color;
00171     FontInfo font;
00172     struct GC_s *prev;
00173 } GC_t;
00174 static GC_t *curGC;
00175 
00176 static void set_color(Color * cp)
00177 {
00178     int i;
00179     char buffer[32];
00180 
00181     if (eqColor(cp, &curGC->color))
00182         return;
00183     for (i = 0; i < ColorsUsed; i++) {
00184         if (eqColor(cp, &colorlist[i]))
00185             break;
00186     }
00187     if (i == ColorsUsed) {
00188         if (ColorsUsed == NPENS)
00189             i--;
00190         else
00191             ColorsUsed++;
00192         sprintf(buffer, "PC%d,%d,%d,%d%s", i, cp->r, cp->g, cp->b, Sep);
00193         colorlist[i] = *cp;
00194         output(buffer);
00195 #ifdef HPDEBUG
00196         fprintf(stderr, "set pen %d color %d %d %d\n", i, cp->r, cp->g,
00197                 cp->b);
00198 #endif
00199     }
00200     setPen(i);
00201     curGC->color = *cp;
00202 }
00203 
00204 static void initColors(void)
00205 {
00206     colorlist = N_GNEW(NPENS, Color);
00207     colorlist[0] = white;
00208     colorlist[1] = black;
00209     ColorsUsed = 2;
00210 }
00211 
00212 static void destroyColors(void)
00213 {
00214     free(colorlist);
00215     ColorsUsed = 0;
00216 }
00217 
00218 static void setFont(FontInfo * fi)
00219 {
00220     int otherfont;
00221     char buffer[128];
00222 
00223     if (eqFontInfo(fi, &fontState.fonts[fontState.curfont]))
00224         return;
00225     otherfont = (fontState.curfont ? 0 : 1);
00226 
00227     if (!eqFontInfo(fi, &fontState.fonts[otherfont])) {
00228         if (fi->spacing)
00229             sprintf(buffer, "%s1,%d,2,1,4,%.1f,5,%d,6,%d,7,%d%s",
00230                     (otherfont ? "AD" : "SD"), fi->symbol,
00231                     Scale * (fi->size), fi->italic, fi->bold, fi->face,
00232                     Sep);
00233         else
00234             sprintf(buffer, "%s1,%d,2,0,3,%.1f,5,%d,6,%d,7,%d%s",
00235                     (otherfont ? "AD" : "SD"), fi->symbol,
00236                     (fi->size) / Scale, fi->italic, fi->bold, fi->face,
00237                     Sep);
00238         output(buffer);
00239     }
00240     sprintf(buffer, "%s%s\n", (otherfont ? "SA" : "SS"), Sep);
00241     output(buffer);
00242     fontState.curfont = otherfont;
00243     fontState.fonts[otherfont] = *fi;
00244     curGC->font = *fi;
00245 }
00246 
00247 static void set_line_bold(int on)
00248 {
00249     char buffer[32];
00250 
00251     if (on) {
00252         sprintf(buffer, "PW%.3f%s\n", 2 * PENW, Sep);
00253         curGC->bold = TRUE;
00254     } else {
00255         sprintf(buffer, "PW%.3f%s\n", PENW, Sep);
00256         curGC->bold = FALSE;
00257     }
00258     output(buffer);
00259 }
00260 
00261 static void set_line_style(int sty)
00262 {
00263     char buffer[8];
00264     char *opt = NULL;
00265 
00266     curGC->style = sty;
00267     switch (sty) {
00268     case SOLID:
00269         opt = "LT";
00270         break;
00271     case DOTTED:
00272         opt = "LT1";
00273         break;
00274     case DASHED:
00275         opt = "LT2";
00276         break;
00277     case INVIS:
00278     default:
00279         return;
00280     }
00281     sprintf(buffer, "%s%s", opt, Sep);
00282     output(buffer);
00283 }
00284 
00285 static GC_t *makeGC(GC_t * old)
00286 {
00287     GC_t *newGC;
00288     newGC = GNEW(GC_t);
00289     if (old)
00290         *newGC = *old;
00291     else {
00292         newGC->bold = FALSE, newGC->style = SOLID, newGC->color = black;
00293         newGC->font = dfltFont;
00294     }
00295     newGC->prev = 0;
00296     return newGC;
00297 }
00298 
00299 static void initGC(void)
00300 {
00301     char buffer[32];
00302 
00303     curGC = makeGC(0);
00304     /* Pick pen 1; set default pen width; set colors
00305      */
00306     sprintf(buffer, "SP1%sPW%.3f%s\n", Sep, PENW, Sep);
00307     output(buffer);
00308     fontState.curfont = 1;
00309     setFont(&dfltFont);
00310     CurrentPen = 1;
00311     initColors();
00312 }
00313 
00314 static void destroyGC(void)
00315 {
00316     GC_t *gc, *gc1;
00317     for (gc = curGC; gc; gc = gc1) {
00318         gc1 = gc->prev;
00319         free(gc);
00320     }
00321     curGC = 0;
00322     fontState.fonts[0] = nullFont;
00323     fontState.fonts[1] = nullFont;
00324     fontState.curfont = 1;
00325     destroyColors();
00326 }
00327 
00328 static void saveGC(void)
00329 {
00330     GC_t *newGC;
00331     newGC = makeGC(curGC);
00332     newGC->prev = curGC;
00333     curGC = newGC;
00334 }
00335 
00336 static void restoreGC(void)
00337 {
00338     GC_t *gc, *newGC;
00339     gc = curGC;
00340     newGC = gc->prev;
00341     if (gc->bold != newGC->bold)
00342         set_line_bold(newGC->bold);
00343     if (gc->style != newGC->style)
00344         set_line_style(newGC->style);
00345     if (!eqColor(&gc->color, &newGC->color)) {
00346 #ifdef HPDEBUG
00347         fprintf(stderr, "restore color\n");
00348 #endif
00349         set_color(&newGC->color);
00350     }
00351     if (!eqFontInfo(&gc->font, &newGC->font))
00352         setFont(&newGC->font);
00353     free(gc);
00354     curGC = newGC;
00355 }
00356 
00357 static int isInvis(void)
00358 {
00359     return (curGC->style == INVIS);
00360 }
00361 
00362 #if 0                           /* not used */
00363 static double _Xalign;
00364 #define getTextAlign() (_Xalign)
00365 static void initTextAlign(void)
00366 {
00367     char buffer[20];
00368     _Xalign = -0.5;
00369     sprintf(buffer, "LO4%s", Sep);
00370     output(buffer);
00371 }
00372 
00373 static int setTextAlign(double al)
00374 {
00375     char buffer[20];
00376     char opt;
00377 
00378     if (al == 0.0)
00379         opt = '1';
00380     else if (al == -1.0)
00381         opt = '7';
00382     else if (al == -0.5)
00383         opt = '4';
00384     else
00385         return 0;
00386 
00387     sprintf(buffer, "LO%c%s", opt, Sep);
00388     output(buffer);
00389     _Xalign = al;
00390     return 1;
00391 }
00392 #endif
00393 
00394 static void hpgl_reset(void)
00395 {
00396     /* onetime = TRUE; */
00397 }
00398 
00399 static void
00400 hpgl_begin_job(FILE * ofp, graph_t * g, char **lib, char *user,
00401                char *info[], point pages)
00402 {
00403     /* Pages = pages; */
00404     N_pages = pages.x * pages.y;
00405 }
00406 
00407 static void hpgl_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb)
00408 {
00409     PB = bb;
00410     PageWidth = pb.x;
00411     if (Output_lang == PCL) {
00412         prefix = pcl_prefix;
00413         suffix = pcl_suffix;
00414     } else {
00415         prefix = raw_prefix;
00416         suffix = raw_suffix;
00417     }
00418 }
00419 
00420 static void hpgl_set_scale(double scx, double scy)
00421 {
00422     char buffer[64];
00423     sprintf(buffer, "SC%.4f,%.4f,%.4f,%.4f,2%s\n",
00424             -Origin.x / scx, PT2UNIT(scx), -Origin.y / scy, PT2UNIT(scy),
00425             Sep);
00426     output(buffer);
00427 }
00428 
00429 static void hpgl_begin_page(graph_t * g, point page, double scale, int rot,
00430                             point offset)
00431 {
00432     char buffer[64];
00433     box clipWin;
00434 
00435     bufcnt = 0;
00436     Scale = scale;
00437 
00438     /* Initialize output */
00439     output(prefix);
00440     sprintf(buffer, "BP%sIN%s", Sep, Sep);
00441     output(buffer);
00442 #ifdef SMILE
00443     doSmile();
00444 #endif
00445 #if 0                           /* not used */
00446     initTextAlign();
00447 #endif
00448     initGC();
00449 
00450     if (N_pages > 1) {
00451         saveGC();
00452         setFont(&coordFont);
00453         if (rot == 90) {
00454             sprintf(buffer, "RO90IP%s", Sep);
00455             output(buffer);
00456         }
00457         sprintf(buffer, "PA0,0%sLB(%d,%d)\03%s\n", Sep, page.x, page.y,
00458                 Sep);
00459         output(buffer);
00460         if (rot == 90) {
00461             sprintf(buffer, "ROIP%s", Sep);
00462             output(buffer);
00463         }
00464         restoreGC();
00465     }
00466 
00467     if (rot == 90) {
00468         /* Rotate layout. HPGL/2 automatically shifts
00469          * origin to bottom right corner, so we have to
00470          * use the page width to set the new origin.
00471          */
00472         sprintf(buffer, "RO90IP%s", Sep);
00473         output(buffer);
00474 
00475         clipWin.LL.x = PB.LL.y - HP_OY - 1;
00476         clipWin.LL.y = PageWidth - PB.UR.x - HP_OX - 1;
00477         clipWin.UR.x = PB.UR.y - HP_OY + 1;
00478         clipWin.UR.y = PageWidth - PB.LL.x - HP_OX + 1;
00479         Origin.x = PB.LL.y + scale * offset.y - HP_OY;
00480         Origin.y = PageWidth - PB.LL.x - scale * offset.x - HP_OX;
00481     } else {
00482         clipWin.LL.x = PB.LL.x - HP_OX - 1;
00483         clipWin.LL.y = PB.LL.y - HP_OY - 1;
00484         clipWin.UR.x = PB.UR.x - HP_OX + 1;
00485         clipWin.UR.y = PB.UR.y - HP_OY + 1;
00486         Origin.x = PB.LL.x + scale * offset.x - HP_OX;
00487         Origin.y = PB.LL.y + scale * offset.y - HP_OY;
00488     }
00489     /* Set clipping window */
00490     sprintf(buffer, "IW%d,%d,%d,%d%s\n",
00491             (int) PT2UNIT(clipWin.LL.x), (int) PT2UNIT(clipWin.LL.y),
00492             (int) PT2UNIT(clipWin.UR.x), (int) PT2UNIT(clipWin.UR.y), Sep);
00493     /* output(buffer); *//* Turn off clipping. */
00494     hpgl_set_scale(scale, scale);
00495 
00496 }
00497 
00498 static void hpgl_end_page(void)
00499 {
00500     char buffer[32];
00501 
00502     sprintf(buffer, "PU%sSP0%sPG;\n", Sep, Sep);        /* pen up; advance page */
00503     output(buffer);
00504     output(suffix);
00505     destroyGC();
00506 }
00507 
00508 static void hpgl_begin_context(void)
00509 {
00510     saveGC();
00511 }
00512 
00513 static void hpgl_end_context(void)
00514 {
00515     restoreGC();
00516 }
00517 
00518 static void mkFontCanon(unsigned char *old, unsigned char *new)
00519 {
00520     unsigned char c;
00521     while ((c = *old++)) {
00522         if (isalnum(c) == FALSE)
00523             continue;
00524         if (isupper(c))
00525             c = tolower(c);
00526         *new++ = c;
00527     }
00528     *new = c;
00529 }
00530 
00531   /* factors for turning font size, in points,
00532    * to pitches, in chars per inch, for fixed pitch fonts.
00533    */
00534 static double courierPitch = 110.76923;
00535 static double stickPitch = 102.85714;
00536 
00537 typedef struct {
00538     char *name;
00539     int symbol;
00540     double *spacing;
00541     int face;
00542     int italic;
00543     int bold;
00544 } FontIndex;
00545 static FontIndex fontIndex[] = {
00546     {"timesroman", 277, 0, 5, 0, 0},
00547     {"timesbold", 277, 0, 5, 0, 3},
00548     {"timesitalic", 277, 0, 5, 1, 0},
00549     {"timesbolditalic", 277, 0, 5, 1, 3},
00550     {"helvetica", 277, 0, 4, 0, 0},
00551     {"helveticabold", 277, 0, 4, 0, 3},
00552     {"helveticaoblique", 277, 0, 4, 1, 0},
00553     {"helveticaboldoblique", 277, 0, 4, 1, 3},
00554     {"courier", 277, &courierPitch, 3, 0, 0},
00555     {"courierbold", 277, &courierPitch, 3, 0, 3},
00556     {"courieroblique", 277, &courierPitch, 3, 1, 0},
00557     {"courierboldoblique", 277, &courierPitch, 3, 1, 3},
00558     {"palatinoroman", 277, 0, 15, 0, 0},
00559     {"palatinobold", 277, 0, 15, 0, 3},
00560     {"palatinoitalic", 277, 0, 15, 1, 0},
00561     {"palatinobolditalic", 277, 0, 15, 1, 3},
00562     {"stickcw", 277, &stickPitch, 48, 0, 0},
00563     {"stick", 277, 0, 48, 0, 0},
00564     {"zapfdingbats", 332, 0, 45, 0, 0},
00565     {"symbol", 173, 0, 5, 0, 0}
00566 };
00567 
00568 static void mkFontInfo(char *name, double size, FontInfo * fip)
00569 {
00570     int i;
00571     char buf[128];
00572     FontIndex *fi;
00573 
00574     mkFontCanon((unsigned char *) name, (unsigned char *) buf);
00575     fi = fontIndex;
00576     for (i = 0; i < sizeof(fontIndex) / sizeof(FontIndex) - 1; i++) {
00577         if (streq(buf, fi->name))
00578             break;
00579         fi++;
00580     }
00581     fip->symbol = fi->symbol;
00582     fip->italic = fi->italic;
00583     fip->bold = fi->bold;
00584     fip->face = fi->face;
00585     if (fi->spacing) {          /* fixed spacing */
00586         fip->spacing = 0;
00587         fip->size = (*(fi->spacing)) / size;
00588     } else {                    /* proportional spacing */
00589         fip->spacing = 1;
00590         fip->size = size;
00591     }
00592 }
00593 
00594 static void hpgl_set_font(char *name, double size)
00595 {
00596     static FontInfo fi;
00597 
00598     mkFontInfo(name, size, &fi);
00599     setFont(&fi);
00600 }
00601 
00602 static void hpgl_set_color(char *name)
00603 {
00604     gvcolor_t color;
00605 
00606 #ifdef HPDEBUG
00607     fprintf(stderr, "set color %s\n", name);
00608 #endif
00609     colorxlate(name, &color, RGBA_BYTE);
00610     set_color((Color *) color.u.rgba);
00611 }
00612 
00613 static void hpgl_set_style(char **s)
00614 {
00615     char *line;
00616 
00617     while ((line = *s++)) {
00618         if (streq(line, "solid"))
00619             set_line_style(SOLID);
00620         else if (streq(line, "dashed"))
00621             set_line_style(DASHED);
00622         else if (streq(line, "dotted"))
00623             set_line_style(DOTTED);
00624         else if (streq(line, "invis"))
00625             set_line_style(INVIS);
00626         else if (streq(line, "bold"))
00627             set_line_bold(TRUE);
00628         else if (streq(line, "filled")) {       /* no-op */
00629         } else if (streq(line, "unfilled")) {   /* no-op */
00630         } else {
00631             agerr(AGERR,
00632                   "hpgl_set_style: unsupported style %s - ignoring\n",
00633                   line);
00634         }
00635     }
00636 }
00637 
00638 static void hpgl_textpara(point p, textpara_t * para)
00639 {
00640     char buffer[128];
00641 
00642     if (isInvis())
00643         return;
00644 
00645     switch (para->just) {
00646     case 'l':
00647         break;
00648     case 'r':
00649         p.x -= para->width;
00650         break;
00651     default:
00652     case 'n':
00653         p.x -= para->width / 2;
00654         break;
00655     }
00656 
00657     sprintf(buffer, "PA%d,%d%s", CX(p.x), CY(p.y), Sep);
00658     output(buffer);
00659     output_text(para->str);
00660 
00661 #ifdef HPDEBUG
00662     fprintf(stderr, "text =%s=\n", para->str);
00663 #endif
00664 }
00665 
00666 static int firstSeg;
00667 #define FLATNESS  1.0
00668 static int isFlat(double x0, double y0, double x1, double y1, double x2,
00669                   double y2, double x3, double y3)
00670 {
00671     double sa, ca, y, O = y3 - y0, A = x3 - x0, H = sqrt(O * O + A * A);
00672 
00673     if (H == 0)
00674         return TRUE;
00675 
00676     sa = O / H, ca = A / H;
00677     y = -sa * (x1 - x0) + ca * (y1 - y0);
00678     if (y > FLATNESS || y < -FLATNESS)
00679         return FALSE;
00680     y = -sa * (x2 - x0) + ca * (y2 - y0);
00681     return y <= FLATNESS && y >= -FLATNESS;
00682 }
00683 
00684 static void Bzier(double x0, double y0, double x1, double y1, double x2,
00685                   double y2, double x3, double y3)
00686 {
00687     char buffer[64];
00688     if (isFlat(x0, y0, x1, y1, x2, y2, x3, y3)) {
00689         if (firstSeg) {
00690             sprintf(buffer, "%d,%d", CX(x3), CY(y3));
00691             firstSeg = 0;
00692         } else {
00693             sprintf(buffer, ",%d,%d", CX(x3), CY(y3));
00694         }
00695         output(buffer);
00696         return;
00697     }
00698     Bzier(x0, y0,
00699           (x0 + x1) / 2, (y0 + y1) / 2,
00700           (x0 + x2) / 4 + x1 / 2, (y0 + y2) / 4 + y1 / 2,
00701           (x0 + x3) / 8 + 3 * (x1 + x2) / 8,
00702           (y0 + y3) / 8 + 3 * (y1 + y2) / 8);
00703     Bzier((x0 + x3) / 8 + 3 * (x1 + x2) / 8,
00704           (y0 + y3) / 8 + 3 * (y1 + y2) / 8, (x1 + x3) / 4 + x2 / 2,
00705           (y1 + y3) / 4 + y2 / 2, (x2 + x3) / 2, (y2 + y3) / 2, x3, y3);
00706 
00707 }
00708 
00709 static void hpgl_bezier(point * A, int n, int arrow_at_start,
00710                         int arrow_at_end, int filled)
00711 {
00712     char buffer[32];
00713     int j;
00714 
00715     if (arrow_at_start || arrow_at_end)
00716         agerr(AGERR, "hpgl_bezier illegal arrow args\n");
00717     if (isInvis())
00718         return;
00719     sprintf(buffer, "PA%d,%d%sPD", CX(A[0].x), CY(A[0].y), Sep);
00720     output(buffer);
00721     firstSeg = 1;
00722     for (j = 1; j < n; j += 3)
00723         Bzier((double) A[j - 1].x, (double) A[j - 1].y,
00724               (double) A[j].x, (double) A[j].y,
00725               (double) A[j + 1].x, (double) A[j + 1].y,
00726               (double) A[j + 2].x, (double) A[j + 2].y);
00727     sprintf(buffer, "%sPU%s\n", Sep, Sep);
00728     output(buffer);
00729 }
00730 
00731 static void hpgl_polygon(point * A, int n, int filled)
00732 {
00733     int j;
00734     char buffer[64];
00735 
00736     if (isInvis())
00737         return;
00738     sprintf(buffer, "PA%d,%d%sPM0%sPD", CX(A[0].x), CY(A[0].y), Sep, Sep);
00739     output(buffer);
00740     for (j = 1; j < n - 1; j++) {
00741         sprintf(buffer, "%d,%d,", CX(A[j].x), CY(A[j].y));
00742         output(buffer);
00743     }
00744     sprintf(buffer, "%d,%d%sPM2%sPU%s", CY(A[n - 1].x), CY(A[n - 1].y),
00745             Sep, Sep, Sep);
00746     output(buffer);
00747     if (filled) {
00748 #ifdef HPDEBUG
00749         fprintf(stderr, "fill pen %d\n", CurrentPen);
00750 #endif
00751         if (CurrentPen == 1) {
00752             sprintf(buffer, "FP%sLT%sEP%sLT99%s\n", Sep, Sep, Sep, Sep);
00753         } else {
00754             sprintf(buffer, "FP%sSP1%sLT%sEP%sSP%d%sLT99%s\n",
00755                     Sep, Sep, Sep, Sep, CurrentPen, Sep, Sep);
00756         }
00757     } else {
00758         sprintf(buffer, "EP%s\n", Sep);
00759     }
00760     output(buffer);
00761 }
00762 
00763 /***** Arrowheads now centralized in emit.c
00764 static void hpgl_arrowhead(point p,double theta,double scale,int flag)
00765 {
00766     point   sp,ep;
00767     double  costh, sinth,arroww2,arrowl;
00768     char    buffer[128];
00769 
00770     if (isInvis()) return;
00771     costh = cos(RADIANS(theta));
00772     sinth = sin(RADIANS(theta));
00773         arrowl = ARROW_LENGTH * scale;
00774         arroww2 = ARROW_WIDTH * scale / 2.0;
00775     sp.x = p.x + arrowl*costh + arroww2*sinth;
00776     sp.y = p.y + arrowl*sinth - arroww2*costh;
00777     ep.x = p.x + arrowl*costh - arroww2*sinth;
00778     ep.y = p.y + arrowl*sinth + arroww2*costh;
00779         sprintf(buffer,"PA%d,%d%sPM0%sPD%d,%d,%d,%d%sPM2%sPU%sFP%s\n",
00780       CX(sp.x),CY(sp.y),Sep,Sep,
00781       CX(p.x),CY(p.y),CX(ep.x),CY(ep.y), Sep, Sep, Sep, Sep);
00782     output(buffer);
00783 }
00784 **********/
00785 
00786 static void hpgl_ellipse(point p, int rx, int ry, int filled)
00787 {
00788     char buffer[128];
00789 
00790     if (isInvis())
00791         return;
00792     sprintf(buffer, "PA%d,%d%s", p.x, p.y, Sep);
00793     output(buffer);
00794     hpgl_set_scale(Scale * rx, Scale * ry);
00795     if (filled) {
00796         if (CurrentPen == 1)
00797             sprintf(buffer, "WG1,0,360%sLT%sEW1,0,360%sLT99%s", Sep, Sep,
00798                     Sep, Sep);
00799         else
00800             sprintf(buffer, "WG1,0,360%sSP1%sLT%sEW1,0,360%sSP%d%sLT99%s",
00801                     Sep, Sep, Sep, Sep, CurrentPen, Sep, Sep);
00802     } else
00803         sprintf(buffer, "EW1,0,360%s", Sep);
00804     output(buffer);
00805     hpgl_set_scale(Scale, Scale);
00806 }
00807 
00808 /* Use encoded form */
00809 static void hpgl_polyline(point * A, int n)
00810 {
00811     int j;
00812     char buffer[64];
00813 
00814     if (isInvis())
00815         return;
00816     sprintf(buffer, "PA%d,%d%sPD", CX(A[0].x), CY(A[0].y), Sep);
00817     output(buffer);
00818     for (j = 1; j < n - 1; j++) {
00819         sprintf(buffer, "%d,%d,", CX(A[j].x), CY(A[j].y));
00820         output(buffer);
00821     }
00822     sprintf(buffer, "%d,%d%sPU%s\n", CX(A[n - 1].x), CY(A[n - 1].y), Sep,
00823             Sep);
00824     output(buffer);
00825 }
00826 
00827 static void hpgl_usershape(usershape_t *us, boxf p, point *A, int n, boolean filled)
00828 {
00829     static boolean onetime = TRUE;
00830     if (onetime) {
00831         agerr(AGERR, "custom shapes not available with this driver\n");
00832         onetime = FALSE;
00833     }
00834 }
00835 
00836 codegen_t HPGL_CodeGen = {
00837     hpgl_reset,
00838     hpgl_begin_job, 0,          /* hpgl_end_job */
00839     hpgl_begin_graph, 0,        /* hpgl_end_graph */
00840     hpgl_begin_page, hpgl_end_page,
00841     0, /* hpgl_begin_layer */ 0,        /* hpgl_end_layer */
00842     0, /* hpgl_begin_cluster */ 0,      /* hpgl_end_cluster */
00843     0, /* hpgl_begin_nodes */ 0,        /* hpgl_end_nodes */
00844     0, /* hpgl_begin_edges */ 0,        /* hpgl_end_edges */
00845     0, /* hpgl_begin_node */ 0, /* hpgl_end_node */
00846     0, /* hpgl_begin_edge */ 0, /* hpgl_end_edge */
00847     hpgl_begin_context, hpgl_end_context,
00848     0, /* hpgl_begin_anchor */ 0,       /* hpgl_end_anchor */
00849     hpgl_set_font, hpgl_textpara,
00850     hpgl_set_color, hpgl_set_color, hpgl_set_style,
00851     hpgl_ellipse, hpgl_polygon,
00852     hpgl_bezier, hpgl_polyline,
00853     0,                          /* bezier_has_arrows */
00854     0,                          /* hpgl_comment */
00855     hpgl_usershape
00856 };

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