54 #include <pango/pango.h>
69 #define DPRINTF(...) do { if (DEBUG) printf(__VA_ARGS__); } while (0)
76 const char *names[] = {
93 if (type >=0 && type <
sizeof(names)/
sizeof(names[0]))
96 return N_(
"<undefined>");
101 const char* names[] = {
107 if (state >= 0 && state <
sizeof(names) /
sizeof(names[0])) {
111 return N_(
"<undefined>");
119 const char *names[] = {
126 N_(
"poly area start"),
127 N_(
"poly area stop"),
131 if (interp >= 0 && interp <
sizeof(names)/
sizeof(names[0]))
132 return names[interp];
134 return N_(
"<undefined>");
137 #define NUMBER_OF_DEFAULT_COLORS 18
138 #define NUMBER_OF_DEFAULT_TRANSFORMATIONS 20
140 static int defaultColorIndex = 0;
166 {0,0,1,1,0,FALSE,FALSE,FALSE},
167 {0,0,1,1,0,FALSE,FALSE,FALSE},
168 {0,0,1,1,0,FALSE,FALSE,FALSE},
169 {0,0,1,1,0,FALSE,FALSE,FALSE},
170 {0,0,1,1,0,FALSE,FALSE,FALSE},
171 {0,0,1,1,0,FALSE,FALSE,FALSE},
172 {0,0,1,1,0,FALSE,FALSE,FALSE},
173 {0,0,1,1,0,FALSE,FALSE,FALSE},
174 {0,0,1,1,0,FALSE,FALSE,FALSE},
175 {0,0,1,1,0,FALSE,FALSE,FALSE},
176 {0,0,1,1,0,FALSE,FALSE,FALSE},
177 {0,0,1,1,0,FALSE,FALSE,FALSE},
178 {0,0,1,1,0,FALSE,FALSE,FALSE},
179 {0,0,1,1,0,FALSE,FALSE,FALSE},
180 {0,0,1,1,0,FALSE,FALSE,FALSE},
181 {0,0,1,1,0,FALSE,FALSE,FALSE},
182 {0,0,1,1,0,FALSE,FALSE,FALSE},
183 {0,0,1,1,0,FALSE,FALSE,FALSE},
184 {0,0,1,1,0,FALSE,FALSE,FALSE},
185 {0,0,1,1,0,FALSE,FALSE,FALSE},
195 returnProject->
path = g_get_current_dir ();
202 return returnProject;
213 if (gerbvProject->
file[i]) {
215 g_free(gerbvProject->
file[i]);
219 g_free (gerbvProject->
path);
222 g_free (gerbvProject->
project);
224 g_free (gerbvProject->
file);
225 g_free (gerbvProject);
233 g_free (fileInfo->
name);
235 cairo_surface_destroy ((cairo_surface_t *)
245 DPRINTF(
"Opening filename = %s\n", filename);
248 GERB_COMPILE_WARNING(_(
"Could not read \"%s\" (loaded %d)"),
254 DPRINTF(
" Successfully opened file!\n");
261 guint16 red, guint16 green, guint16 blue, guint16 alpha)
264 DPRINTF(
"Opening filename = %s\n", filename);
267 GERB_COMPILE_WARNING(_(
"Could not read \"%s\" (loaded %d)"),
273 GdkColor colorTemplate = {0, red, green, blue};
274 gerbvProject->
file[idx_loaded]->
color = colorTemplate;
275 gerbvProject->
file[idx_loaded]->
alpha = alpha;
276 DPRINTF(
" Successfully opened file!\n");
282 gerbv_save_layer_from_index(
gerbv_project_t *gerbvProject, gint index, gchar *filename)
292 GERB_COMPILE_ERROR(_(
"Exporting mirrored file "
293 "is not supported!"));
299 GERB_COMPILE_ERROR(_(
"Exporting inverted file "
300 "is not supported!"));
313 GERB_COMPILE_ERROR(_(
"Exporting inverted file "
314 "is not supported!"));
348 for (idx = 0; idx <= gerbvProject->
last_loaded; idx++) {
350 (void) gerbv_revert_file (gerbvProject, idx);
363 g_free (gerbvProject->
file[index]);
366 for (i=index; i<(gerbvProject->
last_loaded); i++) {
367 gerbvProject->
file[i]=gerbvProject->
file[i+1];
382 for (index = gerbvProject->
last_loaded ; index >= 0; index--) {
383 if (gerbvProject->
file[index] && gerbvProject->
file[index]->
name) {
384 gerbv_unload_layer (gerbvProject, index);
392 gerbv_change_layer_order(
gerbv_project_t *gerbvProject, gint oldPosition, gint newPosition)
397 temp_file = gerbvProject->
file[oldPosition];
399 if (oldPosition < newPosition){
400 for (index = oldPosition; index < newPosition; index++) {
401 gerbvProject->
file[index] = gerbvProject->
file[index + 1];
404 for (index = oldPosition; index > newPosition; index--) {
405 gerbvProject->
file[index] = gerbvProject->
file[index - 1];
408 gerbvProject->
file[newPosition] = temp_file;
415 gchar
const* filename, gchar
const* baseName,
int idx,
int reload){
416 gerb_verify_error_t error = GERB_IMAGE_OK;
419 DPRINTF(
"In open_image, now error check file....\n");
420 error = gerbv_image_verify(parsed_image);
423 if (error & GERB_IMAGE_MISSING_NETLIST) {
424 GERB_COMPILE_ERROR(_(
"Missing netlist - aborting file read"));
430 if (error & GERB_IMAGE_MISSING_FORMAT)
431 g_warning(_(
"Missing format in file...trying to load anyways\n"));
432 if (error & GERB_IMAGE_MISSING_APERTURES) {
433 g_warning(_(
"Missing apertures/drill sizes...trying to load anyways\n"));
438 if (error & GERB_IMAGE_MISSING_INFO)
439 g_warning(_(
"Missing info...trying to load anyways\n"));
448 gerbvProject->
file[idx]->
image = parsed_image;
453 gerbvProject->
file[idx]->
image = parsed_image;
460 gerbvProject->
file[idx]->
name = g_strdup (baseName);
463 r = defaultColors[defaultColorIndex % NUMBER_OF_DEFAULT_COLORS].red*257;
464 g = defaultColors[defaultColorIndex % NUMBER_OF_DEFAULT_COLORS].green*257;
465 b = defaultColors[defaultColorIndex % NUMBER_OF_DEFAULT_COLORS].blue*257;
467 GdkColor colorTemplate = {0, r, g, b};
468 gerbvProject->
file[idx]->
color = colorTemplate;
469 gerbvProject->
file[idx]->
alpha = defaultColors[defaultColorIndex % NUMBER_OF_DEFAULT_COLORS].alpha*257;
471 gerbvProject->
file[idx]->
transform = defaultTransformations[defaultColorIndex % NUMBER_OF_DEFAULT_TRANSFORMATIONS];
483 gerbv_HID_Attribute *fattr,
int n_fattr, gboolean forceLoadFile)
488 gboolean isPnpFile = FALSE, foundBinary;
489 gerbv_HID_Attribute *attr_list = NULL;
510 if ((idx+1) >= gerbvProject->
max_files) {
519 DPRINTF(
"In open_image, about to try opening filename = %s\n", filename);
521 fd = gerb_fopen(filename);
523 GERB_COMPILE_ERROR(_(
"Trying to open \"%s\": %s"),
524 filename, strerror(errno));
528 DPRINTF(
"In open_image, successfully opened file. Now check its type....\n");
536 DPRINTF(
"Found RS-274X file\n");
537 if (!foundBinary || forceLoadFile) {
540 gchar *currentLoadDirectory = g_path_get_dirname (filename);
541 parsed_image =
parse_gerb(fd, currentLoadDirectory);
542 g_free (currentLoadDirectory);
544 }
else if(drill_file_p(fd, &foundBinary)) {
545 DPRINTF(
"Found drill file\n");
546 if (!foundBinary || forceLoadFile)
547 parsed_image = parse_drillfile(fd, attr_list, n_attr, reload);
549 }
else if (pick_and_place_check_file_type(fd, &foundBinary)) {
550 DPRINTF(
"Found pick-n-place file\n");
551 if (!foundBinary || forceLoadFile) {
553 pick_and_place_parse_file_to_images(fd, &parsed_image, &parsed_image2);
560 parsed_image2 = (
void *)1;
561 pick_and_place_parse_file_to_images(fd, &parsed_image, &parsed_image2);
562 parsed_image2 = NULL;
568 parsed_image2 = (
void *)1;
569 pick_and_place_parse_file_to_images(fd, &parsed_image2, &parsed_image);
570 parsed_image2 = NULL;
573 GERB_COMPILE_ERROR(_(
"%s: unknown pick-and-place board side to reload"), filename);
580 gchar *str = g_strdup_printf(_(
"Most likely found a RS-274D file "
581 "\"%s\" ... trying to open anyways\n"), filename);
583 g_warning(
"%s", str);
586 if (!foundBinary || forceLoadFile) {
589 gchar *currentLoadDirectory = g_path_get_dirname (filename);
590 parsed_image =
parse_gerb(fd, currentLoadDirectory);
591 g_free (currentLoadDirectory);
595 DPRINTF(
"Unknown filetype");
596 GERB_COMPILE_ERROR(_(
"%s: Unknown file type."), filename);
601 if (parsed_image == NULL) {
607 if ((parsed_image->
netlist != NULL)
614 _(
"File \"%s\" contains no drill hits or routes"),
620 _(
"File \"%s\" contains no drawing elements"),
626 gchar *baseName = g_path_get_basename (filename);
627 gchar *displayedName;
629 displayedName = g_strconcat (baseName, _(
" (top)"), NULL);
631 displayedName = g_strdup (baseName);
632 retv = gerbv_add_parsed_image_to_project (gerbvProject, parsed_image, filename, displayedName, idx, reload);
634 g_free (displayedName);
644 gchar *baseName = g_path_get_basename (filename);
645 gchar *displayedName;
646 displayedName = g_strconcat (baseName, _(
" (bottom)"), NULL);
647 retv = gerbv_add_parsed_image_to_project (gerbvProject, parsed_image2, filename, displayedName, idx + 1, reload);
649 g_free (displayedName);
659 gboolean foundBinary;
661 fd = gerb_fopen(filename);
666 || drill_file_p(fd, &foundBinary)
667 || pick_and_place_check_file_type(fd, &foundBinary)
680 fd = gerb_fopen(filename);
682 GERB_COMPILE_ERROR(_(
"Trying to open \"%s\": %s"),
683 filename, strerror(errno));
686 returnImage = parse_drillfile(fd, NULL, 0, 0);
696 fd = gerb_fopen(filename);
698 GERB_COMPILE_ERROR(_(
"Trying to open \"%s\": %s"),
699 filename, strerror(errno));
702 gchar *currentLoadDirectory = g_path_get_dirname (filename);
703 returnImage =
parse_gerb(fd, currentLoadDirectory);
704 g_free (currentLoadDirectory);
709 static inline int isnormal_or_zero(
double x)
711 int cl = fpclassify(x);
712 return cl == FP_NORMAL || cl == FP_ZERO;
719 double x1=HUGE_VAL,y1=HUGE_VAL, x2=-HUGE_VAL,y2=-HUGE_VAL;
722 gdouble minX, minY, maxX, maxY;
739 if (!isnormal_or_zero(minX) || !isnormal_or_zero(minY)
740 || !isnormal_or_zero(maxX) || !isnormal_or_zero(maxY)) {
745 cairo_matrix_t fullMatrix;
746 cairo_matrix_init (&fullMatrix, 1, 0, 0, 1, 0, 0);
757 cairo_matrix_scale (&fullMatrix, scaleX, scaleY);
760 cairo_matrix_transform_point (&fullMatrix, &minX, &minY);
761 cairo_matrix_transform_point (&fullMatrix, &maxX, &maxY);
774 boundingbox->
left = x1;
775 boundingbox->
right = x2;
776 boundingbox->
top = y1;
785 double width, height;
786 double x_scale, y_scale;
789 gerbv_render_get_boundingbox(gerbvProject, &bb);
798 if (!isnormal(width)||!isnormal(height)||((width < 0.01) && (height < 0.01))) {
814 renderInfo->
scaleFactorX = MIN((gdouble)GERBV_SCALE_MAX,
816 renderInfo->
scaleFactorX = MAX((gdouble)GERBV_SCALE_MIN,
831 gerbv_render_get_boundingbox(gerbvProject, &bb);
840 gerbv_render_to_pixmap_using_gdk (
gerbv_project_t *gerbvProject, GdkPixmap *pixmap,
842 GdkColor *selectionColor){
843 GdkGC *gc = gdk_gc_new(pixmap);
844 GdkPixmap *colorStamp, *clipmask;
851 gdk_colormap_alloc_color(gdk_colormap_get_system(), &gerbvProject->
background, FALSE, TRUE);
852 gdk_gc_set_foreground(gc, &gerbvProject->
background);
853 gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, -1, -1);
858 colorStamp = gdk_pixmap_new(pixmap, renderInfo->
displayWidth,
860 clipmask = gdk_pixmap_new(NULL, renderInfo->
displayWidth,
874 gdk_colormap_alloc_color(gdk_colormap_get_system(), &gerbvProject->
file[i]->
color, FALSE, TRUE);
875 gdk_gc_set_foreground(gc, &gerbvProject->
file[i]->
color);
879 gdk_gc_set_function(gc, GDK_COPY);
880 gdk_draw_rectangle(colorStamp, gc, TRUE, 0, 0, -1, -1);
883 gdk_gc_set_function(gc, GDK_COPY);
886 gdk_gc_set_function(gc, GDK_XOR);
892 DPRINTF(
" .... calling image2pixmap on image %d...\n", i);
894 draw_gdk_image_to_pixmap(&clipmask, gerbvProject->
file[i]->
image,
897 DRAW_IMAGE, NULL, renderInfo, gerbvProject->
file[i]->
transform);
904 gdk_gc_set_clip_mask(gc, clipmask);
905 gdk_gc_set_clip_origin(gc, 0, 0);
906 gdk_draw_drawable(pixmap, gc, colorStamp, 0, 0, 0, 0, -1, -1);
907 gdk_gc_set_clip_mask(gc, NULL);
912 if (selectionInfo && selectionInfo->selectedNodeArray
913 && (selection_length (selectionInfo) != 0)) {
914 if (!selectionColor->pixel)
915 gdk_colormap_alloc_color(gdk_colormap_get_system(), selectionColor, FALSE, TRUE);
917 gdk_gc_set_foreground(gc, selectionColor);
918 gdk_gc_set_function(gc, GDK_COPY);
919 gdk_draw_rectangle(colorStamp, gc, TRUE, 0, 0, -1, -1);
921 gerbv_selection_item_t sItem;
927 file = gerbvProject->
file[j];
931 for (k = 0; k < selection_length (selectionInfo); k++) {
932 sItem = selection_get_item_by_index (selectionInfo, k);
934 if (file->
image != sItem.image)
938 draw_gdk_image_to_pixmap(&clipmask, file->
image,
942 DRAW_SELECTIONS, selectionInfo,
945 gdk_gc_set_clip_mask(gc, clipmask);
946 gdk_gc_set_clip_origin(gc, 0, 0);
947 gdk_draw_drawable(pixmap, gc, colorStamp, 0, 0, 0, 0, -1, -1);
948 gdk_gc_set_clip_mask(gc, NULL);
955 gdk_pixmap_unref(colorStamp);
956 gdk_pixmap_unref(clipmask);
962 gerbv_render_all_layers_to_cairo_target_for_vector_output (
970 gerbv_render_cairo_set_scale_and_translation (cr, renderInfo);
974 if ((bg->red != 0xffff || bg->green != 0xffff || bg->blue != 0xffff)
975 && (bg->red != 0x0000 || bg->green != 0x0000 || bg->blue != 0x0000)) {
976 r = (double) bg->red/G_MAXUINT16;
977 g = (
double) bg->green/G_MAXUINT16;
978 b = (double) bg->blue/G_MAXUINT16;
979 cairo_set_source_rgba (cr, r, g, b, 1);
984 cairo_set_user_data (cr, (cairo_user_data_key_t *)0, &r, NULL);
985 cairo_set_user_data (cr, (cairo_user_data_key_t *)1, &g, NULL);
986 cairo_set_user_data (cr, (cairo_user_data_key_t *)2, &b, NULL);
991 gerbv_render_layer_to_cairo_target_without_transforming(
992 cr, gerbvProject->
file[i],
1000 gerbv_render_all_layers_to_cairo_target (
gerbv_project_t *gerbvProject,
1006 cairo_set_source_rgba (cr,
1007 (
double) gerbvProject->
background.red/G_MAXUINT16,
1008 (
double) gerbvProject->
background.green/G_MAXUINT16,
1009 (
double) gerbvProject->
background.blue/G_MAXUINT16, 1);
1012 for (i = gerbvProject->
last_loaded; i >= 0; i--) {
1014 cairo_push_group (cr);
1016 gerbvProject->
file[i], renderInfo);
1017 cairo_pop_group_to_source (cr);
1018 cairo_paint_with_alpha (cr, (
double)
1019 gerbvProject->
file[i]->
alpha/G_MAXUINT16);
1028 gerbv_render_cairo_set_scale_and_translation(cr, renderInfo);
1029 gerbv_render_layer_to_cairo_target_without_transforming(cr, fileInfo, renderInfo, TRUE);
1034 gerbv_render_cairo_set_scale_and_translation(cairo_t *cr,
gerbv_render_info_t *renderInfo){
1035 gdouble translateX, translateY;
1043 cairo_set_tolerance (cr, 1.0);
1044 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
1047 cairo_set_tolerance (cr, 0.1);
1048 cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
1054 cairo_translate (cr, -translateX, translateY + renderInfo->
displayHeight);
1063 cairo_set_source_rgba (cr, (
double) fileInfo->
color.red/G_MAXUINT16,
1064 (
double) fileInfo->
color.green/G_MAXUINT16,
1065 (
double) fileInfo->
color.blue/G_MAXUINT16, 1);
1070 draw_image_to_cairo_target (cr, fileInfo->
image,
1072 renderInfo, TRUE, fileInfo->
transform, pixelOutput);
1077 gerbv_attribute_destroy_HID_attribute (gerbv_HID_Attribute *attributeList,
int n_attr)
1082 for (i = 0 ; i < n_attr ; i++) {
1083 if ( (attributeList[i].type == HID_String ||
1084 attributeList[i].type == HID_Label) &&
1085 attributeList[i].default_val.str_value != NULL) {
1086 free (attributeList[i].default_val.str_value);
1088 if (attributeList[i].name != NULL) {
1089 free (attributeList[i].name);
1094 if (attributeList != NULL) {
1095 free (attributeList);
1101 gerbv_HID_Attribute *
1102 gerbv_attribute_dup (gerbv_HID_Attribute *attributeList,
int n_attr)
1104 gerbv_HID_Attribute *nl;
1107 nl = (gerbv_HID_Attribute *) malloc (n_attr *
sizeof (gerbv_HID_Attribute));
1109 fprintf (stderr,
"malloc failed in %s()\n", __FUNCTION__);
1115 for (i = 0 ; i < n_attr ; i++) {
1116 nl[i] = attributeList[i];
1117 nl[i].name = attributeList[i].name ? strdup (attributeList[i].name) : NULL;
1119 if (attributeList[i].type == HID_String ||
1120 attributeList[i].type == HID_Label) {
1121 nl[i].default_val.str_value =
1122 attributeList[i].default_val.str_value
1123 ? strdup (attributeList[i].default_val.str_value) : NULL;
1138 return project->
file[i];
1149 *x = x0*cos(rad) - *y*sin(rad);
1150 *y = x0*sin(rad) + *y*cos(rad);
1180 if (fileinfo == NULL) {
1181 DPRINTF(
"%s(): NULL fileinfo\n", __func__);
1192 int plen = strlen(path);
1193 int elen = strlen(ext);
1194 if ( plen < elen )
return FALSE;
1195 return (strcmp(path+plen-elen, ext) == 0) ? TRUE
Header info for the GDK rendering functions.
Header info for the cairo rendering functions and the related selection calculating functions.
Header info for the Excellon drill parsing functions.
gboolean gerbv_export_drill_file_from_image(const gchar *filename, gerbv_image_t *inputImage, gerbv_user_transformation_t *transform)
Export an image to a new file in Excellon drill format.
gboolean gerbv_export_rs274x_file_from_image(const gchar *filename, gerbv_image_t *inputImage, gerbv_user_transformation_t *transform)
Export an image to a new file in RS274X format.
void gerbv_destroy_image(gerbv_image_t *image)
Free an image structure.
void gerbv_image_create_dummy_apertures(gerbv_image_t *parsed_image)
Create any missing apertures in the specified image.
Header info for the statistics generating functions for RS274X files.
gboolean gerber_is_rs274d_p(gerb_file_t *fd)
gboolean gerber_is_rs274x_p(gerb_file_t *fd, gboolean *returnFoundBinary)
gerbv_image_t * parse_gerb(gerb_file_t *fd, gchar *directoryPath)
Header info for the RS274X parsing functions.
int gerbv_open_image(gerbv_project_t *gerbvProject, gchar const *filename, int idx, int reload, gerbv_HID_Attribute *fattr, int n_fattr, gboolean forceLoadFile)
gerbv_image_t * gerbv_create_rs274x_image_from_filename(gchar const *filename)
Parse a RS274X file and return the parsed image.
void gerbv_destroy_project(gerbv_project_t *gerbvProject)
Free a project and all related variables.
const char * gerbv_interpolation_name(gerbv_interpolation_t interp)
Return string name of gerbv_interpolation_t interpolation.
void gerbv_rotate_coord(double *x, double *y, double rad)
void gerbv_open_layer_from_filename_with_color(gerbv_project_t *gerbvProject, gchar const *filename, guint16 red, guint16 green, guint16 blue, guint16 alpha)
Open a file, parse the contents, and add a new layer to an existing project while setting the color o...
gerbv_project_t * gerbv_create_project(void)
Create a new project structure and initialize some important variables.
const char * gerbv_aperture_state_name(gerbv_aperture_state_t state)
gboolean gerbv_is_loadable_file(const char *filename)
gerbv_fileinfo_t * gerbv_get_fileinfo_for_image(const gerbv_image_t *image, const gerbv_project_t *project)
void gerbv_open_layer_from_filename(gerbv_project_t *gerbvProject, gchar const *filename)
Open a file, parse the contents, and add a new layer to an existing project.
void gerbv_transform_coord(double *x, double *y, const gerbv_user_transformation_t *trans)
gboolean gerbv_endswith(const char *path, const char *ext)
void gerbv_destroy_fileinfo(gerbv_fileinfo_t *fileInfo)
Free a fileinfo structure.
const char * gerbv_aperture_type_name(gerbv_aperture_type_t type)
Return string name of gerbv_aperture_type_t aperture type.
void gerbv_render_zoom_to_fit_display(gerbv_project_t *gerbvProject, gerbv_render_info_t *renderInfo)
Calculate the zoom and translations to fit the rendered scene inside the given scene size.
int gerbv_transform_coord_for_image(double *x, double *y, const gerbv_image_t *image, const gerbv_project_t *project)
gerbv_image_t * gerbv_create_excellon_image_from_filename(const gchar *filename)
Parse an Excellon drill file and return the parsed image.
void gerbv_render_layer_to_cairo_target(cairo_t *cr, gerbv_fileinfo_t *fileInfo, gerbv_render_info_t *renderInfo)
Render a layer to a cairo context.
The main header file for the libgerbv library.
@ GERBV_RENDER_TYPE_CAIRO_HIGH_QUALITY
@ GERBV_RENDER_TYPE_GDK_XOR
@ GERBV_RENDER_TYPE_CAIRO_NORMAL
@ GERBV_LAYERTYPE_PICKANDPLACE_BOT
@ GERBV_LAYERTYPE_PICKANDPLACE_TOP
Header info for the PNP (pick-and-place) parsing functions.
Header info for the selection support functions for libgerbv.
gerbv_user_transformation_t transform
gpointer privateRenderData
gerbv_stats_t * gerbv_stats
gerbv_layertype_t layertype
gerbv_drill_stats_t * drill_stats
gerbv_image_info_t * info
gboolean show_invisible_selection
gboolean check_before_delete
gerbv_render_types_t renderType