static void draw_letter_V(float x, float y, VMDDisplayList *disp) { // draw the down stroke (note the order, this is because of the // way I define the coordinates in the draw_stroke routine for width) draw_stroke(x+STROKE_WIDTH*(1.5f), y+0, x+STROKE_WIDTH/2.0f, y+1.0f, disp); // and the up stroke draw_stroke(x+STROKE_WIDTH*(1.5f), y+0, x+STROKE_WIDTH*2.5f, y+1.0f, disp); }
int ca_test_stroke(caskbench_context_t *ctx) { cairo_t *cr = ctx->cairo_cr; if(ctx->shape_defaults.animation) { int num_particles = ctx->shape_defaults.animation; double start_frame, stop_frame, delta; particles = (kinetics_t *) malloc (sizeof (kinetics_t) * num_particles); int i,j; for (i = 0; i < num_particles; i++) kinetics_init (&particles[i], ctx); for (j=0;j<num_particles;j++){ cairo_set_source_rgb (cr, 1, 1, 1); cairo_rectangle (cr, 0, 0, ctx->canvas_width ,ctx->canvas_height); cairo_fill (cr); for (i = 0; i < num_particles; i++) { kinetics_update(&particles[i], 0.1); draw_stroke(ctx, &particles[i]); } } } else { draw_stroke(ctx, NULL); } return 1; }
static void draw_letter_M(float x, float y, VMDDisplayList *disp) { // up draw_stroke(x+STROKE_WIDTH/2.0f, y, x+STROKE_WIDTH*1.5f, y+1.0f, disp); // down draw_stroke(x+STROKE_WIDTH*2.5f, y, x+STROKE_WIDTH*1.5f, y+1.0f, disp); // up draw_stroke(x+STROKE_WIDTH*2.5f, y, x+STROKE_WIDTH*3.5f, y+1.0f, disp); // down draw_stroke(x+STROKE_WIDTH*4.5f, y, x+STROKE_WIDTH*3.5f, y+1.0f, disp); }
gfxpoly_t* gfxpoly_from_stroke(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit, double gridsize) { gfxdrawer_t d; gfxdrawer_target_poly(&d, gridsize); draw_stroke(line, &d, width, cap_style, joint_style, miterLimit); gfxpoly_t*poly = (gfxpoly_t*)d.result(&d); assert(gfxpoly_check(poly, 1)); gfxpoly_t*poly2 = gfxpoly_process(poly, 0, &windrule_circular, &onepolygon); gfxpoly_destroy(poly); return poly2; }
// display ink object void draw_ink (PtrInk ink) { int nStrokes; PtrStroke stroke = NULL; if (ink == NULL) return; stroke = ink->firstStroke; nStrokes = get_num_of_strokes (ink); SB_INKPRINTF("nStrokes=%d\n", nStrokes); if (stroke == NULL || nStrokes <= 0) { return; } while (stroke) { draw_stroke (stroke); stroke = stroke->nextStroke; } }
// This one is tricky static void draw_letter_D(float x, float y, VMDDisplayList *disp) { // up draw_stroke(x+STROKE_WIDTH/2.0f, y, x+STROKE_WIDTH/2.0f, y+1.0f, disp); // and the curve float stepsize = (float) VMD_PI/60; float offset[3] = {STROKE_WIDTH, 0.5f, 0.0f}; offset[0] += x; offset[1] += y; float c[8][3]; int i, j; for (i=0; i<60; i++) { // inside coords find_ellipse_coords(stepsize*i, 0.5f - STROKE_WIDTH, STROKE_WIDTH, c[1]); find_ellipse_coords(stepsize*(i+1), 0.5f - STROKE_WIDTH, STROKE_WIDTH, c[2]); // outside coords find_ellipse_coords(stepsize * i, 0.5 , STROKE_WIDTH * 2, c[0]); find_ellipse_coords(stepsize * (i+1), 0.5 , STROKE_WIDTH * 2, c[3]); // add the offsets for (j=0; j<4; j++) vec_add(c[j], c[j], offset); draw_outsides(c, disp, FALSE); } }
int draw_image_to_cairo_target (cairo_t *cairoTarget, gerbv_image_t *image, gdouble pixelWidth, enum draw_mode drawMode, gerbv_selection_info_t *selectionInfo, gerbv_render_info_t *renderInfo, gboolean allowOptimization, gerbv_user_transformation_t transform, gboolean pixelOutput) { const int hole_cross_inc_px = 8; struct gerbv_net *net, *polygonStartNet=NULL; double x1, y1, x2, y2, cp_x=0, cp_y=0; gdouble *p, p0, p1, dx, dy, lineWidth, r; gerbv_netstate_t *oldState; gerbv_layer_t *oldLayer; cairo_operator_t drawOperatorClear, drawOperatorDark; gboolean invertPolarity = FALSE, oddWidth = FALSE; gdouble minX=0, minY=0, maxX=0, maxY=0; gdouble criticalRadius; gdouble scaleX = transform.scaleX; gdouble scaleY = transform.scaleY; gboolean limitLineWidth = TRUE; gboolean displayPixel = TRUE; /* If we are scaling the image at all, ignore the line width checks * since scaled up lines can still be visible */ if ((scaleX != 1)||(scaleY != 1)){ limitLineWidth = FALSE; } if (transform.mirrorAroundX) scaleY *= -1; if (transform.mirrorAroundY) scaleX *= -1; cairo_translate (cairoTarget, transform.translateX, transform.translateY); cairo_scale (cairoTarget, scaleX, scaleY); cairo_rotate (cairoTarget, transform.rotation); gboolean useOptimizations = allowOptimization; /* If the user is using any transformations for this layer, then don't * bother using rendering optimizations */ if ((fabs(transform.translateX) > 0.00001) || (fabs(transform.translateY) > 0.00001) || (fabs(transform.scaleX - 1) > 0.00001) || (fabs(transform.scaleY - 1) > 0.00001) || (fabs(transform.rotation) > 0.00001) || transform.mirrorAroundX || transform.mirrorAroundY) useOptimizations = FALSE; if (useOptimizations && pixelOutput) { minX = renderInfo->lowerLeftX; minY = renderInfo->lowerLeftY; maxX = renderInfo->lowerLeftX + (renderInfo->displayWidth / renderInfo->scaleFactorX); maxY = renderInfo->lowerLeftY + (renderInfo->displayHeight / renderInfo->scaleFactorY); } /* do initial justify */ cairo_translate (cairoTarget, image->info->imageJustifyOffsetActualA, image->info->imageJustifyOffsetActualB); /* set the fill rule so aperture holes are cleared correctly */ cairo_set_fill_rule (cairoTarget, CAIRO_FILL_RULE_EVEN_ODD); /* offset image */ cairo_translate (cairoTarget, image->info->offsetA, image->info->offsetB); /* do image rotation */ cairo_rotate (cairoTarget, image->info->imageRotation); /* load in polarity operators depending on the image polarity */ invertPolarity = transform.inverted; if (image->info->polarity == GERBV_POLARITY_NEGATIVE) invertPolarity = !invertPolarity; if (drawMode == DRAW_SELECTIONS) invertPolarity = FALSE; if (invertPolarity) { drawOperatorClear = CAIRO_OPERATOR_OVER; drawOperatorDark = CAIRO_OPERATOR_CLEAR; cairo_set_operator (cairoTarget, CAIRO_OPERATOR_OVER); cairo_paint (cairoTarget); cairo_set_operator (cairoTarget, CAIRO_OPERATOR_CLEAR); } else { drawOperatorClear = CAIRO_OPERATOR_CLEAR; drawOperatorDark = CAIRO_OPERATOR_OVER; } /* next, push two cairo states to simulate the first layer and netstate translations (these will be popped when another layer or netstate is started */ cairo_save (cairoTarget); cairo_save (cairoTarget); /* store the current layer and netstate so we know when they change */ oldLayer = image->layers; oldState = image->states; for (net = image->netlist->next; net != NULL; net = gerbv_image_return_next_renderable_object(net)) { /* check if this is a new layer */ if (net->layer != oldLayer){ /* it's a new layer, so recalculate the new transformation matrix for it */ cairo_restore (cairoTarget); cairo_restore (cairoTarget); cairo_save (cairoTarget); /* do any rotations */ cairo_rotate (cairoTarget, net->layer->rotation); /* handle the layer polarity */ if ((net->layer->polarity == GERBV_POLARITY_CLEAR)^invertPolarity) { cairo_set_operator (cairoTarget, CAIRO_OPERATOR_CLEAR); drawOperatorClear = CAIRO_OPERATOR_OVER; drawOperatorDark = CAIRO_OPERATOR_CLEAR; } else { cairo_set_operator (cairoTarget, CAIRO_OPERATOR_OVER); drawOperatorClear = CAIRO_OPERATOR_CLEAR; drawOperatorDark = CAIRO_OPERATOR_OVER; } /* Draw any knockout areas */ gerbv_knockout_t *ko = &net->layer->knockout; if (ko->firstInstance == TRUE) { cairo_operator_t oldOperator = cairo_get_operator (cairoTarget); if (ko->polarity == GERBV_POLARITY_CLEAR) { cairo_set_operator (cairoTarget, drawOperatorClear); } else { cairo_set_operator (cairoTarget, drawOperatorDark); } cairo_new_path (cairoTarget); cairo_rectangle (cairoTarget, ko->lowerLeftX - ko->border, ko->lowerLeftY - ko->border, ko->width + 2*ko->border, ko->height + 2*ko->border); draw_fill (cairoTarget, drawMode, selectionInfo, image, net); cairo_set_operator (cairoTarget, oldOperator); } /* Finally, reapply old netstate transformation */ cairo_save (cairoTarget); draw_apply_netstate_transformation (cairoTarget, net->state); oldLayer = net->layer; } /* check if this is a new netstate */ if (net->state != oldState){ /* pop the transformation matrix back to the "pre-state" state and resave it */ cairo_restore (cairoTarget); cairo_save (cairoTarget); /* it's a new state, so recalculate the new transformation matrix for it */ draw_apply_netstate_transformation (cairoTarget, net->state); oldState = net->state; } /* if we are only drawing from the selection buffer, search if this net is in the buffer */ if (drawMode == DRAW_SELECTIONS) { /* this flag makes sure we don't draw any unintentional polygons... if we've successfully entered a polygon (the first net matches, and we don't want to check the nets inside the polygon) then polygonStartNet will be set */ if (!polygonStartNet) { if (!draw_net_is_in_selection_buffer_remove (net, selectionInfo, FALSE)) continue; } } /* step and repeat */ gerbv_step_and_repeat_t *sr = &net->layer->stepAndRepeat; int ix, iy; for (ix = 0; ix < sr->X; ix++) { for (iy = 0; iy < sr->Y; iy++) { double sr_x = ix * sr->dist_X; double sr_y = iy * sr->dist_Y; if (useOptimizations && pixelOutput && ((net->boundingBox.right+sr_x < minX) || (net->boundingBox.left+sr_x > maxX) || (net->boundingBox.top+sr_y < minY) || (net->boundingBox.bottom+sr_y > maxY))) { continue; } x1 = net->start_x + sr_x; y1 = net->start_y + sr_y; x2 = net->stop_x + sr_x; y2 = net->stop_y + sr_y; /* translate circular x,y data as well */ if (net->cirseg) { cp_x = net->cirseg->cp_x + sr_x; cp_y = net->cirseg->cp_y + sr_y; } /* render any labels attached to this net */ /* NOTE: this is currently only used on PNP files, so we may make some assumptions here... */ if (net->label) { cairo_set_font_size (cairoTarget, 0.05); cairo_save (cairoTarget); cairo_move_to (cairoTarget, x1, y1); cairo_scale (cairoTarget, 1, -1); cairo_show_text (cairoTarget, net->label->str); cairo_restore (cairoTarget); } /* Polygon area fill routines */ switch (net->interpolation) { case GERBV_INTERPOLATION_PAREA_START : draw_render_polygon_object (net, cairoTarget, sr_x, sr_y, image, drawMode, selectionInfo, pixelOutput); continue; case GERBV_INTERPOLATION_DELETED: continue; default : break; } /* * If aperture state is off we allow use of undefined apertures. * This happens when gerber files starts, but hasn't decided on * which aperture to use. */ if (image->aperture[net->aperture] == NULL) continue; switch (net->aperture_state) { case GERBV_APERTURE_STATE_ON : /* if the aperture width is truly 0, then render as a 1 pixel width line. 0 diameter apertures are used by some programs to draw labels, etc, and they are rendered by other programs as 1 pixel wide */ /* NOTE: also, make sure all lines are at least 1 pixel wide, so they always show up at low zoom levels */ if (limitLineWidth&&((image->aperture[net->aperture]->parameter[0] < pixelWidth)&& (pixelOutput))) criticalRadius = pixelWidth/2.0; else criticalRadius = image->aperture[net->aperture]->parameter[0]/2.0; lineWidth = criticalRadius*2.0; // convert to a pixel integer cairo_user_to_device_distance (cairoTarget, &lineWidth, &x1); if (pixelOutput) { lineWidth = round(lineWidth); if ((int)lineWidth % 2) { oddWidth = TRUE; } else { oddWidth = FALSE; } } cairo_device_to_user_distance (cairoTarget, &lineWidth, &x1); cairo_set_line_width (cairoTarget, lineWidth); switch (net->interpolation) { case GERBV_INTERPOLATION_x10 : case GERBV_INTERPOLATION_LINEARx01 : case GERBV_INTERPOLATION_LINEARx001 : case GERBV_INTERPOLATION_LINEARx1 : cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND); /* weed out any lines that are * obviously not going to * render on the visible screen */ switch (image->aperture[net->aperture]->type) { case GERBV_APTYPE_CIRCLE : if (renderInfo->show_cross_on_drill_holes && image->layertype == GERBV_LAYERTYPE_DRILL) { /* Draw center crosses on slot hole */ cairo_set_line_width (cairoTarget, pixelWidth); cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_SQUARE); r = image->aperture[net->aperture]->parameter[0]/2.0 + hole_cross_inc_px*pixelWidth; draw_cairo_cross (cairoTarget, x1, y1, r); draw_cairo_cross (cairoTarget, x2, y2, r); cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND); cairo_set_line_width (cairoTarget, lineWidth); } draw_cairo_move_to (cairoTarget, x1, y1, oddWidth, pixelOutput); draw_cairo_line_to (cairoTarget, x2, y2, oddWidth, pixelOutput); draw_stroke (cairoTarget, drawMode, selectionInfo, image, net); break; case GERBV_APTYPE_RECTANGLE : dx = image->aperture[net->aperture]->parameter[0]/2; dy = image->aperture[net->aperture]->parameter[1]/2; if(x1 > x2) dx = -dx; if(y1 > y2) dy = -dy; cairo_new_path(cairoTarget); draw_cairo_move_to (cairoTarget, x1 - dx, y1 - dy, FALSE, pixelOutput); draw_cairo_line_to (cairoTarget, x1 - dx, y1 + dy, FALSE, pixelOutput); draw_cairo_line_to (cairoTarget, x2 - dx, y2 + dy, FALSE, pixelOutput); draw_cairo_line_to (cairoTarget, x2 + dx, y2 + dy, FALSE, pixelOutput); draw_cairo_line_to (cairoTarget, x2 + dx, y2 - dy, FALSE, pixelOutput); draw_cairo_line_to (cairoTarget, x1 + dx, y1 - dy, FALSE, pixelOutput); draw_fill (cairoTarget, drawMode, selectionInfo, image, net); break; /* TODO: for now, just render ovals or polygons like a circle */ case GERBV_APTYPE_OVAL : case GERBV_APTYPE_POLYGON : draw_cairo_move_to (cairoTarget, x1,y1, oddWidth, pixelOutput); draw_cairo_line_to (cairoTarget, x2,y2, oddWidth, pixelOutput); draw_stroke (cairoTarget, drawMode, selectionInfo, image, net); break; /* macros can only be flashed, so ignore any that might be here */ default: GERB_COMPILE_WARNING(_("Skipped aperture type \"%s\""), _(aperture_names[image->aperture[net->aperture]->type])); break; } break; case GERBV_INTERPOLATION_CW_CIRCULAR : case GERBV_INTERPOLATION_CCW_CIRCULAR : /* cairo doesn't have a function to draw oval arcs, so we must * draw an arc and stretch it by scaling different x and y values */ cairo_new_path(cairoTarget); if (image->aperture[net->aperture]->type == GERBV_APTYPE_RECTANGLE) { cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_SQUARE); } else { cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND); } cairo_save (cairoTarget); cairo_translate(cairoTarget, cp_x, cp_y); cairo_scale (cairoTarget, net->cirseg->width, net->cirseg->height); if (net->cirseg->angle2 > net->cirseg->angle1) { cairo_arc (cairoTarget, 0.0, 0.0, 0.5, DEG2RAD(net->cirseg->angle1), DEG2RAD(net->cirseg->angle2)); } else { cairo_arc_negative (cairoTarget, 0.0, 0.0, 0.5, DEG2RAD(net->cirseg->angle1), DEG2RAD(net->cirseg->angle2)); } cairo_restore (cairoTarget); draw_stroke (cairoTarget, drawMode, selectionInfo, image, net); break; default : GERB_COMPILE_WARNING(_("Skipped interpolation type %d"), net->interpolation); break; } break; case GERBV_APERTURE_STATE_OFF : break; case GERBV_APERTURE_STATE_FLASH : p = image->aperture[net->aperture]->parameter; cairo_save (cairoTarget); draw_cairo_translate_adjust(cairoTarget, x2, y2, pixelOutput); switch (image->aperture[net->aperture]->type) { case GERBV_APTYPE_CIRCLE : if (renderInfo->show_cross_on_drill_holes && image->layertype == GERBV_LAYERTYPE_DRILL) { /* Draw center cross on drill hole */ cairo_set_line_width (cairoTarget, pixelWidth); cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_SQUARE); r = p[0]/2.0 + hole_cross_inc_px*pixelWidth; draw_cairo_cross (cairoTarget, 0, 0, r); cairo_set_line_width (cairoTarget, lineWidth); cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND); } gerbv_draw_circle(cairoTarget, p[0]); gerbv_draw_aperture_hole (cairoTarget, p[1], p[2], pixelOutput); break; case GERBV_APTYPE_RECTANGLE : // some CAD programs use very thin flashed rectangles to compose // logos/images, so we must make sure those display here displayPixel = pixelOutput; p0 = p[0]; p1 = p[1]; if (limitLineWidth && (p[0] < pixelWidth) && pixelOutput) { p0 = pixelWidth; displayPixel = FALSE; } if (limitLineWidth && (p[1] < pixelWidth) && pixelOutput) { p1 = pixelWidth; displayPixel = FALSE; } gerbv_draw_rectangle(cairoTarget, p0, p1, displayPixel); gerbv_draw_aperture_hole (cairoTarget, p[2], p[3], displayPixel); break; case GERBV_APTYPE_OVAL : gerbv_draw_oblong(cairoTarget, p[0], p[1]); gerbv_draw_aperture_hole (cairoTarget, p[2], p[3], pixelOutput); break; case GERBV_APTYPE_POLYGON : gerbv_draw_polygon(cairoTarget, p[0], p[1], p[2]); gerbv_draw_aperture_hole (cairoTarget, p[3], p[4], pixelOutput); break; case GERBV_APTYPE_MACRO : gerbv_draw_amacro(cairoTarget, drawOperatorClear, drawOperatorDark, image->aperture[net->aperture]->simplified, (gint)p[0], pixelWidth, drawMode, selectionInfo, image, net); break; default : GERB_MESSAGE(_("Unknown aperture type")); return 0; } /* and finally fill the path */ draw_fill (cairoTarget, drawMode, selectionInfo, image, net); cairo_restore (cairoTarget); break; default: GERB_MESSAGE(_("Unknown aperture state")); return 0; } } } } /* restore the initial two state saves (one for layer, one for netstate)*/ cairo_restore (cairoTarget); cairo_restore (cairoTarget); return 1; }
int gerbv_draw_amacro(cairo_t *cairoTarget, cairo_operator_t clearOperator, cairo_operator_t darkOperator, gerbv_simplified_amacro_t *s, gint usesClearPrimative, gdouble pixelWidth, enum draw_mode drawMode, gerbv_selection_info_t *selectionInfo, gerbv_image_t *image, struct gerbv_net *net) { int handled = 1; gerbv_simplified_amacro_t *ls = s; dprintf("Drawing simplified aperture macros:\n"); if (usesClearPrimative) cairo_push_group (cairoTarget); while (ls != NULL) { /* * This handles the exposure thing in the aperture macro * The exposure is always the first element on stack independent * of aperture macro. */ cairo_save (cairoTarget); cairo_new_path(cairoTarget); cairo_operator_t oldOperator = cairo_get_operator (cairoTarget); switch (ls->type) { case GERBV_APTYPE_MACRO_CIRCLE: if (draw_update_macro_exposure (cairoTarget, clearOperator, darkOperator, ls->parameter[CIRCLE_EXPOSURE])) { cairo_translate (cairoTarget, ls->parameter[CIRCLE_CENTER_X], ls->parameter[CIRCLE_CENTER_Y]); gerbv_draw_circle (cairoTarget, ls->parameter[CIRCLE_DIAMETER]); draw_fill (cairoTarget, drawMode, selectionInfo, image, net); } break; case GERBV_APTYPE_MACRO_OUTLINE: { int pointCounter,numberOfPoints; /* Number of points parameter seems to not include the start point, * so we add one to include the start point. */ numberOfPoints = (int) ls->parameter[OUTLINE_NUMBER_OF_POINTS] + 1; if (draw_update_macro_exposure (cairoTarget, clearOperator, darkOperator, ls->parameter[OUTLINE_EXPOSURE])) { cairo_rotate (cairoTarget, DEG2RAD(ls->parameter[2*(numberOfPoints - 1) + OUTLINE_ROTATION])); cairo_move_to (cairoTarget, ls->parameter[OUTLINE_FIRST_X], ls->parameter[OUTLINE_FIRST_Y]); for (pointCounter=0; pointCounter < numberOfPoints; pointCounter++) { cairo_line_to (cairoTarget, ls->parameter[pointCounter * 2 + OUTLINE_FIRST_X], ls->parameter[pointCounter * 2 + OUTLINE_FIRST_Y]); } /* although the gerber specs allow for an open outline, I interpret it to mean the outline should be closed by the rendering softare automatically, since there is no dimension for line thickness. */ draw_fill (cairoTarget, drawMode, selectionInfo, image, net); } break; } case GERBV_APTYPE_MACRO_POLYGON: if (draw_update_macro_exposure (cairoTarget, clearOperator, darkOperator, ls->parameter[POLYGON_EXPOSURE])) { cairo_translate (cairoTarget, ls->parameter[POLYGON_CENTER_X], ls->parameter[POLYGON_CENTER_Y]); gerbv_draw_polygon(cairoTarget, ls->parameter[POLYGON_DIAMETER], ls->parameter[POLYGON_NUMBER_OF_POINTS], ls->parameter[POLYGON_ROTATION]); draw_fill (cairoTarget, drawMode, selectionInfo, image, net); } break; case GERBV_APTYPE_MACRO_MOIRE: { gdouble diameter, diameterDifference; int circleIndex; cairo_translate (cairoTarget, ls->parameter[MOIRE_CENTER_X], ls->parameter[MOIRE_CENTER_Y]); cairo_rotate (cairoTarget, DEG2RAD(ls->parameter[MOIRE_ROTATION])); diameter = ls->parameter[MOIRE_OUTSIDE_DIAMETER] - ls->parameter[MOIRE_CIRCLE_THICKNESS]; diameterDifference = 2*(ls->parameter[MOIRE_GAP_WIDTH] + ls->parameter[MOIRE_CIRCLE_THICKNESS]); cairo_set_line_width (cairoTarget, ls->parameter[MOIRE_CIRCLE_THICKNESS]); for (circleIndex = 0; circleIndex < (int)ls->parameter[MOIRE_NUMBER_OF_CIRCLES]; circleIndex++) { gdouble currentDiameter = diameter - diameterDifference * (float) circleIndex; if (currentDiameter >= 0) { gerbv_draw_circle (cairoTarget, currentDiameter); draw_stroke (cairoTarget, drawMode, selectionInfo, image, net); } } gdouble crosshairRadius = ls->parameter[MOIRE_CROSSHAIR_LENGTH] / 2.0; cairo_set_line_width (cairoTarget, ls->parameter[MOIRE_CROSSHAIR_THICKNESS]); cairo_move_to (cairoTarget, -crosshairRadius, 0); cairo_line_to (cairoTarget, crosshairRadius, 0); cairo_move_to (cairoTarget, 0, -crosshairRadius); cairo_line_to (cairoTarget, 0, crosshairRadius); draw_stroke (cairoTarget, drawMode, selectionInfo, image, net); break; } case GERBV_APTYPE_MACRO_THERMAL: { gint i; gdouble startAngle1, startAngle2, endAngle1, endAngle2; cairo_translate (cairoTarget, ls->parameter[THERMAL_CENTER_X], ls->parameter[THERMAL_CENTER_Y]); cairo_rotate (cairoTarget, DEG2RAD(ls->parameter[THERMAL_ROTATION])); startAngle1 = asin (ls->parameter[THERMAL_CROSSHAIR_THICKNESS]/ls->parameter[THERMAL_INSIDE_DIAMETER]); endAngle1 = M_PI_2 - startAngle1; endAngle2 = asin (ls->parameter[THERMAL_CROSSHAIR_THICKNESS]/ls->parameter[THERMAL_OUTSIDE_DIAMETER]); startAngle2 = M_PI_2 - endAngle2; for (i = 0; i < 4; i++) { cairo_arc (cairoTarget, 0, 0, ls->parameter[THERMAL_INSIDE_DIAMETER]/2.0, startAngle1, endAngle1); cairo_arc_negative (cairoTarget, 0, 0, ls->parameter[THERMAL_OUTSIDE_DIAMETER]/2.0, startAngle2, endAngle2); draw_fill (cairoTarget, drawMode, selectionInfo, image, net); cairo_rotate (cairoTarget, M_PI_2); } break; } case GERBV_APTYPE_MACRO_LINE20: if (draw_update_macro_exposure (cairoTarget, clearOperator, darkOperator, ls->parameter[LINE20_EXPOSURE])) { gdouble cParameter = ls->parameter[LINE20_LINE_WIDTH]; if (cParameter < pixelWidth) cParameter = pixelWidth; cairo_set_line_width (cairoTarget, cParameter); cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_BUTT); cairo_rotate (cairoTarget, DEG2RAD(ls->parameter[LINE20_ROTATION])); cairo_move_to (cairoTarget, ls->parameter[LINE20_START_X], ls->parameter[LINE20_START_Y]); cairo_line_to (cairoTarget, ls->parameter[LINE20_END_X], ls->parameter[LINE20_END_Y]); draw_stroke (cairoTarget, drawMode, selectionInfo, image, net); } break; case GERBV_APTYPE_MACRO_LINE21: { gdouble halfWidth, halfHeight; if (draw_update_macro_exposure (cairoTarget, clearOperator, darkOperator, ls->parameter[LINE21_EXPOSURE])) { halfWidth = ls->parameter[LINE21_WIDTH] / 2.0; halfHeight = ls->parameter[LINE21_HEIGHT] / 2.0; if (halfWidth < pixelWidth) halfWidth = pixelWidth; if (halfHeight < pixelWidth) halfHeight = pixelWidth; cairo_rotate (cairoTarget, DEG2RAD(ls->parameter[LINE21_ROTATION])); cairo_translate (cairoTarget, ls->parameter[LINE21_CENTER_X], ls->parameter[LINE21_CENTER_Y]); cairo_rectangle (cairoTarget, -halfWidth, -halfHeight, ls->parameter[LINE21_WIDTH], ls->parameter[LINE21_HEIGHT]); draw_fill (cairoTarget, drawMode, selectionInfo, image, net); } break; } case GERBV_APTYPE_MACRO_LINE22: { gdouble halfWidth, halfHeight; if (draw_update_macro_exposure (cairoTarget, clearOperator, darkOperator, ls->parameter[LINE22_EXPOSURE])) { halfWidth = ls->parameter[LINE22_WIDTH] / 2.0; halfHeight = ls->parameter[LINE22_HEIGHT] / 2.0; if (halfWidth < pixelWidth) halfWidth = pixelWidth; if (halfHeight < pixelWidth) halfHeight = pixelWidth; cairo_rotate (cairoTarget, DEG2RAD(ls->parameter[LINE22_ROTATION])); cairo_translate (cairoTarget, ls->parameter[LINE22_LOWER_LEFT_X], ls->parameter[LINE22_LOWER_LEFT_Y]); cairo_rectangle (cairoTarget, 0, 0, ls->parameter[LINE22_WIDTH], ls->parameter[LINE22_HEIGHT]); draw_fill (cairoTarget, drawMode, selectionInfo, image, net); } break; } default: handled = 0; } cairo_set_operator (cairoTarget, oldOperator); cairo_restore (cairoTarget); ls = ls->next; } if (usesClearPrimative) { cairo_pop_group_to_source (cairoTarget); cairo_paint (cairoTarget); } return handled; }
static int arrowdraw(struct objlist *obj, N_VALUE *inst, N_VALUE *rval, int argc, char **argv) { int GC, w, h, intp, i, j, num, close_path; struct narray *points; int *points2, *pdata; int x0, y0, x1, y1, type, stroke, fill, clip, zoom; if (_exeparent(obj, argv[1], inst, rval, argc, argv)) { return 1; } _getobj(obj, "GC", inst, &GC); if (GC < 0) { return 0; } _getobj(obj, "stroke", inst, &stroke); _getobj(obj, "fill", inst, &fill); if (fill == 0 && stroke == 0) { return 0; } _getobj(obj, "type", inst, &type); _getobj(obj, "clip", inst, &clip); _getobj(obj, "close_path", inst, &close_path); if (type == PATH_TYPE_CURVE) { _getobj(obj, "interpolation", inst, &intp); _getobj(obj, "_points", inst, &points); if (arraynum(points) == 0) { curve_expand_points(obj, inst, intp, points); } if (intp == INTERPOLATION_TYPE_SPLINE_CLOSE || intp == INTERPOLATION_TYPE_BSPLINE_CLOSE) { close_path = TRUE; } } else { _getobj(obj, "points", inst, &points); } num = arraynum(points) / 2; pdata = arraydata(points); points2 = g_malloc(sizeof(int) * num * 2); if (points2 == NULL) { return 1; } j = 0; x1 = y1 = 0; for (i = 0; i < num; i++) { x0 = pdata[2 * i]; y0 = pdata[2 * i + 1]; if (i == 0 || x0 != x1 || y0 != y1) { points2[2 * j] = x0; points2[2 * j + 1] = y0; j++; x1 = x0; y1 = y0; } } num = j; if (num < 2) { g_free(points2); return 0; } GRAregion(GC, &w, &h, &zoom); GRAview(GC, 0, 0, w * 10000.0 / zoom, h * 10000.0 / zoom, clip); if (fill) { draw_fill(obj, inst, GC, points2, num); } if (stroke) { draw_stroke(obj, inst, GC, points2, pdata, num, close_path); } g_free(points2); GRAaddlist(GC, obj, inst, argv[0], argv[1]); return 0; }
void onDrawContent(SkCanvas* canvas) override { SkPath path; SkScalar width = fWidth; if (fCubicButton.fEnabled) { path.moveTo(fPts[0]); path.cubicTo(fPts[1], fPts[2], fPts[3]); setForGeometry(); draw_stroke(canvas, path, width, 950, false); } if (fConicButton.fEnabled) { path.moveTo(fPts[4]); path.conicTo(fPts[5], fPts[6], fWeight); setForGeometry(); draw_stroke(canvas, path, width, 950, false); } if (fQuadButton.fEnabled) { path.reset(); path.moveTo(fPts[7]); path.quadTo(fPts[8], fPts[9]); setForGeometry(); draw_stroke(canvas, path, width, 950, false); } if (fRRectButton.fEnabled) { SkScalar rad = 32; SkRect r; r.set(&fPts[10], 2); path.reset(); SkRRect rr; rr.setRectXY(r, rad, rad); path.addRRect(rr); setForGeometry(); draw_stroke(canvas, path, width, 950, false); path.reset(); SkRRect rr2; rr.inset(width/2, width/2, &rr2); path.addRRect(rr2, SkPath::kCCW_Direction); rr.inset(-width/2, -width/2, &rr2); path.addRRect(rr2, SkPath::kCW_Direction); SkPaint paint; paint.setAntiAlias(true); paint.setColor(0x40FF8844); canvas->drawPath(path, paint); } if (fCircleButton.fEnabled) { path.reset(); SkRect r; r.set(&fPts[12], 2); path.addOval(r); setForGeometry(); if (fCircleButton.fFill) { draw_fill(canvas, r, width); } else { draw_stroke(canvas, path, width, 950, false); } } if (fTextButton.fEnabled) { path.reset(); SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(fTextSize); paint.getTextPath(fText.c_str(), fText.size(), 0, fTextSize, &path); setForText(); draw_stroke(canvas, path, width * fWidthScale / fTextSize, fTextSize, true); } if (fAnimate) { fWidth += fDWidth; if (fDWidth > 0 && fWidth > kWidthMax) { fDWidth = -fDWidth; } else if (fDWidth < 0 && fWidth < kWidthMin) { fDWidth = -fDWidth; } } setAsNeeded(); if (fConicButton.fEnabled) { draw_control(canvas, fWeightControl, fWeight, 0, 5, "weight"); } #ifdef SK_DEBUG draw_control(canvas, fErrorControl, gDebugStrokerError, kStrokerErrorMin, kStrokerErrorMax, "error"); #endif draw_control(canvas, fWidthControl, fWidth * fWidthScale, kWidthMin * fWidthScale, kWidthMax * fWidthScale, "width"); draw_button(canvas, fQuadButton); draw_button(canvas, fCubicButton); draw_button(canvas, fConicButton); draw_button(canvas, fRRectButton); draw_button(canvas, fCircleButton); draw_button(canvas, fTextButton); this->inval(NULL); }