1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 
5 #include <stdio.h>
6 #include <stdarg.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <assert.h>
10 
11 #include "global.h"
12 #include "data.h"
13 #include "misc.h"
14 #include "pcb-printf.h"
15 
16 #include "hid.h"
17 #include "hid_draw.h"
18 #include "../hidint.h"
19 #include "hid/common/hidnogui.h"
20 #include "hid/common/draw_helpers.h"
21 #include "../ps/ps.h"
22 #include "hid/common/hidinit.h"
23 
24 #ifdef HAVE_LIBDMALLOC
25 #include <dmalloc.h>
26 #endif
27 
28 #define CRASH fprintf(stderr, "HID error: pcb called unimplemented EPS function %s.\n", __FUNCTION__); abort()
29 
30 /*----------------------------------------------------------------------------*/
31 /* Function prototypes                                                        */
32 /*----------------------------------------------------------------------------*/
33 static HID_Attribute * eps_get_export_options (int *n);
34 static void eps_do_export (HID_Attr_Val * options);
35 static void eps_parse_arguments (int *argc, char ***argv);
36 static int eps_set_layer (const char *name, int group, int empty);
37 static hidGC eps_make_gc (void);
38 static void eps_destroy_gc (hidGC gc);
39 static void eps_use_mask (enum mask_mode mode);
40 static void eps_set_color (hidGC gc, const char *name);
41 static void eps_set_line_cap (hidGC gc, EndCapStyle style);
42 static void eps_set_line_width (hidGC gc, Coord width);
43 static void eps_set_draw_xor (hidGC gc, int _xor);
44 static void eps_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
45 static void eps_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
46 static void eps_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle delta_angle);
47 static void eps_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
48 static void eps_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius);
49 static void eps_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y);
50 static void eps_calibrate (double xval, double yval);
51 static void eps_set_crosshair (int x, int y, int action);
52 /*----------------------------------------------------------------------------*/
53 
54 typedef struct hid_gc_struct
55 {
56   EndCapStyle cap;
57   Coord width;
58   int color;
59   int erase;
60 } hid_gc_struct;
61 
62 static HID eps_hid;
63 static HID_DRAW eps_graphics;
64 
65 static FILE *f = 0;
66 static Coord linewidth = -1;
67 static int lastcap = -1;
68 static int lastcolor = -1;
69 static int print_group[MAX_GROUP];
70 static int print_layer[MAX_ALL_LAYER];
71 static int fast_erase = -1;
72 
73 static HID_Attribute eps_attribute_list[] = {
74   /* other HIDs expect this to be first.  */
75 
76 /* %start-doc options "92 Encapsulated Postscript Export"
77 @ftable @code
78 @item --eps-file <string>
79 Name of the encapsulated postscript output file. Can contain a path.
80 @end ftable
81 %end-doc
82 */
83   {"eps-file", "Encapsulated Postscript output file",
84    HID_String, 0, 0, {0, 0, 0}, 0, 0},
85 #define HA_psfile 0
86 
87 /* %start-doc options "92 Encapsulated Postscript Export"
88 @ftable @code
89 @item --eps-scale <num>
90 Scale EPS output by the parameter @samp{num}.
91 @end ftable
92 %end-doc
93 */
94   {"eps-scale", "EPS scale",
95    HID_Real, 0, 100, {0, 0, 1.0}, 0, 0},
96 #define HA_scale 1
97 
98 /* %start-doc options "92 Encapsulated Postscript Export"
99 @ftable @code
100 @cindex screen-layer-order (EPS)
101 @item --screen-layer-order
102 Export layers as shown on screen.
103 @end ftable
104 %end-doc
105 */
106   {"screen-layer-order", "Export layers in the order shown on screen",
107    HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
108 #define HA_as_shown 2
109 
110 /* %start-doc options "92 Encapsulated Postscript Export"
111 @ftable @code
112 @item --monochrome
113 Convert output to monochrome.
114 @end ftable
115 %end-doc
116 */
117   {"monochrome", "Convert to monochrome",
118    HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
119 #define HA_mono 3
120 
121 /* %start-doc options "92 Encapsulated Postscript Export"
122 @ftable @code
123 @cindex only-visible
124 @item --only-visible
125 Limit the bounds of the EPS file to the visible items.
126 @end ftable
127 %end-doc
128 */
129   {"only-visible", "Limit the bounds of the EPS file to the visible items",
130    HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
131 #define HA_only_visible 4
132 };
133 
134 #define NUM_OPTIONS (sizeof(eps_attribute_list)/sizeof(eps_attribute_list[0]))
135 
REGISTER_ATTRIBUTES(eps_attribute_list)136 REGISTER_ATTRIBUTES (eps_attribute_list)
137 
138 static HID_Attr_Val eps_values[NUM_OPTIONS];
139 
140 static HID_Attribute *
141 eps_get_export_options (int *n)
142 {
143   static char *last_made_filename = 0;
144 
145   if (PCB) derive_default_filename(PCB->Filename, &eps_attribute_list[HA_psfile], ".eps", &last_made_filename);
146 
147   if (n)
148     *n = NUM_OPTIONS;
149   return eps_attribute_list;
150 }
151 
152 static int top_group, bottom_group;
153 
154 static int
layer_stack_sort(const void * va,const void * vb)155 layer_stack_sort (const void *va, const void *vb)
156 {
157   int a_layer = *(int *) va;
158   int b_layer = *(int *) vb;
159   int a_group = GetLayerGroupNumberByNumber (a_layer);
160   int b_group = GetLayerGroupNumberByNumber (b_layer);
161   int aside = (a_group == bottom_group ? 0 : a_group == top_group ? 2 : 1);
162   int bside = (b_group == bottom_group ? 0 : b_group == top_group ? 2 : 1);
163 
164   if (bside != aside)
165     return bside - aside;
166 
167   if (b_group != a_group)
168     return b_group - a_group;
169 
170   return b_layer - a_layer;
171 }
172 
173 static const char *filename;
174 static BoxType *bounds;
175 static int in_mono, as_shown;
176 
177 void
eps_hid_export_to_file(FILE * the_file,HID_Attr_Val * options)178 eps_hid_export_to_file (FILE * the_file, HID_Attr_Val * options)
179 {
180   int i;
181   static int saved_layer_stack[MAX_LAYER];
182   BoxType region;
183   FlagType save_thindraw;
184 
185   save_thindraw = PCB->Flags;
186   CLEAR_FLAG(THINDRAWFLAG, PCB);
187   CLEAR_FLAG(THINDRAWPOLYFLAG, PCB);
188   CLEAR_FLAG(CHECKPLANESFLAG, PCB);
189 
190   f = the_file;
191 
192   region.X1 = 0;
193   region.Y1 = 0;
194   region.X2 = PCB->MaxWidth;
195   region.Y2 = PCB->MaxHeight;
196 
197   if (options[HA_only_visible].int_value)
198     bounds = GetDataBoundingBox (PCB->Data);
199   else
200     bounds = &region;
201 
202   memset (print_group, 0, sizeof (print_group));
203   memset (print_layer, 0, sizeof (print_layer));
204 
205   /* Figure out which layers actually have stuff on them.  */
206   for (i = 0; i < max_copper_layer; i++)
207     {
208       LayerType *layer = PCB->Data->Layer + i;
209       if (layer->On)
210 	if (layer->LineN || layer->TextN || layer->ArcN || layer->PolygonN)
211 	  print_group[GetLayerGroupNumberByNumber (i)] = 1;
212     }
213 
214   /* Now, if only one layer has real stuff on it, we can use the fast
215      erase logic.  Otherwise, we have to use the expensive multi-mask
216      erase.  */
217   fast_erase = 0;
218   for (i = 0; i < max_group; i++)
219     if (print_group[i])
220       fast_erase ++;
221 
222   /* If NO layers had anything on them, at least print the component
223      layer to get the pins.  */
224   if (fast_erase == 0)
225     {
226       print_group[GetLayerGroupNumberBySide (TOP_SIDE)] = 1;
227       fast_erase = 1;
228     }
229 
230   /* "fast_erase" is 1 if we can just paint white to erase.  */
231   fast_erase = fast_erase == 1 ? 1 : 0;
232 
233   /* Now, for each group we're printing, mark its layers for
234      printing.  */
235   for (i = 0; i < max_copper_layer; i++)
236     if (print_group[GetLayerGroupNumberByNumber (i)])
237       print_layer[i] = 1;
238 
239   if (fast_erase) {
240     eps_hid.poly_before = 1;
241     eps_hid.poly_after = 0;
242   } else {
243     eps_hid.poly_before = 0;
244     eps_hid.poly_after = 1;
245   }
246 
247   memcpy (saved_layer_stack, LayerStack, sizeof (LayerStack));
248   as_shown = options[HA_as_shown].int_value;
249   if (!options[HA_as_shown].int_value)
250     {
251       top_group = GetLayerGroupNumberBySide (TOP_SIDE);
252       bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE);
253       qsort (LayerStack, max_copper_layer, sizeof (LayerStack[0]), layer_stack_sort);
254     }
255   fprintf (f, "%%!PS-Adobe-3.0 EPSF-3.0\n");
256   linewidth = -1;
257   lastcap = -1;
258   lastcolor = -1;
259 
260   in_mono = options[HA_mono].int_value;
261 
262 #define pcb2em(x) 1 + COORD_TO_INCH (x) * 72.0 * options[HA_scale].real_value
263   fprintf (f, "%%%%BoundingBox: 0 0 %lli %lli\n",
264 	   llrint (pcb2em (bounds->X2 - bounds->X1)),
265 	   llrint (pcb2em (bounds->Y2 - bounds->Y1)) );
266   fprintf (f, "%%%%HiResBoundingBox: 0.000000 0.000000 %.6f %.6f\n",
267 	   pcb2em (bounds->X2 - bounds->X1),
268 	   pcb2em (bounds->Y2 - bounds->Y1));
269 #undef pcb2em
270   fprintf (f, "%%%%Pages: 1\n");
271   fprintf (f,
272 	   "save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def\n");
273   fprintf (f, "%%%%EndProlog\n");
274   fprintf (f, "%%%%Page: 1 1\n");
275   fprintf (f, "%%%%BeginDocument: %s\n\n", filename);
276 
277   fprintf (f, "72 72 scale\n");
278   fprintf (f, "1 dup neg scale\n");
279   fprintf (f, "%g dup scale\n", options[HA_scale].real_value);
280   pcb_fprintf (f, "%mi %mi translate\n", -bounds->X1, -bounds->Y2);
281   if (options[HA_as_shown].int_value && Settings.ShowBottomSide)
282     pcb_fprintf (f, "-1 1 scale %mi 0 translate\n", bounds->X1 - bounds->X2);
283   linewidth = -1;
284   lastcap = -1;
285   lastcolor = -1;
286 #define Q (Coord) MIL_TO_COORD(10)
287   pcb_fprintf (f,
288 	   "/nclip { %mi %mi moveto %mi %mi lineto %mi %mi lineto %mi %mi lineto %mi %mi lineto eoclip newpath } def\n",
289 	   bounds->X1 - Q, bounds->Y1 - Q, bounds->X1 - Q, bounds->Y2 + Q,
290 	   bounds->X2 + Q, bounds->Y2 + Q, bounds->X2 + Q, bounds->Y1 - Q,
291 	   bounds->X1 - Q, bounds->Y1 - Q);
292 #undef Q
293   fprintf (f, "/t { moveto lineto stroke } bind def\n");
294   fprintf (f, "/tc { moveto lineto strokepath nclip } bind def\n");
295   fprintf (f, "/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n");
296   fprintf (f,
297 	   "     x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def\n");
298   fprintf (f, "/c { 0 360 arc fill } bind def\n");
299   fprintf (f, "/cc { 0 360 arc nclip } bind def\n");
300   fprintf (f,
301 	   "/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def\n");
302 
303   hid_expose_callback (&eps_hid, bounds, 0);
304 
305   fprintf (f, "showpage\n");
306 
307   fprintf (f, "%%%%EndDocument\n");
308   fprintf (f, "%%%%Trailer\n");
309   fprintf (f, "cleartomark countdictstack exch sub { end } repeat restore\n");
310   fprintf (f, "%%%%EOF\n");
311 
312   memcpy (LayerStack, saved_layer_stack, sizeof (LayerStack));
313   PCB->Flags = save_thindraw;
314 }
315 
316 static void
eps_do_export(HID_Attr_Val * options)317 eps_do_export (HID_Attr_Val * options)
318 {
319   int i;
320   int save_ons[MAX_ALL_LAYER];
321 
322   if (!options)
323     {
324       eps_get_export_options (0);
325       for (i = 0; i < NUM_OPTIONS; i++)
326 	eps_values[i] = eps_attribute_list[i].default_val;
327       options = eps_values;
328     }
329 
330   filename = options[HA_psfile].str_value;
331   if (!filename)
332     filename = "pcb-out.eps";
333 
334   f = fopen (filename, "w");
335   if (!f)
336     {
337       perror (filename);
338       return;
339     }
340 
341   if (!options[HA_as_shown].int_value)
342     hid_save_and_show_layer_ons (save_ons);
343   eps_hid_export_to_file (f, options);
344   if (!options[HA_as_shown].int_value)
345     hid_restore_layer_ons (save_ons);
346 
347   fclose (f);
348 }
349 
350 static void
eps_parse_arguments(int * argc,char *** argv)351 eps_parse_arguments (int *argc, char ***argv)
352 {
353   hid_register_attributes (eps_attribute_list,
354 			   sizeof (eps_attribute_list) /
355 			   sizeof (eps_attribute_list[0]));
356   hid_parse_command_line (argc, argv);
357 }
358 
359 static int is_mask;
360 static int is_paste;
361 static int is_drill;
362 
363 static int
eps_set_layer(const char * name,int group,int empty)364 eps_set_layer (const char *name, int group, int empty)
365 {
366   int idx = (group >= 0
367 	     && group <
368 	     max_group) ? PCB->LayerGroups.Entries[group][0] : group;
369   if (name == 0)
370     name = PCB->Data->Layer[idx].Name;
371 
372   if (idx >= 0 && idx < max_copper_layer && !print_layer[idx])
373     return 0;
374   if (SL_TYPE (idx) == SL_ASSY || SL_TYPE (idx) == SL_FAB)
375     return 0;
376 
377   if (strcmp (name, "invisible") == 0)
378     return 0;
379 
380   is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL);
381   is_mask = (SL_TYPE (idx) == SL_MASK);
382   is_paste = (SL_TYPE (idx) == SL_PASTE);
383 
384   if (is_mask || is_paste)
385     return 0;
386 #if 0
387   printf ("Layer %s group %d drill %d mask %d\n", name, group, is_drill,
388 	  is_mask);
389 #endif
390   fprintf (f, "%% Layer %s group %d drill %d mask %d\n", name, group,
391 	   is_drill, is_mask);
392 
393   if (as_shown)
394     {
395       switch (idx)
396 	{
397 	case SL (SILK, TOP):
398 	case SL (SILK, BOTTOM):
399 	  if (SL_MYSIDE (idx))
400 	    return PCB->ElementOn;
401 	  else
402 	    return 0;
403 	}
404     }
405   else
406     {
407       switch (idx)
408 	{
409 	case SL (SILK, TOP):
410 	  return 1;
411 	case SL (SILK, BOTTOM):
412 	  return 0;
413 	}
414     }
415 
416   return 1;
417 }
418 
419 static hidGC
eps_make_gc(void)420 eps_make_gc (void)
421 {
422   hidGC rv = (hidGC) malloc (sizeof (hid_gc_struct));
423   rv->cap = Trace_Cap;
424   rv->width = 0;
425   rv->color = 0;
426   return rv;
427 }
428 
429 static void
eps_destroy_gc(hidGC gc)430 eps_destroy_gc (hidGC gc)
431 {
432   free (gc);
433 }
434 
435 static void
eps_use_mask(enum mask_mode mode)436 eps_use_mask (enum mask_mode mode)
437 {
438   static int mask_pending = 0;
439   switch (mode)
440     {
441     case HID_MASK_CLEAR:
442       if (!mask_pending)
443 	{
444 	  mask_pending = 1;
445 	  fprintf (f, "gsave\n");
446 	}
447       break;
448     case HID_MASK_BEFORE:
449     case HID_MASK_AFTER:
450       break;
451     case HID_MASK_OFF:
452       if (mask_pending)
453 	{
454 	  mask_pending = 0;
455 	  fprintf (f, "grestore\n");
456 	  lastcolor = -1;
457 	}
458       break;
459     }
460 }
461 
462 static void
eps_set_color(hidGC gc,const char * name)463 eps_set_color (hidGC gc, const char *name)
464 {
465   static void *cache = 0;
466   hidval cval;
467 
468   if (strcmp (name, "erase") == 0)
469     {
470       gc->color = 0xffffff;
471       gc->erase = fast_erase ? 0 : 1;
472       return;
473     }
474   if (strcmp (name, "drill") == 0)
475     {
476       gc->color = 0xffffff;
477       gc->erase = 0;
478       return;
479     }
480   gc->erase = 0;
481   if (hid_cache_color (0, name, &cval, &cache))
482     {
483       gc->color = cval.lval;
484     }
485   else if (in_mono)
486     {
487       gc->color = 0;
488     }
489   else if (name[0] == '#')
490     {
491       unsigned int r, g, b;
492       sscanf (name + 1, "%2x%2x%2x", &r, &g, &b);
493       gc->color = (r << 16) + (g << 8) + b;
494     }
495   else
496     gc->color = 0;
497 }
498 
499 static void
eps_set_line_cap(hidGC gc,EndCapStyle style)500 eps_set_line_cap (hidGC gc, EndCapStyle style)
501 {
502   gc->cap = style;
503 }
504 
505 static void
eps_set_line_width(hidGC gc,Coord width)506 eps_set_line_width (hidGC gc, Coord width)
507 {
508   gc->width = width;
509 }
510 
511 static void
eps_set_draw_xor(hidGC gc,int xor_)512 eps_set_draw_xor (hidGC gc, int xor_)
513 {
514   ;
515 }
516 
517 static void
use_gc(hidGC gc)518 use_gc (hidGC gc)
519 {
520   if (linewidth != gc->width)
521     {
522       pcb_fprintf (f, "%mi setlinewidth\n", gc->width);
523       linewidth = gc->width;
524     }
525   if (lastcap != gc->cap)
526     {
527       int c;
528       switch (gc->cap)
529 	{
530 	case Round_Cap:
531 	case Trace_Cap:
532 	  c = 1;
533 	  break;
534 	default:
535 	case Square_Cap:
536 	  c = 2;
537 	  break;
538 	}
539       fprintf (f, "%d setlinecap\n", c);
540       lastcap = gc->cap;
541     }
542   if (lastcolor != gc->color)
543     {
544       int c = gc->color;
545 #define CV(x,b) (((x>>b)&0xff)/255.0)
546       fprintf (f, "%g %g %g setrgbcolor\n", CV (c, 16), CV (c, 8), CV (c, 0));
547       lastcolor = gc->color;
548     }
549 }
550 
551 static void eps_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
552 static void eps_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius);
553 
554 static void
eps_draw_rect(hidGC gc,Coord x1,Coord y1,Coord x2,Coord y2)555 eps_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
556 {
557   use_gc (gc);
558   pcb_fprintf (f, "%mi %mi %mi %mi r\n", x1, y1, x2, y2);
559 }
560 
561 static void
eps_draw_line(hidGC gc,Coord x1,Coord y1,Coord x2,Coord y2)562 eps_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
563 {
564   Coord w = gc->width / 2;
565   if (x1 == x2 && y1 == y2)
566     {
567       if (gc->cap == Square_Cap)
568 	eps_fill_rect (gc, x1 - w, y1 - w, x1 + w, y1 + w);
569       else
570 	eps_fill_circle (gc, x1, y1, w);
571       return;
572     }
573   use_gc (gc);
574   if (gc->erase && gc->cap != Square_Cap)
575     {
576       double ang = atan2 (y2 - y1, x2 - x1);
577       double dx = w * sin (ang);
578       double dy = -w * cos (ang);
579       double deg = ang * 180.0 / M_PI;
580       Coord vx1 = x1 + dx;
581       Coord vy1 = y1 + dy;
582 
583       pcb_fprintf (f, "%mi %mi moveto ", vx1, vy1);
584       pcb_fprintf (f, "%mi %mi %mi %g %g arc\n", x2, y2, w, deg - 90, deg + 90);
585       pcb_fprintf (f, "%mi %mi %mi %g %g arc\n", x1, y1, w, deg + 90, deg + 270);
586       fprintf (f, "nclip\n");
587 
588       return;
589     }
590   pcb_fprintf (f, "%mi %mi %mi %mi %s\n", x1, y1, x2, y2, gc->erase ? "tc" : "t");
591 }
592 
593 static void
eps_draw_arc(hidGC gc,Coord cx,Coord cy,Coord width,Coord height,Angle start_angle,Angle delta_angle)594 eps_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
595 	      Angle start_angle, Angle delta_angle)
596 {
597   Angle sa, ea;
598   if (delta_angle > 0)
599     {
600       sa = start_angle;
601       ea = start_angle + delta_angle;
602     }
603   else
604     {
605       sa = start_angle + delta_angle;
606       ea = start_angle;
607     }
608 #if 0
609   printf ("draw_arc %d,%d %dx%d %d..%d %d..%d\n",
610 	  cx, cy, width, height, start_angle, delta_angle, sa, ea);
611 #endif
612   use_gc (gc);
613   pcb_fprintf (f, "%ma %ma %mi %mi %mi %mi %g a\n",
614 	   sa, ea, -width, height, cx, cy, (double) linewidth / width);
615 }
616 
617 static void
eps_fill_circle(hidGC gc,Coord cx,Coord cy,Coord radius)618 eps_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
619 {
620   use_gc (gc);
621   pcb_fprintf (f, "%mi %mi %mi %s\n", cx, cy, radius, gc->erase ? "cc" : "c");
622 }
623 
624 static void
eps_fill_polygon(hidGC gc,int n_coords,Coord * x,Coord * y)625 eps_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
626 {
627   int i;
628   char *op = "moveto";
629   use_gc (gc);
630   for (i = 0; i < n_coords; i++)
631     {
632       pcb_fprintf (f, "%mi %mi %s\n", x[i], y[i], op);
633       op = "lineto";
634     }
635   fprintf (f, "fill\n");
636 }
637 
638 static void
eps_fill_rect(hidGC gc,Coord x1,Coord y1,Coord x2,Coord y2)639 eps_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
640 {
641   use_gc (gc);
642   pcb_fprintf (f, "%mi %mi %mi %mi r\n", x1, y1, x2, y2);
643 }
644 
645 static void
eps_calibrate(double xval,double yval)646 eps_calibrate (double xval, double yval)
647 {
648   CRASH;
649 }
650 
651 static void
eps_set_crosshair(int x,int y,int action)652 eps_set_crosshair (int x, int y, int action)
653 {
654 }
655 
656 void
hid_eps_init()657 hid_eps_init ()
658 {
659   memset (&eps_hid, 0, sizeof (HID));
660   memset (&eps_graphics, 0, sizeof (HID_DRAW));
661 
662   common_nogui_init (&eps_hid);
663   common_draw_helpers_init (&eps_graphics);
664 
665   eps_hid.struct_size         = sizeof (HID);
666   eps_hid.name                = "eps";
667   eps_hid.description         = "Encapsulated Postscript";
668   eps_hid.exporter            = 1;
669   eps_hid.poly_after          = 1;
670 
671   eps_hid.get_export_options  = eps_get_export_options;
672   eps_hid.do_export           = eps_do_export;
673   eps_hid.parse_arguments     = eps_parse_arguments;
674   eps_hid.set_layer           = eps_set_layer;
675   eps_hid.calibrate           = eps_calibrate;
676   eps_hid.set_crosshair       = eps_set_crosshair;
677 
678   eps_hid.graphics            = &eps_graphics;
679 
680   eps_graphics.make_gc        = eps_make_gc;
681   eps_graphics.destroy_gc     = eps_destroy_gc;
682   eps_graphics.use_mask       = eps_use_mask;
683   eps_graphics.set_color      = eps_set_color;
684   eps_graphics.set_line_cap   = eps_set_line_cap;
685   eps_graphics.set_line_width = eps_set_line_width;
686   eps_graphics.set_draw_xor   = eps_set_draw_xor;
687   eps_graphics.draw_line      = eps_draw_line;
688   eps_graphics.draw_arc       = eps_draw_arc;
689   eps_graphics.draw_rect      = eps_draw_rect;
690   eps_graphics.fill_circle    = eps_fill_circle;
691   eps_graphics.fill_polygon   = eps_fill_polygon;
692   eps_graphics.fill_rect      = eps_fill_rect;
693 
694   hid_register_hid (&eps_hid);
695 }
696