00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <math.h>
00036
00037 #ifdef HAVE_STRING_H
00038 #include <string.h>
00039 #endif
00040
00041 #include <gtk/gtk.h>
00042 #include "gerbv.h"
00043 #include "draw-gdk.h"
00044
00045 #undef round
00046 #define round(x) ceil((double)(x))
00047
00048 #define dprintf if(DEBUG) printf
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static GdkPoint
00063 rotate_point(GdkPoint point, int angle)
00064 {
00065 double sint, cost;
00066 GdkPoint returned;
00067
00068 if (angle == 0)
00069 return point;
00070
00071 sint = sin(-(double)angle * M_PI / 180.0);
00072 cost = cos(-(double)angle * M_PI / 180.0);
00073
00074 returned.x = (int)round(cost * (double)point.x - sint * (double)point.y);
00075 returned.y = (int)round(sint * (double)point.x + cost * (double)point.y);
00076
00077 return returned;
00078 }
00079
00080
00081
00082
00083
00084 static void
00085 gerbv_gdk_draw_prim1(GdkPixmap *pixmap, GdkGC *gc, double *p,
00086 double scale, gint x, gint y)
00087 {
00088 const int exposure_idx = 0;
00089 const int diameter_idx = 1;
00090 const int x_offset_idx = 2;
00091 const int y_offset_idx = 3;
00092 const gint full_circle = 23360;
00093 GdkGC *local_gc = gdk_gc_new(pixmap);
00094 gint dia = round(fabs(p[diameter_idx] * scale));
00095 gint real_x = x - dia / 2;
00096 gint real_y = y - dia / 2;
00097 GdkColor color;
00098
00099 gdk_gc_copy(local_gc, gc);
00100
00101 real_x += (int)(p[x_offset_idx] * (double)scale);
00102 real_y -= (int)(p[y_offset_idx] * (double)scale);
00103
00104
00105 if (p[exposure_idx] == 0.0) {
00106 color.pixel = 0;
00107 gdk_gc_set_foreground(local_gc, &color);
00108 }
00109
00110 gdk_gc_set_line_attributes(local_gc,
00111 1,
00112 GDK_LINE_SOLID,
00113 GDK_CAP_BUTT,
00114 GDK_JOIN_MITER);
00115
00116
00117
00118
00119 gdk_draw_arc(pixmap, local_gc, 1, real_x, real_y, dia, dia,
00120 0, full_circle);
00121
00122 gdk_gc_unref(local_gc);
00123
00124 return;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 static void
00134 gerbv_gdk_draw_prim4(GdkPixmap *pixmap, GdkGC *gc, double *p,
00135 double scale, gint x, gint y)
00136 {
00137 const int exposure_idx = 0;
00138 const int nuf_points_idx = 1;
00139 const int first_x_idx = 2;
00140 const int first_y_idx = 3;
00141 const int rotext_idx = 4;
00142 GdkGC *local_gc = gdk_gc_new(pixmap);
00143 int nuf_points, point;
00144 double rotation;
00145 GdkPoint *points;
00146 GdkColor color;
00147
00148
00149 nuf_points = (int)p[nuf_points_idx] + 1;
00150 points = (GdkPoint *)g_malloc(sizeof(GdkPoint) * nuf_points);
00151 if (!points) {
00152 g_free(points);
00153 return;
00154 }
00155
00156 rotation = p[(nuf_points - 1) * 2 + rotext_idx];
00157 for (point = 0; point < nuf_points; point++) {
00158 points[point].x = (int)round(scale * p[point * 2 + first_x_idx]);
00159 points[point].y = -(int)round(scale * p[point * 2 + first_y_idx]);
00160 if (rotation != 0.0)
00161 points[point] = rotate_point(points[point], rotation);
00162 points[point].x += x;
00163 points[point].y += y;
00164 }
00165
00166 gdk_gc_copy(local_gc, gc);
00167
00168
00169 if (p[exposure_idx] == 0.0) {
00170 color.pixel = 0;
00171 gdk_gc_set_foreground(local_gc, &color);
00172 }
00173
00174 gdk_gc_set_line_attributes(local_gc,
00175 1,
00176 GDK_LINE_SOLID,
00177 GDK_CAP_BUTT,
00178 GDK_JOIN_MITER);
00179 gdk_draw_polygon(pixmap, local_gc, 1, points, nuf_points);
00180
00181 g_free(points);
00182
00183 gdk_gc_unref(local_gc);
00184
00185 return;
00186 }
00187
00188
00189
00190
00191
00192 static void
00193 gerbv_gdk_draw_prim5(GdkPixmap *pixmap, GdkGC *gc, double *p,
00194 double scale, gint x, gint y)
00195 {
00196 const int exposure_idx = 0;
00197 const int nuf_vertices_idx = 1;
00198 const int center_x_idx = 2;
00199 const int center_y_idx = 3;
00200 const int diameter_idx = 4;
00201 const int rotation_idx = 5;
00202 int nuf_vertices, i;
00203 double vertex, tick, rotation, radius;
00204 GdkPoint *points;
00205 GdkGC *local_gc = gdk_gc_new(pixmap);
00206 GdkColor color;
00207
00208 nuf_vertices = (int)p[nuf_vertices_idx];
00209 points = (GdkPoint *)g_malloc(sizeof(GdkPoint) * nuf_vertices);
00210 if (!points) {
00211 g_free(points);
00212 return;
00213 }
00214
00215 gdk_gc_copy(local_gc, gc);
00216
00217
00218 if (p[exposure_idx] == 0.0) {
00219 color.pixel = 0;
00220 gdk_gc_set_foreground(local_gc, &color);
00221 }
00222
00223 tick = 2 * M_PI / (double)nuf_vertices;
00224 rotation = -p[rotation_idx] * M_PI / 180.0;
00225 radius = p[diameter_idx] / 2.0;
00226 for (i = 0; i < nuf_vertices; i++) {
00227 vertex = tick * (double)i + rotation;
00228 points[i].x = (int)round(scale * radius * cos(vertex)) + x +
00229 p[center_x_idx];
00230 points[i].y = (int)round(scale * radius * sin(vertex)) + y +
00231 p[center_y_idx];
00232 }
00233
00234 gdk_draw_polygon(pixmap, local_gc, 1, points, nuf_vertices);
00235
00236 gdk_gc_unref(local_gc);
00237
00238 g_free(points);
00239 return;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 static void
00250 gerbv_gdk_draw_prim6(GdkPixmap *pixmap, GdkGC *gc, double *p,
00251 double scale, gint x, gint y)
00252 {
00253 const int outside_dia_idx = 2;
00254 const int ci_thickness_idx = 3;
00255 const int gap_idx = 4;
00256 const int nuf_circles_idx = 5;
00257 const int ch_thickness_idx = 6;
00258 const int ch_length_idx = 7;
00259 const int rotation_idx = 8;
00260 GdkGC *local_gc = gdk_gc_new(pixmap);
00261 double real_dia;
00262 double real_gap;
00263 int circle;
00264 GdkPoint crosshair[4];
00265 int point;
00266
00267 gdk_gc_copy(local_gc, gc);
00268 gdk_gc_set_line_attributes(local_gc,
00269 (int)round(scale * p[ci_thickness_idx]),
00270 GDK_LINE_SOLID,
00271 GDK_CAP_BUTT,
00272 GDK_JOIN_MITER);
00273
00274 real_dia = p[outside_dia_idx] - p[ci_thickness_idx] / 2.0;
00275 real_gap = p[gap_idx] + p[ci_thickness_idx];
00276
00277 for (circle = 0; circle != (int)p[nuf_circles_idx]; circle++) {
00278
00279
00280
00281 const gint full_circle = 23360;
00282 gint dia = (real_dia - real_gap * circle) * scale;
00283 gdk_draw_arc(pixmap, local_gc, 0, x - dia / 2, y - dia / 2,
00284 dia, dia, 0, full_circle);
00285
00286 }
00287
00288
00289
00290
00291 memset(crosshair, 0, sizeof(GdkPoint) * 4);
00292 crosshair[0].x = (int)((p[ch_length_idx] / 2.0) * scale);
00293
00294 crosshair[1].x = -crosshair[0].x;
00295
00296
00297 crosshair[2].y = crosshair[0].x;
00298
00299 crosshair[3].y = -crosshair[0].x;
00300
00301 gdk_gc_set_line_attributes(local_gc,
00302 (int)round(scale * p[ch_thickness_idx]),
00303 GDK_LINE_SOLID,
00304 GDK_CAP_BUTT,
00305 GDK_JOIN_MITER);
00306
00307 for (point = 0; point < 4; point++) {
00308 crosshair[point] = rotate_point(crosshair[point],
00309 p[rotation_idx]);
00310 crosshair[point].x += x;
00311 crosshair[point].y += y;
00312 }
00313 gdk_draw_line(pixmap, local_gc,
00314 crosshair[0].x, crosshair[0].y,
00315 crosshair[1].x, crosshair[1].y);
00316 gdk_draw_line(pixmap, local_gc,
00317 crosshair[2].x, crosshair[2].y,
00318 crosshair[3].x, crosshair[3].y);
00319
00320 gdk_gc_unref(local_gc);
00321
00322 return;
00323 }
00324
00325
00326 static void
00327 gerbv_gdk_draw_prim7(GdkPixmap *pixmap, GdkGC *gc, double *p,
00328 double scale, gint x, gint y)
00329 {
00330 const int outside_dia_idx = 2;
00331 const int inside_dia_idx = 3;
00332 const int ch_thickness_idx = 4;
00333 const int rotation_idx = 5;
00334 const gint full_circle = 23360;
00335 GdkGCValues gc_val;
00336 int diameter, i;
00337 GdkGC *local_gc = gdk_gc_new(pixmap);
00338 GdkPoint point[4];
00339 double ci_thickness = (p[outside_dia_idx] -
00340 p[inside_dia_idx]) / 2.0;
00341
00342 gdk_gc_copy(local_gc, gc);
00343 gdk_gc_set_line_attributes(local_gc,
00344 (int)round(scale * ci_thickness),
00345 GDK_LINE_SOLID,
00346 GDK_CAP_BUTT,
00347 GDK_JOIN_MITER);
00348
00349
00350
00351
00352 diameter = (p[inside_dia_idx] + ci_thickness) * scale;
00353 gdk_draw_arc(pixmap, local_gc, 0, x - diameter / 2, y - diameter / 2,
00354 diameter, diameter, 0, full_circle);
00355
00356
00357
00358
00359
00360
00361
00362
00363 for (i = 0; i < 4; i++) {
00364 point[i].x = round((p[outside_dia_idx] / 2.0) * scale) + 2;
00365 point[i].y = 0;
00366 point[i] = rotate_point(point[i], p[rotation_idx] + 90 * i);
00367 point[i].x += x;
00368 point[i].y += y;
00369 }
00370
00371 gdk_gc_set_line_attributes(local_gc,
00372 (int)round(scale * p[ch_thickness_idx]),
00373 GDK_LINE_SOLID,
00374 GDK_CAP_BUTT,
00375 GDK_JOIN_MITER);
00376
00377
00378 gdk_gc_get_values(local_gc, &gc_val);
00379 if (gc_val.foreground.pixel == 1)
00380 gc_val.foreground.pixel = 0;
00381 else
00382 gc_val.foreground.pixel = 1;
00383 gdk_gc_set_foreground(local_gc, &(gc_val.foreground));
00384
00385
00386 gdk_draw_line(pixmap, local_gc,
00387 point[0].x, point[0].y, point[2].x, point[2].y);
00388 gdk_draw_line(pixmap, local_gc,
00389 point[1].x, point[1].y, point[3].x, point[3].y);
00390
00391 gdk_gc_unref(local_gc);
00392
00393 return;
00394 }
00395
00396
00397
00398
00399
00400 static void
00401 gerbv_gdk_draw_prim20(GdkPixmap *pixmap, GdkGC *gc, double *p,
00402 double scale, gint x, gint y)
00403 {
00404 const int exposure_idx = 0;
00405 const int linewidth_idx = 1;
00406 const int start_x_idx = 2;
00407 const int start_y_idx = 3;
00408 const int end_x_idx = 4;
00409 const int end_y_idx = 5;
00410 const int rotation_idx = 6;
00411 const int nuf_points = 2;
00412 GdkGC *local_gc = gdk_gc_new(pixmap);
00413 GdkPoint points[nuf_points];
00414 GdkColor color;
00415 int i;
00416
00417 gdk_gc_copy(local_gc, gc);
00418
00419
00420 if (p[exposure_idx] == 0.0) {
00421 color.pixel = 0;
00422 gdk_gc_set_foreground(local_gc, &color);
00423 }
00424
00425 gdk_gc_set_line_attributes(local_gc,
00426 (int)round(scale * p[linewidth_idx]),
00427 GDK_LINE_SOLID,
00428 GDK_CAP_BUTT,
00429 GDK_JOIN_MITER);
00430
00431 points[0].x = (p[start_x_idx] * scale);
00432 points[0].y = (p[start_y_idx] * scale);
00433 points[1].x = (p[end_x_idx] * scale);
00434 points[1].y = (p[end_y_idx] * scale);
00435
00436 for (i = 0; i < nuf_points; i++) {
00437 points[i] = rotate_point(points[i], -p[rotation_idx]);
00438 points[i].x = x + points[i].x;
00439 points[i].y = y - points[i].y;
00440 }
00441
00442 gdk_draw_line(pixmap, local_gc,
00443 points[0].x, points[0].y,
00444 points[1].x, points[1].y);
00445
00446 gdk_gc_unref(local_gc);
00447
00448 return;
00449 }
00450
00451
00452 static void
00453 gerbv_gdk_draw_prim21(GdkPixmap *pixmap, GdkGC *gc, double *p,
00454 double scale, gint x, gint y)
00455 {
00456 const int exposure_idx = 0;
00457 const int width_idx = 1;
00458 const int height_idx = 2;
00459 const int exp_x_idx = 3;
00460 const int exp_y_idx = 4;
00461 const int rotation_idx = 5;
00462 const int nuf_points = 4;
00463 GdkPoint points[nuf_points];
00464 GdkColor color;
00465 GdkGC *local_gc = gdk_gc_new(pixmap);
00466 int half_width, half_height;
00467 int i;
00468
00469 half_width = (int)round(p[width_idx] * scale / 2.0);
00470 half_height =(int)round(p[height_idx] * scale / 2.0);
00471
00472 points[0].x = half_width;
00473 points[0].y = half_height;
00474
00475 points[1].x = half_width;
00476 points[1].y = -half_height;
00477
00478 points[2].x = -half_width;
00479 points[2].y = -half_height;
00480
00481 points[3].x = -half_width;
00482 points[3].y = half_height;
00483
00484 for (i = 0; i < nuf_points; i++) {
00485 points[i] = rotate_point(points[i], p[rotation_idx]);
00486 points[i].x += (x + (int)(p[exp_x_idx] * scale));
00487 points[i].y += (y - (int)(p[exp_y_idx] * scale));
00488 }
00489
00490 gdk_gc_copy(local_gc, gc);
00491
00492
00493 if (p[exposure_idx] == 0.0) {
00494 color.pixel = 0;
00495 gdk_gc_set_foreground(local_gc, &color);
00496 }
00497
00498 gdk_draw_polygon(pixmap, local_gc, 1, points, nuf_points);
00499
00500 gdk_gc_unref(local_gc);
00501
00502 return;
00503 }
00504
00505
00506
00507
00508
00509 static void
00510 gerbv_gdk_draw_prim22(GdkPixmap *pixmap, GdkGC *gc, double *p,
00511 double scale, gint x, gint y)
00512 {
00513 const int exposure_idx = 0;
00514 const int width_idx = 1;
00515 const int height_idx = 2;
00516 const int x_lower_left_idx = 3;
00517 const int y_lower_left_idx = 4;
00518 const int rotation_idx = 5;
00519 const int nuf_points = 4;
00520 GdkPoint points[nuf_points];
00521 GdkGC *local_gc = gdk_gc_new(pixmap);
00522 GdkColor color;
00523 int i;
00524
00525 points[0].x = (int)round(p[x_lower_left_idx] * scale);
00526 points[0].y = (int)round(p[y_lower_left_idx] * scale);
00527
00528 points[1].x = (int)round((p[x_lower_left_idx] + p[width_idx])
00529 * scale);
00530 points[1].y = (int)round(p[y_lower_left_idx] * scale);
00531
00532 points[2].x = (int)round((p[x_lower_left_idx] + p[width_idx])
00533 * scale);
00534 points[2].y = (int)round((p[y_lower_left_idx] - p[height_idx])
00535 * scale);
00536
00537 points[3].x = (int)round(p[x_lower_left_idx] * scale);
00538 points[3].y = (int)round((p[y_lower_left_idx] - p[height_idx])
00539 * scale);
00540
00541 for (i = 0; i < nuf_points; i++) {
00542 points[i] = rotate_point(points[i], p[rotation_idx]);
00543 points[i].x += x;
00544 points[i].y += y;
00545 }
00546
00547 gdk_gc_copy(local_gc, gc);
00548
00549
00550 if (p[exposure_idx] == 0.0) {
00551 color.pixel = 0;
00552 gdk_gc_set_foreground(local_gc, &color);
00553 }
00554
00555 gdk_draw_polygon(pixmap, local_gc, 1, points, nuf_points);
00556
00557 gdk_gc_unref(local_gc);
00558
00559 return;
00560 }
00561
00562
00563 static void
00564 gerbv_gdk_draw_amacro(GdkPixmap *pixmap, GdkGC *gc,
00565 gerbv_simplified_amacro_t *s, double scale,
00566 gint x, gint y)
00567 {
00568 gerbv_simplified_amacro_t *ls = s;
00569
00570 dprintf("Drawing simplified aperture macros:\n");
00571 while (ls != NULL) {
00572
00573 switch (ls->type) {
00574 case GERBV_APTYPE_MACRO_CIRCLE:
00575 gerbv_gdk_draw_prim1(pixmap, gc, ls->parameter, scale, x, y);
00576 dprintf(" Circle\n");
00577 break;
00578 case GERBV_APTYPE_MACRO_OUTLINE:
00579 gerbv_gdk_draw_prim4(pixmap, gc, ls->parameter, scale, x, y);
00580 dprintf(" Outline\n");
00581 break;
00582 case GERBV_APTYPE_MACRO_POLYGON:
00583 gerbv_gdk_draw_prim5(pixmap, gc, ls->parameter, scale, x, y);
00584 dprintf(" Polygon\n");
00585 break;
00586 case GERBV_APTYPE_MACRO_MOIRE:
00587 gerbv_gdk_draw_prim6(pixmap, gc, ls->parameter, scale, x, y);
00588 dprintf(" Moiré\n");
00589 break;
00590 case GERBV_APTYPE_MACRO_THERMAL:
00591 gerbv_gdk_draw_prim7(pixmap, gc, ls->parameter, scale, x, y);
00592 dprintf(" Thermal\n");
00593 break;
00594 case GERBV_APTYPE_MACRO_LINE20:
00595 gerbv_gdk_draw_prim20(pixmap, gc, ls->parameter, scale, x, y);
00596 dprintf(" Line 20\n");
00597 break;
00598 case GERBV_APTYPE_MACRO_LINE21:
00599 gerbv_gdk_draw_prim21(pixmap, gc, ls->parameter, scale, x, y);
00600 dprintf(" Line 21\n");
00601 break;
00602 case GERBV_APTYPE_MACRO_LINE22:
00603 gerbv_gdk_draw_prim22(pixmap, gc, ls->parameter, scale, x, y);
00604 dprintf(" Line 22\n");
00605 break;
00606 default:
00607 GERB_FATAL_ERROR("Unknown simplified aperture macro");
00608 }
00609
00610 ls = ls->next;
00611 }
00612
00613 }
00614
00615
00616
00617
00618
00619 static void
00620 gerbv_gdk_draw_circle(GdkPixmap *pixmap, GdkGC *gc,
00621 gint filled, gint x, gint y, gint dia)
00622 {
00623 static const gint full_circle = 23360;
00624 gint real_x = x - dia / 2;
00625 gint real_y = y - dia / 2;
00626
00627 gdk_draw_arc(pixmap, gc, filled, real_x, real_y, dia, dia, 0, full_circle);
00628
00629 return;
00630 }
00631
00632
00633
00634
00635
00636 static void
00637 gerbv_gdk_draw_rectangle(GdkPixmap *pixmap, GdkGC *gc,
00638 gint filled, gint x, gint y, gint x_side, gint y_side)
00639 {
00640
00641 gint real_x = x - x_side / 2;
00642 gint real_y = y - y_side / 2;
00643
00644 gdk_draw_rectangle(pixmap, gc, filled, real_x, real_y, x_side, y_side);
00645
00646 return;
00647 }
00648
00649
00650
00651
00652
00653 static void
00654 gerbv_gdk_draw_oval(GdkPixmap *pixmap, GdkGC *gc,
00655 gint filled, gint x, gint y, gint x_axis, gint y_axis)
00656 {
00657 gint delta = 0;
00658 GdkGC *local_gc = gdk_gc_new(pixmap);
00659
00660 gdk_gc_copy(local_gc, gc);
00661
00662 if (x_axis > y_axis) {
00663
00664 delta = x_axis / 2 - y_axis / 2;
00665 gdk_gc_set_line_attributes(local_gc, y_axis,
00666 GDK_LINE_SOLID,
00667 GDK_CAP_ROUND,
00668 GDK_JOIN_MITER);
00669 gdk_draw_line(pixmap, local_gc, x - delta, y, x + delta, y);
00670 } else {
00671
00672 delta = y_axis / 2 - x_axis / 2;
00673 gdk_gc_set_line_attributes(local_gc, x_axis,
00674 GDK_LINE_SOLID,
00675 GDK_CAP_ROUND,
00676 GDK_JOIN_MITER);
00677 gdk_draw_line(pixmap, local_gc, x, y - delta, x, y + delta);
00678 }
00679
00680 gdk_gc_unref(local_gc);
00681
00682 return;
00683 }
00684
00685
00686
00687
00688
00689
00690
00691 static void
00692 gerbv_gdk_draw_arc(GdkPixmap *pixmap, GdkGC *gc,
00693 int x, int y,
00694 int width, int height,
00695 double angle1, double angle2)
00696 {
00697 gint real_x = x - width / 2;
00698 gint real_y = y - height / 2;
00699
00700 gdk_draw_arc(pixmap, gc, FALSE, real_x, real_y, width, height,
00701 (gint)(angle1 * 64.0), (gint)(angle2 - angle1) * 64.0);
00702
00703 return;
00704 }
00705
00706 void
00707 draw_gdk_render_polygon_object (gerbv_net_t *oldNet, gerbv_image_t *image, double sr_x, double sr_y,
00708 double unit_scale, double trans_x, double trans_y, GdkGC *gc, GdkGC *pgc,
00709 GdkPixmap **pixmap) {
00710 gerbv_net_t *currentNet;
00711 gint x1,x2,y1,y2,cp_x=0,cp_y=0,cir_width=0,cir_height=0;
00712 GdkPoint *points = NULL;
00713 int pointArraySize=0;
00714 int curr_point_idx = 0;
00715 int steps,i;
00716 double angleDiff;
00717
00718
00719
00720 curr_point_idx = 0;
00721 pointArraySize = 0;
00722
00723 for (currentNet = oldNet->next; currentNet!=NULL; currentNet = currentNet->next){
00724 x1 = (int)round((image->info->offsetA + currentNet->start_x + sr_x) * unit_scale + trans_x);
00725 y1 = (int)round((-image->info->offsetB - currentNet->start_y - sr_y) * unit_scale + trans_y);
00726 x2 = (int)round((image->info->offsetA + currentNet->stop_x + sr_x) * unit_scale + trans_x);
00727 y2 = (int)round((-image->info->offsetB - currentNet->stop_y - sr_y) * unit_scale + trans_y);
00728
00729
00730
00731
00732 if (currentNet->cirseg) {
00733 cir_width = (int)round(currentNet->cirseg->width * unit_scale);
00734 cir_height = (int)round(currentNet->cirseg->height * unit_scale);
00735 cp_x = (int)round((image->info->offsetA + currentNet->cirseg->cp_x) *
00736 unit_scale + trans_x);
00737 cp_y = (int)round((image->info->offsetB - currentNet->cirseg->cp_y) *
00738 unit_scale + trans_y);
00739 }
00740
00741 switch (currentNet->interpolation) {
00742 case GERBV_INTERPOLATION_x10 :
00743 case GERBV_INTERPOLATION_LINEARx01 :
00744 case GERBV_INTERPOLATION_LINEARx001 :
00745 case GERBV_INTERPOLATION_LINEARx1 :
00746 if (pointArraySize < (curr_point_idx + 1)) {
00747 points = (GdkPoint *)g_realloc(points,sizeof(GdkPoint) * (curr_point_idx + 1));
00748 pointArraySize = (curr_point_idx + 1);
00749 }
00750 points[curr_point_idx].x = x2;
00751 points[curr_point_idx].y = y2;
00752 curr_point_idx++;
00753 break;
00754 case GERBV_INTERPOLATION_CW_CIRCULAR :
00755 case GERBV_INTERPOLATION_CCW_CIRCULAR :
00756
00757
00758 angleDiff = currentNet->cirseg->angle2 - currentNet->cirseg->angle1;
00759 steps = (int) abs(angleDiff);
00760 if (pointArraySize < (curr_point_idx + steps)) {
00761 points = (GdkPoint *)g_realloc(points,sizeof(GdkPoint) * (curr_point_idx + steps));
00762 pointArraySize = (curr_point_idx + steps);
00763 }
00764 for (i=0; i<steps; i++){
00765 points[curr_point_idx].x = cp_x + cir_width / 2.0 * cos ((currentNet->cirseg->angle1 +
00766 (angleDiff * i) / steps)*M_PI/180);
00767 points[curr_point_idx].y = cp_y - cir_width / 2.0 * sin ((currentNet->cirseg->angle1 +
00768 (angleDiff * i) / steps)*M_PI/180);
00769 curr_point_idx++;
00770 }
00771 break;
00772 case GERBV_INTERPOLATION_PAREA_END :
00773 gdk_gc_copy(pgc, gc);
00774 gdk_gc_set_line_attributes(pgc, 1,
00775 GDK_LINE_SOLID,
00776 GDK_CAP_PROJECTING,
00777 GDK_JOIN_MITER);
00778 gdk_draw_polygon(*pixmap, pgc, 1, points, curr_point_idx);
00779 g_free(points);
00780 points = NULL;
00781 return;
00782 default:
00783 break;
00784 }
00785 }
00786 return;
00787 }
00788
00789
00790
00791
00792 int
00793 draw_gdk_image_to_pixmap(GdkPixmap **pixmap, gerbv_image_t *image,
00794 double scale, double trans_x, double trans_y,
00795 gerbv_polarity_t polarity, gchar drawMode, gerbv_selection_info_t *selectionInfo)
00796 {
00797 GdkGC *gc = gdk_gc_new(*pixmap);
00798 GdkGC *pgc = gdk_gc_new(*pixmap);
00799 GdkGCValues gc_values;
00800 struct gerbv_net *net;
00801 gint x1, y1, x2, y2;
00802 int p1, p2, p3;
00803 int cir_width = 0, cir_height = 0;
00804 int cp_x = 0, cp_y = 0;
00805 double unit_scale;
00806 GdkColor transparent, opaque;
00807
00808
00809 if (image == NULL || image->netlist == NULL) {
00810
00811
00812
00813 gdk_gc_unref(gc);
00814 gdk_gc_unref(pgc);
00815
00816 return 0;
00817 }
00818
00819
00820 opaque.pixel = 0;
00821 transparent.pixel = 1;
00822
00823
00824
00825
00826 if (polarity == GERBV_POLARITY_NEGATIVE) {
00827 gdk_gc_set_foreground(gc, &transparent);
00828 gdk_draw_rectangle(*pixmap, gc, TRUE, 0, 0, -1, -1);
00829 gdk_gc_set_foreground(gc, &opaque);
00830 } else {
00831 gdk_gc_set_foreground(gc, &opaque);
00832 gdk_draw_rectangle(*pixmap, gc, TRUE, 0, 0, -1, -1);
00833 gdk_gc_set_foreground(gc, &transparent);
00834 }
00835
00836 for (net = image->netlist->next ; net != NULL; net = gerbv_image_return_next_renderable_object(net)) {
00837 int repeat_X=1, repeat_Y=1;
00838 double repeat_dist_X=0.0, repeat_dist_Y=0.0;
00839 int repeat_i, repeat_j;
00840
00841
00842
00843
00844 repeat_X = net->layer->stepAndRepeat.X;
00845 repeat_Y = net->layer->stepAndRepeat.Y;
00846 repeat_dist_X = net->layer->stepAndRepeat.dist_X;
00847 repeat_dist_Y = net->layer->stepAndRepeat.dist_Y;
00848
00849 if (drawMode == DRAW_SELECTIONS) {
00850 int i;
00851 gboolean foundNet = FALSE;
00852
00853 for (i=0; i<selectionInfo->selectedNodeArray->len; i++){
00854 gerbv_selection_item_t sItem = g_array_index (selectionInfo->selectedNodeArray,
00855 gerbv_selection_item_t, i);
00856 if (sItem.net == net)
00857 foundNet = TRUE;
00858 }
00859 if (!foundNet)
00860 continue;
00861 }
00862
00863 for(repeat_i = 0; repeat_i < repeat_X; repeat_i++) {
00864 for(repeat_j = 0; repeat_j < repeat_Y; repeat_j++) {
00865 double sr_x = repeat_i * repeat_dist_X;
00866 double sr_y = repeat_j * repeat_dist_Y;
00867
00868 unit_scale = scale;
00869
00870
00871
00872
00873 x1 = (int)round((image->info->offsetA + net->start_x + sr_x) * unit_scale +
00874 trans_x);
00875 y1 = (int)round((-image->info->offsetB - net->start_y - sr_y) * unit_scale +
00876 trans_y);
00877 x2 = (int)round((image->info->offsetA + net->stop_x + sr_x) * unit_scale +
00878 trans_x);
00879 y2 = (int)round((-image->info->offsetB - net->stop_y - sr_y) * unit_scale +
00880 trans_y);
00881
00882
00883
00884
00885 if (net->cirseg) {
00886 cir_width = (int)round(net->cirseg->width * unit_scale);
00887 cir_height = (int)round(net->cirseg->height * unit_scale);
00888 cp_x = (int)round((image->info->offsetA + net->cirseg->cp_x) *
00889 unit_scale + trans_x);
00890 cp_y = (int)round((image->info->offsetB - net->cirseg->cp_y) *
00891 unit_scale + trans_y);
00892 }
00893
00894
00895
00896
00897
00898 gdk_gc_set_function(gc, GDK_COPY);
00899 if ((net->layer->polarity == GERBV_POLARITY_CLEAR) != (polarity == GERBV_POLARITY_NEGATIVE))
00900 gdk_gc_set_foreground(gc, &opaque);
00901 else
00902 gdk_gc_set_foreground(gc, &transparent);
00903
00904
00905
00906
00907 switch (net->interpolation) {
00908 case GERBV_INTERPOLATION_PAREA_START :
00909 draw_gdk_render_polygon_object (net,image,sr_x,sr_y,unit_scale,trans_x,trans_y,gc,pgc,pixmap);
00910 continue;
00911
00912 case GERBV_INTERPOLATION_DELETED:
00913 continue;
00914 default :
00915 break;
00916 }
00917
00918
00919
00920
00921
00922
00923 if (image->aperture[net->aperture] == NULL) {
00924
00925
00926
00927
00928 continue;
00929 }
00930
00931 switch (net->aperture_state) {
00932 case GERBV_APERTURE_STATE_ON :
00933 p1 = (int)round(image->aperture[net->aperture]->parameter[0] * unit_scale);
00934 if (image->aperture[net->aperture]->type == GERBV_APTYPE_RECTANGLE)
00935 gdk_gc_set_line_attributes(gc, p1,
00936 GDK_LINE_SOLID,
00937 GDK_CAP_PROJECTING,
00938 GDK_JOIN_MITER);
00939 else
00940 gdk_gc_set_line_attributes(gc, p1,
00941 GDK_LINE_SOLID,
00942 GDK_CAP_ROUND,
00943 GDK_JOIN_MITER);
00944
00945 switch (net->interpolation) {
00946 case GERBV_INTERPOLATION_x10 :
00947 case GERBV_INTERPOLATION_LINEARx01 :
00948 case GERBV_INTERPOLATION_LINEARx001 :
00949 GERB_MESSAGE("Linear != x1\n");
00950 gdk_gc_set_line_attributes(gc, p1,
00951 GDK_LINE_ON_OFF_DASH,
00952 GDK_CAP_ROUND,
00953 GDK_JOIN_MITER);
00954 gdk_draw_line(*pixmap, gc, x1, y1, x2, y2);
00955 gdk_gc_set_line_attributes(gc, p1,
00956 GDK_LINE_SOLID,
00957 GDK_CAP_ROUND,
00958 GDK_JOIN_MITER);
00959 break;
00960 case GERBV_INTERPOLATION_LINEARx1 :
00961 if (image->aperture[net->aperture]->type != GERBV_APTYPE_RECTANGLE)
00962 gdk_draw_line(*pixmap, gc, x1, y1, x2, y2);
00963 else {
00964 gint dx, dy;
00965 GdkPoint poly[6];
00966
00967 dx = (int)round(image->aperture[net->aperture]->parameter[0]
00968 * unit_scale / 2);
00969 dy = (int)round(image->aperture[net->aperture]->parameter[1]
00970 * unit_scale / 2);
00971 if(x1 > x2) dx = -dx;
00972 if(y1 > y2) dy = -dy;
00973 poly[0].x = x1 - dx; poly[0].y = y1 - dy;
00974 poly[1].x = x1 - dx; poly[1].y = y1 + dy;
00975 poly[2].x = x2 - dx; poly[2].y = y2 + dy;
00976 poly[3].x = x2 + dx; poly[3].y = y2 + dy;
00977 poly[4].x = x2 + dx; poly[4].y = y2 - dy;
00978 poly[5].x = x1 + dx; poly[5].y = y1 - dy;
00979 gdk_draw_polygon(*pixmap, gc, 1, poly, 6);
00980 }
00981 break;
00982 case GERBV_INTERPOLATION_CW_CIRCULAR :
00983 case GERBV_INTERPOLATION_CCW_CIRCULAR :
00984 gerbv_gdk_draw_arc(*pixmap, gc, cp_x, cp_y, cir_width, cir_height,
00985 net->cirseg->angle1, net->cirseg->angle2);
00986 break;
00987 default :
00988 break;
00989 }
00990 break;
00991 case GERBV_APERTURE_STATE_OFF :
00992 break;
00993 case GERBV_APERTURE_STATE_FLASH :
00994 p1 = (int)round(image->aperture[net->aperture]->parameter[0] * unit_scale);
00995 p2 = (int)round(image->aperture[net->aperture]->parameter[1] * unit_scale);
00996 p3 = (int)round(image->aperture[net->aperture]->parameter[2] * unit_scale);
00997
00998 switch (image->aperture[net->aperture]->type) {
00999 case GERBV_APTYPE_CIRCLE :
01000 gerbv_gdk_draw_circle(*pixmap, gc, TRUE, x2, y2, p1);
01001
01002
01003
01004
01005
01006
01007 if (p2) {
01008
01009 gdk_gc_get_values(gc, &gc_values);
01010 if (gc_values.foreground.pixel == opaque.pixel) {
01011 gdk_gc_set_foreground(gc, &transparent);
01012 gerbv_gdk_draw_circle(*pixmap, gc, TRUE, x2, y2, p2);
01013 gdk_gc_set_foreground(gc, &opaque);
01014 } else {
01015 gdk_gc_set_foreground(gc, &opaque);
01016 gerbv_gdk_draw_circle(*pixmap, gc, TRUE, x2, y2, p2);
01017 gdk_gc_set_foreground(gc, &transparent);
01018 }
01019 }
01020
01021 break;
01022 case GERBV_APTYPE_RECTANGLE:
01023 gerbv_gdk_draw_rectangle(*pixmap, gc, TRUE, x2, y2, p1, p2);
01024 break;
01025 case GERBV_APTYPE_OVAL :
01026 gerbv_gdk_draw_oval(*pixmap, gc, TRUE, x2, y2, p1, p2);
01027 break;
01028 case GERBV_APTYPE_POLYGON :
01029
01030 gerbv_gdk_draw_circle(*pixmap, gc, TRUE, x2, y2, p1);
01031 break;
01032 case GERBV_APTYPE_MACRO :
01033 gerbv_gdk_draw_amacro(*pixmap, gc,
01034 image->aperture[net->aperture]->simplified,
01035 unit_scale, x2, y2);
01036 break;
01037 default :
01038 GERB_MESSAGE("Unknown aperture type\n");
01039 return 0;
01040 }
01041 break;
01042 default :
01043 GERB_MESSAGE("Unknown aperture state\n");
01044 return 0;
01045 }
01046 }
01047 }
01048 }
01049
01050
01051
01052 gdk_gc_unref(gc);
01053 gdk_gc_unref(pgc);
01054
01055 return 1;
01056
01057 }
01058
01059