00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <math.h>
00032 #include <glib.h>
00033 #include <locale.h>
00034 #include <errno.h>
00035 #include <ctype.h>
00036
00037 #include "config.h"
00038 #include "gerbv.h"
00039 #include "gerb_image.h"
00040 #include "gerber.h"
00041 #include "gerb_stats.h"
00042 #include "amacro.h"
00043
00044
00045
00046 #ifndef RENDER_USING_GDK
00047 #include <cairo.h>
00048 #endif
00049
00050
00051 #include "draw-gdk.h"
00052
00053
00054 #define dprintf if(DEBUG) printf
00055
00056
00057
00058 #define A2I(a,b) (((a & 0xff) << 8) + (b & 0xff))
00059
00060 #define MAXL 200
00061
00062
00063 static void parse_G_code(gerb_file_t *fd, gerb_state_t *state,
00064 gerbv_image_t *image);
00065 static void parse_D_code(gerb_file_t *fd, gerb_state_t *state,
00066 gerbv_image_t *image);
00067 static int parse_M_code(gerb_file_t *fd, gerbv_image_t *image);
00068 static void parse_rs274x(gint levelOfRecursion, gerb_file_t *fd,
00069 gerbv_image_t *image, gerb_state_t *state,
00070 gerbv_net_t *curr_net, gerbv_stats_t *stats,
00071 gchar *directoryPath);
00072 static int parse_aperture_definition(gerb_file_t *fd,
00073 gerbv_aperture_t *aperture,
00074 gerbv_image_t *image, gdouble scale);
00075 static void calc_cirseg_sq(struct gerbv_net *net, int cw,
00076 double delta_cp_x, double delta_cp_y);
00077 static void calc_cirseg_mq(struct gerbv_net *net, int cw,
00078 double delta_cp_x, double delta_cp_y);
00079
00080 static void
00081 gerber_update_min_and_max(gerbv_image_info_t *info, gdouble repeatX, gdouble repeatY,
00082 gdouble x, gdouble y, gdouble apertureSizeX1,
00083 gdouble apertureSizeX2,gdouble apertureSizeY1,
00084 gdouble apertureSizeY2);
00085
00086
00087 static void gerber_update_any_running_knockout_measurements(gerbv_image_t *image);
00088
00089 static void gerber_calculate_final_justify_effects (gerbv_image_t *image);
00090
00091 gboolean knockoutMeasure = FALSE;
00092 gdouble knockoutLimitXmin, knockoutLimitYmin, knockoutLimitXmax,
00093 knockoutLimitYmax;
00094 gerbv_layer_t *knockoutLayer = NULL;
00095
00096 #ifndef RENDER_USING_GDK
00097 cairo_matrix_t currentMatrix;
00098 #endif
00099
00100
00101 gerbv_net_t *
00102 gerber_create_new_net (gerbv_net_t *currentNet, gerbv_layer_t *layer, gerbv_netstate_t *state){
00103 gerbv_net_t *newNet = g_new0 (gerbv_net_t, 1);
00104
00105 currentNet->next = newNet;
00106 if (layer)
00107 newNet->layer = layer;
00108 else
00109 newNet->layer = currentNet->layer;
00110 if (state)
00111 newNet->state = state;
00112 else
00113 newNet->state = currentNet->state;
00114 return newNet;
00115 }
00116
00117
00118 gboolean
00119 gerber_create_new_aperture (gerbv_image_t *image, int *indexNumber,
00120 gerbv_aperture_type_t apertureType, gdouble parameter1, gdouble parameter2){
00121 int i;
00122
00123
00124 for (i = APERTURE_MIN; i <= APERTURE_MAX; i++) {
00125 if (image->aperture[i] == NULL) {
00126 image->aperture[i] = g_new0 (gerbv_aperture_t, 1);
00127 image->aperture[i]->type = apertureType;
00128 image->aperture[i]->amacro = NULL;
00129 image->aperture[i]->parameter[0] = parameter1;
00130 image->aperture[i]->parameter[1] = parameter2;
00131 *indexNumber = i;
00132 return TRUE;
00133 }
00134 }
00135 return FALSE;
00136 }
00137
00138
00148 gboolean
00149 gerber_parse_file_segment (gint levelOfRecursion, gerbv_image_t *image,
00150 gerb_state_t *state, gerbv_net_t *curr_net,
00151 gerbv_stats_t *stats, gerb_file_t *fd,
00152 gchar *directoryPath) {
00153 int read, coord, len, polygonPoints=0;
00154 double x_scale = 0.0, y_scale = 0.0;
00155 double delta_cp_x = 0.0, delta_cp_y = 0.0;
00156 double aperture_size;
00157 double scale;
00158 gboolean foundEOF = FALSE;
00159 gchar *string;
00160
00161 while ((read = gerb_fgetc(fd)) != EOF) {
00162
00163
00164 if (state->state->unit == GERBV_UNIT_MM)
00165 scale = 25.4;
00166 else
00167 scale = 1.0;
00168 switch ((char)(read & 0xff)) {
00169 case 'G':
00170 dprintf("... Found G code\n");
00171 parse_G_code(fd, state, image);
00172 break;
00173 case 'D':
00174 dprintf("... Found D code\n");
00175 parse_D_code(fd, state, image);
00176 break;
00177 case 'M':
00178 dprintf("... Found M code\n");
00179 switch(parse_M_code(fd, image)) {
00180 case 1 :
00181 case 2 :
00182 case 3 :
00183 foundEOF = TRUE;
00184 break;
00185 default:
00186 gerbv_stats_add_error(stats->error_list,
00187 -1,
00188 "Unknown M code found.\n",
00189 GERBV_MESSAGE_ERROR);
00190 }
00191 break;
00192 case 'X':
00193 dprintf("... Found X code\n");
00194 stats->X++;
00195 coord = gerb_fgetint(fd, &len);
00196 if (image->format && image->format->omit_zeros == GERBV_OMIT_ZEROS_TRAILING) {
00197
00198 switch ((image->format->x_int + image->format->x_dec) - len) {
00199 case 5:
00200 coord *= 10;
00201 case 4:
00202 coord *= 10;
00203 case 3:
00204 coord *= 10;
00205 case 2:
00206 coord *= 10;
00207 case 1:
00208 coord *= 10;
00209 break;
00210 default:
00211 ;
00212 }
00213 }
00214 if (image->format && (image->format->coordinate==GERBV_COORDINATE_INCREMENTAL))
00215 state->curr_x += coord;
00216 else
00217 state->curr_x = coord;
00218 state->changed = 1;
00219 break;
00220 case 'Y':
00221 dprintf("... Found Y code\n");
00222 stats->Y++;
00223 coord = gerb_fgetint(fd, &len);
00224 if (image->format && image->format->omit_zeros == GERBV_OMIT_ZEROS_TRAILING) {
00225
00226 switch ((image->format->y_int + image->format->y_dec) - len) {
00227 case 5:
00228 coord *= 10;
00229 case 4:
00230 coord *= 10;
00231 case 3:
00232 coord *= 10;
00233 case 2:
00234 coord *= 10;
00235 case 1:
00236 coord *= 10;
00237 break;
00238 default:
00239 ;
00240 }
00241 }
00242 if (image->format && (image->format->coordinate==GERBV_COORDINATE_INCREMENTAL))
00243 state->curr_y += coord;
00244 else
00245 state->curr_y = coord;
00246 state->changed = 1;
00247 break;
00248 case 'I':
00249 dprintf("... Found I code\n");
00250 stats->I++;
00251 state->delta_cp_x = gerb_fgetint(fd, NULL);
00252 state->changed = 1;
00253 break;
00254 case 'J':
00255 dprintf("... Found J code\n");
00256 stats->J++;
00257 state->delta_cp_y = gerb_fgetint(fd, NULL);
00258 state->changed = 1;
00259 break;
00260 case '%':
00261 dprintf("... Found %% code\n");
00262 parse_rs274x(levelOfRecursion, fd, image, state, curr_net, stats, directoryPath);
00263 while (1) {
00264 int c = gerb_fgetc(fd);
00265 if(c == EOF || c == '%')
00266 break;
00267 }
00268 break;
00269 case '*':
00270 dprintf("... Found * code\n");
00271 stats->star++;
00272 if (state->changed == 0) break;
00273 state->changed = 0;
00274
00275
00276
00277 if ((state->aperture_state == GERBV_APERTURE_STATE_OFF)&&(!state->in_parea_fill)&&
00278 (state->interpolation != GERBV_INTERPOLATION_PAREA_START)) {
00279
00280 state->prev_x = state->curr_x;
00281 state->prev_y = state->curr_y;
00282 break;
00283 }
00284 curr_net = gerber_create_new_net (curr_net, state->layer, state->state);
00285
00286
00287
00288
00289 if (image && image->format ){
00290 x_scale = pow(10.0, (double)image->format->x_dec);
00291 y_scale = pow(10.0, (double)image->format->y_dec);
00292 }
00293 x_scale *= scale;
00294 y_scale *= scale;
00295 curr_net->start_x = (double)state->prev_x / x_scale;
00296 curr_net->start_y = (double)state->prev_y / y_scale;
00297 curr_net->stop_x = (double)state->curr_x / x_scale;
00298 curr_net->stop_y = (double)state->curr_y / y_scale;
00299 delta_cp_x = (double)state->delta_cp_x / x_scale;
00300 delta_cp_y = (double)state->delta_cp_y / y_scale;
00301
00302
00303 switch (state->interpolation) {
00304 case GERBV_INTERPOLATION_CW_CIRCULAR :
00305 curr_net->cirseg = g_new0 (gerbv_cirseg_t,1);
00306 if (state->mq_on)
00307 calc_cirseg_mq(curr_net, 1, delta_cp_x, delta_cp_y);
00308 else
00309 calc_cirseg_sq(curr_net, 1, delta_cp_x, delta_cp_y);
00310 break;
00311 case GERBV_INTERPOLATION_CCW_CIRCULAR :
00312 curr_net->cirseg = g_new0 (gerbv_cirseg_t,1);
00313 if (state->mq_on)
00314 calc_cirseg_mq(curr_net, 0, delta_cp_x, delta_cp_y);
00315 else
00316 calc_cirseg_sq(curr_net, 0, delta_cp_x, delta_cp_y);
00317 break;
00318 case GERBV_INTERPOLATION_PAREA_START :
00319
00320
00321
00322 state->parea_start_node = curr_net;
00323 state->in_parea_fill = 1;
00324 polygonPoints = 0;
00325 break;
00326 case GERBV_INTERPOLATION_PAREA_END :
00327 state->parea_start_node = NULL;
00328 state->in_parea_fill = 0;
00329 polygonPoints = 0;
00330 break;
00331 default :
00332 break;
00333 }
00334
00335
00336
00337
00338 if (state->in_parea_fill && state->parea_start_node) {
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 if ((state->aperture_state == GERBV_APERTURE_STATE_OFF &&
00350 state->interpolation != GERBV_INTERPOLATION_PAREA_START) && (polygonPoints > 0)) {
00351 curr_net->interpolation = GERBV_INTERPOLATION_PAREA_END;
00352
00353 curr_net = gerber_create_new_net (curr_net, state->layer, state->state);
00354 curr_net->interpolation = GERBV_INTERPOLATION_PAREA_START;
00355 state->parea_start_node = curr_net;
00356
00357 curr_net = gerber_create_new_net (curr_net, state->layer, state->state);
00358 curr_net->start_x = (double)state->prev_x / x_scale;
00359 curr_net->start_y = (double)state->prev_y / y_scale;
00360 curr_net->stop_x = (double)state->curr_x / x_scale;
00361 curr_net->stop_y = (double)state->curr_y / y_scale;
00362 }
00363 if (state->interpolation != GERBV_INTERPOLATION_PAREA_START)
00364 polygonPoints++;
00365
00366 }
00367
00368 curr_net->interpolation = state->interpolation;
00369
00370
00371
00372
00373
00374
00375
00376 if (((state->interpolation == GERBV_INTERPOLATION_CW_CIRCULAR) ||
00377 (state->interpolation == GERBV_INTERPOLATION_CCW_CIRCULAR)) &&
00378 ((state->delta_cp_x == 0.0) && (state->delta_cp_y == 0.0)))
00379 curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1;
00380
00381
00382
00383
00384
00385
00386
00387 if ((state->interpolation == GERBV_INTERPOLATION_PAREA_START) ||
00388 (state->interpolation == GERBV_INTERPOLATION_PAREA_END))
00389 state->interpolation = state->prev_interpolation;
00390
00391
00392
00393
00394 curr_net->layer = state->layer;
00395
00396 state->delta_cp_x = 0.0;
00397 state->delta_cp_y = 0.0;
00398 curr_net->aperture = state->curr_aperture;
00399 curr_net->aperture_state = state->aperture_state;
00400
00401
00402
00403
00404
00405 state->prev_x = state->curr_x;
00406 state->prev_y = state->curr_y;
00407
00408
00409
00410
00411
00412 if ((curr_net->aperture == 0) && !state->in_parea_fill)
00413 break;
00414
00415
00416 if ((curr_net->aperture_state != GERBV_APERTURE_STATE_OFF)){
00417 double repeat_off_X = 0.0, repeat_off_Y = 0.0;
00418
00419
00420 if (!state->in_parea_fill) {
00421 dprintf(" In parse_D_code, adding 1 to D_list ...\n");
00422 int retcode = gerbv_stats_increment_D_list_count(stats->D_code_list,
00423 curr_net->aperture,
00424 1,
00425 stats->error_list);
00426 if (retcode == -1) {
00427 string = g_strdup_printf("Found undefined D code D%d in file \n%s\n",
00428 curr_net->aperture,
00429 fd->filename);
00430 gerbv_stats_add_error(stats->error_list,
00431 -1,
00432 string,
00433 GERBV_MESSAGE_ERROR);
00434 g_free(string);
00435 stats->D_unknown++;
00436 }
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 repeat_off_X = (state->layer->stepAndRepeat.X - 1) *
00448 state->layer->stepAndRepeat.dist_X;
00449 repeat_off_Y = (state->layer->stepAndRepeat.Y - 1) *
00450 state->layer->stepAndRepeat.dist_Y;
00451
00452
00453 #ifndef RENDER_USING_GDK
00454 cairo_matrix_init (¤tMatrix, 1, 0, 0, 1, 0, 0);
00455
00456 cairo_matrix_translate (¤tMatrix, image->info->offsetA,
00457 image->info->offsetB);
00458
00459 cairo_matrix_rotate (¤tMatrix, image->info->imageRotation);
00460
00461
00462
00463 cairo_matrix_rotate (¤tMatrix, state->layer->rotation);
00464
00465
00466
00467 cairo_matrix_scale (¤tMatrix, state->state->scaleA,
00468 state->state->scaleB);
00469
00470 cairo_matrix_translate (¤tMatrix, state->state->offsetA,
00471 state->state->offsetB);
00472
00473 switch (state->state->mirrorState) {
00474 case GERBV_MIRROR_STATE_FLIPA:
00475 cairo_matrix_scale (¤tMatrix, -1, 1);
00476 break;
00477 case GERBV_MIRROR_STATE_FLIPB:
00478 cairo_matrix_scale (¤tMatrix, 1, -1);
00479 break;
00480 case GERBV_MIRROR_STATE_FLIPAB:
00481 cairo_matrix_scale (¤tMatrix, -1, -1);
00482 break;
00483 default:
00484 break;
00485 }
00486
00487 if (state->state->axisSelect == GERBV_AXIS_SELECT_SWAPAB) {
00488
00489
00490
00491 cairo_matrix_rotate (¤tMatrix, 3 * M_PI / 2);
00492 cairo_matrix_scale (¤tMatrix, 1, -1);
00493 }
00494 #endif
00495
00496
00497 if ((image->aperture[curr_net->aperture] != NULL) &&
00498 (image->aperture[curr_net->aperture]->type == GERBV_APTYPE_MACRO)) {
00499 gerbv_simplified_amacro_t *ls = image->aperture[curr_net->aperture]->simplified;
00500
00501 while (ls != NULL) {
00502 gdouble offsetx = 0, offsety = 0, widthx = 0, widthy = 0;
00503 gboolean calculatedAlready = FALSE;
00504
00505 if (ls->type == GERBV_APTYPE_MACRO_CIRCLE) {
00506 offsetx=ls->parameter[CIRCLE_CENTER_X];
00507 offsety=ls->parameter[CIRCLE_CENTER_Y];
00508 widthx=widthy=ls->parameter[CIRCLE_DIAMETER];
00509 } else if (ls->type == GERBV_APTYPE_MACRO_OUTLINE) {
00510 int pointCounter,numberOfPoints;
00511 numberOfPoints = (int) ls->parameter[OUTLINE_NUMBER_OF_POINTS];
00512
00513 for (pointCounter = 0; pointCounter < numberOfPoints; pointCounter++) {
00514 gerber_update_min_and_max (image->info, repeat_off_X, repeat_off_Y,
00515 ls->parameter[pointCounter * 2 + OUTLINE_FIRST_X],
00516 ls->parameter[pointCounter * 2 + OUTLINE_FIRST_Y],
00517 0,0,0,0);
00518 }
00519 calculatedAlready = TRUE;
00520 } else if (ls->type == GERBV_APTYPE_MACRO_POLYGON) {
00521 offsetx = ls->parameter[POLYGON_CENTER_X];
00522 offsety = ls->parameter[POLYGON_CENTER_Y];
00523 widthx = widthy = ls->parameter[POLYGON_DIAMETER];
00524 } else if (ls->type == GERBV_APTYPE_MACRO_MOIRE) {
00525 offsetx = ls->parameter[MOIRE_CENTER_X];
00526 offsety = ls->parameter[MOIRE_CENTER_Y];
00527 widthx = widthy = ls->parameter[MOIRE_OUTSIDE_DIAMETER];
00528 } else if (ls->type == GERBV_APTYPE_MACRO_THERMAL) {
00529 offsetx = ls->parameter[THERMAL_CENTER_X];
00530 offsety = ls->parameter[THERMAL_CENTER_Y];
00531 widthx = widthy = ls->parameter[THERMAL_OUTSIDE_DIAMETER];
00532 } else if (ls->type == GERBV_APTYPE_MACRO_LINE20) {
00533 widthx = widthy = ls->parameter[LINE20_LINE_WIDTH];
00534 gerber_update_min_and_max (image->info, repeat_off_X, repeat_off_Y,
00535 ls->parameter[LINE20_START_X] + offsetx,
00536 ls->parameter[LINE20_START_Y] + offsety,
00537 widthx/2,widthx/2,widthy/2,widthy/2);
00538 gerber_update_min_and_max (image->info, repeat_off_X, repeat_off_Y,
00539 ls->parameter[LINE20_END_X] + offsetx,
00540 ls->parameter[LINE20_END_Y] + offsety,
00541 widthx/2,widthx/2,widthy/2,widthy/2);
00542 calculatedAlready = TRUE;
00543 } else if (ls->type == GERBV_APTYPE_MACRO_LINE21) {
00544 gdouble largestDimension = sqrt (ls->parameter[LINE21_WIDTH]/2 *
00545 ls->parameter[LINE21_WIDTH]/2 + ls->parameter[LINE21_HEIGHT/2] *
00546 ls->parameter[LINE21_HEIGHT]/2);
00547
00548 offsetx = ls->parameter[LINE21_CENTER_X];
00549 offsety = ls->parameter[LINE21_CENTER_Y];
00550 widthx = widthy=largestDimension;
00551 } else if (ls->type == GERBV_APTYPE_MACRO_LINE22) {
00552 gdouble largestDimension = sqrt (ls->parameter[LINE22_WIDTH]/2 *
00553 ls->parameter[LINE22_WIDTH]/2 + ls->parameter[LINE22_HEIGHT/2] *
00554 ls->parameter[LINE22_HEIGHT]/2);
00555
00556 offsetx = ls->parameter[LINE22_LOWER_LEFT_X] +
00557 ls->parameter[LINE22_WIDTH]/2;
00558 offsety = ls->parameter[LINE22_LOWER_LEFT_Y] +
00559 ls->parameter[LINE22_HEIGHT]/2;
00560 widthx = widthy=largestDimension;
00561 }
00562
00563 if (!calculatedAlready) {
00564 gerber_update_min_and_max (image->info, repeat_off_X, repeat_off_Y,
00565 curr_net->stop_x + offsetx,
00566 curr_net->stop_y + offsety,
00567 widthx/2,widthx/2,widthy/2,widthy/2);
00568 }
00569 ls = ls->next;
00570 }
00571 } else {
00572 if (image->aperture[curr_net->aperture] != NULL) {
00573 aperture_size = image->aperture[curr_net->aperture]->parameter[0];
00574 } else {
00575
00576
00577 aperture_size = 0;
00578 }
00579
00580
00581
00582
00583
00584 if (curr_net->aperture_state != GERBV_APERTURE_STATE_FLASH) {
00585 gerber_update_min_and_max (image->info, repeat_off_X, repeat_off_Y,
00586 curr_net->start_x, curr_net->start_y,
00587 aperture_size/2,aperture_size/2,
00588 aperture_size/2,aperture_size/2);
00589 }
00590 gerber_update_min_and_max (image->info, repeat_off_X, repeat_off_Y,
00591 curr_net->stop_x, curr_net->stop_y,
00592 aperture_size/2,aperture_size/2,
00593 aperture_size/2,aperture_size/2);
00594 }
00595 }
00596 break;
00597 case 10 :
00598 case 13 :
00599 case ' ' :
00600 case '\t' :
00601 case 0 :
00602 break;
00603 default:
00604 stats->unknown++;
00605 string = g_strdup_printf("Found unknown character (whitespace?) [%d]%c\n",
00606 read, read);
00607 gerbv_stats_add_error(stats->error_list,
00608 -1,
00609 string,
00610 GERBV_MESSAGE_ERROR);
00611 g_free(string);
00612 }
00613 }
00614 return foundEOF;
00615 }
00616
00617
00618
00625 gerbv_image_t *
00626 parse_gerb(gerb_file_t *fd, gchar *directoryPath)
00627 {
00628 gerb_state_t *state = NULL;
00629 gerbv_image_t *image = NULL;
00630 gerbv_net_t *curr_net = NULL;
00631 gerbv_stats_t *stats;
00632 gboolean foundEOF = FALSE;
00633 gchar *string;
00634
00635
00636
00637
00638
00639 setlocale(LC_NUMERIC, "C" );
00640
00641
00642
00643
00644
00645 state = g_new0 (gerb_state_t, 1);
00646
00647
00648
00649
00650 image = gerbv_create_image(image, "RS274-X (Gerber) File");
00651 if (image == NULL)
00652 GERB_FATAL_ERROR("malloc image failed\n");
00653 curr_net = image->netlist;
00654 image->layertype = GERBV_LAYERTYPE_RS274X;
00655 image->gerbv_stats = gerbv_stats_new();
00656 if (image->gerbv_stats == NULL)
00657 GERB_FATAL_ERROR("malloc gerbv_stats failed\n");
00658 stats = (gerbv_stats_t *) image->gerbv_stats;
00659
00660
00661 state->layer = image->layers;
00662 state->state = image->states;
00663 curr_net->layer = state->layer;
00664 curr_net->state = state->state;
00665
00666
00667
00668
00669 dprintf("In parse_gerb, starting to parse file...\n");
00670 foundEOF = gerber_parse_file_segment (1, image, state, curr_net, stats,
00671 fd, directoryPath);
00672
00673 if (!foundEOF) {
00674 string = g_strdup_printf("File %s is missing Gerber EOF code.\n", fd->filename);
00675 gerbv_stats_add_error(stats->error_list,
00676 -1,
00677 string,
00678 GERBV_MESSAGE_ERROR);
00679 g_free(string);
00680 }
00681 g_free(state);
00682
00683 dprintf(" ... done parsing Gerber file\n");
00684 gerber_update_any_running_knockout_measurements (image);
00685 gerber_calculate_final_justify_effects(image);
00686
00687 return image;
00688 }
00689
00690
00691
00695 gboolean
00696 gerber_is_rs274x_p(gerb_file_t *fd, gboolean *returnFoundBinary)
00697 {
00698 char *buf;
00699 int len = 0;
00700 char *letter;
00701 int i;
00702 gboolean found_binary = FALSE;
00703 gboolean found_ADD = FALSE;
00704 gboolean found_D0 = FALSE;
00705 gboolean found_D2 = FALSE;
00706 gboolean found_M0 = FALSE;
00707 gboolean found_M2 = FALSE;
00708 gboolean found_star = FALSE;
00709 gboolean found_X = FALSE;
00710 gboolean found_Y = FALSE;
00711
00712 dprintf ("gerber_is_rs274x_p(%p, %p), fd->fd = %p\n", fd, returnFoundBinary, fd->fd);
00713 buf = (char *) g_malloc(MAXL);
00714 if (buf == NULL)
00715 GERB_FATAL_ERROR("malloc buf failed while checking for rs274x.\n");
00716
00717 while (fgets(buf, MAXL, fd->fd) != NULL) {
00718 dprintf ("buf = \"%s\"\n", buf);
00719 len = strlen(buf);
00720
00721
00722
00723
00724
00725 for (i = 0; i < len; i++) {
00726 if (!isprint((int) buf[i]) && (buf[i] != '\r') &&
00727 (buf[i] != '\n') && (buf[i] != '\t')) {
00728 found_binary = TRUE;
00729 dprintf ("found_binary (%d)\n", buf[i]);
00730 }
00731 }
00732 if (g_strstr_len(buf, len, "%ADD")) {
00733 found_ADD = TRUE;
00734 dprintf ("found_ADD\n");
00735 }
00736 if (g_strstr_len(buf, len, "D00")) {
00737 found_D0 = TRUE;
00738 dprintf ("found_D0\n");
00739 }
00740 if (g_strstr_len(buf, len, "D02")) {
00741 found_D2 = TRUE;
00742 dprintf ("found_D2\n");
00743 }
00744 if (g_strstr_len(buf, len, "M0")) {
00745 found_M0 = TRUE;
00746 dprintf ("found_M0\n");
00747 }
00748 if (g_strstr_len(buf, len, "M00")) {
00749 found_M0 = TRUE;
00750 dprintf ("found_M0\n");
00751 }
00752 if (g_strstr_len(buf, len, "M2")) {
00753 found_M2 = TRUE;
00754 dprintf ("found_M2\n");
00755 }
00756 if (g_strstr_len(buf, len, "M02")) {
00757 found_M2 = TRUE;
00758 dprintf ("found_M2\n");
00759 }
00760 if (g_strstr_len(buf, len, "*")) {
00761 found_star = TRUE;
00762 dprintf ("found_star\n");
00763 }
00764
00765 if ((letter = g_strstr_len(buf, len, "X")) != NULL) {
00766 if (isdigit((int) letter[1])) {
00767 found_X = TRUE;
00768 dprintf ("found_X\n");
00769 }
00770 }
00771 if ((letter = g_strstr_len(buf, len, "Y")) != NULL) {
00772 if (isdigit((int) letter[1])) {
00773 found_Y = TRUE;
00774 dprintf ("found_Y\n");
00775 }
00776 }
00777 }
00778 rewind(fd->fd);
00779 free(buf);
00780
00781 *returnFoundBinary = found_binary;
00782
00783
00784 if ((found_D0 || found_D2 || found_M0 || found_M2) &&
00785 found_ADD && found_star && (found_X || found_Y))
00786 return TRUE;
00787
00788
00789 return FALSE;
00790
00791 }
00792
00793
00794
00798 gboolean
00799 gerber_is_rs274d_p(gerb_file_t *fd)
00800 {
00801 char *buf;
00802 int len = 0;
00803 char *letter;
00804 int i;
00805 gboolean found_binary = FALSE;
00806 gboolean found_ADD = FALSE;
00807 gboolean found_D0 = FALSE;
00808 gboolean found_D2 = FALSE;
00809 gboolean found_M0 = FALSE;
00810 gboolean found_M2 = FALSE;
00811 gboolean found_star = FALSE;
00812 gboolean found_X = FALSE;
00813 gboolean found_Y = FALSE;
00814
00815 buf = malloc(MAXL);
00816 if (buf == NULL)
00817 GERB_FATAL_ERROR("malloc buf failed while checking for rs274d.\n");
00818
00819 while (fgets(buf, MAXL, fd->fd) != NULL) {
00820 len = strlen(buf);
00821
00822
00823
00824
00825 for (i = 0; i < len; i++) {
00826 if (!isprint( (int) buf[i]) && (buf[i] != '\r') &&
00827 (buf[i] != '\n') && (buf[i] != '\t')) {
00828 found_binary = TRUE;
00829 }
00830 }
00831
00832 if (g_strstr_len(buf, len, "%ADD")) {
00833 found_ADD = TRUE;
00834 }
00835 if (g_strstr_len(buf, len, "D00")) {
00836 found_D0 = TRUE;
00837 }
00838 if (g_strstr_len(buf, len, "D02")) {
00839 found_D2 = TRUE;
00840 }
00841 if (g_strstr_len(buf, len, "M0")) {
00842 found_M0 = TRUE;
00843 }
00844 if (g_strstr_len(buf, len, "M00")) {
00845 found_M0 = TRUE;
00846 }
00847 if (g_strstr_len(buf, len, "M02")) {
00848 found_M2 = TRUE;
00849 }
00850 if (g_strstr_len(buf, len, "*")) {
00851 found_star = TRUE;
00852 }
00853
00854 if ((letter = g_strstr_len(buf, len, "X")) != NULL) {
00855
00856 if (isdigit( (int) letter[1])) {
00857 found_X = TRUE;
00858 }
00859 }
00860 if ((letter = g_strstr_len(buf, len, "Y")) != NULL) {
00861
00862 if (isdigit( (int) letter[1])) {
00863 found_Y = TRUE;
00864 }
00865 }
00866 }
00867 rewind(fd->fd);
00868 free(buf);
00869
00870
00871 if ((found_D0 || found_D2 || found_M0 || found_M2) &&
00872 !found_ADD && found_star && (found_X || found_Y) &&
00873 !found_binary)
00874 return TRUE;
00875
00876 return FALSE;
00877
00878 }
00879
00880
00881
00885 static void
00886 parse_G_code(gerb_file_t *fd, gerb_state_t *state, gerbv_image_t *image)
00887 {
00888 int op_int;
00889 gerbv_format_t *format = image->format;
00890 gerbv_stats_t *stats = image->gerbv_stats;
00891 int c;
00892 gchar *string;
00893
00894 op_int=gerb_fgetint(fd, NULL);
00895
00896 switch(op_int) {
00897 case 0:
00898
00899 stats->G0++;
00900 break;
00901 case 1:
00902 state->interpolation = GERBV_INTERPOLATION_LINEARx1;
00903 stats->G1++;
00904 break;
00905 case 2:
00906 state->interpolation = GERBV_INTERPOLATION_CW_CIRCULAR;
00907 stats->G2++;
00908 break;
00909 case 3:
00910 state->interpolation = GERBV_INTERPOLATION_CCW_CIRCULAR;
00911 stats->G3++;
00912 break;
00913 case 4:
00914
00915
00916
00917 c = gerb_fgetc(fd);
00918 while ((c != EOF) && (c != '*')) {
00919 c = gerb_fgetc(fd);
00920 }
00921 stats->G4++;
00922 break;
00923 case 10:
00924 state->interpolation = GERBV_INTERPOLATION_x10;
00925 stats->G10++;
00926 break;
00927 case 11:
00928 state->interpolation = GERBV_INTERPOLATION_LINEARx01;
00929 stats->G11++;
00930 break;
00931 case 12:
00932 state->interpolation = GERBV_INTERPOLATION_LINEARx001;
00933 stats->G12++;
00934 break;
00935 case 36:
00936 state->prev_interpolation = state->interpolation;
00937 state->interpolation = GERBV_INTERPOLATION_PAREA_START;
00938 state->changed = 1;
00939 stats->G36++;
00940 break;
00941 case 37:
00942 state->interpolation = GERBV_INTERPOLATION_PAREA_END;
00943 state->changed = 1;
00944 stats->G37++;
00945 break;
00946 case 54:
00947
00948 if (gerb_fgetc(fd) == 'D') {
00949 int a = gerb_fgetint(fd, NULL);
00950 if ((a >= APERTURE_MIN) && (a <= APERTURE_MAX)) {
00951 state->curr_aperture = a;
00952 } else {
00953 string = g_strdup_printf("Found aperture D%d out of bounds while parsing G code in file \n%s\n",
00954 a, fd->filename);
00955 gerbv_stats_add_error(stats->error_list,
00956 -1,
00957 string,
00958 GERBV_MESSAGE_ERROR);
00959 g_free(string);
00960 }
00961 } else {
00962 string = g_strdup_printf("Found unexpected code after G54 in file \n%s\n", fd->filename);
00963 gerbv_stats_add_error(stats->error_list,
00964 -1,
00965 string,
00966 GERBV_MESSAGE_ERROR);
00967 g_free(string);
00968
00969 }
00970 stats->G54++;
00971 break;
00972 case 55:
00973 stats->G55++;
00974 break;
00975 case 70:
00976 state->state = gerbv_image_return_new_netstate (state->state);
00977 state->state->unit = GERBV_UNIT_INCH;
00978 stats->G70++;
00979 break;
00980 case 71:
00981 state->state = gerbv_image_return_new_netstate (state->state);
00982 state->state->unit = GERBV_UNIT_MM;
00983 stats->G71++;
00984 break;
00985 case 74:
00986 state->mq_on = 0;
00987 stats->G74++;
00988 break;
00989 case 75:
00990 state->mq_on = 1;
00991 stats->G75++;
00992 break;
00993 case 90:
00994 if (format) format->coordinate = GERBV_COORDINATE_ABSOLUTE;
00995 stats->G90++;
00996 break;
00997 case 91:
00998 if (format) format->coordinate = GERBV_COORDINATE_INCREMENTAL;
00999 stats->G91++;
01000 break;
01001 default:
01002 string = g_strdup_printf("Encountered unknown G code G%d in file \n%s\n", op_int, fd->filename);
01003 gerbv_stats_add_error(stats->error_list,
01004 -1,
01005 string,
01006 GERBV_MESSAGE_ERROR);
01007 g_free(string);
01008 string = g_strdup_printf("Ignorning unknown G code G%d\n", op_int);
01009 gerbv_stats_add_error(stats->error_list,
01010 -1,
01011 string,
01012 GERBV_MESSAGE_WARNING);
01013 g_free(string);
01014 stats->G_unknown++;
01015
01016 break;
01017 }
01018
01019 return;
01020 }
01021
01022
01023
01027 static void
01028 parse_D_code(gerb_file_t *fd, gerb_state_t *state, gerbv_image_t *image)
01029 {
01030 int a;
01031 gerbv_stats_t *stats = image->gerbv_stats;
01032 gchar *string;
01033
01034 a = gerb_fgetint(fd, NULL);
01035 dprintf(" In parse_D_code, found D number = %d ... \n", a);
01036 switch(a) {
01037 case 0 :
01038 string = g_strdup_printf("Found invalid D00 code in file \n%s.\n", fd->filename);
01039 gerbv_stats_add_error(stats->error_list,
01040 -1,
01041 string,
01042 GERBV_MESSAGE_ERROR);
01043 g_free(string);
01044 stats->D_error++;
01045 break;
01046 case 1 :
01047 state->aperture_state = GERBV_APERTURE_STATE_ON;
01048 state->changed = 1;
01049 stats->D1++;
01050 break;
01051 case 2 :
01052 state->aperture_state = GERBV_APERTURE_STATE_OFF;
01053 state->changed = 1;
01054 stats->D2++;
01055 break;
01056 case 3 :
01057 state->aperture_state = GERBV_APERTURE_STATE_FLASH;
01058 state->changed = 1;
01059 stats->D3++;
01060 break;
01061 default:
01062 if ((a >= APERTURE_MIN) && (a <= APERTURE_MAX)) {
01063 state->curr_aperture = a;
01064
01065 } else {
01066 string = g_strdup_printf("Found out of bounds aperture D%d in file \n%s\n",
01067 a, fd->filename);
01068 gerbv_stats_add_error(stats->error_list,
01069 -1,
01070 string,
01071 GERBV_MESSAGE_ERROR);
01072 g_free(string);
01073 stats->D_error++;
01074 }
01075 state->changed = 0;
01076 break;
01077 }
01078
01079 return;
01080 }
01081
01082
01083
01084 static int
01085 parse_M_code(gerb_file_t *fd, gerbv_image_t *image)
01086 {
01087 int op_int;
01088 gerbv_stats_t *stats = image->gerbv_stats;
01089 gchar *string;
01090
01091 op_int=gerb_fgetint(fd, NULL);
01092
01093 switch (op_int) {
01094 case 0:
01095 stats->M0++;
01096 return 1;
01097 case 1:
01098 stats->M1++;
01099 return 2;
01100 case 2:
01101 stats->M2++;
01102 return 3;
01103 default:
01104 string = g_strdup_printf("Encountered unknown M code M%d in file \n%s\n",
01105 op_int, fd->filename);
01106 gerbv_stats_add_error(stats->error_list,
01107 -1,
01108 string,
01109 GERBV_MESSAGE_ERROR);
01110 g_free(string);
01111 string = g_strdup_printf("Ignorning unknown M code M%d\n", op_int);
01112 gerbv_stats_add_error(stats->error_list,
01113 -1,
01114 string,
01115 GERBV_MESSAGE_WARNING);
01116 g_free(string);
01117 stats->M_unknown++;
01118 }
01119 return 0;
01120 }
01121
01122
01123
01124 static void
01125 parse_rs274x(gint levelOfRecursion, gerb_file_t *fd, gerbv_image_t *image,
01126 gerb_state_t *state, gerbv_net_t *curr_net, gerbv_stats_t *stats,
01127 gchar *directoryPath)
01128 {
01129 int op[2];
01130 char str[3];
01131 int tmp;
01132 gerbv_aperture_t *a = NULL;
01133 gerbv_amacro_t *tmp_amacro;
01134 int ano;
01135 gdouble scale = 1.0;
01136 gchar *string;
01137
01138 if (state->state->unit == GERBV_UNIT_MM)
01139 scale = 25.4;
01140
01141 op[0] = gerb_fgetc(fd);
01142 op[1] = gerb_fgetc(fd);
01143
01144 if ((op[0] == EOF) || (op[1] == EOF)) {
01145 string = g_strdup_printf("Unexpected EOF found in file \n%s\n", fd->filename);
01146 gerbv_stats_add_error(stats->error_list,
01147 -1,
01148 string,
01149 GERBV_MESSAGE_ERROR);
01150 g_free(string);
01151 }
01152
01153 switch (A2I(op[0], op[1])){
01154
01155
01156
01157
01158 case A2I('A','S'):
01159 op[0] = gerb_fgetc(fd);
01160 op[1] = gerb_fgetc(fd);
01161 state->state = gerbv_image_return_new_netstate (state->state);
01162
01163 if ((op[0] == EOF) || (op[1] == EOF)) {
01164 string = g_strdup_printf("Unexpected EOF found in file \n%s\n", fd->filename);
01165 gerbv_stats_add_error(stats->error_list,
01166 -1,
01167 string,
01168 GERBV_MESSAGE_ERROR);
01169 g_free(string);
01170 }
01171
01172 if (((op[0] == 'A') && (op[1] == 'Y')) ||
01173 ((op[0] == 'B') && (op[1] == 'X'))) {
01174 state->state->axisSelect = GERBV_AXIS_SELECT_SWAPAB;
01175 } else {
01176 state->state->axisSelect = GERBV_AXIS_SELECT_NOSELECT;
01177 }
01178
01179 op[0] = gerb_fgetc(fd);
01180 op[1] = gerb_fgetc(fd);
01181
01182 if ((op[0] == EOF) || (op[1] == EOF)) {
01183 string = g_strdup_printf("Unexpected EOF found in file \n%s\n", fd->filename);
01184 gerbv_stats_add_error(stats->error_list,
01185 -1,
01186 string,
01187 GERBV_MESSAGE_ERROR);
01188 g_free(string);
01189 }
01190
01191 if (((op[0] == 'A') && (op[1] == 'Y')) ||
01192 ((op[0] == 'B') && (op[1] == 'X'))) {
01193 state->state->axisSelect = GERBV_AXIS_SELECT_SWAPAB;
01194 } else {
01195 state->state->axisSelect = GERBV_AXIS_SELECT_NOSELECT;
01196 }
01197 break;
01198
01199 case A2I('F','S'):
01200 image->format = g_new0 (gerbv_format_t,1);
01201
01202 switch (gerb_fgetc(fd)) {
01203 case 'L':
01204 image->format->omit_zeros = GERBV_OMIT_ZEROS_LEADING;
01205 break;
01206 case 'T':
01207 image->format->omit_zeros = GERBV_OMIT_ZEROS_TRAILING;
01208 break;
01209 case 'D':
01210 image->format->omit_zeros = GERBV_OMIT_ZEROS_EXPLICIT;
01211 break;
01212 default:
01213 string = g_strdup_printf("EagleCad bug detected: Undefined handling of zeros in format code in file \n%s\n",
01214 fd->filename);
01215 gerbv_stats_add_error(stats->error_list,
01216 -1,
01217 string,
01218 GERBV_MESSAGE_ERROR);
01219 g_free(string);
01220 string = g_strdup_printf("Defaulting to omitting leading zeros.\n");
01221 gerbv_stats_add_error(stats->error_list,
01222 -1,
01223 string,
01224 GERBV_MESSAGE_WARNING);
01225 g_free(string);
01226 gerb_ungetc(fd);
01227 image->format->omit_zeros = GERBV_OMIT_ZEROS_LEADING;
01228 }
01229
01230 switch (gerb_fgetc(fd)) {
01231 case 'A':
01232 image->format->coordinate = GERBV_COORDINATE_ABSOLUTE;
01233 break;
01234 case 'I':
01235 image->format->coordinate = GERBV_COORDINATE_INCREMENTAL;
01236 break;
01237 default:
01238 string = g_strdup_printf("Invalid coordinate type defined in format code in file \n%s\n",
01239 fd->filename);
01240 gerbv_stats_add_error(stats->error_list,
01241 -1,
01242 string,
01243 GERBV_MESSAGE_ERROR);
01244 g_free(string);
01245 string = g_strdup_printf("Defaulting to absolute coordinates.\n");
01246 gerbv_stats_add_error(stats->error_list,
01247 -1,
01248 string,
01249 GERBV_MESSAGE_WARNING);
01250 g_free(string);
01251 image->format->coordinate = GERBV_COORDINATE_ABSOLUTE;
01252 }
01253 op[0] = gerb_fgetc(fd);
01254 while((op[0] != '*')&&(op[0] != EOF)) {
01255 switch (op[0]) {
01256 case 'N':
01257 op[0] = (char)gerb_fgetc(fd);
01258 image->format->lim_seqno = op[0] - '0';
01259 break;
01260 case 'G':
01261 op[0] = (char)gerb_fgetc(fd);
01262 image->format->lim_gf = op[0] - '0';
01263 break;
01264 case 'D':
01265 op[0] = (char)gerb_fgetc(fd);
01266 image->format->lim_pf = op[0] - '0';
01267 break;
01268 case 'M':
01269 op[0] = (char)gerb_fgetc(fd);
01270 image->format->lim_mf = op[0] - '0';
01271 break;
01272 case 'X' :
01273 op[0] = gerb_fgetc(fd);
01274 if ((op[0] < '0') || (op[0] > '6')) {
01275 string = g_strdup_printf("Illegal format size %c in file \n%s\n",
01276 (char)op[0], fd->filename);
01277 gerbv_stats_add_error(stats->error_list,
01278 -1,
01279 string,
01280 GERBV_MESSAGE_ERROR);
01281 g_free(string);
01282 }
01283 image->format->x_int = op[0] - '0';
01284 op[0] = gerb_fgetc(fd);
01285 if ((op[0] < '0') || (op[0] > '6')) {
01286 string = g_strdup_printf("Illegal format size %c in file \n%s\n",
01287 (char)op[0], fd->filename);
01288 gerbv_stats_add_error(stats->error_list,
01289 -1,
01290 string,
01291 GERBV_MESSAGE_ERROR);
01292 g_free(string);
01293 }
01294 image->format->x_dec = op[0] - '0';
01295 break;
01296 case 'Y':
01297 op[0] = gerb_fgetc(fd);
01298 if ((op[0] < '0') || (op[0] > '6')) {
01299 string = g_strdup_printf("Illegal format size %c in file \n%s\n",
01300 (char)op[0], fd->filename);
01301 gerbv_stats_add_error(stats->error_list,
01302 -1,
01303 string,
01304 GERBV_MESSAGE_ERROR);
01305 g_free(string);
01306 }
01307 image->format->y_int = op[0] - '0';
01308 op[0] = gerb_fgetc(fd);
01309 if ((op[0] < '0') || (op[0] > '6')) {
01310 string = g_strdup_printf("Illegal format size %c in file \n%s\n",
01311 (char)op[0], fd->filename);
01312 gerbv_stats_add_error(stats->error_list,
01313 -1,
01314 string,
01315 GERBV_MESSAGE_ERROR);
01316 g_free(string);
01317 }
01318 image->format->y_dec = op[0] - '0';
01319 break;
01320 default :
01321 string = g_strdup_printf("Illegal format statement [%c] in file \n%s\n",
01322 op[0], fd->filename);
01323 gerbv_stats_add_error(stats->error_list,
01324 -1,
01325 string,
01326 GERBV_MESSAGE_ERROR);
01327 g_free(string);
01328 string = g_strdup_printf("Ignoring invalid format statement.\n");
01329 gerbv_stats_add_error(stats->error_list,
01330 -1,
01331 string,
01332 GERBV_MESSAGE_WARNING);
01333 g_free(string);
01334 }
01335 op[0] = gerb_fgetc(fd);
01336 }
01337 break;
01338 case A2I('M','I'):
01339 op[0] = gerb_fgetc(fd);
01340 state->state = gerbv_image_return_new_netstate (state->state);
01341
01342 while ((op[0] != '*')&&(op[0] != EOF)) {
01343 gint readValue=0;
01344 switch (op[0]) {
01345 case 'A' :
01346 readValue = gerb_fgetint(fd, NULL);
01347 if (readValue == 1) {
01348 if (state->state->mirrorState == GERBV_MIRROR_STATE_FLIPB)
01349 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPAB;
01350 else
01351 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPA;
01352 }
01353 break;
01354 case 'B' :
01355 readValue = gerb_fgetint(fd, NULL);
01356 if (readValue == 1) {
01357 if (state->state->mirrorState == GERBV_MIRROR_STATE_FLIPA)
01358 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPAB;
01359 else
01360 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPB;
01361 }
01362 break;
01363 default :
01364 string = g_strdup_printf("Wrong character in mirror:%c\n", op[0]);
01365 gerbv_stats_add_error(stats->error_list,
01366 -1,
01367 string,
01368 GERBV_MESSAGE_ERROR);
01369 g_free(string);
01370 }
01371 op[0] = gerb_fgetc(fd);
01372 }
01373 break;
01374 case A2I('M','O'):
01375 op[0] = gerb_fgetc(fd);
01376 op[1] = gerb_fgetc(fd);
01377
01378 if ((op[0] == EOF) || (op[1] == EOF))
01379 gerbv_stats_add_error(stats->error_list,
01380 -1,
01381 "Unexpected EOF found.\n",
01382 GERBV_MESSAGE_ERROR);
01383 switch (A2I(op[0],op[1])) {
01384 case A2I('I','N'):
01385 state->state = gerbv_image_return_new_netstate (state->state);
01386 state->state->unit = GERBV_UNIT_INCH;
01387 break;
01388 case A2I('M','M'):
01389 state->state = gerbv_image_return_new_netstate (state->state);
01390 state->state->unit = GERBV_UNIT_MM;
01391 break;
01392 default:
01393 string = g_strdup_printf("Illegal unit:%c%c\n", op[0], op[1]);
01394 gerbv_stats_add_error(stats->error_list,
01395 -1,
01396 string,
01397 GERBV_MESSAGE_ERROR);
01398 g_free(string);
01399 }
01400 break;
01401 case A2I('O','F'):
01402 op[0] = gerb_fgetc(fd);
01403
01404 while ((op[0] != '*')&&(op[0] != EOF)) {
01405 switch (op[0]) {
01406 case 'A' :
01407 state->state->offsetA = gerb_fgetdouble(fd) / scale;
01408 break;
01409 case 'B' :
01410 state->state->offsetB = gerb_fgetdouble(fd) / scale;
01411 break;
01412 default :
01413 string = g_strdup_printf("Wrong character in offset:%c\n", op[0]);
01414 gerbv_stats_add_error(stats->error_list,
01415 -1,
01416 string,
01417 GERBV_MESSAGE_ERROR);
01418 g_free(string);
01419 }
01420 op[0] = gerb_fgetc(fd);
01421 }
01422 break;
01423 case A2I('I','F'):
01424 {
01425 gchar *includeFilename = gerb_fgetstring(fd, '*');
01426
01427 if (includeFilename) {
01428 gchar *fullPath;
01429 if (!g_path_is_absolute(includeFilename)) {
01430 fullPath = g_build_filename (directoryPath, includeFilename, NULL);
01431 } else {
01432 fullPath = g_strdup (includeFilename);
01433 }
01434 if (levelOfRecursion < 10) {
01435 gerb_file_t *includefd = NULL;
01436
01437 includefd = gerb_fopen(fullPath);
01438 if (includefd) {
01439 gerber_parse_file_segment (levelOfRecursion + 1, image, state, curr_net, stats, includefd, directoryPath);
01440 gerb_fclose(includefd);
01441 } else {
01442 string = g_strdup_printf("In file %s,\nIncluded file %s cannot be found\n",
01443 fd->filename, fullPath);
01444 gerbv_stats_add_error(stats->error_list,
01445 -1,
01446 string,
01447 GERBV_MESSAGE_ERROR);
01448 g_free(string);
01449 }
01450 g_free (fullPath);
01451 } else {
01452 string = g_strdup_printf("Parser encountered more than 10 levels of include file recursion which is not allowed by the RS-274X spec\n");
01453 gerbv_stats_add_error(stats->error_list,
01454 -1,
01455 string,
01456 GERBV_MESSAGE_ERROR);
01457 g_free(string);
01458 }
01459
01460 }
01461 }
01462 break;
01463 case A2I('I','O'):
01464 op[0] = gerb_fgetc(fd);
01465
01466 while ((op[0] != '*')&&(op[0] != EOF)) {
01467 switch (op[0]) {
01468 case 'A' :
01469 image->info->offsetA = gerb_fgetdouble(fd) / scale;
01470 break;
01471 case 'B' :
01472 image->info->offsetB = gerb_fgetdouble(fd) / scale;
01473 break;
01474 default :
01475 string = g_strdup_printf("In file %s,\nwrong character in image offset %c\n",
01476 fd->filename, op[0]);
01477 gerbv_stats_add_error(stats->error_list,
01478 -1,
01479 string,
01480 GERBV_MESSAGE_ERROR);
01481 g_free(string);
01482 }
01483 op[0] = gerb_fgetc(fd);
01484 }
01485 break;
01486 case A2I('S','F'):
01487 if (gerb_fgetc(fd) == 'A')
01488 state->state->scaleA = gerb_fgetdouble(fd);
01489 else
01490 gerb_ungetc(fd);
01491 if (gerb_fgetc(fd) == 'B')
01492 state->state->scaleB = gerb_fgetdouble(fd);
01493 else
01494 gerb_ungetc(fd);
01495 break;
01496 case A2I('I','C'):
01497
01498
01499
01500
01501
01502 op[0] = gerb_fgetc(fd);
01503 op[1] = gerb_fgetc(fd);
01504
01505 if ((op[0] == EOF) || (op[1] == EOF)) {
01506 string = g_strdup_printf("Unexpected EOF found in file \n%s\n", fd->filename);
01507 gerbv_stats_add_error(stats->error_list,
01508 -1,
01509 string,
01510 GERBV_MESSAGE_ERROR);
01511 g_free(string);
01512 }
01513 switch (A2I(op[0],op[1])) {
01514 case A2I('A','S'):
01515 image->info->encoding = GERBV_ENCODING_ASCII;
01516 break;
01517 case A2I('E','B'):
01518 image->info->encoding = GERBV_ENCODING_EBCDIC;
01519 break;
01520 case A2I('B','C'):
01521 image->info->encoding = GERBV_ENCODING_BCD;
01522 break;
01523 case A2I('I','S'):
01524 image->info->encoding = GERBV_ENCODING_ISO_ASCII;
01525 break;
01526 case A2I('E','I'):
01527 image->info->encoding = GERBV_ENCODING_EIA;
01528 break;
01529 default:
01530 string = g_strdup_printf("In file %s, \nunknown input code (IC): %c%c\n",
01531 fd->filename, op[0], op[1]);
01532 gerbv_stats_add_error(stats->error_list,
01533 -1,
01534 string,
01535 GERBV_MESSAGE_ERROR);
01536 g_free(string);
01537 }
01538 break;
01539
01540
01541 case A2I('I','J'):
01542 op[0] = gerb_fgetc(fd);
01543 image->info->imageJustifyTypeA = GERBV_JUSTIFY_LOWERLEFT;
01544 image->info->imageJustifyTypeB = GERBV_JUSTIFY_LOWERLEFT;
01545 image->info->imageJustifyOffsetA = 0.0;
01546 image->info->imageJustifyOffsetB = 0.0;
01547 while ((op[0] != '*')&&(op[0] != EOF)) {
01548 switch (op[0]) {
01549 case 'A' :
01550 op[0] = gerb_fgetc(fd);
01551 if (op[0] == 'C') {
01552 image->info->imageJustifyTypeA = GERBV_JUSTIFY_CENTERJUSTIFY;
01553 } else if (op[0] == 'L') {
01554 image->info->imageJustifyTypeA = GERBV_JUSTIFY_LOWERLEFT;
01555 } else {
01556 gerb_ungetc (fd);
01557 image->info->imageJustifyOffsetA = gerb_fgetdouble(fd) / scale;
01558 }
01559 break;
01560 case 'B' :
01561 op[0] = gerb_fgetc(fd);
01562 if (op[0] == 'C') {
01563 image->info->imageJustifyTypeB = GERBV_JUSTIFY_CENTERJUSTIFY;
01564 } else if (op[0] == 'L') {
01565 image->info->imageJustifyTypeB = GERBV_JUSTIFY_LOWERLEFT;
01566 } else {
01567 gerb_ungetc (fd);
01568 image->info->imageJustifyOffsetB = gerb_fgetdouble(fd) / scale;
01569 }
01570 break;
01571 default :
01572 string = g_strdup_printf("In file %s,\nwrong character in image justify:%c\n",
01573 fd->filename, op[0]);
01574 gerbv_stats_add_error(stats->error_list,
01575 -1,
01576 string,
01577 GERBV_MESSAGE_ERROR);
01578 g_free(string);
01579 }
01580 op[0] = gerb_fgetc(fd);
01581 }
01582 break;
01583 case A2I('I','N'):
01584 image->info->name = gerb_fgetstring(fd, '*');
01585 break;
01586 case A2I('I','P'):
01587
01588 for (ano = 0; ano < 3; ano++) {
01589 op[0] = gerb_fgetc(fd);
01590 if (op[0] == EOF) {
01591 string = g_strdup_printf("In file %s,\nunexpected EOF while reading image polarity (IP)\n",
01592 fd->filename);
01593 gerbv_stats_add_error(stats->error_list,
01594 -1,
01595 string,
01596 GERBV_MESSAGE_ERROR);
01597 g_free(string);
01598 }
01599 str[ano] = (char)op[0];
01600 }
01601
01602 if (strncmp(str, "POS", 3) == 0)
01603 image->info->polarity = GERBV_POLARITY_POSITIVE;
01604 else if (strncmp(str, "NEG", 3) == 0)
01605 image->info->polarity = GERBV_POLARITY_NEGATIVE;
01606 else {
01607 string = g_strdup_printf("Unknown polarity : %c%c%c\n", str[0], str[1], str[2]);
01608 gerbv_stats_add_error(stats->error_list,
01609 -1,
01610 string,
01611 GERBV_MESSAGE_ERROR);
01612 g_free(string);
01613 }
01614 break;
01615 case A2I('I','R'):
01616 tmp = gerb_fgetint(fd, NULL);
01617 if (tmp == 90)
01618 image->info->imageRotation = M_PI / 2.0;
01619 else if (tmp == 180)
01620 image->info->imageRotation = M_PI;
01621 else if (tmp == 270)
01622 image->info->imageRotation = 3.0 * M_PI / 2.0;
01623 else {
01624 string = g_strdup_printf("Image rotation must be 0, 90, 180 or 270 (is actually %d)\n", tmp);
01625 gerbv_stats_add_error(stats->error_list,
01626 -1,
01627 string,
01628 GERBV_MESSAGE_ERROR);
01629 g_free(string);
01630 }
01631 break;
01632 case A2I('P','F'):
01633 image->info->plotterFilm = gerb_fgetstring(fd, '*');
01634 break;
01635
01636
01637 case A2I('A','D'):
01638 a = (gerbv_aperture_t *) g_new0 (gerbv_aperture_t,1);
01639
01640 ano = parse_aperture_definition(fd, a, image, scale);
01641 if ((ano >= APERTURE_MIN) && (ano <= APERTURE_MAX)) {
01642 a->unit = state->state->unit;
01643 image->aperture[ano] = a;
01644 dprintf(" In parse_rs274x, adding new aperture to aperture list ...\n");
01645 gerbv_stats_add_aperture(stats->aperture_list,
01646 -1, ano,
01647 a->type,
01648 a->parameter);
01649 gerbv_stats_add_to_D_list(stats->D_code_list,
01650 ano);
01651 } else {
01652 string = g_strdup_printf("In file %s,\naperture number out of bounds : %d\n",
01653 fd->filename, ano);
01654 gerbv_stats_add_error(stats->error_list,
01655 -1,
01656 string,
01657 GERBV_MESSAGE_ERROR);
01658 g_free(string);
01659 }
01660
01661
01662 break;
01663 case A2I('A','M'):
01664 tmp_amacro = image->amacro;
01665 image->amacro = parse_aperture_macro(fd);
01666 if (image->amacro) {
01667 image->amacro->next = tmp_amacro;
01668 #ifdef AMACRO_DEBUG
01669 print_program(image->amacro);
01670 #endif
01671 } else {
01672 string = g_strdup_printf("In file %s, \nfailed to parse aperture macro\n",
01673 fd->filename);
01674 gerbv_stats_add_error(stats->error_list,
01675 -1,
01676 string,
01677 GERBV_MESSAGE_ERROR);
01678 g_free(string);
01679 }
01680 break;
01681
01682 case A2I('L','N'):
01683 state->layer = gerbv_image_return_new_layer (state->layer);
01684 state->layer->name = gerb_fgetstring(fd, '*');
01685 break;
01686 case A2I('L','P'):
01687 state->layer = gerbv_image_return_new_layer (state->layer);
01688 switch (gerb_fgetc(fd)) {
01689 case 'D':
01690 state->layer->polarity = GERBV_POLARITY_DARK;
01691 break;
01692 case 'C':
01693 state->layer->polarity = GERBV_POLARITY_CLEAR;
01694 break;
01695 default:
01696 string = g_strdup_printf("In file %s,\nunknown Layer Polarity: %c\n",
01697 fd->filename, op[0]);
01698 gerbv_stats_add_error(stats->error_list,
01699 -1,
01700 string,
01701 GERBV_MESSAGE_ERROR);
01702 g_free(string);
01703 }
01704 break;
01705 case A2I('K','O'):
01706 state->layer = gerbv_image_return_new_layer (state->layer);
01707 gerber_update_any_running_knockout_measurements (image);
01708
01709 knockoutMeasure = FALSE;
01710 op[0] = gerb_fgetc(fd);
01711 if (op[0] == '*') {
01712 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_NOKNOCKOUT;
01713 break;
01714 } else if (op[0] == 'C') {
01715 state->layer->knockout.polarity = GERBV_POLARITY_CLEAR;
01716 } else if (op[0] == 'D') {
01717 state->layer->knockout.polarity = GERBV_POLARITY_DARK;
01718 } else {
01719 string = g_strdup_printf("In file %s,\nknockout must supply a polarity (C, D, or *)\n",
01720 fd->filename);
01721 gerbv_stats_add_error(stats->error_list,
01722 -1,
01723 string,
01724 GERBV_MESSAGE_ERROR);
01725 g_free(string);
01726 }
01727 state->layer->knockout.lowerLeftX = 0.0;
01728 state->layer->knockout.lowerLeftY = 0.0;
01729 state->layer->knockout.width = 0.0;
01730 state->layer->knockout.height = 0.0;
01731 state->layer->knockout.border = 0.0;
01732 state->layer->knockout.firstInstance = TRUE;
01733 op[0] = gerb_fgetc(fd);
01734 while ((op[0] != '*')&&(op[0] != EOF)) {
01735 switch (op[0]) {
01736 case 'X':
01737 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
01738 state->layer->knockout.lowerLeftX = gerb_fgetdouble(fd) / scale;
01739 break;
01740 case 'Y':
01741 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
01742 state->layer->knockout.lowerLeftY = gerb_fgetdouble(fd) / scale;
01743 break;
01744 case 'I':
01745 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
01746 state->layer->knockout.width = gerb_fgetdouble(fd) / scale;
01747 break;
01748 case 'J':
01749 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
01750 state->layer->knockout.height = gerb_fgetdouble(fd) / scale;
01751 break;
01752 case 'K':
01753 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_BORDER;
01754 state->layer->knockout.border = gerb_fgetdouble(fd) / scale;
01755
01756
01757 knockoutMeasure = TRUE;
01758 knockoutLimitXmin = HUGE_VAL;
01759 knockoutLimitYmin = HUGE_VAL;
01760 knockoutLimitXmax = -HUGE_VAL;
01761 knockoutLimitYmax = -HUGE_VAL;
01762 knockoutLayer = state->layer;
01763 break;
01764 default:
01765 string = g_strdup_printf("In file %s, \nunknown variable in knockout",
01766 fd->filename);
01767 gerbv_stats_add_error(stats->error_list,
01768 -1,
01769 string,
01770 GERBV_MESSAGE_ERROR);
01771 g_free(string);
01772 }
01773 op[0] = gerb_fgetc(fd);
01774 }
01775 break;
01776 case A2I('S','R'):
01777
01778 state->layer = gerbv_image_return_new_layer (state->layer);
01779 op[0] = gerb_fgetc(fd);
01780 if (op[0] == '*') {
01781 state->layer->stepAndRepeat.X = 1;
01782 state->layer->stepAndRepeat.Y = 1;
01783 state->layer->stepAndRepeat.dist_X = 0.0;
01784 state->layer->stepAndRepeat.dist_Y = 0.0;
01785 break;
01786 }
01787 while ((op[0] != '*')&&(op[0] != EOF)) {
01788 switch (op[0]) {
01789 case 'X':
01790 state->layer->stepAndRepeat.X = gerb_fgetint(fd, NULL);
01791 break;
01792 case 'Y':
01793 state->layer->stepAndRepeat.Y = gerb_fgetint(fd, NULL);
01794 break;
01795 case 'I':
01796 state->layer->stepAndRepeat.dist_X = gerb_fgetdouble(fd) / scale;
01797 break;
01798 case 'J':
01799 state->layer->stepAndRepeat.dist_Y = gerb_fgetdouble(fd) / scale;
01800 break;
01801 default:
01802 string = g_strdup_printf("In file %s,\nstep-and-repeat parameter error\n",
01803 fd->filename);
01804 gerbv_stats_add_error(stats->error_list,
01805 -1,
01806 string,
01807 GERBV_MESSAGE_ERROR);
01808 g_free(string);
01809 }
01810
01811
01812
01813
01814
01815
01816 if(state->layer->stepAndRepeat.X == 0)
01817 state->layer->stepAndRepeat.X = 1;
01818 if(state->layer->stepAndRepeat.Y == 0)
01819 state->layer->stepAndRepeat.Y = 1;
01820
01821 op[0] = gerb_fgetc(fd);
01822 }
01823 break;
01824
01825 case A2I('R','O'):
01826 state->layer = gerbv_image_return_new_layer (state->layer);
01827
01828 state->layer->rotation = gerb_fgetdouble(fd) * M_PI / 180;
01829 op[0] = gerb_fgetc(fd);
01830 if (op[0] != '*') {
01831 string = g_strdup_printf("In file %s,\nerror in layer rotation command\n",
01832 fd->filename);
01833 gerbv_stats_add_error(stats->error_list,
01834 -1,
01835 string,
01836 GERBV_MESSAGE_ERROR);
01837 g_free(string);
01838 }
01839 break;
01840 default:
01841 string = g_strdup_printf("In file %s,\nunknown RS-274X extension found %%%c%c%%\n",
01842 fd->filename, op[0], op[1]);
01843 gerbv_stats_add_error(stats->error_list,
01844 -1,
01845 string,
01846 GERBV_MESSAGE_ERROR);
01847 g_free(string);
01848 }
01849
01850 return;
01851 }
01852
01853
01854
01855
01856
01857
01858 typedef struct {
01859 double *stack;
01860 int sp;
01861 } macro_stack_t;
01862
01863
01864 static macro_stack_t *
01865 new_stack(unsigned int stack_size)
01866 {
01867 macro_stack_t *s;
01868
01869 s = (macro_stack_t *) g_new0 (macro_stack_t,1);
01870 s->stack = (double *) g_new0 (double, stack_size);
01871 s->sp = 0;
01872 return s;
01873 }
01874
01875
01876 static void
01877 free_stack(macro_stack_t *s)
01878 {
01879 if (s && s->stack)
01880 free(s->stack);
01881
01882 if (s)
01883 free(s);
01884
01885 return;
01886 }
01887
01888
01889 static void
01890 push(macro_stack_t *s, double val)
01891 {
01892 s->stack[s->sp++] = val;
01893 return;
01894 }
01895
01896
01897 static int
01898 pop(macro_stack_t *s, double *value)
01899 {
01900
01901 if (s->sp == 0) {
01902 return -1;
01903 }
01904
01905 *value = s->stack[--s->sp];
01906 return 0;
01907 }
01908
01909
01910
01911 static int
01912 simplify_aperture_macro(gerbv_aperture_t *aperture, gdouble scale)
01913 {
01914 const int extra_stack_size = 10;
01915 macro_stack_t *s;
01916 gerbv_instruction_t *ip;
01917 int handled = 1, nuf_parameters = 0, i, j, clearOperatorUsed = FALSE;
01918 double *lp;
01919 double tmp[2] = {0.0, 0.0};
01920 gerbv_aperture_type_t type = GERBV_APTYPE_NONE;
01921 gerbv_simplified_amacro_t *sam;
01922
01923 if (aperture == NULL)
01924 GERB_FATAL_ERROR("aperture NULL in simplify aperture macro\n");
01925
01926 if (aperture->amacro == NULL)
01927 GERB_FATAL_ERROR("aperture->amacro NULL in simplify aperture macro\n");
01928
01929
01930 s = new_stack(aperture->amacro->nuf_push + extra_stack_size);
01931 if (s == NULL)
01932 GERB_FATAL_ERROR("malloc stack failed\n");
01933
01934
01935 lp = (double *)malloc(sizeof(double) * APERTURE_PARAMETERS_MAX);
01936 if (lp == NULL)
01937 GERB_FATAL_ERROR("malloc local parameter storage failed\n");
01938
01939 memcpy(lp, aperture->parameter, sizeof(double) * APERTURE_PARAMETERS_MAX);
01940
01941 for(ip = aperture->amacro->program; ip != NULL; ip = ip->next) {
01942 switch(ip->opcode) {
01943 case GERBV_OPCODE_NOP:
01944 break;
01945 case GERBV_OPCODE_PUSH :
01946 push(s, ip->data.fval);
01947 break;
01948 case GERBV_OPCODE_PPUSH :
01949 push(s, lp[ip->data.ival - 1]);
01950 break;
01951 case GERBV_OPCODE_PPOP:
01952 if (pop(s, &tmp[0]) < 0)
01953 GERB_FATAL_ERROR("Tried to pop an empty stack");
01954 lp[ip->data.ival - 1] = tmp[0];
01955 break;
01956 case GERBV_OPCODE_ADD :
01957 if (pop(s, &tmp[0]) < 0)
01958 GERB_FATAL_ERROR("Tried to pop an empty stack");
01959 if (pop(s, &tmp[1]) < 0)
01960 GERB_FATAL_ERROR("Tried to pop an empty stack");
01961 push(s, tmp[1] + tmp[0]);
01962 break;
01963 case GERBV_OPCODE_SUB :
01964 if (pop(s, &tmp[0]) < 0)
01965 GERB_FATAL_ERROR("Tried to pop an empty stack");
01966 if (pop(s, &tmp[1]) < 0)
01967 GERB_FATAL_ERROR("Tried to pop an empty stack");
01968 push(s, tmp[1] - tmp[0]);
01969 break;
01970 case GERBV_OPCODE_MUL :
01971 if (pop(s, &tmp[0]) < 0)
01972 GERB_FATAL_ERROR("Tried to pop an empty stack");
01973 if (pop(s, &tmp[1]) < 0)
01974 GERB_FATAL_ERROR("Tried to pop an empty stack");
01975 push(s, tmp[1] * tmp[0]);
01976 break;
01977 case GERBV_OPCODE_DIV :
01978 if (pop(s, &tmp[0]) < 0)
01979 GERB_FATAL_ERROR("Tried to pop an empty stack");
01980 if (pop(s, &tmp[1]) < 0)
01981 GERB_FATAL_ERROR("Tried to pop an empty stack");
01982 push(s, tmp[1] / tmp[0]);
01983 break;
01984 case GERBV_OPCODE_PRIM :
01985
01986
01987
01988
01989
01990 switch(ip->data.ival) {
01991 case 1:
01992 dprintf(" Aperture macro circle [1] (");
01993 type = GERBV_APTYPE_MACRO_CIRCLE;
01994 nuf_parameters = 4;
01995 break;
01996 case 3:
01997 break;
01998 case 4 :
01999 dprintf(" Aperture macro outline [4] (");
02000 type = GERBV_APTYPE_MACRO_OUTLINE;
02001
02002
02003
02004
02005
02006
02007 nuf_parameters = ((int)s->stack[1] + 1) * 2 + 3;
02008 break;
02009 case 5 :
02010 dprintf(" Aperture macro polygon [5] (");
02011 type = GERBV_APTYPE_MACRO_POLYGON;
02012 nuf_parameters = 6;
02013 break;
02014 case 6 :
02015 dprintf(" Aperture macro moiré [6] (");
02016 type = GERBV_APTYPE_MACRO_MOIRE;
02017 nuf_parameters = 9;
02018 break;
02019 case 7 :
02020 dprintf(" Aperture macro thermal [7] (");
02021 type = GERBV_APTYPE_MACRO_THERMAL;
02022 nuf_parameters = 6;
02023 break;
02024 case 2 :
02025 case 20 :
02026 dprintf(" Aperture macro line 20/2 (");
02027 type = GERBV_APTYPE_MACRO_LINE20;
02028 nuf_parameters = 7;
02029 break;
02030 case 21 :
02031 dprintf(" Aperture macro line 21 (");
02032 type = GERBV_APTYPE_MACRO_LINE21;
02033 nuf_parameters = 6;
02034 break;
02035 case 22 :
02036 dprintf(" Aperture macro line 22 (");
02037 type = GERBV_APTYPE_MACRO_LINE22;
02038 nuf_parameters = 6;
02039 break;
02040 default :
02041 handled = 0;
02042 }
02043
02044 if (type != GERBV_APTYPE_NONE) {
02045 if (nuf_parameters > APERTURE_PARAMETERS_MAX) {
02046 GERB_COMPILE_ERROR("Number of parameters to aperture macro are more than gerbv is able to store\n");
02047 }
02048
02049
02050
02051
02052
02053 sam = (gerbv_simplified_amacro_t *)malloc(sizeof(gerbv_simplified_amacro_t));
02054 if (sam == NULL)
02055 GERB_FATAL_ERROR("Failed to malloc simplified aperture macro\n");
02056 sam->type = type;
02057 sam->next = NULL;
02058 memset(sam->parameter, 0,
02059 sizeof(double) * APERTURE_PARAMETERS_MAX);
02060 memcpy(sam->parameter, s->stack,
02061 sizeof(double) * nuf_parameters);
02062
02063
02064 switch (type) {
02065 case GERBV_APTYPE_MACRO_CIRCLE:
02066 if (fabs(sam->parameter[0]) < 0.001)
02067 clearOperatorUsed = TRUE;
02068 sam->parameter[1]/=scale;
02069 sam->parameter[2]/=scale;
02070 sam->parameter[3]/=scale;
02071 break;
02072 case GERBV_APTYPE_MACRO_OUTLINE:
02073 if (fabs(sam->parameter[0]) < 0.001)
02074 clearOperatorUsed = TRUE;
02075 for (j=2; j<nuf_parameters-1; j++){
02076 sam->parameter[j]/=scale;
02077 }
02078 break;
02079 case GERBV_APTYPE_MACRO_POLYGON:
02080 if (fabs(sam->parameter[0]) < 0.001)
02081 clearOperatorUsed = TRUE;
02082 sam->parameter[2]/=scale;
02083 sam->parameter[3]/=scale;
02084 sam->parameter[4]/=scale;
02085 break;
02086 case GERBV_APTYPE_MACRO_MOIRE:
02087 sam->parameter[0]/=scale;
02088 sam->parameter[1]/=scale;
02089 sam->parameter[2]/=scale;
02090 sam->parameter[3]/=scale;
02091 sam->parameter[4]/=scale;
02092 sam->parameter[6]/=scale;
02093 sam->parameter[7]/=scale;
02094 break;
02095 case GERBV_APTYPE_MACRO_THERMAL:
02096 sam->parameter[0]/=scale;
02097 sam->parameter[1]/=scale;
02098 sam->parameter[2]/=scale;
02099 sam->parameter[3]/=scale;
02100 sam->parameter[4]/=scale;
02101 break;
02102 case GERBV_APTYPE_MACRO_LINE20:
02103 if (fabs(sam->parameter[0]) < 0.001)
02104 clearOperatorUsed = TRUE;
02105 sam->parameter[1]/=scale;
02106 sam->parameter[2]/=scale;
02107 sam->parameter[3]/=scale;
02108 sam->parameter[4]/=scale;
02109 sam->parameter[5]/=scale;
02110 break;
02111 case GERBV_APTYPE_MACRO_LINE21:
02112 case GERBV_APTYPE_MACRO_LINE22:
02113 if (fabs(sam->parameter[0]) < 0.001)
02114 clearOperatorUsed = TRUE;
02115 sam->parameter[1]/=scale;
02116 sam->parameter[2]/=scale;
02117 sam->parameter[3]/=scale;
02118 sam->parameter[4]/=scale;
02119 break;
02120 default:
02121 break;
02122 }
02123
02124
02125
02126
02127
02128 if (aperture->simplified == NULL) {
02129 aperture->simplified = sam;
02130 } else {
02131 gerbv_simplified_amacro_t *tmp_sam;
02132 tmp_sam = aperture->simplified;
02133 while (tmp_sam->next != NULL) {
02134 tmp_sam = tmp_sam->next;
02135 }
02136 tmp_sam->next = sam;
02137 }
02138
02139 #ifdef DEBUG
02140 for (i = 0; i < nuf_parameters; i++) {
02141 dprintf("%f, ", s->stack[i]);
02142 }
02143 #endif
02144 dprintf(")\n");
02145 }
02146
02147
02148
02149
02150
02151
02152
02153 s->sp = 0;
02154 break;
02155 default :
02156 break;
02157 }
02158 }
02159 free_stack(s);
02160
02161
02162
02163 aperture->parameter[0]= (gdouble) clearOperatorUsed;
02164 return handled;
02165 }
02166
02167
02168
02169 static int
02170 parse_aperture_definition(gerb_file_t *fd, gerbv_aperture_t *aperture,
02171 gerbv_image_t *image, gdouble scale)
02172 {
02173 int ano, i;
02174 char *ad;
02175 char *token;
02176 gerbv_amacro_t *curr_amacro;
02177 gerbv_amacro_t *amacro = image->amacro;
02178 gerbv_stats_t *stats = image->gerbv_stats;
02179 gdouble tempHolder;
02180 gchar *string;
02181
02182 if (gerb_fgetc(fd) != 'D') {
02183 string = g_strdup_printf("Found AD code with no following 'D' in file \n%s\n",
02184 fd->filename);
02185 gerbv_stats_add_error(stats->error_list,
02186 -1,
02187 string,
02188 GERBV_MESSAGE_ERROR);
02189 g_free(string);
02190 return -1;
02191 }
02192
02193
02194
02195
02196 ano = gerb_fgetint(fd, NULL);
02197
02198
02199
02200
02201 ad = gerb_fgetstring(fd, '*');
02202 token = strtok(ad, ",");
02203
02204 if (strlen(token) == 1) {
02205 switch (token[0]) {
02206 case 'C':
02207 aperture->type = GERBV_APTYPE_CIRCLE;
02208 break;
02209 case 'R' :
02210 aperture->type = GERBV_APTYPE_RECTANGLE;
02211 break;
02212 case 'O' :
02213 aperture->type = GERBV_APTYPE_OVAL;
02214 break;
02215 case 'P' :
02216 aperture->type = GERBV_APTYPE_POLYGON;
02217 break;
02218 }
02219
02220 } else {
02221 aperture->type = GERBV_APTYPE_MACRO;
02222
02223
02224
02225
02226 curr_amacro = amacro;
02227 while (curr_amacro) {
02228 if ((strlen(curr_amacro->name) == strlen(token)) &&
02229 (strcmp(curr_amacro->name, token) == 0)) {
02230 aperture->amacro = curr_amacro;
02231 break;
02232 }
02233 curr_amacro = curr_amacro->next;
02234 }
02235 }
02236
02237
02238
02239
02240 for (token = strtok(NULL, "X"), i = 0; token != NULL;
02241 token = strtok(NULL, "X"), i++) {
02242 if (i == APERTURE_PARAMETERS_MAX) {
02243 string = g_strdup_printf("In file %s,\nmaximum number of allowed parameters exceeded in aperture %d\n",
02244 fd->filename, ano);
02245 gerbv_stats_add_error(stats->error_list,
02246 -1,
02247 string,
02248 GERBV_MESSAGE_ERROR);
02249 g_free(string);
02250 break;
02251 }
02252 errno = 0;
02253
02254 tempHolder = strtod(token, NULL);
02255
02256
02257 if (!(((aperture->type == GERBV_APTYPE_POLYGON) && ((i==1) || (i==2)))||
02258 (aperture->type == GERBV_APTYPE_MACRO))) {
02259 tempHolder /= scale;
02260 }
02261
02262 aperture->parameter[i] = tempHolder;
02263 if (errno) {
02264 string = g_strdup_printf("Failed to read all parameters exceeded in aperture %d\n", ano);
02265 gerbv_stats_add_error(stats->error_list,
02266 -1,
02267 string,
02268 GERBV_MESSAGE_WARNING);
02269 g_free(string);
02270 aperture->parameter[i] = 0.0;
02271 }
02272 }
02273
02274 aperture->nuf_parameters = i;
02275
02276 gerb_ungetc(fd);
02277
02278 if (aperture->type == GERBV_APTYPE_MACRO) {
02279 dprintf("Simplifying aperture %d using aperture macro \"%s\"\n", ano,
02280 aperture->amacro->name);
02281 simplify_aperture_macro(aperture, scale);
02282 dprintf("Done simplifying\n");
02283 }
02284
02285 g_free(ad);
02286
02287 return ano;
02288 }
02289
02290
02291
02292 static void
02293 calc_cirseg_sq(struct gerbv_net *net, int cw,
02294 double delta_cp_x, double delta_cp_y)
02295 {
02296 double d1x, d1y, d2x, d2y;
02297 double alfa, beta;
02298 int quadrant = 0;
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308 if (net->start_x > net->stop_x)
02309
02310 if (net->start_y < net->stop_y)
02311 quadrant = 1;
02312 else
02313 quadrant = 2;
02314 else
02315
02316 if (net->start_y > net->stop_y)
02317 quadrant = 3;
02318 else
02319 quadrant = 4;
02320
02321
02322
02323
02324 if (cw) {
02325 switch (quadrant) {
02326 case 1 :
02327 quadrant = 3;
02328 break;
02329 case 2 :
02330 quadrant = 4;
02331 break;
02332 case 3 :
02333 quadrant = 1;
02334 break;
02335 case 4 :
02336 quadrant = 2;
02337 break;
02338 default :
02339 GERB_COMPILE_ERROR("Unknow quadrant value while converting to cw\n");
02340 }
02341 }
02342
02343
02344
02345
02346 switch (quadrant) {
02347 case 1 :
02348 net->cirseg->cp_x = net->start_x - delta_cp_x;
02349 net->cirseg->cp_y = net->start_y - delta_cp_y;
02350 break;
02351 case 2 :
02352 net->cirseg->cp_x = net->start_x + delta_cp_x;
02353 net->cirseg->cp_y = net->start_y - delta_cp_y;
02354 break;
02355 case 3 :
02356 net->cirseg->cp_x = net->start_x + delta_cp_x;
02357 net->cirseg->cp_y = net->start_y + delta_cp_y;
02358 break;
02359 case 4 :
02360 net->cirseg->cp_x = net->start_x - delta_cp_x;
02361 net->cirseg->cp_y = net->start_y + delta_cp_y;
02362 break;
02363 default :
02364 GERB_COMPILE_ERROR("Strange quadrant : %d\n", quadrant);
02365 }
02366
02367
02368
02369
02370 d1x = fabs(net->start_x - net->cirseg->cp_x);
02371 d1y = fabs(net->start_y - net->cirseg->cp_y);
02372 d2x = fabs(net->stop_x - net->cirseg->cp_x);
02373 d2y = fabs(net->stop_y - net->cirseg->cp_y);
02374
02375 alfa = atan2(d1y, d1x);
02376 beta = atan2(d2y, d2x);
02377
02378
02379
02380
02381 net->cirseg->width = alfa < beta ?
02382 2 * (d1x / cos(alfa)) : 2 * (d2x / cos(beta));
02383 net->cirseg->height = alfa > beta ?
02384 2 * (d1y / sin(alfa)) : 2 * (d2y / sin(beta));
02385
02386 if (alfa < 0.000001 && beta < 0.000001) {
02387 net->cirseg->height = 0;
02388 }
02389
02390 #define RAD2DEG(a) (a * 180 / M_PI)
02391
02392 switch (quadrant) {
02393 case 1 :
02394 net->cirseg->angle1 = RAD2DEG(alfa);
02395 net->cirseg->angle2 = RAD2DEG(beta);
02396 break;
02397 case 2 :
02398 net->cirseg->angle1 = 180.0 - RAD2DEG(alfa);
02399 net->cirseg->angle2 = 180.0 - RAD2DEG(beta);
02400 break;
02401 case 3 :
02402 net->cirseg->angle1 = 180.0 + RAD2DEG(alfa);
02403 net->cirseg->angle2 = 180.0 + RAD2DEG(beta);
02404 break;
02405 case 4 :
02406 net->cirseg->angle1 = 360.0 - RAD2DEG(alfa);
02407 net->cirseg->angle2 = 360.0 - RAD2DEG(beta);
02408 break;
02409 default :
02410 GERB_COMPILE_ERROR("Strange quadrant : %d\n", quadrant);
02411 }
02412
02413 if (net->cirseg->width < 0.0)
02414 GERB_COMPILE_WARNING("Negative width [%f] in quadrant %d [%f][%f]\n",
02415 net->cirseg->width, quadrant, alfa, beta);
02416
02417 if (net->cirseg->height < 0.0)
02418 GERB_COMPILE_WARNING("Negative height [%f] in quadrant %d [%f][%f]\n",
02419 net->cirseg->height, quadrant, RAD2DEG(alfa), RAD2DEG(beta));
02420
02421 return;
02422
02423 }
02424
02425
02426
02427 static void
02428 calc_cirseg_mq(struct gerbv_net *net, int cw,
02429 double delta_cp_x, double delta_cp_y)
02430 {
02431 double d1x, d1y, d2x, d2y;
02432 double alfa, beta;
02433
02434 net->cirseg->cp_x = net->start_x + delta_cp_x;
02435 net->cirseg->cp_y = net->start_y + delta_cp_y;
02436
02437
02438
02439
02440 d1x = net->start_x - net->cirseg->cp_x;
02441 d1y = net->start_y - net->cirseg->cp_y;
02442 d2x = net->stop_x - net->cirseg->cp_x;
02443 d2y = net->stop_y - net->cirseg->cp_y;
02444
02445 alfa = atan2(d1y, d1x);
02446 beta = atan2(d2y, d2x);
02447
02448 net->cirseg->width = sqrt(delta_cp_x*delta_cp_x + delta_cp_y*delta_cp_y);
02449 net->cirseg->width *= 2.0;
02450 net->cirseg->height = net->cirseg->width;
02451
02452 net->cirseg->angle1 = RAD2DEG(alfa);
02453 net->cirseg->angle2 = RAD2DEG(beta);
02454
02455
02456
02457
02458 if (net->cirseg->angle1 < 0.0) {
02459 net->cirseg->angle1 += 360.0;
02460 net->cirseg->angle2 += 360.0;
02461 }
02462
02463 if (net->cirseg->angle2 < 0.0)
02464 net->cirseg->angle2 += 360.0;
02465
02466 if(net->cirseg->angle2 == 0.0)
02467 net->cirseg->angle2 = 360.0;
02468
02469
02470
02471
02472
02473
02474
02475
02476 if (cw) {
02477 if (net->cirseg->angle1 <= net->cirseg->angle2)
02478 net->cirseg->angle2 -= 360.0;
02479 } else {
02480 if (net->cirseg->angle1 >= net->cirseg->angle2)
02481 net->cirseg->angle2 += 360.0;
02482 }
02483
02484 return;
02485 }
02486
02487
02488 static void
02489 gerber_update_any_running_knockout_measurements (gerbv_image_t *image)
02490 {
02491 if (knockoutMeasure) {
02492 knockoutLayer->knockout.lowerLeftX = knockoutLimitXmin;
02493 knockoutLayer->knockout.lowerLeftY = knockoutLimitYmin;
02494 knockoutLayer->knockout.width = knockoutLimitXmax - knockoutLimitXmin;
02495 knockoutLayer->knockout.height = knockoutLimitYmax - knockoutLimitYmin;
02496 knockoutMeasure = FALSE;
02497 }
02498 }
02499
02500
02501 static void
02502 gerber_calculate_final_justify_effects(gerbv_image_t *image)
02503 {
02504 gdouble translateA = 0.0, translateB = 0.0;
02505
02506 if (image->info->imageJustifyTypeA != GERBV_JUSTIFY_NOJUSTIFY) {
02507 if (image->info->imageJustifyTypeA == GERBV_JUSTIFY_CENTERJUSTIFY)
02508 translateA = (image->info->max_x - image->info->min_x) / 2.0;
02509 else
02510 translateA = -image->info->min_x;
02511 }
02512 if (image->info->imageJustifyTypeB != GERBV_JUSTIFY_NOJUSTIFY) {
02513 if (image->info->imageJustifyTypeB == GERBV_JUSTIFY_CENTERJUSTIFY)
02514 translateB = (image->info->max_y - image->info->min_y) / 2.0;
02515 else
02516 translateB = -image->info->min_y;
02517 }
02518
02519
02520
02521 image->info->min_x += translateA+ image->info->imageJustifyOffsetA;
02522 image->info->max_x += translateA+ image->info->imageJustifyOffsetA;
02523 image->info->min_y += translateB+ image->info->imageJustifyOffsetB;
02524 image->info->max_y += translateB+ image->info->imageJustifyOffsetB;
02525
02526
02527
02528 image->info->imageJustifyOffsetActualA = translateA +
02529 image->info->imageJustifyOffsetA;
02530 image->info->imageJustifyOffsetActualB = translateB +
02531 image->info->imageJustifyOffsetB;
02532 }
02533
02534
02535 static void
02536 gerber_update_min_and_max(gerbv_image_info_t *info, gdouble repeatX, gdouble repeatY,
02537 gdouble x, gdouble y, gdouble apertureSizeX1,
02538 gdouble apertureSizeX2,gdouble apertureSizeY1,
02539 gdouble apertureSizeY2)
02540 {
02541 gdouble ourX1 = x - apertureSizeX1, ourY1 = y - apertureSizeY1;
02542 gdouble ourX2 = x + apertureSizeX2, ourY2 = y + apertureSizeY2;
02543
02544 if (repeatX > 0)
02545 ourX2 += repeatX;
02546 if (repeatY > 0)
02547 ourY2 += repeatY;
02548
02549 #ifndef RENDER_USING_GDK
02550
02551
02552
02553
02554 cairo_matrix_transform_point (¤tMatrix, &ourX1, &ourY1);
02555 cairo_matrix_transform_point (¤tMatrix, &ourX2, &ourY2);
02556 #endif
02557
02558
02559
02560 if(info->min_x > ourX1)
02561 info->min_x = ourX1;
02562 if(info->min_x > ourX2)
02563 info->min_x = ourX2;
02564 if(info->max_x < ourX1)
02565 info->max_x = ourX1;
02566 if(info->max_x < ourX2)
02567 info->max_x = ourX2;
02568 if(info->min_y > ourY1)
02569 info->min_y = ourY1;
02570 if(info->min_y > ourY2)
02571 info->min_y = ourY2;
02572 if(info->max_y < ourY1)
02573 info->max_y = ourY1;
02574 if(info->max_y < ourY2)
02575 info->max_y = ourY2;
02576
02577 if (knockoutMeasure) {
02578 if(knockoutLimitXmin > ourX1)
02579 knockoutLimitXmin = ourX1;
02580 if(knockoutLimitXmin > ourX2)
02581 knockoutLimitXmin = ourX2;
02582 if(knockoutLimitXmax < ourX1)
02583 knockoutLimitXmax = ourX1;
02584 if(knockoutLimitXmax < ourX2)
02585 knockoutLimitXmax = ourX2;
02586 if(knockoutLimitYmin > ourY1)
02587 knockoutLimitYmin = ourY1;
02588 if(knockoutLimitYmin > ourY2)
02589 knockoutLimitYmin = ourY2;
02590 if(knockoutLimitYmax < ourY1)
02591 knockoutLimitYmax = ourY1;
02592 if(knockoutLimitYmax < ourY2)
02593 knockoutLimitYmax = ourY2;
02594 }
02595 }
02596