w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

psspecial.c
Go to the documentation of this file.
1 #include "defs.h"
2 #include "global.h"
3 #include <math.h>
4 #include "emit.h"
5 #include "ps.h"
6 
7 char *GetKeyStr();
8 int GetKeyVal();
9 int IsSame();
10 extern double cos(), sin(), sqrt();
11 static void ps_pensize();
12 static void ps_flushpath();
13 static void ps_flushdashedpath();
14 static void ps_drawto();
15 static void ps_arc();
16 static void ps_flushspline();
17 static int dist();
18 static void ps_whiten();
19 static void ps_blacken();
20 static void ps_shade();
21 static void push_location(), pop_location();
23 static void draw_line();
24 static void ps_texture();
25 static void ps_rotate();
26 
27 #define TWOPI (3.14157926536*2.0)
28 #define MAXPOINTS 600 /* Most number of points in a path */
29 #define SPLINEPOINTS 5000 /* Most points in a spline */
30 #define RADTODEG (360/(TWOPI))
31 
32 #define xconv(x) ((int) ((x) * ( ((float) resolution) / 1000.0) + 0.5))
33 #define yconv(y) ((int) ((y) * ( ((float) resolution) / 1000.0) + 0.5))
34 
35 static int xx[MAXPOINTS], yy[MAXPOINTS], pathlen,
36  pensize = 2; /* Size we want Imagen to draw at, default 2 pixels */
37 static double graylevel = 0.5;
38 
39 #define NOFILL 0
40 #define BLACK 1
41 #define GRAY 2
42 #define WHITE 3
43 static int
44 /* texture_defined = FALSE,*//* Have we done a set_texture yet? */
45  shade_next = NOFILL, /* Should next object be shaded? */
47 
50 
51 #define skipblank(p) for (; *p == ' '; p++)
52 
53 struct bangspecial {
55  char bs_string[1];
56 };
57 static struct bangspecial *bangspecials = NULL;
58 static struct bangspecial **nextbs = &bangspecials;
59 
60 /*-->DoSpecial*/
61 /*********************************************************************/
62 /***************************** DoSpecial ***************************/
63 /*********************************************************************/
64 
65 typedef enum {
67  } ValTyp;
68 
69 typedef struct {
70  char *Key; /* the keyword string */
71  char *Val; /* the value string */
72  ValTyp vt; /* the value type */
73  union { /* the decoded value */
74  int i;
75  float n;
76  } v;
77  } KeyWord;
78 
79 typedef struct {
80  char *Entry;
82  } KeyDesc;
83 
84 #define PSFILE 0
85 #define EPSFILE 1
86 
87 KeyDesc KeyTab[] = {{"psfile", String},
88  {"epsfile", String},
89  {"hsize", Dimension},
90  {"vsize", Dimension},
91  {"hoffset", Dimension},
92  {"voffset", Dimension},
93  {"hscale", Number},
94  {"vscale", Number},
95  {"rotation", Dimension},
96  {"angle", Number},
97  {"llx", Number},
98  {"lly", Number},
99  {"urx", Number},
100  {"ury", Number},
101  {"rwi", Number},
102  {"rhi", Number},
103  {"clip", None}
104  };
105 
106 #define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
107 
108 /* ARGSUSED */
109 void
111 char *str;
112 int n;
113 {
114  char spbuf[STRSIZE];
115  char *sf = NULL;
116  char *p, *q;
117  struct bangspecial *b;
118  KeyWord k;
119  int i;
120 
121  str[n] = '\0';
122  spbuf[0] = '\0';
123  p = str;
124 
125  skipblank(p);
126  if (*p == '\0')
127  return;
128  usesspecial = TRUE;
129 
130  if (*p == '!') {
131  b = (struct bangspecial *)
132  alloc_check(malloc((unsigned)sizeof(struct bangspecial)+n-1),
133  "bangspecials");
134  strncpy(b->bs_string, p+1, n);
135  b->bs_next = NULL;
136  *nextbs = b;
137  nextbs = &(b->bs_next);
138  return;
139  }
140  if (strncmp(p, "landscape", 9) == 0) {
141  landscape = TRUE;
142  return;
143  }
144  if (strncmp(p, "papersize", 9) == 0) {
145  p += 9;
146  while (*p == '=' || *p == ' ')
147  p++;
148  /* TODO */
149  return;
150  }
151  if (strncmp(p, "header", 6) == 0) {
152  p += 6;
153  while ((*p <= ' ' || *p == '=' || *p == '(') && *p != '\0')
154  p++;
155  q = p + strlen(p) - 1;
156  while ((*q <= ' '|| *q == '(') && p <= q)
157  q--;
158  *++q = '\0';
159  if (p <= q)
160  ps_add_include(p);
161  return;
162  }
163  if (strncmp(p, "background", 10) == 0) {
164  usescolor = TRUE;
165  p += 11;
166  skipblank(p);
167  background(p);
168  return;
169  }
170  if (strncmp(p, "color", 5) == 0) {
171  usescolor = TRUE;
172  p += 6;
173  skipblank(p);
174  if (strncmp(p, "push", 4) == 0) {
175  p += 5;
176  skipblank(p);
177  pushcolor(p, FALSE);
178  } else if (strncmp(p, "pop", 3) == 0) {
179  popcolor(FALSE);
180  } else {
182  }
183  return;
184  }
185  if (strncmp(p, "src:", 4) == 0) {
186  return;
187  }
188  if (strncmp(p, "pos:", 4) == 0) {
189  return;
190  }
191  if (strncmp(p, "om:", 3) == 0) {
192  return;
193  }
194  if (strncmp(p, "xtex:", 5) == 0) {
195  return;
196  }
197  if (strncmp(p, "html:", 5) == 0) {
198  return;
199  }
200 
201  while ((p=GetKeyStr(p,&k)) != NULL) { /* get all keyword-value pairs */
202  /* for compatibility, single words are taken as file names */
203  if (k.vt == None && access(k.Key,F_OK) == 0) {
204 /*
205  if (sf)
206  Warning(" More than one \\special file name given. %s ignored", sf);
207 */
208  (void)strcpy(spbuf, k.Key);
209  sf = spbuf;
210  } else if (GetKeyVal(&k, KeyTab, NKEYS, &i) && i != -1) {
211  if (i == PSFILE || i == EPSFILE ) {
212 /*
213  if (sf)
214  Warning(" More than one \\special file name given. %s ignored", sf);
215 */
216  (void)strcpy(spbuf, k.Val);
217  sf = spbuf;
218  } /* the keywords are ignored */
219  } /*else
220  Warning(" Invalid keyword or value in \\special - \"%s\" ignored",
221  k.Key);*/
222  }
223  if (sf) {
224  if (*sf == '`')
225  /* TO DO? */;
226  else
227  ps_scanifont(sf);
228  } /*else
229  Warning(" No special file name provided.");*/
230 }
231 
233 {
234  struct bangspecial *b;
235 
236  if (bangspecials != NULL) {
237  EMITS("TeXDict begin @defspecial\n");
238  for (b = bangspecials; b != NULL; b = b->bs_next) {
239  EMITC('\n');
240  ps_string(b->bs_string);
241  EMITC('\n');
242  }
243  EMITS("\n@fedspecial end\n");
244  }
245 }
246 
247 /* interpret a \special command, made up of keyword=value pairs */
248 void
250 char *str;
251 int n;
252 {
253  char spbuf[STRSIZE];
254  char *sf = NULL;
255  char *p, *q;
256  KeyWord k;
257  int i;
258  float llx, lly, urx, ury, hsize, vsize;
259 
260  str[n] = '\0';
261  spbuf[0] = '\0';
262  p = str;
263 
264  end_string();
265  dev_setposn(h, v);
266 
267  for (; *p == ' '; p++)
268  ;
269  if (*p == '\0')
270  return;
271 
272  if (*p == '!')
273  return;
274  if (strncmp(p, "landscape", 9) == 0)
275  return;
276  if (strncmp(p, "papersize", 9) == 0)
277  return;
278  if (strncmp(p, "header", 6) == 0)
279  return;
280  if (strncmp(p, "ps:", 3) == 0) {
281  dev_initfont();
282  p += 3;
283  if (*p == ':') {
284  p++;
285  if (strncmp(p, "[begin]", 7) == 0) {
286  EMITC('\n');
287  ps_string(p+7);
288  EMITC('\n');
289  } else if (strncmp(p, "[end]", 5) == 0) {
290  EMITC('\n');
291  ps_string(p+5);
292  EMITC('\n');
293  } else {
294  EMITC('\n');
295  ps_string(p);
296  EMITC('\n');
297  }
298  } else if (strncmp(p, " plotfile ", 10) == 0) {
299  p += 10;
300  for (; *p == ' '; p++);
301  if (*p == '"')
302  for (q = ++p; *q != '\0' && *q != '"'; q++);
303  else
304  for (q = p; *q != '\0' && *q != ' '; q++);
305  *q = '\0';
306  if (*p == '`')
307  ps_createpipe(++p);
308  else
309  ps_copyfigfile(p);
310  } else {
311  EMITC('\n');
312  ps_string(p);
313  EMITC('\n');
314  dev_setposn(h, v);
315  dev_initfont();
316  }
317  return;
318  }
319  if (*p == '"') {
320  EMIT(outfp, "@beginspecial\n");
321  EMITS("@setspecial\n");
322  EMITS("TeXDict begin\n");
323  ps_string(++p);
324  EMITS("\nend\n");
325  EMITS("@endspecial\n");
326  return;
327  }
328  if (strncmp(p, "pn ", 3) == 0) {
329  ps_pensize(p+3);
330  return;
331  }
332  if (strcmp(p, "fp") == 0) {
333  ps_flushpath(0);
334  return;
335  }
336  if (strcmp(p, "ip") == 0) { /* tpic 2.0 */
337  ps_flushpath(1);
338  return;
339  }
340  if (strncmp(p, "da ", 3) == 0) {
341  ps_flushdashedpath(p+3, 0);
342  return;
343  }
344  if (strncmp(p, "dt ", 3) == 0) {
345  ps_flushdashedpath(p+3, 1);
346  return;
347  }
348  if (strncmp(p, "pa ", 3) == 0) {
349  ps_drawto(p+3);
350  return;
351  }
352  if (strncmp(p, "ar ", 3) == 0) { /* tpic 2.0 */
353  ps_arc(p+3, 0);
354  return;
355  }
356  if (strncmp(p, "ia ", 3) == 0) { /* tpic 2.0 */
357  ps_arc(p+3, 1);
358  return;
359  }
360  if (strcmp(p, "sp") == 0) { /* tpic 2.0 */
361  ps_flushspline(p+2);
362  return;
363  }
364  if (strncmp(p, "sp ", 3) == 0) { /* tpic 2.0 */
365  ps_flushspline(p+3);
366  return;
367  }
368  if (strcmp(p, "sh") == 0) { /* tpic 2.0 */
369  ps_shade(p+2);
370  return;
371  }
372  if (strncmp(p, "sh", 2) == 0) { /* tpic 2.0 */
373  ps_shade(p+3);
374  return;
375  }
376  if (strcmp(p, "wh") == 0) {
377  ps_whiten();
378  return;
379  }
380  if (strcmp(p, "bk") == 0) {
381  ps_blacken();
382  return;
383  }
384  if (strncmp(p, "tx ", 3) == 0) {
385  ps_texture(p+3);
386  return;
387  }
388  if (strncmp(p, "rt ", 3) == 0) { /* dviout/prt */
389  ps_rotate(p+2);
390  return;
391  }
392  if (strncmp(p, "background", 10) == 0)
393  return;
394  if (strncmp(p, "color", 5) == 0) {
395  p += 6;
396  skipblank(p);
397  if (strncmp(p, "push", 4) == 0) {
398  p += 5;
399  skipblank(p);
400  pushcolor(p, TRUE);
401  } else if (strncmp(p, "pop", 3) == 0) {
402  popcolor(TRUE);
403  } else {
405  }
406  return;
407  }
408  if (strncmp(p, "RGB", 3) == 0) { /* eclcolor.sty */
409  p += 3;
410  if (*p == '=')
411  p++;
412  ps_setrgbcolor(p);
413  return;
414  }
415  if (strncmp(p, "HSB", 3) == 0) { /* eclcolor.sty */
416  p += 3;
417  if (*p == '=')
418  p++;
419  ps_sethsbcolor(p);
420  return;
421  }
422  if (strncmp(p, "CMYK", 4) == 0) { /* eclcolor.sty */
423  p += 4;
424  if (*p == '=')
425  p++;
427  return;
428  }
429  if (strncmp(p, "postscriptbox", 13) == 0) { /* for jdvi2kps */
430  EMIT(outfp, "@beginspecial\n");
431  for (p += 13; *p == ' '; p++)
432  ;
433  if (sscanf(p, "{ %fpt }{ %fpt }{ %[^ {}] }", &hsize, &vsize, spbuf) != 3)
434  Warning(" badly formed postscriptbox command - ignored");
435  sf = spbuf;
436  if (scanfile(sf, &llx, &lly, &urx, &ury)) {
437  EMIT(outfp, "%f %f %f %f false @bbox\n", llx, lly, urx, ury);
438  EMIT(outfp, "%f @hsize\n", hsize*72/72.27);
439  EMIT(outfp, "%f @vsize\n", vsize*72/72.27);
440  }
441  EMITS("@setspecial\n");
442  if (sf) {
443  if (*sf == '`')
444  ps_createpipe(++sf);
445  else
447  } else
448  Warning(" No special file name provided.");
449  EMITS("@endspecial\n");
450  return;
451  }
452  if (strncmp(p, "src:", 4) == 0) {
453  return;
454  }
455  if (strncmp(p, "pos:", 4) == 0) {
456  return;
457  }
458  if (strncmp(p, "om:", 3) == 0) {
459  return;
460  }
461  if (strncmp(p, "xtex:", 5) == 0) {
462  return;
463  }
464  if (strncmp(p, "html:", 5) == 0) {
465  return;
466  }
467 
468  EMIT(outfp, "@beginspecial\n");
469  while ((p=GetKeyStr(p,&k)) != NULL) { /* get all keyword-value pairs */
470  /* for compatibility, single words are taken as file names */
471  if (k.vt == None && access(k.Key,F_OK) == 0) {
472  if (sf)
473  Warning(" More than one \\special file name given. %s ignored", sf);
474  (void)strcpy(spbuf, k.Key);
475  sf = spbuf;
476  } else if (GetKeyVal(&k, KeyTab, NKEYS, &i) && i != -1) {
477  if (i == PSFILE || i == EPSFILE ) {
478  if (sf)
479  Warning(" More than one \\special file name given. %s ignored", sf);
480  (void)strcpy(spbuf, k.Val);
481  sf = spbuf;
482  if (i == EPSFILE && scanfile(sf, &llx, &lly, &urx, &ury)) {
483  EMIT(outfp, "%f %f %f %f true @bbox\n",
484  llx, lly, urx, ury);
485  EMIT(outfp, "@ecl\n");
486  }
487  } else /* the keywords are simply output as PS procedure calls */
488  EMIT(outfp, "%f @%s\n", k.v.n, KeyTab[i].Entry);
489  } else
490  Warning(" Invalid keyword or value in \\special - \"%s\" ignored",
491  k.Key);
492  }
493 
494  EMITS("@setspecial\n");
495  if (sf) {
496  if (*sf == '`')
497  ps_createpipe(++sf);
498  else
500  } else
501  Warning(" No special file name provided.");
502  EMITS("@endspecial\n");
503  return;
504 }
505 
506 
507 /*-->GetKeyStr*/
508 /**********************************************************************/
509 /***************************** GetKeyStr ****************************/
510 /**********************************************************************/
511 
512 /* extract first keyword-value pair from string (value part may be null)
513  * return pointer to remainder of string
514  * return NULL if none found
515  */
516 
519 
520 char *GetKeyStr(str, kw)
521 char *str;
522 KeyWord *kw;
523 {
524  char *s, *k, *v, t;
525 
526  if (!str)
527  return NULL;
528  for (s = str ; *s == ' '; s++ )
529  ;
530  if (*s == '\0')
531  return NULL;
532 
533  /* extract keyword portion */
534  for (k = KeyStr; *s != ' ' && *s != '\0' && *s != '='; *k++ = *s++)
535  ;
536  *k = '\0';
537 
538  kw->Key = KeyStr;
539  kw->Val = v = NULL;
540  kw->vt = None;
541  for (; *s == ' '; s++) /* skip over blanks */
542  ;
543  if (*s != '=') /* look for "=" */
544  return s;
545 
546  for (s++ ; *s == ' '; s++) /* skip over blanks */
547  ;
548  if (*s == '\'' || *s == '\"') /* get string delimiter */
549  t = *s++;
550  else
551  t = ' ';
552  /* copy value portion up to delim */
553  for (v = ValStr; *s != t && *s != '\0'; *v++ = *s++)
554  ;
555  if (t != ' ' && *s == t)
556  s++;
557  *v = '\0';
558  kw->Val = ValStr;
559  kw->vt = String;
560 
561  return s;
562 }
563 
564 
565 /*-->GetKeyVal*/
566 /**********************************************************************/
567 /***************************** GetKeyVal ****************************/
568 /**********************************************************************/
569 
570  /* get next keyword-value pair
571  * decode value according to table entry
572  */
573 
574 int GetKeyVal(kw, tab, nt, tno)
575 KeyWord *kw;
576 KeyDesc tab[];
577 int nt;
578 int *tno;
579 {
580  int i;
581  char c = '\0';
582 
583  *tno = -1;
584 
585  for (i=0; i<nt; i++)
586  if (IsSame(kw->Key, tab[i].Entry)) {
587  *tno = i;
588  switch (tab[i].Type) {
589  case None:
590  if (kw->vt != None)
591  return FALSE;
592  break;
593  case String:
594  if (kw->vt != String)
595  return FALSE;
596  break;
597  case Integer:
598  if (kw->vt != String)
599  return FALSE;
600  if (sscanf(kw->Val,"%d%c", &(kw->v.i), &c) != 1 || c != '\0')
601  return FALSE;
602  break;
603  case Number:
604  case Dimension:
605  if (kw->vt != String)
606  return FALSE;
607  if (sscanf(kw->Val,"%f%c", &(kw->v.n), &c) != 1 || c != '\0')
608  return FALSE;
609  break;
610  }
611  kw->vt = tab[i].Type;
612  return TRUE;
613  }
614 
615  return TRUE;
616 }
617 
618 char ToLower(c)
619 char c;
620 {
621  return (isupper(c)?tolower(c):c);
622 }
623 
624 int IsSame(a, b) /* compare strings, ignore case */
625 char *a, *b;
626 {
627  for ( ; *a != '\0'; )
628  if (ToLower(*a++) != ToLower(*b++))
629  return FALSE;
630  return (*a == *b ? TRUE : FALSE);
631 }
632 
633 /*-->scanfile*/ /* scan a file */
634 /*********************************************************************/
635 /***************************** scanfile ******************************/
636 /*********************************************************************/
639 char *str;
640 float *llx, *lly, *urx, *ury;
641 {
642  FILE *spfp;
643  char buffer[BUFSIZ];
644  int i;
645 
646  if ((spfp = fopen(str,"r")) == NULL) {
647  Warning("Unable to open file %s", str);
648  return FALSE;
649  }
650  while (fgets(buffer, BUFSIZ, spfp) != NULL) {
651  i = 0;
652  if (buffer[i++] == '%' && buffer[i++] == '%') {
653  if (!strncmp(&buffer[i], "BoundingBox:", 12)) {
654  for (; buffer[i++] != ':'; )
655  ;
656  for (; buffer[i] == ' '; i++) /* skip space */
657  ;
658  if (buffer[i] != '?' && strncmp(&buffer[i], "(atend)", 7)) {
659  (void)sscanf(&buffer[i], "%f %f %f %f", llx, lly, urx, ury);
660  (void)fclose(spfp);
661  return TRUE;
662  }
663  }
664  }
665  }
666  (void)fclose(spfp);
667  return FALSE;
668 }
669 
670 /*
671  * Support drawing routines for Chris Torek's DVI->ImPress program.
672  *
673  * Requires v1.7 or later ImPress to handle paths.
674  * Better if v1.9 or later for arc, circle, and ellipse primitives
675  * (define USEGRAPHICS).
676  *
677  * Tim Morgan, UC Irvine, 11/17/85
678  *
679  * PostScript version
680  * Kazuhiro Kazama, NTT Software Laboratories.
681  */
682 
683 /*
684  * Save the graphic state and set up a new coordinate system
685  */
686 static void push_location()
687 {
688  EMIT(outfp, "%.3f @push\n", (float)mag/1000);
689 }
690 
691 /*
692  * Restore the graphic state
693  */
694 static void pop_location()
695 {
696  EMIT(outfp, "@pop\n");
697 }
698 
699 /*
700  * Set the pen size
701  * Called as \special{pn size}
702  * eg: \special{pn 8}
703  * The size is the number of milli-inches for the diameter of the pen.
704  * This routine converts that value to device-dependent pixels, and makes
705  * sure that the resulting value is within legal bounds.
706  */
707 static void ps_pensize(cp)
708 char *cp;
709 {
710  int size;
711 
712  if (sscanf(cp, "%d ", &size) != 1) {
713  Warning("Illegal format for pn: %s", cp);
714  return;
715  }
716  pensize = xconv(size);
717  if (pensize < 0) pensize = 0;
718 }
719 
720 /*
721  * Make sure the pen size is set. Since we push and pop the state,
722  * this has to be sent for each different object (I think).
723  */
724 static void set_pen_size()
725 {
726  EMIT(outfp, "%d setlinewidth\n", pensize);
727 }
728 
729 /*
730  * Actually apply the attributes (shade, whiten, or blacken) to the currently
731  * defined path/figure.
732  */
733 static void do_attributes()
734 {
735  switch (shade_next) {
736  case BLACK:
737  EMIT(outfp, "0 setgray ");
738  break;
739  case GRAY:
740  EMIT(outfp, "%1.3f setgray ", graylevel);
741  break;
742  case WHITE:
743  EMIT(outfp, "1 setgray ");
744  break;
745  }
746  shade_next = NOFILL;
747 }
748 
749 /*
750  * Flush the path that we've built up with ps_drawto()
751  * Called as \special{fp}
752  */
753 static void ps_flushpath(invisible)
754 int invisible;
755 {
756  int i;
757 
758  push_location();
759  if (pathlen <= 0) return;
760  set_pen_size();
761  EMIT(outfp, "%d %d p\n", xx[1], yy[1]);
762  for (i=2; i<=pathlen; i++) {
763  EMIT(outfp, "%d %d l\n", xx[i], yy[i]);
764  }
765  pathlen = 0;
766  if (shade_next == NOFILL)
767  EMIT(outfp, "stroke\n");
768  else {
769  if (invisible) {
770  do_attributes();
771  EMIT(outfp, "fill\n");
772  } else {
773  EMIT(outfp, "gsave ");
774  do_attributes();
775  EMIT(outfp, "fill grestore stroke\n");
776  }
777  }
778  pop_location();
779 }
780 
781 /*
782  * Draw a dashed or dotted line between the first pair of points in the array
783  * Called as \special{da <inchesperdash>} (dashed line)
784  * or \special{dt <inchesperdot>} (dotted line)
785  * eg: \special{da 0.05}
786  */
788 char *cp;
789 int dotted; /* boolean */
790 {
791  int i;
792  int ipd;
793  float inchesperdash;
794 
795  if (sscanf(cp, "%f ", &inchesperdash) != 1) {
796  Warning("Illegal format for dotted/dashed line da/dt: %s", cp);
797  return;
798  }
799  ipd = (int)(1000.0 * inchesperdash + 0.5);
800  if (ipd == 0)
801  ipd = 1;
802  push_location();
803  if (pathlen <= 0) return;
804  set_pen_size();
805  EMIT(outfp, "%d %d p\n", xx[1], yy[1]);
806  for (i=2; i<=pathlen; i++) {
807  if (dotted) {
808  EMIT(outfp, "1 setlinecap\n");
809  EMIT(outfp, "[%d %d] 0 setdash\n",
810  pensize, (int)xconv((ipd)) - pensize);
811  } else {
812  EMIT(outfp, "[%d] 0 setdash\n", (int)xconv(ipd));
813  }
814  EMIT(outfp, "%d %d l\n", xx[i], yy[i]);
815  }
816  pathlen = 0;
817  if (shade_next == NOFILL)
818  EMIT(outfp, "stroke\n");
819  else {
820  EMIT(outfp, "gsave ");
821  do_attributes();
822  EMIT(outfp, "fill grestore stroke\n");
823  }
824  pop_location();
825 }
826 
827 /*
828  * Virtually draw to a given x,y position on the virtual page.
829  * X and Y are expressed in thousandths of an inch, and this
830  * routine converts them to pixels.
831  *
832  * Called as \special{pa <x> <y>}
833  * eg: \special{pa 0 1200}
834  */
835 static void ps_drawto(cp)
836 char *cp;
837 {
838  int x,y;
839 
840  if (sscanf(cp, "%d %d ", &x, &y) != 2) {
841  Warning("Illegal format for pa: %s", cp);
842  return;
843  }
844  if (++pathlen >= MAXPOINTS)
845  Fatal("Too many points specified\n", 0);
846  xx[pathlen] = xconv(x);
847  yy[pathlen] = yconv(y);
848 }
849 
850 static void ps_arc(cp, invisible)
851 char *cp;
852 int invisible;
853 {
854  int xc, yc, xrad, yrad;
855  float start_angle, end_angle;
856  short alpha0, alpha1;
857 
858  if (sscanf(cp, "%d %d %d %d %f %f ",
859  &xc, &yc, &xrad, &yrad, &start_angle, &end_angle) != 6) {
860  Warning("Illegal format for arc: %s", cp);
861  return;
862  }
863  push_location();
864  set_pen_size();
865 
866  if (start_angle < 0.0) /* for gpic */
867  start_angle += TWOPI;
868  if (end_angle < 0.0)
869  end_angle += TWOPI;
870  alpha0 = start_angle * RADTODEG + 0.5;
871  alpha1 = end_angle * RADTODEG + 0.5;
872  EMIT(outfp, "%d %d %d %d %d %d @ar\n",
873  xconv(xc), yconv(yc), xconv((double) xrad), yconv((double) yrad),
874  alpha0, alpha1);
875  if (shade_next == NOFILL)
876  EMIT(outfp, "stroke\n");
877  else {
878  if (invisible) {
879  do_attributes();
880  EMIT(outfp, "fill\n");
881  } else {
882  EMIT(outfp, "gsave ");
883  do_attributes();
884  EMIT(outfp, "fill grestore stroke\n");
885  }
886  }
887  pop_location();
888 }
889 
890 /*
891  * Create a spline through the points in the array.
892  * Called like flush path (fp) command, after points
893  * have been defined via pa command(s).
894  *
895  * eg: \special{sp}
896  */
898 static void ps_flushspline(cp)
899 char *cp;
900 {
901  int xp, yp, N;
902  double t1, t2, t3, w;
903  int i, j, steps;
904 
905  push_location();
906  set_pen_size();
907  if (*cp) {
908  float f;
909  int ipd;
910 
911  (void) sscanf(cp, "%f", &f);
912  ipd = (int)(1000.0 * (f > 0 ? f : -f) + 0.5);
913  if (ipd == 0)
914  ipd = 1;
915  if (f < 0.0) { /* dotted */
916  EMIT(outfp, "1 setlinecap\n");
917  EMIT(outfp, "[%d %d] 0 setdash\n",
918  pensize, (int)xconv((ipd)) - pensize);
919  } else if (f > 0.0) /* dashed */
920  EMIT(outfp, "[%d] 0 setdash\n", (int)xconv(ipd));
921  }
922  splinelen = 0;
923  N = pathlen + 1;
924  xx[0] = xx[1];
925  yy[0] = yy[1];
926  xx[N] = xx[N-1];
927  yy[N] = yy[N-1];
928  for (i = 0; i < N-1; i++) { /* interval */
929  steps = (dist(xx[i],yy[i], xx[i+1],yy[i+1]) +
930  dist(xx[i+1],yy[i+1], xx[i+2],yy[i+2])) / 20;
931  for (j = 0; j < steps; j++) { /* points within */
932  w = ((double) j + 0.5) / ((double) steps);
933  t1 = 0.5 * w * w;
934  w -= 0.5;
935  t2 = 0.75 - w * w;
936  w -= 0.5;
937  t3 = 0.5 * w * w;
938  xp = t1 * xx[i+2] + t2 * xx[i+1] + t3 * xx[i] + 0.5;
939  yp = t1 * yy[i+2] + t2 * yy[i+1] + t3 * yy[i] + 0.5;
940  if (splinelen >= SPLINEPOINTS)
941  Fatal("Too many points in spline\n", 0);
942  splinex[splinelen] = xp;
943  spliney[splinelen++] = yp;
944  }
945  }
946  EMIT(outfp, "%d %d p\n", splinex[0], spliney[0]);
947  for (i=1; i<splinelen; i++) {
948  EMIT(outfp, "%d %d l\n", splinex[i], spliney[i]);
949  }
950 
951  pathlen = 0;
952  if (shade_next == NOFILL)
953  EMIT(outfp, "stroke\n");
954  else {
955  EMIT(outfp, "gsave ");
956  do_attributes();
957  EMIT(outfp, "fill grestore stroke\n");
958  }
959  pop_location();
960 }
961 
962 static int dist(x1, y1, x2, y2) /* integer distance from x1,y1 to x2,y2 */
963 {
964  double dx, dy;
965 
966  dx = x2 - x1;
967  dy = y2 - y1;
968  return sqrt(dx*dx + dy*dy) + 0.5;
969 }
970 
971 /*
972  * Whiten the interior of the next figure (path). Command is:
973  * \special{wh}
974  */
975 static void ps_whiten()
976 {
977  shade_next = WHITE;
978 }
979 
980 /*
981  * Blacken the interior of the next figure (path). Command is:
982  * \special{bk}
983  */
984 static void ps_blacken()
985 {
986  shade_next = BLACK;
987 }
988 
989 /*
990  * Shade the interior of the next figure (path) with the predefined
991  * texture. Command is:
992  * \special{sh}
993  */
994 static void ps_shade(cp)
995 char *cp;
996 {
997  if (*cp) {
998  float f;
999 
1000  if (sscanf(cp, "%f", &f) != 1) {
1001  Warning("Illegal format for shading value sh: %s", cp);
1002  return;
1003  }
1004  if (f >= 0.0 && f <= 1.0)
1005  graylevel = 1.0 - f;
1006  } else
1007  graylevel = 0.5;
1008  shade_next = GRAY;
1009 }
1010 
1011 static void ps_texture(cp)
1012 char *cp;
1013 {
1014  int blackbits = 0, totalbits = 0;
1015 
1016  while (*cp) {
1017  switch (*cp) {
1018  case '0':
1019  totalbits += 4;
1020  break;
1021  case '1':
1022  case '2':
1023  case '4':
1024  case '8':
1025  blackbits++;
1026  totalbits += 4;
1027  break;
1028  case '3':
1029  case '5':
1030  case '6':
1031  case '9':
1032  case 'a':
1033  case 'A':
1034  case 'c':
1035  case 'C':
1036  blackbits += 2;
1037  totalbits += 4;
1038  break;
1039  case '7':
1040  case 'b':
1041  case 'B':
1042  case 'd':
1043  case 'D':
1044  case 'e':
1045  case 'E':
1046  blackbits += 3;
1047  totalbits += 4;
1048  break;
1049  case 'f':
1050  case 'F':
1051  blackbits += 4;
1052  totalbits += 4;
1053  break;
1054  case ' ':
1055  break;
1056  default:
1057  /* error */
1058  break;
1059  }
1060  cp++;
1061  }
1062  graylevel = 1.0 - ((double) blackbits / (double) totalbits);
1063  shade_next = GRAY;
1064 }
1065 
1066 static void ps_rotate(cp)
1067 char *cp;
1068 {
1069  int x, y;
1070  float angle;
1071 
1072  if (sscanf(cp, "%d %d %f", &x, &y, &angle) != 3) {
1073  Warning("Illegal format for rt: %s", cp);
1074  return;
1075  }
1076  dev_initfont();
1077  if (angle == 0 && is_rotated) {
1078  EMIT(outfp, "currentpoint grestore moveto\n");
1079  is_rotated = FALSE;
1080  } else {
1081  if (is_rotated)
1082  EMIT(outfp, "currentpoint grestore moveto\n");
1083  else
1084  is_rotated = TRUE;
1085  EMIT(outfp, "gsave currentpoint %d add exch %d add exch 2 copy\n",
1086  yconv(y), xconv(x));
1087  EMIT(outfp, "translate %f rotate neg exch neg exch translate\n",
1088  angle * RADTODEG);
1089  }
1090 }
1091 
1092 static void ps_setrgbcolor(cp)
1093 char *cp;
1094 {
1095  float r, g, b;
1096 
1097  (void)sscanf(cp, "%f %f %f", &r, &g, &b);
1098  EMIT(outfp, "%f %f %f @RGB\n", r, g, b);
1099 }
1100 
1101 static void ps_sethsbcolor(cp)
1102 char *cp;
1103 {
1104  float h, s, b;
1105 
1106  (void)sscanf(cp, "%f %f %f", &h, &s, &b);
1107  EMIT(outfp, "%f %f %f @HSB\n", h, s, b);
1108 }
1109 
1110 static void ps_setcmykcolor(cp)
1111 char *cp;
1112 {
1113  float c, m, y, k;
1114 
1115  (void)sscanf(cp, "%f %f %f %f", &c, &m, &y, &k);
1116  EMIT(outfp, "%f %f %f %f @CMYK\n", c, m, y, k);
1117 }
cp
Definition: action.c:1035
q
Definition: afm2pl.c:2287
double ury
Definition: aftopl.c:56
double urx
Definition: aftopl.c:55
double lly
Definition: aftopl.c:54
FILE * outfp
Definition: aftopl.c:22
double llx
Definition: aftopl.c:53
#define vsize
Definition: aptex-macros.h:900
#define mag
Definition: aptex-macros.h:802
#define n
Definition: t4ht.c:1290
#define b
Definition: jpegint.h:372
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
void Warning(const char *sb1, const char *sb2)
Definition: detex.c:4677
#define F_OK
Definition: defs.h:34
int w
Definition: dviconv.c:26
int v
Definition: dviconv.c:10
int h
Definition: dviconv.c:9
void Fatal()
char * alloc_check()
#define fopen
Definition: xxstdio.h:21
#define fgets
Definition: xxstdio.h:29
int __BOOLEAN__
Definition: defs.h:174
__BOOLEAN__ landscape
Definition: global.h:129
static int dist()
__BOOLEAN__ usescolor
Definition: psspecial.c:49
static void ps_rotate()
int splinex[5000]
Definition: psspecial.c:897
#define MAXPOINTS
Definition: psspecial.c:28
static void ps_shade()
static struct bangspecial ** nextbs
Definition: psspecial.c:58
static double graylevel
Definition: psspecial.c:37
double cos()
static int is_rotated
Definition: psspecial.c:46
static void ps_sethsbcolor()
static void pop_location()
Definition: psspecial.c:694
static void ps_flushspline()
static void set_pen_size()
Definition: psspecial.c:724
static void ps_blacken()
Definition: psspecial.c:984
#define TWOPI
Definition: psspecial.c:27
static int xx[600]
Definition: psspecial.c:35
char KeyStr[257]
Definition: psspecial.c:517
static void ps_pensize()
KeyDesc KeyTab[]
Definition: psspecial.c:87
static int yy[600]
Definition: psspecial.c:35
static void ps_drawto()
static void ps_whiten()
Definition: psspecial.c:975
static void ps_flushpath()
#define skipblank(p)
Definition: psspecial.c:51
dev_outbangspecials()
Definition: psspecial.c:232
static void ps_setcmykcolor()
ValTyp
Definition: psspecial.c:65
@ Integer
Definition: psspecial.c:66
@ Dimension
Definition: psspecial.c:66
@ None
Definition: psspecial.c:66
@ String
Definition: psspecial.c:66
@ Number
Definition: psspecial.c:66
#define BLACK
Definition: psspecial.c:40
static void ps_setrgbcolor()
#define WHITE
Definition: psspecial.c:42
char ValStr[257]
Definition: psspecial.c:518
#define NOFILL
Definition: psspecial.c:39
static void draw_line()
static void ps_flushdashedpath()
int splinelen
Definition: psspecial.c:897
#define RADTODEG
Definition: psspecial.c:30
__BOOLEAN__ scanfile(char *str, float *llx, float *lly, float *urx, float *ury)
Definition: psspecial.c:638
int IsSame()
void dev_predospecial(char *str, int n)
Definition: psspecial.c:110
char ToLower(char c)
Definition: psspecial.c:618
double sin()
#define yconv(y)
Definition: psspecial.c:33
double sqrt()
int GetKeyVal()
void dev_dospecial(char *str, int n)
Definition: psspecial.c:249
static int shade_next
Definition: psspecial.c:45
static void ps_arc()
__BOOLEAN__ usesspecial
Definition: psspecial.c:48
static void do_attributes()
Definition: psspecial.c:733
int spliney[5000]
Definition: psspecial.c:897
static int pensize
Definition: psspecial.c:36
#define SPLINEPOINTS
Definition: psspecial.c:29
static struct bangspecial * bangspecials
Definition: psspecial.c:57
#define GRAY
Definition: psspecial.c:41
#define EPSFILE
Definition: psspecial.c:85
#define NKEYS
Definition: psspecial.c:106
static void push_location()
Definition: psspecial.c:686
char * GetKeyStr()
#define xconv(x)
Definition: psspecial.c:32
static void ps_texture()
static int pathlen
Definition: psspecial.c:35
char * strncpy()
int strcmp()
Definition: coll.cpp:143
int sscanf()
char * strcpy()
#define EMIT
Definition: emit.h:2
#define EMITC(c)
Definition: emit.h:13
#define EMITS(s)
Definition: emit.h:4
static void
Definition: fpif.c:118
#define STRSIZE
mpz_t * f
Definition: gen-fib.c:34
#define xp
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
unsigned int Dimension
Definition: gf2pbm.c:43
#define c(n)
Definition: gpos-common.c:150
#define a(n)
Definition: gpos-common.c:148
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
kerning y
Definition: ttdriver.c:212
#define hsize
Definition: gd_gif_out.c:57
end_string(void)
Definition: dvi.c:309
dev_initfont(void)
Definition: dvi.c:186
dev_setposn(int x, int y)
Definition: dvi.c:255
#define fclose
Definition: debug.h:100
#define access
Definition: win32lib.h:59
static const char * tab[]
Definition: xdirtest.c:23
#define malloc
Definition: alloca.c:91
int strncmp()
static boolean dotted(short n)
Definition: mtx.c:54
angle
Definition: cordic.py:17
float x
Definition: cordic.py:15
int k
Definition: otp-parser.c:70
#define t1
#define t3
#define t2
real tno[600]
Definition: pmxab.c:87
static int background
Definition: pngtopnm.c:71
static int size
Definition: ppmlabel.c:24
int g
Definition: ppmqvga.c:68
int r
Definition: ppmqvga.c:68
void pushcolor(p, outtops)
Definition: pscolor.c:130
void popcolor(outtops)
Definition: pscolor.c:148
void resetcolorstack(p, outtops)
Definition: pscolor.c:170
ps_scanifont(char *str)
Definition: psifont.c:12
#define x1
#define y1
#define y2
#define x2
@ ps_string
Definition: sd.h:146
#define tolower(ch)
Definition: utype.h:137
#define isupper(ch)
Definition: utype.h:80
#define str(s)
Definition: sh6.c:399
char * Entry
Definition: psspecial.c:80
ValTyp Type
Definition: psspecial.c:81
ValTyp vt
Definition: psspecial.c:72
float n
Definition: psspecial.c:75
union KeyWord::@100 v
char * Val
Definition: psspecial.c:71
char * Key
Definition: psspecial.c:70
int i
Definition: psspecial.c:74
A string of characters.
Definition: t1part.c:49
struct bangspecial * bs_next
Definition: psspecial.c:54
char bs_string[1]
Definition: psspecial.c:55
Definition: utils.c:300
Definition: tfmaux.c:31
Definition: dvips.h:235
#define FILE
Definition: t1stdio.h:34
int j
Definition: t4ht.c:1589
*job_name strlen((char *) job_name) - 4)
long unsigned N
Definition: tex4ht.c:2765
m
Definition: tex4ht.c:3990
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
void ps_createpipe()
void ps_copyfigfile()
void ps_add_include(char *str)
Definition: psio.c:26
int nt
Definition: tfmread.c:8
#define BUFSIZ
Definition: ps.c:61