2 * gEDA - GNU Electronic Design Automation
4 * render.c -- this file is a part of gerbv.
6 * Copyright (C) 2007 Stuart Brorson (SDB@cloud9.net)
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
26 \brief Rendering support functions for libgerbv
47 #include <libgen.h> /* dirname */
54 #include "callbacks.h"
55 #include "interface.h"
58 #ifdef RENDER_USING_GDK
62 #include <cairo-win32.h>
64 #include <cairo-xlib.h>
71 #define dprintf if(DEBUG) printf
73 /**Global variable to keep track of what's happening on the screen.
74 Declared extern in gerbv_screen.h
76 extern gerbv_screen_t screen
;
78 extern gerbv_render_info_t screenRenderInfo
;
82 render_layer_to_cairo_target_without_transforming(cairo_t *cr, gerbv_fileinfo_t *fileInfo, gerbv_render_info_t *renderInfo );
86 render_check_scale_factor_limits (void) {
87 if ((screenRenderInfo
.scaleFactorX
> 5000)||(screenRenderInfo
.scaleFactorY
> 5000)) {
88 screenRenderInfo
.scaleFactorX
= 5000;
89 screenRenderInfo
.scaleFactorY
= 5000;
95 /* ------------------------------------------------------ */
97 render_zoom_display (gint zoomType
, gdouble scaleFactor
, gdouble mouseX
, gdouble mouseY
) {
98 double us_midx
, us_midy
; /* unscaled translation for screen center */
99 int half_w
, half_h
; /* cache for half window dimensions */
100 gdouble mouseCoordinateX
= 0.0;
101 gdouble mouseCoordinateY
= 0.0;
102 double oldWidth
, oldHeight
;
104 half_w
= screenRenderInfo
.displayWidth
/ 2;
105 half_h
= screenRenderInfo
.displayHeight
/ 2;
107 oldWidth
= screenRenderInfo
.displayWidth
/ screenRenderInfo
.scaleFactorX
;
108 oldHeight
= screenRenderInfo
.displayHeight
/ screenRenderInfo
.scaleFactorY
;
109 if (zoomType
== ZOOM_IN_CMOUSE
|| zoomType
== ZOOM_OUT_CMOUSE
) {
110 /* calculate what user coordinate the mouse is pointing at */
111 mouseCoordinateX
= mouseX
/ screenRenderInfo
.scaleFactorX
+ screenRenderInfo
.lowerLeftX
;
112 mouseCoordinateY
= (screenRenderInfo
.displayHeight
- mouseY
) /
113 screenRenderInfo
.scaleFactorY
+ screenRenderInfo
.lowerLeftY
;
116 us_midx
= screenRenderInfo
.lowerLeftX
+ (screenRenderInfo
.displayWidth
/ 2.0 )/
117 screenRenderInfo
.scaleFactorX
;
118 us_midy
= screenRenderInfo
.lowerLeftY
+ (screenRenderInfo
.displayHeight
/ 2.0 )/
119 screenRenderInfo
.scaleFactorY
;
122 case ZOOM_IN
: /* Zoom In */
123 case ZOOM_IN_CMOUSE
: /* Zoom In Around Mouse Pointer */
124 screenRenderInfo
.scaleFactorX
+= screenRenderInfo
.scaleFactorX
/3;
125 screenRenderInfo
.scaleFactorY
+= screenRenderInfo
.scaleFactorY
/3;
126 (void) render_check_scale_factor_limits ();
127 screenRenderInfo
.lowerLeftX
+= (oldWidth
- (screenRenderInfo
.displayWidth
/
128 screenRenderInfo
.scaleFactorX
)) / 2.0;
129 screenRenderInfo
.lowerLeftY
+= (oldHeight
- (screenRenderInfo
.displayHeight
/
130 screenRenderInfo
.scaleFactorY
)) / 2.0;
132 case ZOOM_OUT
: /* Zoom Out */
133 case ZOOM_OUT_CMOUSE
: /* Zoom Out Around Mouse Pointer */
134 if ((screenRenderInfo
.scaleFactorX
> 10)&&(screenRenderInfo
.scaleFactorY
> 10)) {
135 screenRenderInfo
.scaleFactorX
-= screenRenderInfo
.scaleFactorX
/3;
136 screenRenderInfo
.scaleFactorY
-= screenRenderInfo
.scaleFactorY
/3;
137 screenRenderInfo
.lowerLeftX
+= (oldWidth
- (screenRenderInfo
.displayWidth
/
138 screenRenderInfo
.scaleFactorX
)) / 2.0;
139 screenRenderInfo
.lowerLeftY
+= (oldHeight
- (screenRenderInfo
.displayHeight
/
140 screenRenderInfo
.scaleFactorY
)) / 2.0;
143 case ZOOM_FIT
: /* Zoom Fit */
144 gerbv_render_zoom_to_fit_display (mainProject
, &screenRenderInfo
);
146 case ZOOM_SET
: /*explicit scale set by user */
147 screenRenderInfo
.scaleFactorX
= scaleFactor
;
148 screenRenderInfo
.scaleFactorY
= scaleFactor
;
149 (void) render_check_scale_factor_limits ();
150 screenRenderInfo
.lowerLeftX
+= (oldWidth
- (screenRenderInfo
.displayWidth
/
151 screenRenderInfo
.scaleFactorX
)) / 2.0;
152 screenRenderInfo
.lowerLeftY
+= (oldHeight
- (screenRenderInfo
.displayHeight
/
153 screenRenderInfo
.scaleFactorY
)) / 2.0;
156 GERB_MESSAGE("Illegal zoom direction %d\n", zoomType
);
159 if (zoomType
== ZOOM_IN_CMOUSE
|| zoomType
== ZOOM_OUT_CMOUSE
) {
160 /* make sure the mouse is still pointing at the point calculated earlier */
161 screenRenderInfo
.lowerLeftX
= mouseCoordinateX
- mouseX
/ screenRenderInfo
.scaleFactorX
;
162 screenRenderInfo
.lowerLeftY
= mouseCoordinateY
- (screenRenderInfo
.displayHeight
- mouseY
) /
163 screenRenderInfo
.scaleFactorY
;
165 render_refresh_rendered_image_on_screen();
170 /* --------------------------------------------------------- */
171 /** Will determine the outline of the zoomed regions.
172 * In case region to be zoomed is too small (which correspondes
173 * e.g. to a double click) it is interpreted as a right-click
174 * and will be used to identify a part from the CURRENT selection,
175 * which is drawn on screen*/
177 render_calculate_zoom_from_outline(GtkWidget
*widget
, GdkEventButton
*event
)
179 int x1
, y1
, x2
, y2
, dx
, dy
; /* Zoom outline (UR and LL corners) */
180 double centerPointX
, centerPointY
;
181 int half_x
, half_y
; /* cache for half window dimensions */
183 x1
= MIN(screen
.start_x
, event
->x
);
184 y1
= MIN(screen
.start_y
, event
->y
);
185 x2
= MAX(screen
.start_x
, event
->x
);
186 y2
= MAX(screen
.start_y
, event
->y
);
190 if ((dx
>= 4) && (dy
>= 4)) {
191 if (screen
.centered_outline_zoom
) {
192 /* Centered outline mode */
193 x1
= screen
.start_x
- dx
;
194 y1
= screen
.start_y
- dy
;
200 centerPointX
= half_x
/screenRenderInfo
.scaleFactorX
+ screenRenderInfo
.lowerLeftX
;
201 centerPointY
= (screenRenderInfo
.displayHeight
- half_y
)/screenRenderInfo
.scaleFactorY
+
202 screenRenderInfo
.lowerLeftY
;
204 screenRenderInfo
.scaleFactorX
*= MIN(((double)screenRenderInfo
.displayWidth
/ dx
),
205 ((double)screenRenderInfo
.displayHeight
/ dy
));
206 screenRenderInfo
.scaleFactorY
= screenRenderInfo
.scaleFactorX
;
207 (void) render_check_scale_factor_limits ();
208 screenRenderInfo
.lowerLeftX
= centerPointX
- (screenRenderInfo
.displayWidth
/
209 2.0 / screenRenderInfo
.scaleFactorX
);
210 screenRenderInfo
.lowerLeftY
= centerPointY
- (screenRenderInfo
.displayHeight
/
211 2.0 / screenRenderInfo
.scaleFactorY
);
213 render_refresh_rendered_image_on_screen();
216 /* ------------------------------------------------------ */
218 render_draw_selection_box_outline(void) {
221 GdkGCValuesMask values_mask
;
222 gint x1
, y1
, x2
, y2
, dx
, dy
;
224 memset(&values
, 0, sizeof(values
));
225 values
.function
= GDK_XOR
;
226 if (!screen
.zoom_outline_color
.pixel
)
227 gdk_colormap_alloc_color(gdk_colormap_get_system(), &screen
.zoom_outline_color
, FALSE
, TRUE
);
228 values
.foreground
= screen
.zoom_outline_color
;
229 values_mask
= GDK_GC_FUNCTION
| GDK_GC_FOREGROUND
;
230 gc
= gdk_gc_new_with_values(screen
.drawing_area
->window
, &values
, values_mask
);
232 x1
= MIN(screen
.start_x
, screen
.last_x
);
233 y1
= MIN(screen
.start_y
, screen
.last_y
);
234 x2
= MAX(screen
.start_x
, screen
.last_x
);
235 y2
= MAX(screen
.start_y
, screen
.last_y
);
239 gdk_draw_rectangle(screen
.drawing_area
->window
, gc
, FALSE
, x1
, y1
, dx
, dy
);
243 /* --------------------------------------------------------- */
245 render_draw_zoom_outline(gboolean centered
)
249 GdkGCValuesMask values_mask
;
250 gint x1
, y1
, x2
, y2
, dx
, dy
;
252 memset(&values
, 0, sizeof(values
));
253 values
.function
= GDK_XOR
;
254 if (!screen
.zoom_outline_color
.pixel
)
255 gdk_colormap_alloc_color(gdk_colormap_get_system(), &screen
.zoom_outline_color
, FALSE
, TRUE
);
256 values
.foreground
= screen
.zoom_outline_color
;
257 values_mask
= GDK_GC_FUNCTION
| GDK_GC_FOREGROUND
;
258 gc
= gdk_gc_new_with_values(screen
.drawing_area
->window
, &values
, values_mask
);
260 x1
= MIN(screen
.start_x
, screen
.last_x
);
261 y1
= MIN(screen
.start_y
, screen
.last_y
);
262 x2
= MAX(screen
.start_x
, screen
.last_x
);
263 y2
= MAX(screen
.start_y
, screen
.last_y
);
268 /* Centered outline mode */
269 x1
= screen
.start_x
- dx
;
270 y1
= screen
.start_y
- dy
;
277 gdk_draw_rectangle(screen
.drawing_area
->window
, gc
, FALSE
, x1
, y1
, dx
, dy
);
280 /* Draw actual zoom area in dashed lines */
281 memset(&values
, 0, sizeof(values
));
282 values
.function
= GDK_XOR
;
283 values
.foreground
= screen
.zoom_outline_color
;
284 values
.line_style
= GDK_LINE_ON_OFF_DASH
;
285 values_mask
= GDK_GC_FUNCTION
| GDK_GC_FOREGROUND
| GDK_GC_LINE_STYLE
;
286 gc
= gdk_gc_new_with_values(screen
.drawing_area
->window
, &values
,
289 if ((dy
== 0) || ((double)dx
/dy
> (double)screen
.drawing_area
->allocation
.width
/
290 screen
.drawing_area
->allocation
.height
)) {
291 dy
= dx
* (double)screen
.drawing_area
->allocation
.height
/
292 screen
.drawing_area
->allocation
.width
;
295 dx
= dy
* (double)screen
.drawing_area
->allocation
.width
/
296 screen
.drawing_area
->allocation
.height
;
299 gdk_draw_rectangle(screen
.drawing_area
->window
, gc
, FALSE
, (x1
+x2
-dx
)/2,
300 (y1
+y2
-dy
)/2, dx
, dy
);
306 /* ------------------------------------------------------ */
307 /** Displays a measured distance graphically on screen and in statusbar.
308 activated when using SHIFT and mouse dragged to measure distances\n
309 under win32 graphical annotations are currently disabled (GTK 2.47)*/
311 render_draw_measure_distance(void)
313 #if !defined (__MINGW32__)
317 GdkGCValuesMask values_mask
;
322 #if !defined (__MINGW32__) /*taken out because of different drawing behaviour under win32 resulting in a smear */
323 memset(&values
, 0, sizeof(values
));
324 values
.function
= GDK_XOR
;
325 if (!screen
.zoom_outline_color
.pixel
)
326 gdk_colormap_alloc_color(gdk_colormap_get_system(), &screen
.zoom_outline_color
, FALSE
, TRUE
);
327 values
.foreground
= screen
.zoom_outline_color
;
328 values_mask
= GDK_GC_FUNCTION
| GDK_GC_FOREGROUND
;
329 gc
= gdk_gc_new_with_values(screen
.drawing_area
->window
, &values
,
332 x1
= MIN(screen
.start_x
, screen
.last_x
);
333 y1
= MIN(screen
.start_y
, screen
.last_y
);
334 x2
= MAX(screen
.start_x
, screen
.last_x
);
335 y2
= MAX(screen
.start_y
, screen
.last_y
);
336 dx
= (x2
- x1
)/ screenRenderInfo
.scaleFactorX
;
337 dy
= (y2
- y1
)/ screenRenderInfo
.scaleFactorY
;
339 #if !defined (__MINGW32__)
340 gdk_draw_line(screen
.drawing_area
->window
, gc
, screen
.start_x
,
341 screen
.start_y
, screen
.last_x
, screen
.last_y
);
343 screen
.win
.lastMeasuredX
= dx
;
344 screen
.win
.lastMeasuredY
= dy
;
345 callbacks_update_statusbar_measured_distance (dx
, dy
);
346 #if !defined (__MINGW32__)
349 } /* draw_measure_distance */
351 /* ------------------------------------------------------ */
352 void render_selection_layer (void){
353 #ifndef RENDER_USING_GDK
356 if (screen
.selectionRenderData
)
357 cairo_surface_destroy ((cairo_surface_t
*) screen
.selectionRenderData
);
358 screen
.selectionRenderData
=
359 (gpointer
) cairo_surface_create_similar ((cairo_surface_t
*)screen
.windowSurface
,
360 CAIRO_CONTENT_COLOR_ALPHA
, screenRenderInfo
.displayWidth
,
361 screenRenderInfo
.displayHeight
);
362 if (screen
.selectionInfo
.type
!= GERBV_SELECTION_EMPTY
) {
363 cr
= cairo_create(screen
.selectionRenderData
);
364 gerbv_render_cairo_set_scale_and_translation(cr
, &screenRenderInfo
);
365 cairo_set_source_rgba (cr
, 1.0, 1.0, 1.0, 0.85);
366 /* for now, assume everything in the selection buffer is from one image */
367 gerbv_image_t
*matchImage
;
369 if (screen
.selectionInfo
.selectedNodeArray
->len
> 0) {
370 gerbv_selection_item_t sItem
= g_array_index (screen
.selectionInfo
.selectedNodeArray
,
371 gerbv_selection_item_t
, 0);
372 matchImage
= (gerbv_image_t
*) sItem
.image
;
373 dprintf(" .... calling render_image_to_cairo_target on selection layer...\n");
374 for(j
= mainProject
->last_loaded
; j
>= 0; j
--) {
375 if ((mainProject
->file
[j
]) && (mainProject
->file
[j
]->image
== matchImage
)) {
376 draw_image_to_cairo_target (cr
, mainProject
->file
[j
]->image
,
377 mainProject
->file
[j
]->transform
.inverted
,
378 1.0/MAX(screenRenderInfo
.scaleFactorX
,
379 screenRenderInfo
.scaleFactorY
),
380 DRAW_SELECTIONS
, &screen
.selectionInfo
);
389 /* ------------------------------------------------------ */
390 void render_refresh_rendered_image_on_screen (void) {
393 dprintf("----> Entering redraw_pixmap...\n");
394 cursor
= gdk_cursor_new(GDK_WATCH
);
395 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
), cursor
);
396 gdk_cursor_destroy(cursor
);
398 if (screenRenderInfo
.renderType
< 2){
400 gdk_pixmap_unref(screen
.pixmap
);
401 screen
.pixmap
= gdk_pixmap_new(screen
.drawing_area
->window
, screenRenderInfo
.displayWidth
,
402 screenRenderInfo
.displayHeight
, -1);
403 gerbv_render_to_pixmap_using_gdk (mainProject
, screen
.pixmap
, &screenRenderInfo
, &screen
.selectionInfo
,
404 &screen
.selection_color
);
405 dprintf("<---- leaving redraw_pixmap.\n");
407 #ifndef RENDER_USING_GDK
410 dprintf(" .... Now try rendering the drawing using cairo .... \n");
412 * This now allows drawing several layers on top of each other.
413 * Higher layer numbers have higher priority in the Z-order.
415 for(i
= mainProject
->last_loaded
; i
>= 0; i
--) {
416 if (mainProject
->file
[i
]) {
418 if (mainProject
->file
[i
]->privateRenderData
)
419 cairo_surface_destroy ((cairo_surface_t
*) mainProject
->file
[i
]->privateRenderData
);
420 mainProject
->file
[i
]->privateRenderData
=
421 (gpointer
) cairo_surface_create_similar ((cairo_surface_t
*)screen
.windowSurface
,
422 CAIRO_CONTENT_COLOR_ALPHA
, screenRenderInfo
.displayWidth
,
423 screenRenderInfo
.displayHeight
);
424 cr
= cairo_create(mainProject
->file
[i
]->privateRenderData
);
425 gerbv_render_layer_to_cairo_target (cr
, mainProject
->file
[i
], &screenRenderInfo
);
426 dprintf(" .... calling render_image_to_cairo_target on layer %d...\n", i
);
430 /* render the selection layer */
431 render_selection_layer();
433 render_recreate_composite_surface ();
436 /* remove watch cursor and switch back to normal cursor */
437 callbacks_switch_to_correct_cursor ();
438 callbacks_force_expose_event_for_screen();
441 /* ------------------------------------------------------ */
443 render_clear_selection_buffer (void){
444 if (screen
.selectionInfo
.type
== GERBV_SELECTION_EMPTY
)
447 g_array_remove_range (screen
.selectionInfo
.selectedNodeArray
, 0,
448 screen
.selectionInfo
.selectedNodeArray
->len
);
449 screen
.selectionInfo
.type
= GERBV_SELECTION_EMPTY
;
450 callbacks_update_selected_object_message (FALSE
);
454 render_remove_selected_objects_belonging_to_layer (gint index
) {
457 for (i
=screen
.selectionInfo
.selectedNodeArray
->len
-1; i
>=0; i
--) {
458 gerbv_selection_item_t sItem
= g_array_index (screen
.selectionInfo
.selectedNodeArray
,
459 gerbv_selection_item_t
, i
);
461 gerbv_image_t
*matchImage
= (gerbv_image_t
*) sItem
.image
;
462 if (mainProject
->file
[index
]->image
== matchImage
) {
463 g_array_remove_index (screen
.selectionInfo
.selectedNodeArray
, index
);
466 callbacks_update_selected_object_message (FALSE
);
469 /* ------------------------------------------------------ */
470 #ifndef RENDER_USING_GDK
472 render_create_cairo_buffer_surface () {
473 if (screen
.bufferSurface
) {
474 cairo_surface_destroy (screen
.bufferSurface
);
475 screen
.bufferSurface
= NULL
;
477 if (!screen
.windowSurface
)
480 screen
.bufferSurface
= cairo_surface_create_similar ((cairo_surface_t
*)screen
.windowSurface
,
481 CAIRO_CONTENT_COLOR
, screenRenderInfo
.displayWidth
,
482 screenRenderInfo
.displayHeight
);
486 /* ------------------------------------------------------ */
488 render_find_selected_objects_and_refresh_display (gint activeFileIndex
, gboolean eraseOldSelection
){
489 /* clear the old selection array if desired */
490 if ((eraseOldSelection
)&&(screen
.selectionInfo
.selectedNodeArray
->len
))
491 g_array_remove_range (screen
.selectionInfo
.selectedNodeArray
, 0,
492 screen
.selectionInfo
.selectedNodeArray
->len
);
494 /* make sure we have a bufferSurface...if we start up in FAST mode, we may not
495 have one yet, but we need it for selections */
496 if (!render_create_cairo_buffer_surface())
499 /* call draw_image... passing the FILL_SELECTION mode to just search for
500 nets which match the selection, and fill the selection buffer with them */
501 cairo_t
*cr
= cairo_create(screen
.bufferSurface
);
502 gerbv_render_cairo_set_scale_and_translation(cr
,&screenRenderInfo
);
503 draw_image_to_cairo_target (cr
, mainProject
->file
[activeFileIndex
]->image
, mainProject
->file
[activeFileIndex
]->transform
.inverted
,
504 1.0/MAX(screenRenderInfo
.scaleFactorX
, screenRenderInfo
.scaleFactorY
),
505 FIND_SELECTIONS
, &screen
.selectionInfo
);
507 /* if the selection array is empty, switch the "mode" to empty to make it
508 easier to check if it is holding anything */
509 if (!screen
.selectionInfo
.selectedNodeArray
->len
)
510 screen
.selectionInfo
.type
= GERBV_SELECTION_EMPTY
;
511 /* re-render the selection buffer layer */
512 if (screenRenderInfo
.renderType
< 2){
513 render_refresh_rendered_image_on_screen ();
516 render_selection_layer();
517 render_recreate_composite_surface ();
518 callbacks_force_expose_event_for_screen();
522 /* ------------------------------------------------------ */
524 render_fill_selection_buffer_from_mouse_click (gint mouseX
, gint mouseY
, gint activeFileIndex
,
525 gboolean eraseOldSelection
) {
526 screen
.selectionInfo
.lowerLeftX
= mouseX
;
527 screen
.selectionInfo
.lowerLeftY
= mouseY
;
528 /* no need to populate the upperright coordinates for a point_click */
529 screen
.selectionInfo
.type
= GERBV_SELECTION_POINT_CLICK
;
530 render_find_selected_objects_and_refresh_display (activeFileIndex
, eraseOldSelection
);
533 /* ------------------------------------------------------ */
535 render_fill_selection_buffer_from_mouse_drag (gint corner1X
, gint corner1Y
,
536 gint corner2X
, gint corner2Y
, gint activeFileIndex
, gboolean eraseOldSelection
) {
537 /* figure out the lower left corner of the box */
538 screen
.selectionInfo
.lowerLeftX
= MIN(corner1X
, corner2X
);
539 screen
.selectionInfo
.lowerLeftY
= MIN(corner1Y
, corner2Y
);
540 /* figure out the upper right corner of the box */
541 screen
.selectionInfo
.upperRightX
= MAX(corner1X
, corner2X
);
542 screen
.selectionInfo
.upperRightY
= MAX(corner1Y
, corner2Y
);
544 screen
.selectionInfo
.type
= GERBV_SELECTION_DRAG_BOX
;
545 render_find_selected_objects_and_refresh_display (activeFileIndex
, eraseOldSelection
);
548 /* ------------------------------------------------------ */
549 void render_recreate_composite_surface () {
552 if (!render_create_cairo_buffer_surface())
555 cairo_t
*cr
= cairo_create(screen
.bufferSurface
);
556 /* fill the background with the appropriate color */
557 cairo_set_source_rgba (cr
, (double) mainProject
->background
.red
/G_MAXUINT16
,
558 (double) mainProject
->background
.green
/G_MAXUINT16
,
559 (double) mainProject
->background
.blue
/G_MAXUINT16
, 1);
562 for(i
= mainProject
->last_loaded
; i
>= 0; i
--) {
563 if (mainProject
->file
[i
] && mainProject
->file
[i
]->isVisible
) {
564 cairo_set_source_surface (cr
, (cairo_surface_t
*) mainProject
->file
[i
]->privateRenderData
,
566 /* ignore alpha if we are in high-speed render mode */
567 if (((double) mainProject
->file
[i
]->alpha
< 65535)&&(screenRenderInfo
.renderType
!= 1)) {
568 cairo_paint_with_alpha(cr
,(double) mainProject
->file
[i
]->alpha
/G_MAXUINT16
);
575 /* render the selection layer at the end */
576 if (screen
.selectionInfo
.type
!= GERBV_SELECTION_EMPTY
) {
577 cairo_set_source_surface (cr
, (cairo_surface_t
*) screen
.selectionRenderData
,
579 cairo_paint_with_alpha (cr
,1.0);
584 /* ------------------------------------------------------ */
585 void render_project_to_cairo_target (cairo_t
*cr
) {
586 /* fill the background with the appropriate color */
587 cairo_set_source_rgba (cr
, (double) mainProject
->background
.red
/G_MAXUINT16
,
588 (double) mainProject
->background
.green
/G_MAXUINT16
,
589 (double) mainProject
->background
.blue
/G_MAXUINT16
, 1);
592 cairo_set_source_surface (cr
, (cairo_surface_t
*) screen
.bufferSurface
, 0 , 0);
596 #endif /* RENDER_USING_GDK */
599 render_free_screen_resources (void) {
600 #ifndef RENDER_USING_GDK
601 if (screen
.selectionRenderData
)
602 cairo_surface_destroy ((cairo_surface_t
*)
603 screen
.selectionRenderData
);
604 if (screen
.bufferSurface
)
605 cairo_surface_destroy ((cairo_surface_t
*)
606 screen
.bufferSurface
);
607 if (screen
.windowSurface
)
608 cairo_surface_destroy ((cairo_surface_t
*)
609 screen
.windowSurface
);
612 gdk_pixmap_unref(screen
.pixmap
);
616 /* ------------------------------------------------------------------ */
617 /*! This fills out the project's Gerber statistics table.
618 * It is called from within callbacks.c when the user
619 * asks for a Gerber report. */
621 generate_gerber_analysis(void)
624 gerbv_stats_t
*stats
;
625 gerbv_stats_t
*instats
;
627 /* Create new stats structure to hold report for whole project
628 * (i.e. all layers together) */
629 stats
= gerbv_stats_new();
631 /* Loop through open layers and compile statistics by accumulating reports from each layer */
632 for (i
= 0; i
<= mainProject
->last_loaded
; i
++) {
633 if (mainProject
->file
[i
] && mainProject
->file
[i
]->isVisible
&&
634 (mainProject
->file
[i
]->image
->layertype
== GERBV_LAYERTYPE_RS274X
) ) {
635 instats
= mainProject
->file
[i
]->image
->gerbv_stats
;
636 gerbv_stats_add_layer(stats
, instats
, i
+1);
643 /* ------------------------------------------------------------------ */
644 /*! This fills out the project's Drill statistics table.
645 * It is called from within callbacks.c when the user
646 * asks for a Drill report. */
647 gerbv_drill_stats_t
*
648 generate_drill_analysis(void)
651 gerbv_drill_stats_t
*stats
;
652 gerbv_drill_stats_t
*instats
;
654 stats
= gerbv_drill_stats_new();
656 /* Loop through open layers and compile statistics by accumulating reports from each layer */
657 for(i
= mainProject
->last_loaded
; i
>= 0; i
--) {
658 if (mainProject
->file
[i
] &&
659 mainProject
->file
[i
]->isVisible
&&
660 (mainProject
->file
[i
]->image
->layertype
== GERBV_LAYERTYPE_DRILL
) ) {
661 instats
= mainProject
->file
[i
]->image
->drill_stats
;
662 /* add this batch of stats. Send the layer
663 * index for error reporting */
664 gerbv_drill_stats_add_layer(stats
, instats
, i
+1);