gerbv
draw-gdk.c
Go to the documentation of this file.
1 /*
2  * gEDA - GNU Electronic Design Automation
3  * This file is a part of gerbv.
4  *
5  * Copyright (C) 2000-2003 Stefan Petersen (spe@stacken.kth.se)
6  *
7  * $Id$
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
22  */
23 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <math.h> /* ceil(), atan2() */
36 
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #endif
40 
41 #include <gtk/gtk.h>
42 #include "gerbv.h"
43 #include "draw-gdk.h"
44 #include "common.h"
45 
46 #undef round
47 #define round(x) ceil((double)(x))
48 
49 #undef DPRINTF
50 #define DPRINTF(...) do { if (DEBUG) printf(__VA_ARGS__); } while (0)
51 
52 /*
53  * If you want to rotate a
54  * column vector v by t degrees using matrix M, use
55  *
56  * M = {{cos t, -sin t}, {sin t, cos t}} in M*v.
57  *
58  * From comp.graphics.algorithms Frequently Asked Questions
59  *
60  * Due reverse defintion of X-axis in GTK you have to negate
61  * angels.
62  *
63  */
64 static GdkPoint
65 rotate_point(GdkPoint point, double angle)
66 {
67  double sint, cost;
68  GdkPoint returned;
69 
70  if (angle == 0.0)
71  return point;
72 
73  sint = sin(DEG2RAD(-angle));
74  cost = cos(DEG2RAD(-angle));
75 
76  returned.x = lround(cost*point.x - sint*point.y);
77  returned.y = lround(sint*point.x + cost*point.y);
78 
79  return returned;
80 }
81 
82 
83 /*
84  * Aperture macro primitive 1 (Circle)
85  */
86 static void
87 gerbv_gdk_draw_prim1(GdkPixmap *pixmap, GdkGC *gc, gerbv_simplified_amacro_t *s,
88  double scale, gint x, gint y)
89 {
90  const int exposure_idx = 0;
91  const int diameter_idx = 1;
92  const int x_offset_idx = 2;
93  const int y_offset_idx = 3;
94  const int rotation_idx = 4;
95  const gint full_circle = 23360;
96  GdkGC *local_gc = gdk_gc_new(pixmap);
97  gint dia = round(fabs(s->parameter[diameter_idx] * scale));
98  gint real_x = x - dia / 2;
99  gint real_y = y - dia / 2;
100  GdkPoint center;
101  GdkColor color;
102 
103  gdk_gc_copy(local_gc, gc);
104 
105  center.x = (int)(s->parameter[x_offset_idx] * (double)scale);
106  center.y = -(int)(s->parameter[y_offset_idx] * (double)scale);
107  center = rotate_point(center, s->parameter[rotation_idx]);
108  real_x += center.x;
109  real_y += center.y;
110 
111  /* Exposure */
112  if (s->parameter[exposure_idx] == 0.0) {
113  color.pixel = 0;
114  gdk_gc_set_foreground(local_gc, &color);
115  }
116 
117  gdk_gc_set_line_attributes(local_gc,
118  1, /* outline always 1 pixels */
119  GDK_LINE_SOLID,
120  GDK_CAP_BUTT,
121  GDK_JOIN_MITER);
122 
123  /*
124  * A filled circle
125  */
126  gdk_draw_arc(pixmap, local_gc, 1, real_x, real_y, dia, dia,
127  0, full_circle);
128 
129  gdk_gc_unref(local_gc);
130 
131  return;
132 } /* gerbv_gdk_draw_prim1 */
133 
134 
135 /*
136  * Aperture macro primitive 4 (outline)
137  * - Start point is not included in number of points.
138  * - Outline is 1 pixel.
139  */
140 static void
141 gerbv_gdk_draw_prim4(GdkPixmap *pixmap, GdkGC *gc, gerbv_simplified_amacro_t *s,
142  double scale, gint x, gint y)
143 {
144  const int exposure_idx = 0;
145  const int nuf_points_idx = 1;
146  const int first_x_idx = 2;
147  const int first_y_idx = 3;
148  const int rotext_idx = 4;
149  GdkGC *local_gc = gdk_gc_new(pixmap);
150  int nuf_points, point;
151  double rotation;
152  GdkPoint *points;
153  GdkColor color;
154 
155  /* Include start point */
156  nuf_points = (int)s->parameter[nuf_points_idx] + 1;
157  points = g_new(GdkPoint, nuf_points);
158  if (!points) {
159  g_free(points);
160  return;
161  }
162 
163  rotation = s->parameter[(nuf_points - 1) * 2 + rotext_idx];
164  for (point = 0; point < nuf_points; point++) {
165  points[point].x = (int)round(scale * s->parameter[point * 2 + first_x_idx]);
166  points[point].y = -(int)round(scale * s->parameter[point * 2 + first_y_idx]);
167  if (rotation != 0.0)
168  points[point] = rotate_point(points[point], rotation);
169  points[point].x += x;
170  points[point].y += y;
171  }
172 
173  gdk_gc_copy(local_gc, gc);
174 
175  /* Exposure */
176  if (s->parameter[exposure_idx] == 0.0) {
177  color.pixel = 0;
178  gdk_gc_set_foreground(local_gc, &color);
179  }
180 
181  gdk_gc_set_line_attributes(local_gc,
182  1, /* outline always 1 pixels */
183  GDK_LINE_SOLID,
184  GDK_CAP_BUTT,
185  GDK_JOIN_MITER);
186  gdk_draw_polygon(pixmap, local_gc, 1, points, nuf_points);
187 
188  g_free(points);
189 
190  gdk_gc_unref(local_gc);
191 
192  return;
193 } /* gerbv_gdk_draw_prim4 */
194 
195 
196 /*
197  * Aperture macro primitive 5 (polygon)
198  */
199 static void
200 gerbv_gdk_draw_prim5(GdkPixmap *pixmap, GdkGC *gc, gerbv_simplified_amacro_t *s,
201  double scale, gint x, gint y)
202 {
203  const int exposure_idx = 0;
204  const int nuf_vertices_idx = 1;
205  const int center_x_idx = 2;
206  const int center_y_idx = 3;
207  const int diameter_idx = 4;
208  const int rotation_idx = 5;
209  int nuf_vertices, i;
210  double vertex, tick, rotation, radius;
211  GdkPoint *points;
212  GdkGC *local_gc = gdk_gc_new(pixmap);
213  GdkColor color;
214 
215  nuf_vertices = (int)s->parameter[nuf_vertices_idx];
216  points = g_new(GdkPoint, nuf_vertices);
217  if (!points) {
218  g_free(points);
219  return;
220  }
221 
222  gdk_gc_copy(local_gc, gc);
223 
224  /* Exposure */
225  if (s->parameter[exposure_idx] == 0.0) {
226  color.pixel = 0;
227  gdk_gc_set_foreground(local_gc, &color);
228  }
229 
230  tick = 2 * M_PI / (double)nuf_vertices;
231  rotation = DEG2RAD(-s->parameter[rotation_idx]);
232  radius = s->parameter[diameter_idx] / 2.0;
233  for (i = 0; i < nuf_vertices; i++) {
234  vertex = tick * (double)i + rotation;
235  points[i].x = (int)round(scale * (radius * cos(vertex) + s->parameter[center_x_idx])) + x;
236  points[i].y = (int)round(scale * (radius * sin(vertex) - s->parameter[center_y_idx])) + y;
237  }
238 
239  gdk_draw_polygon(pixmap, local_gc, 1, points, nuf_vertices);
240 
241  gdk_gc_unref(local_gc);
242 
243  g_free(points);
244  return;
245 } /* gerbv_gdk_draw_prim5 */
246 
247 
248 /*
249  * Doesn't handle and explicit x,y yet
250  * Questions:
251  * - is "gap" distance between edges of circles or distance between
252  * center of line of circle?
253  */
254 static void
255 gerbv_gdk_draw_prim6(GdkPixmap *pixmap, GdkGC *gc, gerbv_simplified_amacro_t *s,
256  double scale, gint x, gint y)
257 {
258  const int outside_dia_idx = 2;
259  const int ci_thickness_idx = 3;
260  const int gap_idx = 4;
261  const int nuf_circles_idx = 5;
262  const int ch_thickness_idx = 6;
263  const int ch_length_idx = 7;
264  const int rotation_idx = 8;
265  GdkGC *local_gc = gdk_gc_new(pixmap);
266  double real_dia;
267  double real_dia_diff;
268  int circle;
269  GdkPoint crosshair[4];
270  int point;
271 
272  gdk_gc_copy(local_gc, gc);
273  gdk_gc_set_line_attributes(local_gc,
274  (int)round(scale * s->parameter[ci_thickness_idx]),
275  GDK_LINE_SOLID,
276  GDK_CAP_BUTT,
277  GDK_JOIN_MITER);
278 
279  real_dia = s->parameter[outside_dia_idx] - s->parameter[ci_thickness_idx] / 2.0;
280  real_dia_diff = 2*(s->parameter[gap_idx] + s->parameter[ci_thickness_idx]);
281 
282  for (circle = 0; circle != (int)s->parameter[nuf_circles_idx]; circle++) {
283  /*
284  * Non filled circle
285  */
286  const gint full_circle = 23360;
287  gint dia = (real_dia - real_dia_diff * circle) * scale;
288  if (dia >= 0){
289  gdk_draw_arc(pixmap, local_gc, 0, x - dia / 2, y - dia / 2,
290  dia, dia, 0, full_circle);
291  }
292  }
293 
294  /*
295  * Cross Hair
296  */
297  memset(crosshair, 0, sizeof(GdkPoint) * 4);
298  crosshair[0].x = (int)((s->parameter[ch_length_idx] / 2.0) * scale);
299  /*crosshair[0].y = 0;*/
300  crosshair[1].x = -crosshair[0].x;
301  /*crosshair[1].y = 0;*/
302  /*crosshair[2].x = 0;*/
303  crosshair[2].y = crosshair[0].x;
304  /*crosshair[3].x = 0;*/
305  crosshair[3].y = -crosshair[0].x;
306 
307  gdk_gc_set_line_attributes(local_gc,
308  (int)round(scale * s->parameter[ch_thickness_idx]),
309  GDK_LINE_SOLID,
310  GDK_CAP_BUTT,
311  GDK_JOIN_MITER);
312 
313  for (point = 0; point < 4; point++) {
314  crosshair[point] = rotate_point(crosshair[point],
315  s->parameter[rotation_idx]);
316  crosshair[point].x += x;
317  crosshair[point].y += y;
318  }
319  gdk_draw_line(pixmap, local_gc,
320  crosshair[0].x, crosshair[0].y,
321  crosshair[1].x, crosshair[1].y);
322  gdk_draw_line(pixmap, local_gc,
323  crosshair[2].x, crosshair[2].y,
324  crosshair[3].x, crosshair[3].y);
325 
326  gdk_gc_unref(local_gc);
327 
328  return;
329 } /* gerbv_gdk_draw_prim6 */
330 
331 
332 static void
333 gerbv_gdk_draw_prim7(GdkPixmap *pixmap, GdkGC *gc, gerbv_simplified_amacro_t *s,
334  double scale, gint x, gint y)
335 {
336  const int outside_dia_idx = 2;
337  const int inside_dia_idx = 3;
338  const int ch_thickness_idx = 4;
339  const int rotation_idx = 5;
340  const gint full_circle = 23360;
341  GdkGCValues gc_val;
342  int diameter, i;
343  GdkGC *local_gc = gdk_gc_new(pixmap);
344  GdkPoint point[4];
345  double ci_thickness = (s->parameter[outside_dia_idx] -
346  s->parameter[inside_dia_idx]) / 2.0;
347 
348  gdk_gc_copy(local_gc, gc);
349  gdk_gc_set_line_attributes(local_gc,
350  (int)round(scale * ci_thickness),
351  GDK_LINE_SOLID,
352  GDK_CAP_BUTT,
353  GDK_JOIN_MITER);
354 
355  /*
356  * Non filled circle
357  */
358  diameter = (s->parameter[inside_dia_idx] + ci_thickness) * scale;
359  gdk_draw_arc(pixmap, local_gc, 0, x - diameter / 2, y - diameter / 2,
360  diameter, diameter, 0, full_circle);
361 
362  /*
363  * Cross hair
364  */
365  /* Calculate the end points of the crosshair */
366  /* GDK doesn't always remove all of the circle (round of error probably)
367  I extend the crosshair line with 2 (one pixel in each end) to make
368  sure all of the circle is removed with the crosshair */
369  for (i = 0; i < 4; i++) {
370  point[i].x = round((s->parameter[outside_dia_idx] / 2.0) * scale) + 2;
371  point[i].y = 0;
372  point[i] = rotate_point(point[i], s->parameter[rotation_idx] + 90 * i);
373  point[i].x += x;
374  point[i].y += y;
375  }
376 
377  gdk_gc_set_line_attributes(local_gc,
378  (int)round(scale * s->parameter[ch_thickness_idx]),
379  GDK_LINE_SOLID,
380  GDK_CAP_BUTT,
381  GDK_JOIN_MITER);
382 
383  /* The cross hair should "cut out" parts of the circle, hence inverse */
384  gdk_gc_get_values(local_gc, &gc_val);
385  if (gc_val.foreground.pixel == 1)
386  gc_val.foreground.pixel = 0;
387  else
388  gc_val.foreground.pixel = 1;
389  gdk_gc_set_foreground(local_gc, &(gc_val.foreground));
390 
391  /* Draw the actual cross */
392  gdk_draw_line(pixmap, local_gc,
393  point[0].x, point[0].y, point[2].x, point[2].y);
394  gdk_draw_line(pixmap, local_gc,
395  point[1].x, point[1].y, point[3].x, point[3].y);
396 
397  gdk_gc_unref(local_gc);
398 
399  return;
400 } /* gerbv_gdk_draw_prim7 */
401 
402 
403 /*
404  * Doesn't handle and explicit x,y yet
405  */
406 static void
407 gerbv_gdk_draw_prim20(GdkPixmap *pixmap, GdkGC *gc, gerbv_simplified_amacro_t *s,
408  double scale, gint x, gint y)
409 {
410  const int exposure_idx = 0;
411  const int linewidth_idx = 1;
412  const int start_x_idx = 2;
413  const int start_y_idx = 3;
414  const int end_x_idx = 4;
415  const int end_y_idx = 5;
416  const int rotation_idx = 6;
417  const int nuf_points = 2;
418  GdkGC *local_gc = gdk_gc_new(pixmap);
419  GdkPoint points[nuf_points];
420  GdkColor color;
421  int i;
422 
423  gdk_gc_copy(local_gc, gc);
424 
425  /* Exposure */
426  if (s->parameter[exposure_idx] == 0.0) {
427  color.pixel = 0;
428  gdk_gc_set_foreground(local_gc, &color);
429  }
430 
431  gdk_gc_set_line_attributes(local_gc,
432  (int)round(scale * s->parameter[linewidth_idx]),
433  GDK_LINE_SOLID,
434  GDK_CAP_BUTT,
435  GDK_JOIN_MITER);
436 
437  points[0].x = (s->parameter[start_x_idx] * scale);
438  points[0].y = (s->parameter[start_y_idx] * scale);
439  points[1].x = (s->parameter[end_x_idx] * scale);
440  points[1].y = (s->parameter[end_y_idx] * scale);
441 
442  for (i = 0; i < nuf_points; i++) {
443  points[i] = rotate_point(points[i], -s->parameter[rotation_idx]);
444  points[i].x = x + points[i].x;
445  points[i].y = y - points[i].y;
446  }
447 
448  gdk_draw_line(pixmap, local_gc,
449  points[0].x, points[0].y,
450  points[1].x, points[1].y);
451 
452  gdk_gc_unref(local_gc);
453 
454  return;
455 } /* gerbv_gdk_draw_prim20 */
456 
457 
458 static void
459 gerbv_gdk_draw_prim21(GdkPixmap *pixmap, GdkGC *gc, gerbv_simplified_amacro_t *s,
460  double scale, gint x, gint y)
461 {
462  const int exposure_idx = 0;
463  const int width_idx = 1;
464  const int height_idx = 2;
465  const int exp_x_idx = 3;
466  const int exp_y_idx = 4;
467  const int rotation_idx = 5;
468  const int nuf_points = 4;
469  GdkPoint points[nuf_points];
470  GdkColor color;
471  GdkGC *local_gc = gdk_gc_new(pixmap);
472  int half_width, half_height;
473  int i;
474 
475  half_width = (int)round(s->parameter[width_idx] * scale / 2.0);
476  half_height =(int)round(s->parameter[height_idx] * scale / 2.0);
477 
478  points[0].x = half_width;
479  points[0].y = half_height;
480 
481  points[1].x = half_width;
482  points[1].y = -half_height;
483 
484  points[2].x = -half_width;
485  points[2].y = -half_height;
486 
487  points[3].x = -half_width;
488  points[3].y = half_height;
489 
490  for (i = 0; i < nuf_points; i++) {
491  points[i].x += (int)(s->parameter[exp_x_idx] * scale);
492  points[i].y -= (int)(s->parameter[exp_y_idx] * scale);
493  points[i] = rotate_point(points[i], s->parameter[rotation_idx]);
494  points[i].x += x;
495  points[i].y += y;
496  }
497 
498  gdk_gc_copy(local_gc, gc);
499 
500  /* Exposure */
501  if (s->parameter[exposure_idx] == 0.0) {
502  color.pixel = 0;
503  gdk_gc_set_foreground(local_gc, &color);
504  }
505 
506  gdk_draw_polygon(pixmap, local_gc, 1, points, nuf_points);
507 
508  gdk_gc_unref(local_gc);
509 
510  return;
511 } /* gerbv_gdk_draw_prim21 */
512 
513 
514 /*
515  * Doesn't handle explicit x,y yet
516  */
517 static void
518 gerbv_gdk_draw_prim22(GdkPixmap *pixmap, GdkGC *gc, gerbv_simplified_amacro_t *s,
519  double scale, gint x, gint y)
520 {
521  const int exposure_idx = 0;
522  const int width_idx = 1;
523  const int height_idx = 2;
524  const int x_lower_left_idx = 3;
525  const int y_lower_left_idx = 4;
526  const int rotation_idx = 5;
527  const int nuf_points = 4;
528  GdkPoint points[nuf_points];
529  GdkGC *local_gc = gdk_gc_new(pixmap);
530  GdkColor color;
531  int i;
532 
533  points[0].x = (int)round(s->parameter[x_lower_left_idx] * scale);
534  points[0].y = (int)round(s->parameter[y_lower_left_idx] * scale);
535 
536  points[1].x = (int)round((s->parameter[x_lower_left_idx] + s->parameter[width_idx])
537  * scale);
538  points[1].y = (int)round(s->parameter[y_lower_left_idx] * scale);
539 
540  points[2].x = (int)round((s->parameter[x_lower_left_idx] + s->parameter[width_idx])
541  * scale);
542  points[2].y = (int)round((s->parameter[y_lower_left_idx] + s->parameter[height_idx])
543  * scale);
544 
545  points[3].x = (int)round(s->parameter[x_lower_left_idx] * scale);
546  points[3].y = (int)round((s->parameter[y_lower_left_idx] + s->parameter[height_idx])
547  * scale);
548 
549  for (i = 0; i < nuf_points; i++) {
550  points[i] = rotate_point(points[i], -s->parameter[rotation_idx]);
551  points[i].x = x + points[i].x;
552  points[i].y = y - points[i].y;
553  }
554 
555  gdk_gc_copy(local_gc, gc);
556 
557  /* Exposure */
558  if (s->parameter[exposure_idx] == 0.0) {
559  color.pixel = 0;
560  gdk_gc_set_foreground(local_gc, &color);
561  }
562 
563  gdk_draw_polygon(pixmap, local_gc, 1, points, nuf_points);
564 
565  gdk_gc_unref(local_gc);
566 
567  return;
568 } /* gerbv_gdk_draw_prim22 */
569 
570 /* Keep this array in order and without holes */
571 static void (*dgk_draw_amacro_funcs[])(GdkPixmap *, GdkGC *, gerbv_simplified_amacro_t *,
572  double, gint, gint) = {
573  [GERBV_APTYPE_MACRO_CIRCLE] = &gerbv_gdk_draw_prim1,
574  [GERBV_APTYPE_MACRO_OUTLINE] = &gerbv_gdk_draw_prim4,
575  [GERBV_APTYPE_MACRO_POLYGON] = &gerbv_gdk_draw_prim5,
576  [GERBV_APTYPE_MACRO_MOIRE] = &gerbv_gdk_draw_prim6,
577  [GERBV_APTYPE_MACRO_THERMAL] = &gerbv_gdk_draw_prim7,
578  [GERBV_APTYPE_MACRO_LINE20] = &gerbv_gdk_draw_prim20,
579  [GERBV_APTYPE_MACRO_LINE21] = &gerbv_gdk_draw_prim21,
580  [GERBV_APTYPE_MACRO_LINE22] = &gerbv_gdk_draw_prim22,
581 };
582 
583 static inline void
584 gerbv_gdk_draw_amacro(GdkPixmap *pixmap, GdkGC *gc,
585  gerbv_simplified_amacro_t *s, double scale,
586  gint x, gint y)
587 {
588  DPRINTF("%s(): drawing simplified aperture macros:\n", __func__);
589 
590  while (s != NULL) {
591  if (s->type >= GERBV_APTYPE_MACRO_CIRCLE
592  && s->type <= GERBV_APTYPE_MACRO_LINE22) {
593  dgk_draw_amacro_funcs[s->type](pixmap, gc,
594  s, scale, x, y);
595  DPRINTF(" %s\n", gerbv_aperture_type_name(s->type));
596  } else {
597  GERB_FATAL_ERROR(
598  _("Unknown simplified aperture macro type %d"),
599  s->type);
600  }
601 
602  s = s->next;
603  }
604 } /* gerbv_gdk_draw_amacro */
605 
606 
607 /*
608  * Draws a circle _centered_ at x,y with diameter dia
609  */
610 static void
611 gerbv_gdk_draw_circle(GdkPixmap *pixmap, GdkGC *gc,
612  gint filled, gint x, gint y, gint dia)
613 {
614  static const gint full_circle = 23360;
615  gint real_x = x - dia / 2;
616  gint real_y = y - dia / 2;
617 
618  gdk_draw_arc(pixmap, gc, filled, real_x, real_y, dia, dia, 0, full_circle);
619 
620  return;
621 } /* gerbv_gdk_draw_circle */
622 
623 
624 /*
625  * Draws a rectangle _centered_ at x,y with sides x_side, y_side
626  */
627 static void
628 gerbv_gdk_draw_rectangle(GdkPixmap *pixmap, GdkGC *gc,
629  int filled, gint x, gint y, gint x_side, gint y_side,
630  double angle_deg)
631 {
632  int i;
633  GdkPoint points[4];
634 
635  points[0].x = -(x_side >> 1);
636  points[0].y = -(y_side >> 1);
637  points[1].x = x_side >> 1;
638  points[1].y = points[0].y;
639  points[2].x = points[1].x;
640  points[2].y = y_side >> 1;
641  points[3].x = points[0].x;
642  points[3].y = points[2].y;
643 
644  for (i = 0; i < 4; i++) {
645  points[i] = rotate_point(points[i], angle_deg);
646  points[i].x += x;
647  points[i].y += y;
648  }
649 
650  gdk_draw_polygon(pixmap, gc, filled, points, 4);
651 
652  return;
653 } /* gerbv_gdk_draw_rectangle */
654 
655 
656 /*
657  * Draws an oval _centered_ at x,y with x axis x_axis and y axis y_axis
658  */
659 static void
660 gerbv_gdk_draw_oval(GdkPixmap *pixmap, GdkGC *gc,
661  int filled, gint x, gint y, gint x_axis, gint y_axis,
662  double angle_deg)
663 {
664  gint width;
665  GdkPoint points[2];
666  GdkGC *local_gc = gdk_gc_new(pixmap);
667 
668  gdk_gc_copy(local_gc, gc);
669 
670  if (x_axis > y_axis) {
671  /* Draw in x axis */
672  width = y_axis;
673 
674  points[0].x = -(x_axis >> 1) + (y_axis >> 1);
675  points[0].y = 0;
676  points[1].x = (x_axis >> 1) - (y_axis >> 1);
677  points[1].y = 0;
678  } else {
679  /* Draw in y axis */
680  width = x_axis;
681 
682  points[0].x = 0;
683  points[0].y = -(y_axis >> 1) + (x_axis >> 1);
684  points[1].x = 0;
685  points[1].y = (y_axis >> 1) - (x_axis >> 1);
686  }
687 
688  points[0] = rotate_point(points[0], angle_deg);
689  points[0].x += x;
690  points[0].y += y;
691  points[1] = rotate_point(points[1], angle_deg);
692  points[1].x += x;
693  points[1].y += y;
694 
695  gdk_gc_set_line_attributes(local_gc, width,
696  GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_MITER);
697  gdk_draw_line(pixmap, local_gc,
698  points[0].x, points[0].y,
699  points[1].x, points[1].y);
700 
701  gdk_gc_unref(local_gc);
702 
703  return;
704 } /* gerbv_gdk_draw_oval */
705 
706 
707 /*
708  * Draws an arc
709  * Draws an arc _centered_ at x,y
710  * direction: 0 counterclockwise, 1 clockwise
711  */
712 static void
713 gerbv_gdk_draw_arc(GdkPixmap *pixmap, GdkGC *gc,
714  int x, int y,
715  gdouble width, gdouble height,
716  double angle1, double angle2)
717 {
718  gint real_x = round(x - width / 2);
719  gint real_y = round(y - height / 2);
720 
721  gdk_draw_arc(pixmap, gc, FALSE, real_x, real_y, width, height,
722  round(64*fmod(angle1, 360)), round(64*(angle2 - angle1)));
723 } /* gerbv_gdk_draw_arc */
724 
725 void
726 draw_gdk_render_polygon_object (gerbv_net_t *oldNet, gerbv_image_t *image, double sr_x, double sr_y,
727  cairo_matrix_t *fullMatrix, cairo_matrix_t *scaleMatrix, GdkGC *gc, GdkGC *pgc,
728  GdkPixmap **pixmap) {
729  gerbv_net_t *currentNet;
730  gint x2,y2,cp_x=0,cp_y=0,cir_width=0;
731  GdkPoint *points = NULL;
732  unsigned int pointArraySize, curr_point_idx;
733  int steps,i;
734  gdouble angleDiff, tempX, tempY;
735 
736  /* save the first net in the polygon as the "ID" net pointer
737  in case we are saving this net to the selection array */
738  curr_point_idx = 0;
739  pointArraySize = 0;
740 
741  for (currentNet = oldNet->next; currentNet!=NULL; currentNet = currentNet->next){
742  tempX = currentNet->stop_x + sr_x;
743  tempY = currentNet->stop_y + sr_y;
744  cairo_matrix_transform_point (fullMatrix, &tempX, &tempY);
745  x2 = (int)round(tempX);
746  y2 = (int)round(tempY);
747 
748  /*
749  * If circle segment, scale and translate that one too
750  */
751  if (currentNet->cirseg) {
752  tempX = currentNet->cirseg->width;
753  tempY = currentNet->cirseg->height;
754  cairo_matrix_transform_point (scaleMatrix, &tempX, &tempY);
755 
756  /* Variables can be negative after transformation */
757  tempX = fabs(tempX);
758  cir_width = (int)round(tempX);
759 
760  tempX = currentNet->cirseg->cp_x + sr_x;
761  tempY = currentNet->cirseg->cp_y + sr_y;
762  cairo_matrix_transform_point (fullMatrix, &tempX, &tempY);
763  cp_x = (int)round(tempX);
764  cp_y = (int)round(tempY);
765  }
766 
767  switch (currentNet->interpolation) {
772  if (pointArraySize < (curr_point_idx + 1)) {
773  pointArraySize = curr_point_idx + 1;
774  points = (GdkPoint *)g_realloc(points,
775  pointArraySize*sizeof(GdkPoint));
776  }
777  points[curr_point_idx].x = x2;
778  points[curr_point_idx].y = y2;
779  curr_point_idx++;
780  break;
783  /* we need to chop up the arc into small lines for rendering
784  with GDK */
785  angleDiff = currentNet->cirseg->angle2 - currentNet->cirseg->angle1;
786  steps = (int) fabs(angleDiff);
787  if (pointArraySize < (curr_point_idx + steps)) {
788  pointArraySize = curr_point_idx + steps;
789  points = (GdkPoint *)g_realloc(points,
790  pointArraySize*sizeof(GdkPoint));
791  }
792  for (i=0; i<steps; i++){
793  points[curr_point_idx].x = cp_x + cir_width / 2.0 * cos (DEG2RAD(currentNet->cirseg->angle1 +
794  (angleDiff * i) / steps));
795  points[curr_point_idx].y = cp_y - cir_width / 2.0 * sin (DEG2RAD(currentNet->cirseg->angle1 +
796  (angleDiff * i) / steps));
797  curr_point_idx++;
798  }
799  break;
801  gdk_gc_copy(pgc, gc);
802  gdk_gc_set_line_attributes(pgc, 1,
803  GDK_LINE_SOLID,
804  GDK_CAP_PROJECTING,
805  GDK_JOIN_MITER);
806  gdk_draw_polygon(*pixmap, pgc, 1, points, curr_point_idx);
807  g_free(points);
808  points = NULL;
809  return;
810  default:
811  GERB_COMPILE_WARNING(
812  _("Skipped interpolation type %d"),
813  currentNet->interpolation);
814  break;
815  }
816  }
817  return;
818 }
819 
820 void
821 draw_gdk_apply_netstate_transformation (cairo_matrix_t *fullMatrix, cairo_matrix_t *scaleMatrix,
822  gerbv_netstate_t *state) {
823  /* apply scale factor */
824  cairo_matrix_scale (fullMatrix, state->scaleA, state->scaleB);
825  cairo_matrix_scale (scaleMatrix, state->scaleA, state->scaleB);
826  /* apply offset */
827  cairo_matrix_translate (fullMatrix, state->offsetA, state->offsetB);
828  /* apply mirror */
829  switch (state->mirrorState) {
830  case GERBV_MIRROR_STATE_FLIPA:
831  cairo_matrix_scale (fullMatrix, -1, 1);
832  cairo_matrix_scale (scaleMatrix, -1, 1);
833  break;
834  case GERBV_MIRROR_STATE_FLIPB:
835  cairo_matrix_scale (fullMatrix, 1, -1);
836  cairo_matrix_scale (scaleMatrix, -1, 1);
837  break;
838  case GERBV_MIRROR_STATE_FLIPAB:
839  cairo_matrix_scale (fullMatrix, -1, -1);
840  cairo_matrix_scale (scaleMatrix, -1, 1);
841  break;
842  default:
843  break;
844  }
845  /* finally, apply axis select */
846  if (state->axisSelect == GERBV_AXIS_SELECT_SWAPAB) {
847  /* we do this by rotating 270 (counterclockwise, then mirroring
848  the Y axis */
849  cairo_matrix_rotate (fullMatrix, M_PI + M_PI_2);
850  cairo_matrix_scale (fullMatrix, 1, -1);
851  }
852 }
853 
854 static void
855 draw_gdk_cross (GdkPixmap *pixmap, GdkGC *gc, gint xc, gint yc, gint r)
856 {
857  gdk_gc_set_line_attributes (gc, 1, GDK_LINE_SOLID,
858  GDK_CAP_BUTT, GDK_JOIN_MITER);
859  gdk_draw_line (pixmap, gc, xc - r, yc, xc + r, yc);
860  gdk_draw_line (pixmap, gc, xc, yc - r, xc, yc + r);
861 }
862 
863 /*
864  * Convert a gerber image to a GDK clip mask to be used when creating pixmap
865  */
866 int
867 draw_gdk_image_to_pixmap(GdkPixmap **pixmap, gerbv_image_t *image,
868  double scale, double trans_x, double trans_y,
869  enum draw_mode drawMode,
870  gerbv_selection_info_t *selectionInfo, gerbv_render_info_t *renderInfo,
871  gerbv_user_transformation_t transform)
872 {
873  const int hole_cross_inc_px = 8;
874  GdkGC *gc = gdk_gc_new(*pixmap);
875  GdkGC *pgc = gdk_gc_new(*pixmap);
876  GdkGCValues gc_values;
877  struct gerbv_net *net;
878  gerbv_netstate_t *oldState;
879  gerbv_layer_t *oldLayer;
880  gint x1, y1, x2, y2;
881  glong xlong1, ylong1, xlong2, ylong2;
882  int p1, p2;
883  double cir_width = 0, cir_height = 0;
884  int cp_x = 0, cp_y = 0;
885  GdkColor transparent, opaque;
886  gerbv_polarity_t polarity;
887  gdouble tempX, tempY, r;
888  gdouble minX=0,minY=0,maxX=0,maxY=0;
889 
890  if (image == NULL || image->netlist == NULL) {
891  gdk_gc_unref(gc);
892  gdk_gc_unref(pgc);
893 
894  return 0;
895  }
896 
897  if (transform.inverted) {
898  if (image->info->polarity == GERBV_POLARITY_POSITIVE)
899  polarity = GERBV_POLARITY_NEGATIVE;
900  else
901  polarity = GERBV_POLARITY_POSITIVE;
902  } else {
903  polarity = image->info->polarity;
904  }
905  if (drawMode == DRAW_SELECTIONS)
906  polarity = GERBV_POLARITY_POSITIVE;
907 
908  gboolean useOptimizations = TRUE;
909  // if the user is using any transformations for this layer, then don't bother using rendering
910  // optimizations
911  if (fabs(transform.translateX) > GERBV_PRECISION_LINEAR_INCH
912  || fabs(transform.translateY) > GERBV_PRECISION_LINEAR_INCH
913  || fabs(transform.scaleX - 1) > GERBV_PRECISION_LINEAR_INCH
914  || fabs(transform.scaleY - 1) > GERBV_PRECISION_LINEAR_INCH
915  || fabs(transform.rotation) > GERBV_PRECISION_ANGLE_RAD
916  || transform.mirrorAroundX || transform.mirrorAroundY)
917  useOptimizations = FALSE;
918 
919  // calculate the transformation matrix for the user_transformation options
920  cairo_matrix_t fullMatrix, scaleMatrix;
921  cairo_matrix_init (&fullMatrix, 1, 0, 0, 1, 0, 0);
922  cairo_matrix_init (&scaleMatrix, 1, 0, 0, 1, 0, 0);
923 
924  cairo_matrix_translate (&fullMatrix, trans_x, trans_y);
925  cairo_matrix_scale (&fullMatrix, scale, scale);
926  cairo_matrix_scale (&scaleMatrix, scale, scale);
927  /* offset image */
928 
929  cairo_matrix_translate (&fullMatrix, transform.translateX, -1*transform.translateY);
930  // don't use mirroring for the scale matrix
931  gdouble scaleX = transform.scaleX;
932  gdouble scaleY = -1*transform.scaleY;
933  cairo_matrix_scale (&scaleMatrix, scaleX, -1*scaleY);
934  if (transform.mirrorAroundX)
935  scaleY *= -1;
936  if (transform.mirrorAroundY)
937  scaleX *= -1;
938 
939  cairo_matrix_scale (&fullMatrix, scaleX, scaleY);
940  /* do image rotation */
941  cairo_matrix_rotate (&fullMatrix, transform.rotation);
942  //cairo_matrix_rotate (&scaleMatrix, transform.rotation);
943 
944  /* do image rotation */
945  cairo_matrix_rotate (&fullMatrix, image->info->imageRotation);
946 
947  if (useOptimizations) {
948  minX = renderInfo->lowerLeftX;
949  minY = renderInfo->lowerLeftY;
950  maxX = renderInfo->lowerLeftX + (renderInfo->displayWidth /
951  renderInfo->scaleFactorX);
952  maxY = renderInfo->lowerLeftY + (renderInfo->displayHeight /
953  renderInfo->scaleFactorY);
954  }
955 
956  /* Set up the two "colors" we have */
957  opaque.pixel = 0; /* opaque will not let color through */
958  transparent.pixel = 1; /* transparent will let color through */
959 
960  /*
961  * Clear clipmask and set draw color depending image on image polarity
962  */
963  if (polarity == GERBV_POLARITY_NEGATIVE) {
964  gdk_gc_set_foreground(gc, &transparent);
965  gdk_draw_rectangle(*pixmap, gc, TRUE, 0, 0, -1, -1);
966  gdk_gc_set_foreground(gc, &opaque);
967  } else {
968  gdk_gc_set_foreground(gc, &opaque);
969  gdk_draw_rectangle(*pixmap, gc, TRUE, 0, 0, -1, -1);
970  gdk_gc_set_foreground(gc, &transparent);
971  }
972  oldLayer = image->layers;
973  oldState = image->states;
974  for (net = image->netlist->next ; net != NULL; net = gerbv_image_return_next_renderable_object(net)) {
975  int repeat_X=1, repeat_Y=1;
976  double repeat_dist_X=0.0, repeat_dist_Y=0.0;
977  int repeat_i, repeat_j;
978 
979  /*
980  * If step_and_repeat (%SR%) used, repeat the drawing;
981  */
982  repeat_X = net->layer->stepAndRepeat.X;
983  repeat_Y = net->layer->stepAndRepeat.Y;
984  repeat_dist_X = net->layer->stepAndRepeat.dist_X;
985  repeat_dist_Y = net->layer->stepAndRepeat.dist_Y;
986 
987  /* check if this is a new netstate */
988  if (net->state != oldState){
989  /* it's a new state, so recalculate the new transformation matrix
990  for it */
991  draw_gdk_apply_netstate_transformation (&fullMatrix, &scaleMatrix, net->state);
992  oldState = net->state;
993  }
994  /* check if this is a new layer */
995  /* for now, only do layer rotations in GDK rendering */
996  if (net->layer != oldLayer){
997  cairo_matrix_rotate (&fullMatrix, net->layer->rotation);
998  oldLayer = net->layer;
999  }
1000 
1001  if (drawMode == DRAW_SELECTIONS) {
1002  gboolean foundNet = FALSE;
1003  gerbv_selection_item_t sItem;
1004 
1005  for (guint i = 0; i < selectionInfo->selectedNodeArray->len; i++) {
1006  sItem = g_array_index (selectionInfo->selectedNodeArray,
1007  gerbv_selection_item_t, i);
1008  if (sItem.net == net) {
1009  foundNet = TRUE;
1010  break;
1011  }
1012  }
1013  if (!foundNet)
1014  continue;
1015  }
1016 
1017  for(repeat_i = 0; repeat_i < repeat_X; repeat_i++) {
1018  for(repeat_j = 0; repeat_j < repeat_Y; repeat_j++) {
1019  double sr_x = repeat_i * repeat_dist_X;
1020  double sr_y = repeat_j * repeat_dist_Y;
1021 
1022  if ((useOptimizations)&&((net->boundingBox.right+sr_x < minX)
1023  || (net->boundingBox.left+sr_x > maxX)
1024  || (net->boundingBox.top+sr_y < minY)
1025  || (net->boundingBox.bottom+sr_y > maxY))) {
1026  continue;
1027  }
1028 
1029  /*
1030  * If circle segment, scale and translate that one too
1031  */
1032  if (net->cirseg) {
1033  tempX = net->cirseg->width;
1034  tempY = net->cirseg->height;
1035  cairo_matrix_transform_point (&scaleMatrix, &tempX, &tempY);
1036 
1037  /* Variables can be negative after transformation */
1038  tempX = fabs(tempX);
1039  tempY = fabs(tempY);
1040  cir_width = tempX;
1041  cir_height = tempY;
1042 
1043  tempX = net->cirseg->cp_x;
1044  tempY = net->cirseg->cp_y;
1045  cairo_matrix_transform_point (&fullMatrix, &tempX, &tempY);
1046  cp_x = (int)round(tempX);
1047  cp_y = (int)round(tempY);
1048  }
1049 
1050  /*
1051  * Set GdkFunction depending on if this (gerber) layer is inverted
1052  * and allow for the photoplot being negative.
1053  */
1054  gdk_gc_set_function(gc, GDK_COPY);
1055  if ((net->layer->polarity == GERBV_POLARITY_CLEAR) != (polarity == GERBV_POLARITY_NEGATIVE))
1056  gdk_gc_set_foreground(gc, &opaque);
1057  else
1058  gdk_gc_set_foreground(gc, &transparent);
1059 
1060  /*
1061  * Polygon Area Fill routines
1062  */
1063  switch (net->interpolation) {
1065  draw_gdk_render_polygon_object (net,image,sr_x,sr_y,&fullMatrix,
1066  &scaleMatrix,gc,pgc,pixmap);
1067  continue;
1068  /* make sure we completely skip over any deleted nodes */
1070  continue;
1071  default :
1072  break;
1073  }
1074 
1075 
1076  /*
1077  * If aperture state is off we allow use of undefined apertures.
1078  * This happens when gerber files starts, but hasn't decided on
1079  * which aperture to use.
1080  */
1081  if (image->aperture[net->aperture] == NULL) {
1082  /* Commenting this out since it gets emitted every time you click on the screen
1083  if (net->aperture_state != GERBV_APERTURE_STATE_OFF)
1084  GERB_MESSAGE("Aperture D%d is not defined", net->aperture);
1085  */
1086  continue;
1087  }
1088 
1089  /*
1090  * Scale points with window scaling and translate them
1091  */
1092  tempX = net->start_x + sr_x;
1093  tempY = net->start_y + sr_y;
1094  cairo_matrix_transform_point (&fullMatrix, &tempX, &tempY);
1095  xlong1 = (int)round(tempX);
1096  ylong1 = (int)round(tempY);
1097 
1098  tempX = net->stop_x + sr_x;
1099  tempY = net->stop_y + sr_y;
1100  cairo_matrix_transform_point (&fullMatrix, &tempX, &tempY);
1101  xlong2 = (int)round(tempX);
1102  ylong2 = (int)round(tempY);
1103 
1104  /* if the object is way outside our view window, just skip over it in order
1105  to eliminate some GDK clipping problems at high zoom levels */
1106  if ((xlong1 < -10000) && (xlong2 < -10000))
1107  continue;
1108  if ((ylong1 < -10000) && (ylong2 < -10000))
1109  continue;
1110  if ((xlong1 > 10000) && (xlong2 > 10000))
1111  continue;
1112  if ((ylong1 > 10000) && (ylong2 > 10000))
1113  continue;
1114 
1115  if (xlong1 > G_MAXINT) x1 = G_MAXINT;
1116  else if (xlong1 < G_MININT) x1 = G_MININT;
1117  else x1 = (int)xlong1;
1118 
1119  if (xlong2 > G_MAXINT) x2 = G_MAXINT;
1120  else if (xlong2 < G_MININT) x2 = G_MININT;
1121  else x2 = (int)xlong2;
1122 
1123  if (ylong1 > G_MAXINT) y1 = G_MAXINT;
1124  else if (ylong1 < G_MININT) y1 = G_MININT;
1125  else y1 = (int)ylong1;
1126 
1127  if (ylong2 > G_MAXINT) y2 = G_MAXINT;
1128  else if (ylong2 < G_MININT) y2 = G_MININT;
1129  else y2 = (int)ylong2;
1130 
1131  switch (net->aperture_state) {
1133  tempX = image->aperture[net->aperture]->parameter[0];
1134  cairo_matrix_transform_point (&scaleMatrix, &tempX, &tempY);
1135 
1136  /* Variables can be negative after transformation */
1137  tempX = fabs(tempX);
1138  p1 = (int)round(tempX);
1139 
1140  gdk_gc_set_line_attributes(gc, p1, GDK_LINE_SOLID,
1141  (image->aperture[net->aperture]->type == GERBV_APTYPE_RECTANGLE)?
1142  GDK_CAP_PROJECTING: GDK_CAP_ROUND,
1143  GDK_JOIN_MITER);
1144 
1145  switch (net->interpolation) {
1149  GERB_MESSAGE(_("Linear != x1"));
1150  gdk_gc_set_line_attributes(gc, p1,
1151  GDK_LINE_ON_OFF_DASH,
1152  GDK_CAP_ROUND,
1153  GDK_JOIN_MITER);
1154  gdk_draw_line(*pixmap, gc, x1, y1, x2, y2);
1155  gdk_gc_set_line_attributes(gc, p1,
1156  GDK_LINE_SOLID,
1157  GDK_CAP_ROUND,
1158  GDK_JOIN_MITER);
1159  break;
1161  if (image->aperture[net->aperture]->type != GERBV_APTYPE_RECTANGLE) {
1162  gdk_draw_line(*pixmap, gc, x1, y1, x2, y2);
1163 
1164  if (renderInfo->show_cross_on_drill_holes
1165  && image->layertype == GERBV_LAYERTYPE_DRILL) {
1166  /* Draw crosses on drill slot start and end */
1167  r = p1/2.0 + hole_cross_inc_px;
1168  draw_gdk_cross(*pixmap, gc, x1, y1, r);
1169  draw_gdk_cross(*pixmap, gc, x2, y2, r);
1170  }
1171  break;
1172  }
1173 
1174  gint dx, dy;
1175  GdkPoint poly[6];
1176 
1177  tempX = image->aperture[net->aperture]->parameter[0]/2;
1178  tempY = image->aperture[net->aperture]->parameter[1]/2;
1179  cairo_matrix_transform_point (&scaleMatrix, &tempX, &tempY);
1180  dx = (int)round(tempX);
1181  dy = (int)round(tempY);
1182 
1183  if(x1 > x2) dx = -dx;
1184  if(y1 > y2) dy = -dy;
1185  poly[0].x = x1 - dx; poly[0].y = y1 - dy;
1186  poly[1].x = x1 - dx; poly[1].y = y1 + dy;
1187  poly[2].x = x2 - dx; poly[2].y = y2 + dy;
1188  poly[3].x = x2 + dx; poly[3].y = y2 + dy;
1189  poly[4].x = x2 + dx; poly[4].y = y2 - dy;
1190  poly[5].x = x1 + dx; poly[5].y = y1 - dy;
1191  gdk_draw_polygon(*pixmap, gc, 1, poly, 6);
1192  break;
1193 
1196  gerbv_gdk_draw_arc(*pixmap, gc, cp_x, cp_y,
1197  cir_width, cir_height,
1198  net->cirseg->angle1 +
1199  RAD2DEG(transform.rotation),
1200  net->cirseg->angle2 +
1201  RAD2DEG(transform.rotation));
1202  break;
1203  default :
1204  GERB_COMPILE_WARNING(
1205  _("Skipped interpolation type %d"),
1206  net->interpolation);
1207  break;
1208  }
1209  break;
1211  break;
1213  tempX = image->aperture[net->aperture]->parameter[0];
1214  tempY = image->aperture[net->aperture]->parameter[1];
1215  cairo_matrix_transform_point (&scaleMatrix, &tempX, &tempY);
1216 
1217  /* Variables can be negative after transformation */
1218  tempX = fabs(tempX);
1219  tempY = fabs(tempY);
1220  p1 = (int)round(tempX);
1221  p2 = (int)round(tempY);
1222 
1223  switch (image->aperture[net->aperture]->type) {
1224  case GERBV_APTYPE_CIRCLE :
1225  gerbv_gdk_draw_circle(*pixmap, gc, TRUE, x2, y2, p1);
1226 
1227  if (renderInfo->show_cross_on_drill_holes
1228  && image->layertype == GERBV_LAYERTYPE_DRILL) {
1229  r = p1/2.0 + hole_cross_inc_px;
1230  draw_gdk_cross(*pixmap, gc, x2, y2, r);
1231  }
1232 
1233  /*
1234  * If circle has an inner diameter we must remove
1235  * that part of the circle to make a hole in it.
1236  * We should actually support square holes too,
1237  * but due to laziness I don't.
1238  */
1239  if (p2) {
1240  gdk_gc_get_values(gc, &gc_values);
1241  if (gc_values.foreground.pixel == opaque.pixel) {
1242  gdk_gc_set_foreground(gc, &transparent);
1243  gerbv_gdk_draw_circle(*pixmap, gc, TRUE, x2, y2, p2);
1244  gdk_gc_set_foreground(gc, &opaque);
1245  } else {
1246  gdk_gc_set_foreground(gc, &opaque);
1247  gerbv_gdk_draw_circle(*pixmap, gc, TRUE, x2, y2, p2);
1248  gdk_gc_set_foreground(gc, &transparent);
1249  }
1250  }
1251 
1252  break;
1254  gerbv_gdk_draw_rectangle(*pixmap, gc, TRUE,
1255  x2, y2, p1, p2, RAD2DEG(transform.rotation +
1256  image->info->imageRotation));
1257  break;
1258  case GERBV_APTYPE_OVAL :
1259  gerbv_gdk_draw_oval(*pixmap, gc, TRUE,
1260  x2, y2, p1, p2, RAD2DEG(transform.rotation +
1261  image->info->imageRotation));
1262  break;
1263  case GERBV_APTYPE_POLYGON :
1264  /* TODO: gdk_draw_polygon() */
1265  gerbv_gdk_draw_circle(*pixmap, gc, TRUE, x2, y2, p1);
1266  break;
1267  case GERBV_APTYPE_MACRO :
1268  /* TODO: check line22 and others */
1269  gerbv_gdk_draw_amacro(*pixmap, gc,
1270  image->aperture[net->aperture]->simplified,
1271  scale, x2, y2);
1272  break;
1273  default :
1274  GERB_MESSAGE(_("Unknown aperture type %d"),
1275  image->aperture[net->aperture]->type);
1276  return 0;
1277  }
1278  break;
1279  default :
1280  GERB_MESSAGE(_("Unknown aperture state %d"),
1281  net->aperture_state);
1282  return 0;
1283  }
1284  }
1285  }
1286  }
1287  /*
1288  * Destroy GCs before exiting
1289  */
1290  gdk_gc_unref(gc);
1291  gdk_gc_unref(pgc);
1292 
1293  return 1;
1294 
1295 } /* image2pixmap */
1296 
1297 
Header info for the GDK rendering functions.
gerbv_net_t * gerbv_image_return_next_renderable_object(gerbv_net_t *oldNet)
Return the next net entry which corresponds to a unique visible object.
Definition: gerb_image.c:1345
const char * gerbv_aperture_type_name(gerbv_aperture_type_t type)
Return string name of gerbv_aperture_type_t aperture type.
Definition: gerbv.c:72
The main header file for the libgerbv library.
@ GERBV_APERTURE_STATE_OFF
Definition: gerbv.h:178
@ GERBV_APERTURE_STATE_ON
Definition: gerbv.h:179
@ GERBV_APERTURE_STATE_FLASH
Definition: gerbv.h:180
gerbv_polarity_t
Definition: gerbv.h:281
@ GERBV_POLARITY_CLEAR
Definition: gerbv.h:284
@ GERBV_POLARITY_NEGATIVE
Definition: gerbv.h:282
@ GERBV_POLARITY_POSITIVE
Definition: gerbv.h:281
@ GERBV_APTYPE_MACRO_LINE20
Definition: gerbv.h:170
@ GERBV_APTYPE_MACRO_LINE21
Definition: gerbv.h:171
@ GERBV_APTYPE_OVAL
Definition: gerbv.h:162
@ GERBV_APTYPE_MACRO_OUTLINE
Definition: gerbv.h:166
@ GERBV_APTYPE_MACRO_CIRCLE
Definition: gerbv.h:165
@ GERBV_APTYPE_MACRO
Definition: gerbv.h:164
@ GERBV_APTYPE_CIRCLE
Definition: gerbv.h:160
@ GERBV_APTYPE_POLYGON
Definition: gerbv.h:163
@ GERBV_APTYPE_MACRO_POLYGON
Definition: gerbv.h:167
@ GERBV_APTYPE_RECTANGLE
Definition: gerbv.h:161
@ GERBV_APTYPE_MACRO_THERMAL
Definition: gerbv.h:169
@ GERBV_APTYPE_MACRO_LINE22
Definition: gerbv.h:172
@ GERBV_APTYPE_MACRO_MOIRE
Definition: gerbv.h:168
@ GERBV_INTERPOLATION_LINEARx01
Definition: gerbv.h:304
@ GERBV_INTERPOLATION_PAREA_START
Definition: gerbv.h:308
@ GERBV_INTERPOLATION_LINEARx001
Definition: gerbv.h:305
@ GERBV_INTERPOLATION_DELETED
Definition: gerbv.h:310
@ GERBV_INTERPOLATION_CW_CIRCULAR
Definition: gerbv.h:306
@ GERBV_INTERPOLATION_PAREA_END
Definition: gerbv.h:309
@ GERBV_INTERPOLATION_LINEARx10
Definition: gerbv.h:303
@ GERBV_INTERPOLATION_CCW_CIRCULAR
Definition: gerbv.h:307
@ GERBV_INTERPOLATION_LINEARx1
Definition: gerbv.h:302
@ GERBV_LAYERTYPE_DRILL
Definition: gerbv.h:329
gerbv_layer_t * layers
Definition: gerbv.h:724
gerbv_layertype_t layertype
Definition: gerbv.h:722
gerbv_net_t * netlist
Definition: gerbv.h:729
gerbv_aperture_t * aperture[APERTURE_MAX]
Definition: gerbv.h:723
gerbv_netstate_t * states
Definition: gerbv.h:725
gerbv_image_info_t * info
Definition: gerbv.h:728
gerbv_step_and_repeat_t stepAndRepeat
Definition: gerbv.h:635
gerbv_polarity_t polarity
Definition: gerbv.h:638
gdouble rotation
Definition: gerbv.h:637
gerbv_render_size_t boundingBox
Definition: gerbv.h:661
gerbv_layer_t * layer
Definition: gerbv.h:668
double stop_y
Definition: gerbv.h:660
gerbv_aperture_state_t aperture_state
Definition: gerbv.h:663
double stop_x
Definition: gerbv.h:659
double start_x
Definition: gerbv.h:657
gerbv_netstate_t * state
Definition: gerbv.h:669
struct gerbv_net * next
Definition: gerbv.h:666
double start_y
Definition: gerbv.h:658
gerbv_interpolation_t interpolation
Definition: gerbv.h:664
gerbv_cirseg_t * cirseg
Definition: gerbv.h:665
int aperture
Definition: gerbv.h:662
gdouble offsetB
Definition: gerbv.h:649
gdouble scaleA
Definition: gerbv.h:650
gdouble scaleB
Definition: gerbv.h:651
gerbv_axis_select_t axisSelect
Definition: gerbv.h:645
gdouble offsetA
Definition: gerbv.h:648
gerbv_mirror_state_t mirrorState
Definition: gerbv.h:646
gdouble lowerLeftY
Definition: gerbv.h:778
gboolean show_cross_on_drill_holes
Definition: gerbv.h:782
gdouble scaleFactorX
Definition: gerbv.h:775
gint displayHeight
Definition: gerbv.h:781
gdouble lowerLeftX
Definition: gerbv.h:777
gdouble scaleFactorY
Definition: gerbv.h:776