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 static 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);
255 case '\0':
case '\t':
case ' ':
263 read = gerb_fgetc(fd);
264 if (read !=
'\r' && read != EOF)
273 read = gerb_fgetc(fd);
274 if (read !=
'\n' && read != EOF)
283 if(c == EOF || c ==
'%')
292 DPRINTF(
"... Found * code at line %ld\n", line_num);
294 if (state->changed == 0)
break;
302 state->prev_x = state->curr_x;
303 state->prev_y = state->curr_y;
306 curr_net = gerber_create_new_net (curr_net, state->
layer, state->state);
311 if (image && image->
format ){
312 x_scale = pow(10.0, (
double)image->
format->x_dec);
313 y_scale = pow(10.0, (
double)image->
format->y_dec);
317 curr_net->
start_x = (double)state->prev_x / x_scale;
318 curr_net->
start_y = (
double)state->prev_y / y_scale;
319 curr_net->
stop_x = (double)state->curr_x / x_scale;
320 curr_net->
stop_y = (
double)state->curr_y / y_scale;
321 delta_cp_x = (double)state->delta_cp_x / x_scale;
322 delta_cp_y = (
double)state->delta_cp_y / y_scale;
324 switch (state->interpolation) {
329 curr_net->
cirseg = g_new0 (gerbv_cirseg_t, 1);
331 calc_cirseg_mq(curr_net, cw, delta_cp_x, delta_cp_y);
333 calc_cirseg_sq(curr_net, cw, delta_cp_x, delta_cp_y);
339 if (delta_cp_x < 0 || delta_cp_y < 0) {
342 _(
"Signed incremental distance IxJy "
343 "in single quadrant %s circular "
344 "interpolation %s at line %ld "
346 cw? _(
"CW"): _(
"CCW"), cw?
"G02":
"G03",
347 line_num, fd->filename);
357 state->parea_start_node = curr_net;
358 state->in_parea_fill = 1;
360 boundingBox = boundingBoxNew;
364 if (state->parea_start_node != NULL) {
365 state->parea_start_node->boundingBox = boundingBox;
368 _(
"End of polygon without start "
369 "at line %ld in file \"%s\""),
370 line_num, fd->filename);
374 state->parea_start_node = NULL;
375 state->in_parea_fill = 0;
385 if (state->in_parea_fill && state->parea_start_node) {
398 && polygonPoints > 0) {
400 curr_net = gerber_create_new_net (curr_net, state->
layer, state->state);
402 state->parea_start_node->boundingBox = boundingBox;
403 state->parea_start_node = curr_net;
405 curr_net = gerber_create_new_net (curr_net, state->
layer, state->state);
406 curr_net->
start_x = (double)state->prev_x / x_scale;
407 curr_net->
start_y = (
double)state->prev_y / y_scale;
408 curr_net->
stop_x = (double)state->curr_x / x_scale;
409 curr_net->
stop_y = (
double)state->curr_y / y_scale;
410 boundingBox = boundingBoxNew;
427 ((state->delta_cp_x == 0.0) && (state->delta_cp_y == 0.0)))
439 state->interpolation = state->prev_interpolation;
445 curr_net->
layer = state->layer;
447 state->delta_cp_x = 0.0;
448 state->delta_cp_y = 0.0;
449 curr_net->
aperture = state->curr_aperture;
456 state->prev_x = state->curr_x;
457 state->prev_y = state->curr_y;
463 if ((curr_net->
aperture == 0) && !state->in_parea_fill)
469 double repeat_off_X = 0.0, repeat_off_Y = 0.0;
472 if (!state->in_parea_fill) {
473 DPRINTF(
" In %s(), adding 1 to D_list ...\n",
475 int retcode = gerbv_stats_increment_D_list_count(
476 stats->D_code_list, curr_net->
aperture,
481 _(
"Found undefined D code D%02d "
482 "at line %ld in file \"%s\""),
483 curr_net->
aperture, line_num, fd->filename);
496 repeat_off_X = (state->layer->stepAndRepeat.X - 1) *
497 state->layer->stepAndRepeat.dist_X;
498 repeat_off_Y = (state->layer->stepAndRepeat.Y - 1) *
499 state->layer->stepAndRepeat.dist_Y;
501 cairo_matrix_init (¤tMatrix, 1, 0, 0, 1, 0, 0);
503 cairo_matrix_translate (¤tMatrix, image->
info->offsetA,
504 image->
info->offsetB);
506 cairo_matrix_rotate (¤tMatrix, image->
info->imageRotation);
510 cairo_matrix_rotate (¤tMatrix, state->layer->rotation);
514 cairo_matrix_scale (¤tMatrix, state->state->scaleA,
515 state->state->scaleB);
517 cairo_matrix_translate (¤tMatrix, state->state->offsetA,
518 state->state->offsetB);
520 switch (state->state->mirrorState) {
521 case GERBV_MIRROR_STATE_FLIPA:
522 cairo_matrix_scale (¤tMatrix, -1, 1);
524 case GERBV_MIRROR_STATE_FLIPB:
525 cairo_matrix_scale (¤tMatrix, 1, -1);
527 case GERBV_MIRROR_STATE_FLIPAB:
528 cairo_matrix_scale (¤tMatrix, -1, -1);
534 if (state->state->axisSelect == GERBV_AXIS_SELECT_SWAPAB) {
538 cairo_matrix_rotate (¤tMatrix, M_PI + M_PI_2);
539 cairo_matrix_scale (¤tMatrix, 1, -1);
545 gerbv_simplified_amacro_t *ls = image->
aperture[curr_net->
aperture]->simplified;
548 gdouble offsetx = 0, offsety = 0, widthx = 0, widthy = 0;
549 gboolean calculatedAlready = FALSE;
552 offsetx=ls->parameter[CIRCLE_CENTER_X];
553 offsety=ls->parameter[CIRCLE_CENTER_Y];
555 DEG2RAD(ls->parameter[CIRCLE_ROTATION]));
556 widthx=widthy=ls->parameter[CIRCLE_DIAMETER];
558 int pointCounter,numberOfPoints;
559 gdouble rotation = DEG2RAD(ls->parameter[
560 OUTLINE_ROTATION_IDX(ls->parameter)]);
561 numberOfPoints = ls->parameter[OUTLINE_NUMBER_OF_POINTS] + 1;
563 for (pointCounter = 0; pointCounter < numberOfPoints; pointCounter++) {
564 gdouble px = ls->parameter[OUTLINE_X_IDX_OF_POINT(pointCounter)];
565 gdouble py = ls->parameter[OUTLINE_Y_IDX_OF_POINT(pointCounter)];
567 gerber_update_min_and_max (&boundingBox,
572 calculatedAlready = TRUE;
574 offsetx = ls->parameter[POLYGON_CENTER_X];
575 offsety = ls->parameter[POLYGON_CENTER_Y];
577 DEG2RAD(ls->parameter[POLYGON_ROTATION]));
578 widthx = widthy = ls->parameter[POLYGON_DIAMETER];
580 offsetx = ls->parameter[MOIRE_CENTER_X];
581 offsety = ls->parameter[MOIRE_CENTER_Y];
583 DEG2RAD(ls->parameter[MOIRE_ROTATION]));
584 widthx = widthy = ls->parameter[MOIRE_OUTSIDE_DIAMETER];
586 offsetx = ls->parameter[THERMAL_CENTER_X];
587 offsety = ls->parameter[THERMAL_CENTER_Y];
589 DEG2RAD(ls->parameter[THERMAL_ROTATION]));
590 widthx = widthy = ls->parameter[THERMAL_OUTSIDE_DIAMETER];
592 gdouble rotation = DEG2RAD(ls->parameter[LINE20_ROTATION]);
593 gdouble sx = ls->parameter[LINE20_START_X];
594 gdouble sy = ls->parameter[LINE20_START_Y];
595 gdouble ex = ls->parameter[LINE20_END_X];
596 gdouble ey = ls->parameter[LINE20_END_Y];
599 widthx = widthy = ls->parameter[LINE20_LINE_WIDTH];
600 gerber_update_min_and_max (&boundingBox,
603 widthx/2,widthx/2,widthy/2,widthy/2);
604 gerber_update_min_and_max (&boundingBox,
607 widthx/2,widthx/2,widthy/2,widthy/2);
608 calculatedAlready = TRUE;
610 gdouble largestDimension = hypot(ls->parameter[LINE21_WIDTH],
611 ls->parameter[LINE21_HEIGHT]);
612 offsetx = ls->parameter[LINE21_CENTER_X];
613 offsety = ls->parameter[LINE21_CENTER_Y];
615 DEG2RAD(ls->parameter[LINE21_ROTATION]));
616 widthx = widthy = largestDimension;
618 gdouble largestDimension = hypot(ls->parameter[LINE22_WIDTH],
619 ls->parameter[LINE22_HEIGHT]);
621 offsetx = ls->parameter[LINE22_LOWER_LEFT_X] +
622 ls->parameter[LINE22_WIDTH]/2;
623 offsety = ls->parameter[LINE22_LOWER_LEFT_Y] +
624 ls->parameter[LINE22_HEIGHT]/2;
626 DEG2RAD(ls->parameter[LINE22_ROTATION]));
627 widthx = widthy=largestDimension;
630 if (!calculatedAlready) {
631 gerber_update_min_and_max (&boundingBox,
632 curr_net->
stop_x + offsetx,
633 curr_net->
stop_y + offsety,
634 widthx/2,widthx/2,widthy/2,widthy/2);
645 aperture_sizeY = aperture_sizeX;
649 aperture_sizeX = aperture_sizeY = 0;
658 calc_cirseg_bbox(curr_net->
cirseg,
659 aperture_sizeX, aperture_sizeY,
667 gerber_update_min_and_max (&boundingBox,
669 aperture_sizeX/2,aperture_sizeX/2,
670 aperture_sizeY/2,aperture_sizeY/2);
672 gerber_update_min_and_max (&boundingBox,
674 aperture_sizeX/2,aperture_sizeX/2,
675 aperture_sizeY/2,aperture_sizeY/2);
682 gerber_update_image_min_max(&boundingBox, repeat_off_X, repeat_off_Y, image);
685 if (knockoutMeasure) {
686 if (boundingBox.left < knockoutLimitXmin)
687 knockoutLimitXmin = boundingBox.left;
688 if (boundingBox.right+repeat_off_X > knockoutLimitXmax)
689 knockoutLimitXmax = boundingBox.right+repeat_off_X;
690 if (boundingBox.bottom < knockoutLimitYmin)
691 knockoutLimitYmin = boundingBox.bottom;
692 if (boundingBox.top+repeat_off_Y > knockoutLimitYmax)
693 knockoutLimitYmax = boundingBox.top+repeat_off_Y;
696 if (!state->in_parea_fill) {
698 boundingBox = boundingBoxNew;
703 case '\0':
case '\t':
case ' ':
710 read = gerb_fgetc(fd);
711 if (read !=
'\r' && read != EOF)
719 read = gerb_fgetc(fd);
720 if (read !=
'\n' && read != EOF)
727 _(
"Found unknown character '%s' (0x%x) "
728 "at line %ld in file \"%s\""),
729 gerbv_escape_char(read), read,
730 line_num, fd->filename);
747 gerb_state_t *state = NULL;
751 gboolean foundEOF = FALSE;
757 setlocale(LC_NUMERIC,
"C" );
763 state = g_new0 (gerb_state_t, 1);
770 GERB_FATAL_ERROR(
"malloc image failed in %s()", __FUNCTION__);
775 GERB_FATAL_ERROR(
"malloc gerbv_stats failed in %s()", __FUNCTION__);
780 state->layer = image->
layers;
781 state->state = image->
states;
782 curr_net->
layer = state->layer;
783 curr_net->
state = state->state;
788 DPRINTF(
"In %s(), starting to parse file...\n", __func__);
794 _(
"Missing Gerber EOF code in file \"%s\""), fd->filename);
798 DPRINTF(
" ... done parsing Gerber file\n");
799 gerber_update_any_running_knockout_measurements (image);
800 gerber_calculate_final_justify_effects(image);
817 gboolean found_binary = FALSE;
818 gboolean found_ADD = FALSE;
819 gboolean found_percent_cmd = FALSE;
820 gboolean found_D0 = FALSE;
821 gboolean found_D2 = FALSE;
822 gboolean found_M0 = FALSE;
823 gboolean found_M2 = FALSE;
824 gboolean found_star = FALSE;
825 gboolean found_X = FALSE;
826 gboolean found_Y = FALSE;
828 DPRINTF(
"%s(%p, %p), fd->fd = %p\n",
829 __func__, fd, returnFoundBinary, fd->fd);
830 buf = (
char *) g_malloc(MAXL);
832 GERB_FATAL_ERROR(
"malloc buf failed while checking for rs274x in %s()",
835 while (fgets(buf, MAXL, fd->fd) != NULL) {
836 DPRINTF(
"buf = \"%s\"\n", buf);
843 for (i = 0; i < len; i++) {
844 if (!isprint((
int) buf[i]) && (buf[i] !=
'\r') &&
845 (buf[i] !=
'\n') && (buf[i] !=
'\t')) {
847 DPRINTF(
"found_binary (%d)\n", buf[i]);
850 if (g_strstr_len(buf, len,
"%ADD")) {
852 DPRINTF(
"found_ADD\n");
854 if (g_strstr_len(buf, len,
"%FS") ||
855 g_strstr_len(buf, len,
"%MO") ||
856 g_strstr_len(buf, len,
"%LP") ||
857 g_strstr_len(buf, len,
"%AM")) {
858 found_percent_cmd = TRUE;
859 DPRINTF(
"found_percent_cmd\n");
861 if (g_strstr_len(buf, len,
"D00") || g_strstr_len(buf, len,
"D0")) {
863 DPRINTF(
"found_D0\n");
865 if (g_strstr_len(buf, len,
"D02") || g_strstr_len(buf, len,
"D2")) {
867 DPRINTF(
"found_D2\n");
869 if (g_strstr_len(buf, len,
"M00") || g_strstr_len(buf, len,
"M0")) {
871 DPRINTF(
"found_M0\n");
873 if (g_strstr_len(buf, len,
"M02") || g_strstr_len(buf, len,
"M2")) {
875 DPRINTF(
"found_M2\n");
877 if (g_strstr_len(buf, len,
"*")) {
879 DPRINTF(
"found_star\n");
882 if ((letter = g_strstr_len(buf, len,
"X")) != NULL) {
883 if (isdigit((
int) letter[1])) {
885 DPRINTF(
"found_X\n");
888 if ((letter = g_strstr_len(buf, len,
"Y")) != NULL) {
889 if (isdigit((
int) letter[1])) {
891 DPRINTF(
"found_Y\n");
898 *returnFoundBinary = found_binary;
901 if ((found_D0 || found_D2 || found_M0 || found_M2) &&
902 (found_ADD || found_percent_cmd) && found_star && (found_X || found_Y))
922 gboolean found_binary = FALSE;
923 gboolean found_ADD = FALSE;
924 gboolean found_D0 = FALSE;
925 gboolean found_D2 = FALSE;
926 gboolean found_M0 = FALSE;
927 gboolean found_M2 = FALSE;
928 gboolean found_star = FALSE;
929 gboolean found_X = FALSE;
930 gboolean found_Y = FALSE;
934 GERB_FATAL_ERROR(
"malloc buf failed while checking for rs274d in %s()",
937 while (fgets(buf, MAXL, fd->fd) != NULL) {
943 for (i = 0; i < len; i++) {
944 if (!isprint( (
int) buf[i]) && (buf[i] !=
'\r') &&
945 (buf[i] !=
'\n') && (buf[i] !=
'\t')) {
950 if (g_strstr_len(buf, len,
"%ADD")) {
953 if (g_strstr_len(buf, len,
"D00") || g_strstr_len(buf, len,
"D0")) {
956 if (g_strstr_len(buf, len,
"D02") || g_strstr_len(buf, len,
"D2")) {
959 if (g_strstr_len(buf, len,
"M00") || g_strstr_len(buf, len,
"M0")) {
962 if (g_strstr_len(buf, len,
"M02") || g_strstr_len(buf, len,
"M2")) {
965 if (g_strstr_len(buf, len,
"*")) {
969 if ((letter = g_strstr_len(buf, len,
"X")) != NULL) {
971 if (isdigit( (
int) letter[1])) {
975 if ((letter = g_strstr_len(buf, len,
"Y")) != NULL) {
977 if (isdigit( (
int) letter[1])) {
986 if ((found_D0 || found_D2 || found_M0 || found_M2) &&
987 !found_ADD && found_star && (found_X || found_Y) &&
1010 op_int=gerb_fgetint(fd, NULL);
1013 DPRINTF(
"\n Found G%02d at line %ld (%s)\n",
1037 if (c ==
'\r' || c ==
'\n') {
1039 _(
"Found newline while parsing "
1040 "G04 code at line %ld in file \"%s\", "
1041 "maybe you forgot a \"*\"?"),
1042 *line_num_p, fd->filename);
1045 while (c != EOF && c !=
'*');
1062 state->prev_interpolation = state->interpolation;
1074 if (gerb_fgetc(fd) ==
'D') {
1075 int a = gerb_fgetint(fd, NULL);
1076 if ((a >= 0) && (a <= APERTURE_MAX)) {
1077 state->curr_aperture = a;
1080 _(
"Found aperture D%02d out of bounds while parsing "
1081 "G code at line %ld in file \"%s\""),
1082 a, *line_num_p, fd->filename);
1086 _(
"Found unexpected code after G54 "
1087 "at line %ld in file \"%s\""),
1088 *line_num_p, fd->filename);
1097 state->state = gerbv_image_return_new_netstate (state->state);
1102 state->state = gerbv_image_return_new_netstate (state->state);
1124 _(
"Encountered unknown G code G%02d "
1125 "at line %ld in file \"%s\""),
1126 op_int, *line_num_p, fd->filename);
1128 _(
"Ignoring unknown G code G%02d"), op_int);
1151 a = gerb_fgetint(fd, NULL);
1152 DPRINTF(
" Found D%02d code at line %ld\n", a, *line_num_p);
1157 _(
"Found invalid D00 code at line %ld in file \"%s\""),
1158 *line_num_p, fd->filename);
1177 if ((a >= 0) && (a <= APERTURE_MAX)) {
1178 state->curr_aperture = a;
1182 _(
"Found out of bounds aperture D%02d "
1183 "at line %ld in file \"%s\""),
1184 a, *line_num_p, fd->filename);
1197 parse_M_code(gerb_file_t *fd,
gerbv_image_t *image,
long int *line_num_p)
1202 op_int=gerb_fgetint(fd, NULL);
1216 _(
"Encountered unknown M%02d code at line %ld in file \"%s\""),
1217 op_int, *line_num_p, fd->filename);
1219 _(
"Ignoring unknown M%02d code"), op_int);
1227 parse_rs274x(gint levelOfRecursion, gerb_file_t *fd,
gerbv_image_t *image,
1229 gchar *directoryPath,
long int *line_num_p)
1234 gerbv_aperture_t *a = NULL;
1235 gerbv_amacro_t *tmp_amacro;
1237 gdouble scale = 1.0;
1243 op[0] = gerb_fgetc(fd);
1244 op[1] = gerb_fgetc(fd);
1246 if (op[0] == EOF || op[1] == EOF)
1248 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1250 switch (A2I(op[0], op[1])){
1256 op[0] = gerb_fgetc(fd);
1257 op[1] = gerb_fgetc(fd);
1258 state->state = gerbv_image_return_new_netstate (state->state);
1260 if (op[0] == EOF || op[1] == EOF)
1262 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1264 if (((op[0] ==
'A') && (op[1] ==
'Y')) ||
1265 ((op[0] ==
'B') && (op[1] ==
'X'))) {
1266 state->state->axisSelect = GERBV_AXIS_SELECT_SWAPAB;
1268 state->state->axisSelect = GERBV_AXIS_SELECT_NOSELECT;
1271 op[0] = gerb_fgetc(fd);
1272 op[1] = gerb_fgetc(fd);
1274 if (op[0] == EOF || op[1] == EOF)
1276 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1278 if (((op[0] ==
'A') && (op[1] ==
'Y')) ||
1279 ((op[0] ==
'B') && (op[1] ==
'X'))) {
1280 state->state->axisSelect = GERBV_AXIS_SELECT_SWAPAB;
1282 state->state->axisSelect = GERBV_AXIS_SELECT_NOSELECT;
1289 switch (gerb_fgetc(fd)) {
1301 _(
"EagleCad bug detected: Undefined handling of zeros "
1302 "in format code at line %ld in file \"%s\""),
1303 *line_num_p, fd->filename);
1305 _(
"Defaulting to omitting leading zeros"));
1310 switch (gerb_fgetc(fd)) {
1319 _(
"Invalid coordinate type defined in format code "
1320 "at line %ld in file \"%s\""),
1321 *line_num_p, fd->filename);
1323 _(
"Defaulting to absolute coordinates"));
1326 op[0] = gerb_fgetc(fd);
1327 while((op[0] !=
'*')&&(op[0] != EOF)) {
1330 op[0] = (char)gerb_fgetc(fd);
1331 image->
format->lim_seqno = op[0] -
'0';
1334 op[0] = (char)gerb_fgetc(fd);
1335 image->
format->lim_gf = op[0] -
'0';
1338 op[0] = (char)gerb_fgetc(fd);
1339 image->
format->lim_pf = op[0] -
'0';
1342 op[0] = (char)gerb_fgetc(fd);
1343 image->
format->lim_mf = op[0] -
'0';
1346 op[0] = gerb_fgetc(fd);
1347 if ((op[0] <
'0') || (op[0] >
'6')) {
1349 _(
"Illegal format size '%s' "
1350 "at line %ld in file \"%s\""),
1351 gerbv_escape_char(op[0]),
1352 *line_num_p, fd->filename);
1354 image->
format->x_int = op[0] -
'0';
1355 op[0] = gerb_fgetc(fd);
1356 if ((op[0] <
'0') || (op[0] >
'6')) {
1358 _(
"Illegal format size '%s' "
1359 "at line %ld in file \"%s\""),
1360 gerbv_escape_char(op[0]),
1361 *line_num_p, fd->filename);
1363 image->
format->x_dec = op[0] -
'0';
1366 op[0] = gerb_fgetc(fd);
1367 if ((op[0] <
'0') || (op[0] >
'6')) {
1369 _(
"Illegal format size '%s' "
1370 "at line %ld in file \"%s\""),
1371 gerbv_escape_char(op[0]),
1372 *line_num_p, fd->filename);
1374 image->
format->y_int = op[0] -
'0';
1375 op[0] = gerb_fgetc(fd);
1376 if ((op[0] <
'0') || (op[0] >
'6')) {
1378 _(
"Illegal format size '%s' "
1379 "at line %ld in file \"%s\""),
1380 gerbv_escape_char(op[0]),
1381 *line_num_p, fd->filename);
1383 image->
format->y_dec = op[0] -
'0';
1387 _(
"Illegal format statement '%s' "
1388 "at line %ld in file \"%s\""),
1389 gerbv_escape_char(op[0]),
1390 *line_num_p, fd->filename);
1392 _(
"Ignoring invalid format statement"));
1394 op[0] = gerb_fgetc(fd);
1398 op[0] = gerb_fgetc(fd);
1399 state->state = gerbv_image_return_new_netstate (state->state);
1401 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1405 readValue = gerb_fgetint(fd, NULL);
1406 if (readValue == 1) {
1407 if (state->state->mirrorState == GERBV_MIRROR_STATE_FLIPB)
1408 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPAB;
1410 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPA;
1414 readValue = gerb_fgetint(fd, NULL);
1415 if (readValue == 1) {
1416 if (state->state->mirrorState == GERBV_MIRROR_STATE_FLIPA)
1417 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPAB;
1419 state->state->mirrorState=GERBV_MIRROR_STATE_FLIPB;
1424 _(
"Wrong character '%s' in mirror "
1425 "at line %ld in file \"%s\""),
1426 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1428 op[0] = gerb_fgetc(fd);
1432 op[0] = gerb_fgetc(fd);
1433 op[1] = gerb_fgetc(fd);
1435 if (op[0] == EOF || op[1] == EOF)
1437 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1439 switch (A2I(op[0],op[1])) {
1441 state->state = gerbv_image_return_new_netstate (state->state);
1445 state->state = gerbv_image_return_new_netstate (state->state);
1450 _(
"Illegal unit '%s%s' at line %ld in file \"%s\""),
1451 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]),
1452 *line_num_p, fd->filename);
1456 op[0] = gerb_fgetc(fd);
1458 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1461 state->state->offsetA = gerb_fgetdouble(fd) / scale;
1464 state->state->offsetB = gerb_fgetdouble(fd) / scale;
1468 _(
"Wrong character '%s' in offset "
1469 "at line %ld in file \"%s\""),
1470 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1472 op[0] = gerb_fgetc(fd);
1477 gchar *includeFilename = gerb_fgetstring(fd,
'*');
1479 if (includeFilename) {
1481 if (!g_path_is_absolute(includeFilename)) {
1482 fullPath = g_build_filename (directoryPath, includeFilename, NULL);
1484 fullPath = g_strdup (includeFilename);
1486 if (levelOfRecursion < 10) {
1487 gerb_file_t *includefd = NULL;
1489 includefd = gerb_fopen(fullPath);
1492 gerb_fclose(includefd);
1495 _(
"Included file \"%s\" cannot be found "
1496 "at line %ld in file \"%s\""),
1497 fullPath, *line_num_p, fd->filename);
1502 _(
"Parser encountered more than 10 levels of "
1503 "include file recursion which is not allowed "
1504 "by the RS-274X spec"));
1506 g_free (includeFilename);
1511 op[0] = gerb_fgetc(fd);
1513 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1516 image->
info->offsetA = gerb_fgetdouble(fd) / scale;
1519 image->
info->offsetB = gerb_fgetdouble(fd) / scale;
1523 _(
"Wrong character '%s' in image offset "
1524 "at line %ld in file \"%s\""),
1525 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1527 op[0] = gerb_fgetc(fd);
1531 state->state = gerbv_image_return_new_netstate (state->state);
1532 if (gerb_fgetc(fd) ==
'A')
1533 state->state->
scaleA = gerb_fgetdouble(fd);
1536 if (gerb_fgetc(fd) ==
'B')
1537 state->state->scaleB = gerb_fgetdouble(fd);
1547 op[0] = gerb_fgetc(fd);
1548 op[1] = gerb_fgetc(fd);
1550 if (op[0] == EOF || op[1] == EOF)
1552 _(
"Unexpected EOF found in file \"%s\""), fd->filename);
1554 switch (A2I(op[0],op[1])) {
1556 image->info->encoding = GERBV_ENCODING_ASCII;
1559 image->info->encoding = GERBV_ENCODING_EBCDIC;
1562 image->info->encoding = GERBV_ENCODING_BCD;
1565 image->info->encoding = GERBV_ENCODING_ISO_ASCII;
1568 image->info->encoding = GERBV_ENCODING_EIA;
1572 _(
"Unknown input code (IC) '%s%s' "
1573 "at line %ld in file \"%s\""),
1574 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]),
1575 *line_num_p, fd->filename);
1581 op[0] = gerb_fgetc(fd);
1582 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_LOWERLEFT;
1583 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_LOWERLEFT;
1584 image->
info->imageJustifyOffsetA = 0.0;
1585 image->
info->imageJustifyOffsetB = 0.0;
1586 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1589 op[0] = gerb_fgetc(fd);
1591 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_CENTERJUSTIFY;
1592 }
else if (op[0] ==
'L') {
1593 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_LOWERLEFT;
1596 image->
info->imageJustifyOffsetA = gerb_fgetdouble(fd) / scale;
1600 op[0] = gerb_fgetc(fd);
1602 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_CENTERJUSTIFY;
1603 }
else if (op[0] ==
'L') {
1604 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_LOWERLEFT;
1607 image->
info->imageJustifyOffsetB = gerb_fgetdouble(fd) / scale;
1612 _(
"Wrong character '%s' in image justify "
1613 "at line %ld in file \"%s\""),
1614 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1616 op[0] = gerb_fgetc(fd);
1620 image->info->name = gerb_fgetstring(fd,
'*');
1624 for (ano = 0; ano < 3; ano++) {
1625 op[0] = gerb_fgetc(fd);
1628 _(
"Unexpected EOF while reading image polarity (IP) "
1629 "in file \"%s\""), fd->filename);
1631 str[ano] = (char)op[0];
1634 if (strncmp(str,
"POS", 3) == 0)
1636 else if (strncmp(str,
"NEG", 3) == 0)
1640 _(
"Unknown polarity '%s%s%s' "
1641 "at line %ld in file \"%s\""),
1642 gerbv_escape_char(str[0]), gerbv_escape_char(str[1]),
1643 gerbv_escape_char(str[2]), *line_num_p, fd->filename);
1647 tmp = gerb_fgetint(fd, NULL) % 360;
1649 image->
info->imageRotation = 0.0;
1651 image->
info->imageRotation = M_PI_2;
1652 else if (tmp == 180)
1653 image->
info->imageRotation = M_PI;
1654 else if (tmp == 270)
1655 image->
info->imageRotation = M_PI + M_PI_2;
1658 _(
"Image rotation must be 0, 90, 180 or 270 "
1659 "(is actually %d) at line %ld in file \"%s\""),
1660 tmp, *line_num_p, fd->filename);
1664 image->info->plotterFilm = gerb_fgetstring(fd,
'*');
1669 a = (gerbv_aperture_t *) g_new0 (gerbv_aperture_t,1);
1671 ano = parse_aperture_definition(fd, a, image, scale, line_num_p);
1675 else if ((ano >= 0) && (ano <= APERTURE_MAX)) {
1676 a->unit = state->state->unit;
1678 DPRINTF(
" In %s(), adding new aperture to aperture list ...\n",
1680 gerbv_stats_add_aperture(stats->aperture_list,
1684 gerbv_stats_add_to_D_list(stats->D_code_list,
1686 if (ano < APERTURE_MIN) {
1688 _(
"Aperture number out of bounds %d "
1689 "at line %ld in file \"%s\""),
1690 ano, *line_num_p, fd->filename);
1694 _(
"Aperture number out of bounds %d "
1695 "at line %ld in file \"%s\""),
1696 ano, *line_num_p, fd->filename);
1702 tmp_amacro = image->amacro;
1703 image->
amacro = parse_aperture_macro(fd);
1705 image->
amacro->next = tmp_amacro;
1707 print_program(image->
amacro);
1711 _(
"Failed to parse aperture macro "
1712 "at line %ld in file \"%s\""),
1713 *line_num_p, fd->filename);
1719 state->layer = gerbv_image_return_new_layer (state->layer);
1720 state->layer->
name = gerb_fgetstring(fd,
'*');
1723 state->layer = gerbv_image_return_new_layer (state->layer);
1724 switch (gerb_fgetc(fd)) {
1733 _(
"Unknown layer polarity '%s' "
1734 "at line %ld in file \"%s\""),
1735 gerbv_escape_char(op[0]), *line_num_p, fd->filename);
1739 state->layer = gerbv_image_return_new_layer (state->layer);
1740 gerber_update_any_running_knockout_measurements (image);
1742 knockoutMeasure = FALSE;
1743 op[0] = gerb_fgetc(fd);
1745 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_NOKNOCKOUT;
1747 }
else if (op[0] ==
'C') {
1749 }
else if (op[0] ==
'D') {
1753 _(
"Knockout must supply a polarity (C, D, or *) "
1754 "at line %ld in file \"%s\""),
1755 *line_num_p, fd->filename);
1757 state->layer->knockout.lowerLeftX = 0.0;
1758 state->layer->knockout.lowerLeftY = 0.0;
1759 state->layer->knockout.width = 0.0;
1760 state->layer->knockout.height = 0.0;
1761 state->layer->knockout.border = 0.0;
1762 state->layer->knockout.firstInstance = TRUE;
1763 op[0] = gerb_fgetc(fd);
1764 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1767 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1768 state->layer->knockout.lowerLeftX = gerb_fgetdouble(fd) / scale;
1771 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1772 state->layer->knockout.lowerLeftY = gerb_fgetdouble(fd) / scale;
1775 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1776 state->layer->knockout.width = gerb_fgetdouble(fd) / scale;
1779 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1780 state->layer->knockout.height = gerb_fgetdouble(fd) / scale;
1783 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_BORDER;
1784 state->layer->knockout.border = gerb_fgetdouble(fd) / scale;
1787 knockoutMeasure = TRUE;
1788 knockoutLimitXmin = HUGE_VAL;
1789 knockoutLimitYmin = HUGE_VAL;
1790 knockoutLimitXmax = -HUGE_VAL;
1791 knockoutLimitYmax = -HUGE_VAL;
1792 knockoutLayer = state->layer;
1796 _(
"Unknown variable in knockout "
1797 "at line %ld in file \"%s\""),
1798 *line_num_p, fd->filename);
1800 op[0] = gerb_fgetc(fd);
1805 state->layer = gerbv_image_return_new_layer (state->layer);
1806 op[0] = gerb_fgetc(fd);
1808 state->layer->stepAndRepeat.X = 1;
1809 state->layer->stepAndRepeat.Y = 1;
1810 state->layer->stepAndRepeat.dist_X = 0.0;
1811 state->layer->stepAndRepeat.dist_Y = 0.0;
1814 while ((op[0] !=
'*')&&(op[0] != EOF)) {
1817 state->layer->stepAndRepeat.X = gerb_fgetint(fd, NULL);
1820 state->layer->stepAndRepeat.Y = gerb_fgetint(fd, NULL);
1823 state->layer->stepAndRepeat.dist_X = gerb_fgetdouble(fd) / scale;
1826 state->layer->stepAndRepeat.dist_Y = gerb_fgetdouble(fd) / scale;
1830 _(
"Step-and-repeat parameter error "
1831 "at line %ld in file \"%s\""),
1832 *line_num_p, fd->filename);
1840 if(state->layer->stepAndRepeat.X == 0)
1841 state->layer->stepAndRepeat.X = 1;
1842 if(state->layer->stepAndRepeat.Y == 0)
1843 state->layer->stepAndRepeat.Y = 1;
1845 op[0] = gerb_fgetc(fd);
1850 state->layer = gerbv_image_return_new_layer (state->layer);
1852 state->layer->
rotation = DEG2RAD(gerb_fgetdouble(fd));
1853 op[0] = gerb_fgetc(fd);
1856 _(
"Error in layer rotation command "
1857 "at line %ld in file \"%s\""),
1858 *line_num_p, fd->filename);
1867 _(
"Ignoring Gerber X2 attribute %%%s%s%% "
1868 "at line %ld in file \"%s\""),
1869 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]),
1870 *line_num_p, fd->filename);
1874 _(
"Unknown RS-274X extension found %%%s%s%% "
1875 "at line %ld in file \"%s\""),
1876 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]),
1877 *line_num_p, fd->filename);
1884 tmp = gerb_fgetc(fd);
1885 }
while (tmp != EOF && tmp !=
'*');
1902 static macro_stack_t *
1903 new_stack(
size_t stack_size)
1907 s = (macro_stack_t *) g_new0 (macro_stack_t,1);
1908 s->stack = (
double *) g_new0 (
double, stack_size);
1910 s->capacity = stack_size;
1916 free_stack(macro_stack_t *s)
1929 push(macro_stack_t *s,
double val)
1931 if (s->sp >= s->capacity) {
1932 GERB_FATAL_ERROR(_(
"push will overflow stack capacity"));
1935 s->stack[s->sp++] = val;
1941 pop(macro_stack_t *s,
double *value)
1948 *value = s->stack[--s->sp];
1955 simplify_aperture_macro(gerbv_aperture_t *aperture, gdouble scale)
1957 const int extra_stack_size = 10;
1959 gerbv_instruction_t *ip;
1960 int handled = 1, nuf_parameters = 0, i, j, clearOperatorUsed = FALSE;
1962 double tmp[2] = {0.0, 0.0};
1964 gerbv_simplified_amacro_t *sam;
1966 if (aperture == NULL)
1967 GERB_FATAL_ERROR(_(
"aperture NULL in simplify aperture macro"));
1969 if (aperture->amacro == NULL)
1970 GERB_FATAL_ERROR(_(
"aperture->amacro NULL in simplify aperture macro"));
1973 s = new_stack(aperture->amacro->nuf_push + extra_stack_size);
1975 GERB_FATAL_ERROR(
"malloc stack failed in %s()", __FUNCTION__);
1978 lp = g_new (
double,APERTURE_PARAMETERS_MAX);
1980 memcpy(lp, aperture->parameter,
sizeof(
double) * APERTURE_PARAMETERS_MAX);
1982 for(ip = aperture->amacro->program; ip != NULL; ip = ip->next) {
1983 switch(ip->opcode) {
1987 push(s, ip->data.fval);
1990 ssize_t
const idx = ip->data.ival - 1;
1991 if ((idx < 0) || (idx >= APERTURE_PARAMETERS_MAX))
1992 GERB_FATAL_ERROR(_(
"Tried to access oob aperture"));
1997 if (pop(s, &tmp[0]) < 0)
1998 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1999 ssize_t
const idx = ip->data.ival - 1;
2000 if ((idx < 0) || (idx >= APERTURE_PARAMETERS_MAX))
2001 GERB_FATAL_ERROR(_(
"Tried to access oob aperture"));
2006 if (pop(s, &tmp[0]) < 0)
2007 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2008 if (pop(s, &tmp[1]) < 0)
2009 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2010 push(s, tmp[1] + tmp[0]);
2013 if (pop(s, &tmp[0]) < 0)
2014 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2015 if (pop(s, &tmp[1]) < 0)
2016 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2017 push(s, tmp[1] - tmp[0]);
2020 if (pop(s, &tmp[0]) < 0)
2021 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2022 if (pop(s, &tmp[1]) < 0)
2023 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2024 push(s, tmp[1] * tmp[0]);
2027 if (pop(s, &tmp[0]) < 0)
2028 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2029 if (pop(s, &tmp[1]) < 0)
2030 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
2031 push(s, tmp[1] / tmp[0]);
2039 switch(ip->data.ival) {
2041 DPRINTF(
" Aperture macro circle [1] (");
2048 DPRINTF(
" Aperture macro outline [4] (");
2061 int const sstack = (int)s->stack[1];
2062 if ((sstack < 0) || (sstack >= INT_MAX / 4)) {
2063 GERB_COMPILE_ERROR(_(
"Possible signed integer overflow "
2064 "in calculating number of parameters "
2065 "to aperture macro, will clamp to "
2066 "(%d)"), APERTURE_PARAMETERS_MAX);
2067 nuf_parameters = APERTURE_PARAMETERS_MAX;
2069 nuf_parameters = (sstack + 1) * 2 + 3;
2073 DPRINTF(
" Aperture macro polygon [5] (");
2078 DPRINTF(
" Aperture macro moire [6] (");
2083 DPRINTF(
" Aperture macro thermal [7] (");
2089 DPRINTF(
" Aperture macro line 20/2 (");
2094 DPRINTF(
" Aperture macro line 21 (");
2099 DPRINTF(
" Aperture macro line 22 (");
2108 if (nuf_parameters > APERTURE_PARAMETERS_MAX) {
2109 GERB_COMPILE_ERROR(_(
"Number of parameters to aperture macro (%d) "
2110 "are more than gerbv is able to store (%d)"),
2111 nuf_parameters, APERTURE_PARAMETERS_MAX);
2112 nuf_parameters = APERTURE_PARAMETERS_MAX;
2119 sam = g_new (gerbv_simplified_amacro_t, 1);
2122 memset(sam->parameter, 0,
2123 sizeof(
double) * APERTURE_PARAMETERS_MAX);
2127 if (nuf_parameters > s->capacity) {
2128 GERB_COMPILE_ERROR(_(
"Number of parameters to aperture macro (%d) "
2129 "capped to stack capacity (%zu)"),
2130 nuf_parameters, s->capacity);
2131 nuf_parameters = s->capacity;
2138 if (nuf_parameters > s->sp)
2139 nuf_parameters = s->sp;
2140 memcpy(sam->parameter, s->stack,
2141 sizeof(
double) * nuf_parameters);
2146 if (fabs(sam->parameter[0]) < 0.001)
2147 clearOperatorUsed = TRUE;
2148 sam->parameter[1]/=scale;
2149 sam->parameter[2]/=scale;
2150 sam->parameter[3]/=scale;
2153 if (fabs(sam->parameter[0]) < 0.001)
2154 clearOperatorUsed = TRUE;
2155 for (j=2; j<nuf_parameters-1; j++){
2156 sam->parameter[j]/=scale;
2160 if (fabs(sam->parameter[0]) < 0.001)
2161 clearOperatorUsed = TRUE;
2162 sam->parameter[2]/=scale;
2163 sam->parameter[3]/=scale;
2164 sam->parameter[4]/=scale;
2167 sam->parameter[0]/=scale;
2168 sam->parameter[1]/=scale;
2169 sam->parameter[2]/=scale;
2170 sam->parameter[3]/=scale;
2171 sam->parameter[4]/=scale;
2172 sam->parameter[6]/=scale;
2173 sam->parameter[7]/=scale;
2176 sam->parameter[0]/=scale;
2177 sam->parameter[1]/=scale;
2178 sam->parameter[2]/=scale;
2179 sam->parameter[3]/=scale;
2180 sam->parameter[4]/=scale;
2183 if (fabs(sam->parameter[0]) < 0.001)
2184 clearOperatorUsed = TRUE;
2185 sam->parameter[1]/=scale;
2186 sam->parameter[2]/=scale;
2187 sam->parameter[3]/=scale;
2188 sam->parameter[4]/=scale;
2189 sam->parameter[5]/=scale;
2193 if (fabs(sam->parameter[0]) < 0.001)
2194 clearOperatorUsed = TRUE;
2195 sam->parameter[1]/=scale;
2196 sam->parameter[2]/=scale;
2197 sam->parameter[3]/=scale;
2198 sam->parameter[4]/=scale;
2208 if (aperture->simplified == NULL) {
2209 aperture->simplified = sam;
2211 gerbv_simplified_amacro_t *tmp_sam;
2212 tmp_sam = aperture->simplified;
2213 while (tmp_sam->next != NULL) {
2214 tmp_sam = tmp_sam->next;
2216 tmp_sam->next = sam;
2220 for (i = 0; i < nuf_parameters; i++) {
2221 DPRINTF(
"%f, ", s->stack[i]);
2244 aperture->parameter[0]= (gdouble) clearOperatorUsed;
2251 parse_aperture_definition(gerb_file_t *fd, gerbv_aperture_t *aperture,
2253 long int *line_num_p)
2258 gerbv_amacro_t *curr_amacro;
2259 gerbv_amacro_t *amacro = image->
amacro;
2263 if (gerb_fgetc(fd) !=
'D') {
2265 _(
"Found AD code with no following 'D' "
2266 "at line %ld in file \"%s\""),
2267 *line_num_p, fd->filename);
2274 ano = gerb_fgetint(fd, NULL);
2279 ad = gerb_fgetstring(fd,
'*');
2283 _(
"Invalid aperture definition at line %ld in file \"%s\", "
2285 *line_num_p, fd->filename);
2289 token = strtok(ad,
",");
2291 if (token == NULL) {
2293 _(
"Invalid aperture definition at line %ld in file \"%s\""),
2294 *line_num_p, fd->filename);
2297 if (strlen(token) == 1) {
2319 curr_amacro = amacro;
2320 while (curr_amacro) {
2321 if ((strlen(curr_amacro->name) == strlen(token)) &&
2322 (strcmp(curr_amacro->name, token) == 0)) {
2323 aperture->amacro = curr_amacro;
2326 curr_amacro = curr_amacro->next;
2333 for (token = strtok(NULL,
"X"), i = 0; token != NULL;
2334 token = strtok(NULL,
"X"), i++) {
2335 if (i == APERTURE_PARAMETERS_MAX) {
2337 _(
"Maximum number of allowed parameters exceeded "
2338 "in aperture %d at line %ld in file \"%s\""),
2339 ano, *line_num_p, fd->filename);
2344 tempHolder = strtod(token, NULL);
2349 tempHolder /= scale;
2352 aperture->parameter[i] = tempHolder;
2355 _(
"Failed to read all parameters exceeded in "
2356 "aperture %d at line %ld in file \"%s\""),
2357 ano, *line_num_p, fd->filename);
2358 aperture->parameter[i] = 0.0;
2362 aperture->nuf_parameters = i;
2367 DPRINTF(
"Simplifying aperture %d using aperture macro \"%s\"\n", ano,
2368 aperture->amacro->name);
2369 simplify_aperture_macro(aperture, scale);
2370 DPRINTF(
"Done simplifying\n");
2381 calc_cirseg_sq(
struct gerbv_net *net,
int cw,
2382 double delta_cp_x,
double delta_cp_y)
2384 double d1x, d1y, d2x, d2y;
2427 GERB_COMPILE_ERROR(_(
"Unknow quadrant value while converting to cw"));
2452 GERB_COMPILE_ERROR(_(
"Strange quadrant: %d"), quadrant);
2463 alfa = atan2(d1y, d1x);
2464 beta = atan2(d2y, d2x);
2469 net->
cirseg->width = alfa < beta ?
2470 2 * (d1x / cos(alfa)) : 2 * (d2x / cos(beta));
2471 net->
cirseg->height = alfa > beta ?
2472 2 * (d1y / sin(alfa)) : 2 * (d2y / sin(beta));
2474 if (alfa < GERBV_PRECISION_ANGLE_RAD
2475 && beta < GERBV_PRECISION_ANGLE_RAD) {
2481 net->
cirseg->angle1 = RAD2DEG(alfa);
2482 net->
cirseg->angle2 = RAD2DEG(beta);
2485 net->
cirseg->angle1 = 180.0 - RAD2DEG(alfa);
2486 net->
cirseg->angle2 = 180.0 - RAD2DEG(beta);
2489 net->
cirseg->angle1 = 180.0 + RAD2DEG(alfa);
2490 net->
cirseg->angle2 = 180.0 + RAD2DEG(beta);
2493 net->
cirseg->angle1 = 360.0 - RAD2DEG(alfa);
2494 net->
cirseg->angle2 = 360.0 - RAD2DEG(beta);
2497 GERB_COMPILE_ERROR(_(
"Strange quadrant: %d"), quadrant);
2500 if (net->
cirseg->width < 0.0)
2501 GERB_COMPILE_WARNING(_(
"Negative width [%f] in quadrant %d [%f][%f]"),
2502 net->
cirseg->width, quadrant, RAD2DEG(alfa), RAD2DEG(beta));
2504 if (net->
cirseg->height < 0.0)
2505 GERB_COMPILE_WARNING(_(
"Negative height [%f] in quadrant %d [%f][%f]"),
2506 net->
cirseg->height, quadrant, RAD2DEG(alfa), RAD2DEG(beta));
2515 calc_cirseg_mq(
struct gerbv_net *net,
int cw,
2516 double delta_cp_x,
double delta_cp_y)
2518 double d1x, d1y, d2x, d2y;
2537 if (fabs(d1x) < DBL_EPSILON) d1x = 0;
2538 if (fabs(d1y) < DBL_EPSILON) d1y = 0;
2539 if (fabs(d2x) < DBL_EPSILON) d2x = 0;
2540 if (fabs(d2y) < DBL_EPSILON) d2y = 0;
2542 net->
cirseg->width = hypot(delta_cp_x, delta_cp_y);
2543 net->
cirseg->width *= 2.0;
2549 alfa = atan2(d1y, d1x);
2550 beta = atan2(d2y, d2x);
2556 alfa += M_PI + M_PI;
2557 beta += M_PI + M_PI;
2561 beta += M_PI + M_PI;
2571 if (alfa - beta < DBL_EPSILON)
2572 beta -= M_PI + M_PI;
2574 if (beta - alfa < DBL_EPSILON)
2575 beta += M_PI + M_PI;
2578 net->
cirseg->angle1 = RAD2DEG(alfa);
2579 net->
cirseg->angle2 = RAD2DEG(beta);
2584 calc_cirseg_bbox(
const gerbv_cirseg_t *cirseg,
2585 double apert_size_x,
double apert_size_y,
2588 gdouble x, y, ang1, ang2, step_pi_2;
2594 ang1 = DEG2RAD(MIN(cirseg->angle1, cirseg->angle2));
2595 ang2 = DEG2RAD(MAX(cirseg->angle1, cirseg->angle2));
2598 x = cirseg->cp_x + cirseg->width*cos(ang1)/2;
2599 y = cirseg->cp_y + cirseg->width*sin(ang1)/2;
2600 gerber_update_min_and_max(bbox, x, y,
2601 apert_size_x, apert_size_x,
2602 apert_size_y, apert_size_y);
2605 for (step_pi_2 = (floor(ang1/M_PI_2) + 1)*M_PI_2;
2606 step_pi_2 < MIN(ang2, ang1 + 2*M_PI);
2607 step_pi_2 += M_PI_2) {
2608 x = cirseg->cp_x + cirseg->width*cos(step_pi_2)/2;
2609 y = cirseg->cp_y + cirseg->width*sin(step_pi_2)/2;
2610 gerber_update_min_and_max(bbox, x, y,
2611 apert_size_x, apert_size_x,
2612 apert_size_y, apert_size_y);
2616 x = cirseg->cp_x + cirseg->width*cos(ang2)/2;
2617 y = cirseg->cp_y + cirseg->width*sin(ang2)/2;
2618 gerber_update_min_and_max(bbox, x, y,
2619 apert_size_x, apert_size_x,
2620 apert_size_y, apert_size_y);
2624 gerber_update_any_running_knockout_measurements (
gerbv_image_t *image)
2626 if (knockoutMeasure) {
2627 knockoutLayer->
knockout.lowerLeftX = knockoutLimitXmin;
2628 knockoutLayer->
knockout.lowerLeftY = knockoutLimitYmin;
2629 knockoutLayer->
knockout.width = knockoutLimitXmax - knockoutLimitXmin;
2630 knockoutLayer->
knockout.height = knockoutLimitYmax - knockoutLimitYmin;
2631 knockoutMeasure = FALSE;
2637 gerber_calculate_final_justify_effects(
gerbv_image_t *image)
2639 gdouble translateA = 0.0, translateB = 0.0;
2641 if (image->
info->imageJustifyTypeA != GERBV_JUSTIFY_NOJUSTIFY) {
2642 if (image->
info->imageJustifyTypeA == GERBV_JUSTIFY_CENTERJUSTIFY)
2643 translateA = (image->
info->max_x - image->
info->min_x) / 2.0;
2645 translateA = -image->
info->min_x;
2647 if (image->
info->imageJustifyTypeB != GERBV_JUSTIFY_NOJUSTIFY) {
2648 if (image->
info->imageJustifyTypeB == GERBV_JUSTIFY_CENTERJUSTIFY)
2649 translateB = (image->
info->max_y - image->
info->min_y) / 2.0;
2651 translateB = -image->
info->min_y;
2656 image->
info->min_x += translateA+ image->
info->imageJustifyOffsetA;
2657 image->
info->max_x += translateA+ image->
info->imageJustifyOffsetA;
2658 image->
info->min_y += translateB+ image->
info->imageJustifyOffsetB;
2659 image->
info->max_y += translateB+ image->
info->imageJustifyOffsetB;
2663 image->
info->imageJustifyOffsetActualA = translateA +
2664 image->
info->imageJustifyOffsetA;
2665 image->
info->imageJustifyOffsetActualB = translateB +
2666 image->
info->imageJustifyOffsetB;
2672 double repeat_off_X,
double repeat_off_Y,
2675 image->
info->min_x = MIN(image->
info->min_x, boundingBox->
left);
2676 image->
info->min_y = MIN(image->
info->min_y, boundingBox->
bottom);
2677 image->
info->max_x = MAX(image->
info->max_x,
2678 boundingBox->
right + repeat_off_X);
2679 image->
info->max_y = MAX(image->
info->max_y,
2680 boundingBox->
top + repeat_off_Y);
2685 gdouble x, gdouble y, gdouble apertureSizeX1,
2686 gdouble apertureSizeX2,gdouble apertureSizeY1,
2687 gdouble apertureSizeY2)
2689 gdouble ourX1 = x - apertureSizeX1, ourY1 = y - apertureSizeY1;
2690 gdouble ourX2 = x + apertureSizeX2, ourY2 = y + apertureSizeY2;
2696 cairo_matrix_transform_point (¤tMatrix, &ourX1, &ourY1);
2697 cairo_matrix_transform_point (¤tMatrix, &ourX2, &ourY2);
2702 boundingBox->
left = MIN(boundingBox->
left, ourX1);
2703 boundingBox->
left = MIN(boundingBox->
left, ourX2);
2704 boundingBox->
right = MAX(boundingBox->
right, ourX1);
2705 boundingBox->
right = MAX(boundingBox->
right, ourX2);
2708 boundingBox->
top = MAX(boundingBox->
top, ourY1);
2709 boundingBox->
top = MAX(boundingBox->
top, ourY2);
2713 add_trailing_zeros_if_omitted(
int *coord,
int omitted_num,
2718 && omitted_num > 0) {
2719 for (
int i = 0; i < omitted_num; i++)
2732 case 1:
return N_(
"exposure on");
2733 case 2:
return N_(
"exposure off");
2734 case 3:
return N_(
"flash aperture");
2735 default:
return N_(
"unknown D-code");
2743 case 0:
return N_(
"move");
2744 case 1:
return N_(
"1X linear interpolation");
2745 case 2:
return N_(
"CW interpolation");
2746 case 3:
return N_(
"CCW interpolation");
2747 case 4:
return N_(
"comment/ignore block");
2748 case 10:
return N_(
"10X linear interpolation");
2749 case 11:
return N_(
"0.1X linear interpolation");
2750 case 12:
return N_(
"0.01X linear interpolation");
2751 case 36:
return N_(
"poly fill on");
2752 case 37:
return N_(
"poly fill off");
2753 case 54:
return N_(
"tool prepare");
2754 case 55:
return N_(
"flash prepare");
2755 case 70:
return N_(
"units = inches");
2756 case 71:
return N_(
"units = mm");
2757 case 74:
return N_(
"disable 360 circ. interpolation");
2758 case 75:
return N_(
"enable 360 circ. interpolation");
2759 case 90:
return N_(
"absolute units");
2760 case 91:
return N_(
"incremental units");
2761 default:
return N_(
"unknown G-code");
2769 case 0:
return N_(
"program stop (obsolete)");
2770 case 1:
return N_(
"optional stop (obsolete)");
2771 case 2:
return N_(
"end of file");
2772 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