1 /*
2  * gEDA - GNU Electronic Design Automation
3  * This file is a part of Gerbv.
4  *
5  *   Copyright (C) 2000-2003 Stefan Petersen (spe@stacken.kth.se)
6  *
7  * $Id$
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
22  */
23 
24 //! \example example1.c
25 //! \example example2.c
26 //! \example example3.c
27 //! \example example4.c
28 //! \example example5.c
29 //! \example example6.c
30 
31 //! \defgroup gerbv Gerbv
32 //! @{ Gerbv program @}
33 
34 //! \defgroup libgerbv libgerbv
35 //! @{ Gerber library @}
36 
37 /** \file gerbv.h
38     \brief The main header file for the libgerbv library
39     \ingroup libgerbv
40 */
41 
42 /**
43 \mainpage Gerbv/libgerbv Index Page
44 
45 \section intro_sec Introduction
46 
47 Gerbv is a program which can display, edit, export, and do other manipulation
48 of file formats used in PCB design (RS274X, Excellon drill, and
49 pick-and-place). The core library (libgerbv) is available as a separate
50 library, allowing other software to easily incorporate advanced Gerber
51 functionality.
52 
53 This code documentation is mainly intended to help explain the libgerbv API to
54 developers wishing to use libgerbv in his/her own projects. The easiest way to
55 learn to use libgerbv is by reading through and compiling the example source
56 files (click on "Examples" in the navigation tree in the left pane, or look in
57 the doc/example-code/ directory in CVS).
58 
59 For help with using the standalone Gerbv software, please refer to the man page
60 (using the command "man gerbv") or go to the Gerbv homepage for documentation
61 (http://gerbv.geda-project.org).
62 
63 */
64 
65 #ifndef __GERBV_H__
66 #define __GERBV_H__
67 
68 #if defined(__cplusplus)
69 extern "C" {
70 #endif
71 
72 #ifdef HAVE_CONFIG_H
73 # include "config.h"
74 #endif
75 
76 #include <glib.h>
77 #include <gtk/gtk.h>
78 #include <gdk/gdk.h>
79 #include <gdk/gdkkeysyms.h>
80 
81 #ifndef RENDER_USING_GDK
82 # include <cairo.h>
83 #endif
84 
85 #define APERTURE_MIN 10
86 #define APERTURE_MAX 9999
87 
88 /*
89  * Maximum number of aperture parameters is set by the outline aperture
90  * macro. There (p. 28) is defined up to 50 points in polygon.
91  * So 50 points with x and y plus two for holding extra data gives...
92  */
93 #define APERTURE_PARAMETERS_MAX 102
94 #define GERBV_SCALE_MIN 10
95 #define GERBV_SCALE_MAX 3000
96 #define MAX_ERRMSGLEN 25
97 #define MAX_COORDLEN 28
98 #define MAX_DISTLEN 180
99 #define MAX_STATUSMSGLEN (MAX_ERRMSGLEN+MAX_COORDLEN+MAX_DISTLEN)
100 
101 /*
102  * Files only have a limited precision in their data, so when interpreting
103  * layer rotations or linear size that have been read from a project file, we
104  * have to tolerate a certain amount of error.
105  */
106 #define GERBV_PRECISION_ANGLE_RAD	1e-6
107 #define GERBV_PRECISION_LINEAR_INCH	1e-6
108 
109 /* Macros to convert between unscaled gerber coordinates and other units */
110 /* XXX NOTE: Currently unscaled units are assumed as inch, this is not
111    XXX necessarily true for all files */
112 #define COORD2INS(c) (c)
113 #define COORD2MILS(c) ((c)*1000.0)
114 #define COORD2MMS(c) ((c)*25.4)
115 
116 #define DEG2RAD(d) ((d)*M_PI/180.0)
117 #define RAD2DEG(r) ((r)*180.0*M_1_PI)
118 
119 #define GERB_FATAL_ERROR(...) g_log(NULL, G_LOG_LEVEL_ERROR, __VA_ARGS__)
120 #define GERB_COMPILE_ERROR(...)  g_log(NULL, G_LOG_LEVEL_CRITICAL, __VA_ARGS__)
121 #define GERB_COMPILE_WARNING(...)  g_log(NULL, G_LOG_LEVEL_WARNING, __VA_ARGS__)
122 #define GERB_MESSAGE(...)  g_log(NULL, G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
123 
124 /*! The aperture macro commands */
125 typedef enum {GERBV_OPCODE_NOP, /*!< no operation */
126 	      GERBV_OPCODE_PUSH, /*!< push the instruction onto the stack */
127 	      GERBV_OPCODE_PPUSH, /*!< push parameter onto stack */
128 	      GERBV_OPCODE_PPOP, /*!< pop parameter from stack */
129 	      GERBV_OPCODE_ADD, /*!< mathmatical add operation */
130 	      GERBV_OPCODE_SUB, /*!< mathmatical subtract operation */
131 	      GERBV_OPCODE_MUL, /*!< mathmatical multiply operation */
132 	      GERBV_OPCODE_DIV, /*!< mathmatical divide operation */
133 	      GERBV_OPCODE_PRIM /*!< draw macro primative */
134 } gerbv_opcodes_t;
135 
136 /*! The different message types used in libgerbv */
137 typedef enum {GERBV_MESSAGE_FATAL, /*!< processing cannot continue */
138 		GERBV_MESSAGE_ERROR, /*!< something went wrong, but processing can still continue */
139 		GERBV_MESSAGE_WARNING, /*!< something was encountered that may provide the wrong output */
140 		GERBV_MESSAGE_NOTE /*!< an irregularity was encountered, but needs no intervention */
141 } gerbv_message_type_t;
142 
143 /*! The different aperture types available.
144  *  Please keep these in sync with the aperture names defined in
145  *  gerbv_aperture_type_name() in gerbv.c */
146 typedef enum {
147 		GERBV_APTYPE_NONE, /*!< no aperture used */
148 		GERBV_APTYPE_CIRCLE, /*!< a round aperture */
149 		GERBV_APTYPE_RECTANGLE, /*!< a rectangular aperture */
150 		GERBV_APTYPE_OVAL, /*!< an ovular (obround) aperture */
151 		GERBV_APTYPE_POLYGON, /*!< a polygon aperture */
152 		GERBV_APTYPE_MACRO, /*!< a RS274X macro */
153 			GERBV_APTYPE_MACRO_CIRCLE, /*!< a RS274X circle macro */
154 			GERBV_APTYPE_MACRO_OUTLINE, /*!< a RS274X outline macro */
155 			GERBV_APTYPE_MACRO_POLYGON, /*!< a RS274X polygon macro */
156 			GERBV_APTYPE_MACRO_MOIRE, /*!< a RS274X moire macro */
157 			GERBV_APTYPE_MACRO_THERMAL, /*!< a RS274X thermal macro */
158 			GERBV_APTYPE_MACRO_LINE20, /*!< a RS274X vector line (code 20) macro */
159 			GERBV_APTYPE_MACRO_LINE21, /*!< a RS274X centered line (code 21) macro */
160 			GERBV_APTYPE_MACRO_LINE22 /*!< a RS274X lower left line (code 22) macro */
161 } gerbv_aperture_type_t;
162 
163 const char *gerbv_aperture_type_name(gerbv_aperture_type_t type);
164 
165 /*! The current state of the aperture drawing tool */
166 typedef enum {GERBV_APERTURE_STATE_OFF, /*!< tool drawing is off, and nothing will be drawn */
167 		GERBV_APERTURE_STATE_ON, /*!< tool drawing is on, and something will be drawn */
168 		GERBV_APERTURE_STATE_FLASH /*!< tool is flashing, and will draw a single aperture */
169 } gerbv_aperture_state_t;
170 
171 /*! The circle aperture macro parameter indexes */
172 typedef enum {
173 		CIRCLE_EXPOSURE,
174 		CIRCLE_DIAMETER,
175 		CIRCLE_CENTER_X,
176 		CIRCLE_CENTER_Y,
177 } gerbv_aptype_macro_circle_index_t;
178 
179 typedef enum {
180 		OUTLINE_EXPOSURE,
181 		OUTLINE_NUMBER_OF_POINTS,
182 		OUTLINE_FIRST_X, /* x0 */
183 		OUTLINE_FIRST_Y, /* y0 */
184 		/* x1, y1, x2, y2, ..., rotation */
185 		OUTLINE_ROTATION, /* Rotation index is correct if outline has
186 				     no point except first */
187 } gerbv_aptype_macro_outline_index_t;
188 
189 /* Point number is from 0 (first) to (including) OUTLINE_NUMBER_OF_POINTS */
190 #define OUTLINE_X_IDX_OF_POINT(number) (2*(number) + OUTLINE_FIRST_X)
191 #define OUTLINE_Y_IDX_OF_POINT(number) (2*(number) + OUTLINE_FIRST_Y)
192 #define	OUTLINE_ROTATION_IDX(param_array) \
193 			((int)param_array[OUTLINE_NUMBER_OF_POINTS]*2 + \
194 			OUTLINE_ROTATION)
195 
196 typedef enum {
197 		POLYGON_EXPOSURE,
198 		POLYGON_NUMBER_OF_POINTS,
199 		POLYGON_CENTER_X,
200 		POLYGON_CENTER_Y,
201 		POLYGON_DIAMETER,
202 		POLYGON_ROTATION,
203 } gerbv_aptype_macro_polygon_index_t;
204 
205 typedef enum {
206 		MOIRE_CENTER_X,
207 		MOIRE_CENTER_Y,
208 		MOIRE_OUTSIDE_DIAMETER,
209 		MOIRE_CIRCLE_THICKNESS,
210 		MOIRE_GAP_WIDTH,
211 		MOIRE_NUMBER_OF_CIRCLES,
212 		MOIRE_CROSSHAIR_THICKNESS,
213 		MOIRE_CROSSHAIR_LENGTH,
214 		MOIRE_ROTATION,
215 } gerbv_aptype_macro_moire_index_t;
216 
217 typedef enum {
218 		THERMAL_CENTER_X,
219 		THERMAL_CENTER_Y,
220 		THERMAL_OUTSIDE_DIAMETER,
221 		THERMAL_INSIDE_DIAMETER,
222 		THERMAL_CROSSHAIR_THICKNESS,
223 		THERMAL_ROTATION,
224 } gerbv_aptype_macro_thermal_index_t;
225 
226 /*! The vector line aperture macro parameter indexes */
227 typedef enum {
228 		LINE20_EXPOSURE,
229 		LINE20_LINE_WIDTH,
230 		LINE20_WIDTH = LINE20_LINE_WIDTH,	/* Unification alias */
231 		LINE20_START_X,
232 		LINE20_START_Y,
233 		LINE20_END_X,
234 		LINE20_END_Y,
235 		LINE20_ROTATION,
236 } gerbv_aptype_macro_line20_index_t;
237 
238 /*! The centered line aperture macro parameter indexes */
239 typedef enum {
240 		LINE21_EXPOSURE,
241 		LINE21_WIDTH,
242 		LINE21_HEIGHT,
243 		LINE21_CENTER_X,
244 		LINE21_CENTER_Y,
245 		LINE21_ROTATION,
246 } gerbv_aptype_macro_line21_index_t;
247 
248 /*! The lower left line aperture macro parameter indexes */
249 typedef enum {
250 		LINE22_EXPOSURE,
251 		LINE22_WIDTH,
252 		LINE22_HEIGHT,
253 		LINE22_LOWER_LEFT_X,
254 		LINE22_LOWER_LEFT_Y,
255 		LINE22_ROTATION,
256 } gerbv_aptype_macro_line22_index_t;
257 
258 
259 /*! The current unit used */
260 typedef enum {GERBV_UNIT_INCH, /*!< inches */
261 		GERBV_UNIT_MM, /*!< mm */
262 		GERBV_UNIT_UNSPECIFIED /*!< use default units */
263 } gerbv_unit_t;
264 
265 /*! The different drawing polarities available */
266 typedef enum {GERBV_POLARITY_POSITIVE, /*!< draw "positive", using the current layer's polarity */
267 		GERBV_POLARITY_NEGATIVE, /*!< draw "negative", reversing the current layer's polarity */
268 		GERBV_POLARITY_DARK, /*!< add to the current rendering */
269 		GERBV_POLARITY_CLEAR /*!< subtract from the current rendering */
270 } gerbv_polarity_t;
271 
272 /*! The decimal point parsing style used */
273 typedef enum {GERBV_OMIT_ZEROS_LEADING, /*!< omit extra zeros before the decimal point */
274 		GERBV_OMIT_ZEROS_TRAILING, /*!< omit extra zeros after the decimal point */
275 		GERBV_OMIT_ZEROS_EXPLICIT, /*!< explicitly specify how many decimal places are used */
276 		GERBV_OMIT_ZEROS_UNSPECIFIED /*!< use the default parsing style */
277 } gerbv_omit_zeros_t;
278 
279 /*! The coordinate system used */
280 typedef enum {GERBV_COORDINATE_ABSOLUTE, /*!< all coordinates are absolute from a common origin */
281 		GERBV_COORDINATE_INCREMENTAL /*!< all coordinates are relative to the previous coordinate */
282 } gerbv_coordinate_t;
283 
284 /*! The interpolation methods available.
285  *  Please keep these in sync with the interpolation names defined in
286  *  gerbv_interpolation_name() in gerbv.c */
287 typedef enum {GERBV_INTERPOLATION_LINEARx1, /*!< draw a line */
288 		GERBV_INTERPOLATION_LINEARx10, /*!< draw a line */
289 		GERBV_INTERPOLATION_LINEARx01, /*!< draw a line */
290 		GERBV_INTERPOLATION_LINEARx001, /*!< draw a line */
291 		GERBV_INTERPOLATION_CW_CIRCULAR, /*!< draw an arc in the clockwise direction */
292 		GERBV_INTERPOLATION_CCW_CIRCULAR, /*!< draw an arc in the counter-clockwise direction */
293 		GERBV_INTERPOLATION_PAREA_START, /*!< start a polygon draw */
294 		GERBV_INTERPOLATION_PAREA_END, /*!< end a polygon draw */
295 		GERBV_INTERPOLATION_DELETED /*!< the net has been deleted by the user, and will not be drawn */
296 } gerbv_interpolation_t;
297 
298 /* For backward compatibility */
299 enum {GERBV_INTERPOLATION_x10 = GERBV_INTERPOLATION_LINEARx10};
300 
301 const char *gerbv_interpolation_name(gerbv_interpolation_t interp);
302 
303 typedef enum {GERBV_ENCODING_NONE,
304 		GERBV_ENCODING_ASCII,
305 		GERBV_ENCODING_EBCDIC,
306 		GERBV_ENCODING_BCD,
307 		GERBV_ENCODING_ISO_ASCII,
308 		GERBV_ENCODING_EIA
309 } gerbv_encoding_t;
310 
311 /*! The different layer types used */
312 typedef enum {
313 		GERBV_LAYERTYPE_RS274X, /*!< the file is a RS274X file */
314 		GERBV_LAYERTYPE_DRILL, /*!< the file is an Excellon drill file */
315 		GERBV_LAYERTYPE_PICKANDPLACE_TOP, /*!< the file is a CSV pick and place file, top side */
316 		GERBV_LAYERTYPE_PICKANDPLACE_BOT, /*!< the file is a CSV pick and place file, bottom side */
317 } gerbv_layertype_t;
318 
319 typedef enum {GERBV_KNOCKOUT_TYPE_NOKNOCKOUT,
320 		GERBV_KNOCKOUT_TYPE_FIXEDKNOCK,
321 		GERBV_KNOCKOUT_TYPE_BORDER
322 } gerbv_knockout_type_t;
323 
324 typedef enum {GERBV_MIRROR_STATE_NOMIRROR,
325 		GERBV_MIRROR_STATE_FLIPA,
326 		GERBV_MIRROR_STATE_FLIPB,
327 		GERBV_MIRROR_STATE_FLIPAB
328 } gerbv_mirror_state_t;
329 
330 typedef enum {GERBV_AXIS_SELECT_NOSELECT,
331 		GERBV_AXIS_SELECT_SWAPAB
332 } gerbv_axis_select_t;
333 
334 typedef enum {GERBV_JUSTIFY_NOJUSTIFY,
335 		GERBV_JUSTIFY_LOWERLEFT,
336 		GERBV_JUSTIFY_CENTERJUSTIFY
337 } gerbv_image_justify_type_t;
338 
339 /*! The different selection modes available */
340 typedef enum {	GERBV_SELECTION_POINT_CLICK = 1, /*!< the user clicked on a single point */
341 		GERBV_SELECTION_DRAG_BOX /*!< the user dragged a box to encompass one or more objects */
342 } gerbv_selection_t;
343 
344 enum draw_mode {
345 	DRAW_IMAGE = 0,
346 	DRAW_SELECTIONS,
347 	FIND_SELECTIONS,
348 	FIND_SELECTIONS_TOGGLE,
349 };
350 
351 /*! The different rendering modes available to libgerbv */
352 typedef enum {GERBV_RENDER_TYPE_GDK, /*!< render using normal GDK drawing functions */
353 		GERBV_RENDER_TYPE_GDK_XOR, /*!< use the GDK_XOR mask to draw a pseudo-transparent scene */
354 		GERBV_RENDER_TYPE_CAIRO_NORMAL, /*!< use the cairo library */
355 		GERBV_RENDER_TYPE_CAIRO_HIGH_QUALITY, /*!< use the cairo library with the smoothest edges */
356 		GERBV_RENDER_TYPE_MAX /*!< End-of-enum indicator */
357 } gerbv_render_types_t;
358 
359 /*
360  * The following typedef's are taken directly from src/hid.h in the
361  * pcb project.  The names are kept the same to make it easier to
362  * compare to pcb's sources.
363  */
364 
365 /* Used for HID attributes (exporting and printing, mostly).
366    HA_boolean uses int_value, HA_enum sets int_value to the index and
367    str_value to the enumeration string.  HID_Label just shows the
368    default str_value.  HID_Mixed is a real_value followed by an enum,
369    like 0.5in or 100mm.
370 */
371 typedef struct {
372     int int_value;
373     char *str_value;
374     double real_value;
375 } gerbv_HID_Attr_Val;
376 
377 typedef struct {
378     char *name;
379     char *help_text;
380     enum
381 	{ HID_Label, HID_Integer, HID_Real, HID_String,
382 	  HID_Boolean, HID_Enum, HID_Mixed, HID_Path
383 	} type;
384     int min_val, max_val;	/* for integer and real */
385     gerbv_HID_Attr_Val default_val;	/* Also actual value for global attributes.  */
386     const char **enumerations;
387     /* If set, this is used for global attributes (i.e. those set
388        statically with REGISTER_ATTRIBUTES below) instead of changing
389        the default_val.  Note that a HID_Mixed attribute must specify a
390        pointer to gerbv_HID_Attr_Val here, and HID_Boolean assumes this is
391        "char *" so the value should be initialized to zero, and may be
392        set to non-zero (not always one).  */
393     void *value;
394     int hash; /* for detecting changes. */
395 } gerbv_HID_Attribute;
396 /* end of HID attributes from PCB */
397 
398 /*! A linked list of errors found in the files */
399 typedef struct error_list {
400     int layer;
401     gchar *error_text;
402     gerbv_message_type_t type;
403     struct error_list *next;
404 } gerbv_error_list_t;
405 
406 typedef struct instruction {
407     gerbv_opcodes_t opcode;
408     union {
409 	int ival;
410 	float fval;
411     } data;
412     struct instruction *next;
413 } gerbv_instruction_t;
414 
415 typedef struct amacro {
416     gchar *name;
417     gerbv_instruction_t *program;
418     unsigned int nuf_push;  /* Nuf pushes in program to estimate stack size */
419     struct amacro *next;
420 } gerbv_amacro_t;
421 
422 typedef struct gerbv_simplified_amacro {
423     gerbv_aperture_type_t type;
424     double parameter[APERTURE_PARAMETERS_MAX];
425     struct gerbv_simplified_amacro *next;
426 } gerbv_simplified_amacro_t;
427 
428 typedef struct gerbv_aperture {
429     gerbv_aperture_type_t type;
430     gerbv_amacro_t *amacro;
431     gerbv_simplified_amacro_t *simplified;
432     double parameter[APERTURE_PARAMETERS_MAX];
433     int nuf_parameters;
434     gerbv_unit_t unit;
435 } gerbv_aperture_t;
436 
437 /* the gerb_aperture_list is used to keep track of
438  * apertures used in stats reporting */
439 typedef struct gerbv_aperture_list {
440     int number;
441     int layer;
442     int count;
443     gerbv_aperture_type_t type;
444     double parameter[5];
445     struct gerbv_aperture_list *next;
446 } gerbv_aperture_list_t;
447 
448 /*! Contains statistics on the various codes used in a RS274X file */
449 typedef struct {
450     gerbv_error_list_t *error_list;
451     gerbv_aperture_list_t *aperture_list;
452     gerbv_aperture_list_t *D_code_list;
453 
454     int layer_count;
455     int G0;
456     int G1;
457     int G2;
458     int G3;
459     int G4;
460     int G10;
461     int G11;
462     int G12;
463     int G36;
464     int G37;
465     int G54;
466     int G55;
467     int G70;
468     int G71;
469     int G74;
470     int G75;
471     int G90;
472     int G91;
473     int G_unknown;
474 
475     int D1;
476     int D2;
477     int D3;
478 /*    GHashTable *D_user_defined; */
479     int D_unknown;
480     int D_error;
481 
482     int M0;
483     int M1;
484     int M2;
485     int M_unknown;
486 
487     int X;
488     int Y;
489     int I;
490     int J;
491 
492     /* Must include % RS-274 codes */
493     int star;
494     int unknown;
495 
496 } gerbv_stats_t;
497 
498 /*! Linked list of drills found in active layers.  Used in reporting statistics */
499 typedef struct drill_list {
500     int drill_num;
501     double drill_size;
502     gchar *drill_unit;
503     int drill_count;
504     struct drill_list *next;
505 } gerbv_drill_list_t;
506 
507 /*! Struct holding statistics of drill commands used.  Used in reporting statistics */
508 typedef struct {
509     int layer_count;
510 
511     gerbv_error_list_t *error_list;
512     gerbv_drill_list_t *drill_list;
513     int comment;
514     int F;
515 
516     int G00;
517     int G01;
518     int G02;
519     int G03;
520     int G04;
521     int G05;
522     int G85;
523     int G90;
524     int G91;
525     int G93;
526     int G_unknown;
527 
528     int M00;
529     int M01;
530     int M18;
531     int M25;
532     int M30;
533     int M31;
534     int M45;
535     int M47;
536     int M48;
537     int M71;
538     int M72;
539     int M95;
540     int M97;
541     int M98;
542     int M_unknown;
543 
544     int R;
545 
546     int unknown;
547 
548     /* used to total up the drill count across all layers/sizes */
549     int total_count;
550 
551     char *detect;
552 
553 } gerbv_drill_stats_t;
554 
555 typedef struct {
556 	gpointer image;		/* gerbv_image_t* */
557 	gpointer net;		/* gerbv_net_t* */
558 } gerbv_selection_item_t;
559 
560 /*! Struct holding info about the last selection */
561 typedef struct {
562 	gerbv_selection_t type;
563 	gdouble lowerLeftX;
564 	gdouble lowerLeftY;
565 	gdouble upperRightX;
566 	gdouble upperRightY;
567 	GArray *selectedNodeArray;
568 } gerbv_selection_info_t;
569 
570 /*!  Stores image transformation information, used to modify the rendered
571 position/scale/etc of an image. */
572 typedef struct {
573     gdouble translateX; /*!< the X translation (in inches) */
574     gdouble translateY; /*!< the Y translation (in inches) */
575     gdouble scaleX; /*!< the X scale factor (1.0 is default) */
576     gdouble scaleY; /*!< the Y scale factor (1.0 is default) */
577     gdouble rotation; /*!< the rotation of the layer around the origin (in radians) */
578     gboolean mirrorAroundX;  /*!< TRUE if the layer is mirrored around the X axis (vertical flip) */
579     gboolean mirrorAroundY;  /*!< TRUE if the layer is mirrored around the Y axis (vertical flip) */
580     gboolean inverted; /*!< TRUE if the image should be rendered "inverted" (light is dark and vice versa) */
581 } gerbv_user_transformation_t;
582 
583 /*!  This defines a box location and size (used to rendering logic) */
584 typedef struct {
585     double left; /*!< the X coordinate of the left side */
586     double right; /*!< the X coordinate of the right side */
587     double bottom; /*!< the Y coordinate of the bottom side */
588     double top; /*!< the Y coordinate of the top side */
589 } gerbv_render_size_t;
590 
591 typedef struct gerbv_cirseg {
592     double cp_x;   /* center point x */
593     double cp_y;   /* center point y */
594     double width;  /* used as diameter */
595     double height; /* */
596     double angle1; /* in degrees */
597     double angle2; /* in degrees */
598 } gerbv_cirseg_t;
599 
600 typedef struct gerbv_step_and_repeat { /* SR parameters */
601     int X;
602     int Y;
603     double dist_X;
604     double dist_Y;
605 } gerbv_step_and_repeat_t;
606 
607 typedef struct {
608     gboolean firstInstance;
609     gerbv_knockout_type_t type;
610     gerbv_polarity_t polarity;
611     gdouble lowerLeftX;
612     gdouble lowerLeftY;
613     gdouble width;
614     gdouble height;
615     gdouble border;
616 } gerbv_knockout_t;
617 
618 /*!  The structure used to keep track of RS274X layer groups */
619 typedef struct {
620     gerbv_step_and_repeat_t stepAndRepeat; /*!< the current step and repeat group (refer to RS274X spec) */
621     gerbv_knockout_t knockout; /*!< the current knockout group (refer to RS274X spec) */
622     gdouble rotation; /*!< the current rotation around the origin */
623     gerbv_polarity_t polarity; /*!< the polarity of this layer */
624     gchar *name; /*!< the layer name (NULL for none) */
625     gpointer next; /*!< the next layer group in the array */
626 } gerbv_layer_t;
627 
628 /*!  The structure used to keep track of RS274X state groups */
629 typedef struct {
630     gerbv_axis_select_t axisSelect; /*!< the AB to XY coordinate mapping (refer to RS274X spec) */
631     gerbv_mirror_state_t mirrorState; /*!< any mirroring around the X or Y axis */
632     gerbv_unit_t unit; /*!< the current length unit */
633     gdouble offsetA; /*!< the offset along the A axis (usually this is the X axis) */
634     gdouble offsetB; /*!< the offset along the B axis (usually this is the Y axis) */
635     gdouble scaleA; /*!< the scale factor in the A axis (usually this is the X axis) */
636     gdouble scaleB; /*!< the scale factor in the B axis (usually this is the Y axis) */
637     gpointer next; /*!< the next state group in the array */
638 } gerbv_netstate_t;
639 
640 /*!  The structure used to hold a geometric entity (line/polygon/etc)*/
641 typedef struct gerbv_net {
642     double start_x; /*!< the X coordinate of the start point */
643     double start_y; /*!< the Y coordinate of the start point */
644     double stop_x; /*!< the X coordinate of the end point */
645     double stop_y; /*!< the Y coordinate of the end point */
646     gerbv_render_size_t boundingBox; /*!< the bounding box containing this net (used for rendering optimizations) */
647     int aperture; /*!< the index of the aperture used for this entity */
648     gerbv_aperture_state_t aperture_state; /*!< the state of the aperture tool (on/off/etc) */
649     gerbv_interpolation_t interpolation; /*!< the path interpolation method (linear/etc) */
650     gerbv_cirseg_t *cirseg; /*!< information for arc nets */
651     struct gerbv_net *next; /*!< the next net in the array */
652     GString *label; /*!< a label string for this net */
653     gerbv_layer_t *layer; /*!< the RS274X layer this net belongs to */
654     gerbv_netstate_t *state; /*!< the RS274X state this net belongs to */
655 } gerbv_net_t;
656 
657 /*! Struct holding info about interpreting the Gerber files read
658  *  e.g. leading zeros, etc.  */
659 typedef struct gerbv_format {
660     gerbv_omit_zeros_t omit_zeros;
661     gerbv_coordinate_t coordinate;
662     int x_int;
663     int x_dec;
664     int y_int;
665     int y_dec;
666     int lim_seqno; /* Length limit for codes of sequence number */
667     int lim_gf;    /* Length limit for codes of general function */
668     int lim_pf;    /* Length limit for codes of plot function */
669     int lim_mf;    /* Length limit for codes of miscellaneous function */
670 } gerbv_format_t;
671 
672 
673 /*! Struct holding info about a particular image */
674 typedef struct gerbv_image_info {
675     char *name;
676     gerbv_polarity_t polarity;
677     double min_x; /* Always in inches */
678     double min_y;
679     double max_x;
680     double max_y;
681     double offsetA;
682     double offsetB;
683     gerbv_encoding_t encoding;
684     double imageRotation;
685     gerbv_image_justify_type_t imageJustifyTypeA;
686     gerbv_image_justify_type_t imageJustifyTypeB;
687     gdouble imageJustifyOffsetA;
688     gdouble imageJustifyOffsetB;
689     gdouble imageJustifyOffsetActualA;
690     gdouble imageJustifyOffsetActualB;
691     gchar *plotterFilm;
692 
693     /* Descriptive string for the type of file (rs274-x, drill, etc)
694      * that this is
695      */
696     gchar *type;
697 
698     /* Attribute list that is used to hold all sorts of information
699      * about how the layer is to be parsed.
700     */
701     gerbv_HID_Attribute *attr_list;
702     int n_attr;
703 } gerbv_image_info_t;
704 
705 /*!  The structure used to hold a layer (RS274X, drill, or pick-and-place data) */
706 typedef struct {
707   gerbv_layertype_t layertype; /*!< the type of layer (RS274X, drill, or pick-and-place) */
708   gerbv_aperture_t *aperture[APERTURE_MAX]; /*!< an array with all apertures used */
709   gerbv_layer_t *layers; /*!< an array of all RS274X layers used (only used in RS274X types) */
710   gerbv_netstate_t *states; /*!< an array of all RS274X states used (only used in RS274X types) */
711   gerbv_amacro_t *amacro; /*!< an array of all macros used (only used in RS274X types) */
712   gerbv_format_t *format; /*!< formatting info */
713   gerbv_image_info_t *info; /*!< miscellaneous info regarding the layer such as overall size, etc */
714   gerbv_net_t *netlist; /*!< an array of all geometric entities in the layer */
715   gerbv_stats_t *gerbv_stats; /*!< RS274X statistics for the layer */
716   gerbv_drill_stats_t *drill_stats;  /*!< Excellon drill statistics for the layer */
717 } gerbv_image_t;
718 
719 /*!  Holds information related to an individual layer that is part of a project */
720 typedef struct {
721   gerbv_image_t *image; /*!< the image holding all the geometry of the layer */
722   GdkColor color; /*!< the color to render this layer with */
723   guint16 alpha; /*!< the transparency to render this layer with */
724   gboolean isVisible; /*!< TRUE if this layer should be rendered with the project */
725   gpointer privateRenderData; /*!< private data holder for the rendering backend */
726   gchar *fullPathname; /*!< this full pathname to the file */
727   gchar *name; /*!< the name used when referring to this layer (e.g. in a layer selection menu) */
728   gerbv_user_transformation_t transform; /*!< user-specified transformation for this layer (mirroring, translating, etc) */
729   gboolean layer_dirty;  /*!< True if layer has been modified since last save */
730 } gerbv_fileinfo_t;
731 
732 /*!  The top-level structure used in libgerbv.  A gerbv_project_t groups together
733 any number of layers, while keeping track of other basic paramters needed for rendering */
734 typedef struct {
735   GdkColor  background; /*!< the background color used for rendering */
736   int max_files; /*!< the current number of fileinfos in the file array */
737   gerbv_fileinfo_t **file; /*!< the array for holding the child fileinfos */
738   int curr_index; /*!< the index of the currently active fileinfo */
739   int last_loaded; /*!< the (number-1) of fileinfos currently in the project */
740   int renderType; /*!< the type of renderer to use */
741   gboolean check_before_delete;  /*!< TRUE to ask before deleting objects */
742   gboolean show_invisible_selection; /*!< TRUE to show selected objects on invisible files */
743   gchar *path; /*!< the default path to load new files from */
744   gchar *execpath;    /*!< the path to executed version of Gerbv */
745   gchar *execname;    /*!< the path plus executible name for Gerbv */
746   gchar *project;     /*!< the default name for the private project file */
747 } gerbv_project_t;
748 
749 /*! Color of layer */
750 typedef struct{
751     unsigned char red;
752     unsigned char green;
753     unsigned char blue;
754     unsigned char alpha;
755 }gerbv_layer_color;
756 
757 /*!  This contains the rendering info for a scene */
758 typedef struct {
759 	gdouble scaleFactorX; /*!< the X direction scale factor */
760 	gdouble scaleFactorY; /*!< the Y direction scale factor */
761 	gdouble lowerLeftX; /*!< the X coordinate of the lower left corner (in real world coordinates, in inches) */
762 	gdouble lowerLeftY; /*!< the Y coordinate of the lower left corner (in real world coordinates, in inches) */
763 	gerbv_render_types_t renderType; /*!< the type of rendering to use */
764 	gint displayWidth; /*!< the width of the scene (in pixels, or points depending on the surface type) */
765 	gint displayHeight; /*!< the height of the scene (in pixels, or points depending on the surface type) */
766 	gboolean show_cross_on_drill_holes; /*!< TRUE to show cross on drill holes */
767 } gerbv_render_info_t;
768 
769 //! Allocate a new gerbv_image structure
770 //! \return the newly created image
771 gerbv_image_t *gerbv_create_image(gerbv_image_t *image, /*!< the old image to free or NULL */
772 		const gchar *type /*!< the type of image to create */
773 );
774 
775 //! Free an image structure
776 void gerbv_destroy_image(gerbv_image_t *image /*!< the image to free */
777 );
778 
779 //! Copy an image into an existing image, effectively merging the two together
780 void
781 gerbv_image_copy_image (gerbv_image_t *sourceImage, /*!< the source image */
782 	gerbv_user_transformation_t *transform, /*!< the transformation to apply to the new image, or NULL for none */
783 	gerbv_image_t *destinationImage /*!< the destination image to copy to */
784 );
785 
786 //! Duplicate an existing image and return the new copy
787 //! \return the newly created image
788 gerbv_image_t *
789 gerbv_image_duplicate_image (gerbv_image_t *sourceImage, /*!< the source image */
790 	gerbv_user_transformation_t *transform /*!< the transformation to apply to the new image, or NULL for none */
791 );
792 
793 //! Delete a net in an existing image
794 void
795 gerbv_image_delete_net (gerbv_net_t *currentNet /*!< the net to delete */
796 );
797 
798 gboolean
799 gerbv_image_reduce_area_of_selected_objects (GArray *selectionArray, gdouble areaReduction, gint paneRows,
800 		gint paneColumns, gdouble paneSeparation);
801 
802 gboolean
803 gerbv_image_move_selected_objects (GArray *selectionArray, gdouble translationX,
804 		gdouble translationY);
805 
806 //! Return the next net entry which corresponds to a unique visible object
807 gerbv_net_t *
808 gerbv_image_return_next_renderable_object (gerbv_net_t *oldNet);
809 
810 //! Create a new project structure and initialize some important variables
811 gerbv_project_t *
812 gerbv_create_project (void);
813 
814 //! Free a project and all related variables
815 void
816 gerbv_destroy_project (gerbv_project_t *gerbvProject /*!< the project to destroy */
817 );
818 
819 //! Open a file, parse the contents, and add a new layer to an existing project
820 void
821 gerbv_open_layer_from_filename (
822 	gerbv_project_t *gerbvProject, /*!< the existing project to add the new layer to */
823 	gchar *filename /*!< the full pathname of the file to be parsed */
824 );
825 
826 //! Open a file, parse the contents, and add a new layer to an existing project while setting the color of the layer
827 void
828 gerbv_open_layer_from_filename_with_color(gerbv_project_t *gerbvProject, /*!< the existing project to add the new layer to */
829 	gchar *filename, /*!< the full pathname of the file to be parsed */
830 	guint16 red, /*!< the value for the red color component */
831 	guint16 green, /*!< the value for the green color component */
832 	guint16 blue, /*!< the value for the blue color component */
833 	guint16 alpha /*!< the value for the alpha color component */
834 );
835 
836 //! Free a fileinfo structure
837 void
838 gerbv_destroy_fileinfo (gerbv_fileinfo_t *fileInfo /*!< the fileinfo to free */
839 );
840 
841 gboolean
842 gerbv_save_layer_from_index(gerbv_project_t *gerbvProject, gint index, gchar *filename);
843 
844 int
845 gerbv_revert_file(gerbv_project_t *gerbvProject, int idx);
846 
847 void
848 gerbv_revert_all_files(gerbv_project_t *gerbvProject);
849 
850 void
851 gerbv_unload_layer(gerbv_project_t *gerbvProject, int index);
852 
853 void
854 gerbv_unload_all_layers (gerbv_project_t *gerbvProject);
855 
856 void
857 gerbv_change_layer_order(gerbv_project_t *gerbvProject, gint oldPosition, gint newPosition);
858 
859 gint
860 gerbv_add_parsed_image_to_project (gerbv_project_t *gerbvProject, gerbv_image_t *parsed_image,
861 			gchar *filename, gchar *baseName, int idx, int reload);
862 int
863 gerbv_open_image(gerbv_project_t *gerbvProject, char *filename, int idx, int reload,
864 		gerbv_HID_Attribute *fattr, int n_fattr, gboolean forceLoadFile);
865 
866 void
867 gerbv_render_get_boundingbox(gerbv_project_t *gerbvProject, gerbv_render_size_t *boundingbox);
868 
869 //! Calculate the zoom and translations to fit the rendered scene inside the given scene size
870 void
871 gerbv_render_zoom_to_fit_display (gerbv_project_t *gerbvProject, /*!< the project to use for calculating */
872 		gerbv_render_info_t *renderInfo /*!< the scene render pointer (updates the values in this parameter) */
873 );
874 
875 void
876 gerbv_render_translate_to_fit_display (gerbv_project_t *gerbvProject, gerbv_render_info_t *renderInfo);
877 
878 void
879 gerbv_render_to_pixmap_using_gdk (gerbv_project_t *gerbvProject, GdkPixmap *pixmap,
880 		gerbv_render_info_t *renderInfo, gerbv_selection_info_t *selectionInfo,
881 		GdkColor *selectionColor);
882 
883 #ifndef RENDER_USING_GDK
884 void
885 gerbv_render_all_layers_to_cairo_target_for_vector_output (gerbv_project_t *gerbvProject,
886 		cairo_t *cr, gerbv_render_info_t *renderInfo);
887 
888 void
889 gerbv_render_all_layers_to_cairo_target (gerbv_project_t *gerbvProject, cairo_t *cr,
890 			gerbv_render_info_t *renderInfo);
891 
892 //! Render a layer to a cairo context
893 void
894 gerbv_render_layer_to_cairo_target (cairo_t *cr, /*!< the cairo context */
895 		gerbv_fileinfo_t *fileInfo, /*!< the layer fileinfo pointer */
896 		gerbv_render_info_t *renderInfo /*!< the scene render info */
897 );
898 
899 void
900 gerbv_render_cairo_set_scale_and_translation(cairo_t *cr, gerbv_render_info_t *renderInfo);
901 
902 void
903 gerbv_render_layer_to_cairo_target_without_transforming(cairo_t *cr, gerbv_fileinfo_t *fileInfo, gerbv_render_info_t *renderInfo, gboolean pixelOutput );
904 #endif
905 
906 double
907 gerbv_get_tool_diameter(int toolNumber
908 );
909 
910 int
911 gerbv_process_tools_file(const char *toolFileName
912 );
913 
914 //! Render a project to a PNG file, autoscaling the layers to fit inside the specified image dimensions
915 void
916 gerbv_export_png_file_from_project_autoscaled (
917 		gerbv_project_t *gerbvProject, /*!< the project to render */
918 		int widthInPixels, /*!< the width of the rendered picture (in pixels) */
919 		int heightInPixels, /*!< the height of the rendered picture (in pixels) */
920 		gchar const* filename  /*!< the filename for the exported PNG file */
921 );
922 
923 //! Render a project to a PNG file using user-specified render info
924 void
925 gerbv_export_png_file_from_project (
926 		gerbv_project_t *gerbvProject, /*!< the project to render */
927 		gerbv_render_info_t *renderInfo, /*!< the render settings for the rendered image */
928 		gchar const* filename /*!< the filename for the exported PNG file */
929 );
930 
931 //! Render a project to a PDF file, autoscaling the layers to fit inside the specified image dimensions
932 void
933 gerbv_export_pdf_file_from_project_autoscaled (
934 		gerbv_project_t *gerbvProject, /*!< the project to render */
935 		gchar const* filename  /*!< the filename for the exported PDF file */
936 );
937 
938 //! Render a project to a PDF file using user-specified render info
939 void
940 gerbv_export_pdf_file_from_project (
941 		gerbv_project_t *gerbvProject, /*!< the project to render */
942 		gerbv_render_info_t *renderInfo, /*!< the render settings for the rendered image */
943 		gchar const* filename /*!< the filename for the exported PDF file */
944 );
945 
946 //! Render a project to a Postscript file, autoscaling the layers to fit inside the specified image dimensions
947 void
948 gerbv_export_postscript_file_from_project_autoscaled (
949 		gerbv_project_t *gerbvProject, /*!< the project to render */
950 		gchar const* filename  /*!< the filename for the exported Postscript file */
951 );
952 
953 //! Render a project to a Postscript file using user-specified render info
954 void
955 gerbv_export_postscript_file_from_project (
956 		gerbv_project_t *gerbvProject, /*!< the project to render */
957 		gerbv_render_info_t *renderInfo, /*!< the render settings for the rendered image */
958 		gchar const* filename /*!< the filename for the exported Postscript file */
959 );
960 
961 //! Render a project to a SVG file, autoscaling the layers to fit inside the specified image dimensions
962 void
963 gerbv_export_svg_file_from_project_autoscaled (
964 		gerbv_project_t *gerbvProject, /*!< the project to render */
965 		gchar const* filename  /*!< the filename for the exported   file */
966 );
967 
968 //! Render a project to a   file using user-specified render info
969 void
970 gerbv_export_svg_file_from_project (
971 		gerbv_project_t *gerbvProject, /*!< the project to render */
972 		gerbv_render_info_t *renderInfo, /*!< the render settings for the rendered image */
973 		gchar const* filename /*!< the filename for the exported   file */
974 );
975 
976 //! Export an image to a new file in DXF format
977 //! \return TRUE if successful, or FALSE if not
978 gboolean
979 gerbv_export_dxf_file_from_image (const gchar *filename, /*!< the filename for the new file */
980 		gerbv_image_t *image, /*!< the image to export */
981 		gerbv_user_transformation_t *transform /*!< the transformation to apply before exporting */
982 );
983 
984 //! Parse a RS274X file and return the parsed image
985 //! \return the new gerbv_image_t, or NULL if not successful
986 gerbv_image_t *
987 gerbv_create_rs274x_image_from_filename (gchar *filename /*!< the filename of the file to be parsed*/
988 );
989 
990 //! Export an image to a new file in RS274X format
991 //! \return TRUE if successful, or FALSE if not
992 gboolean
993 gerbv_export_rs274x_file_from_image (const gchar *filename, /*!< the filename for the new file */
994 		gerbv_image_t *image, /*!< the image to export */
995 		gerbv_user_transformation_t *transform /*!< the transformation to apply before exporting */
996 );
997 
998 //! Export an image to a new file in Excellon drill format
999 //! \return TRUE if successful, or FALSE if not
1000 gboolean
1001 gerbv_export_drill_file_from_image (const gchar *filename, /*!< the filename for the new file */
1002 		gerbv_image_t *image, /*!< the image to export */
1003 		gerbv_user_transformation_t *transform /*!< the transformation to apply before exporting */
1004 );
1005 
1006 //! Export an image to a new file in ISEL NCP drill format
1007 //! \return TRUE if successful, or FALSE if not
1008 gboolean
1009 gerbv_export_isel_drill_file_from_image (const gchar *filename, /*!< the filename for the new file */
1010 		gerbv_image_t *image, /*!< the image to export */
1011 		gerbv_user_transformation_t *transform /*!< the transformation to apply before exporting */
1012 );
1013 
1014 //! Export an image to a new file in gEDA PCB format
1015 //! \return TRUE if successful, or FALSE if not
1016 gboolean
1017 gerbv_export_geda_pcb_file_from_image (const gchar *filename, /*!< the filename for the new file */
1018 		gerbv_image_t *image, /*!< the image to export */
1019 		gerbv_user_transformation_t *transform /*!< the transformation to apply before exporting */
1020 );
1021 
1022 //! Draw a line on the specified image
1023 void
1024 gerbv_image_create_line_object (gerbv_image_t *image, /*!< the image to draw to */
1025 		gdouble startX, /*!< the starting X coordinate */
1026 		gdouble startY, /*!< the starting Y coordinate */
1027 		gdouble endX, /*!< the ending X coordinate */
1028 		gdouble endY, /*!< the ending Y coordinate */
1029 		gdouble lineWidth, /*!< the width of the line to draw */
1030 		gerbv_aperture_type_t apertureType  /*!< the type of aperture to use (e.g. CIRCLE) */
1031 );
1032 
1033 //! Draw an arc on the specified image
1034 void
1035 gerbv_image_create_arc_object (gerbv_image_t *image, /*!< the image to draw to */
1036 		gdouble centerX, /*!< the center X coordinate */
1037 		gdouble centerY, /*!< the center Y coordinate */
1038 		gdouble radius, /*!< the arc radius */
1039 		gdouble startAngle, /*!< the start angle (in CCW degrees) */
1040 		gdouble endAngle, /*!< the start angle (in CCW degrees) */
1041 		gdouble lineWidth, /*!< the width of the line to draw */
1042 		gerbv_aperture_type_t apertureType  /*!< the type of aperture to use (e.g. CIRCLE) */
1043 );
1044 
1045 //! Draw a filled rectangle on the specified image
1046 void
1047 gerbv_image_create_rectangle_object (gerbv_image_t *image, /*!< the image to draw to */
1048 		gdouble coordinateX, /*!< the X coordinate of the lower left corner */
1049 		gdouble coordinateY, /*!< the Y coordinate of the lower left corner */
1050 		gdouble width, /*!< the width of the drawn rectangle */
1051 		gdouble height /*!< the height of the drawn rectangle */
1052 );
1053 
1054 //! Create any missing apertures in the specified image
1055 void
1056 gerbv_image_create_dummy_apertures (gerbv_image_t *parsed_image /*!< the image to repair */
1057 );
1058 
1059 /*! Create new struct for holding drill stats */
1060 gerbv_drill_stats_t *
1061 gerbv_drill_stats_new(void);
1062 
1063 /*! Free the memory for a drill stats struct */
1064 void
1065 gerbv_drill_stats_destroy(gerbv_drill_stats_t *);
1066 
1067 /*! Add stats gathered from specified layer to accumulatedd drill stats
1068  *  compiled from all layers */
1069 void
1070 gerbv_drill_stats_add_layer(gerbv_drill_stats_t *accum_stats,
1071 		gerbv_drill_stats_t *input_stats,
1072 		int this_layer
1073 );
1074 
1075 /*! Create new struct for holding Gerber stats */
1076 gerbv_stats_t *
1077 gerbv_stats_new(void);
1078 
1079 /*! Free the memory for a stats struct */
1080 void
1081 gerbv_stats_destroy(gerbv_stats_t *);
1082 
1083 /*! Add stats gathered from specified layer to accumulated Gerber stats
1084  *  compiled from all layers */
1085 void
1086 gerbv_stats_add_layer(gerbv_stats_t *accum_stats,
1087 		gerbv_stats_t *input_stats,
1088 		int this_layer
1089 );
1090 
1091 void
1092 gerbv_attribute_destroy_HID_attribute (gerbv_HID_Attribute *attributeList, int n_attr);
1093 
1094 gerbv_HID_Attribute *
1095 gerbv_attribute_dup (gerbv_HID_Attribute *, int);
1096 
1097 /*! Return found fileinfo for image, or NULL */
1098 gerbv_fileinfo_t *
1099 gerbv_get_fileinfo_for_image(const gerbv_image_t *image,
1100 				const gerbv_project_t *project);
1101 
1102 /*! Transform coordinate x and y for image in project */
1103 int
1104 gerbv_transform_coord_for_image(double *x, double *y,
1105 		const gerbv_image_t *image, const gerbv_project_t *project);
1106 
1107 /*! Transform coordinate x and y */
1108 void
1109 gerbv_transform_coord(double *x, double *y,
1110 		const gerbv_user_transformation_t *trans);
1111 
1112 /*! Rotate coordinate x and y buy angle in radians */
1113 void
1114 gerbv_rotate_coord(double *x, double *y, double rad);
1115 
1116 #undef MIN
1117 #undef MAX
1118 #define MIN(x,y) ({ \
1119 		typeof(x) _x = (x);     \
1120 		typeof(y) _y = (y);     \
1121 		(void) (&_x == &_y);    \
1122 		_x < _y ? _x : _y; })
1123 #define MAX(x,y) ({ \
1124 		typeof(x) _x = (x);     \
1125 		typeof(y) _y = (y);     \
1126 		(void) (&_x == &_y);    \
1127 		_x > _y ? _x : _y; })
1128 
1129 #if defined(__cplusplus)
1130 }
1131 #endif
1132 
1133 #endif /* __GERBV_H__ */
1134