Graphviz  2.41.20171026.1811
hpglgen.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 
15 /* TODO:
16  * Use encoded form for polyline and polygon
17  */
18 #include <ctype.h>
19 #include "render.h"
20 
21 #define SOLID 0
22 #define DOTTED 1
23 #define DASHED 2
24 #define INVIS 3
25  /* Convert point (1/72 inch) to hpgl units (0.025 mm) */
26 #define PT2UNIT(p) ((p)*(double)14.111)
27 #define PENW 0.0138
28 #define NPENS 32
29 #define CX(_x) ((int)(_x))
30 #define CY(_y) ((int)(_y))
31 
32  /* Origin of HP plotter from lower left corner, in points
33  * This varies from plotter to plotter. We assume 1/4" and
34  * hope for the best.
35  */
36 #define HP_OX 18
37 #define HP_OY 18
38 
39 static char *raw_prefix = "";
40 static char *raw_suffix = "";
41 #ifdef NOTUSED_ERG_MUST_KNOW_WHY
42 static char *clr_prefix = "\033%-12345X@PJL ENTER LANGUAGE = HPGL2\n";
43 static char *clr_suffix = "\033%-12345X\n";
44 #endif
45 static char *pcl_prefix = "\033E\n\033%%0B\n";
46 static char *pcl_suffix = "\033%%0A\n";
47 
48 static int N_pages;
49 /* static point Pages; */
50 static double Scale;
51 static point Origin;
52 static box PB;
53 static int CurrentPen;
54 static int ColorsUsed;
55 static char *Sep = ";";
56 static int PageWidth; /* Width of page, in points. */
57 static char *prefix; /* Machine-dependent prefix and suffix */
58 static char *suffix;
59 /* static boolean onetime = TRUE; */
60 
61 #define MAXLINELEN 80
62 static int bufcnt; /* Number of characters output on current line */
63 static char *text_hdr = "LB";
64 static void output(char *str)
65 {
66  char *ptr = str;
67  int len;
68 
69  while (*ptr != '\0')
70  ptr++;
71  len = ptr - str;
72  if (bufcnt + len > MAXLINELEN) {
73  fputs("\n", Output_file);
74  bufcnt = 0;
75  }
76  fputs(str, Output_file);
77  if ((len > 0) && (*(ptr - 1) == '\n'))
78  bufcnt = 0;
79  else
80  bufcnt += len;
81 }
82 
83 static void output_text(char *str)
84 {
85  char *ptr = str;
86  int len;
87  char text_tail[32];
88 
89  sprintf(text_tail, "\03%s\n", Sep);
90  while (*ptr != '\0')
91  ptr++;
92  len = (ptr - str) + strlen(text_tail) + strlen(text_hdr);
93  if (bufcnt + len > MAXLINELEN) {
94  fputs("\n", Output_file);
95  }
96  fputs(text_hdr, Output_file);
97  fputs(str, Output_file);
98  fputs(text_tail, Output_file);
99  bufcnt = 0;
100 }
101 
102 #ifdef SMILE
103 void doSmile(void)
104 {
105  fprintf(Output_file,
106  "SP1SD1,341,2,1,4,14,5,0,6,0,7,5SSLO7PA%d,0LB\001\003IN\n",
107  (int) PT2UNIT(PageWid - 2 * HP_OX));
108 
109 }
110 #endif
111 
112 static void setPen(int p)
113 {
114  char buffer[32];
115  sprintf(buffer, "SP%d%s", p, Sep);
116  output(buffer);
117 #ifdef HPDEBUG
118  fprintf(stderr, "set pen %d\n", p);
119 #endif
120  CurrentPen = p;
121 }
122 
123 typedef struct {
124  int symbol;
125  int spacing;
126  int face;
127  int bold;
128  int italic;
129  double size;
130 } FontInfo;
131 static FontInfo dfltFont = { 277, 1, 5, 0, 0, 14.0 };
132 static FontInfo coordFont = { 277, 1, 5, 0, 0, 8.0 };
133 static FontInfo nullFont = { 0, 0, 0, 0, 0, 0.0 };
134 
135  /* Font 0 is the stdfont; font 1 is the alt font */
136 typedef struct {
137  FontInfo fonts[2];
138  int curfont;
139 } FontState;
140 static FontState fontState;
141 
142 static int eqFontInfo(FontInfo * fi1, FontInfo * fi2)
143 {
144  return ((fi1->face == fi2->face) &&
145  (fi1->spacing == fi2->spacing) &&
146  (fi1->bold == fi2->bold) &&
147  (fi1->italic == fi2->italic) &&
148  (fi1->size == fi2->size) && (fi1->symbol == fi2->symbol));
149 }
150 
151 typedef struct {
152  unsigned char r, g, b;
153 } Color;
154 
155 static int eqColor(Color * c1, Color * c2)
156 {
157  return ((c1->r == c2->r) && (c1->g == c2->g) && (c1->b == c2->b));
158 }
159 
160 static Color black = { 0, 0, 0 };
161 static Color white = { 255, 255, 255 };
162 static Color *colorlist;
163 
164 typedef struct GC_s {
165  int bold;
166  int style;
169  struct GC_s *prev;
170 } GC_t;
171 static GC_t *curGC;
172 
173 static void set_color(Color * cp)
174 {
175  int i;
176  char buffer[32];
177 
178  if (eqColor(cp, &curGC->color))
179  return;
180  for (i = 0; i < ColorsUsed; i++) {
181  if (eqColor(cp, &colorlist[i]))
182  break;
183  }
184  if (i == ColorsUsed) {
185  if (ColorsUsed == NPENS)
186  i--;
187  else
188  ColorsUsed++;
189  sprintf(buffer, "PC%d,%d,%d,%d%s", i, cp->r, cp->g, cp->b, Sep);
190  colorlist[i] = *cp;
191  output(buffer);
192 #ifdef HPDEBUG
193  fprintf(stderr, "set pen %d color %d %d %d\n", i, cp->r, cp->g,
194  cp->b);
195 #endif
196  }
197  setPen(i);
198  curGC->color = *cp;
199 }
200 
201 static void initColors(void)
202 {
203  colorlist = N_GNEW(NPENS, Color);
204  colorlist[0] = white;
205  colorlist[1] = black;
206  ColorsUsed = 2;
207 }
208 
209 static void destroyColors(void)
210 {
211  free(colorlist);
212  ColorsUsed = 0;
213 }
214 
215 static void setFont(FontInfo * fi)
216 {
217  int otherfont;
218  char buffer[128];
219 
220  if (eqFontInfo(fi, &fontState.fonts[fontState.curfont]))
221  return;
222  otherfont = (fontState.curfont ? 0 : 1);
223 
224  if (!eqFontInfo(fi, &fontState.fonts[otherfont])) {
225  if (fi->spacing)
226  sprintf(buffer, "%s1,%d,2,1,4,%.1f,5,%d,6,%d,7,%d%s",
227  (otherfont ? "AD" : "SD"), fi->symbol,
228  Scale * (fi->size), fi->italic, fi->bold, fi->face,
229  Sep);
230  else
231  sprintf(buffer, "%s1,%d,2,0,3,%.1f,5,%d,6,%d,7,%d%s",
232  (otherfont ? "AD" : "SD"), fi->symbol,
233  (fi->size) / Scale, fi->italic, fi->bold, fi->face,
234  Sep);
235  output(buffer);
236  }
237  sprintf(buffer, "%s%s\n", (otherfont ? "SA" : "SS"), Sep);
238  output(buffer);
239  fontState.curfont = otherfont;
240  fontState.fonts[otherfont] = *fi;
241  curGC->font = *fi;
242 }
243 
244 static void set_line_bold(int on)
245 {
246  char buffer[32];
247 
248  if (on) {
249  sprintf(buffer, "PW%.3f%s\n", 2 * PENW, Sep);
250  curGC->bold = TRUE;
251  } else {
252  sprintf(buffer, "PW%.3f%s\n", PENW, Sep);
253  curGC->bold = FALSE;
254  }
255  output(buffer);
256 }
257 
258 static void set_line_style(int sty)
259 {
260  char buffer[8];
261  char *opt = NULL;
262 
263  curGC->style = sty;
264  switch (sty) {
265  case SOLID:
266  opt = "LT";
267  break;
268  case DOTTED:
269  opt = "LT1";
270  break;
271  case DASHED:
272  opt = "LT2";
273  break;
274  case INVIS:
275  default:
276  return;
277  }
278  sprintf(buffer, "%s%s", opt, Sep);
279  output(buffer);
280 }
281 
282 static GC_t *makeGC(GC_t * old)
283 {
284  GC_t *newGC;
285  newGC = GNEW(GC_t);
286  if (old)
287  *newGC = *old;
288  else {
289  newGC->bold = FALSE, newGC->style = SOLID, newGC->color = black;
290  newGC->font = dfltFont;
291  }
292  newGC->prev = 0;
293  return newGC;
294 }
295 
296 static void initGC(void)
297 {
298  char buffer[32];
299 
300  curGC = makeGC(0);
301  /* Pick pen 1; set default pen width; set colors
302  */
303  sprintf(buffer, "SP1%sPW%.3f%s\n", Sep, PENW, Sep);
304  output(buffer);
305  fontState.curfont = 1;
306  setFont(&dfltFont);
307  CurrentPen = 1;
308  initColors();
309 }
310 
311 static void destroyGC(void)
312 {
313  GC_t *gc, *gc1;
314  for (gc = curGC; gc; gc = gc1) {
315  gc1 = gc->prev;
316  free(gc);
317  }
318  curGC = 0;
319  fontState.fonts[0] = nullFont;
320  fontState.fonts[1] = nullFont;
321  fontState.curfont = 1;
322  destroyColors();
323 }
324 
325 static void saveGC(void)
326 {
327  GC_t *newGC;
328  newGC = makeGC(curGC);
329  newGC->prev = curGC;
330  curGC = newGC;
331 }
332 
333 static void restoreGC(void)
334 {
335  GC_t *gc, *newGC;
336  gc = curGC;
337  newGC = gc->prev;
338  if (gc->bold != newGC->bold)
339  set_line_bold(newGC->bold);
340  if (gc->style != newGC->style)
341  set_line_style(newGC->style);
342  if (!eqColor(&gc->color, &newGC->color)) {
343 #ifdef HPDEBUG
344  fprintf(stderr, "restore color\n");
345 #endif
346  set_color(&newGC->color);
347  }
348  if (!eqFontInfo(&gc->font, &newGC->font))
349  setFont(&newGC->font);
350  free(gc);
351  curGC = newGC;
352 }
353 
354 static int isInvis(void)
355 {
356  return (curGC->style == INVIS);
357 }
358 
359 #if 0 /* not used */
360 static double _Xalign;
361 #define getTextAlign() (_Xalign)
362 static void initTextAlign(void)
363 {
364  char buffer[20];
365  _Xalign = -0.5;
366  sprintf(buffer, "LO4%s", Sep);
367  output(buffer);
368 }
369 
370 static int setTextAlign(double al)
371 {
372  char buffer[20];
373  char opt;
374 
375  if (al == 0.0)
376  opt = '1';
377  else if (al == -1.0)
378  opt = '7';
379  else if (al == -0.5)
380  opt = '4';
381  else
382  return 0;
383 
384  sprintf(buffer, "LO%c%s", opt, Sep);
385  output(buffer);
386  _Xalign = al;
387  return 1;
388 }
389 #endif
390 
391 static void hpgl_reset(void)
392 {
393  /* onetime = TRUE; */
394 }
395 
396 static void
397 hpgl_begin_job(FILE * ofp, graph_t * g, const char **lib, char *info[], point pages)
398 {
399  /* Pages = pages; */
400  N_pages = pages.x * pages.y;
401 }
402 
403 static void hpgl_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb)
404 {
405  PB = bb;
406  PageWidth = pb.x;
407  if (Output_lang == PCL) {
408  prefix = pcl_prefix;
409  suffix = pcl_suffix;
410  } else {
411  prefix = raw_prefix;
412  suffix = raw_suffix;
413  }
414 }
415 
416 static void hpgl_set_scale(double scx, double scy)
417 {
418  char buffer[64];
419  sprintf(buffer, "SC%.4f,%.4f,%.4f,%.4f,2%s\n",
420  -Origin.x / scx, PT2UNIT(scx), -Origin.y / scy, PT2UNIT(scy),
421  Sep);
422  output(buffer);
423 }
424 
425 static void hpgl_begin_page(graph_t * g, point page, double scale, int rot,
426  point offset)
427 {
428  char buffer[64];
429  box clipWin;
430 
431  bufcnt = 0;
432  Scale = scale;
433 
434  /* Initialize output */
435  output(prefix);
436  sprintf(buffer, "BP%sIN%s", Sep, Sep);
437  output(buffer);
438 #ifdef SMILE
439  doSmile();
440 #endif
441 #if 0 /* not used */
442  initTextAlign();
443 #endif
444  initGC();
445 
446  if (N_pages > 1) {
447  saveGC();
448  setFont(&coordFont);
449  if (rot == 90) {
450  sprintf(buffer, "RO90IP%s", Sep);
451  output(buffer);
452  }
453  sprintf(buffer, "PA0,0%sLB(%d,%d)\03%s\n", Sep, page.x, page.y,
454  Sep);
455  output(buffer);
456  if (rot == 90) {
457  sprintf(buffer, "ROIP%s", Sep);
458  output(buffer);
459  }
460  restoreGC();
461  }
462 
463  if (rot == 90) {
464  /* Rotate layout. HPGL/2 automatically shifts
465  * origin to bottom right corner, so we have to
466  * use the page width to set the new origin.
467  */
468  sprintf(buffer, "RO90IP%s", Sep);
469  output(buffer);
470 
471  clipWin.LL.x = PB.LL.y - HP_OY - 1;
472  clipWin.LL.y = PageWidth - PB.UR.x - HP_OX - 1;
473  clipWin.UR.x = PB.UR.y - HP_OY + 1;
474  clipWin.UR.y = PageWidth - PB.LL.x - HP_OX + 1;
475  Origin.x = PB.LL.y + scale * offset.y - HP_OY;
476  Origin.y = PageWidth - PB.LL.x - scale * offset.x - HP_OX;
477  } else {
478  clipWin.LL.x = PB.LL.x - HP_OX - 1;
479  clipWin.LL.y = PB.LL.y - HP_OY - 1;
480  clipWin.UR.x = PB.UR.x - HP_OX + 1;
481  clipWin.UR.y = PB.UR.y - HP_OY + 1;
482  Origin.x = PB.LL.x + scale * offset.x - HP_OX;
483  Origin.y = PB.LL.y + scale * offset.y - HP_OY;
484  }
485  /* Set clipping window */
486  sprintf(buffer, "IW%d,%d,%d,%d%s\n",
487  (int) PT2UNIT(clipWin.LL.x), (int) PT2UNIT(clipWin.LL.y),
488  (int) PT2UNIT(clipWin.UR.x), (int) PT2UNIT(clipWin.UR.y), Sep);
489  /* output(buffer); *//* Turn off clipping. */
490  hpgl_set_scale(scale, scale);
491 
492 }
493 
494 static void hpgl_end_page(void)
495 {
496  char buffer[32];
497 
498  sprintf(buffer, "PU%sSP0%sPG;\n", Sep, Sep); /* pen up; advance page */
499  output(buffer);
500  output(suffix);
501  destroyGC();
502 }
503 
504 static void hpgl_begin_context(void)
505 {
506  saveGC();
507 }
508 
509 static void hpgl_end_context(void)
510 {
511  restoreGC();
512 }
513 
514 static void mkFontCanon(unsigned char *old, unsigned char *new)
515 {
516  unsigned char c;
517  while ((c = *old++)) {
518  if (isalnum(c) == FALSE)
519  continue;
520  if (isupper(c))
521  c = tolower(c);
522  *new++ = c;
523  }
524  *new = c;
525 }
526 
527  /* factors for turning font size, in points,
528  * to pitches, in chars per inch, for fixed pitch fonts.
529  */
530 static double courierPitch = 110.76923;
531 static double stickPitch = 102.85714;
532 
533 typedef struct {
534  char *name;
535  int symbol;
536  double *spacing;
537  int face;
538  int italic;
539  int bold;
540 } FontIndex;
541 static FontIndex fontIndex[] = {
542  {"timesroman", 277, 0, 5, 0, 0},
543  {"timesbold", 277, 0, 5, 0, 3},
544  {"timesitalic", 277, 0, 5, 1, 0},
545  {"timesbolditalic", 277, 0, 5, 1, 3},
546  {"helvetica", 277, 0, 4, 0, 0},
547  {"helveticabold", 277, 0, 4, 0, 3},
548  {"helveticaoblique", 277, 0, 4, 1, 0},
549  {"helveticaboldoblique", 277, 0, 4, 1, 3},
550  {"courier", 277, &courierPitch, 3, 0, 0},
551  {"courierbold", 277, &courierPitch, 3, 0, 3},
552  {"courieroblique", 277, &courierPitch, 3, 1, 0},
553  {"courierboldoblique", 277, &courierPitch, 3, 1, 3},
554  {"palatinoroman", 277, 0, 15, 0, 0},
555  {"palatinobold", 277, 0, 15, 0, 3},
556  {"palatinoitalic", 277, 0, 15, 1, 0},
557  {"palatinobolditalic", 277, 0, 15, 1, 3},
558  {"stickcw", 277, &stickPitch, 48, 0, 0},
559  {"stick", 277, 0, 48, 0, 0},
560  {"zapfdingbats", 332, 0, 45, 0, 0},
561  {"symbol", 173, 0, 5, 0, 0}
562 };
563 
564 static void mkFontInfo(char *name, double size, FontInfo * fip)
565 {
566  int i;
567  char buf[128];
568  FontIndex *fi;
569 
570  mkFontCanon((unsigned char *) name, (unsigned char *) buf);
571  fi = fontIndex;
572  for (i = 0; i < sizeof(fontIndex) / sizeof(FontIndex) - 1; i++) {
573  if (streq(buf, fi->name))
574  break;
575  fi++;
576  }
577  fip->symbol = fi->symbol;
578  fip->italic = fi->italic;
579  fip->bold = fi->bold;
580  fip->face = fi->face;
581  if (fi->spacing) { /* fixed spacing */
582  fip->spacing = 0;
583  fip->size = (*(fi->spacing)) / size;
584  } else { /* proportional spacing */
585  fip->spacing = 1;
586  fip->size = size;
587  }
588 }
589 
590 static void hpgl_set_font(char *name, double size)
591 {
592  static FontInfo fi;
593 
594  mkFontInfo(name, size, &fi);
595  setFont(&fi);
596 }
597 
598 static void hpgl_set_color(char *name)
599 {
600  gvcolor_t color;
601 
602 #ifdef HPDEBUG
603  fprintf(stderr, "set color %s\n", name);
604 #endif
605  colorxlate(name, &color, RGBA_BYTE);
606  set_color((Color *) color.u.rgba);
607 }
608 
609 static void hpgl_set_style(char **s)
610 {
611  char *line;
612 
613  while ((line = *s++)) {
614  if (streq(line, "solid"))
615  set_line_style(SOLID);
616  else if (streq(line, "dashed"))
617  set_line_style(DASHED);
618  else if (streq(line, "dotted"))
619  set_line_style(DOTTED);
620  else if (streq(line, "invis"))
621  set_line_style(INVIS);
622  else if (streq(line, "bold"))
623  set_line_bold(TRUE);
624  else if (streq(line, "filled")) { /* no-op */
625  } else if (streq(line, "unfilled")) { /* no-op */
626  } else {
627  agerr(AGERR,
628  "hpgl_set_style: unsupported style %s - ignoring\n",
629  line);
630  }
631  }
632 }
633 
634 static void hpgl_textpara(point p, textpara_t * para)
635 {
636  char buffer[128];
637 
638  if (isInvis())
639  return;
640 
641  switch (para->just) {
642  case 'l':
643  break;
644  case 'r':
645  p.x -= para->width;
646  break;
647  default:
648  case 'n':
649  p.x -= para->width / 2;
650  break;
651  }
652 
653  sprintf(buffer, "PA%d,%d%s", CX(p.x), CY(p.y), Sep);
654  output(buffer);
655  output_text(para->str);
656 
657 #ifdef HPDEBUG
658  fprintf(stderr, "text =%s=\n", para->str);
659 #endif
660 }
661 
662 static int firstSeg;
663 #define FLATNESS 1.0
664 static int isFlat(double x0, double y0, double x1, double y1, double x2,
665  double y2, double x3, double y3)
666 {
667  double sa, ca, y, O = y3 - y0, A = x3 - x0, H = sqrt(O * O + A * A);
668 
669  if (H == 0)
670  return TRUE;
671 
672  sa = O / H, ca = A / H;
673  y = -sa * (x1 - x0) + ca * (y1 - y0);
674  if (y > FLATNESS || y < -FLATNESS)
675  return FALSE;
676  y = -sa * (x2 - x0) + ca * (y2 - y0);
677  return y <= FLATNESS && y >= -FLATNESS;
678 }
679 
680 static void Bzier(double x0, double y0, double x1, double y1, double x2,
681  double y2, double x3, double y3)
682 {
683  char buffer[64];
684  if (isFlat(x0, y0, x1, y1, x2, y2, x3, y3)) {
685  if (firstSeg) {
686  sprintf(buffer, "%d,%d", CX(x3), CY(y3));
687  firstSeg = 0;
688  } else {
689  sprintf(buffer, ",%d,%d", CX(x3), CY(y3));
690  }
691  output(buffer);
692  return;
693  }
694  Bzier(x0, y0,
695  (x0 + x1) / 2, (y0 + y1) / 2,
696  (x0 + x2) / 4 + x1 / 2, (y0 + y2) / 4 + y1 / 2,
697  (x0 + x3) / 8 + 3 * (x1 + x2) / 8,
698  (y0 + y3) / 8 + 3 * (y1 + y2) / 8);
699  Bzier((x0 + x3) / 8 + 3 * (x1 + x2) / 8,
700  (y0 + y3) / 8 + 3 * (y1 + y2) / 8, (x1 + x3) / 4 + x2 / 2,
701  (y1 + y3) / 4 + y2 / 2, (x2 + x3) / 2, (y2 + y3) / 2, x3, y3);
702 
703 }
704 
705 static void hpgl_bezier(point * A, int n, int arrow_at_start,
706  int arrow_at_end, int filled)
707 {
708  char buffer[32];
709  int j;
710 
711  if (arrow_at_start || arrow_at_end)
712  agerr(AGERR, "hpgl_bezier illegal arrow args\n");
713  if (isInvis())
714  return;
715  sprintf(buffer, "PA%d,%d%sPD", CX(A[0].x), CY(A[0].y), Sep);
716  output(buffer);
717  firstSeg = 1;
718  for (j = 1; j < n; j += 3)
719  Bzier((double) A[j - 1].x, (double) A[j - 1].y,
720  (double) A[j].x, (double) A[j].y,
721  (double) A[j + 1].x, (double) A[j + 1].y,
722  (double) A[j + 2].x, (double) A[j + 2].y);
723  sprintf(buffer, "%sPU%s\n", Sep, Sep);
724  output(buffer);
725 }
726 
727 static void hpgl_polygon(point * A, int n, int filled)
728 {
729  int j;
730  char buffer[64];
731 
732  if (isInvis())
733  return;
734  sprintf(buffer, "PA%d,%d%sPM0%sPD", CX(A[0].x), CY(A[0].y), Sep, Sep);
735  output(buffer);
736  for (j = 1; j < n - 1; j++) {
737  sprintf(buffer, "%d,%d,", CX(A[j].x), CY(A[j].y));
738  output(buffer);
739  }
740  sprintf(buffer, "%d,%d%sPM2%sPU%s", CY(A[n - 1].x), CY(A[n - 1].y),
741  Sep, Sep, Sep);
742  output(buffer);
743  if (filled) {
744 #ifdef HPDEBUG
745  fprintf(stderr, "fill pen %d\n", CurrentPen);
746 #endif
747  if (CurrentPen == 1) {
748  sprintf(buffer, "FP%sLT%sEP%sLT99%s\n", Sep, Sep, Sep, Sep);
749  } else {
750  sprintf(buffer, "FP%sSP1%sLT%sEP%sSP%d%sLT99%s\n",
751  Sep, Sep, Sep, Sep, CurrentPen, Sep, Sep);
752  }
753  } else {
754  sprintf(buffer, "EP%s\n", Sep);
755  }
756  output(buffer);
757 }
758 
759 /***** Arrowheads now centralized in emit.c
760 static void hpgl_arrowhead(point p,double theta,double scale,int flag)
761 {
762  point sp,ep;
763  double costh, sinth,arroww2,arrowl;
764  char buffer[128];
765 
766  if (isInvis()) return;
767  costh = cos(RADIANS(theta));
768  sinth = sin(RADIANS(theta));
769  arrowl = ARROW_LENGTH * scale;
770  arroww2 = ARROW_WIDTH * scale / 2.0;
771  sp.x = p.x + arrowl*costh + arroww2*sinth;
772  sp.y = p.y + arrowl*sinth - arroww2*costh;
773  ep.x = p.x + arrowl*costh - arroww2*sinth;
774  ep.y = p.y + arrowl*sinth + arroww2*costh;
775  sprintf(buffer,"PA%d,%d%sPM0%sPD%d,%d,%d,%d%sPM2%sPU%sFP%s\n",
776  CX(sp.x),CY(sp.y),Sep,Sep,
777  CX(p.x),CY(p.y),CX(ep.x),CY(ep.y), Sep, Sep, Sep, Sep);
778  output(buffer);
779 }
780 **********/
781 
782 static void hpgl_ellipse(point p, int rx, int ry, int filled)
783 {
784  char buffer[128];
785 
786  if (isInvis())
787  return;
788  sprintf(buffer, "PA%d,%d%s", p.x, p.y, Sep);
789  output(buffer);
790  hpgl_set_scale(Scale * rx, Scale * ry);
791  if (filled) {
792  if (CurrentPen == 1)
793  sprintf(buffer, "WG1,0,360%sLT%sEW1,0,360%sLT99%s", Sep, Sep,
794  Sep, Sep);
795  else
796  sprintf(buffer, "WG1,0,360%sSP1%sLT%sEW1,0,360%sSP%d%sLT99%s",
797  Sep, Sep, Sep, Sep, CurrentPen, Sep, Sep);
798  } else
799  sprintf(buffer, "EW1,0,360%s", Sep);
800  output(buffer);
801  hpgl_set_scale(Scale, Scale);
802 }
803 
804 /* Use encoded form */
805 static void hpgl_polyline(point * A, int n)
806 {
807  int j;
808  char buffer[64];
809 
810  if (isInvis())
811  return;
812  sprintf(buffer, "PA%d,%d%sPD", CX(A[0].x), CY(A[0].y), Sep);
813  output(buffer);
814  for (j = 1; j < n - 1; j++) {
815  sprintf(buffer, "%d,%d,", CX(A[j].x), CY(A[j].y));
816  output(buffer);
817  }
818  sprintf(buffer, "%d,%d%sPU%s\n", CX(A[n - 1].x), CY(A[n - 1].y), Sep,
819  Sep);
820  output(buffer);
821 }
822 
823 static void hpgl_usershape(usershape_t *us, boxf p, point *A, int n, boolean filled)
824 {
825  static boolean onetime = TRUE;
826  if (onetime) {
827  agerr(AGERR, "custom shapes not available with this driver\n");
828  onetime = FALSE;
829  }
830 }
831 
832 codegen_t HPGL_CodeGen = {
833  hpgl_reset,
834  hpgl_begin_job, 0, /* hpgl_end_job */
835  hpgl_begin_graph, 0, /* hpgl_end_graph */
836  hpgl_begin_page, hpgl_end_page,
837  0, /* hpgl_begin_layer */ 0, /* hpgl_end_layer */
838  0, /* hpgl_begin_cluster */ 0, /* hpgl_end_cluster */
839  0, /* hpgl_begin_nodes */ 0, /* hpgl_end_nodes */
840  0, /* hpgl_begin_edges */ 0, /* hpgl_end_edges */
841  0, /* hpgl_begin_node */ 0, /* hpgl_end_node */
842  0, /* hpgl_begin_edge */ 0, /* hpgl_end_edge */
843  hpgl_begin_context, hpgl_end_context,
844  0, /* hpgl_begin_anchor */ 0, /* hpgl_end_anchor */
845  hpgl_set_font, hpgl_textpara,
846  hpgl_set_color, hpgl_set_color, hpgl_set_style,
847  hpgl_ellipse, hpgl_polygon,
848  hpgl_bezier, hpgl_polyline,
849  0, /* bezier_has_arrows */
850  0, /* hpgl_comment */
851  hpgl_usershape
852 };
unsigned char b
Definition: hpglgen.c:152
int italic
Definition: hpglgen.c:128
Definition: cgraph.h:388
union color_s::@10 u
#define DASHED
Definition: hpglgen.c:23
Definition: hpglgen.c:164
int spacing
Definition: hpglgen.c:125
unsigned char g
Definition: hpglgen.c:152
int bold
Definition: hpglgen.c:165
#define PCL
Definition: const.h:134
#define DOTTED
Definition: hpglgen.c:22
#define HP_OY
Definition: hpglgen.c:37
int face
Definition: hpglgen.c:537
#define FLATNESS
Definition: hpglgen.c:663
Definition: color.h:34
Definition: hpglgen.c:151
int agerr(agerrlevel_t level, const char *fmt,...)
Definition: agerror.c:141
int symbol
Definition: hpglgen.c:124
point UR
Definition: geom.h:33
int x
Definition: geom.h:26
codegen_t HPGL_CodeGen
Definition: hpglgen.c:832
#define PT2UNIT(p)
Definition: hpglgen.c:26
Color color
Definition: hpglgen.c:167
#define INVIS
Definition: hpglgen.c:24
#define NPENS
Definition: hpglgen.c:28
#define SOLID
Definition: hpglgen.c:21
int symbol
Definition: hpglgen.c:535
Definition: gvcint.h:70
FontInfo font
Definition: hpglgen.c:168
int face
Definition: hpglgen.c:126
char * name
Definition: hpglgen.c:534
int italic
Definition: hpglgen.c:538
point LL
Definition: geom.h:33
Definition: grammar.c:79
#define PENW
Definition: hpglgen.c:27
#define HP_OX
Definition: hpglgen.c:36
double * spacing
Definition: hpglgen.c:536
int colorxlate(char *str, gvcolor_t *color, color_type_t target_type)
Definition: colxlate.c:254
#define NULL
Definition: logic.h:39
#define GNEW(t)
Definition: memory.h:37
Definition: geom.h:26
#define streq(s, t)
Definition: cghdr.h:52
GVC_t * gvc
Definition: htmlparse.c:87
double size
Definition: hpglgen.c:129
unsigned char r
Definition: hpglgen.c:152
#define CY(_y)
Definition: hpglgen.c:30
int curfont
Definition: hpglgen.c:138
int bold
Definition: hpglgen.c:539
int style
Definition: hpglgen.c:166
#define MAXLINELEN
Definition: hpglgen.c:61
FontInfo fonts[2]
Definition: hpglgen.c:137
struct GC_s * prev
Definition: hpglgen.c:169
agxbuf * str
Definition: htmlparse.c:85
#define CX(_x)
Definition: hpglgen.c:29
int y
Definition: geom.h:26
unsigned char rgba[4]
Definition: color.h:38
Definition: geom.h:35
#define N_GNEW(n, t)
Definition: agxbuf.c:20
struct GC_s GC_t
#define FALSE
Definition: cgraph.h:35
int bold
Definition: hpglgen.c:127
Definition: geom.h:33
#define TRUE
Definition: cgraph.h:38