58 # include <cairo-win32.h>
60 # include <cairo-quartz.h>
62 # include <cairo-xlib.h>
67 #define DPRINTF(...) do { if (DEBUG) printf(__VA_ARGS__); } while (0)
73 render_zoom_display (gint zoomType, gdouble scaleFactor, gdouble mouseX, gdouble mouseY)
75 gdouble mouseCoordinateX = 0.0;
76 gdouble mouseCoordinateY = 0.0;
77 double oldWidth, oldHeight;
82 if (zoomType == ZOOM_IN_CMOUSE || zoomType == ZOOM_OUT_CMOUSE) {
85 mouseCoordinateY = (screenRenderInfo.
displayHeight - mouseY) /
92 screenRenderInfo.
scaleFactorX = MIN((gdouble)GERBV_SCALE_MAX,
101 case ZOOM_OUT_CMOUSE :
102 screenRenderInfo.
scaleFactorX = MAX((gdouble)GERBV_SCALE_MIN,
115 MIN((gdouble)GERBV_SCALE_MAX, scaleFactor);
123 GERB_MESSAGE(_(
"Illegal zoom direction %d"), zoomType);
126 if (zoomType == ZOOM_IN_CMOUSE || zoomType == ZOOM_OUT_CMOUSE) {
132 render_refresh_rendered_image_on_screen();
146 int x1, y1, x2, y2, dx, dy;
147 double centerPointX, centerPointY;
150 x1 = MIN((gdouble)screen.start_x, event->x);
151 y1 = MIN((gdouble)screen.start_y, event->y);
152 x2 = MAX((gdouble)screen.start_x, event->x);
153 y2 = MAX((gdouble)screen.start_y, event->y);
157 if ((dx >= 4) && (dy >= 4)) {
158 if (screen.centered_outline_zoom) {
160 x1 = screen.start_x - dx;
161 y1 = screen.start_y - dy;
174 screenRenderInfo.
scaleFactorX = MIN((gdouble)GERBV_SCALE_MAX,
182 render_refresh_rendered_image_on_screen();
187 render_draw_selection_box_outline(
void) {
190 GdkGCValuesMask values_mask;
191 gint x1, y1, x2, y2, dx, dy;
193 memset(&values, 0,
sizeof(values));
194 values.function = GDK_XOR;
195 if (!screen.zoom_outline_color.pixel)
196 gdk_colormap_alloc_color(gdk_colormap_get_system(), &screen.zoom_outline_color, FALSE, TRUE);
197 values.foreground = screen.zoom_outline_color;
198 values_mask = GDK_GC_FUNCTION | GDK_GC_FOREGROUND;
199 gc = gdk_gc_new_with_values(screen.drawing_area->window, &values, values_mask);
201 x1 = MIN(screen.start_x, screen.last_x);
202 y1 = MIN(screen.start_y, screen.last_y);
203 x2 = MAX(screen.start_x, screen.last_x);
204 y2 = MAX(screen.start_y, screen.last_y);
208 gdk_draw_rectangle(screen.drawing_area->window, gc, FALSE, x1, y1, dx, dy);
214 render_draw_zoom_outline(gboolean centered)
218 GdkGCValuesMask values_mask;
219 gint x1, y1, x2, y2, dx, dy;
221 memset(&values, 0,
sizeof(values));
222 values.function = GDK_XOR;
223 if (!screen.zoom_outline_color.pixel)
224 gdk_colormap_alloc_color(gdk_colormap_get_system(), &screen.zoom_outline_color, FALSE, TRUE);
225 values.foreground = screen.zoom_outline_color;
226 values_mask = GDK_GC_FUNCTION | GDK_GC_FOREGROUND;
227 gc = gdk_gc_new_with_values(screen.drawing_area->window, &values, values_mask);
229 x1 = MIN(screen.start_x, screen.last_x);
230 y1 = MIN(screen.start_y, screen.last_y);
231 x2 = MAX(screen.start_x, screen.last_x);
232 y2 = MAX(screen.start_y, screen.last_y);
238 x1 = screen.start_x - dx;
239 y1 = screen.start_y - dy;
246 gdk_draw_rectangle(screen.drawing_area->window, gc, FALSE, x1, y1, dx, dy);
250 memset(&values, 0,
sizeof(values));
251 values.function = GDK_XOR;
252 values.foreground = screen.zoom_outline_color;
253 values.line_style = GDK_LINE_ON_OFF_DASH;
254 values_mask = GDK_GC_FUNCTION | GDK_GC_FOREGROUND | GDK_GC_LINE_STYLE;
255 gc = gdk_gc_new_with_values(screen.drawing_area->window, &values,
258 if ((dy == 0) || ((
double)dx/dy > (
double)screen.drawing_area->allocation.width/
259 screen.drawing_area->allocation.height)) {
260 dy = dx * (double)screen.drawing_area->allocation.height/
261 screen.drawing_area->allocation.width;
264 dx = dy * (double)screen.drawing_area->allocation.width/
265 screen.drawing_area->allocation.height;
268 gdk_draw_rectangle(screen.drawing_area->window, gc, FALSE, (x1+x2-dx)/2,
269 (y1+y2-dy)/2, dx, dy);
277 render_board2screen(gdouble *X, gdouble *Y, gdouble x, gdouble y) {
285 render_trim_point(gdouble *start_x, gdouble *start_y, gdouble last_x, gdouble last_y)
287 const gdouble max_coord = (1<<15) - 2;
291 if (fabs (*start_x) < max_coord && fabs (*start_y) < max_coord)
294 dx = last_x - *start_x;
295 dy = last_y - *start_y;
297 if (*start_x < -max_coord) {
298 *start_x = -max_coord;
299 if (last_x > -max_coord && fabs (dx) > 0.1)
300 *start_y = last_y - (last_x + max_coord) / dx * dy;
302 if (*start_x > max_coord) {
303 *start_x = max_coord;
304 if (last_x < max_coord && fabs (dx) > 0.1)
305 *start_y = last_y - (last_x - max_coord) / dx * dy;
308 dx = last_x - *start_x;
309 dy = last_y - *start_y;
311 if (*start_y < -max_coord) {
312 *start_y = -max_coord;
313 if (last_y > -max_coord && fabs (dy) > 0.1)
314 *start_x = last_x - (last_y + max_coord) / dy * dx;
316 if (*start_y > max_coord) {
317 *start_y = max_coord;
318 if (last_y < max_coord && fabs (dy) > 0.1)
319 *start_x = last_x - (last_y - max_coord) / dy * dx;
332 GdkGCValuesMask values_mask;
333 gdouble start_x, start_y, last_x, last_y;
334 memset(&values, 0,
sizeof(values));
335 values.function = GDK_XOR;
336 values.line_width = 6;
337 if (!screen.zoom_outline_color.pixel)
338 gdk_colormap_alloc_color(gdk_colormap_get_system(), &screen.zoom_outline_color, FALSE, TRUE);
339 values.foreground = screen.zoom_outline_color;
340 values_mask = GDK_GC_FUNCTION | GDK_GC_LINE_WIDTH | GDK_GC_FOREGROUND;
341 gc = gdk_gc_new_with_values(screen.drawing_area->window, &values,
343 render_board2screen(&start_x, &start_y,
344 screen.measure_start_x, screen.measure_start_y);
345 render_board2screen(&last_x, &last_y,
346 screen.measure_stop_x, screen.measure_stop_y);
347 render_trim_point(&start_x, &start_y, last_x, last_y);
348 render_trim_point(&last_x, &last_y, start_x, start_y);
349 gdk_draw_line(screen.drawing_area->window, gc, start_x,
350 start_y, last_x, last_y);
361 dx = fabs (screen.measure_start_x - screen.measure_stop_x);
362 dy = fabs (screen.measure_start_y - screen.measure_stop_y);
364 screen.measure_last_x = dx;
365 screen.measure_last_y = dy;
366 callbacks_update_statusbar_measured_distance (dx, dy);
371 static void render_selection (
void)
373 gerbv_selection_item_t sel_item;
380 if (selection_length (&screen.selectionInfo) == 0)
383 if (screen.selectionRenderData)
384 cairo_surface_destroy (
385 (cairo_surface_t *)screen.selectionRenderData);
387 screen.selectionRenderData =
388 (gpointer) cairo_surface_create_similar (
389 (cairo_surface_t *)screen.windowSurface,
390 CAIRO_CONTENT_COLOR_ALPHA,
404 for (j = 0; j < selection_length (&screen.selectionInfo); j++) {
405 sel_item = selection_get_item_by_index (
406 &screen.selectionInfo, j);
407 if (file->
image != sel_item.image)
412 cr = cairo_create(screen.selectionRenderData);
413 gerbv_render_cairo_set_scale_and_translation(cr,
415 cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.85);
416 draw_image_to_cairo_target (cr,
417 file->
image, pixel_width,
418 DRAW_SELECTIONS, &screen.selectionInfo,
419 &screenRenderInfo, TRUE,
429 void render_refresh_rendered_image_on_screen (
void) {
432 DPRINTF(
"----> Entering redraw_pixmap...\n");
433 cursor = gdk_cursor_new(GDK_WATCH);
434 gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window), cursor);
435 gdk_cursor_destroy(cursor);
439 gdk_pixmap_unref(screen.pixmap);
440 screen.pixmap = gdk_pixmap_new(screen.drawing_area->window, screenRenderInfo.
displayWidth,
442 gerbv_render_to_pixmap_using_gdk (
mainProject, screen.pixmap, &screenRenderInfo, &screen.selectionInfo,
443 &screen.selection_color);
444 DPRINTF(
"<---- leaving redraw_pixmap.\n");
448 DPRINTF(
" .... Now try rendering the drawing using cairo .... \n");
459 (gpointer) cairo_surface_create_similar ((cairo_surface_t *)screen.windowSurface,
460 CAIRO_CONTENT_COLOR_ALPHA, screenRenderInfo.
displayWidth,
464 DPRINTF(
" .... calling render_image_to_cairo_target on layer %d...\n", i);
469 render_recreate_composite_surface ();
472 callbacks_switch_to_correct_cursor ();
473 callbacks_force_expose_event_for_screen();
478 render_remove_selected_objects_belonging_to_layer (
483 for (i = 0; i < selection_length (sel_info);) {
484 gerbv_selection_item_t sItem =
485 selection_get_item_by_index (sel_info, i);
488 selection_clear_item_by_index (sel_info, i);
496 render_create_cairo_buffer_surface () {
497 if (screen.bufferSurface) {
498 cairo_surface_destroy (screen.bufferSurface);
499 screen.bufferSurface = NULL;
501 if (!screen.windowSurface)
504 screen.bufferSurface= cairo_surface_create_similar ((cairo_surface_t *)screen.windowSurface,
512 render_find_selected_objects_and_refresh_display (gint activeFileIndex,
513 enum selection_action action)
515 enum draw_mode mode = FIND_SELECTIONS;
518 if ((action == SELECTION_REPLACE)
519 && (selection_length (&screen.selectionInfo) != 0))
520 selection_clear (&screen.selectionInfo);
522 if (action == SELECTION_TOGGLE)
523 mode = FIND_SELECTIONS_TOGGLE;
527 if (!render_create_cairo_buffer_surface ())
532 cairo_t *cr = cairo_create (screen.bufferSurface);
533 gerbv_render_cairo_set_scale_and_translation (cr, &screenRenderInfo);
534 draw_image_to_cairo_target (cr,
538 mode, &screen.selectionInfo, &screenRenderInfo, TRUE,
544 render_refresh_rendered_image_on_screen ();
546 render_recreate_composite_surface ();
547 callbacks_force_expose_event_for_screen ();
553 render_fill_selection_buffer_from_mouse_click (gint mouseX, gint mouseY,
554 gint activeFileIndex,
enum selection_action action)
556 screen.selectionInfo.lowerLeftX = mouseX;
557 screen.selectionInfo.lowerLeftY = mouseY;
560 render_find_selected_objects_and_refresh_display (
561 activeFileIndex, action);
566 render_fill_selection_buffer_from_mouse_drag (gint corner1X, gint corner1Y,
567 gint corner2X, gint corner2Y,
568 gint activeFileIndex,
enum selection_action action)
571 screen.selectionInfo.lowerLeftX = MIN(corner1X, corner2X);
572 screen.selectionInfo.lowerLeftY = MIN(corner1Y, corner2Y);
574 screen.selectionInfo.upperRightX = MAX(corner1X, corner2X);
575 screen.selectionInfo.upperRightY = MAX(corner1Y, corner2Y);
578 render_find_selected_objects_and_refresh_display (
579 activeFileIndex, action);
583 void render_recreate_composite_surface ()
587 if (!render_create_cairo_buffer_surface())
590 cairo_t *cr= cairo_create(screen.bufferSurface);
612 if (selection_length (&screen.selectionInfo) != 0) {
614 cairo_set_source_surface (cr, (cairo_surface_t *) screen.selectionRenderData,
616 cairo_paint_with_alpha (cr,1.0);
622 void render_project_to_cairo_target (cairo_t *cr) {
629 cairo_set_source_surface (cr, (cairo_surface_t *) screen.bufferSurface, 0 , 0);
635 render_free_screen_resources (
void) {
636 if (screen.selectionRenderData)
637 cairo_surface_destroy ((cairo_surface_t *)
638 screen.selectionRenderData);
639 if (screen.bufferSurface)
640 cairo_surface_destroy ((cairo_surface_t *)
641 screen.bufferSurface);
642 if (screen.windowSurface)
643 cairo_surface_destroy ((cairo_surface_t *)
644 screen.windowSurface);
646 gdk_pixmap_unref(screen.pixmap);
Header info for the GUI callback functions.
Header info for the cairo rendering functions and the related selection calculating functions.
void gerbv_drill_stats_add_layer(gerbv_drill_stats_t *accum_stats, gerbv_drill_stats_t *input_stats, int this_layer)
gerbv_drill_stats_t * gerbv_drill_stats_new(void)
Allocates a new drill_stats structure.
gerbv_stats_t * gerbv_stats_new(void)
Allocates a new gerbv_stats structure.
void gerbv_stats_add_layer(gerbv_stats_t *accum_stats, gerbv_stats_t *input_stats, int this_layer)
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.
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_GDK_XOR
@ GERBV_SELECTION_POINT_CLICK
@ GERBV_SELECTION_DRAG_BOX
Header info for the GUI building functions for Gerber Viewer.
gerbv_project_t * mainProject
Global state variable to keep track of what's happening on the screen.
Header info for common structs and functions used for the GUI application.
void render_calculate_zoom_from_outline(GtkWidget *widget, GdkEventButton *event)
Will determine the outline of the zoomed regions.
gerbv_stats_t * generate_gerber_analysis(void)
void render_draw_measure_distance(void)
Displays a measured distance graphically on screen and in statusbar.
void render_toggle_measure_line(void)
Draws/erases measure line.
gerbv_drill_stats_t * generate_drill_analysis(void)
Header info for the rendering support functions for gerbv.
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
gboolean show_invisible_selection
gerbv_render_types_t renderType