50 #define A2I(a, b) (((a & 0xff) << 8) + (b & 0xff))
57 static int parse_M_code(gerb_file_t* fd,
gerbv_image_t* image,
long int* line_num_p);
58 static void parse_rs274x(
60 gerbv_stats_t* stats, gchar* directoryPath,
long int* line_num_p
62 static int parse_aperture_definition(
63 gerb_file_t* fd, gerbv_aperture_t* aperture,
gerbv_image_t* image, gdouble scale,
long int* line_num_p
65 static void calc_cirseg_sq(
struct gerbv_net* net,
int cw,
double delta_cp_x,
double delta_cp_y);
66 static void calc_cirseg_mq(
struct gerbv_net* net,
int cw,
double delta_cp_x,
double delta_cp_y);
68 calc_cirseg_bbox(
const gerbv_cirseg_t* cirseg,
double apert_size_x,
double apert_size_y,
gerbv_render_size_t* bbox);
70 static void gerber_update_any_running_knockout_measurements(
gerbv_image_t* image);
72 static void gerber_calculate_final_justify_effects(
gerbv_image_t* image);
74 static gboolean add_trailing_zeros_if_omitted(
int* coord,
int omitted_num,
gerbv_format_t* format);
76 gboolean knockoutMeasure = FALSE;
77 gdouble knockoutLimitXmin, knockoutLimitYmin, knockoutLimitXmax, knockoutLimitYmax;
79 cairo_matrix_t currentMatrix;
86 currentNet->
next = newNet;
88 newNet->
layer = layer;
92 newNet->
state = state;
100 gerber_create_new_aperture(
106 for (i = 0; i <= APERTURE_MAX; i++) {
108 image->
aperture[i] = g_new0(gerbv_aperture_t, 1);
109 image->
aperture[i]->type = apertureType;
110 image->
aperture[i]->parameter[0] = parameter1;
111 image->
aperture[i]->parameter[1] = parameter2;
132 gerb_file_t* fd, gchar* directoryPath
134 int read, coord, len, polygonPoints = 0;
135 double x_scale = 0.0, y_scale = 0.0;
136 double delta_cp_x = 0.0, delta_cp_y = 0.0;
137 double aperture_sizeX, aperture_sizeY;
139 gboolean foundEOF = FALSE;
140 gerbv_render_size_t boundingBoxNew = { HUGE_VAL, -HUGE_VAL, HUGE_VAL, -HUGE_VAL }, boundingBox = boundingBoxNew;
142 long int line_num = 1;
144 while ((read = gerb_fgetc(fd)) != EOF) {
151 switch ((
char)(read & 0xff)) {
153 dprintf(
"... Found G code at line %ld\n", line_num);
157 dprintf(
"... Found D code at line %ld\n", line_num);
161 dprintf(
"... Found M code at line %ld\n", line_num);
163 switch (parse_M_code(fd, image, &line_num)) {
166 case 3: foundEOF = TRUE;
break;
170 line_num, fd->filename
176 coord = gerb_fgetint(fd, &len);
178 add_trailing_zeros_if_omitted(
181 dprintf(
"... Found X code %d at line %ld\n", coord, line_num);
183 state->curr_x += coord;
185 state->curr_x = coord;
192 coord = gerb_fgetint(fd, &len);
194 add_trailing_zeros_if_omitted(
197 dprintf(
"... Found Y code %d at line %ld\n", coord, line_num);
199 state->curr_y += coord;
201 state->curr_y = coord;
208 coord = gerb_fgetint(fd, &len);
210 add_trailing_zeros_if_omitted(
213 dprintf(
"... Found I code %d at line %ld\n", coord, line_num);
214 state->delta_cp_x = coord;
220 coord = gerb_fgetint(fd, &len);
222 add_trailing_zeros_if_omitted(
225 dprintf(
"... Found J code %d at line %ld\n", coord, line_num);
226 state->delta_cp_y = coord;
231 dprintf(
"... Found %% code at line %ld\n", line_num);
233 parse_rs274x(levelOfRecursion, fd, image, state, curr_net, stats, directoryPath, &line_num);
249 read = gerb_fgetc(fd);
250 if (read !=
'\r' && read != EOF)
259 read = gerb_fgetc(fd);
260 if (read !=
'\n' && read != EOF)
269 if (c == EOF || c ==
'%')
278 dprintf(
"... Found * code at line %ld\n", line_num);
280 if (state->changed == 0)
289 state->prev_x = state->curr_x;
290 state->prev_y = state->curr_y;
293 curr_net = gerber_create_new_net(curr_net, state->
layer, state->state);
298 if (image && image->
format) {
299 x_scale = pow(10.0, (
double)image->
format->x_dec);
300 y_scale = pow(10.0, (
double)image->
format->y_dec);
304 curr_net->
start_x = (double)state->prev_x / x_scale;
305 curr_net->
start_y = (
double)state->prev_y / y_scale;
306 curr_net->
stop_x = (double)state->curr_x / x_scale;
307 curr_net->
stop_y = (
double)state->curr_y / y_scale;
308 delta_cp_x = (double)state->delta_cp_x / x_scale;
309 delta_cp_y = (
double)state->delta_cp_y / y_scale;
311 switch (state->interpolation) {
317 curr_net->
cirseg = g_new0(gerbv_cirseg_t, 1);
319 calc_cirseg_mq(curr_net, cw, delta_cp_x, delta_cp_y);
321 calc_cirseg_sq(curr_net, cw, delta_cp_x, delta_cp_y);
327 if (delta_cp_x < 0 || delta_cp_y < 0) {
330 _(
"Signed incremental distance IxJy "
331 "in single quadrant %s circular "
332 "interpolation %s at line %ld "
334 cw ? _(
"CW") : _(
"CCW"), cw ?
"G02" :
"G03", line_num, fd->filename
344 state->parea_start_node = curr_net;
345 state->in_parea_fill = 1;
347 boundingBox = boundingBoxNew;
351 if (state->parea_start_node != NULL) {
352 state->parea_start_node->boundingBox = boundingBox;
356 _(
"End of polygon without start "
357 "at line %ld in file \"%s\""),
358 line_num, fd->filename
363 state->parea_start_node = NULL;
364 state->in_parea_fill = 0;
373 if (state->in_parea_fill && state->parea_start_node) {
387 curr_net = gerber_create_new_net(curr_net, state->
layer, state->state);
389 state->parea_start_node->boundingBox = boundingBox;
390 state->parea_start_node = curr_net;
392 curr_net = gerber_create_new_net(curr_net, state->
layer, state->state);
393 curr_net->
start_x = (double)state->prev_x / x_scale;
394 curr_net->
start_y = (
double)state->prev_y / y_scale;
395 curr_net->
stop_x = (double)state->curr_x / x_scale;
396 curr_net->
stop_y = (
double)state->curr_y / y_scale;
397 boundingBox = boundingBoxNew;
413 && ((state->delta_cp_x == 0.0) && (state->delta_cp_y == 0.0)))
425 state->interpolation = state->prev_interpolation;
431 curr_net->
layer = state->layer;
433 state->delta_cp_x = 0.0;
434 state->delta_cp_y = 0.0;
435 curr_net->
aperture = state->curr_aperture;
442 state->prev_x = state->curr_x;
443 state->prev_y = state->curr_y;
449 if ((curr_net->
aperture == 0) && !state->in_parea_fill)
455 double repeat_off_X = 0.0, repeat_off_Y = 0.0;
458 if (!state->in_parea_fill) {
459 dprintf(
" In %s(), adding 1 to D_list ...\n", __func__);
461 gerbv_stats_increment_D_list_count(stats->D_code_list, curr_net->
aperture, 1,
error_list);
465 _(
"Found undefined D code D%02d "
466 "at line %ld in file \"%s\""),
467 curr_net->
aperture, line_num, fd->filename
481 repeat_off_X = (state->layer->stepAndRepeat.X - 1) * state->layer->stepAndRepeat.dist_X;
482 repeat_off_Y = (state->layer->stepAndRepeat.Y - 1) * state->layer->stepAndRepeat.dist_Y;
484 cairo_matrix_init(¤tMatrix, 1, 0, 0, 1, 0, 0);
486 cairo_matrix_translate(¤tMatrix, image->
info->offsetA, image->
info->offsetB);
488 cairo_matrix_rotate(¤tMatrix, image->
info->imageRotation);
492 cairo_matrix_rotate(¤tMatrix, state->layer->rotation);
496 cairo_matrix_scale(¤tMatrix, state->state->scaleA, state->state->scaleB);
498 cairo_matrix_translate(¤tMatrix, state->state->offsetA, state->state->offsetB);
500 switch (state->state->mirrorState) {
501 case GERBV_MIRROR_STATE_FLIPA: cairo_matrix_scale(¤tMatrix, -1, 1);
break;
502 case GERBV_MIRROR_STATE_FLIPB: cairo_matrix_scale(¤tMatrix, 1, -1);
break;
503 case GERBV_MIRROR_STATE_FLIPAB: cairo_matrix_scale(¤tMatrix, -1, -1);
break;
507 if (state->state->axisSelect == GERBV_AXIS_SELECT_SWAPAB) {
511 cairo_matrix_rotate(¤tMatrix, M_PI + M_PI_2);
512 cairo_matrix_scale(¤tMatrix, 1, -1);
518 gerbv_simplified_amacro_t* ls = image->
aperture[curr_net->
aperture]->simplified;
521 gdouble offsetx = 0, offsety = 0, widthx = 0, widthy = 0;
522 gboolean calculatedAlready = FALSE;
525 offsetx = ls->parameter[CIRCLE_CENTER_X];
526 offsety = ls->parameter[CIRCLE_CENTER_Y];
527 widthx = widthy = ls->parameter[CIRCLE_DIAMETER];
529 int pointCounter, numberOfPoints;
530 numberOfPoints = ls->parameter[OUTLINE_NUMBER_OF_POINTS] + 1;
532 for (pointCounter = 0; pointCounter < numberOfPoints; pointCounter++) {
533 gerber_update_min_and_max(
535 curr_net->
stop_x + ls->parameter[OUTLINE_X_IDX_OF_POINT(pointCounter)],
536 curr_net->
stop_y + ls->parameter[OUTLINE_Y_IDX_OF_POINT(pointCounter)], 0, 0, 0,
540 calculatedAlready = TRUE;
542 offsetx = ls->parameter[POLYGON_CENTER_X];
543 offsety = ls->parameter[POLYGON_CENTER_Y];
544 widthx = widthy = ls->parameter[POLYGON_DIAMETER];
546 offsetx = ls->parameter[MOIRE_CENTER_X];
547 offsety = ls->parameter[MOIRE_CENTER_Y];
548 widthx = widthy = ls->parameter[MOIRE_OUTSIDE_DIAMETER];
550 offsetx = ls->parameter[THERMAL_CENTER_X];
551 offsety = ls->parameter[THERMAL_CENTER_Y];
552 widthx = widthy = ls->parameter[THERMAL_OUTSIDE_DIAMETER];
554 widthx = widthy = ls->parameter[LINE20_LINE_WIDTH];
555 gerber_update_min_and_max(
556 &boundingBox, curr_net->
stop_x + ls->parameter[LINE20_START_X],
557 curr_net->
stop_y + ls->parameter[LINE20_START_Y], widthx / 2, widthx / 2,
558 widthy / 2, widthy / 2
560 gerber_update_min_and_max(
561 &boundingBox, curr_net->
stop_x + ls->parameter[LINE20_END_X],
562 curr_net->
stop_y + ls->parameter[LINE20_END_Y], widthx / 2, widthx / 2, widthy / 2,
565 calculatedAlready = TRUE;
567 gdouble largestDimension =
568 hypot(ls->parameter[LINE21_WIDTH], ls->parameter[LINE21_HEIGHT]);
569 offsetx = ls->parameter[LINE21_CENTER_X];
570 offsety = ls->parameter[LINE21_CENTER_Y];
571 widthx = widthy = largestDimension;
573 gdouble largestDimension =
574 hypot(ls->parameter[LINE22_WIDTH], ls->parameter[LINE22_HEIGHT]);
576 offsetx = ls->parameter[LINE22_LOWER_LEFT_X] + ls->parameter[LINE22_WIDTH] / 2;
577 offsety = ls->parameter[LINE22_LOWER_LEFT_Y] + ls->parameter[LINE22_HEIGHT] / 2;
578 widthx = widthy = largestDimension;
581 if (!calculatedAlready) {
582 gerber_update_min_and_max(
583 &boundingBox, curr_net->
stop_x + offsetx, curr_net->
stop_y + offsety, widthx / 2,
584 widthx / 2, widthy / 2, widthy / 2
596 aperture_sizeY = aperture_sizeX;
600 aperture_sizeX = aperture_sizeY = 0;
607 calc_cirseg_bbox(curr_net->
cirseg, aperture_sizeX, aperture_sizeY, &boundingBox);
614 gerber_update_min_and_max(
615 &boundingBox, curr_net->
start_x, curr_net->
start_y, aperture_sizeX / 2,
616 aperture_sizeX / 2, aperture_sizeY / 2, aperture_sizeY / 2
619 gerber_update_min_and_max(
620 &boundingBox, curr_net->
stop_x, curr_net->
stop_y, aperture_sizeX / 2,
621 aperture_sizeX / 2, aperture_sizeY / 2, aperture_sizeY / 2
628 gerber_update_image_min_max(&boundingBox, repeat_off_X, repeat_off_Y, image);
631 if (knockoutMeasure) {
632 if (boundingBox.left < knockoutLimitXmin)
633 knockoutLimitXmin = boundingBox.left;
634 if (boundingBox.right + repeat_off_X > knockoutLimitXmax)
635 knockoutLimitXmax = boundingBox.right + repeat_off_X;
636 if (boundingBox.bottom < knockoutLimitYmin)
637 knockoutLimitYmin = boundingBox.bottom;
638 if (boundingBox.top + repeat_off_Y > knockoutLimitYmax)
639 knockoutLimitYmax = boundingBox.top + repeat_off_Y;
642 if (!state->in_parea_fill) {
644 boundingBox = boundingBoxNew;
657 read = gerb_fgetc(fd);
658 if (read !=
'\r' && read != EOF)
666 read = gerb_fgetc(fd);
667 if (read !=
'\n' && read != EOF)
675 _(
"Found unknown character '%s' (0x%x) "
676 "at line %ld in file \"%s\""),
677 gerbv_escape_char(read), read, line_num, fd->filename
693 gerb_state_t* state = NULL;
697 gboolean foundEOF = FALSE;
703 setlocale(LC_NUMERIC,
"C");
709 state = g_new0(gerb_state_t, 1);
716 GERB_FATAL_ERROR(
"malloc image failed in %s()", __FUNCTION__);
721 GERB_FATAL_ERROR(
"malloc gerbv_stats failed in %s()", __FUNCTION__);
726 state->layer = image->
layers;
727 state->state = image->
states;
728 curr_net->
layer = state->layer;
729 curr_net->
state = state->state;
734 dprintf(
"In %s(), starting to parse file...\n", __func__);
739 stats->error_list,
GERBV_MESSAGE_ERROR, -1, _(
"Missing Gerber EOF code in file \"%s\""), fd->filename
744 dprintf(
" ... done parsing Gerber file\n");
745 gerber_update_any_running_knockout_measurements(image);
746 gerber_calculate_final_justify_effects(image);
761 gboolean found_binary = FALSE;
762 gboolean found_ADD = FALSE;
763 gboolean found_D0 = FALSE;
764 gboolean found_D2 = FALSE;
765 gboolean found_M0 = FALSE;
766 gboolean found_M2 = FALSE;
767 gboolean found_star = FALSE;
768 gboolean found_X = FALSE;
769 gboolean found_Y = FALSE;
771 dprintf(
"%s(%p, %p), fd->fd = %p\n", __func__, fd, returnFoundBinary, fd->fd);
772 buf = (
char*)g_malloc(MAXL);
774 GERB_FATAL_ERROR(
"malloc buf failed while checking for rs274x in %s()", __FUNCTION__);
776 while (fgets(buf, MAXL, fd->fd) != NULL) {
777 dprintf(
"buf = \"%s\"\n", buf);
784 for (i = 0; i < len; i++) {
785 if (!isprint((
int)buf[i]) && (buf[i] !=
'\r') && (buf[i] !=
'\n') && (buf[i] !=
'\t')) {
787 dprintf(
"found_binary (%d)\n", buf[i]);
790 if (g_strstr_len(buf, len,
"%ADD")) {
792 dprintf(
"found_ADD\n");
794 if (g_strstr_len(buf, len,
"D00") || g_strstr_len(buf, len,
"D0")) {
796 dprintf(
"found_D0\n");
798 if (g_strstr_len(buf, len,
"D02") || g_strstr_len(buf, len,
"D2")) {
800 dprintf(
"found_D2\n");
802 if (g_strstr_len(buf, len,
"M00") || g_strstr_len(buf, len,
"M0")) {
804 dprintf(
"found_M0\n");
806 if (g_strstr_len(buf, len,
"M02") || g_strstr_len(buf, len,
"M2")) {
808 dprintf(
"found_M2\n");
810 if (g_strstr_len(buf, len,
"*")) {
812 dprintf(
"found_star\n");
815 if ((letter = g_strstr_len(buf, len,
"X")) != NULL) {
816 if (isdigit((
int)letter[1])) {
818 dprintf(
"found_X\n");
821 if ((letter = g_strstr_len(buf, len,
"Y")) != NULL) {
822 if (isdigit((
int)letter[1])) {
824 dprintf(
"found_Y\n");
831 *returnFoundBinary = found_binary;
834 if ((found_D0 || found_D2 || found_M0 || found_M2) && found_ADD && found_star && (found_X || found_Y))
851 gboolean found_binary = FALSE;
852 gboolean found_ADD = FALSE;
853 gboolean found_D0 = FALSE;
854 gboolean found_D2 = FALSE;
855 gboolean found_M0 = FALSE;
856 gboolean found_M2 = FALSE;
857 gboolean found_star = FALSE;
858 gboolean found_X = FALSE;
859 gboolean found_Y = FALSE;
863 GERB_FATAL_ERROR(
"malloc buf failed while checking for rs274d in %s()", __FUNCTION__);
865 while (fgets(buf, MAXL, fd->fd) != NULL) {
871 for (i = 0; i < len; i++) {
872 if (!isprint((
int)buf[i]) && (buf[i] !=
'\r') && (buf[i] !=
'\n') && (buf[i] !=
'\t')) {
877 if (g_strstr_len(buf, len,
"%ADD")) {
880 if (g_strstr_len(buf, len,
"D00") || g_strstr_len(buf, len,
"D0")) {
883 if (g_strstr_len(buf, len,
"D02") || g_strstr_len(buf, len,
"D2")) {
886 if (g_strstr_len(buf, len,
"M00") || g_strstr_len(buf, len,
"M0")) {
889 if (g_strstr_len(buf, len,
"M02") || g_strstr_len(buf, len,
"M2")) {
892 if (g_strstr_len(buf, len,
"*")) {
896 if ((letter = g_strstr_len(buf, len,
"X")) != NULL) {
898 if (isdigit((
int)letter[1])) {
902 if ((letter = g_strstr_len(buf, len,
"Y")) != NULL) {
904 if (isdigit((
int)letter[1])) {
913 if ((found_D0 || found_D2 || found_M0 || found_M2) && !found_ADD && found_star && (found_X || found_Y)
933 op_int = gerb_fgetint(fd, NULL);
936 dprintf(
"\n Found G%02d at line %ld (%s)\n", op_int, *line_num_p,
gerber_g_code_name(op_int));
959 if (c ==
'\r' || c ==
'\n') {
962 _(
"Found newline while parsing "
963 "G04 code at line %ld in file \"%s\", "
964 "maybe you forgot a \"*\"?"),
965 *line_num_p, fd->filename
968 }
while (c != EOF && c !=
'*');
985 state->prev_interpolation = state->interpolation;
997 if (gerb_fgetc(fd) ==
'D') {
998 int a = gerb_fgetint(fd, NULL);
999 if ((a >= 0) && (a <= APERTURE_MAX)) {
1000 state->curr_aperture = a;
1004 _(
"Found aperture D%02d out of bounds while parsing "
1005 "G code at line %ld in file \"%s\""),
1006 a, *line_num_p, fd->filename
1012 _(
"Found unexpected code after G54 "
1013 "at line %ld in file \"%s\""),
1014 *line_num_p, fd->filename
1020 case 55: stats->G55++;
break;
1022 state->state = gerbv_image_return_new_netstate(state->state);
1027 state->state = gerbv_image_return_new_netstate(state->state);
1052 _(
"Encountered unknown G code G%02d "
1053 "at line %ld in file \"%s\""),
1054 op_int, *line_num_p, fd->filename
1076 a = gerb_fgetint(fd, NULL);
1077 dprintf(
" Found D%02d code at line %ld\n", a, *line_num_p);
1083 *line_num_p, fd->filename
1103 if ((a >= 0) && (a <= APERTURE_MAX)) {
1104 state->curr_aperture = a;
1109 _(
"Found out of bounds aperture D%02d "
1110 "at line %ld in file \"%s\""),
1111 a, *line_num_p, fd->filename
1124 parse_M_code(gerb_file_t* fd,
gerbv_image_t* image,
long int* line_num_p) {
1128 op_int = gerb_fgetint(fd, NULL);
1131 case 0: stats->M0++;
return 1;
1132 case 1: stats->M1++;
return 2;
1133 case 2: stats->M2++;
return 3;
1137 _(
"Encountered unknown M%02d code at line %ld in file \"%s\""), op_int, *line_num_p, fd->filename
1139 gerbv_stats_printf(stats->error_list,
GERBV_MESSAGE_WARNING, -1, _(
"Ignoring unknown M%02d code"), op_int);
1149 gerbv_stats_t* stats, gchar* directoryPath,
long int* line_num_p
1154 gerbv_aperture_t* a = NULL;
1155 gerbv_amacro_t* tmp_amacro;
1157 gdouble scale = 1.0;
1163 op[0] = gerb_fgetc(fd);
1164 op[1] = gerb_fgetc(fd);
1166 if (op[0] == EOF || op[1] == EOF)
1169 switch (A2I(op[0], op[1])) {
1175 op[0] = gerb_fgetc(fd);
1176 op[1] = gerb_fgetc(fd);
1177 state->state = gerbv_image_return_new_netstate(state->state);
1179 if (op[0] == EOF || op[1] == EOF)
1184 if (((op[0] ==
'A') && (op[1] ==
'Y')) || ((op[0] ==
'B') && (op[1] ==
'X'))) {
1185 state->state->axisSelect = GERBV_AXIS_SELECT_SWAPAB;
1187 state->state->axisSelect = GERBV_AXIS_SELECT_NOSELECT;
1190 op[0] = gerb_fgetc(fd);
1191 op[1] = gerb_fgetc(fd);
1193 if (op[0] == EOF || op[1] == EOF)
1198 if (((op[0] ==
'A') && (op[1] ==
'Y')) || ((op[0] ==
'B') && (op[1] ==
'X'))) {
1199 state->state->axisSelect = GERBV_AXIS_SELECT_SWAPAB;
1201 state->state->axisSelect = GERBV_AXIS_SELECT_NOSELECT;
1208 switch (gerb_fgetc(fd)) {
1215 _(
"EagleCad bug detected: Undefined handling of zeros "
1216 "in format code at line %ld in file \"%s\""),
1217 *line_num_p, fd->filename
1226 switch (gerb_fgetc(fd)) {
1232 _(
"Invalid coordinate type defined in format code "
1233 "at line %ld in file \"%s\""),
1234 *line_num_p, fd->filename
1239 op[0] = gerb_fgetc(fd);
1240 while ((op[0] !=
'*') && (op[0] != EOF)) {
1243 op[0] = (char)gerb_fgetc(fd);
1244 image->
format->lim_seqno = op[0] -
'0';
1247 op[0] = (char)gerb_fgetc(fd);
1248 image->
format->lim_gf = op[0] -
'0';
1251 op[0] = (char)gerb_fgetc(fd);
1252 image->
format->lim_pf = op[0] -
'0';
1255 op[0] = (char)gerb_fgetc(fd);
1256 image->
format->lim_mf = op[0] -
'0';
1259 op[0] = gerb_fgetc(fd);
1260 if ((op[0] <
'0') || (op[0] >
'6')) {
1263 _(
"Illegal format size '%s' "
1264 "at line %ld in file \"%s\""),
1265 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1268 image->
format->x_int = op[0] -
'0';
1269 op[0] = gerb_fgetc(fd);
1270 if ((op[0] <
'0') || (op[0] >
'6')) {
1273 _(
"Illegal format size '%s' "
1274 "at line %ld in file \"%s\""),
1275 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1278 image->
format->x_dec = op[0] -
'0';
1281 op[0] = gerb_fgetc(fd);
1282 if ((op[0] <
'0') || (op[0] >
'6')) {
1285 _(
"Illegal format size '%s' "
1286 "at line %ld in file \"%s\""),
1287 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1290 image->
format->y_int = op[0] -
'0';
1291 op[0] = gerb_fgetc(fd);
1292 if ((op[0] <
'0') || (op[0] >
'6')) {
1295 _(
"Illegal format size '%s' "
1296 "at line %ld in file \"%s\""),
1297 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1300 image->
format->y_dec = op[0] -
'0';
1305 _(
"Illegal format statement '%s' "
1306 "at line %ld in file \"%s\""),
1307 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1313 op[0] = gerb_fgetc(fd);
1317 op[0] = gerb_fgetc(fd);
1318 state->state = gerbv_image_return_new_netstate(state->state);
1320 while ((op[0] !=
'*') && (op[0] != EOF)) {
1324 readValue = gerb_fgetint(fd, NULL);
1325 if (readValue == 1) {
1326 if (state->state->mirrorState == GERBV_MIRROR_STATE_FLIPB)
1327 state->state->mirrorState = GERBV_MIRROR_STATE_FLIPAB;
1329 state->state->mirrorState = GERBV_MIRROR_STATE_FLIPA;
1333 readValue = gerb_fgetint(fd, NULL);
1334 if (readValue == 1) {
1335 if (state->state->mirrorState == GERBV_MIRROR_STATE_FLIPA)
1336 state->state->mirrorState = GERBV_MIRROR_STATE_FLIPAB;
1338 state->state->mirrorState = GERBV_MIRROR_STATE_FLIPB;
1344 _(
"Wrong character '%s' in mirror "
1345 "at line %ld in file \"%s\""),
1346 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1349 op[0] = gerb_fgetc(fd);
1353 op[0] = gerb_fgetc(fd);
1354 op[1] = gerb_fgetc(fd);
1356 if (op[0] == EOF || op[1] == EOF)
1361 switch (A2I(op[0], op[1])) {
1363 state->state = gerbv_image_return_new_netstate(state->state);
1367 state->state = gerbv_image_return_new_netstate(state->state);
1373 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]), *line_num_p, fd->filename
1378 op[0] = gerb_fgetc(fd);
1380 while ((op[0] !=
'*') && (op[0] != EOF)) {
1382 case 'A': state->state->offsetA = gerb_fgetdouble(fd) / scale;
break;
1383 case 'B': state->state->offsetB = gerb_fgetdouble(fd) / scale;
break;
1387 _(
"Wrong character '%s' in offset "
1388 "at line %ld in file \"%s\""),
1389 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1392 op[0] = gerb_fgetc(fd);
1397 gchar* includeFilename = gerb_fgetstring(fd,
'*');
1399 if (includeFilename) {
1401 if (!g_path_is_absolute(includeFilename)) {
1402 fullPath = g_build_filename(directoryPath, includeFilename, NULL);
1404 fullPath = g_strdup(includeFilename);
1406 if (levelOfRecursion < 10) {
1407 gerb_file_t* includefd = NULL;
1409 includefd = gerb_fopen(fullPath);
1412 levelOfRecursion + 1, image, state, curr_net, stats, includefd, directoryPath
1414 gerb_fclose(includefd);
1418 _(
"Included file \"%s\" cannot be found "
1419 "at line %ld in file \"%s\""),
1420 fullPath, *line_num_p, fd->filename
1427 _(
"Parser encountered more than 10 levels of "
1428 "include file recursion which is not allowed "
1429 "by the RS-274X spec")
1432 g_free(includeFilename);
1437 op[0] = gerb_fgetc(fd);
1439 while ((op[0] !=
'*') && (op[0] != EOF)) {
1441 case 'A': image->
info->offsetA = gerb_fgetdouble(fd) / scale;
break;
1442 case 'B': image->
info->offsetB = gerb_fgetdouble(fd) / scale;
break;
1446 _(
"Wrong character '%s' in image offset "
1447 "at line %ld in file \"%s\""),
1448 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1451 op[0] = gerb_fgetc(fd);
1455 state->state = gerbv_image_return_new_netstate(state->state);
1456 if (gerb_fgetc(fd) ==
'A')
1457 state->state->
scaleA = gerb_fgetdouble(fd);
1460 if (gerb_fgetc(fd) ==
'B')
1461 state->state->scaleB = gerb_fgetdouble(fd);
1471 op[0] = gerb_fgetc(fd);
1472 op[1] = gerb_fgetc(fd);
1474 if (op[0] == EOF || op[1] == EOF)
1479 switch (A2I(op[0], op[1])) {
1480 case A2I(
'A',
'S'): image->info->encoding = GERBV_ENCODING_ASCII;
break;
1481 case A2I(
'E',
'B'): image->info->encoding = GERBV_ENCODING_EBCDIC;
break;
1482 case A2I(
'B',
'C'): image->info->encoding = GERBV_ENCODING_BCD;
break;
1483 case A2I(
'I',
'S'): image->info->encoding = GERBV_ENCODING_ISO_ASCII;
break;
1484 case A2I(
'E',
'I'): image->info->encoding = GERBV_ENCODING_EIA;
break;
1488 _(
"Unknown input code (IC) '%s%s' "
1489 "at line %ld in file \"%s\""),
1490 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]), *line_num_p, fd->filename
1497 op[0] = gerb_fgetc(fd);
1498 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_LOWERLEFT;
1499 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_LOWERLEFT;
1500 image->
info->imageJustifyOffsetA = 0.0;
1501 image->
info->imageJustifyOffsetB = 0.0;
1502 while ((op[0] !=
'*') && (op[0] != EOF)) {
1505 op[0] = gerb_fgetc(fd);
1507 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_CENTERJUSTIFY;
1508 }
else if (op[0] ==
'L') {
1509 image->
info->imageJustifyTypeA = GERBV_JUSTIFY_LOWERLEFT;
1512 image->
info->imageJustifyOffsetA = gerb_fgetdouble(fd) / scale;
1516 op[0] = gerb_fgetc(fd);
1518 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_CENTERJUSTIFY;
1519 }
else if (op[0] ==
'L') {
1520 image->
info->imageJustifyTypeB = GERBV_JUSTIFY_LOWERLEFT;
1523 image->
info->imageJustifyOffsetB = gerb_fgetdouble(fd) / scale;
1529 _(
"Wrong character '%s' in image justify "
1530 "at line %ld in file \"%s\""),
1531 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1534 op[0] = gerb_fgetc(fd);
1537 case A2I(
'I',
'N'): image->info->name = gerb_fgetstring(fd,
'*');
break;
1540 for (ano = 0; ano < 3; ano++) {
1541 op[0] = gerb_fgetc(fd);
1545 _(
"Unexpected EOF while reading image polarity (IP) "
1550 str[ano] = (char)op[0];
1553 if (strncmp(str,
"POS", 3) == 0)
1555 else if (strncmp(str,
"NEG", 3) == 0)
1560 _(
"Unknown polarity '%s%s%s' "
1561 "at line %ld in file \"%s\""),
1562 gerbv_escape_char(str[0]), gerbv_escape_char(str[1]), gerbv_escape_char(str[2]), *line_num_p,
1568 tmp = gerb_fgetint(fd, NULL) % 360;
1570 image->
info->imageRotation = 0.0;
1572 image->
info->imageRotation = M_PI_2;
1573 else if (tmp == 180)
1574 image->
info->imageRotation = M_PI;
1575 else if (tmp == 270)
1576 image->
info->imageRotation = M_PI + M_PI_2;
1580 _(
"Image rotation must be 0, 90, 180 or 270 "
1581 "(is actually %d) at line %ld in file \"%s\""),
1582 tmp, *line_num_p, fd->filename
1586 case A2I(
'P',
'F'): image->info->plotterFilm = gerb_fgetstring(fd,
'*');
break;
1590 a = (gerbv_aperture_t*)g_new0(gerbv_aperture_t, 1);
1592 ano = parse_aperture_definition(fd, a, image, scale, line_num_p);
1595 }
else if ((ano >= 0) && (ano <= APERTURE_MAX)) {
1596 a->unit = state->state->unit;
1598 dprintf(
" In %s(), adding new aperture to aperture list ...\n", __func__);
1599 gerbv_stats_add_aperture(stats->aperture_list, -1, ano, a->type, a->parameter);
1600 gerbv_stats_add_to_D_list(stats->D_code_list, ano);
1601 if (ano < APERTURE_MIN) {
1604 _(
"Aperture number out of bounds %d "
1605 "at line %ld in file \"%s\""),
1606 ano, *line_num_p, fd->filename
1612 _(
"Aperture number out of bounds %d "
1613 "at line %ld in file \"%s\""),
1614 ano, *line_num_p, fd->filename
1621 tmp_amacro = image->amacro;
1622 image->
amacro = parse_aperture_macro(fd);
1624 image->
amacro->next = tmp_amacro;
1626 print_program(image->
amacro);
1631 _(
"Failed to parse aperture macro "
1632 "at line %ld in file \"%s\""),
1633 *line_num_p, fd->filename
1640 state->layer = gerbv_image_return_new_layer(state->layer);
1641 state->layer->
name = gerb_fgetstring(fd,
'*');
1644 state->layer = gerbv_image_return_new_layer(state->layer);
1645 switch (gerb_fgetc(fd)) {
1651 _(
"Unknown layer polarity '%s' "
1652 "at line %ld in file \"%s\""),
1653 gerbv_escape_char(op[0]), *line_num_p, fd->filename
1658 state->layer = gerbv_image_return_new_layer(state->layer);
1659 gerber_update_any_running_knockout_measurements(image);
1661 knockoutMeasure = FALSE;
1662 op[0] = gerb_fgetc(fd);
1664 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_NOKNOCKOUT;
1666 }
else if (op[0] ==
'C') {
1668 }
else if (op[0] ==
'D') {
1673 _(
"Knockout must supply a polarity (C, D, or *) "
1674 "at line %ld in file \"%s\""),
1675 *line_num_p, fd->filename
1678 state->layer->knockout.lowerLeftX = 0.0;
1679 state->layer->knockout.lowerLeftY = 0.0;
1680 state->layer->knockout.width = 0.0;
1681 state->layer->knockout.height = 0.0;
1682 state->layer->knockout.border = 0.0;
1683 state->layer->knockout.firstInstance = TRUE;
1684 op[0] = gerb_fgetc(fd);
1685 while ((op[0] !=
'*') && (op[0] != EOF)) {
1688 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1689 state->layer->knockout.lowerLeftX = gerb_fgetdouble(fd) / scale;
1692 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1693 state->layer->knockout.lowerLeftY = gerb_fgetdouble(fd) / scale;
1696 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1697 state->layer->knockout.width = gerb_fgetdouble(fd) / scale;
1700 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_FIXEDKNOCK;
1701 state->layer->knockout.height = gerb_fgetdouble(fd) / scale;
1704 state->layer->knockout.type = GERBV_KNOCKOUT_TYPE_BORDER;
1705 state->layer->knockout.border = gerb_fgetdouble(fd) / scale;
1708 knockoutMeasure = TRUE;
1709 knockoutLimitXmin = HUGE_VAL;
1710 knockoutLimitYmin = HUGE_VAL;
1711 knockoutLimitXmax = -HUGE_VAL;
1712 knockoutLimitYmax = -HUGE_VAL;
1713 knockoutLayer = state->layer;
1718 _(
"Unknown variable in knockout "
1719 "at line %ld in file \"%s\""),
1720 *line_num_p, fd->filename
1723 op[0] = gerb_fgetc(fd);
1728 state->layer = gerbv_image_return_new_layer(state->layer);
1729 op[0] = gerb_fgetc(fd);
1731 state->layer->stepAndRepeat.X = 1;
1732 state->layer->stepAndRepeat.Y = 1;
1733 state->layer->stepAndRepeat.dist_X = 0.0;
1734 state->layer->stepAndRepeat.dist_Y = 0.0;
1737 while ((op[0] !=
'*') && (op[0] != EOF)) {
1739 case 'X': state->layer->stepAndRepeat.X = gerb_fgetint(fd, NULL);
break;
1740 case 'Y': state->layer->stepAndRepeat.Y = gerb_fgetint(fd, NULL);
break;
1741 case 'I': state->layer->stepAndRepeat.dist_X = gerb_fgetdouble(fd) / scale;
break;
1742 case 'J': state->layer->stepAndRepeat.dist_Y = gerb_fgetdouble(fd) / scale;
break;
1746 _(
"Step-and-repeat parameter error "
1747 "at line %ld in file \"%s\""),
1748 *line_num_p, fd->filename
1757 if (state->layer->stepAndRepeat.X == 0)
1758 state->layer->stepAndRepeat.X = 1;
1759 if (state->layer->stepAndRepeat.Y == 0)
1760 state->layer->stepAndRepeat.Y = 1;
1762 op[0] = gerb_fgetc(fd);
1767 state->layer = gerbv_image_return_new_layer(state->layer);
1769 state->layer->
rotation = DEG2RAD(gerb_fgetdouble(fd));
1770 op[0] = gerb_fgetc(fd);
1774 _(
"Error in layer rotation command "
1775 "at line %ld in file \"%s\""),
1776 *line_num_p, fd->filename
1783 _(
"Unknown RS-274X extension found %%%s%s%% "
1784 "at line %ld in file \"%s\""),
1785 gerbv_escape_char(op[0]), gerbv_escape_char(op[1]), *line_num_p, fd->filename
1793 tmp = gerb_fgetc(fd);
1794 }
while (tmp != EOF && tmp !=
'*');
1809 static macro_stack_t*
1810 new_stack(
size_t stack_size) {
1813 s = (macro_stack_t*)g_new0(macro_stack_t, 1);
1814 s->stack = (
double*)g_new0(
double, stack_size);
1816 s->capacity = stack_size;
1821 free_stack(macro_stack_t* s) {
1832 push(macro_stack_t* s,
double val) {
1833 if (s->sp >= s->capacity) {
1834 GERB_FATAL_ERROR(_(
"push will overflow stack capacity"));
1837 s->stack[s->sp++] = val;
1842 pop(macro_stack_t* s,
double* value) {
1848 *value = s->stack[--s->sp];
1854 simplify_aperture_macro(gerbv_aperture_t* aperture, gdouble scale) {
1855 const int extra_stack_size = 10;
1857 gerbv_instruction_t* ip;
1858 int handled = 1, nuf_parameters = 0, i, j, clearOperatorUsed = FALSE;
1860 double tmp[2] = { 0.0, 0.0 };
1862 gerbv_simplified_amacro_t* sam;
1864 if (aperture == NULL)
1865 GERB_FATAL_ERROR(_(
"aperture NULL in simplify aperture macro"));
1867 if (aperture->amacro == NULL)
1868 GERB_FATAL_ERROR(_(
"aperture->amacro NULL in simplify aperture macro"));
1871 s = new_stack(aperture->amacro->nuf_push + extra_stack_size);
1873 GERB_FATAL_ERROR(
"malloc stack failed in %s()", __FUNCTION__);
1876 lp = g_new(
double, APERTURE_PARAMETERS_MAX);
1878 memcpy(lp, aperture->parameter,
sizeof(
double) * APERTURE_PARAMETERS_MAX);
1880 for (ip = aperture->amacro->program; ip != NULL; ip = ip->next) {
1881 switch (ip->opcode) {
1886 const ssize_t idx = ip->data.ival - 1;
1887 if ((idx < 0) || (idx >= APERTURE_PARAMETERS_MAX))
1888 GERB_FATAL_ERROR(_(
"Tried to access oob aperture"));
1894 if (pop(s, &tmp[0]) < 0)
1895 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1896 const ssize_t idx = ip->data.ival - 1;
1897 if ((idx < 0) || (idx >= APERTURE_PARAMETERS_MAX))
1898 GERB_FATAL_ERROR(_(
"Tried to access oob aperture"));
1903 if (pop(s, &tmp[0]) < 0)
1904 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1905 if (pop(s, &tmp[1]) < 0)
1906 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1907 push(s, tmp[1] + tmp[0]);
1910 if (pop(s, &tmp[0]) < 0)
1911 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1912 if (pop(s, &tmp[1]) < 0)
1913 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1914 push(s, tmp[1] - tmp[0]);
1917 if (pop(s, &tmp[0]) < 0)
1918 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1919 if (pop(s, &tmp[1]) < 0)
1920 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1921 push(s, tmp[1] * tmp[0]);
1924 if (pop(s, &tmp[0]) < 0)
1925 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1926 if (pop(s, &tmp[1]) < 0)
1927 GERB_FATAL_ERROR(_(
"Tried to pop an empty stack"));
1928 push(s, tmp[1] / tmp[0]);
1936 switch (ip->data.ival) {
1938 dprintf(
" Aperture macro circle [1] (");
1944 dprintf(
" Aperture macro outline [4] (");
1957 const int sstack = (int)s->stack[1];
1958 if ((sstack < 0) || (sstack >= INT_MAX / 4)) {
1960 _(
"Possible signed integer overflow "
1961 "in calculating number of parameters "
1962 "to aperture macro, will clamp to "
1964 APERTURE_PARAMETERS_MAX
1966 nuf_parameters = APERTURE_PARAMETERS_MAX;
1968 nuf_parameters = (sstack + 1) * 2 + 3;
1972 dprintf(
" Aperture macro polygon [5] (");
1977 dprintf(
" Aperture macro moire [6] (");
1982 dprintf(
" Aperture macro thermal [7] (");
1988 dprintf(
" Aperture macro line 20/2 (");
1993 dprintf(
" Aperture macro line 21 (");
1998 dprintf(
" Aperture macro line 22 (");
2002 default: handled = 0;
2006 if (nuf_parameters > APERTURE_PARAMETERS_MAX) {
2008 _(
"Number of parameters to aperture macro (%d) "
2009 "are more than gerbv is able to store (%d)"),
2010 nuf_parameters, APERTURE_PARAMETERS_MAX
2012 nuf_parameters = APERTURE_PARAMETERS_MAX;
2019 sam = g_new(gerbv_simplified_amacro_t, 1);
2022 memset(sam->parameter, 0,
sizeof(
double) * APERTURE_PARAMETERS_MAX);
2026 if (nuf_parameters > s->capacity) {
2028 _(
"Number of parameters to aperture macro (%d) "
2029 "capped to stack capacity (%zu)"),
2030 nuf_parameters, s->capacity
2032 nuf_parameters = s->capacity;
2034 memcpy(sam->parameter, s->stack,
sizeof(
double) * nuf_parameters);
2039 if (fabs(sam->parameter[0]) < 0.001)
2040 clearOperatorUsed = TRUE;
2041 sam->parameter[1] /= scale;
2042 sam->parameter[2] /= scale;
2043 sam->parameter[3] /= scale;
2046 if (fabs(sam->parameter[0]) < 0.001)
2047 clearOperatorUsed = TRUE;
2048 for (j = 2; j < nuf_parameters - 1; j++) {
2049 sam->parameter[j] /= scale;
2053 if (fabs(sam->parameter[0]) < 0.001)
2054 clearOperatorUsed = TRUE;
2055 sam->parameter[2] /= scale;
2056 sam->parameter[3] /= scale;
2057 sam->parameter[4] /= scale;
2060 sam->parameter[0] /= scale;
2061 sam->parameter[1] /= scale;
2062 sam->parameter[2] /= scale;
2063 sam->parameter[3] /= scale;
2064 sam->parameter[4] /= scale;
2065 sam->parameter[6] /= scale;
2066 sam->parameter[7] /= scale;
2069 sam->parameter[0] /= scale;
2070 sam->parameter[1] /= scale;
2071 sam->parameter[2] /= scale;
2072 sam->parameter[3] /= scale;
2073 sam->parameter[4] /= scale;
2076 if (fabs(sam->parameter[0]) < 0.001)
2077 clearOperatorUsed = TRUE;
2078 sam->parameter[1] /= scale;
2079 sam->parameter[2] /= scale;
2080 sam->parameter[3] /= scale;
2081 sam->parameter[4] /= scale;
2082 sam->parameter[5] /= scale;
2086 if (fabs(sam->parameter[0]) < 0.001)
2087 clearOperatorUsed = TRUE;
2088 sam->parameter[1] /= scale;
2089 sam->parameter[2] /= scale;
2090 sam->parameter[3] /= scale;
2091 sam->parameter[4] /= scale;
2100 if (aperture->simplified == NULL) {
2101 aperture->simplified = sam;
2103 gerbv_simplified_amacro_t* tmp_sam;
2104 tmp_sam = aperture->simplified;
2105 while (tmp_sam->next != NULL) {
2106 tmp_sam = tmp_sam->next;
2108 tmp_sam->next = sam;
2112 for (i = 0; i < nuf_parameters; i++) {
2113 dprintf(
"%f, ", s->stack[i]);
2135 aperture->parameter[0] = (gdouble)clearOperatorUsed;
2141 parse_aperture_definition(
2142 gerb_file_t* fd, gerbv_aperture_t* aperture,
gerbv_image_t* image, gdouble scale,
long int* line_num_p
2147 gerbv_amacro_t* curr_amacro;
2148 gerbv_amacro_t* amacro = image->
amacro;
2152 if (gerb_fgetc(fd) !=
'D') {
2155 _(
"Found AD code with no following 'D' "
2156 "at line %ld in file \"%s\""),
2157 *line_num_p, fd->filename
2165 ano = gerb_fgetint(fd, NULL);
2170 ad = gerb_fgetstring(fd,
'*');
2175 _(
"Invalid aperture definition at line %ld in file \"%s\", "
2177 *line_num_p, fd->filename
2182 token = strtok(ad,
",");
2184 if (token == NULL) {
2187 *line_num_p, fd->filename
2191 if (strlen(token) == 1) {
2205 curr_amacro = amacro;
2206 while (curr_amacro) {
2207 if ((strlen(curr_amacro->name) == strlen(token)) && (strcmp(curr_amacro->name, token) == 0)) {
2208 aperture->amacro = curr_amacro;
2211 curr_amacro = curr_amacro->next;
2218 for (token = strtok(NULL,
"X"), i = 0; token != NULL; token = strtok(NULL,
"X"), i++) {
2219 if (i == APERTURE_PARAMETERS_MAX) {
2222 _(
"Maximum number of allowed parameters exceeded "
2223 "in aperture %d at line %ld in file \"%s\""),
2224 ano, *line_num_p, fd->filename
2230 tempHolder = strtod(token, NULL);
2235 tempHolder /= scale;
2238 aperture->parameter[i] = tempHolder;
2242 _(
"Failed to read all parameters exceeded in "
2243 "aperture %d at line %ld in file \"%s\""),
2244 ano, *line_num_p, fd->filename
2246 aperture->parameter[i] = 0.0;
2250 aperture->nuf_parameters = i;
2255 dprintf(
"Simplifying aperture %d using aperture macro \"%s\"\n", ano, aperture->amacro->name);
2256 simplify_aperture_macro(aperture, scale);
2257 dprintf(
"Done simplifying\n");
2267 calc_cirseg_sq(
struct gerbv_net* net,
int cw,
double delta_cp_x,
double delta_cp_y) {
2268 double d1x, d1y, d2x, d2y;
2297 case 1: quadrant = 3;
break;
2298 case 2: quadrant = 4;
break;
2299 case 3: quadrant = 1;
break;
2300 case 4: quadrant = 2;
break;
2301 default: GERB_COMPILE_ERROR(_(
"Unknow quadrant value while converting to cw"));
2325 default: GERB_COMPILE_ERROR(_(
"Strange quadrant: %d"), quadrant);
2336 alfa = atan2(d1y, d1x);
2337 beta = atan2(d2y, d2x);
2342 net->
cirseg->width = alfa < beta ? 2 * (d1x / cos(alfa)) : 2 * (d2x / cos(beta));
2343 net->
cirseg->height = alfa > beta ? 2 * (d1y / sin(alfa)) : 2 * (d2y / sin(beta));
2345 if (alfa < GERBV_PRECISION_ANGLE_RAD && beta < GERBV_PRECISION_ANGLE_RAD) {
2351 net->
cirseg->angle1 = RAD2DEG(alfa);
2352 net->
cirseg->angle2 = RAD2DEG(beta);
2355 net->
cirseg->angle1 = 180.0 - RAD2DEG(alfa);
2356 net->
cirseg->angle2 = 180.0 - RAD2DEG(beta);
2359 net->
cirseg->angle1 = 180.0 + RAD2DEG(alfa);
2360 net->
cirseg->angle2 = 180.0 + RAD2DEG(beta);
2363 net->
cirseg->angle1 = 360.0 - RAD2DEG(alfa);
2364 net->
cirseg->angle2 = 360.0 - RAD2DEG(beta);
2366 default: GERB_COMPILE_ERROR(_(
"Strange quadrant: %d"), quadrant);
2369 if (net->
cirseg->width < 0.0)
2370 GERB_COMPILE_WARNING(
2371 _(
"Negative width [%f] in quadrant %d [%f][%f]"), net->
cirseg->width, quadrant, RAD2DEG(alfa), RAD2DEG(beta)
2374 if (net->
cirseg->height < 0.0)
2375 GERB_COMPILE_WARNING(
2376 _(
"Negative height [%f] in quadrant %d [%f][%f]"), net->
cirseg->height, quadrant, RAD2DEG(alfa),
2386 calc_cirseg_mq(
struct gerbv_net* net,
int cw,
double delta_cp_x,
double delta_cp_y) {
2387 double d1x, d1y, d2x, d2y;
2406 if (fabs(d1x) < DBL_EPSILON)
2408 if (fabs(d1y) < DBL_EPSILON)
2410 if (fabs(d2x) < DBL_EPSILON)
2412 if (fabs(d2y) < DBL_EPSILON)
2415 net->
cirseg->width = hypot(delta_cp_x, delta_cp_y);
2416 net->
cirseg->width *= 2.0;
2422 alfa = atan2(d1y, d1x);
2423 beta = atan2(d2y, d2x);
2429 alfa += M_PI + M_PI;
2430 beta += M_PI + M_PI;
2434 beta += M_PI + M_PI;
2444 if (alfa - beta < DBL_EPSILON)
2445 beta -= M_PI + M_PI;
2447 if (beta - alfa < DBL_EPSILON)
2448 beta += M_PI + M_PI;
2451 net->
cirseg->angle1 = RAD2DEG(alfa);
2452 net->
cirseg->angle2 = RAD2DEG(beta);
2457 calc_cirseg_bbox(
const gerbv_cirseg_t* cirseg,
double apert_size_x,
double apert_size_y,
gerbv_render_size_t* bbox) {
2458 gdouble x, y, ang1, ang2, step_pi_2;
2464 ang1 = DEG2RAD(MIN(cirseg->angle1, cirseg->angle2));
2465 ang2 = DEG2RAD(MAX(cirseg->angle1, cirseg->angle2));
2468 x = cirseg->cp_x + cirseg->width * cos(ang1) / 2;
2469 y = cirseg->cp_y + cirseg->width * sin(ang1) / 2;
2470 gerber_update_min_and_max(bbox, x, y, apert_size_x, apert_size_x, apert_size_y, apert_size_y);
2473 for (step_pi_2 = (ang1 / M_PI_2 + 1) * M_PI_2; step_pi_2 < MIN(ang2, ang1 + 2 * M_PI); step_pi_2 += M_PI_2) {
2474 x = cirseg->cp_x + cirseg->width * cos(step_pi_2) / 2;
2475 y = cirseg->cp_y + cirseg->width * sin(step_pi_2) / 2;
2476 gerber_update_min_and_max(bbox, x, y, apert_size_x, apert_size_x, apert_size_y, apert_size_y);
2480 x = cirseg->cp_x + cirseg->width * cos(ang2) / 2;
2481 y = cirseg->cp_y + cirseg->width * sin(ang2) / 2;
2482 gerber_update_min_and_max(bbox, x, y, apert_size_x, apert_size_x, apert_size_y, apert_size_y);
2486 gerber_update_any_running_knockout_measurements(
gerbv_image_t* image) {
2487 if (knockoutMeasure) {
2488 knockoutLayer->
knockout.lowerLeftX = knockoutLimitXmin;
2489 knockoutLayer->
knockout.lowerLeftY = knockoutLimitYmin;
2490 knockoutLayer->
knockout.width = knockoutLimitXmax - knockoutLimitXmin;
2491 knockoutLayer->
knockout.height = knockoutLimitYmax - knockoutLimitYmin;
2492 knockoutMeasure = FALSE;
2497 gerber_calculate_final_justify_effects(
gerbv_image_t* image) {
2498 gdouble translateA = 0.0, translateB = 0.0;
2500 if (image->
info->imageJustifyTypeA != GERBV_JUSTIFY_NOJUSTIFY) {
2501 if (image->
info->imageJustifyTypeA == GERBV_JUSTIFY_CENTERJUSTIFY)
2502 translateA = (image->
info->max_x - image->
info->min_x) / 2.0;
2504 translateA = -image->
info->min_x;
2506 if (image->
info->imageJustifyTypeB != GERBV_JUSTIFY_NOJUSTIFY) {
2507 if (image->
info->imageJustifyTypeB == GERBV_JUSTIFY_CENTERJUSTIFY)
2508 translateB = (image->
info->max_y - image->
info->min_y) / 2.0;
2510 translateB = -image->
info->min_y;
2515 image->
info->min_x += translateA + image->
info->imageJustifyOffsetA;
2516 image->
info->max_x += translateA + image->
info->imageJustifyOffsetA;
2517 image->
info->min_y += translateB + image->
info->imageJustifyOffsetB;
2518 image->
info->max_y += translateB + image->
info->imageJustifyOffsetB;
2522 image->
info->imageJustifyOffsetActualA = translateA + image->
info->imageJustifyOffsetA;
2523 image->
info->imageJustifyOffsetActualB = translateB + image->
info->imageJustifyOffsetB;
2527 gerber_update_image_min_max(
2530 image->
info->min_x = MIN(image->
info->min_x, boundingBox->
left);
2531 image->
info->min_y = MIN(image->
info->min_y, boundingBox->
bottom);
2532 image->
info->max_x = MAX(image->
info->max_x, boundingBox->
right + repeat_off_X);
2533 image->
info->max_y = MAX(image->
info->max_y, boundingBox->
top + repeat_off_Y);
2537 gerber_update_min_and_max(
2538 gerbv_render_size_t* boundingBox, gdouble x, gdouble y, gdouble apertureSizeX1, gdouble apertureSizeX2,
2539 gdouble apertureSizeY1, gdouble apertureSizeY2
2541 gdouble ourX1 = x - apertureSizeX1, ourY1 = y - apertureSizeY1;
2542 gdouble ourX2 = x + apertureSizeX2, ourY2 = y + apertureSizeY2;
2548 cairo_matrix_transform_point(¤tMatrix, &ourX1, &ourY1);
2549 cairo_matrix_transform_point(¤tMatrix, &ourX2, &ourY2);
2554 boundingBox->
left = MIN(boundingBox->
left, ourX1);
2555 boundingBox->
left = MIN(boundingBox->
left, ourX2);
2556 boundingBox->
right = MAX(boundingBox->
right, ourX1);
2557 boundingBox->
right = MAX(boundingBox->
right, ourX2);
2560 boundingBox->
top = MAX(boundingBox->
top, ourY1);
2561 boundingBox->
top = MAX(boundingBox->
top, ourY2);
2565 add_trailing_zeros_if_omitted(
int* coord,
int omitted_num,
gerbv_format_t* format) {
2567 for (
int i = 0; i < omitted_num; i++)
2580 case 1:
return N_(
"exposure on");
2581 case 2:
return N_(
"exposure off");
2582 case 3:
return N_(
"flash aperture");
2583 default:
return N_(
"unknown D-code");
2591 case 0:
return N_(
"move");
2592 case 1:
return N_(
"1X linear interpolation");
2593 case 2:
return N_(
"CW interpolation");
2594 case 3:
return N_(
"CCW interpolation");
2595 case 4:
return N_(
"comment/ignore block");
2596 case 10:
return N_(
"10X linear interpolation");
2597 case 11:
return N_(
"0.1X linear interpolation");
2598 case 12:
return N_(
"0.01X linear interpolation");
2599 case 36:
return N_(
"poly fill on");
2600 case 37:
return N_(
"poly fill off");
2601 case 54:
return N_(
"tool prepare");
2602 case 55:
return N_(
"flash prepare");
2603 case 70:
return N_(
"units = inches");
2604 case 71:
return N_(
"units = mm");
2605 case 74:
return N_(
"disable 360 circ. interpolation");
2606 case 75:
return N_(
"enable 360 circ. interpolation");
2607 case 90:
return N_(
"absolute units");
2608 case 91:
return N_(
"incremental units");
2609 default:
return N_(
"unknown G-code");
2617 case 0:
return N_(
"program stop (obsolete)");
2618 case 1:
return N_(
"optional stop (obsolete)");
2619 case 2:
return N_(
"end of file");
2620 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.
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