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