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.h"
00044 #include "draw-gdk.h"
00045 #include <cairo.h>
00046
00047 #define dprintf if(DEBUG) printf
00048 static void
00049 draw_check_if_object_is_in_selected_area (cairo_t *cairoTarget, gboolean isStroke,
00050 gerbv_selection_info_t *selectionInfo, gerbv_image_t *image, struct gerbv_net *net){
00051 gdouble corner1X,corner1Y,corner2X,corner2Y;
00052
00053 corner1X = selectionInfo->lowerLeftX;
00054 corner1Y = selectionInfo->lowerLeftY;
00055 corner2X = selectionInfo->upperRightX;
00056 corner2Y = selectionInfo->upperRightY;
00057
00058
00059
00060 cairo_device_to_user (cairoTarget, &corner1X, &corner1Y);
00061 cairo_device_to_user (cairoTarget, &corner2X, &corner2Y);
00062 if (selectionInfo->type == GERBV_SELECTION_POINT_CLICK) {
00063
00064
00065 if ((isStroke && cairo_in_stroke (cairoTarget, corner1X, corner1Y)) ||
00066 (!isStroke && cairo_in_fill (cairoTarget, corner1X, corner1Y))) {
00067
00068 gerbv_selection_item_t sItem = {image, net};
00069 g_array_append_val (selectionInfo->selectedNodeArray, sItem);
00070 }
00071 }
00072 else if (selectionInfo->type == GERBV_SELECTION_DRAG_BOX) {
00073 gdouble x1,x2,y1,y2;
00074 gdouble minX,minY,maxX,maxY;
00075
00076
00077
00078 minX = MIN(corner1X,corner2X);
00079 maxX = MAX(corner1X,corner2X);
00080 minY = MIN(corner1Y,corner2Y);
00081 maxY = MAX(corner1Y,corner2Y);
00082 if (isStroke)
00083 cairo_stroke_extents (cairoTarget, &x1, &y1, &x2, &y2);
00084 else
00085 cairo_fill_extents (cairoTarget, &x1, &y1, &x2, &y2);
00086
00087 if ((minX < x1) && (minY < y1) && (maxX > x2) && (maxY > y2)) {
00088
00089 gerbv_selection_item_t sItem = {image, net};
00090 g_array_append_val (selectionInfo->selectedNodeArray, sItem);
00091 }
00092 }
00093
00094
00095 cairo_new_path (cairoTarget);
00096 }
00097
00098 static void
00099 draw_fill (cairo_t *cairoTarget, gchar drawMode, gerbv_selection_info_t *selectionInfo,
00100 gerbv_image_t *image, struct gerbv_net *net){
00101 if ((drawMode == DRAW_IMAGE) || (drawMode == DRAW_SELECTIONS))
00102 cairo_fill (cairoTarget);
00103 else
00104 draw_check_if_object_is_in_selected_area (cairoTarget, FALSE,
00105 selectionInfo, image, net);
00106 }
00107
00108 static void
00109 draw_stroke (cairo_t *cairoTarget, gchar drawMode, gerbv_selection_info_t *selectionInfo,
00110 gerbv_image_t *image, struct gerbv_net *net){
00111 if ((drawMode == DRAW_IMAGE) || (drawMode == DRAW_SELECTIONS))
00112 cairo_stroke (cairoTarget);
00113 else
00114 draw_check_if_object_is_in_selected_area (cairoTarget, TRUE,
00115 selectionInfo, image, net);
00116 }
00117
00118
00119
00120
00121 static void
00122 gerbv_draw_circle(cairo_t *cairoTarget, gdouble diameter)
00123 {
00124 cairo_arc (cairoTarget, 0.0, 0.0, diameter/2.0, 0, 2.0*M_PI);
00125 return;
00126 }
00127
00128
00129
00130
00131
00132 static void
00133 gerbv_draw_rectangle(cairo_t *cairoTarget, gdouble width, gdouble height)
00134 {
00135 cairo_rectangle (cairoTarget, - width / 2.0, - height / 2.0, width, height);
00136 return;
00137 }
00138
00139
00140
00141
00142
00143 static void
00144 gerbv_draw_oblong(cairo_t *cairoTarget, gdouble width, gdouble height)
00145 {
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 cairo_save (cairoTarget);
00158 cairo_scale (cairoTarget, width, height);
00159 gerbv_draw_circle (cairoTarget, 1);
00160 cairo_restore (cairoTarget);
00161 return;
00162 }
00163
00164
00165 static void
00166 gerbv_draw_polygon(cairo_t *cairoTarget, gdouble outsideDiameter,
00167 gdouble numberOfSides, gdouble degreesOfRotation)
00168 {
00169 int i, numberOfSidesInteger = (int) numberOfSides;
00170
00171 cairo_rotate(cairoTarget, degreesOfRotation * M_PI/180);
00172 cairo_move_to(cairoTarget, outsideDiameter / 2.0, 0);
00173
00174
00175
00176 for (i = 1; i <= (int)numberOfSidesInteger; i++){
00177 gdouble angle = (double) i / numberOfSidesInteger * M_PI * 2.0;
00178 cairo_line_to (cairoTarget, cos(angle) * outsideDiameter / 2.0,
00179 sin(angle) * outsideDiameter / 2.0);
00180 }
00181 return;
00182 }
00183
00184
00185 static void
00186 gerbv_draw_aperature_hole(cairo_t *cairoTarget, gdouble dimensionX, gdouble dimensionY)
00187 {
00188 if (dimensionX) {
00189 if (dimensionY) {
00190 gerbv_draw_rectangle (cairoTarget, dimensionX, dimensionY);
00191 } else {
00192 gerbv_draw_circle (cairoTarget, dimensionX);
00193 }
00194 }
00195 return;
00196 }
00197
00198 gboolean
00199 draw_update_macro_exposure (cairo_t *cairoTarget, cairo_operator_t clearOperator,
00200 cairo_operator_t darkOperator, gdouble exposureSetting){
00201
00202 if (exposureSetting == 0.0) {
00203 cairo_set_operator (cairoTarget, clearOperator);
00204 }
00205 else if (exposureSetting == 1.0) {
00206 cairo_set_operator (cairoTarget, darkOperator);
00207 }
00208 else if (exposureSetting == 2.0) {
00209
00210 cairo_operator_t currentOperator = cairo_get_operator (cairoTarget);
00211 if (currentOperator == clearOperator) {
00212 cairo_set_operator (cairoTarget, darkOperator);
00213 }
00214 else {
00215 cairo_set_operator (cairoTarget, clearOperator);
00216 }
00217 }
00218 return TRUE;
00219 }
00220
00221
00222 int
00223 gerbv_draw_amacro(cairo_t *cairoTarget, cairo_operator_t clearOperator,
00224 cairo_operator_t darkOperator, gerbv_simplified_amacro_t *s,
00225 gint usesClearPrimative, gchar drawMode, gerbv_selection_info_t *selectionInfo,
00226 gerbv_image_t *image, struct gerbv_net *net)
00227 {
00228 int handled = 1;
00229 gerbv_simplified_amacro_t *ls = s;
00230
00231 dprintf("Drawing simplified aperture macros:\n");
00232 if (usesClearPrimative)
00233 cairo_push_group (cairoTarget);
00234 while (ls != NULL) {
00235
00236
00237
00238
00239
00240 cairo_save (cairoTarget);
00241 cairo_new_path(cairoTarget);
00242 cairo_operator_t oldOperator = cairo_get_operator (cairoTarget);
00243
00244 if (ls->type == GERBV_APTYPE_MACRO_CIRCLE) {
00245
00246 if (draw_update_macro_exposure (cairoTarget, clearOperator,
00247 darkOperator, ls->parameter[CIRCLE_EXPOSURE])){
00248 cairo_translate (cairoTarget, ls->parameter[CIRCLE_CENTER_X],
00249 ls->parameter[CIRCLE_CENTER_Y]);
00250
00251 gerbv_draw_circle (cairoTarget, ls->parameter[CIRCLE_DIAMETER]);
00252 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00253 }
00254 } else if (ls->type == GERBV_APTYPE_MACRO_OUTLINE) {
00255 int pointCounter,numberOfPoints;
00256
00257
00258
00259 numberOfPoints = (int) ls->parameter[OUTLINE_NUMBER_OF_POINTS] + 1;
00260
00261 if (draw_update_macro_exposure (cairoTarget, clearOperator,
00262 darkOperator, ls->parameter[OUTLINE_EXPOSURE])){
00263 cairo_rotate (cairoTarget, ls->parameter[(numberOfPoints - 1) * 2 + OUTLINE_ROTATION] * M_PI/180.0);
00264 cairo_move_to (cairoTarget, ls->parameter[OUTLINE_FIRST_X], ls->parameter[OUTLINE_FIRST_Y]);
00265
00266 for (pointCounter=0; pointCounter < numberOfPoints; pointCounter++) {
00267 cairo_line_to (cairoTarget, ls->parameter[pointCounter * 2 + OUTLINE_FIRST_X],
00268 ls->parameter[pointCounter * 2 + OUTLINE_FIRST_Y]);
00269 }
00270
00271
00272
00273
00274
00275 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00276 }
00277 } else if (ls->type == GERBV_APTYPE_MACRO_POLYGON) {
00278 if (draw_update_macro_exposure (cairoTarget, clearOperator,
00279 darkOperator, ls->parameter[POLYGON_EXPOSURE])){
00280 cairo_translate (cairoTarget, ls->parameter[POLYGON_CENTER_X],
00281 ls->parameter[POLYGON_CENTER_Y]);
00282 gerbv_draw_polygon(cairoTarget, ls->parameter[POLYGON_DIAMETER],
00283 ls->parameter[POLYGON_NUMBER_OF_POINTS], ls->parameter[POLYGON_ROTATION]);
00284 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00285 }
00286 } else if (ls->type == GERBV_APTYPE_MACRO_MOIRE) {
00287 gdouble diameter, gap;
00288 int circleIndex;
00289
00290 cairo_translate (cairoTarget, ls->parameter[MOIRE_CENTER_X],
00291 ls->parameter[MOIRE_CENTER_Y]);
00292 cairo_rotate (cairoTarget, ls->parameter[MOIRE_ROTATION] * M_PI/180);
00293 diameter = ls->parameter[MOIRE_OUTSIDE_DIAMETER] - ls->parameter[MOIRE_CIRCLE_THICKNESS];
00294 gap = ls->parameter[MOIRE_GAP_WIDTH] + ls->parameter[MOIRE_CIRCLE_THICKNESS];
00295 cairo_set_line_width (cairoTarget, ls->parameter[MOIRE_CIRCLE_THICKNESS]);
00296
00297 for (circleIndex = 0; circleIndex < (int)ls->parameter[MOIRE_NUMBER_OF_CIRCLES]; circleIndex++) {
00298 gdouble currentDiameter = (diameter - gap * (float) circleIndex);
00299 gerbv_draw_circle (cairoTarget, currentDiameter);
00300 draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
00301 }
00302
00303 gdouble crosshairRadius = (ls->parameter[MOIRE_CROSSHAIR_LENGTH] / 2.0);
00304
00305 cairo_set_line_width (cairoTarget, ls->parameter[MOIRE_CROSSHAIR_THICKNESS]);
00306 cairo_move_to (cairoTarget, -crosshairRadius, 0);
00307 cairo_line_to (cairoTarget, crosshairRadius, 0);
00308 cairo_move_to (cairoTarget, 0, -crosshairRadius);
00309 cairo_line_to (cairoTarget, 0, crosshairRadius);
00310 draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
00311 } else if (ls->type == GERBV_APTYPE_MACRO_THERMAL) {
00312 gint i;
00313 gdouble startAngle1, startAngle2, endAngle1, endAngle2;
00314
00315 cairo_translate (cairoTarget, ls->parameter[THERMAL_CENTER_X],
00316 ls->parameter[THERMAL_CENTER_Y]);
00317 cairo_rotate (cairoTarget, ls->parameter[THERMAL_ROTATION] * M_PI/180.0);
00318 startAngle1 = atan (ls->parameter[THERMAL_CROSSHAIR_THICKNESS]/ls->parameter[THERMAL_INSIDE_DIAMETER]);
00319 endAngle1 = M_PI/2 - startAngle1;
00320 endAngle2 = atan (ls->parameter[THERMAL_CROSSHAIR_THICKNESS]/ls->parameter[THERMAL_OUTSIDE_DIAMETER]);
00321 startAngle2 = M_PI/2 - endAngle2;
00322 for (i = 0; i < 4; i++) {
00323 cairo_arc (cairoTarget, 0, 0, ls->parameter[THERMAL_INSIDE_DIAMETER]/2.0, startAngle1, endAngle1);
00324 cairo_rel_line_to (cairoTarget, 0, ls->parameter[THERMAL_CROSSHAIR_THICKNESS]);
00325 cairo_arc_negative (cairoTarget, 0, 0, ls->parameter[THERMAL_OUTSIDE_DIAMETER]/2.0,
00326 startAngle2, endAngle2);
00327 cairo_rel_line_to (cairoTarget, -ls->parameter[THERMAL_CROSSHAIR_THICKNESS],0);
00328 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00329 cairo_rotate (cairoTarget, 90 * M_PI/180);
00330 }
00331 } else if (ls->type == GERBV_APTYPE_MACRO_LINE20) {
00332 if (draw_update_macro_exposure (cairoTarget, clearOperator,
00333 darkOperator, ls->parameter[LINE20_EXPOSURE])){
00334 cairo_set_line_width (cairoTarget, ls->parameter[LINE20_LINE_WIDTH]);
00335 cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_BUTT);
00336 cairo_rotate (cairoTarget, ls->parameter[LINE20_ROTATION] * M_PI/180.0);
00337 cairo_move_to (cairoTarget, ls->parameter[LINE20_START_X], ls->parameter[LINE20_START_Y]);
00338 cairo_line_to (cairoTarget, ls->parameter[LINE20_END_X], ls->parameter[LINE20_END_Y]);
00339 draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
00340 }
00341 } else if (ls->type == GERBV_APTYPE_MACRO_LINE21) {
00342 gdouble halfWidth, halfHeight;
00343
00344 if (draw_update_macro_exposure (cairoTarget, clearOperator,
00345 darkOperator, ls->parameter[LINE22_EXPOSURE])){
00346 halfWidth = ls->parameter[LINE21_WIDTH] / 2.0;
00347 halfHeight = ls->parameter[LINE21_HEIGHT] / 2.0;
00348 cairo_translate (cairoTarget, ls->parameter[LINE21_CENTER_X], ls->parameter[LINE21_CENTER_Y]);
00349 cairo_rotate (cairoTarget, ls->parameter[LINE21_ROTATION] * M_PI/180.0);
00350 cairo_rectangle (cairoTarget, -halfWidth, -halfHeight,
00351 ls->parameter[LINE21_WIDTH], ls->parameter[LINE21_HEIGHT]);
00352 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00353 }
00354 } else if (ls->type == GERBV_APTYPE_MACRO_LINE22) {
00355 gdouble halfWidth, halfHeight;
00356
00357 if (draw_update_macro_exposure (cairoTarget, clearOperator,
00358 darkOperator, ls->parameter[LINE22_EXPOSURE])){
00359 halfWidth = ls->parameter[LINE22_WIDTH] / 2.0;
00360 halfHeight = ls->parameter[LINE22_HEIGHT] / 2.0;
00361 cairo_translate (cairoTarget, ls->parameter[LINE22_LOWER_LEFT_X],
00362 ls->parameter[LINE22_LOWER_LEFT_Y]);
00363 cairo_rotate (cairoTarget, ls->parameter[LINE22_ROTATION] * M_PI/180.0);
00364 cairo_rectangle (cairoTarget, 0, 0,
00365 ls->parameter[LINE22_WIDTH], ls->parameter[LINE22_HEIGHT]);
00366 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00367 }
00368 } else {
00369 handled = 0;
00370 }
00371 cairo_set_operator (cairoTarget, oldOperator);
00372 cairo_restore (cairoTarget);
00373 ls = ls->next;
00374 }
00375 if (usesClearPrimative) {
00376 cairo_pop_group_to_source (cairoTarget);
00377 cairo_paint (cairoTarget);
00378 }
00379 return handled;
00380 }
00381
00382
00383 void
00384 draw_apply_netstate_transformation (cairo_t *cairoTarget, gerbv_netstate_t *state)
00385 {
00386
00387 cairo_scale (cairoTarget, state->scaleA, state->scaleB);
00388
00389 cairo_translate (cairoTarget, state->offsetA, state->offsetB);
00390
00391 switch (state->mirrorState) {
00392 case GERBV_MIRROR_STATE_FLIPA:
00393 cairo_scale (cairoTarget, -1, 1);
00394 break;
00395 case GERBV_MIRROR_STATE_FLIPB:
00396 cairo_scale (cairoTarget, 1, -1);
00397 break;
00398 case GERBV_MIRROR_STATE_FLIPAB:
00399 cairo_scale (cairoTarget, -1, -1);
00400 break;
00401 default:
00402 break;
00403 }
00404
00405 if (state->axisSelect == GERBV_AXIS_SELECT_SWAPAB) {
00406
00407
00408 cairo_rotate (cairoTarget, 3 * M_PI / 2);
00409 cairo_scale (cairoTarget, 1, -1);
00410 }
00411 }
00412
00413 void
00414 draw_render_polygon_object (gerbv_net_t *oldNet, cairo_t *cairoTarget, gdouble sr_x, gdouble sr_y,
00415 gerbv_image_t *image, gchar drawMode, gerbv_selection_info_t *selectionInfo ){
00416 gerbv_net_t *currentNet, *polygonStartNet;
00417 int haveDrawnFirstFillPoint = 0;
00418 gdouble x1,y1,x2,y2,cp_x=0,cp_y=0;
00419
00420 haveDrawnFirstFillPoint = FALSE;
00421
00422
00423 polygonStartNet = oldNet;
00424 cairo_new_path(cairoTarget);
00425
00426 for (currentNet = oldNet->next; currentNet!=NULL; currentNet = currentNet->next){
00427 x1 = currentNet->start_x + sr_x;
00428 y1 = currentNet->start_y + sr_y;
00429 x2 = currentNet->stop_x + sr_x;
00430 y2 = currentNet->stop_y + sr_y;
00431
00432
00433 if (currentNet->cirseg) {
00434 cp_x = currentNet->cirseg->cp_x + sr_x;
00435 cp_y = currentNet->cirseg->cp_y + sr_y;
00436 }
00437 if (!haveDrawnFirstFillPoint) {
00438 cairo_move_to (cairoTarget, x2,y2);
00439 haveDrawnFirstFillPoint=TRUE;
00440 continue;
00441 }
00442 switch (currentNet->interpolation) {
00443 case GERBV_INTERPOLATION_x10 :
00444 case GERBV_INTERPOLATION_LINEARx01 :
00445 case GERBV_INTERPOLATION_LINEARx001 :
00446 case GERBV_INTERPOLATION_LINEARx1 :
00447 cairo_line_to (cairoTarget, x2,y2);
00448 break;
00449 case GERBV_INTERPOLATION_CW_CIRCULAR :
00450 case GERBV_INTERPOLATION_CCW_CIRCULAR :
00451 if (currentNet->cirseg->angle2 > currentNet->cirseg->angle1) {
00452 cairo_arc (cairoTarget, cp_x, cp_y, currentNet->cirseg->width/2.0,
00453 currentNet->cirseg->angle1 * M_PI/180,currentNet->cirseg->angle2 * M_PI/180);
00454 }
00455 else {
00456 cairo_arc_negative (cairoTarget, cp_x, cp_y, currentNet->cirseg->width/2.0,
00457 currentNet->cirseg->angle1 * M_PI/180,currentNet->cirseg->angle2 * M_PI/180);
00458 }
00459 break;
00460 case GERBV_INTERPOLATION_PAREA_END :
00461 cairo_close_path(cairoTarget);
00462
00463
00464 cairo_antialias_t oldAlias = cairo_get_antialias (cairoTarget);
00465 cairo_set_antialias (cairoTarget, CAIRO_ANTIALIAS_NONE);
00466 draw_fill (cairoTarget, drawMode, selectionInfo, image, polygonStartNet);
00467 cairo_set_antialias (cairoTarget, oldAlias);
00468 return;
00469 default :
00470 break;
00471 }
00472 }
00473 }
00474
00475 int
00476 draw_image_to_cairo_target (cairo_t *cairoTarget, gerbv_image_t *image,
00477 gboolean invertLayer, gdouble pixelWidth,
00478 gchar drawMode, gerbv_selection_info_t *selectionInfo)
00479 {
00480 struct gerbv_net *net, *polygonStartNet=NULL;
00481 double x1, y1, x2, y2, cp_x=0, cp_y=0;
00482 gdouble p1, p2, p3, p4, p5, dx, dy;
00483 gerbv_netstate_t *oldState;
00484 gerbv_layer_t *oldLayer;
00485 int repeat_X=1, repeat_Y=1;
00486 double repeat_dist_X = 0, repeat_dist_Y = 0;
00487 int repeat_i, repeat_j;
00488 cairo_operator_t drawOperatorClear, drawOperatorDark;
00489 gboolean invertPolarity = FALSE;
00490
00491
00492 cairo_translate (cairoTarget, image->info->imageJustifyOffsetActualA,
00493 image->info->imageJustifyOffsetActualB);
00494
00495
00496 cairo_set_fill_rule (cairoTarget, CAIRO_FILL_RULE_EVEN_ODD);
00497
00498 cairo_translate (cairoTarget, image->info->offsetA, image->info->offsetB);
00499
00500 cairo_rotate (cairoTarget, image->info->imageRotation);
00501
00502 invertPolarity = invertLayer;
00503 if (image->info->polarity == GERBV_POLARITY_NEGATIVE)
00504 invertPolarity = !invertPolarity;
00505 if (invertPolarity) {
00506 drawOperatorClear = CAIRO_OPERATOR_OVER;
00507 drawOperatorDark = CAIRO_OPERATOR_CLEAR;
00508 cairo_set_operator (cairoTarget, CAIRO_OPERATOR_OVER);
00509 cairo_paint (cairoTarget);
00510 cairo_set_operator (cairoTarget, CAIRO_OPERATOR_CLEAR);
00511 }
00512 else {
00513 drawOperatorClear = CAIRO_OPERATOR_CLEAR;
00514 drawOperatorDark = CAIRO_OPERATOR_OVER;
00515 }
00516
00517
00518
00519
00520 cairo_save (cairoTarget);
00521 cairo_save (cairoTarget);
00522
00523 oldLayer = image->layers;
00524 oldState = image->states;
00525
00526 for (net = image->netlist->next ; net != NULL; net = gerbv_image_return_next_renderable_object(net)) {
00527
00528
00529 if (net->layer != oldLayer){
00530
00531
00532 cairo_restore (cairoTarget);
00533 cairo_restore (cairoTarget);
00534 cairo_save (cairoTarget);
00535
00536 cairo_rotate (cairoTarget, net->layer->rotation);
00537
00538 if ((net->layer->polarity == GERBV_POLARITY_CLEAR)) {
00539 cairo_set_operator (cairoTarget, drawOperatorClear);
00540 }
00541 else {
00542 cairo_set_operator (cairoTarget, drawOperatorDark);
00543 }
00544
00545 repeat_X = net->layer->stepAndRepeat.X;
00546 repeat_Y = net->layer->stepAndRepeat.Y;
00547 repeat_dist_X = net->layer->stepAndRepeat.dist_X;
00548 repeat_dist_Y = net->layer->stepAndRepeat.dist_Y;
00549
00550 if (net->layer->knockout.firstInstance == TRUE) {
00551 cairo_operator_t oldOperator = cairo_get_operator (cairoTarget);
00552 if (net->layer->knockout.polarity == GERBV_POLARITY_CLEAR) {
00553 cairo_set_operator (cairoTarget, drawOperatorClear);
00554 }
00555 else {
00556 cairo_set_operator (cairoTarget, drawOperatorDark);
00557 }
00558 cairo_new_path (cairoTarget);
00559 cairo_rectangle (cairoTarget, net->layer->knockout.lowerLeftX - net->layer->knockout.border,
00560 net->layer->knockout.lowerLeftY - net->layer->knockout.border,
00561 net->layer->knockout.width + (net->layer->knockout.border*2),
00562 net->layer->knockout.height + (net->layer->knockout.border*2));
00563 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00564 cairo_set_operator (cairoTarget, oldOperator);
00565 }
00566
00567 cairo_save (cairoTarget);
00568 draw_apply_netstate_transformation (cairoTarget, net->state);
00569 oldLayer = net->layer;
00570 }
00571
00572 if (net->state != oldState){
00573
00574
00575 cairo_restore (cairoTarget);
00576 cairo_save (cairoTarget);
00577
00578
00579 draw_apply_netstate_transformation (cairoTarget, net->state);
00580 oldState = net->state;
00581 }
00582
00583
00584 if (drawMode == DRAW_SELECTIONS) {
00585
00586
00587
00588
00589 if (!polygonStartNet) {
00590 int i;
00591 gboolean foundNet = FALSE;
00592
00593 for (i=0; i<selectionInfo->selectedNodeArray->len; i++){
00594 gerbv_selection_item_t sItem = g_array_index (selectionInfo->selectedNodeArray,
00595 gerbv_selection_item_t, i);
00596 if (sItem.net == net)
00597 foundNet = TRUE;
00598 }
00599 if (!foundNet)
00600 continue;
00601 }
00602
00603 }
00604 for(repeat_i = 0; repeat_i < repeat_X; repeat_i++) {
00605 for(repeat_j = 0; repeat_j < repeat_Y; repeat_j++) {
00606 double sr_x = repeat_i * repeat_dist_X;
00607 double sr_y = repeat_j * repeat_dist_Y;
00608
00609 x1 = net->start_x + sr_x;
00610 y1 = net->start_y + sr_y;
00611 x2 = net->stop_x + sr_x;
00612 y2 = net->stop_y + sr_y;
00613
00614
00615 if (net->cirseg) {
00616 cp_x = net->cirseg->cp_x + sr_x;
00617 cp_y = net->cirseg->cp_y + sr_y;
00618 }
00619
00620
00621
00622
00623 if (net->label) {
00624 cairo_set_font_size (cairoTarget, 0.05);
00625 cairo_save (cairoTarget);
00626
00627 cairo_move_to (cairoTarget, x1, y1);
00628 cairo_scale (cairoTarget, 1, -1);
00629 cairo_show_text (cairoTarget, net->label->str);
00630 cairo_restore (cairoTarget);
00631 }
00632
00633
00634
00635 switch (net->interpolation) {
00636 case GERBV_INTERPOLATION_PAREA_START :
00637 draw_render_polygon_object (net, cairoTarget, sr_x, sr_y, image,
00638 drawMode, selectionInfo);
00639 continue;
00640 case GERBV_INTERPOLATION_DELETED:
00641 continue;
00642 default :
00643 break;
00644 }
00645
00646
00647
00648
00649
00650
00651 if (image->aperture[net->aperture] == NULL) {
00652
00653
00654
00655
00656 continue;
00657 }
00658 switch (net->aperture_state) {
00659 case GERBV_APERTURE_STATE_ON :
00660
00661
00662
00663
00664
00665 if (image->aperture[net->aperture]->parameter[0] > pixelWidth)
00666 cairo_set_line_width (cairoTarget, image->aperture[net->aperture]->parameter[0]);
00667 else
00668 cairo_set_line_width (cairoTarget, pixelWidth);
00669 switch (net->interpolation) {
00670 case GERBV_INTERPOLATION_x10 :
00671 case GERBV_INTERPOLATION_LINEARx01 :
00672 case GERBV_INTERPOLATION_LINEARx001 :
00673 case GERBV_INTERPOLATION_LINEARx1 :
00674 cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND);
00675 switch (image->aperture[net->aperture]->type) {
00676 case GERBV_APTYPE_CIRCLE :
00677 cairo_move_to (cairoTarget, x1,y1);
00678 cairo_line_to (cairoTarget, x2,y2);
00679 draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
00680 break;
00681 case GERBV_APTYPE_RECTANGLE :
00682 dx = (image->aperture[net->aperture]->parameter[0]/ 2);
00683 dy = (image->aperture[net->aperture]->parameter[1]/ 2);
00684 if(x1 > x2)
00685 dx = -dx;
00686 if(y1 > y2)
00687 dy = -dy;
00688 cairo_new_path(cairoTarget);
00689 cairo_move_to (cairoTarget, x1 - dx, y1 - dy);
00690 cairo_line_to (cairoTarget, x1 - dx, y1 + dy);
00691 cairo_line_to (cairoTarget, x2 - dx, y2 + dy);
00692 cairo_line_to (cairoTarget, x2 + dx, y2 + dy);
00693 cairo_line_to (cairoTarget, x2 + dx, y2 - dy);
00694 cairo_line_to (cairoTarget, x1 + dx, y1 - dy);
00695 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00696 break;
00697
00698 case GERBV_APTYPE_OVAL :
00699 case GERBV_APTYPE_POLYGON :
00700 cairo_move_to (cairoTarget, x1,y1);
00701 cairo_line_to (cairoTarget, x2,y2);
00702 draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
00703 break;
00704
00705 default :
00706 break;
00707 }
00708 break;
00709 case GERBV_INTERPOLATION_CW_CIRCULAR :
00710 case GERBV_INTERPOLATION_CCW_CIRCULAR :
00711
00712
00713
00714 cairo_new_path(cairoTarget);
00715 if (image->aperture[net->aperture]->type == GERBV_APTYPE_RECTANGLE) {
00716 cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_SQUARE);
00717 }
00718 else {
00719 cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND);
00720 }
00721 cairo_save (cairoTarget);
00722 cairo_translate(cairoTarget, cp_x, cp_y);
00723 cairo_scale (cairoTarget, net->cirseg->width, net->cirseg->height);
00724 if (net->cirseg->angle2 > net->cirseg->angle1) {
00725 cairo_arc (cairoTarget, 0.0, 0.0, 0.5, net->cirseg->angle1 * M_PI/180,
00726 net->cirseg->angle2 * M_PI/180);
00727 }
00728 else {
00729 cairo_arc_negative (cairoTarget, 0.0, 0.0, 0.5, net->cirseg->angle1 * M_PI/180,
00730 net->cirseg->angle2 * M_PI/180);
00731 }
00732 cairo_restore (cairoTarget);
00733 draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
00734 break;
00735 default :
00736 break;
00737 }
00738 break;
00739 case GERBV_APERTURE_STATE_OFF :
00740 break;
00741 case GERBV_APERTURE_STATE_FLASH :
00742 p1 = image->aperture[net->aperture]->parameter[0];
00743 p2 = image->aperture[net->aperture]->parameter[1];
00744 p3 = image->aperture[net->aperture]->parameter[2];
00745 p4 = image->aperture[net->aperture]->parameter[3];
00746 p5 = image->aperture[net->aperture]->parameter[4];
00747
00748 cairo_save (cairoTarget);
00749 cairo_translate (cairoTarget, x2, y2);
00750
00751 switch (image->aperture[net->aperture]->type) {
00752 case GERBV_APTYPE_CIRCLE :
00753 gerbv_draw_circle(cairoTarget, p1);
00754 gerbv_draw_aperature_hole (cairoTarget, p2, p3);
00755 break;
00756 case GERBV_APTYPE_RECTANGLE :
00757 gerbv_draw_rectangle(cairoTarget, p1, p2);
00758 gerbv_draw_aperature_hole (cairoTarget, p3, p4);
00759 break;
00760 case GERBV_APTYPE_OVAL :
00761 gerbv_draw_oblong(cairoTarget, p1, p2);
00762 gerbv_draw_aperature_hole (cairoTarget, p3, p4);
00763 break;
00764 case GERBV_APTYPE_POLYGON :
00765 gerbv_draw_polygon(cairoTarget, p1, p2, p3);
00766 gerbv_draw_aperature_hole (cairoTarget, p4, p5);
00767 break;
00768 case GERBV_APTYPE_MACRO :
00769 gerbv_draw_amacro(cairoTarget, drawOperatorClear, drawOperatorDark,
00770 image->aperture[net->aperture]->simplified,
00771 (int) image->aperture[net->aperture]->parameter[0],
00772 drawMode, selectionInfo, image, net);
00773 break;
00774 default :
00775 GERB_MESSAGE("Unknown aperture type\n");
00776 return 0;
00777 }
00778
00779 draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
00780 cairo_restore (cairoTarget);
00781 break;
00782 default:
00783 GERB_MESSAGE("Unknown aperture state\n");
00784 return 0;
00785 }
00786 }
00787 }
00788 }
00789
00790
00791 cairo_restore (cairoTarget);
00792 cairo_restore (cairoTarget);
00793
00794 return 1;
00795 }
00796
00797