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);
365 for (i=index; i<(gerbvProject->
last_loaded); i++) {
366 gerbvProject->
file[i]=gerbvProject->
file[i+1];
381 for (index = gerbvProject->
last_loaded ; index >= 0; index--) {
382 if (gerbvProject->
file[index] && gerbvProject->
file[index]->
name) {
383 gerbv_unload_layer (gerbvProject, index);
391 gerbv_change_layer_order(
gerbv_project_t *gerbvProject, gint oldPosition, gint newPosition)
396 temp_file = gerbvProject->
file[oldPosition];
398 if (oldPosition < newPosition){
399 for (index = oldPosition; index < newPosition; index++) {
400 gerbvProject->
file[index] = gerbvProject->
file[index + 1];
403 for (index = oldPosition; index > newPosition; index--) {
404 gerbvProject->
file[index] = gerbvProject->
file[index - 1];
407 gerbvProject->
file[newPosition] = temp_file;
414 gchar
const* filename, gchar
const* baseName,
int idx,
int reload){
415 gerb_verify_error_t error = GERB_IMAGE_OK;
418 DPRINTF(
"In open_image, now error check file....\n");
419 error = gerbv_image_verify(parsed_image);
422 if (error & GERB_IMAGE_MISSING_NETLIST) {
423 GERB_COMPILE_ERROR(_(
"Missing netlist - aborting file read"));
429 if (error & GERB_IMAGE_MISSING_FORMAT)
430 g_warning(_(
"Missing format in file...trying to load anyways\n"));
431 if (error & GERB_IMAGE_MISSING_APERTURES) {
432 g_warning(_(
"Missing apertures/drill sizes...trying to load anyways\n"));
437 if (error & GERB_IMAGE_MISSING_INFO)
438 g_warning(_(
"Missing info...trying to load anyways\n"));
447 gerbvProject->
file[idx]->
image = parsed_image;
452 gerbvProject->
file[idx]->
image = parsed_image;
459 gerbvProject->
file[idx]->
name = g_strdup (baseName);
462 r = defaultColors[defaultColorIndex % NUMBER_OF_DEFAULT_COLORS].red*257;
463 g = defaultColors[defaultColorIndex % NUMBER_OF_DEFAULT_COLORS].green*257;
464 b = defaultColors[defaultColorIndex % NUMBER_OF_DEFAULT_COLORS].blue*257;
466 GdkColor colorTemplate = {0, r, g, b};
467 gerbvProject->
file[idx]->
color = colorTemplate;
468 gerbvProject->
file[idx]->
alpha = defaultColors[defaultColorIndex % NUMBER_OF_DEFAULT_COLORS].alpha*257;
470 gerbvProject->
file[idx]->
transform = defaultTransformations[defaultColorIndex % NUMBER_OF_DEFAULT_TRANSFORMATIONS];
482 gerbv_HID_Attribute *fattr,
int n_fattr, gboolean forceLoadFile)
487 gboolean isPnpFile = FALSE, foundBinary;
488 gerbv_HID_Attribute *attr_list = NULL;
509 if ((idx+1) >= gerbvProject->
max_files) {
518 DPRINTF(
"In open_image, about to try opening filename = %s\n", filename);
520 fd = gerb_fopen(filename);
522 GERB_COMPILE_ERROR(_(
"Trying to open \"%s\": %s"),
523 filename, strerror(errno));
527 DPRINTF(
"In open_image, successfully opened file. Now check its type....\n");
535 DPRINTF(
"Found RS-274X file\n");
536 if (!foundBinary || forceLoadFile) {
539 gchar *currentLoadDirectory = g_path_get_dirname (filename);
540 parsed_image =
parse_gerb(fd, currentLoadDirectory);
541 g_free (currentLoadDirectory);
543 }
else if(drill_file_p(fd, &foundBinary)) {
544 DPRINTF(
"Found drill file\n");
545 if (!foundBinary || forceLoadFile)
546 parsed_image = parse_drillfile(fd, attr_list, n_attr, reload);
548 }
else if (pick_and_place_check_file_type(fd, &foundBinary)) {
549 DPRINTF(
"Found pick-n-place file\n");
550 if (!foundBinary || forceLoadFile) {
552 pick_and_place_parse_file_to_images(fd, &parsed_image, &parsed_image2);
559 parsed_image2 = (
void *)1;
560 pick_and_place_parse_file_to_images(fd, &parsed_image, &parsed_image2);
561 parsed_image2 = NULL;
567 parsed_image2 = (
void *)1;
568 pick_and_place_parse_file_to_images(fd, &parsed_image2, &parsed_image);
569 parsed_image2 = NULL;
572 GERB_COMPILE_ERROR(_(
"%s: unknown pick-and-place board side to reload"), filename);
579 gchar *str = g_strdup_printf(_(
"Most likely found a RS-274D file "
580 "\"%s\" ... trying to open anyways\n"), filename);
582 g_warning(
"%s", str);
585 if (!foundBinary || forceLoadFile) {
588 gchar *currentLoadDirectory = g_path_get_dirname (filename);
589 parsed_image =
parse_gerb(fd, currentLoadDirectory);
590 g_free (currentLoadDirectory);
594 DPRINTF(
"Unknown filetype");
595 GERB_COMPILE_ERROR(_(
"%s: Unknown file type."), filename);
600 if (parsed_image == NULL) {
606 if ((parsed_image->
netlist != NULL)
613 _(
"File \"%s\" contains no drill hits or routes"),
619 _(
"File \"%s\" contains no drawing elements"),
625 gchar *baseName = g_path_get_basename (filename);
626 gchar *displayedName;
628 displayedName = g_strconcat (baseName, _(
" (top)"), NULL);
630 displayedName = g_strdup (baseName);
631 retv = gerbv_add_parsed_image_to_project (gerbvProject, parsed_image, filename, displayedName, idx, reload);
633 g_free (displayedName);
643 gchar *baseName = g_path_get_basename (filename);
644 gchar *displayedName;
645 displayedName = g_strconcat (baseName, _(
" (bottom)"), NULL);
646 retv = gerbv_add_parsed_image_to_project (gerbvProject, parsed_image2, filename, displayedName, idx + 1, reload);
648 g_free (displayedName);
658 gboolean foundBinary;
660 fd = gerb_fopen(filename);
665 || drill_file_p(fd, &foundBinary)
666 || pick_and_place_check_file_type(fd, &foundBinary)
679 fd = gerb_fopen(filename);
681 GERB_COMPILE_ERROR(_(
"Trying to open \"%s\": %s"),
682 filename, strerror(errno));
685 returnImage = parse_drillfile(fd, NULL, 0, 0);
695 fd = gerb_fopen(filename);
697 GERB_COMPILE_ERROR(_(
"Trying to open \"%s\": %s"),
698 filename, strerror(errno));
701 gchar *currentLoadDirectory = g_path_get_dirname (filename);
702 returnImage =
parse_gerb(fd, currentLoadDirectory);
703 g_free (currentLoadDirectory);
708 static inline int isnormal_or_zero(
double x)
710 int cl = fpclassify(x);
711 return cl == FP_NORMAL || cl == FP_ZERO;
718 double x1=HUGE_VAL,y1=HUGE_VAL, x2=-HUGE_VAL,y2=-HUGE_VAL;
721 gdouble minX, minY, maxX, maxY;
738 if (!isnormal_or_zero(minX) || !isnormal_or_zero(minY)
739 || !isnormal_or_zero(maxX) || !isnormal_or_zero(maxY)) {
744 cairo_matrix_t fullMatrix;
745 cairo_matrix_init (&fullMatrix, 1, 0, 0, 1, 0, 0);
756 cairo_matrix_scale (&fullMatrix, scaleX, scaleY);
759 cairo_matrix_transform_point (&fullMatrix, &minX, &minY);
760 cairo_matrix_transform_point (&fullMatrix, &maxX, &maxY);
773 boundingbox->
left = x1;
774 boundingbox->
right = x2;
775 boundingbox->
top = y1;
784 double width, height;
785 double x_scale, y_scale;
788 gerbv_render_get_boundingbox(gerbvProject, &bb);
797 if (!isnormal(width)||!isnormal(height)||((width < 0.01) && (height < 0.01))) {
813 renderInfo->
scaleFactorX = MIN((gdouble)GERBV_SCALE_MAX,
815 renderInfo->
scaleFactorX = MAX((gdouble)GERBV_SCALE_MIN,
830 gerbv_render_get_boundingbox(gerbvProject, &bb);
839 gerbv_render_to_pixmap_using_gdk (
gerbv_project_t *gerbvProject, GdkPixmap *pixmap,
841 GdkColor *selectionColor){
842 GdkGC *gc = gdk_gc_new(pixmap);
843 GdkPixmap *colorStamp, *clipmask;
850 gdk_colormap_alloc_color(gdk_colormap_get_system(), &gerbvProject->
background, FALSE, TRUE);
851 gdk_gc_set_foreground(gc, &gerbvProject->
background);
852 gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, -1, -1);
857 colorStamp = gdk_pixmap_new(pixmap, renderInfo->
displayWidth,
859 clipmask = gdk_pixmap_new(NULL, renderInfo->
displayWidth,
873 gdk_colormap_alloc_color(gdk_colormap_get_system(), &gerbvProject->
file[i]->
color, FALSE, TRUE);
874 gdk_gc_set_foreground(gc, &gerbvProject->
file[i]->
color);
878 gdk_gc_set_function(gc, GDK_COPY);
879 gdk_draw_rectangle(colorStamp, gc, TRUE, 0, 0, -1, -1);
882 gdk_gc_set_function(gc, GDK_COPY);
885 gdk_gc_set_function(gc, GDK_XOR);
891 DPRINTF(
" .... calling image2pixmap on image %d...\n", i);
893 draw_gdk_image_to_pixmap(&clipmask, gerbvProject->
file[i]->
image,
896 DRAW_IMAGE, NULL, renderInfo, gerbvProject->
file[i]->
transform);
903 gdk_gc_set_clip_mask(gc, clipmask);
904 gdk_gc_set_clip_origin(gc, 0, 0);
905 gdk_draw_drawable(pixmap, gc, colorStamp, 0, 0, 0, 0, -1, -1);
906 gdk_gc_set_clip_mask(gc, NULL);
911 if (selectionInfo && selectionInfo->selectedNodeArray
912 && (selection_length (selectionInfo) != 0)) {
913 if (!selectionColor->pixel)
914 gdk_colormap_alloc_color(gdk_colormap_get_system(), selectionColor, FALSE, TRUE);
916 gdk_gc_set_foreground(gc, selectionColor);
917 gdk_gc_set_function(gc, GDK_COPY);
918 gdk_draw_rectangle(colorStamp, gc, TRUE, 0, 0, -1, -1);
920 gerbv_selection_item_t sItem;
926 file = gerbvProject->
file[j];
930 for (k = 0; k < selection_length (selectionInfo); k++) {
931 sItem = selection_get_item_by_index (selectionInfo, k);
933 if (file->
image != sItem.image)
937 draw_gdk_image_to_pixmap(&clipmask, file->
image,
941 DRAW_SELECTIONS, selectionInfo,
944 gdk_gc_set_clip_mask(gc, clipmask);
945 gdk_gc_set_clip_origin(gc, 0, 0);
946 gdk_draw_drawable(pixmap, gc, colorStamp, 0, 0, 0, 0, -1, -1);
947 gdk_gc_set_clip_mask(gc, NULL);
954 gdk_pixmap_unref(colorStamp);
955 gdk_pixmap_unref(clipmask);
961 gerbv_render_all_layers_to_cairo_target_for_vector_output (
969 gerbv_render_cairo_set_scale_and_translation (cr, renderInfo);
973 if ((bg->red != 0xffff || bg->green != 0xffff || bg->blue != 0xffff)
974 && (bg->red != 0x0000 || bg->green != 0x0000 || bg->blue != 0x0000)) {
975 r = (double) bg->red/G_MAXUINT16;
976 g = (
double) bg->green/G_MAXUINT16;
977 b = (double) bg->blue/G_MAXUINT16;
978 cairo_set_source_rgba (cr, r, g, b, 1);
983 cairo_set_user_data (cr, (cairo_user_data_key_t *)0, &r, NULL);
984 cairo_set_user_data (cr, (cairo_user_data_key_t *)1, &g, NULL);
985 cairo_set_user_data (cr, (cairo_user_data_key_t *)2, &b, NULL);
990 gerbv_render_layer_to_cairo_target_without_transforming(
991 cr, gerbvProject->
file[i],
999 gerbv_render_all_layers_to_cairo_target (
gerbv_project_t *gerbvProject,
1005 cairo_set_source_rgba (cr,
1006 (
double) gerbvProject->
background.red/G_MAXUINT16,
1007 (
double) gerbvProject->
background.green/G_MAXUINT16,
1008 (
double) gerbvProject->
background.blue/G_MAXUINT16, 1);
1011 for (i = gerbvProject->
last_loaded; i >= 0; i--) {
1013 cairo_push_group (cr);
1015 gerbvProject->
file[i], renderInfo);
1016 cairo_pop_group_to_source (cr);
1017 cairo_paint_with_alpha (cr, (
double)
1018 gerbvProject->
file[i]->
alpha/G_MAXUINT16);
1027 gerbv_render_cairo_set_scale_and_translation(cr, renderInfo);
1028 gerbv_render_layer_to_cairo_target_without_transforming(cr, fileInfo, renderInfo, TRUE);
1033 gerbv_render_cairo_set_scale_and_translation(cairo_t *cr,
gerbv_render_info_t *renderInfo){
1034 gdouble translateX, translateY;
1042 cairo_set_tolerance (cr, 1.0);
1043 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
1046 cairo_set_tolerance (cr, 0.1);
1047 cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
1053 cairo_translate (cr, -translateX, translateY + renderInfo->
displayHeight);
1062 cairo_set_source_rgba (cr, (
double) fileInfo->
color.red/G_MAXUINT16,
1063 (
double) fileInfo->
color.green/G_MAXUINT16,
1064 (
double) fileInfo->
color.blue/G_MAXUINT16, 1);
1069 draw_image_to_cairo_target (cr, fileInfo->
image,
1071 renderInfo, TRUE, fileInfo->
transform, pixelOutput);
1076 gerbv_attribute_destroy_HID_attribute (gerbv_HID_Attribute *attributeList,
int n_attr)
1081 for (i = 0 ; i < n_attr ; i++) {
1082 if ( (attributeList[i].type == HID_String ||
1083 attributeList[i].type == HID_Label) &&
1084 attributeList[i].default_val.str_value != NULL) {
1085 free (attributeList[i].default_val.str_value);
1090 if (attributeList != NULL) {
1091 free (attributeList);
1097 gerbv_HID_Attribute *
1098 gerbv_attribute_dup (gerbv_HID_Attribute *attributeList,
int n_attr)
1100 gerbv_HID_Attribute *nl;
1103 nl = (gerbv_HID_Attribute *) malloc (n_attr *
sizeof (gerbv_HID_Attribute));
1105 fprintf (stderr,
"malloc failed in %s()\n", __FUNCTION__);
1110 for (i = 0 ; i < n_attr ; i++) {
1112 if (attributeList[i].type == HID_String ||
1113 attributeList[i].type == HID_Label) {
1115 if (attributeList[i].default_val.str_value != NULL) {
1116 nl[i].default_val.str_value = strdup (attributeList[i].default_val.str_value);
1118 nl[i].default_val.str_value = NULL;
1122 nl[i] = attributeList[i];
1137 return project->
file[i];
1148 *x = x0*cos(rad) - *y*sin(rad);
1149 *y = x0*sin(rad) + *y*cos(rad);
1179 if (fileinfo == NULL) {
1180 DPRINTF(
"%s(): NULL fileinfo\n", __func__);
1191 int plen = strlen(path);
1192 int elen = strlen(ext);
1193 if ( plen < elen )
return FALSE;
1194 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