47 #define DPRINTF(...) do { if (DEBUG) printf(__VA_ARGS__); } while (0)
49 #define A2I(a,b) (((a & 0xff) << 8) + (b & 0xff))
54 static void parse_G_code(gerb_file_t *fd, gerb_state_t *state,
56 static void parse_D_code(gerb_file_t *fd, gerb_state_t *state,
58 static int parse_M_code(gerb_file_t *fd,
gerbv_image_t *image,
59 long int *line_num_p);
60 static void parse_rs274x(gint levelOfRecursion, gerb_file_t *fd,
63 gchar *directoryPath,
long int *line_num_p);
64 static int parse_aperture_definition(gerb_file_t *fd,
65 gerbv_aperture_t *aperture,
67 long int *line_num_p);
68 static void calc_cirseg_sq(
struct gerbv_net *net,
int cw,
69 double delta_cp_x,
double delta_cp_y);
70 void calc_cirseg_mq(
struct gerbv_net *net,
int cw,
71 double delta_cp_x,
double delta_cp_y);
72 static void calc_cirseg_bbox(
const gerbv_cirseg_t *cirseg,
73 double apert_size_x,
double apert_size_y,
76 static void gerber_update_any_running_knockout_measurements(
79 static void gerber_calculate_final_justify_effects (
gerbv_image_t *image);
81 static gboolean add_trailing_zeros_if_omitted(
int *coord,
int omitted_num,
84 gboolean knockoutMeasure = FALSE;
85 gdouble knockoutLimitXmin, knockoutLimitYmin,
86 knockoutLimitXmax, knockoutLimitYmax;
88 cairo_matrix_t currentMatrix;
95 currentNet->
next = newNet;
97 newNet->
layer = layer;
101 newNet->
state = state;
109 gerber_create_new_aperture (
gerbv_image_t *image,
int *indexNumber,
114 for (i = 0; i <= APERTURE_MAX; i++) {
116 image->
aperture[i] = g_new0 (gerbv_aperture_t, 1);
117 image->
aperture[i]->type = apertureType;
118 image->
aperture[i]->parameter[0] = parameter1;
119 image->
aperture[i]->parameter[1] = parameter2;
141 gchar *directoryPath)
143 int read, coord, len, polygonPoints=0;
144 double x_scale = 0.0, y_scale = 0.0;
145 double delta_cp_x = 0.0, delta_cp_y = 0.0;
146 double aperture_sizeX, aperture_sizeY;
148 gboolean foundEOF = FALSE;
150 boundingBox = boundingBoxNew;
152 long int line_num = 1;
154 while ((read = gerb_fgetc(fd)) != EOF) {
161 switch ((
char)(read & 0xff)) {
163 DPRINTF(
"... Found G code at line %ld\n", line_num);
167 DPRINTF(
"... Found D code at line %ld\n", line_num);
171 DPRINTF(
"... Found M code at line %ld\n", line_num);
173 switch(parse_M_code(fd, image, &line_num)) {
181 _(
"Unknown M code found at line %ld in file \"%s\""),
182 line_num, fd->filename);
187 coord = gerb_fgetint(fd, &len);
189 add_trailing_zeros_if_omitted(&coord,
192 DPRINTF(
"... Found X code %d at line %ld\n", coord, line_num);
195 state->curr_x += coord;
197 state->curr_x = coord;
204 coord = gerb_fgetint(fd, &len);
206 add_trailing_zeros_if_omitted(&coord,
209 DPRINTF(
"... Found Y code %d at line %ld\n", coord, line_num);
212 state->curr_y += coord;
214 state->curr_y = coord;
221 coord = gerb_fgetint(fd, &len);
223 add_trailing_zeros_if_omitted(&coord,
226 DPRINTF(
"... Found I code %d at line %ld\n", coord, line_num);
227 state->delta_cp_x = coord;
233 coord = gerb_fgetint(fd, &len);
235 add_trailing_zeros_if_omitted(&coord,
238 DPRINTF(
"... Found J code %d at line %ld\n", coord, line_num);
239 state->delta_cp_y = coord;
244 DPRINTF(
"... Found %% code at line %ld\n", line_num);
246 parse_rs274x(levelOfRecursion, fd, image, state, curr_net,
247 stats, directoryPath, &line_num);
250 if ((state->in_block) && (state->saved_curr_net == NULL)) {
252 state->saved_curr_net = curr_net;
253 curr_net = state->block_netlist;
254 }
else if ((!state->in_block) && (state->saved_curr_net != NULL)) {
256 curr_net = state->saved_curr_net;
257 state->saved_curr_net = NULL;
266 case '\0':
case '\t':
case ' ':
274 read = gerb_fgetc(fd);
275 if (read !=
'\r' && read != EOF)
284 read = gerb_fgetc(fd);
285 if (read !=
'\n' && read != EOF)
294 if(c == EOF || c ==
'%')
303 DPRINTF(
"... Found * code at line %ld\n", line_num);
305 if (state->changed == 0)
break;
313 state->prev_x = state->curr_x;
314 state->prev_y = state->curr_y;
317 curr_net = gerber_create_new_net (curr_net, state->
layer, state->state);
322 if (image && image->
format ){
323 x_scale = pow(10.0, (
double)image->
format->x_dec);
324 y_scale = pow(10.0, (
double)image->
format->y_dec);
328 curr_net->
start_x = (double)state->prev_x / x_scale;
329 curr_net->
start_y = (
double)state->prev_y / y_scale;
330 curr_net->
stop_x = (double)state->curr_x / x_scale;
331 curr_net->
stop_y = (
double)state->curr_y / y_scale;
332 delta_cp_x = (double)state->delta_cp_x / x_scale;
333 delta_cp_y = (
double)state->delta_cp_y / y_scale;
335 switch (state->interpolation) {
340 curr_net->
cirseg = g_new0 (gerbv_cirseg_t, 1);
342 calc_cirseg_mq(curr_net, cw, delta_cp_x, delta_cp_y);
344 calc_cirseg_sq(curr_net, cw, delta_cp_x, delta_cp_y);
350 if (delta_cp_x < 0 || delta_cp_y < 0) {
353 _(
"Signed incremental distance IxJy "
354 "in single quadrant %s circular "
355 "interpolation %s at line %ld "
357 cw? _(
"CW"): _(
"CCW"), cw?
"G02":
"G03",
358 line_num, fd->filename);
368 state->parea_start_node = curr_net;
369 state->in_parea_fill = 1;
371 boundingBox = boundingBoxNew;
375 if (state->parea_start_node != NULL) {
376 state->parea_start_node->boundingBox = boundingBox;
379 _(
"End of polygon without start "
380 "at line %ld in file \"%s\""),
381 line_num, fd->filename);
385 state->parea_start_node = NULL;
386 state->in_parea_fill = 0;
396 if (state->in_parea_fill && state->parea_start_node) {
409 && polygonPoints > 0) {
411 curr_net = gerber_create_new_net (curr_net, state->
layer, state->state);
413 state->parea_start_node->boundingBox = boundingBox;
414 state->parea_start_node = curr_net;
416 curr_net = gerber_create_new_net (curr_net, state->
layer, state->state);
417 curr_net->
start_x = (double)state->prev_x / x_scale;
418 curr_net->
start_y = (
double)state->prev_y / y_scale;
419 curr_net->
stop_x = (double)state->curr_x / x_scale;
420 curr_net->
stop_y = (
double)state->curr_y / y_scale;
421 boundingBox = boundingBoxNew;
438 ((state->delta_cp_x == 0.0) && (state->delta_cp_y == 0.0)))
450 state->interpolation = state->prev_interpolation;
456 curr_net->
layer = state->layer;
458 state->delta_cp_x = 0.0;
459 state->delta_cp_y = 0.0;
460 curr_net->
aperture = state->curr_aperture;
467 state->prev_x = state->curr_x;
468 state->prev_y = state->curr_y;
474 if ((curr_net->
aperture == 0) && !state->in_parea_fill)
480 double repeat_off_X = 0.0, repeat_off_Y = 0.0;
483 if (!state->in_parea_fill) {
484 DPRINTF(
" In %s(), adding 1 to D_list ...\n",
486 int retcode = gerbv_stats_increment_D_list_count(
487 stats->D_code_list, curr_net->
aperture,
492 _(
"Found undefined D code D%02d "
493 "at line %ld in file \"%s\""),
494 curr_net->
aperture, line_num, fd->filename);
507 repeat_off_X = (state->layer->stepAndRepeat.X - 1) *
508 state->layer->stepAndRepeat.dist_X;
509 repeat_off_Y = (state->layer->stepAndRepeat.Y - 1) *
510 state->layer->stepAndRepeat.dist_Y;
512 cairo_matrix_init (¤tMatrix, 1, 0, 0, 1, 0, 0);
514 cairo_matrix_translate (¤tMatrix, image->
info->offsetA,
515 image->
info->offsetB);
517 cairo_matrix_rotate (¤tMatrix, image->
info->imageRotation);
521 cairo_matrix_rotate (¤tMatrix, state->layer->rotation);
525 cairo_matrix_scale (¤tMatrix, state->state->scaleA,
526 state->state->scaleB);
528 cairo_matrix_translate (¤tMatrix, state->state->offsetA,
529 state->state->offsetB);
531 switch (state->state->mirrorState) {
532 case GERBV_MIRROR_STATE_FLIPA:
533 cairo_matrix_scale (¤tMatrix, -1, 1);
535 case GERBV_MIRROR_STATE_FLIPB:
536 cairo_matrix_scale (¤tMatrix, 1, -1);
538 case GERBV_MIRROR_STATE_FLIPAB:
539 cairo_matrix_scale (¤tMatrix, -1, -1);
545 if (state->state->axisSelect == GERBV_AXIS_SELECT_SWAPAB) {
549 cairo_matrix_rotate (¤tMatrix, M_PI + M_PI_2);
550 cairo_matrix_scale (¤tMatrix, 1, -1);
556 gerbv_simplified_amacro_t *ls = image->
aperture[curr_net->
aperture]->simplified;
559 gdouble offsetx = 0, offsety = 0, widthx = 0, widthy = 0;
560 gboolean calculatedAlready = FALSE;
563 offsetx=ls->parameter[CIRCLE_CENTER_X];
564 offsety=ls->parameter[CIRCLE_CENTER_Y];
566 DEG2RAD(ls->parameter[CIRCLE_ROTATION]));
567 widthx=widthy=ls->parameter[CIRCLE_DIAMETER];
569 int pointCounter,numberOfPoints;
570 gdouble rotation = DEG2RAD(ls->parameter[
571 OUTLINE_ROTATION_IDX(ls->parameter)]);
572 numberOfPoints = ls->parameter[OUTLINE_NUMBER_OF_POINTS] + 1;
574 for (pointCounter = 0; pointCounter < numberOfPoints; pointCounter++) {
575 gdouble px = ls->parameter[OUTLINE_X_IDX_OF_POINT(pointCounter)];
576 gdouble py = ls->parameter[OUTLINE_Y_IDX_OF_POINT(pointCounter)];
578 gerber_update_min_and_max (&boundingBox,
583 calculatedAlready = TRUE;
585 offsetx = ls->parameter[POLYGON_CENTER_X];
586 offsety = ls->parameter[POLYGON_CENTER_Y];
588 DEG2RAD(ls->parameter[POLYGON_ROTATION]));
589 widthx = widthy = ls->parameter[POLYGON_DIAMETER];
591 offsetx = ls->parameter[MOIRE_CENTER_X];
592 offsety = ls->parameter[MOIRE_CENTER_Y];
594 DEG2RAD(ls->parameter[MOIRE_ROTATION]));
595 widthx = widthy = ls->parameter[MOIRE_OUTSIDE_DIAMETER];
597 offsetx = ls->parameter[THERMAL_CENTER_X];
598 offsety = ls->parameter[THERMAL_CENTER_Y];
600 DEG2RAD(ls->parameter[THERMAL_ROTATION]));
601 widthx = widthy = ls->parameter[THERMAL_OUTSIDE_DIAMETER];
603 gdouble rotation = DEG2RAD(ls->parameter[LINE20_ROTATION]);
604 gdouble sx = ls->parameter[LINE20_START_X];
605 gdouble sy = ls->parameter[LINE20_START_Y];
606 gdouble ex = ls->parameter[LINE20_END_X];
607 gdouble ey = ls->parameter[LINE20_END_Y];
610 widthx = widthy = ls->parameter[LINE20_LINE_WIDTH];
611 gerber_update_min_and_max (&boundingBox,
614 widthx/2,widthx/2,widthy/2,widthy/2);
615 gerber_update_min_and_max (&boundingBox,
618 widthx/2,widthx/2,widthy/2,widthy/2);
619 calculatedAlready = TRUE;
621 gdouble largestDimension = hypot(ls->parameter[LINE21_WIDTH],
622 ls->parameter[LINE21_HEIGHT]);
623 offsetx = ls->parameter[LINE21_CENTER_X];
624 offsety = ls->parameter[LINE21_CENTER_Y];
626 DEG2RAD(ls->parameter[LINE21_ROTATION]));
627 widthx = widthy = largestDimension;
629 gdouble largestDimension = hypot(ls->parameter[LINE22_WIDTH],
630 ls->parameter[LINE22_HEIGHT]);
632 offsetx = ls->parameter[LINE22_LOWER_LEFT_X] +
633 ls->parameter[LINE22_WIDTH]/2;
634 offsety = ls->parameter[LINE22_LOWER_LEFT_Y] +
635 ls->parameter[LINE22_HEIGHT]/2;
637 DEG2RAD(ls->parameter[LINE22_ROTATION]));
638 widthx = widthy=largestDimension;
641 if (!calculatedAlready) {
642 gerber_update_min_and_max (&boundingBox,
643 curr_net->
stop_x + offsetx,
644 curr_net->
stop_y + offsety,
645 widthx/2,widthx/2,widthy/2,widthy/2);
656 aperture_sizeY = aperture_sizeX;
660 aperture_sizeX = aperture_sizeY = 0;
669 calc_cirseg_bbox(curr_net->
cirseg,
670 aperture_sizeX, aperture_sizeY,
678 gerber_update_min_and_max (&boundingBox,
680 aperture_sizeX/2,aperture_sizeX/2,
681 aperture_sizeY/2,aperture_sizeY/2);
683 gerber_update_min_and_max (&boundingBox,
685 aperture_sizeX/2,aperture_sizeX/2,
686 aperture_sizeY/2,aperture_sizeY/2);
693 gerber_update_image_min_max(&boundingBox, repeat_off_X, repeat_off_Y, image);
696 if (knockoutMeasure) {
697 if (boundingBox.left < knockoutLimitXmin)
698 knockoutLimitXmin = boundingBox.left;
699 if (boundingBox.right+repeat_off_X > knockoutLimitXmax)
700 knockoutLimitXmax = boundingBox.right+repeat_off_X;
701 if (boundingBox.bottom < knockoutLimitYmin)
702 knockoutLimitYmin = boundingBox.bottom;
703 if (boundingBox.top+repeat_off_Y > knockoutLimitYmax)
704 knockoutLimitYmax = boundingBox.top+repeat_off_Y;
707 if (!state->in_parea_fill) {
709 boundingBox = boundingBoxNew;
714 case '\0':
case '\t':
case ' ':
721 read = gerb_fgetc(fd);
722 if (read !=
'\r' && read != EOF)
730 read = gerb_fgetc(fd);
731 if (read !=
'\n' && read != EOF)
738 _(
"Found unknown character '%s' (0x%x) "
739 "at line %ld in file \"%s\""),
740 gerbv_escape_char(read), read,
741 line_num, fd->filename);
758 gerb_state_t *state = NULL;
762 gboolean foundEOF = FALSE;
768 setlocale(LC_NUMERIC,
"C" );
774 state = g_new0 (gerb_state_t, 1);
781 GERB_FATAL_ERROR(
"malloc image failed in %s()", __FUNCTION__);
786 GERB_FATAL_ERROR(
"malloc gerbv_stats failed in %s()", __FUNCTION__);
791 state->layer = image->
layers;
792 state->state = image->
states;
793 curr_net->
layer = state->layer;
794 curr_net->
state = state->state;
799 DPRINTF(
"In %s(), starting to parse file...\n", __func__);
805 _(
"Missing Gerber EOF code in file \"%s\""), fd->filename);
809 DPRINTF(
" ... done parsing Gerber file\n");
810 gerber_update_any_running_knockout_measurements (image);
811 gerber_calculate_final_justify_effects(image);
828 gboolean found_binary = FALSE;
829 gboolean found_ADD = FALSE;
830 gboolean found_percent_cmd = FALSE;
831 gboolean found_D0 = FALSE;
832 gboolean found_D2 = FALSE;
833 gboolean found_M0 = FALSE;
834 gboolean found_M2 = FALSE;
835 gboolean found_star = FALSE;
836 gboolean found_X = FALSE;
837 gboolean found_Y = FALSE;
839 DPRINTF(
"%s(%p, %p), fd->fd = %p\n",
840 __func__, fd, returnFoundBinary, fd->fd);
841 buf = (
char *) g_malloc(MAXL);
843 GERB_FATAL_ERROR(
"malloc buf failed while checking for rs274x in %s()",
846 while (fgets(buf, MAXL, fd->fd) != NULL) {
847 DPRINTF(
"buf = \"%s\"\n", buf);
854 for (i = 0; i < len; i++) {
855 if (!isprint((
int) buf[i]) && (buf[i] !=
'\r') &&
856 (buf[i] !=
'\n') && (buf[i] !=
'\t')) {
858 DPRINTF(
"found_binary (%d)\n", buf[i]);
861 if (g_strstr_len(buf, len,
"%ADD")) {
863 DPRINTF(
"found_ADD\n");
865 if (g_strstr_len(buf, len,
"%FS") ||
866 g_strstr_len(buf, len,
"%MO") ||
867 g_strstr_len(buf, len,
"%LP") ||
868 g_strstr_len(buf, len,
"%AM")) {
869 found_percent_cmd = TRUE;
870 DPRINTF(
"found_percent_cmd\n");
872 if (g_strstr_len(buf, len,
"D00") || g_strstr_len(buf, len,
"D0")) {
874 DPRINTF(
"found_D0\n");
876 if (g_strstr_len(buf, len,
"D02") || g_strstr_len(buf, len,
"D2")) {
878 DPRINTF(
"found_D2\n");
880 if (g_strstr_len(buf, len,
"M00") || g_strstr_len(buf, len,
"M0")) {
882 DPRINTF(
"found_M0\n");
884 if (g_strstr_len(buf, len,
"M02") || g_strstr_len(buf, len,
"M2")) {
886 DPRINTF(
"found_M2\n");
888 if (g_strstr_len(buf, len,
"*")) {
890 DPRINTF(
"found_star\n");
893 if ((letter = g_strstr_len(buf, len,
"X")) != NULL) {
894 if (isdigit((
int) letter[1])) {
896 DPRINTF(
"found_X\n");
899 if ((letter = g_strstr_len(buf, len,
"Y")) != NULL) {
900 if (isdigit((
int) letter[1])) {
902 DPRINTF(
"found_Y\n");
909 *returnFoundBinary = found_binary;
912 if ((found_D0 || found_D2 || found_M0 || found_M2) &&
913 (found_ADD || found_percent_cmd) && found_star && (found_X || found_Y))
933 gboolean found_binary = FALSE;
934 gboolean found_ADD = FALSE;
935 gboolean found_D0 = FALSE;
936 gboolean found_D2 = FALSE;
937 gboolean found_M0 = FALSE;
938 gboolean found_M2 = FALSE;
939 gboolean found_star = FALSE;
940 gboolean found_X = FALSE;
941 gboolean found_Y = FALSE;
945 GERB_FATAL_ERROR(
"malloc buf failed while checking for rs274d in %s()",
948 while (fgets(buf, MAXL, fd->fd) != NULL) {
954 for (i = 0; i < len; i++) {
955 if (!isprint( (
int) buf[i]) && (buf[i] !=
'\r') &&
956 (buf[i] !=
'\n') && (buf[i] !=
'\t')) {
961 if (g_strstr_len(buf, len,
"%ADD")) {
964 if (g_strstr_len(buf, len,
"D00") || g_strstr_len(buf, len,
"D0")) {
967 if (g_strstr_len(buf, len,
"D02") || g_strstr_len(buf, len,
"D2")) {
970 if (g_strstr_len(buf, len,
"M00") || g_strstr_len(buf, len,
"M0")) {
973 if (g_strstr_len(buf, len,
"M02") || g_strstr_len(buf, len,
"M2")) {
976 if (g_strstr_len(buf, len,
"*")) {
980 if ((letter = g_strstr_len(buf, len,
"X")) != NULL) {
982 if (isdigit( (
int) letter[1])) {
986 if ((letter = g_strstr_len(buf, len,
"Y")) != NULL) {
988 if (isdigit( (
int) letter[1])) {
997 if ((found_D0 || found_D2 || found_M0 || found_M2) &&
998 !found_ADD && found_star && (found_X || found_Y) &&
1021 op_int=gerb_fgetint(fd, NULL);
1024 DPRINTF(
"\n Found G%02d at line %ld (%s)\n",
1048 if (c ==
'\r' || c ==
'\n') {
1050 _(
"Found newline while parsing "
1051 "G04 code at line %ld in file \"%s\", "
1052 "maybe you forgot a \"*\"?"),
1053 *line_num_p, fd->filename);
1056 while (c != EOF && c !=
'*');
1073 state->prev_interpolation = state->interpolation;
1085 if (gerb_fgetc(fd) ==
'D') {
1086 int a = gerb_fgetint(fd, NULL);
1087 if ((a >= 0) && (a <= APERTURE_MAX)) {
1088 state->curr_aperture = a;
1091 _(
"Found aperture D%02d out of bounds while parsing "
1092 "G code at line %ld in file \"%s\""),
1093 a, *line_num_p, fd->filename);
1097 _(
"Found unexpected code after G54 "
1098 "at line %ld in file \"%s\""),
1099 *line_num_p, fd->filename);
1108 state->state = gerbv_image_return_new_netstate (state->state);
1113 state->state = gerbv_image_return_new_netstate (state->state);
1135 _(
"Encountered unknown G code G%02d "
1136 "at line %ld in file \"%s\""),
1137 op_int, *line_num_p, fd->filename);
1139 _(
"Ignoring unknown G code G%02d"), op_int);
1162 a = gerb_fgetint(fd, NULL);
1163 DPRINTF(
" Found D%02d code at line %ld\n", a, *line_num_p);
1168 _(
"Found invalid D00 code at line %ld in file \"%s\""),
1169 *line_num_p, fd->filename);
1188 if ((a >= 0) && (a <= APERTURE_MAX)) {
1189 state->curr_aperture = a;
1193 _(
"Found out of bounds aperture D%02d "
1194 "at line %ld in file \"%s\""),
1195 a, *line_num_p, fd->filename);
1208 parse_M_code(gerb_file_t *fd,
gerbv_image_t *image,
long int *line_num_p)
1213 op_int=gerb_fgetint(fd, NULL);
1227 _(
"Encountered unknown M%02d code at line %ld in file \"%s\""),
1228 op_int, *line_num_p, fd->filename);
1230 _(
"Ignoring unknown M%02d code"), op_int);
1238 parse_rs274x(gint levelOfRecursion, gerb_file_t *fd,
gerbv_image_t *image,
1240 gchar *directoryPath,
long int *line_num_p)
1245 gerbv_aperture_t *a = NULL;
1246 gerbv_amacro_t *tmp_amacro;
1248 gdouble scale = 1.0;
1254 op[0] = gerb_fgetc(fd);
1255 op[1] = gerb_fgetc(fd);
1257 if (op[0] == EOF || op[1] == EOF)
1259 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1261 switch (A2I(op[0], op[1])){
1264 op[0] = gerb_fgetc(fd);
1269 while (((c = gerb_fgetc(fd)) != EOF) && (c !=
'*')) {
1270 if ((c >=
'0') && (c <=
'9')) {
1271 ap_num = ap_num * 10 + (c -
'0');
1274 if (state->in_block) {
1286 _(
"Nested %%AB%% aperture block (D%d inside D%d) "
1287 "is not supported at line %ld in file \"%s\" — "
1288 "inner block dropped"),
1289 ap_num, state->block_aperture_num,
1290 *line_num_p, fd->filename);
1291 }
else if ((ap_num < APERTURE_MIN) || (ap_num >= APERTURE_MAX)) {
1293 _(
"Aperture block D-code %d out of range "
1294 "at line %ld in file \"%s\""),
1295 ap_num, *line_num_p, fd->filename);
1297 state->in_block = TRUE;
1298 state->block_aperture_num = ap_num;
1300 image->
aperture[ap_num] = g_new0(gerbv_aperture_t, 1);
1303 gerbv_stats_add_aperture(stats->aperture_list,
1306 image->
aperture[ap_num]->parameter);
1307 gerbv_stats_add_to_D_list(stats->D_code_list, ap_num);
1310 state->block_netlist->layer = state->layer;
1311 state->block_netlist->state = state->state;
1316 if (state->in_block) {
1317 image->
aperture[state->block_aperture_num]->block_netlist =
1318 state->block_netlist;
1319 state->in_block = FALSE;
1320 state->block_netlist = NULL;
1329 op[0] = gerb_fgetc(fd);
1330 op[1] = gerb_fgetc(fd);
1331 state->state = gerbv_image_return_new_netstate (state->state);
1333 if (op[0] == EOF || op[1] == EOF)
1335 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1337 if (((op[0] ==
'A') && (op[1] ==
'Y')) ||
1338 ((op[0] ==
'B') && (op[1] ==
'X'))) {
1339 state->state->axisSelect = GERBV_AXIS_SELECT_SWAPAB;
1341 state->state->axisSelect = GERBV_AXIS_SELECT_NOSELECT;
1344 op[0] = gerb_fgetc(fd);
1345 op[1] = gerb_fgetc(fd);
1347 if (op[0] == EOF || op[1] == EOF)
1349 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1351 if (((op[0] ==
'A') && (op[1] ==
'Y')) ||
1352 ((op[0] ==
'B') && (op[1] ==
'X'))) {
1353 state->state->axisSelect = GERBV_AXIS_SELECT_SWAPAB;
1355 state->state->axisSelect = GERBV_AXIS_SELECT_NOSELECT;
1362 switch (gerb_fgetc(fd)) {
1374 _(
"EagleCad bug detected: Undefined handling of zeros "
1375 "in format code at line %ld in file \"%s\""),
1376 *line_num_p, fd->filename);
1378 _(
"Defaulting to omitting leading zeros"));
1383 switch (gerb_fgetc(fd)) {
1392 _(
"Invalid coordinate type defined in format code "
1393 "at line %ld in file \"%s\""),
1394 *line_num_p, fd->filename);
1396 _(
"Defaulting to absolute coordinates"));
1399 op[0] = gerb_fgetc(fd);
1400 while((op[0] !=
'*')&&(op[0] != EOF)) {
1403 op[0] = (char)gerb_fgetc(fd);
1404 image->
format->lim_seqno = op[0] -
'0';
1407 op[0] = (char)gerb_fgetc(fd);
1408 image->
format->lim_gf = op[0] -
'0';
1411 op[0] = (char)gerb_fgetc(fd);
1412 image->
format->lim_pf = op[0] -
'0';
1415 op[0] = (char)gerb_fgetc(fd);
1416 image->
format->lim_mf = op[0] -
'0';
1419 op[0] = gerb_fgetc(fd);
1420 if ((op[0] <
'0') || (op[0] >
'6')) {
1422 _(
"Illegal format size '%s' "
1423 "at line %ld in file \"%s\""),
1424 gerbv_escape_char(op[0]),
1425 *line_num_p, fd->filename);
1427 image->
format->x_int = op[0] -
'0';
1428 op[0] = gerb_fgetc(fd);
1429 if ((op[0] <
'0') || (op[0] >
'6')) {
1431 _(
"Illegal format size '%s' "
1432 "at line %ld in file \"%s\""),
1433 gerbv_escape_char(op[0]),
1434 *line_num_p, fd->filename);
1436 image->
format->x_dec = op[0] -
'0';
1439 op[0] = gerb_fgetc(fd);
1440 if ((op[0] <
'0') || (op[0] >
'6')) {
1442 _(
"Illegal format size '%s' "
1443 "at line %ld in file \"%s\""),
1444 gerbv_escape_char(op[0]),
1445 *line_num_p, fd->filename);
1447 image->
format->y_int = op[0] -
'0';
1448 op[0] = gerb_fgetc(fd);
1449 if ((op[0] <
'0') || (op[0] >
'6')) {
1451 _(
"Illegal format size '%s' "
1452 "at line %ld in file \"%s\""),
1453 gerbv_escape_char(op[0]),
1454 *line_num_p, fd->filename);
1456 image->
format->y_dec = op[0] -
'0';
1460 _(
"Illegal format statement '%s' "
1461 "at line %ld in file \"%s\""),
1462 gerbv_escape_char(op[0]),
1463 *line_num_p, fd->filename);
1465 _(
"Ignoring invalid format statement"));
1467 op[0] = gerb_fgetc(fd);
1471 op[0] = gerb_fgetc(fd);
1472 state->state = gerbv_image_return_new_netstate (state->state);
1474 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1478 readValue = gerb_fgetint(fd, NULL);
1479 if (readValue == 1) {
1480 if (state->state->mirrorState == GERBV_MIRROR_STATE_FLIPB)
1481 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPAB;
1483 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPA;
1487 readValue = gerb_fgetint(fd, NULL);
1488 if (readValue == 1) {
1489 if (state->state->mirrorState == GERBV_MIRROR_STATE_FLIPA)
1490 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPAB;
1492 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPB;
1497 _(
"Wrong character '%s' in mirror "
1498 "at line %ld in file \"%s\""),
1499 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1501 op[0] = gerb_fgetc(fd);
1505 op[0] = gerb_fgetc(fd);
1506 op[1] = gerb_fgetc(fd);
1508 if (op[0] == EOF || op[1] == EOF)
1510 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1512 switch (A2I(op[0],op[1])) {
1514 state->state = gerbv_image_return_new_netstate (state->state);
1518 state->state = gerbv_image_return_new_netstate (state->state);
1523 _(
"Illegal unit '%s%s' at line %ld in file \"%s\""),
1524 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]),
1525 *line_num_p, fd->filename);
1529 op[0] = gerb_fgetc(fd);
1531 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1534 state->state->offsetA = gerb_fgetdouble(fd) / scale;
1537 state->state->offsetB = gerb_fgetdouble(fd) / scale;
1541 _(
"Wrong character '%s' in offset "
1542 "at line %ld in file \"%s\""),
1543 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1545 op[0] = gerb_fgetc(fd);
1550 gchar *includeFilename = gerb_fgetstring(fd,
'*');
1552 if (includeFilename) {
1554 if (!g_path_is_absolute(includeFilename)) {
1555 fullPath = g_build_filename (directoryPath, includeFilename, NULL);
1557 fullPath = g_strdup (includeFilename);
1559 if (levelOfRecursion < 10) {
1560 gerb_file_t *includefd = NULL;
1562 includefd = gerb_fopen(fullPath);
1565 gerb_fclose(includefd);
1568 _(
"Included file \"%s\" cannot be found "
1569 "at line %ld in file \"%s\""),
1570 fullPath, *line_num_p, fd->filename);
1575 _(
"Parser encountered more than 10 levels of "
1576 "include file recursion which is not allowed "
1577 "by the RS-274X spec"));
1579 g_free (includeFilename);
1584 op[0] = gerb_fgetc(fd);
1586 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1589 image->
info->offsetA = gerb_fgetdouble(fd) / scale;
1592 image->
info->offsetB = gerb_fgetdouble(fd) / scale;
1596 _(
"Wrong character '%s' in image offset "
1597 "at line %ld in file \"%s\""),
1598 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1600 op[0] = gerb_fgetc(fd);
1604 state->state = gerbv_image_return_new_netstate (state->state);
1605 if (gerb_fgetc(fd) ==
'A')
1606 state->state->
scaleA = gerb_fgetdouble(fd);
1609 if (gerb_fgetc(fd) ==
'B')
1610 state->state->scaleB = gerb_fgetdouble(fd);
1620 op[0] = gerb_fgetc(fd);
1621 op[1] = gerb_fgetc(fd);
1623 if (op[0] == EOF || op[1] == EOF)
1625 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1627 switch (A2I(op[0],op[1])) {
1629 image->info->encoding = GERBV_ENCODING_ASCII;
1632 image->info->encoding = GERBV_ENCODING_EBCDIC;
1635 image->info->encoding = GERBV_ENCODING_BCD;
1638 image->info->encoding = GERBV_ENCODING_ISO_ASCII;
1641 image->info->encoding = GERBV_ENCODING_EIA;
1645 _(
"Unknown input code (IC) '%s%s' "
1646 "at line %ld in file \"%s\""),
1647 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]),
1648 *line_num_p, fd->filename);
1654 op[0] = gerb_fgetc(fd);
1655 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_LOWERLEFT;
1656 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_LOWERLEFT;
1657 image->
info->imageJustifyOffsetA = 0.0;
1658 image->
info->imageJustifyOffsetB = 0.0;
1659 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1662 op[0] = gerb_fgetc(fd);
1664 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_CENTERJUSTIFY;
1665 }
else if (op[0] ==
'L') {
1666 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_LOWERLEFT;
1669 image->
info->imageJustifyOffsetA = gerb_fgetdouble(fd) / scale;
1673 op[0] = gerb_fgetc(fd);
1675 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_CENTERJUSTIFY;
1676 }
else if (op[0] ==
'L') {
1677 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_LOWERLEFT;
1680 image->
info->imageJustifyOffsetB = gerb_fgetdouble(fd) / scale;
1685 _(
"Wrong character '%s' in image justify "
1686 "at line %ld in file \"%s\""),
1687 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1689 op[0] = gerb_fgetc(fd);
1693 image->info->name = gerb_fgetstring(fd,
'*');
1697 for (ano = 0; ano < 3; ano++) {
1698 op[0] = gerb_fgetc(fd);
1701 _(
"Unexpected EOF while reading image polarity (IP) "
1702 "in file \"%s\""), fd->filename);
1704 str[ano] = (char)op[0];
1707 if (strncmp(str,
"POS", 3) == 0)
1709 else if (strncmp(str,
"NEG", 3) == 0)
1713 _(
"Unknown polarity '%s%s%s' "
1714 "at line %ld in file \"%s\""),
1715 gerbv_escape_char(str[0]), gerbv_escape_char(str[1]),
1716 gerbv_escape_char(str[2]), *line_num_p, fd->filename);
1720 tmp = gerb_fgetint(fd, NULL) % 360;
1722 image->
info->imageRotation = 0.0;
1724 image->
info->imageRotation = M_PI_2;
1725 else if (tmp == 180)
1726 image->
info->imageRotation = M_PI;
1727 else if (tmp == 270)
1728 image->
info->imageRotation = M_PI + M_PI_2;
1731 _(
"Image rotation must be 0, 90, 180 or 270 "
1732 "(is actually %d) at line %ld in file \"%s\""),
1733 tmp, *line_num_p, fd->filename);
1737 image->info->plotterFilm = gerb_fgetstring(fd,
'*');
1742 a = (gerbv_aperture_t *) g_new0 (gerbv_aperture_t,1);
1744 ano = parse_aperture_definition(fd, a, image, scale, line_num_p);
1748 else if ((ano >= 0) && (ano <= APERTURE_MAX)) {
1749 a->unit = state->state->unit;
1751 DPRINTF(
" In %s(), adding new aperture to aperture list ...\n",
1753 gerbv_stats_add_aperture(stats->aperture_list,
1757 gerbv_stats_add_to_D_list(stats->D_code_list,
1759 if (ano < APERTURE_MIN) {
1761 _(
"Aperture number out of bounds %d "
1762 "at line %ld in file \"%s\""),
1763 ano, *line_num_p, fd->filename);
1767 _(
"Aperture number out of bounds %d "
1768 "at line %ld in file \"%s\""),
1769 ano, *line_num_p, fd->filename);
1775 tmp_amacro = image->amacro;
1776 image->
amacro = parse_aperture_macro(fd);
1778 image->
amacro->next = tmp_amacro;
1780 print_program(image->
amacro);
1784 _(
"Failed to parse aperture macro "
1785 "at line %ld in file \"%s\""),
1786 *line_num_p, fd->filename);
1792 state->layer = gerbv_image_return_new_layer (state->layer);
1793 state->layer->
name = gerb_fgetstring(fd,
'*');
1796 state->layer = gerbv_image_return_new_layer (state->layer);
1797 switch (gerb_fgetc(fd)) {
1806 _(
"Unknown layer polarity '%s' "
1807 "at line %ld in file \"%s\""),
1808 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1812 state->state = gerbv_image_return_new_netstate(state->state);
1813 state->state->
rotation = DEG2RAD(gerb_fgetdouble(fd));
1816 state->state = gerbv_image_return_new_netstate(state->state);
1817 state->state->
scaleA = gerb_fgetdouble(fd);
1818 state->state->scaleB = state->state->scaleA;
1821 state->state = gerbv_image_return_new_netstate(state->state);
1822 op[0] = gerb_fgetc(fd);
1824 state->state->mirrorState = GERBV_MIRROR_STATE_NOMIRROR;
1825 }
else if (op[0] ==
'X') {
1826 op[1] = gerb_fgetc(fd);
1828 state->state->mirrorState = GERBV_MIRROR_STATE_FLIPAB;
1831 state->state->mirrorState = GERBV_MIRROR_STATE_FLIPA;
1833 }
else if (op[0] ==
'Y') {
1834 state->state->mirrorState = GERBV_MIRROR_STATE_FLIPB;
1837 _(
"Unknown load mirroring parameter '%s' "
1838 "at line %ld in file \"%s\""),
1839 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1843 state->layer = gerbv_image_return_new_layer (state->layer);
1844 gerber_update_any_running_knockout_measurements (image);
1846 knockoutMeasure = FALSE;
1847 op[0] = gerb_fgetc(fd);
1849 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_NOKNOCKOUT;
1851 }
else if (op[0] ==
'C') {
1853 }
else if (op[0] ==
'D') {
1857 _(
"Knockout must supply a polarity (C, D, or *) "
1858 "at line %ld in file \"%s\""),
1859 *line_num_p, fd->filename);
1861 state->layer->knockout.lowerLeftX = 0.0;
1862 state->layer->knockout.lowerLeftY = 0.0;
1863 state->layer->knockout.width = 0.0;
1864 state->layer->knockout.height = 0.0;
1865 state->layer->knockout.border = 0.0;
1866 state->layer->knockout.firstInstance = TRUE;
1867 op[0] = gerb_fgetc(fd);
1868 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1871 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1872 state->layer->knockout.lowerLeftX = gerb_fgetdouble(fd) / scale;
1875 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1876 state->layer->knockout.lowerLeftY = gerb_fgetdouble(fd) / scale;
1879 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1880 state->layer->knockout.width = gerb_fgetdouble(fd) / scale;
1883 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1884 state->layer->knockout.height = gerb_fgetdouble(fd) / scale;
1887 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_BORDER;
1888 state->layer->knockout.border = gerb_fgetdouble(fd) / scale;
1891 knockoutMeasure = TRUE;
1892 knockoutLimitXmin = HUGE_VAL;
1893 knockoutLimitYmin = HUGE_VAL;
1894 knockoutLimitXmax = -HUGE_VAL;
1895 knockoutLimitYmax = -HUGE_VAL;
1896 knockoutLayer = state->layer;
1900 _(
"Unknown variable in knockout "
1901 "at line %ld in file \"%s\""),
1902 *line_num_p, fd->filename);
1904 op[0] = gerb_fgetc(fd);
1909 state->layer = gerbv_image_return_new_layer (state->layer);
1910 op[0] = gerb_fgetc(fd);
1912 state->layer->stepAndRepeat.X = 1;
1913 state->layer->stepAndRepeat.Y = 1;
1914 state->layer->stepAndRepeat.dist_X = 0.0;
1915 state->layer->stepAndRepeat.dist_Y = 0.0;
1918 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1921 state->layer->stepAndRepeat.X = gerb_fgetint(fd, NULL);
1924 state->layer->stepAndRepeat.Y = gerb_fgetint(fd, NULL);
1927 state->layer->stepAndRepeat.dist_X = gerb_fgetdouble(fd) / scale;
1930 state->layer->stepAndRepeat.dist_Y = gerb_fgetdouble(fd) / scale;
1934 _(
"Step-and-repeat parameter error "
1935 "at line %ld in file \"%s\""),
1936 *line_num_p, fd->filename);
1944 if(state->layer->stepAndRepeat.X == 0)
1945 state->layer->stepAndRepeat.X = 1;
1946 if(state->layer->stepAndRepeat.Y == 0)
1947 state->layer->stepAndRepeat.Y = 1;
1949 op[0] = gerb_fgetc(fd);
1954 state->layer = gerbv_image_return_new_layer (state->layer);
1956 state->layer->
rotation = DEG2RAD(gerb_fgetdouble(fd));
1957 op[0] = gerb_fgetc(fd);
1960 _(
"Error in layer rotation command "
1961 "at line %ld in file \"%s\""),
1962 *line_num_p, fd->filename);
1971 _(
"Ignoring Gerber X2 attribute %%%s%s%% "
1972 "at line %ld in file \"%s\""),
1973 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]),
1974 *line_num_p, fd->filename);
1978 _(
"Unknown RS-274X extension found %%%s%s%% "
1979 "at line %ld in file \"%s\""),
1980 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]),
1981 *line_num_p, fd->filename);
1988 tmp = gerb_fgetc(fd);
1989 }
while (tmp != EOF && tmp !=
'*');
2006 static macro_stack_t *
2007 new_stack(
size_t stack_size)
2011 s = (macro_stack_t *) g_new0 (macro_stack_t,1);
2012 s->stack = (
double *) g_new0 (
double, stack_size);
2014 s->capacity = stack_size;
2020 free_stack(macro_stack_t *s)
2033 push(macro_stack_t *s,
double val)
2035 if (s->sp >= s->capacity) {
2036 GERB_FATAL_ERROR(_(
"push will overflow stack capacity"));
2039 s->stack[s->sp++] = val;
2045 pop(macro_stack_t *s,
double *value)
2052 *value = s->stack[--s->sp];
2059 simplify_aperture_macro(gerbv_aperture_t *aperture, gdouble scale)
2061 const int extra_stack_size = 10;
2063 gerbv_instruction_t *ip;
2064 int handled = 1, nuf_parameters = 0, i, j, clearOperatorUsed = FALSE;
2066 double tmp[2] = {0.0, 0.0};
2068 gerbv_simplified_amacro_t *sam;
2070 if (aperture == NULL)
2071 GERB_FATAL_ERROR(_(
"aperture NULL in simplify aperture macro"));
2073 if (aperture->amacro == NULL)
2074 GERB_FATAL_ERROR(_(
"aperture->amacro NULL in simplify aperture macro"));
2077 s = new_stack(aperture->amacro->nuf_push + extra_stack_size);
2079 GERB_FATAL_ERROR(
"malloc stack failed in %s()", __FUNCTION__);
2082 lp = g_new (
double,APERTURE_PARAMETERS_MAX);
2084 memcpy(lp, aperture->parameter,
sizeof(
double) * APERTURE_PARAMETERS_MAX);
2086 for(ip = aperture->amacro->program; ip != NULL; ip = ip->next) {
2087 switch(ip->opcode) {
2091 push(s, ip->data.fval);
2094 ssize_t
const idx = ip->data.ival - 1;
2095 if ((idx < 0) || (idx >= APERTURE_PARAMETERS_MAX))
2096 GERB_FATAL_ERROR(_(
"Tried to access oob aperture"));
2101 if (pop(s, &tmp[0]) < 0)
2102 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2103 ssize_t
const idx = ip->data.ival - 1;
2104 if ((idx < 0) || (idx >= APERTURE_PARAMETERS_MAX))
2105 GERB_FATAL_ERROR(_(
"Tried to access oob aperture"));
2110 if (pop(s, &tmp[0]) < 0)
2111 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2112 if (pop(s, &tmp[1]) < 0)
2113 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2114 push(s, tmp[1] + tmp[0]);
2117 if (pop(s, &tmp[0]) < 0)
2118 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2119 if (pop(s, &tmp[1]) < 0)
2120 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2121 push(s, tmp[1] - tmp[0]);
2124 if (pop(s, &tmp[0]) < 0)
2125 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2126 if (pop(s, &tmp[1]) < 0)
2127 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2128 push(s, tmp[1] * tmp[0]);
2131 if (pop(s, &tmp[0]) < 0)
2132 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2133 if (pop(s, &tmp[1]) < 0)
2134 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2135 push(s, tmp[1] / tmp[0]);
2143 switch(ip->data.ival) {
2145 DPRINTF(
" Aperture macro circle [1] (");
2152 DPRINTF(
" Aperture macro outline [4] (");
2165 int const sstack = (int)s->stack[1];
2166 if ((sstack < 0) || (sstack >= INT_MAX / 4)) {
2167 GERB_COMPILE_ERROR(_(
"Possible signed integer overflow "
2168 "in calculating number of parameters "
2169 "to aperture macro, will clamp to "
2170 "(%d)"), APERTURE_PARAMETERS_MAX);
2171 nuf_parameters = APERTURE_PARAMETERS_MAX;
2173 nuf_parameters = (sstack + 1) * 2 + 3;
2177 DPRINTF(
" Aperture macro polygon [5] (");
2182 DPRINTF(
" Aperture macro moire [6] (");
2187 DPRINTF(
" Aperture macro thermal [7] (");
2193 DPRINTF(
" Aperture macro line 20/2 (");
2198 DPRINTF(
" Aperture macro line 21 (");
2203 DPRINTF(
" Aperture macro line 22 (");
2212 if (nuf_parameters > APERTURE_PARAMETERS_MAX) {
2213 GERB_COMPILE_ERROR(_(
"Number of parameters to aperture macro (%d) "
2214 "are more than gerbv is able to store (%d)"),
2215 nuf_parameters, APERTURE_PARAMETERS_MAX);
2216 nuf_parameters = APERTURE_PARAMETERS_MAX;
2223 sam = g_new (gerbv_simplified_amacro_t, 1);
2226 memset(sam->parameter, 0,
2227 sizeof(
double) * APERTURE_PARAMETERS_MAX);
2231 if (nuf_parameters > s->capacity) {
2232 GERB_COMPILE_ERROR(_(
"Number of parameters to aperture macro (%d) "
2233 "capped to stack capacity (%zu)"),
2234 nuf_parameters, s->capacity);
2235 nuf_parameters = s->capacity;
2242 if (nuf_parameters > s->sp)
2243 nuf_parameters = s->sp;
2244 memcpy(sam->parameter, s->stack,
2245 sizeof(
double) * nuf_parameters);
2250 if (fabs(sam->parameter[0]) < 0.001)
2251 clearOperatorUsed = TRUE;
2252 sam->parameter[1]/=scale;
2253 sam->parameter[2]/=scale;
2254 sam->parameter[3]/=scale;
2257 if (fabs(sam->parameter[0]) < 0.001)
2258 clearOperatorUsed = TRUE;
2259 for (j=2; j<nuf_parameters-1; j++){
2260 sam->parameter[j]/=scale;
2264 if (fabs(sam->parameter[0]) < 0.001)
2265 clearOperatorUsed = TRUE;
2266 sam->parameter[2]/=scale;
2267 sam->parameter[3]/=scale;
2268 sam->parameter[4]/=scale;
2271 sam->parameter[0]/=scale;
2272 sam->parameter[1]/=scale;
2273 sam->parameter[2]/=scale;
2274 sam->parameter[3]/=scale;
2275 sam->parameter[4]/=scale;
2276 sam->parameter[6]/=scale;
2277 sam->parameter[7]/=scale;
2280 sam->parameter[0]/=scale;
2281 sam->parameter[1]/=scale;
2282 sam->parameter[2]/=scale;
2283 sam->parameter[3]/=scale;
2284 sam->parameter[4]/=scale;
2287 if (fabs(sam->parameter[0]) < 0.001)
2288 clearOperatorUsed = TRUE;
2289 sam->parameter[1]/=scale;
2290 sam->parameter[2]/=scale;
2291 sam->parameter[3]/=scale;
2292 sam->parameter[4]/=scale;
2293 sam->parameter[5]/=scale;
2297 if (fabs(sam->parameter[0]) < 0.001)
2298 clearOperatorUsed = TRUE;
2299 sam->parameter[1]/=scale;
2300 sam->parameter[2]/=scale;
2301 sam->parameter[3]/=scale;
2302 sam->parameter[4]/=scale;
2312 if (aperture->simplified == NULL) {
2313 aperture->simplified = sam;
2315 gerbv_simplified_amacro_t *tmp_sam;
2316 tmp_sam = aperture->simplified;
2317 while (tmp_sam->next != NULL) {
2318 tmp_sam = tmp_sam->next;
2320 tmp_sam->next = sam;
2324 for (i = 0; i < nuf_parameters; i++) {
2325 DPRINTF(
"%f, ", s->stack[i]);
2348 aperture->parameter[0]= (gdouble) clearOperatorUsed;
2355 parse_aperture_definition(gerb_file_t *fd, gerbv_aperture_t *aperture,
2357 long int *line_num_p)
2362 gerbv_amacro_t *curr_amacro;
2363 gerbv_amacro_t *amacro = image->
amacro;
2367 if (gerb_fgetc(fd) !=
'D') {
2369 _(
"Found AD code with no following 'D' "
2370 "at line %ld in file \"%s\""),
2371 *line_num_p, fd->filename);
2378 ano = gerb_fgetint(fd, NULL);
2383 ad = gerb_fgetstring(fd,
'*');
2387 _(
"Invalid aperture definition at line %ld in file \"%s\", "
2389 *line_num_p, fd->filename);
2393 token = strtok(ad,
",");
2395 if (token == NULL) {
2397 _(
"Invalid aperture definition at line %ld in file \"%s\""),
2398 *line_num_p, fd->filename);
2401 if (strlen(token) == 1) {
2423 curr_amacro = amacro;
2424 while (curr_amacro) {
2425 if ((strlen(curr_amacro->name) == strlen(token)) &&
2426 (strcmp(curr_amacro->name, token) == 0)) {
2427 aperture->amacro = curr_amacro;
2430 curr_amacro = curr_amacro->next;
2437 for (token = strtok(NULL,
"X"), i = 0; token != NULL;
2438 token = strtok(NULL,
"X"), i++) {
2439 if (i == APERTURE_PARAMETERS_MAX) {
2441 _(
"Maximum number of allowed parameters exceeded "
2442 "in aperture %d at line %ld in file \"%s\""),
2443 ano, *line_num_p, fd->filename);
2448 tempHolder = strtod(token, NULL);
2453 tempHolder /= scale;
2456 aperture->parameter[i] = tempHolder;
2459 _(
"Failed to read all parameters exceeded in "
2460 "aperture %d at line %ld in file \"%s\""),
2461 ano, *line_num_p, fd->filename);
2462 aperture->parameter[i] = 0.0;
2466 aperture->nuf_parameters = i;
2471 DPRINTF(
"Simplifying aperture %d using aperture macro \"%s\"\n", ano,
2472 aperture->amacro->name);
2473 simplify_aperture_macro(aperture, scale);
2474 DPRINTF(
"Done simplifying\n");
2485 calc_cirseg_sq(
struct gerbv_net *net,
int cw,
2486 double delta_cp_x,
double delta_cp_y)
2488 double d1x, d1y, d2x, d2y;
2531 GERB_COMPILE_ERROR(_(
"Unknow quadrant value while converting to cw"));
2556 GERB_COMPILE_ERROR(_(
"Strange quadrant: %d"), quadrant);
2567 alfa = atan2(d1y, d1x);
2568 beta = atan2(d2y, d2x);
2573 net->
cirseg->width = alfa < beta ?
2574 2 * (d1x / cos(alfa)) : 2 * (d2x / cos(beta));
2575 net->
cirseg->height = alfa > beta ?
2576 2 * (d1y / sin(alfa)) : 2 * (d2y / sin(beta));
2578 if (alfa < GERBV_PRECISION_ANGLE_RAD
2579 && beta < GERBV_PRECISION_ANGLE_RAD) {
2585 net->
cirseg->angle1 = RAD2DEG(alfa);
2586 net->
cirseg->angle2 = RAD2DEG(beta);
2589 net->
cirseg->angle1 = 180.0 - RAD2DEG(alfa);
2590 net->
cirseg->angle2 = 180.0 - RAD2DEG(beta);
2593 net->
cirseg->angle1 = 180.0 + RAD2DEG(alfa);
2594 net->
cirseg->angle2 = 180.0 + RAD2DEG(beta);
2597 net->
cirseg->angle1 = 360.0 - RAD2DEG(alfa);
2598 net->
cirseg->angle2 = 360.0 - RAD2DEG(beta);
2601 GERB_COMPILE_ERROR(_(
"Strange quadrant: %d"), quadrant);
2604 if (net->
cirseg->width < 0.0)
2605 GERB_COMPILE_WARNING(_(
"Negative width [%f] in quadrant %d [%f][%f]"),
2606 net->
cirseg->width, quadrant, RAD2DEG(alfa), RAD2DEG(beta));
2608 if (net->
cirseg->height < 0.0)
2609 GERB_COMPILE_WARNING(_(
"Negative height [%f] in quadrant %d [%f][%f]"),
2610 net->
cirseg->height, quadrant, RAD2DEG(alfa), RAD2DEG(beta));
2619 calc_cirseg_mq(
struct gerbv_net *net,
int cw,
2620 double delta_cp_x,
double delta_cp_y)
2622 double d1x, d1y, d2x, d2y;
2641 if (fabs(d1x) < DBL_EPSILON) d1x = 0;
2642 if (fabs(d1y) < DBL_EPSILON) d1y = 0;
2643 if (fabs(d2x) < DBL_EPSILON) d2x = 0;
2644 if (fabs(d2y) < DBL_EPSILON) d2y = 0;
2646 net->
cirseg->width = hypot(delta_cp_x, delta_cp_y);
2647 net->
cirseg->width *= 2.0;
2653 alfa = atan2(d1y, d1x);
2654 beta = atan2(d2y, d2x);
2660 alfa += M_PI + M_PI;
2661 beta += M_PI + M_PI;
2665 beta += M_PI + M_PI;
2675 if (alfa - beta < DBL_EPSILON)
2676 beta -= M_PI + M_PI;
2678 if (beta - alfa < DBL_EPSILON)
2679 beta += M_PI + M_PI;
2682 net->
cirseg->angle1 = RAD2DEG(alfa);
2683 net->
cirseg->angle2 = RAD2DEG(beta);
2688 calc_cirseg_bbox(
const gerbv_cirseg_t *cirseg,
2689 double apert_size_x,
double apert_size_y,
2692 gdouble x, y, ang1, ang2, step_pi_2;
2698 ang1 = DEG2RAD(MIN(cirseg->angle1, cirseg->angle2));
2699 ang2 = DEG2RAD(MAX(cirseg->angle1, cirseg->angle2));
2702 x = cirseg->cp_x + cirseg->width*cos(ang1)/2;
2703 y = cirseg->cp_y + cirseg->width*sin(ang1)/2;
2704 gerber_update_min_and_max(bbox, x, y,
2705 apert_size_x, apert_size_x,
2706 apert_size_y, apert_size_y);
2709 for (step_pi_2 = (floor(ang1/M_PI_2) + 1)*M_PI_2;
2710 step_pi_2 < MIN(ang2, ang1 + 2*M_PI);
2711 step_pi_2 += M_PI_2) {
2712 x = cirseg->cp_x + cirseg->width*cos(step_pi_2)/2;
2713 y = cirseg->cp_y + cirseg->width*sin(step_pi_2)/2;
2714 gerber_update_min_and_max(bbox, x, y,
2715 apert_size_x, apert_size_x,
2716 apert_size_y, apert_size_y);
2720 x = cirseg->cp_x + cirseg->width*cos(ang2)/2;
2721 y = cirseg->cp_y + cirseg->width*sin(ang2)/2;
2722 gerber_update_min_and_max(bbox, x, y,
2723 apert_size_x, apert_size_x,
2724 apert_size_y, apert_size_y);
2728 gerber_update_any_running_knockout_measurements (
gerbv_image_t *image)
2730 if (knockoutMeasure) {
2731 knockoutLayer->
knockout.lowerLeftX = knockoutLimitXmin;
2732 knockoutLayer->
knockout.lowerLeftY = knockoutLimitYmin;
2733 knockoutLayer->
knockout.width = knockoutLimitXmax - knockoutLimitXmin;
2734 knockoutLayer->
knockout.height = knockoutLimitYmax - knockoutLimitYmin;
2735 knockoutMeasure = FALSE;
2741 gerber_calculate_final_justify_effects(
gerbv_image_t *image)
2743 gdouble translateA = 0.0, translateB = 0.0;
2745 if (image->
info->imageJustifyTypeA != GERBV_JUSTIFY_NOJUSTIFY) {
2746 if (image->
info->imageJustifyTypeA == GERBV_JUSTIFY_CENTERJUSTIFY)
2747 translateA = (image->
info->max_x - image->
info->min_x) / 2.0;
2749 translateA = -image->
info->min_x;
2751 if (image->
info->imageJustifyTypeB != GERBV_JUSTIFY_NOJUSTIFY) {
2752 if (image->
info->imageJustifyTypeB == GERBV_JUSTIFY_CENTERJUSTIFY)
2753 translateB = (image->
info->max_y - image->
info->min_y) / 2.0;
2755 translateB = -image->
info->min_y;
2760 image->
info->min_x += translateA+ image->
info->imageJustifyOffsetA;
2761 image->
info->max_x += translateA+ image->
info->imageJustifyOffsetA;
2762 image->
info->min_y += translateB+ image->
info->imageJustifyOffsetB;
2763 image->
info->max_y += translateB+ image->
info->imageJustifyOffsetB;
2767 image->
info->imageJustifyOffsetActualA = translateA +
2768 image->
info->imageJustifyOffsetA;
2769 image->
info->imageJustifyOffsetActualB = translateB +
2770 image->
info->imageJustifyOffsetB;
2776 double repeat_off_X,
double repeat_off_Y,
2779 image->
info->min_x = MIN(image->
info->min_x, boundingBox->
left);
2780 image->
info->min_y = MIN(image->
info->min_y, boundingBox->
bottom);
2781 image->
info->max_x = MAX(image->
info->max_x,
2782 boundingBox->
right + repeat_off_X);
2783 image->
info->max_y = MAX(image->
info->max_y,
2784 boundingBox->
top + repeat_off_Y);
2789 gdouble x, gdouble y, gdouble apertureSizeX1,
2790 gdouble apertureSizeX2,gdouble apertureSizeY1,
2791 gdouble apertureSizeY2)
2793 gdouble ourX1 = x - apertureSizeX1, ourY1 = y - apertureSizeY1;
2794 gdouble ourX2 = x + apertureSizeX2, ourY2 = y + apertureSizeY2;
2800 cairo_matrix_transform_point (¤tMatrix, &ourX1, &ourY1);
2801 cairo_matrix_transform_point (¤tMatrix, &ourX2, &ourY2);
2806 boundingBox->
left = MIN(boundingBox->
left, ourX1);
2807 boundingBox->
left = MIN(boundingBox->
left, ourX2);
2808 boundingBox->
right = MAX(boundingBox->
right, ourX1);
2809 boundingBox->
right = MAX(boundingBox->
right, ourX2);
2812 boundingBox->
top = MAX(boundingBox->
top, ourY1);
2813 boundingBox->
top = MAX(boundingBox->
top, ourY2);
2817 add_trailing_zeros_if_omitted(
int *coord,
int omitted_num,
2822 && omitted_num > 0) {
2823 for (
int i = 0; i < omitted_num; i++)
2836 case 1:
return N_(
"exposure on");
2837 case 2:
return N_(
"exposure off");
2838 case 3:
return N_(
"flash aperture");
2839 default:
return N_(
"unknown D-code");
2847 case 0:
return N_(
"move");
2848 case 1:
return N_(
"1X linear interpolation");
2849 case 2:
return N_(
"CW interpolation");
2850 case 3:
return N_(
"CCW interpolation");
2851 case 4:
return N_(
"comment/ignore block");
2852 case 10:
return N_(
"10X linear interpolation");
2853 case 11:
return N_(
"0.1X linear interpolation");
2854 case 12:
return N_(
"0.01X linear interpolation");
2855 case 36:
return N_(
"poly fill on");
2856 case 37:
return N_(
"poly fill off");
2857 case 54:
return N_(
"tool prepare");
2858 case 55:
return N_(
"flash prepare");
2859 case 70:
return N_(
"units = inches");
2860 case 71:
return N_(
"units = mm");
2861 case 74:
return N_(
"disable 360 circ. interpolation");
2862 case 75:
return N_(
"enable 360 circ. interpolation");
2863 case 90:
return N_(
"absolute units");
2864 case 91:
return N_(
"incremental units");
2865 default:
return N_(
"unknown G-code");
2873 case 0:
return N_(
"program stop (obsolete)");
2874 case 1:
return N_(
"optional stop (obsolete)");
2875 case 2:
return N_(
"end of file");
2876 default:
return N_(
"unknown M-code");
Aperture macro parsing header info.
gerbv_image_t * gerbv_create_image(gerbv_image_t *image, const gchar *type)
Allocate a new gerbv_image structure.
Header info for the image editing and support functions.
gerbv_stats_t * gerbv_stats_new(void)
Allocates a new gerbv_stats structure.
Header info for the statistics generating functions for RS274X files.
gboolean gerber_is_rs274d_p(gerb_file_t *fd)
static void parse_G_code(gerb_file_t *fd, gerb_state_t *state, gerbv_image_t *image, long int *line_num_p)
static void parse_D_code(gerb_file_t *fd, gerb_state_t *state, gerbv_image_t *image, long int *line_num_p)
const char * gerber_d_code_name(int d_code)
Return Gerber D-code name by code number.
const char * gerber_g_code_name(int g_code)
Return Gerber G-code name by code number.
const char * gerber_m_code_name(int m_code)
Return Gerber M-code name by code number.
gboolean gerber_is_rs274x_p(gerb_file_t *fd, gboolean *returnFoundBinary)
gboolean gerber_parse_file_segment(gint levelOfRecursion, gerbv_image_t *image, gerb_state_t *state, gerbv_net_t *curr_net, gerbv_stats_t *stats, gerb_file_t *fd, gchar *directoryPath)
gerbv_image_t * parse_gerb(gerb_file_t *fd, gchar *directoryPath)
Header info for the RS274X parsing functions.
void gerbv_rotate_coord(double *x, double *y, double rad)
The main header file for the libgerbv library.
@ GERBV_APERTURE_STATE_OFF
@ GERBV_APERTURE_STATE_ON
@ GERBV_APERTURE_STATE_FLASH
@ GERBV_OMIT_ZEROS_TRAILING
@ GERBV_OMIT_ZEROS_EXPLICIT
@ GERBV_OMIT_ZEROS_LEADING
@ GERBV_POLARITY_NEGATIVE
@ GERBV_POLARITY_POSITIVE
@ GERBV_COORDINATE_INCREMENTAL
@ GERBV_COORDINATE_ABSOLUTE
@ GERBV_APTYPE_MACRO_LINE20
@ GERBV_APTYPE_MACRO_LINE21
@ GERBV_APTYPE_MACRO_OUTLINE
@ GERBV_APTYPE_MACRO_CIRCLE
@ GERBV_APTYPE_MACRO_POLYGON
@ GERBV_APTYPE_MACRO_THERMAL
@ GERBV_APTYPE_MACRO_LINE22
@ GERBV_APTYPE_MACRO_MOIRE
@ GERBV_INTERPOLATION_LINEARx01
@ GERBV_INTERPOLATION_PAREA_START
@ GERBV_INTERPOLATION_LINEARx001
@ GERBV_INTERPOLATION_CW_CIRCULAR
@ GERBV_INTERPOLATION_PAREA_END
@ GERBV_INTERPOLATION_LINEARx10
@ GERBV_INTERPOLATION_CCW_CIRCULAR
@ GERBV_INTERPOLATION_LINEARx1
gerbv_stats_t * gerbv_stats
gerbv_layertype_t layertype
gerbv_aperture_t * aperture[APERTURE_MAX]
gerbv_netstate_t * states
gerbv_image_info_t * info
gerbv_polarity_t polarity
gerbv_knockout_t knockout
gerbv_render_size_t boundingBox
gerbv_aperture_state_t aperture_state
gerbv_interpolation_t interpolation