46 static gboolean draw_do_vector_export_fix(cairo_t* cairoTarget,
double* bg_red,
double* bg_green,
double* bg_blue);
55 draw_cairo_line_to(cairo_t* cairoTarget, gdouble x, gdouble y, gboolean adjustByHalf, gboolean pixelOutput) {
57 cairo_user_to_device(cairoTarget, &x, &y);
64 cairo_device_to_user(cairoTarget, &x, &y);
66 cairo_line_to(cairoTarget, x, y);
76 draw_cairo_move_to(cairo_t* cairoTarget, gdouble x, gdouble y, gboolean oddWidth, gboolean pixelOutput) {
78 cairo_user_to_device(cairoTarget, &x, &y);
85 cairo_device_to_user(cairoTarget, &x, &y);
87 cairo_move_to(cairoTarget, x, y);
98 cairo_user_to_device(cairoTarget, &x, &y);
101 cairo_device_to_user(cairoTarget, &x, &y);
104 cairo_translate(cairoTarget, x, y);
115 gerbv_selection_item_t sItem;
117 for (guint i = 0; i < selection_length(selectionInfo); i++) {
118 sItem = selection_get_item_by_index(selectionInfo, i);
119 if (sItem.net == net) {
121 selection_clear_item_by_index(selectionInfo, i);
131 draw_check_if_object_is_in_selected_area(
133 struct gerbv_net* net,
enum draw_mode drawMode
135 gerbv_selection_item_t sItem = { image, net };
136 gdouble corner1X, corner1Y, corner2X, corner2Y;
137 gdouble x1, x2, y1, y2;
138 gdouble minX, minY, maxX, maxY;
140 corner1X = selectionInfo->lowerLeftX;
141 corner1Y = selectionInfo->lowerLeftY;
142 corner2X = selectionInfo->upperRightX;
143 corner2Y = selectionInfo->upperRightY;
147 cairo_device_to_user(cairoTarget, &corner1X, &corner1Y);
148 cairo_device_to_user(cairoTarget, &corner2X, &corner2Y);
150 switch (selectionInfo->type) {
154 if ((isStroke && cairo_in_stroke(cairoTarget, corner1X, corner1Y))
155 || (!isStroke && cairo_in_fill(cairoTarget, corner1X, corner1Y))) {
158 selection_add_item(selectionInfo, &sItem);
166 minX = MIN(corner1X, corner2X);
167 maxX = MAX(corner1X, corner2X);
168 minY = MIN(corner1Y, corner2Y);
169 maxY = MAX(corner1Y, corner2Y);
172 cairo_stroke_extents(cairoTarget, &x1, &y1, &x2, &y2);
174 cairo_fill_extents(cairoTarget, &x1, &y1, &x2, &y2);
176 if ((minX < x1) && (minY < y1) && (maxX > x2) && (maxY > y2)) {
178 selection_add_item(selectionInfo, &sItem);
186 cairo_new_path(cairoTarget);
194 if ((drawMode == DRAW_IMAGE) || (drawMode == DRAW_SELECTIONS))
195 cairo_fill(cairoTarget);
197 draw_check_if_object_is_in_selected_area(cairoTarget, FALSE, selectionInfo, image, net, drawMode);
205 if ((drawMode == DRAW_IMAGE) || (drawMode == DRAW_SELECTIONS))
206 cairo_stroke(cairoTarget);
208 draw_check_if_object_is_in_selected_area(cairoTarget, TRUE, selectionInfo, image, net, drawMode);
216 cairo_arc(cairoTarget, 0.0, 0.0, diameter / 2.0, 0, 2.0 * M_PI);
229 cairo_user_to_device_distance(cairoTarget, &width, &height);
230 width -= (int)round(width) % 2;
231 height -= (int)round(height) % 2;
232 cairo_device_to_user_distance(cairoTarget, &width, &height);
235 cairo_rectangle(cairoTarget, -width / 2.0, -height / 2.0, width, height);
247 gdouble circleDiameter, strokeDistance;
249 cairo_new_path(cairoTarget);
250 if (width < height) {
251 circleDiameter = width;
252 strokeDistance = (height - width) / 2.0;
253 cairo_arc(cairoTarget, 0.0, strokeDistance, circleDiameter / 2.0, 0, -M_PI);
254 cairo_line_to(cairoTarget, -circleDiameter / 2.0, -strokeDistance);
255 cairo_arc(cairoTarget, 0.0, -strokeDistance, circleDiameter / 2.0, -M_PI, 0);
256 cairo_line_to(cairoTarget, circleDiameter / 2.0, strokeDistance);
258 circleDiameter = height;
259 strokeDistance = (width - height) / 2.0;
260 cairo_arc(cairoTarget, -strokeDistance, 0.0, circleDiameter / 2.0, M_PI_2, -M_PI_2);
261 cairo_line_to(cairoTarget, strokeDistance, -circleDiameter / 2.0);
262 cairo_arc(cairoTarget, strokeDistance, 0.0, circleDiameter / 2.0, -M_PI_2, M_PI_2);
263 cairo_line_to(cairoTarget, -strokeDistance, circleDiameter / 2.0);
270 cairo_save (cairoTarget);
271 cairo_scale (cairoTarget, width, height);
273 cairo_restore (cairoTarget);
279 gerbv_draw_polygon(cairo_t* cairoTarget, gdouble outsideDiameter, gdouble numberOfSides, gdouble degreesOfRotation) {
280 int i, numberOfSidesInteger = (int)numberOfSides;
282 cairo_rotate(cairoTarget, DEG2RAD(degreesOfRotation));
283 cairo_move_to(cairoTarget, outsideDiameter / 2.0, 0);
288 for (i = 1; i <= (int)numberOfSidesInteger; i++) {
289 gdouble angle = ((double)i) * M_PI * 2.0 / numberOfSidesInteger;
290 cairo_line_to(cairoTarget, cos(angle) * outsideDiameter / 2.0, sin(angle) * outsideDiameter / 2.0);
297 gerbv_draw_aperture_hole(cairo_t* cairoTarget, gdouble dimensionX, gdouble dimensionY, gboolean pixelOutput) {
309 draw_update_macro_exposure(
310 cairo_t* cairoTarget, cairo_operator_t clearOperator, cairo_operator_t darkOperator, gdouble exposureSetting
313 if (exposureSetting == 0.0) {
314 cairo_set_operator(cairoTarget, clearOperator);
315 }
else if (exposureSetting == 1.0) {
316 cairo_set_operator(cairoTarget, darkOperator);
317 }
else if (exposureSetting == 2.0) {
319 cairo_operator_t currentOperator = cairo_get_operator(cairoTarget);
320 if (currentOperator == clearOperator) {
321 cairo_set_operator(cairoTarget, darkOperator);
323 cairo_set_operator(cairoTarget, clearOperator);
330 cairo_t* cairoTarget, cairo_operator_t clearOperator, cairo_operator_t darkOperator, gerbv_simplified_amacro_t* s,
331 gint usesClearPrimitive, gdouble pixelWidth,
enum draw_mode drawMode,
gerbv_selection_info_t* selectionInfo,
334 gerbv_simplified_amacro_t* ls = s;
335 gboolean doVectorExportFix;
336 double bg_r, bg_g, bg_b;
339 dprintf(
"Drawing simplified aperture macros:\n");
341 doVectorExportFix = draw_do_vector_export_fix(cairoTarget, &bg_r, &bg_g, &bg_b);
343 switch (cairo_surface_get_type(cairo_get_target(cairoTarget))) {
345 case CAIRO_SURFACE_TYPE_PDF:
346 case CAIRO_SURFACE_TYPE_PS:
347 case CAIRO_SURFACE_TYPE_SVG:
350 pixelWidth = DBL_MIN;
357 if (usesClearPrimitive)
358 cairo_push_group(cairoTarget);
366 cairo_save(cairoTarget);
367 cairo_new_path(cairoTarget);
374 draw_update_macro_exposure(cairoTarget, clearOperator, darkOperator, ls->parameter[CIRCLE_EXPOSURE]);
375 cairo_translate(cairoTarget, ls->parameter[CIRCLE_CENTER_X], ls->parameter[CIRCLE_CENTER_Y]);
378 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
379 cairo_save(cairoTarget);
380 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
381 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
383 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
385 cairo_restore(cairoTarget);
390 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
394 draw_update_macro_exposure(cairoTarget, clearOperator, darkOperator, ls->parameter[OUTLINE_EXPOSURE]);
395 cairo_rotate(cairoTarget, DEG2RAD(ls->parameter[OUTLINE_ROTATION_IDX(ls->parameter)]));
396 cairo_move_to(cairoTarget, ls->parameter[OUTLINE_FIRST_X], ls->parameter[OUTLINE_FIRST_Y]);
398 for (
int point = 1; point < 1 + (int)ls->parameter[OUTLINE_NUMBER_OF_POINTS]; point++) {
400 cairoTarget, ls->parameter[OUTLINE_X_IDX_OF_POINT(point)],
401 ls->parameter[OUTLINE_Y_IDX_OF_POINT(point)]
405 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
406 cairo_save(cairoTarget);
407 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
408 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
410 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
412 cairo_restore(cairoTarget);
421 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
425 draw_update_macro_exposure(cairoTarget, clearOperator, darkOperator, ls->parameter[POLYGON_EXPOSURE]);
426 cairo_translate(cairoTarget, ls->parameter[POLYGON_CENTER_X], ls->parameter[POLYGON_CENTER_Y]);
428 cairoTarget, ls->parameter[POLYGON_DIAMETER], ls->parameter[POLYGON_NUMBER_OF_POINTS],
429 ls->parameter[POLYGON_ROTATION]
432 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
433 cairo_save(cairoTarget);
434 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
435 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
437 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
439 cairo_restore(cairoTarget);
444 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
449 gdouble diameter, diameterDifference, crosshairRadius;
451 cairo_translate(cairoTarget, ls->parameter[MOIRE_CENTER_X], ls->parameter[MOIRE_CENTER_Y]);
452 cairo_rotate(cairoTarget, DEG2RAD(ls->parameter[MOIRE_ROTATION]));
453 diameter = ls->parameter[MOIRE_OUTSIDE_DIAMETER] - ls->parameter[MOIRE_CIRCLE_THICKNESS];
454 diameterDifference = 2 * (ls->parameter[MOIRE_GAP_WIDTH] + ls->parameter[MOIRE_CIRCLE_THICKNESS]);
455 cairo_set_line_width(cairoTarget, ls->parameter[MOIRE_CIRCLE_THICKNESS]);
457 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
458 cairo_save(cairoTarget);
459 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
460 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
463 for (
int circle = 0; circle < (int)ls->parameter[MOIRE_NUMBER_OF_CIRCLES]; circle++) {
464 gdouble dia = diameter - diameterDifference * circle;
467 GERB_COMPILE_WARNING(
469 "with non positive diameter"),
476 draw_stroke(cairoTarget, drawMode, selectionInfo, image, net);
479 cairo_set_line_width(cairoTarget, ls->parameter[MOIRE_CROSSHAIR_THICKNESS]);
480 crosshairRadius = ls->parameter[MOIRE_CROSSHAIR_LENGTH] / 2.0;
481 cairo_move_to(cairoTarget, -crosshairRadius, 0);
482 cairo_line_to(cairoTarget, crosshairRadius, 0);
483 cairo_move_to(cairoTarget, 0, -crosshairRadius);
484 cairo_line_to(cairoTarget, 0, crosshairRadius);
486 draw_stroke(cairoTarget, drawMode, selectionInfo, image, net);
488 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
489 cairo_restore(cairoTarget);
496 gdouble startAngle1, startAngle2, endAngle1, endAngle2;
498 cairo_translate(cairoTarget, ls->parameter[THERMAL_CENTER_X], ls->parameter[THERMAL_CENTER_Y]);
499 cairo_rotate(cairoTarget, DEG2RAD(ls->parameter[THERMAL_ROTATION]));
501 asin(ls->parameter[THERMAL_CROSSHAIR_THICKNESS] / ls->parameter[THERMAL_INSIDE_DIAMETER]);
502 endAngle1 = M_PI_2 - startAngle1;
504 asin(ls->parameter[THERMAL_CROSSHAIR_THICKNESS] / ls->parameter[THERMAL_OUTSIDE_DIAMETER]);
505 startAngle2 = M_PI_2 - endAngle2;
507 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
508 cairo_save(cairoTarget);
509 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
510 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
514 cairo_restore(cairoTarget);
519 for (gint i = 0; i < 4; i++) {
521 cairoTarget, 0, 0, ls->parameter[THERMAL_INSIDE_DIAMETER] / 2.0, startAngle1, endAngle1
524 cairoTarget, 0, 0, ls->parameter[THERMAL_OUTSIDE_DIAMETER] / 2.0, startAngle2, endAngle2
526 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
527 cairo_rotate(cairoTarget, M_PI_2);
533 draw_update_macro_exposure(cairoTarget, clearOperator, darkOperator, ls->parameter[LINE20_EXPOSURE]);
534 cairo_set_line_width(cairoTarget, MAX(ls->parameter[LINE20_LINE_WIDTH], pixelWidth));
535 cairo_set_line_cap(cairoTarget, CAIRO_LINE_CAP_BUTT);
536 cairo_rotate(cairoTarget, DEG2RAD(ls->parameter[LINE20_ROTATION]));
537 cairo_move_to(cairoTarget, ls->parameter[LINE20_START_X], ls->parameter[LINE20_START_Y]);
538 cairo_line_to(cairoTarget, ls->parameter[LINE20_END_X], ls->parameter[LINE20_END_Y]);
540 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
541 cairo_save(cairoTarget);
542 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
543 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
545 draw_stroke(cairoTarget, drawMode, selectionInfo, image, net);
547 cairo_restore(cairoTarget);
552 draw_stroke(cairoTarget, drawMode, selectionInfo, image, net);
556 draw_update_macro_exposure(cairoTarget, clearOperator, darkOperator, ls->parameter[LINE21_EXPOSURE]);
557 cairo_rotate(cairoTarget, DEG2RAD(ls->parameter[LINE21_ROTATION]));
558 cairo_translate(cairoTarget, ls->parameter[LINE21_CENTER_X], ls->parameter[LINE21_CENTER_Y]);
560 cairoTarget, -MAX(ls->parameter[LINE21_WIDTH] / 2.0, pixelWidth),
561 -MAX(ls->parameter[LINE21_HEIGHT] / 2.0, pixelWidth), MAX(ls->parameter[LINE21_WIDTH], pixelWidth),
562 MAX(ls->parameter[LINE21_HEIGHT], pixelWidth)
564 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
565 cairo_save(cairoTarget);
566 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
567 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
569 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
571 cairo_restore(cairoTarget);
576 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
580 draw_update_macro_exposure(cairoTarget, clearOperator, darkOperator, ls->parameter[LINE22_EXPOSURE]);
581 cairo_rotate(cairoTarget, DEG2RAD(ls->parameter[LINE22_ROTATION]));
582 cairo_translate(cairoTarget, ls->parameter[LINE22_LOWER_LEFT_X], ls->parameter[LINE22_LOWER_LEFT_Y]);
584 cairoTarget, 0, 0, MAX(ls->parameter[LINE22_WIDTH], pixelWidth),
585 MAX(ls->parameter[LINE22_HEIGHT], pixelWidth)
588 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
589 cairo_save(cairoTarget);
590 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
591 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
593 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
595 cairo_restore(cairoTarget);
600 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
606 cairo_restore(cairoTarget);
610 if (usesClearPrimitive) {
611 cairo_pop_group_to_source(cairoTarget);
612 cairo_paint(cairoTarget);
619 draw_apply_netstate_transformation(cairo_t* cairoTarget,
gerbv_netstate_t* state) {
626 case GERBV_MIRROR_STATE_FLIPA: cairo_scale(cairoTarget, -1, 1);
break;
627 case GERBV_MIRROR_STATE_FLIPB: cairo_scale(cairoTarget, 1, -1);
break;
628 case GERBV_MIRROR_STATE_FLIPAB: cairo_scale(cairoTarget, -1, -1);
break;
632 if (state->
axisSelect == GERBV_AXIS_SELECT_SWAPAB) {
635 cairo_rotate(cairoTarget, M_PI + M_PI_2);
636 cairo_scale(cairoTarget, 1, -1);
641 draw_render_polygon_object(
646 int haveDrawnFirstFillPoint = 0;
647 gdouble x2, y2, cp_x = 0, cp_y = 0;
649 haveDrawnFirstFillPoint = FALSE;
652 polygonStartNet = oldNet;
653 cairo_new_path(cairoTarget);
655 for (currentNet = oldNet->
next; currentNet != NULL; currentNet = currentNet->
next) {
656 x2 = currentNet->
stop_x + sr_x;
657 y2 = currentNet->
stop_y + sr_y;
661 cp_x = currentNet->
cirseg->cp_x + sr_x;
662 cp_y = currentNet->
cirseg->cp_y + sr_y;
664 if (!haveDrawnFirstFillPoint) {
666 haveDrawnFirstFillPoint = TRUE;
677 if (currentNet->
cirseg->angle2 > currentNet->
cirseg->angle1) {
679 cairoTarget, cp_x, cp_y, currentNet->
cirseg->width / 2.0, DEG2RAD(currentNet->
cirseg->angle1),
680 DEG2RAD(currentNet->
cirseg->angle2)
684 cairoTarget, cp_x, cp_y, currentNet->
cirseg->width / 2.0, DEG2RAD(currentNet->
cirseg->angle1),
685 DEG2RAD(currentNet->
cirseg->angle2)
690 cairo_close_path(cairoTarget);
693 cairo_antialias_t oldAlias = cairo_get_antialias(cairoTarget);
694 cairo_set_antialias(cairoTarget, CAIRO_ANTIALIAS_NONE);
695 draw_fill(cairoTarget, drawMode, selectionInfo, image, polygonStartNet);
696 cairo_set_antialias(cairoTarget, oldAlias);
710 cairo_move_to(cairoTarget, xc, yc - r);
711 cairo_rel_line_to(cairoTarget, 0, 2 * r);
712 cairo_move_to(cairoTarget, xc - r, yc);
713 cairo_rel_line_to(cairoTarget, 2 * r, 0);
714 cairo_stroke(cairoTarget);
718 draw_calc_pnp_mark_coords(
struct gerbv_net* start_net,
double* label_x,
double* label_y) {
721 const char*
label = NULL;
723 if (net && net->
label)
742 y = MAX(y, net->
stop_y + 0.01 / 2);
754 draw_image_to_cairo_target(
755 cairo_t* cairoTarget,
gerbv_image_t* image, gdouble pixelWidth,
enum draw_mode drawMode,
759 const int hole_cross_inc_px = 8;
760 struct gerbv_net *net, *polygonStartNet = NULL;
761 double x1, y1, x2, y2, cp_x = 0, cp_y = 0;
762 gdouble * p, p0, p1, dx, dy, lineWidth, r;
765 cairo_operator_t drawOperatorClear, drawOperatorDark;
766 gboolean invertPolarity = FALSE, oddWidth = FALSE;
767 gdouble minX = 0, minY = 0, maxX = 0, maxY = 0;
768 gdouble criticalRadius;
769 gdouble scaleX = transform.
scaleX;
770 gdouble scaleY = transform.
scaleY;
772 gdouble pnp_label_scale_x = 1, pnp_label_scale_y = -1;
773 gboolean limitLineWidth = TRUE;
774 gboolean displayPixel = TRUE;
775 gboolean doVectorExportFix;
776 double bg_r, bg_g, bg_b;
778 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 16, 0)
781 cairo_surface_t* cSurface = cairo_get_target(cairoTarget);
782 if (cairo_surface_get_type(cSurface) == CAIRO_SURFACE_TYPE_SVG) {
783 cairo_svg_surface_set_document_unit(cSurface, CAIRO_SVG_UNIT_PT);
787 doVectorExportFix = draw_do_vector_export_fix(cairoTarget, &bg_r, &bg_g, &bg_b);
791 if ((scaleX != 1) || (scaleY != 1)) {
792 limitLineWidth = FALSE;
797 pnp_label_scale_y = 1;
802 pnp_label_scale_x = -1;
806 cairo_scale(cairoTarget, scaleX, scaleY);
807 cairo_rotate(cairoTarget, transform.
rotation);
809 gboolean useOptimizations = allowOptimization;
813 if (fabs(transform.
translateX) > GERBV_PRECISION_LINEAR_INCH
814 || fabs(transform.
translateY) > GERBV_PRECISION_LINEAR_INCH
815 || fabs(transform.
scaleX - 1) > GERBV_PRECISION_LINEAR_INCH
816 || fabs(transform.
scaleY - 1) > GERBV_PRECISION_LINEAR_INCH
818 useOptimizations = FALSE;
820 if (useOptimizations && pixelOutput) {
828 cairo_translate(cairoTarget, image->
info->imageJustifyOffsetActualA, image->
info->imageJustifyOffsetActualB);
831 cairo_set_fill_rule(cairoTarget, CAIRO_FILL_RULE_EVEN_ODD);
833 cairo_translate(cairoTarget, image->
info->offsetA, image->
info->offsetB);
835 cairo_rotate(cairoTarget, image->
info->imageRotation);
838 invertPolarity = transform.
inverted;
840 invertPolarity = !invertPolarity;
841 if (drawMode == DRAW_SELECTIONS)
842 invertPolarity = FALSE;
844 if (invertPolarity) {
845 drawOperatorClear = CAIRO_OPERATOR_OVER;
846 drawOperatorDark = CAIRO_OPERATOR_CLEAR;
847 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
848 cairo_paint(cairoTarget);
849 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_CLEAR);
851 drawOperatorClear = CAIRO_OPERATOR_CLEAR;
852 drawOperatorDark = CAIRO_OPERATOR_OVER;
858 cairo_save(cairoTarget);
859 cairo_save(cairoTarget);
865 const char* pnp_net_label_str_prev = NULL;
870 if (net->
layer != oldLayer) {
873 cairo_restore(cairoTarget);
874 cairo_restore(cairoTarget);
875 cairo_save(cairoTarget);
880 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_CLEAR);
881 drawOperatorClear = CAIRO_OPERATOR_OVER;
882 drawOperatorDark = CAIRO_OPERATOR_CLEAR;
884 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
885 drawOperatorClear = CAIRO_OPERATOR_CLEAR;
886 drawOperatorDark = CAIRO_OPERATOR_OVER;
891 if (ko->firstInstance == TRUE) {
892 cairo_save(cairoTarget);
895 cairo_set_operator(cairoTarget, drawOperatorClear);
897 cairo_set_operator(cairoTarget, drawOperatorDark);
900 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
902 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
903 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
906 cairo_new_path(cairoTarget);
908 cairoTarget, ko->lowerLeftX - ko->border, ko->lowerLeftY - ko->border, ko->width + 2 * ko->border,
909 ko->height + 2 * ko->border
911 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
913 cairo_restore(cairoTarget);
917 cairo_save(cairoTarget);
918 draw_apply_netstate_transformation(cairoTarget, net->
state);
919 oldLayer = net->
layer;
923 if (net->
state != oldState) {
926 cairo_restore(cairoTarget);
927 cairo_save(cairoTarget);
930 draw_apply_netstate_transformation(cairoTarget, net->
state);
931 oldState = net->
state;
936 if (drawMode == DRAW_SELECTIONS) {
941 if (!polygonStartNet) {
950 if (drawMode != DRAW_SELECTIONS && net->
label
953 && g_strcmp0(net->
label->str, pnp_net_label_str_prev)) {
955 double mark_x, mark_y;
959 pnp_net_label_str_prev = net->
label->str;
961 if (draw_calc_pnp_mark_coords(net, &mark_x, &mark_y)) {
962 cairo_save(cairoTarget);
964 cairo_set_font_size(cairoTarget, 0.05);
965 cairo_move_to(cairoTarget, mark_x, mark_y);
966 cairo_scale(cairoTarget, pnp_label_scale_x, pnp_label_scale_y);
967 cairo_show_text(cairoTarget, net->
label->str);
969 cairo_restore(cairoTarget);
976 for (ix = 0; ix < sr->X; ix++) {
977 for (iy = 0; iy < sr->Y; iy++) {
978 double sr_x = ix * sr->dist_X;
979 double sr_y = iy * sr->dist_Y;
981 if (useOptimizations && pixelOutput
994 cp_x = net->
cirseg->cp_x + sr_x;
995 cp_y = net->
cirseg->cp_y + sr_y;
1002 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
1004 cairo_save(cairoTarget);
1006 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
1007 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
1009 draw_render_polygon_object(
1010 net, cairoTarget, sr_x, sr_y, image, drawMode, selectionInfo, pixelOutput
1013 cairo_restore(cairoTarget);
1015 draw_render_polygon_object(
1016 net, cairoTarget, sr_x, sr_y, image, drawMode, selectionInfo, pixelOutput
1042 && ((image->
aperture[net->
aperture]->parameter[0] < pixelWidth) && (pixelOutput)))
1043 criticalRadius = pixelWidth / 2.0;
1046 lineWidth = criticalRadius * 2.0;
1048 cairo_user_to_device_distance(cairoTarget, &lineWidth, &x1);
1050 lineWidth = round(lineWidth);
1051 if ((
int)lineWidth % 2) {
1057 cairo_device_to_user_distance(cairoTarget, &lineWidth, &x1);
1058 cairo_set_line_width(cairoTarget, lineWidth);
1065 cairo_set_line_cap(cairoTarget, CAIRO_LINE_CAP_ROUND);
1075 cairo_set_line_width(cairoTarget, pixelWidth);
1076 cairo_set_line_cap(cairoTarget, CAIRO_LINE_CAP_SQUARE);
1078 + hole_cross_inc_px * pixelWidth;
1081 cairo_set_line_cap(cairoTarget, CAIRO_LINE_CAP_ROUND);
1082 cairo_set_line_width(cairoTarget, lineWidth);
1088 if (doVectorExportFix
1089 && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
1090 cairo_save(cairoTarget);
1091 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
1092 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
1094 draw_stroke(cairoTarget, drawMode, selectionInfo, image, net);
1096 cairo_restore(cairoTarget);
1098 draw_stroke(cairoTarget, drawMode, selectionInfo, image, net);
1109 cairo_new_path(cairoTarget);
1116 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
1123 draw_stroke(cairoTarget, drawMode, selectionInfo, image, net);
1127 GERB_COMPILE_WARNING(
1128 _(
"Unknown aperture type: %s"),
1139 cairo_new_path(cairoTarget);
1141 cairo_set_line_cap(cairoTarget, CAIRO_LINE_CAP_SQUARE);
1143 cairo_set_line_cap(cairoTarget, CAIRO_LINE_CAP_ROUND);
1145 cairo_save(cairoTarget);
1146 cairo_translate(cairoTarget, cp_x, cp_y);
1147 cairo_scale(cairoTarget, net->
cirseg->width, net->
cirseg->height);
1150 cairoTarget, 0.0, 0.0, 0.5, DEG2RAD(net->
cirseg->angle1),
1151 DEG2RAD(net->
cirseg->angle2)
1155 cairoTarget, 0.0, 0.0, 0.5, DEG2RAD(net->
cirseg->angle1),
1156 DEG2RAD(net->
cirseg->angle2)
1159 cairo_restore(cairoTarget);
1160 draw_stroke(cairoTarget, drawMode, selectionInfo, image, net);
1163 GERB_COMPILE_WARNING(
1173 cairo_save(cairoTarget);
1181 cairo_set_line_width(cairoTarget, pixelWidth);
1182 cairo_set_line_cap(cairoTarget, CAIRO_LINE_CAP_SQUARE);
1183 r = p[0] / 2.0 + hole_cross_inc_px * pixelWidth;
1185 cairo_set_line_width(cairoTarget, lineWidth);
1186 cairo_set_line_cap(cairoTarget, CAIRO_LINE_CAP_ROUND);
1190 gerbv_draw_aperture_hole(cairoTarget, p[1], p[2], pixelOutput);
1195 displayPixel = pixelOutput;
1198 if (limitLineWidth && (p[0] < pixelWidth) && pixelOutput) {
1200 displayPixel = FALSE;
1202 if (limitLineWidth && (p[1] < pixelWidth) && pixelOutput) {
1204 displayPixel = FALSE;
1207 gerbv_draw_aperture_hole(cairoTarget, p[2], p[3], displayPixel);
1211 gerbv_draw_aperture_hole(cairoTarget, p[2], p[3], pixelOutput);
1214 gerbv_draw_polygon(cairoTarget, p[0], p[1], p[2]);
1215 gerbv_draw_aperture_hole(cairoTarget, p[3], p[4], pixelOutput);
1221 cairoTarget, drawOperatorClear, drawOperatorDark,
1222 image->
aperture[net->
aperture]->simplified, (gint)p[0], pixelWidth, drawMode,
1223 selectionInfo, image, net
1227 GERB_COMPILE_WARNING(
1228 _(
"Unknown aperture type: %s"),
1235 if (doVectorExportFix && CAIRO_OPERATOR_CLEAR == cairo_get_operator(cairoTarget)) {
1236 cairo_set_source_rgba(cairoTarget, bg_r, bg_g, bg_b, 1.0);
1237 cairo_set_operator(cairoTarget, CAIRO_OPERATOR_OVER);
1240 draw_fill(cairoTarget, drawMode, selectionInfo, image, net);
1241 cairo_restore(cairoTarget);
1244 GERB_COMPILE_WARNING(
1255 cairo_restore(cairoTarget);
1256 cairo_restore(cairoTarget);
1264 draw_do_vector_export_fix(cairo_t* cairoTarget,
double* bg_red,
double* bg_green,
double* bg_blue) {
1271 switch (cairo_surface_get_type(cairo_get_target(cairoTarget))) {
1273 case CAIRO_SURFACE_TYPE_PDF:
1274 case CAIRO_SURFACE_TYPE_PS:
1275 case CAIRO_SURFACE_TYPE_SVG:
1277 double *p0, *p1, *p2;
1281 p0 = cairo_get_user_data(cairoTarget, (cairo_user_data_key_t*)0);
1282 p1 = cairo_get_user_data(cairoTarget, (cairo_user_data_key_t*)1);
1283 p2 = cairo_get_user_data(cairoTarget, (cairo_user_data_key_t*)2);
1285 if (p0 != NULL && p1 != NULL && p2 != NULL) {
1290 *bg_red = *bg_green = *bg_blue = 1.0;
1296 default:
return FALSE;
void draw_cairo_translate_adjust(cairo_t *cairoTarget, gdouble x, gdouble y, gboolean pixelOutput)
Cairo translate user-space origin.
static gboolean draw_net_is_in_selection_buffer_remove(gerbv_net_t *net, gerbv_selection_info_t *selectionInfo, gboolean remove)
Check if net is in selection buffer and possibly deselect it.
static void draw_cairo_cross(cairo_t *cairoTarget, gdouble xc, gdouble yc, gdouble r)
Draw Cairo cross.
static void gerbv_draw_rectangle(cairo_t *cairoTarget, gdouble width, gdouble height, gboolean pixelOutput)
Draw the rectangle centered at current Cairo coordinates.
void draw_cairo_line_to(cairo_t *cairoTarget, gdouble x, gdouble y, gboolean adjustByHalf, gboolean pixelOutput)
Draw Cairo line from current coordinates.
void draw_cairo_move_to(cairo_t *cairoTarget, gdouble x, gdouble y, gboolean oddWidth, gboolean pixelOutput)
Move Cairo coordinates.
static void gerbv_draw_oblong(cairo_t *cairoTarget, gdouble width, gdouble height)
Draw the oblong centered at current Cairo coordinates.
static void gerbv_draw_circle(cairo_t *cairoTarget, gdouble diameter)
Draw the circle centered at current Cairo coordinates.
Header info for the cairo rendering functions and the related selection calculating 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.
const char * gerbv_interpolation_name(gerbv_interpolation_t interp)
Return string name of gerbv_interpolation_t interpolation.
const char * gerbv_aperture_type_name(gerbv_aperture_type_t type)
Return string name of gerbv_aperture_type_t aperture type.
The main header file for the libgerbv library.
@ GERBV_APERTURE_STATE_OFF
@ GERBV_APERTURE_STATE_ON
@ GERBV_APERTURE_STATE_FLASH
@ GERBV_POLARITY_NEGATIVE
@ GERBV_SELECTION_POINT_CLICK
@ GERBV_SELECTION_DRAG_BOX
@ GERBV_APTYPE_MACRO_LINE20
@ GERBV_APTYPE_MACRO_LINE21
@ GERBV_APTYPE_MACRO_OUTLINE
@ GERBV_APTYPE_MACRO_CIRCLE
@ GERBV_APTYPE_MACRO_POLYGON
@ GERBV_APTYPE_MACRO_THERMAL
@ GERBV_APTYPE_MACRO_LINE22
@ GERBV_APTYPE_MACRO_MOIRE
@ GERBV_INTERPOLATION_LINEARx01
@ GERBV_INTERPOLATION_PAREA_START
@ GERBV_INTERPOLATION_LINEARx001
@ GERBV_INTERPOLATION_DELETED
@ GERBV_INTERPOLATION_CW_CIRCULAR
@ GERBV_INTERPOLATION_PAREA_END
@ GERBV_INTERPOLATION_LINEARx10
@ GERBV_INTERPOLATION_CCW_CIRCULAR
@ GERBV_INTERPOLATION_LINEARx1
@ GERBV_LAYERTYPE_PICKANDPLACE_BOT
@ GERBV_LAYERTYPE_PICKANDPLACE_TOP
Header info for the selection support functions for libgerbv.
gerbv_layertype_t layertype
gerbv_aperture_t * aperture[APERTURE_MAX]
gerbv_netstate_t * states
gerbv_image_info_t * info
gerbv_step_and_repeat_t stepAndRepeat
gerbv_polarity_t polarity
gerbv_knockout_t knockout
gerbv_render_size_t boundingBox
gerbv_aperture_state_t aperture_state
gerbv_interpolation_t interpolation
gerbv_axis_select_t axisSelect
gerbv_mirror_state_t mirrorState
gboolean show_cross_on_drill_holes