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