/** * gtk_render_frame_gap: * @context: a #GtkStyleContext * @cr: a #cairo_t * @x: X origin of the rectangle * @y: Y origin of the rectangle * @width: rectangle width * @height: rectangle height * @gap_side: side where the gap is * @xy0_gap: initial coordinate (X or Y depending on @gap_side) for the gap * @xy1_gap: end coordinate (X or Y depending on @gap_side) for the gap * * Renders a frame around the rectangle defined by (@x, @y, @width, @height), * leaving a gap on one side. @xy0_gap and @xy1_gap will mean X coordinates * for %GTK_POS_TOP and %GTK_POS_BOTTOM gap sides, and Y coordinates for * %GTK_POS_LEFT and %GTK_POS_RIGHT. * * Typical rendering of a frame with a gap: * * ![](frame-gap.png) * * Since: 3.0 **/ void gtk_render_frame_gap (GtkStyleContext *context, cairo_t *cr, gdouble x, gdouble y, gdouble width, gdouble height, GtkPositionType gap_side, gdouble xy0_gap, gdouble xy1_gap) { g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (cr != NULL); g_return_if_fail (xy0_gap <= xy1_gap); g_return_if_fail (xy0_gap >= 0); if (width <= 0 || height <= 0) return; if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT) g_return_if_fail (xy1_gap <= height); else g_return_if_fail (xy1_gap <= width); cairo_save (cr); cairo_new_path (cr); gtk_css_style_render_frame_gap (gtk_style_context_lookup_style (context), cr, x, y, width, height, gap_side, xy0_gap, xy1_gap, gtk_style_context_get_junction_sides (context)); cairo_restore (cr); }
static cairo_time_t do_long_dashed_lines (cairo_t *cr, int width, int height, int loops) { double dash[2] = { 2.0, 2.0 }; int i; cairo_save (cr); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_paint (cr); cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); cairo_set_dash (cr, dash, 2, 0.0); cairo_new_path (cr); cairo_set_line_width (cr, 1.0); for (i = 0; i < height-1; i++) { double y0 = (double) i + 0.5; cairo_move_to (cr, 0.0, y0); cairo_line_to (cr, width, y0); } cairo_perf_timer_start (); cairo_perf_set_thread_aware (cr, FALSE); while (loops--) { if (loops == 0) cairo_perf_set_thread_aware (cr, TRUE); cairo_stroke_preserve (cr); } cairo_perf_timer_stop (); cairo_restore (cr); return cairo_perf_timer_elapsed (); }
int renderLineCairo(imageObj *img, shapeObj *p, strokeStyleObj *stroke) { int i,j; cairo_renderer *r = CAIRO_RENDERER(img); assert(stroke->color); cairo_new_path(r->cr); msCairoSetSourceColor(r->cr,stroke->color); for(i=0; i<p->numlines; i++) { lineObj *l = &(p->line[i]); if(l->numpoints == 0) continue; cairo_move_to(r->cr,l->point[0].x,l->point[0].y); for(j=1; j<l->numpoints; j++) { cairo_line_to(r->cr,l->point[j].x,l->point[j].y); } } if(stroke->patternlength>0) { cairo_set_dash(r->cr,stroke->pattern,stroke->patternlength,-stroke->patternoffset); } switch(stroke->linecap) { case MS_CJC_BUTT: cairo_set_line_cap(r->cr,CAIRO_LINE_CAP_BUTT); break; case MS_CJC_SQUARE: cairo_set_line_cap(r->cr,CAIRO_LINE_CAP_SQUARE); break; case MS_CJC_ROUND: case MS_CJC_NONE: default: cairo_set_line_cap(r->cr,CAIRO_LINE_CAP_ROUND); } cairo_set_line_width (r->cr, stroke->width); cairo_stroke (r->cr); if(stroke->patternlength>0) { cairo_set_dash(r->cr,stroke->pattern,0,0); } return MS_SUCCESS; }
void cairoplot_dot_line (cairo_t *context, double width, double height, double *values, int serie_size, double color_r, double color_g, double color_b, short show_dots) { int counter; double horizontal_step; double relative_height, relative_width; double last, max_value; max_value = cairoplot_utils_max (values, serie_size); relative_height = (height - Y_TOP - Y_BOTTOM) / max_value; relative_width = (width - X_RIGHT) / (serie_size + 1); last = 0; cairo_set_source_rgb (context, color_r, color_g, color_b); for (counter = 0; counter < serie_size; counter++) { if (counter > 0) { cairo_move_to (context, relative_width * (counter - 1) + X_LEFT, (double) height - (last * relative_height) - Y_BOTTOM); cairo_line_to (context, relative_width * counter + X_LEFT, (double) height - (values[counter] * relative_height) - Y_BOTTOM); cairo_set_line_width (context, 2.5); cairo_stroke (context); } if (show_dots) { cairo_new_path (context); cairo_arc (context, relative_width * counter + X_LEFT, (double) height - (values[counter] * relative_height) - Y_BOTTOM, 3, 0, 2.1 * M_PI); cairo_close_path (context); cairo_fill (context); } last = values[counter]; } }
int renderEllipseSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) { cairo_renderer *r = CAIRO_RENDERER(img); cairo_save(r->cr); cairo_set_line_cap(r->cr, CAIRO_LINE_CAP_BUTT); cairo_set_line_join(r->cr, CAIRO_LINE_JOIN_MITER); cairo_translate(r->cr,x,y); cairo_rotate(r->cr,-style->rotation); cairo_scale(r->cr,symbol->sizex*style->scale/2,symbol->sizey*style->scale/2); cairo_arc (r->cr, 0,0,1, 0, 2 * MS_PI); cairo_restore(r->cr); if(style->color) { msCairoSetSourceColor(r->cr, style->color); cairo_fill_preserve(r->cr); } if(style->outlinewidth > 0) { cairo_set_line_width (r->cr, style->outlinewidth); msCairoSetSourceColor(r->cr, style->outlinecolor); cairo_stroke_preserve(r->cr); } cairo_new_path(r->cr); return MS_SUCCESS; }
static cairo_perf_ticks_t do_tessellate (cairo_t *cr, int num_points, int loops) { int i; for (i=0; i < num_points; i++) cairo_line_to (cr, points[i].x, points[i].y); cairo_perf_timer_start (); /* We'd like to measure just tessellation without * rasterization. For now, we can do that with cairo_in_fill. But * we'll have to be careful since cairo_in_fill might eventually * be optimized to have an implementation that doesn't necessarily * include tessellation. */ while (loops--) cairo_in_fill (cr, 50, 50); cairo_perf_timer_stop (); cairo_new_path (cr); return cairo_perf_timer_elapsed (); }
/* * Draw a rounded rectangle path */ void TextSurface::drawBackground (int x, int y, int width, int height, int radius) { int x0, y0, x1, y1; x0 = x; y0 = y; x1 = x + width; y1 = y + height; cairo_new_path (cr); cairo_arc (cr, x0 + radius, y1 - radius, radius, PI / 2, PI); cairo_line_to (cr, x0, y0 + radius); cairo_arc (cr, x0 + radius, y0 + radius, radius, PI, 3 * PI / 2); cairo_line_to (cr, x1 - radius, y0); cairo_arc (cr, x1 - radius, y0 + radius, radius, 3 * PI / 2, 2 * PI); cairo_line_to (cr, x1, y1 - radius); cairo_arc (cr, x1 - radius, y1 - radius, radius, 0, PI / 2); cairo_close_path (cr); }
int ca_test_image_rotate(caskbench_context_t* ctx) { cairo_t *cr = ctx->cairo_cr; static int counter = 0; double radian = 0; int w = ctx->canvas_width; int h = ctx->canvas_height; int iw = cairo_image_surface_get_width (image); int ih = cairo_image_surface_get_height (image); int pw = w - iw; int ph = h - ih; for (int i=0; i<ctx->size; i++) { double x = (double)rnd()/RAND_MAX * pw; double y = (double)rnd()/RAND_MAX * ph; cairo_new_path(cr); cairo_save(cr); cairo_translate(cr, w/2, h/2); radian = (1/57.29) * (counter/50); cairo_rotate(cr, radian); cairo_translate(cr, -iw/2, -ih/2); cairo_set_source_surface (cr, cached_image, 0, 0); cairo_paint (cr); counter++; cairo_restore(cr); } return 1; }
void QCairoPaintEngine::drawPoints(const QPointF *points, int pointCount) { if (!cr || !surface) { qDebug()<<"Cairo Error [QCairoPaintEngine::drawPoints]: no cairo or no surface!"; return; } if (cpen.style()==Qt::NoPen) { qDebug()<<"Cairo Error [QCairoPaintEngine::drawPoints]: no pen set!"; return; } updatePen(); for (int i=0; i<pointCount; i++) { cairo_new_path(cr); cairo_move_to (cr, points[i].x(), points[i].y()); cairo_close_path (cr); } //cairo_close_path(cr); updatePen(); cairo_stroke(cr); }
//----------------------------------------------------------------------------------- void ofxCairoTexture::viewport(float x, float y, float width, float height, bool invertY){ if(width == 0) width = ofGetWindowWidth(); if(height == 0) height = ofGetWindowHeight(); if (invertY){ y = ofGetWindowHeight() - (y + height); } viewportRect.set(x, y, width, height); cairo_reset_clip(cr); cairo_new_path(cr); cairo_move_to(cr,viewportRect.x,viewportRect.y); cairo_line_to(cr,viewportRect.x+viewportRect.width,viewportRect.y); cairo_line_to(cr,viewportRect.x+viewportRect.width,viewportRect.y+viewportRect.height); cairo_line_to(cr,viewportRect.x,viewportRect.y+viewportRect.height); /* cairo_clip(cr); */ };
void cairox_draw_symbol(cairo_t *cr, double x, double y, int s) { if (s == 0) { double d = 5.0; cairo_new_path(cr); cairo_move_to(cr, x-d, y-d); cairo_line_to(cr, x+d, y-d); cairo_line_to(cr, x+d, y+d); cairo_line_to(cr, x-d, y+d); cairo_close_path(cr); cairo_fill(cr); } else if (s == 1) { double d = 6.0; cairo_new_path(cr); cairo_move_to(cr, x-d, y+d*(sqrt(3)-1)); cairo_line_to(cr, x+d, y+d*(sqrt(3)-1)); cairo_line_to(cr, x, y-d); cairo_close_path(cr); cairo_fill(cr); } else if (s == 2) { double d = 7.0; cairo_new_path(cr); cairo_move_to(cr, x-d, y); cairo_line_to(cr, x, y-d); cairo_line_to(cr, x+d, y); cairo_line_to(cr, x, y+d); cairo_close_path(cr); cairo_fill(cr); } else if (s == 3) { double d = 5.0; cairo_new_path(cr); cairo_arc(cr, x, y, d, 0, 2*M_PI); cairo_close_path(cr); cairo_fill(cr); } else if (s == 4) { double d = 4.0; cairo_new_path(cr); cairo_move_to(cr, x-d, y-d); cairo_line_to(cr, x+d, y-d); cairo_line_to(cr, x+d, y+d); cairo_line_to(cr, x-d, y+d); cairo_close_path(cr); cairo_stroke(cr); } else if (s == 5) { double d = 5.0; cairo_new_path(cr); cairo_move_to(cr, x-d, y+d*(sqrt(3)-1)); cairo_line_to(cr, x+d, y+d*(sqrt(3)-1)); cairo_line_to(cr, x, y-d); cairo_close_path(cr); cairo_stroke(cr); } else if (s == 6) { double d = 6.0; cairo_new_path(cr); cairo_move_to(cr, x-d, y); cairo_line_to(cr, x, y-d); cairo_line_to(cr, x+d, y); cairo_line_to(cr, x, y+d); cairo_close_path(cr); cairo_stroke(cr); } else if (s == 7) { double d = 4.0; cairo_new_path(cr); cairo_arc(cr, x, y, d, 0, 2*M_PI); cairo_close_path(cr); cairo_stroke(cr); } }
void cd_rendering_render_optimized_3D_plane (cairo_t *pCairoContext, CairoDock *pDock, GdkRectangle *pArea) { //g_print ("%s ((%d;%d) x (%d;%d) / (%dx%d))\n", __func__, pArea->x, pArea->y, pArea->width, pArea->height, pDock->iCurrentWidth, pDock->iCurrentHeight); double fLineWidth = myBackground.iDockLineWidth; double fMargin = myBackground.iFrameMargin; int iWidth = pDock->iCurrentWidth; int iHeight = pDock->iCurrentHeight; //\____________________ On dessine les decorations du fond sur la portion de fenetre. cairo_save (pCairoContext); double fDockOffsetX, fDockOffsetY; if (pDock->bHorizontalDock) { fDockOffsetX = pArea->x; fDockOffsetY = (pDock->bDirectionUp ? iHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth); } else { fDockOffsetX = (pDock->bDirectionUp ? iHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth); fDockOffsetY = pArea->y; } //cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY); if (pDock->bHorizontalDock) cairo_rectangle (pCairoContext, fDockOffsetX, fDockOffsetY, pArea->width, pDock->iDecorationsHeight); else cairo_rectangle (pCairoContext, fDockOffsetX, fDockOffsetY, pDock->iDecorationsHeight, pArea->height); double fRadius = MIN (myBackground.iDockRadius, (pDock->iDecorationsHeight + myBackground.iDockLineWidth) / 2 - 1); double fDeltaXTrapeze=0.; double fOffsetX; if (cairo_dock_is_extended_dock (pDock)) // mode panel etendu. { fOffsetX = fRadius + fLineWidth / 2; } else { Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock); fOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - fMargin : fRadius + fLineWidth / 2); } double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock); if (g_pBackgroundSurface != NULL) { double fInclinationOnHorizon = (fDockWidth / 2) / iVanishingPointY; double fRadius = myBackground.iDockRadius; if (2*fRadius > pDock->iDecorationsHeight + fLineWidth) fRadius = (pDock->iDecorationsHeight + fLineWidth) / 2 - 1; double fDeltaXForLoop = fInclinationOnHorizon * (pDock->iDecorationsHeight + fLineWidth - (myBackground.bRoundedBottomCorner ? 2 : 1) * fRadius); double cosa = 1. / sqrt (1 + fInclinationOnHorizon * fInclinationOnHorizon); fDeltaXTrapeze = fDeltaXForLoop + fRadius * cosa; double sina = cosa * fInclinationOnHorizon; fDeltaXTrapeze = fInclinationOnHorizon * (pDock->iDecorationsHeight - (FALSE ? 2 : 1-sina) * fRadius) + fRadius * (FALSE ? 1 : cosa); } cairo_dock_render_decorations_in_frame (pCairoContext, pDock, pDock->bHorizontalDock ? fDockOffsetY : fDockOffsetX, fOffsetX-fDeltaXTrapeze, fDockWidth+2*fDeltaXTrapeze); //\____________________ On dessine la partie du cadre qui va bien. cairo_new_path (pCairoContext); if (pDock->bHorizontalDock) { cairo_set_line_width (pCairoContext, fLineWidth); cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY - 0.5*fLineWidth); cairo_rel_line_to (pCairoContext, pArea->width, 0); cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]); cairo_stroke (pCairoContext); cairo_new_path (pCairoContext); cairo_move_to (pCairoContext, fDockOffsetX, (pDock->bDirectionUp ? iHeight - 0.5*fLineWidth : pDock->iDecorationsHeight + 1.5 * fLineWidth)); cairo_rel_line_to (pCairoContext, pArea->width, 0); } else { cairo_move_to (pCairoContext, fDockOffsetX - .5*fLineWidth, fDockOffsetY); cairo_rel_line_to (pCairoContext, 0, pArea->height); cairo_set_line_width (pCairoContext, fLineWidth); cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]); cairo_stroke (pCairoContext); cairo_new_path (pCairoContext); cairo_move_to (pCairoContext, (pDock->bDirectionUp ? iHeight - fLineWidth / 2 : pDock->iDecorationsHeight + 1.5 * fLineWidth), fDockOffsetY); cairo_rel_line_to (pCairoContext, 0, pArea->height); } cairo_set_line_width (pCairoContext, fLineWidth); cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]); cairo_stroke (pCairoContext); cairo_restore (pCairoContext); //\____________________ On dessine les icones impactees. GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons); if (pFirstDrawnElement != NULL) { double fXMin = (pDock->bHorizontalDock ? pArea->x : pArea->y), fXMax = (pDock->bHorizontalDock ? pArea->x + pArea->width : pArea->y + pArea->height); double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex); double fXLeft, fXRight; Icon *icon; GList *ic = pFirstDrawnElement; if (my_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR) { cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_SQUARE); do { icon = ic->data; if (CAIRO_DOCK_IS_SEPARATOR (icon) && icon->acFileName == NULL) { if (_cd_separator_is_impacted (icon, pDock, fXMin, fXMax, TRUE, (my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR))) { cairo_save (pCairoContext); cd_rendering_draw_3D_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, TRUE); cairo_restore (pCairoContext); } } ic = cairo_dock_get_next_element (ic, pDock->icons); } while (ic != pFirstDrawnElement); do { icon = ic->data; if (! CAIRO_DOCK_IS_SEPARATOR (icon) || icon->acFileName != NULL) { fXLeft = icon->fDrawX + icon->fScale + 1; fXRight = icon->fDrawX + (icon->fWidth - 1) * icon->fScale * icon->fWidthFactor - 1; if (fXLeft <= fXMax && floor (fXRight) > fXMin) { if (icon->fDrawX >= 0 && icon->fDrawX + icon->fWidth * icon->fScale <= pDock->iCurrentWidth) icon->fAlpha = 1; else icon->fAlpha = .25; cairo_save (pCairoContext); cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE); cairo_restore (pCairoContext); } } ic = cairo_dock_get_next_element (ic, pDock->icons); } while (ic != pFirstDrawnElement); if (my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR) { do { icon = ic->data; if (CAIRO_DOCK_IS_SEPARATOR (icon) && icon->acFileName == NULL) { if (_cd_separator_is_impacted (icon, pDock, fXMin, fXMax, FALSE, (my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR))) { cairo_save (pCairoContext); cd_rendering_draw_3D_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, FALSE); cairo_restore (pCairoContext); } } ic = cairo_dock_get_next_element (ic, pDock->icons); } while (ic != pFirstDrawnElement); } } else { do { icon = ic->data; fXLeft = icon->fDrawX + icon->fScale + 1; fXRight = icon->fDrawX + (icon->fWidth - 1) * icon->fScale * icon->fWidthFactor - 1; if (fXLeft <= fXMax && floor (fXRight) > fXMin) { if (icon->fDrawX >= 0 && icon->fDrawX + icon->fWidth * icon->fScale <= pDock->iCurrentWidth) icon->fAlpha = 1; else icon->fAlpha = .25; cairo_save (pCairoContext); cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE); cairo_restore (pCairoContext); } ic = cairo_dock_get_next_element (ic, pDock->icons); } while (ic != pFirstDrawnElement); } } }
void draw_render_polygon_object (gerbv_net_t *oldNet, cairo_t *cairoTarget, gdouble sr_x, gdouble sr_y, gerbv_image_t *image, enum draw_mode drawMode, gerbv_selection_info_t *selectionInfo, gboolean pixelOutput) { gerbv_net_t *currentNet, *polygonStartNet; int haveDrawnFirstFillPoint = 0; gdouble x2,y2,cp_x=0,cp_y=0; haveDrawnFirstFillPoint = FALSE; /* save the first net in the polygon as the "ID" net pointer in case we are saving this net to the selection array */ polygonStartNet = oldNet; cairo_new_path(cairoTarget); for (currentNet = oldNet->next; currentNet!=NULL; currentNet = currentNet->next) { x2 = currentNet->stop_x + sr_x; y2 = currentNet->stop_y + sr_y; /* translate circular x,y data as well */ if (currentNet->cirseg) { cp_x = currentNet->cirseg->cp_x + sr_x; cp_y = currentNet->cirseg->cp_y + sr_y; } if (!haveDrawnFirstFillPoint) { draw_cairo_move_to (cairoTarget, x2, y2, FALSE, pixelOutput); haveDrawnFirstFillPoint=TRUE; continue; } switch (currentNet->interpolation) { case GERBV_INTERPOLATION_x10 : case GERBV_INTERPOLATION_LINEARx01 : case GERBV_INTERPOLATION_LINEARx001 : case GERBV_INTERPOLATION_LINEARx1 : draw_cairo_line_to (cairoTarget, x2, y2, FALSE, pixelOutput); break; case GERBV_INTERPOLATION_CW_CIRCULAR : case GERBV_INTERPOLATION_CCW_CIRCULAR : if (currentNet->cirseg->angle2 > currentNet->cirseg->angle1) { cairo_arc (cairoTarget, cp_x, cp_y, currentNet->cirseg->width/2.0, DEG2RAD(currentNet->cirseg->angle1), DEG2RAD(currentNet->cirseg->angle2)); } else { cairo_arc_negative (cairoTarget, cp_x, cp_y, currentNet->cirseg->width/2.0, DEG2RAD(currentNet->cirseg->angle1), DEG2RAD(currentNet->cirseg->angle2)); } break; case GERBV_INTERPOLATION_PAREA_END : cairo_close_path(cairoTarget); /* turn off anti-aliasing for polygons, since it shows seams with adjacent polygons (usually on PCB ground planes) */ cairo_antialias_t oldAlias = cairo_get_antialias (cairoTarget); cairo_set_antialias (cairoTarget, CAIRO_ANTIALIAS_NONE); draw_fill (cairoTarget, drawMode, selectionInfo, image, polygonStartNet); cairo_set_antialias (cairoTarget, oldAlias); return; default : break; } } }
static void draw_check_if_object_is_in_selected_area (cairo_t *cairoTarget, gboolean isStroke, gerbv_selection_info_t *selectionInfo, gerbv_image_t *image, struct gerbv_net *net, enum draw_mode drawMode) { gerbv_selection_item_t sItem = {image, net}; gdouble corner1X, corner1Y, corner2X, corner2Y; gdouble x1, x2, y1, y2; gdouble minX, minY, maxX, maxY; corner1X = selectionInfo->lowerLeftX; corner1Y = selectionInfo->lowerLeftY; corner2X = selectionInfo->upperRightX; corner2Y = selectionInfo->upperRightY; /* calculate the coordinate of the user's click in the current transformation matrix */ cairo_device_to_user (cairoTarget, &corner1X, &corner1Y); cairo_device_to_user (cairoTarget, &corner2X, &corner2Y); switch (selectionInfo->type) { case GERBV_SELECTION_POINT_CLICK: /* use the cairo in_fill routine to see if the point is within the drawn area */ if ((isStroke && cairo_in_stroke (cairoTarget, corner1X, corner1Y)) || (!isStroke && cairo_in_fill (cairoTarget, corner1X, corner1Y))) { if (!draw_net_is_in_selection_buffer_remove (net, selectionInfo, (drawMode == FIND_SELECTIONS_TOGGLE))) { selection_add_item (selectionInfo, &sItem); } } break; case GERBV_SELECTION_DRAG_BOX: /* we can't assume the "lowerleft" corner is actually in the lower left, since the cairo transformation matrix may be mirrored,etc */ minX = MIN(corner1X,corner2X); maxX = MAX(corner1X,corner2X); minY = MIN(corner1Y,corner2Y); maxY = MAX(corner1Y,corner2Y); if (isStroke) cairo_stroke_extents (cairoTarget, &x1, &y1, &x2, &y2); else cairo_fill_extents (cairoTarget, &x1, &y1, &x2, &y2); if ((minX < x1) && (minY < y1) && (maxX > x2) && (maxY > y2)) { if (!draw_net_is_in_selection_buffer_remove (net, selectionInfo, (drawMode == FIND_SELECTIONS_TOGGLE))) { selection_add_item (selectionInfo, &sItem); } } break; default: break; } /* clear the path, since we didn't actually draw it and cairo doesn't reset it after the previous calls */ cairo_new_path (cairoTarget); }
void ofCairoRenderer::draw(ofMesh & primitive, bool useColors, bool useTextures, bool useNormals){ if(primitive.getNumVertices() == 0){ return; } if(primitive.getNumIndices() == 0){ ofMesh indexedMesh = primitive; indexedMesh.setupIndicesAuto(); draw(indexedMesh, useColors, useTextures, useNormals); return; } pushMatrix(); cairo_matrix_init_identity(getCairoMatrix()); cairo_new_path(cr); int i = 1; ofVec3f v = transform(primitive.getVertex(primitive.getIndex(0))); ofVec3f v2; cairo_move_to(cr,v.x,v.y); if(primitive.getMode()==OF_PRIMITIVE_TRIANGLE_STRIP){ v = transform(primitive.getVertex(primitive.getIndex(1))); cairo_line_to(cr,v.x,v.y); v = transform(primitive.getVertex(primitive.getIndex(2))); cairo_line_to(cr,v.x,v.y); i=2; } for(; i<primitive.getNumIndices(); i++){ v = transform(primitive.getVertex(primitive.getIndex(i))); switch(primitive.getMode()){ case(OF_PRIMITIVE_TRIANGLES): if((i+1)%3==0){ cairo_line_to(cr,v.x,v.y); v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); }else if((i+3)%3==0){ cairo_move_to(cr,v.x,v.y); }else{ cairo_line_to(cr,v.x,v.y); } break; case(OF_PRIMITIVE_TRIANGLE_STRIP): v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v.x,v.y); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); break; case(OF_PRIMITIVE_TRIANGLE_FAN): /*triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)1); triangles.addIndex((GLuint)2); for(int i = 2; i < primitive.getNumVertices()-1;i++){ triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)i); triangles.addIndex((GLuint)i+1); }*/ break; default:break; } } cairo_move_to(cr,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).x,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).y); if(ofGetStyle().lineWidth>0){ cairo_stroke( cr ); } popMatrix(); }
void lime_cairo_new_path (value handle) { cairo_new_path ((cairo_t*)val_data (handle)); }
void ofCairoRenderer::draw(const ofMesh & primitive, ofPolyRenderMode mode, bool useColors, bool useTextures, bool useNormals) const{ if(useColors || useTextures || useNormals){ ofLogWarning("ofCairoRenderer") << "draw(): cairo mesh rendering doesn't support colors, textures, or normals. drawing wireframe ..."; } if(primitive.getNumVertices() == 0){ return; } if(primitive.getNumIndices() == 0){ ofMesh indexedMesh = primitive; indexedMesh.setupIndicesAuto(); draw(indexedMesh, mode, useColors, useTextures, useNormals); return; } cairo_new_path(cr); cairo_matrix_t matrix; cairo_matrix_init_identity(&matrix); cairo_new_path(cr); std::size_t i = 1; ofVec3f v = transform(primitive.getVertex(primitive.getIndex(0))); ofVec3f v2; cairo_move_to(cr,v.x,v.y); if(primitive.getMode()==OF_PRIMITIVE_TRIANGLE_STRIP){ v = transform(primitive.getVertex(primitive.getIndex(1))); cairo_line_to(cr,v.x,v.y); v = transform(primitive.getVertex(primitive.getIndex(2))); cairo_line_to(cr,v.x,v.y); i=2; } for(; i<primitive.getNumIndices(); i++){ v = transform(primitive.getVertex(primitive.getIndex(i))); switch(primitive.getMode()){ case(OF_PRIMITIVE_TRIANGLES): if((i+1)%3==0){ cairo_line_to(cr,v.x,v.y); v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); }else if((i+3)%3==0){ cairo_move_to(cr,v.x,v.y); }else{ cairo_line_to(cr,v.x,v.y); } break; case(OF_PRIMITIVE_TRIANGLE_STRIP): v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v.x,v.y); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); break; case(OF_PRIMITIVE_TRIANGLE_FAN): /*triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)1); triangles.addIndex((GLuint)2); for(int i = 2; i < primitive.getNumVertices()-1;i++){ triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)i); triangles.addIndex((GLuint)i+1); }*/ break; default:break; } } cairo_move_to(cr,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).x,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).y); if(currentStyle.lineWidth>0){ cairo_stroke( cr ); } }
void *dt_control_expose(void *voidptr) { int width, height, pointerx, pointery; if(!darktable.gui->surface) return NULL; width = cairo_image_surface_get_width(darktable.gui->surface); height = cairo_image_surface_get_height(darktable.gui->surface); GtkWidget *widget = dt_ui_center(darktable.gui->ui); gtk_widget_get_pointer(widget, &pointerx, &pointery); //create a gtk-independent surface to draw on cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // TODO: control_expose: only redraw the part not overlapped by temporary control panel show! // float tb = 8;//fmaxf(10, width/100.0); darktable.control->tabborder = tb; darktable.control->width = width; darktable.control->height = height; GtkStyle *style = gtk_widget_get_style(widget); cairo_set_source_rgb (cr, style->bg[GTK_STATE_NORMAL].red/65535.0, style->bg[GTK_STATE_NORMAL].green/65535.0, style->bg[GTK_STATE_NORMAL].blue/65535.0 ); cairo_set_line_width(cr, tb); cairo_rectangle(cr, tb/2., tb/2., width-tb, height-tb); cairo_stroke(cr); cairo_set_line_width(cr, 1.5); cairo_set_source_rgb (cr, .1, .1, .1); cairo_rectangle(cr, tb, tb, width-2*tb, height-2*tb); cairo_stroke(cr); cairo_save(cr); cairo_translate(cr, tb, tb); cairo_rectangle(cr, 0, 0, width - 2*tb, height - 2*tb); cairo_clip(cr); cairo_new_path(cr); // draw view dt_view_manager_expose(darktable.view_manager, cr, width-2*tb, height-2*tb, pointerx-tb, pointery-tb); cairo_restore(cr); // draw status bar, if any if(darktable.control->progress < 100.0) { tb = fmaxf(20, width/40.0); char num[10]; cairo_rectangle(cr, width*0.4, height*0.85, width*0.2*darktable.control->progress/100.0f, tb); cairo_fill(cr); cairo_set_source_rgb(cr, 0., 0., 0.); cairo_rectangle(cr, width*0.4, height*0.85, width*0.2, tb); cairo_stroke(cr); cairo_set_source_rgb(cr, 0.9, 0.9, 0.9); cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, tb/3); cairo_move_to (cr, width/2.0-10, height*0.85+2.*tb/3.); snprintf(num, sizeof(num), "%d%%", (int)darktable.control->progress); cairo_show_text (cr, num); } // draw log message, if any dt_pthread_mutex_lock(&darktable.control->log_mutex); if(darktable.control->log_ack != darktable.control->log_pos) { cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); const float fontsize = 14; cairo_set_font_size (cr, fontsize); cairo_text_extents_t ext; cairo_text_extents (cr, darktable.control->log_message[darktable.control->log_ack], &ext); const float pad = 20.0f, xc = width/2.0; const float yc = height*0.85+10, wd = pad + ext.width*.5f; float rad = 14; cairo_set_line_width(cr, 1.); cairo_move_to( cr, xc-wd,yc+rad); for(int k=0; k<5; k++) { cairo_arc (cr, xc-wd, yc, rad, M_PI/2.0, 3.0/2.0*M_PI); cairo_line_to (cr, xc+wd, yc-rad); cairo_arc (cr, xc+wd, yc, rad, 3.0*M_PI/2.0, M_PI/2.0); cairo_line_to (cr, xc-wd, yc+rad); if(k == 0) { cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_fill_preserve (cr); } cairo_set_source_rgba(cr, 0., 0., 0., 1.0/(1+k)); cairo_stroke (cr); rad += .5f; } cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_move_to (cr, xc-wd+.5f*pad, yc + 1./3.*fontsize); cairo_show_text (cr, darktable.control->log_message[darktable.control->log_ack]); } // draw busy indicator if(darktable.control->log_busy > 0) { cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); const float fontsize = 14; cairo_set_font_size (cr, fontsize); cairo_text_extents_t ext; cairo_text_extents (cr, _("working.."), &ext); const float xc = width/2.0, yc = height*0.85-30, wd = ext.width*.5f; cairo_move_to (cr, xc-wd, yc + 1./3.*fontsize); cairo_text_path (cr, _("working..")); cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_fill_preserve(cr); cairo_set_line_width(cr, 0.7); cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_stroke(cr); } dt_pthread_mutex_unlock(&darktable.control->log_mutex); cairo_destroy(cr); cairo_t *cr_pixmap = cairo_create(darktable.gui->surface); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return NULL; }
void ofCairoRenderer::draw(const vector<ofPoint> & vertexData, ofPrimitiveMode drawMode) const{ if(vertexData.size()==0) return; ofCairoRenderer * mut_this = const_cast<ofCairoRenderer*>(this); mut_this->pushMatrix(); cairo_matrix_t matrix; cairo_matrix_init_identity(&matrix); cairo_new_path(cr); //if(indices.getNumIndices()){ int i = 1; ofVec3f v = transform(vertexData[0]); ofVec3f v2; cairo_move_to(cr,v.x,v.y); if(drawMode==OF_PRIMITIVE_TRIANGLE_STRIP){ v = transform(vertexData[1]); cairo_line_to(cr,v.x,v.y); v = transform(vertexData[2]); cairo_line_to(cr,v.x,v.y); i=2; } for(; i<(int)vertexData.size(); i++){ v = transform(vertexData[i]); switch(drawMode){ case(OF_PRIMITIVE_TRIANGLES): if((i+1)%3==0){ cairo_line_to(cr,v.x,v.y); v2 = transform(vertexData[i-2]); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); }else if((i+3)%3==0){ cairo_move_to(cr,v.x,v.y); }else{ cairo_line_to(cr,v.x,v.y); } break; case(OF_PRIMITIVE_TRIANGLE_STRIP): v2 = transform(vertexData[i-2]); cairo_line_to(cr,v.x,v.y); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); break; case(OF_PRIMITIVE_TRIANGLE_FAN): /*triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)1); triangles.addIndex((GLuint)2); for(int i = 2; i < primitive.getNumVertices()-1;i++){ triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)i); triangles.addIndex((GLuint)i+1); }*/ break; default:break; } } cairo_move_to(cr,vertexData[vertexData.size()-1].x,vertexData[vertexData.size()-1].y); cairo_stroke( cr ); mut_this->popMatrix(); }
void Path::clear() { cairo_t* cr = platformPath()->m_cr; cairo_new_path(cr); }
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const { #if USE(FREETYPE) if (!primaryFont()->platformData().m_pattern) { drawSimpleText(context, run, point, from, to); return; } #endif cairo_t* cr = context->platformContext()->cr(); PangoLayout* layout = pango_cairo_create_layout(cr); setPangoAttributes(this, run, layout); gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); pango_layout_set_text(layout, utf8, -1); // Our layouts are single line PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0); // Get the region where this text will be laid out. We will use it to clip // the Cairo context, for when we are only painting part of the text run and // to calculate the size of the shadow buffer. PangoRegionType partialRegion = 0; char* start = g_utf8_offset_to_pointer(utf8, from); char* end = g_utf8_offset_to_pointer(start, to - from); int ranges[] = {start - utf8, end - utf8}; #if PLATFORM(GTK) partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1); #else partialRegion = getClipRegionFromPangoLayoutLine(layoutLine, ranges); #endif drawGlyphsShadow(context, point, layoutLine, partialRegion); cairo_save(cr); cairo_translate(cr, point.x(), point.y()); float red, green, blue, alpha; context->fillColor().getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); #if PLATFORM(GTK) gdk_cairo_region(cr, partialRegion); #else appendRegionToCairoContext(cr, partialRegion); #endif cairo_clip(cr); pango_cairo_show_layout_line(cr, layoutLine); if (context->textDrawingMode() & TextModeStroke) { Color strokeColor = context->strokeColor(); strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); pango_cairo_layout_line_path(cr, layoutLine); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Pango sometimes leaves behind paths we don't want cairo_new_path(cr); destroyPangoRegion(partialRegion); g_free(utf8); g_object_unref(layout); cairo_restore(cr); }
void lime_cairo_new_path (double handle) { cairo_new_path ((cairo_t*)(intptr_t)handle); }
void render_glyph( cairo_t* cr, PangoFontDescription* font_desc, PangoFont* font, const guint code_point, const size_t cell_x, const size_t cell_y, const size_t cell_size, const double tex_size, const int ascent, const int descent, std::ostream& bgm_out ) { PangoLayout *layout = pango_cairo_create_layout(cr); char str[6] = {'\0'}; size_t len = 0; oglplus::aux::ConvertCodePointToUTF8(code_point, str, len); pango_layout_set_font_description(layout, font_desc); pango_layout_set_text(layout, str, len); const int baseline = pango_layout_get_baseline(layout); const double inv_ps = 1.0 / double(PANGO_SCALE); const double font_size = ascent+descent; PangoRectangle ink_rect, log_rect; pango_layout_get_extents( layout, &ink_rect, &log_rect ); // code point number bgm_out << code_point << std::endl; // hex representation of the number bgm_out << std::hex << "0x" << code_point << std::dec << std::endl; // the utf-8 sequence bgm_out << "'" << str << "'" << std::endl; // // vertex[0] logical rectangle metrics // // Left bearing (x) bgm_out << PANGO_LBEARING(log_rect)/font_size << std::endl; // Right bearing (x+width) bgm_out << PANGO_RBEARING(log_rect)/font_size << std::endl; // Ascent bgm_out << (baseline-log_rect.y)/font_size << std::endl; // Descent bgm_out << (log_rect.height+log_rect.y-baseline)/font_size << std::endl; // // vertex[1] ink rectangle metrics // // Left bearing (x) bgm_out << PANGO_LBEARING(ink_rect)/font_size << std::endl; // Right bearing (x+width) bgm_out << PANGO_RBEARING(ink_rect)/font_size << std::endl; // Ascent bgm_out << (baseline-ink_rect.y)/font_size << std::endl; // Descent bgm_out << (ink_rect.y+ink_rect.height-baseline)/font_size << std::endl; // // vertex[2] texture coordinates // // Origin X bgm_out << (cell_x*cell_size+ink_rect.x*inv_ps)/tex_size << std::endl; // Origin Y bgm_out << 1.0-(cell_y*cell_size+baseline*inv_ps)/tex_size << std::endl; // Width bgm_out << ((ink_rect.width)*inv_ps)/tex_size << std::endl; // Height bgm_out << ((ink_rect.height)*inv_ps)/tex_size << std::endl; // separating newline bgm_out << std::endl; cairo_new_path(cr); cairo_move_to(cr, cell_x*cell_size, cell_y*cell_size); cairo_set_line_width(cr, 0.5); pango_cairo_update_layout(cr, layout); pango_cairo_layout_path(cr, layout); cairo_fill(cr); g_object_unref(layout); }
void trap_render (int w, int h, int fill_gradient) { double *ctrlpts = animpts; int len = (NUMPTS * 2); double prevx = ctrlpts[len - 2]; double prevy = ctrlpts[len - 1]; double curx = ctrlpts[0]; double cury = ctrlpts[1]; double midx = (curx + prevx) / 2.0; double midy = (cury + prevy) / 2.0; int i; cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_rectangle (cr, 0, 0, w, h); cairo_fill (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, 0.75, 0.75, 0.75, 1.0); cairo_set_line_width (cr, 1.0); cairo_save (cr); cairo_scale (cr, (double) w / 512.0, (double) h / 512.0); cairo_save (cr); cairo_translate (cr, 170.0, 330.0); cairo_rotate (cr, gear1_rotation); gear (30.0, 120.0, 20, 20.0); cairo_set_source_rgb (cr, 0.75, 0.75, 0.75); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0.25, 0.25, 0.25); cairo_stroke (cr); cairo_restore (cr); cairo_save (cr); cairo_translate (cr, 369.0, 330.0); cairo_rotate (cr, gear2_rotation); gear (15.0, 75.0, 12, 20.0); cairo_set_source_rgb (cr, 0.75, 0.75, 0.75); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0.25, 0.25, 0.25); cairo_stroke (cr); cairo_restore (cr); cairo_save (cr); cairo_translate (cr, 170.0, 116.0); cairo_rotate (cr, gear3_rotation); gear (20.0, 90.0, 14, 20.0); cairo_set_source_rgb (cr, 0.75, 0.75, 0.75); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0.25, 0.25, 0.25); cairo_stroke (cr); cairo_restore (cr); cairo_restore (cr); gear1_rotation += 0.01; gear2_rotation -= (0.01 * (20.0 / 12.0)); gear3_rotation -= (0.01 * (20.0 / 14.0)); stroke_and_fill_step (w, h); cairo_new_path (cr); cairo_move_to (cr, midx, midy); for (i = 2; i <= (NUMPTS * 2); i += 2) { double x2, x1 = (midx + curx) / 2.0; double y2, y1 = (midy + cury) / 2.0; prevx = curx; prevy = cury; if (i < (NUMPTS * 2)) { curx = ctrlpts[i + 0]; cury = ctrlpts[i + 1]; } else { curx = ctrlpts[0]; cury = ctrlpts[1]; } midx = (curx + prevx) / 2.0; midy = (cury + prevy) / 2.0; x2 = (prevx + midx) / 2.0; y2 = (prevy + midy) / 2.0; cairo_curve_to (cr, x1, y1, x2, y2, midx, midy); } cairo_close_path (cr); if (fill_gradient) { double x1, y1, x2, y2; cairo_pattern_t *pattern; cairo_fill_extents (cr, &x1, &y1, &x2, &y2); pattern = cairo_pattern_create_linear (x1, y1, x2, y2); cairo_pattern_add_color_stop_rgb (pattern, 0.0, 1.0, 0.0, 0.0); cairo_pattern_add_color_stop_rgb (pattern, 1.0, 0.0, 0.0, 1.0); cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR); cairo_move_to (cr, 0, 0); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); } else { cairo_set_source_rgba (cr, FILL_R, FILL_G, FILL_B, FILL_OPACITY); } cairo_fill_preserve (cr); cairo_set_source_rgba (cr, STROKE_R, STROKE_G, STROKE_B, STROKE_OPACITY); cairo_set_line_width (cr, LINEWIDTH); cairo_stroke (cr); }
void *dt_control_expose(void *voidptr) { int width, height, pointerx, pointery; if(!darktable.gui->surface) return NULL; width = dt_cairo_image_surface_get_width(darktable.gui->surface); height = dt_cairo_image_surface_get_height(darktable.gui->surface); GtkWidget *widget = dt_ui_center(darktable.gui->ui); GdkDevice *device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(widget))); gdk_window_get_device_position(gtk_widget_get_window(widget), device, &pointerx, &pointery, NULL); // create a gtk-independent surface to draw on cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // TODO: control_expose: only redraw the part not overlapped by temporary control panel show! // float tb = 8; // fmaxf(10, width/100.0); darktable.control->tabborder = tb; darktable.control->width = width; darktable.control->height = height; GdkRGBA color; GtkStyleContext *context = gtk_widget_get_style_context(widget); gboolean color_found = gtk_style_context_lookup_color (context, "bg_color", &color); if(!color_found) { color.red = 1.0; color.green = 0.0; color.blue = 0.0; color.alpha = 1.0; } gdk_cairo_set_source_rgba(cr, &color); cairo_set_line_width(cr, tb); cairo_rectangle(cr, tb / 2., tb / 2., width - tb, height - tb); cairo_stroke(cr); cairo_set_line_width(cr, 1.5); color_found = gtk_style_context_lookup_color (context, "really_dark_bg_color", &color); if(!color_found) { color.red = 1.0; color.green = 0.0; color.blue = 0.0; color.alpha = 1.0; } gdk_cairo_set_source_rgba(cr, &color); cairo_rectangle(cr, tb, tb, width - 2 * tb, height - 2 * tb); cairo_stroke(cr); cairo_save(cr); cairo_translate(cr, tb, tb); cairo_rectangle(cr, 0, 0, width - 2 * tb, height - 2 * tb); cairo_clip(cr); cairo_new_path(cr); // draw view dt_view_manager_expose(darktable.view_manager, cr, width - 2 * tb, height - 2 * tb, pointerx - tb, pointery - tb); cairo_restore(cr); // draw log message, if any dt_pthread_mutex_lock(&darktable.control->log_mutex); if(darktable.control->log_ack != darktable.control->log_pos) { PangoRectangle ink; PangoLayout *layout; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); const float fontsize = DT_PIXEL_APPLY_DPI(14); pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, desc); pango_layout_set_text(layout, darktable.control->log_message[darktable.control->log_ack], -1); pango_layout_get_pixel_extents(layout, &ink, NULL); const float pad = DT_PIXEL_APPLY_DPI(20.0f), xc = width / 2.0; const float yc = height * 0.85 + DT_PIXEL_APPLY_DPI(10), wd = pad + ink.width * .5f; float rad = DT_PIXEL_APPLY_DPI(14); cairo_set_line_width(cr, 1.); cairo_move_to(cr, xc - wd, yc + rad); for(int k = 0; k < 5; k++) { cairo_arc(cr, xc - wd, yc, rad, M_PI / 2.0, 3.0 / 2.0 * M_PI); cairo_line_to(cr, xc + wd, yc - rad); cairo_arc(cr, xc + wd, yc, rad, 3.0 * M_PI / 2.0, M_PI / 2.0); cairo_line_to(cr, xc - wd, yc + rad); if(k == 0) { color_found = gtk_style_context_lookup_color (context, "selected_bg_color", &color); if(!color_found) { color.red = 1.0; color.green = 0.0; color.blue = 0.0; color.alpha = 1.0; } gdk_cairo_set_source_rgba(cr, &color); cairo_fill_preserve(cr); } cairo_set_source_rgba(cr, 0., 0., 0., 1.0 / (1 + k)); cairo_stroke(cr); rad += .5f; } color_found = gtk_style_context_lookup_color (context, "fg_color", &color); if(!color_found) { color.red = 1.0; color.green = 0.0; color.blue = 0.0; color.alpha = 1.0; } gdk_cairo_set_source_rgba(cr, &color); cairo_move_to(cr, xc - wd + .5f * pad, (yc + 1. / 3. * fontsize) - fontsize); pango_cairo_show_layout(cr, layout); pango_font_description_free(desc); g_object_unref(layout); } // draw busy indicator if(darktable.control->log_busy > 0) { PangoRectangle ink; PangoLayout *layout; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); const float fontsize = DT_PIXEL_APPLY_DPI(14); pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, desc); pango_layout_set_text(layout, _("working.."), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); const float xc = width / 2.0, yc = height * 0.85 - DT_PIXEL_APPLY_DPI(30), wd = ink.width * .5f; cairo_move_to(cr, xc - wd, yc + 1. / 3. * fontsize - fontsize); pango_cairo_layout_path(cr, layout); cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_fill_preserve(cr); cairo_set_line_width(cr, 0.7); cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_stroke(cr); pango_font_description_free(desc); g_object_unref(layout); } dt_pthread_mutex_unlock(&darktable.control->log_mutex); cairo_destroy(cr); cairo_t *cr_pixmap = cairo_create(darktable.gui->surface); cairo_set_source_surface(cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return NULL; }
static gboolean calf_keyboard_expose (GtkWidget *widget, GdkEventExpose *event) { g_assert(CALF_IS_KEYBOARD(widget)); cairo_pattern_t *pat; CalfKeyboard *self = CALF_KEYBOARD(widget); GdkWindow *window = widget->window; cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(window)); int sy = widget->allocation.height - 1; cairo_set_line_join(c, CAIRO_LINE_JOIN_MITER); cairo_set_line_width(c, 1); for (int i = 0; i < self->nkeys; i++) { CalfKeyboard::KeyInfo ki = { 0.5 + 12 * i, 0.5, 12, sy, 12 * (i / 7) + semitones_w[i % 7], false }; cairo_new_path(c); if (!self->sink->pre_draw(c, ki)) { cairo_rectangle(c, ki.x, ki.y, ki.width, ki.y + ki.height); pat = cairo_pattern_create_linear (ki.x, ki.y, ki.x, ki.y + ki.height); cairo_pattern_add_color_stop_rgb (pat, 0.0, 0.25, 0.25, 0.2); cairo_pattern_add_color_stop_rgb (pat, 0.1, 0.957, 0.914, 0.925); cairo_pattern_add_color_stop_rgb (pat, 1.0, 0.796, 0.787, 0.662); cairo_set_source(c, pat); cairo_fill(c); cairo_set_source_rgba(c, 0, 0, 0, 0.5); if (!self->sink->pre_draw_outline(c, ki)) cairo_stroke(c); else cairo_new_path(c); self->sink->post_draw(c, ki); } } for (int i = 0; i < self->nkeys - 1; i++) { if ((1 << (i % 7)) & 59) { CalfKeyboard::KeyInfo ki = { 8.5 + 12 * i, 0.5, 8, sy * 3 / 5, 12 * (i / 7) + semitones_b[i % 7], true }; cairo_new_path(c); cairo_rectangle(c, ki.x, ki.y, ki.width, ki.height); // gdk_cairo_set_source_color(c, &scBlackKey); if (!self->sink->pre_draw(c, ki)) { pat = cairo_pattern_create_linear (ki.x, ki.y, ki.x, ki.height + ki.y); cairo_pattern_add_color_stop_rgb (pat, 0.0, 0, 0, 0); cairo_pattern_add_color_stop_rgb (pat, 0.1, 0.27, 0.27, 0.27); cairo_pattern_add_color_stop_rgb (pat, 1.0, 0, 0, 0); cairo_set_source(c, pat); cairo_fill(c); pat = cairo_pattern_create_linear (ki.x + 1, ki.y, ki.x + 1, (int)(ki.height * 0.8 + ki.y)); cairo_pattern_add_color_stop_rgb (pat, 0.0, 0, 0, 0); cairo_pattern_add_color_stop_rgb (pat, 0.1, 0.55, 0.55, 0.55); cairo_pattern_add_color_stop_rgb (pat, 0.5, 0.45, 0.45, 0.45); cairo_pattern_add_color_stop_rgb (pat, 0.5001, 0.35, 0.35, 0.35); cairo_pattern_add_color_stop_rgb (pat, 1.0, 0.25, 0.25, 0.25); cairo_set_source(c, pat); cairo_rectangle(c, ki.x + 1, ki.y, ki.width - 2, (int)(ki.height * 0.8 + ki.y)); cairo_fill(c); self->sink->post_draw(c, ki); } } } pat = cairo_pattern_create_linear (widget->allocation.x, widget->allocation.y, widget->allocation.x, (int)(widget->allocation.height * 0.2 + widget->allocation.y)); cairo_pattern_add_color_stop_rgba (pat, 0.0, 0, 0, 0, 0.4); cairo_pattern_add_color_stop_rgba (pat, 1.0, 0, 0, 0, 0); cairo_rectangle(c, widget->allocation.x, widget->allocation.y, widget->allocation.width, (int)(widget->allocation.height * 0.2)); cairo_set_source(c, pat); cairo_fill(c); self->sink->post_all(c); cairo_destroy(c); return TRUE; }
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 cairo_test_status_t draw (cairo_t *cr, int width, int height) { const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_path_t *path; cairo_t *cr_error; /* Ensure that calling cairo_copy_path on an in-error cairo_t will * propagate the error. */ cr_error = cairo_create (NULL); path = cairo_copy_path (cr_error); if (path->status != CAIRO_STATUS_NULL_POINTER) { cairo_test_log (ctx, "Error: cairo_copy_path returned status of %s rather than propagating %s\n", cairo_status_to_string (path->status), cairo_status_to_string (CAIRO_STATUS_NULL_POINTER)); cairo_path_destroy (path); cairo_destroy (cr_error); return CAIRO_TEST_FAILURE; } cairo_path_destroy (path); path = cairo_copy_path_flat (cr_error); if (path->status != CAIRO_STATUS_NULL_POINTER) { cairo_test_log (ctx, "Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n", cairo_status_to_string (path->status), cairo_status_to_string (CAIRO_STATUS_NULL_POINTER)); cairo_path_destroy (path); cairo_destroy (cr_error); return CAIRO_TEST_FAILURE; } cairo_path_destroy (path); cairo_destroy (cr_error); /* first check that we can copy an empty path */ cairo_new_path (cr); path = cairo_copy_path (cr); if (path->status != CAIRO_STATUS_SUCCESS) { cairo_status_t status = path->status; cairo_test_log (ctx, "Error: cairo_copy_path returned status of %s\n", cairo_status_to_string (status)); cairo_path_destroy (path); return cairo_test_status_from_status (ctx, status); } if (path->num_data != 0) { cairo_test_log (ctx, "Error: cairo_copy_path did not copy an empty path, returned path contains %d elements\n", path->num_data); cairo_path_destroy (path); return CAIRO_TEST_FAILURE; } cairo_append_path (cr, path); cairo_path_destroy (path); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_test_log (ctx, "Error: cairo_append_path failed with a copy of an empty path, returned status of %s\n", cairo_status_to_string (cairo_status (cr))); return cairo_test_status_from_status (ctx, cairo_status (cr)); } /* We draw in the default black, so paint white first. */ cairo_save (cr); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_paint (cr); cairo_restore (cr); /* copy path, munge, and fill */ cairo_translate (cr, 5, 5); make_path (cr); path = cairo_copy_path (cr); cairo_new_path (cr); munge_and_set_path (cr, path, scale_by_two); cairo_path_destroy (path); cairo_fill (cr); /* copy flattened path, munge, and fill */ cairo_translate (cr, 0, 15); make_path (cr); path = cairo_copy_path_flat (cr); cairo_new_path (cr); munge_and_set_path (cr, path, scale_by_two); cairo_path_destroy (path); cairo_fill (cr); /* append two copies of path, and fill */ cairo_translate (cr, 0, 15); cairo_scale (cr, 2.0, 2.0); make_path (cr); path = cairo_copy_path (cr); cairo_new_path (cr); cairo_append_path (cr, path); cairo_translate (cr, 2.5, 2.5); cairo_append_path (cr, path); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_fill (cr); cairo_path_destroy (path); return CAIRO_TEST_SUCCESS; }
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; }
void cd_rendering_render_3D_plane (cairo_t *pCairoContext, CairoDock *pDock) { _define_parameters (hi, h0, H, l, r, gamma, h, w, dw); h = pDock->iDecorationsHeight; if (h < 2 * r) r = h / 2; double dx, dy; if (cairo_dock_is_extended_dock (pDock)) // mode panel etendu. { double Ws = pDock->iCurrentWidth; gamma = Ws / 2 / H; double W = Ws - 2 * (r + (l+(r==0)*2)*sqrt(1+gamma*gamma)); double a = H + hi; double b = H + hi + h0 - W / 2; double c = - W / 2; gamma = (-b + sqrt (b * b - 4 * a * c)) / 2 / a; h = hi + h0 / (1 + gamma); //g_print ("h : %.2f (=) %d\n", h, pDock->iDecorationsHeight); w = 2 * H * gamma; dw = (Ws - w) / 2; //g_print ("dw : %.2f (=) %.2f\n", dw, h * gamma + r + (l+(r==0)*2)*sqrt(1+gamma*gamma)); dx = dw; } else { w = cairo_dock_get_current_dock_width_linear (pDock); gamma = w / 2 / H; dw = h * gamma + r + (l+(r==0)*2)*sqrt(1+gamma*gamma); h = pDock->iDecorationsHeight; Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock); dx = (pFirstIcon != NULL ? pFirstIcon->fX - 0*myBackground.iFrameMargin : r); } //\____________________ On trace le cadre. int sens; if (pDock->bDirectionUp) { sens = 1; dy = pDock->iCurrentHeight - pDock->iDecorationsHeight - 1.5 * l; } else { sens = -1; dy = pDock->iDecorationsHeight + 1.5 * l; } cairo_save (pCairoContext); double fDeltaXTrapeze = cairo_dock_draw_frame (pCairoContext, r, l, w, pDock->iDecorationsHeight, dx, dy, sens, gamma, pDock->bHorizontalDock); //\____________________ On dessine les decorations dedans. dy = (pDock->bDirectionUp ? pDock->iCurrentHeight - pDock->iDecorationsHeight - l : l); cairo_dock_render_decorations_in_frame (pCairoContext, pDock, dy, dx-fDeltaXTrapeze, w+2*fDeltaXTrapeze); //\____________________ On dessine le cadre. if (l > 0) { cairo_set_line_width (pCairoContext, l); cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]); cairo_stroke (pCairoContext); } else cairo_new_path (pCairoContext); /// donner un effet d'epaisseur => chaud du slip avec les separateurs physiques ! cairo_restore (pCairoContext); //\____________________ On dessine la ficelle qui les joint. if (myIcons.iStringLineWidth > 0) cairo_dock_draw_string (pCairoContext, pDock, myIcons.iStringLineWidth, FALSE, (my_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)); //\____________________ On dessine les icones et les etiquettes, en tenant compte de l'ordre pour dessiner celles en arriere-plan avant celles en avant-plan. GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons); if (pFirstDrawnElement == NULL) return; double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex); Icon *icon; GList *ic = pFirstDrawnElement; if (my_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR) { cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_SQUARE); do { icon = ic->data; if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon)) { cairo_save (pCairoContext); cd_rendering_draw_3D_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, TRUE); cairo_restore (pCairoContext); } ic = cairo_dock_get_next_element (ic, pDock->icons); } while (ic != pFirstDrawnElement); do { icon = ic->data; if (icon->acFileName != NULL || ! CAIRO_DOCK_IS_SEPARATOR (icon)) { cairo_save (pCairoContext); cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE); cairo_restore (pCairoContext); } ic = cairo_dock_get_next_element (ic, pDock->icons); } while (ic != pFirstDrawnElement); if (my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR) { do { icon = ic->data; if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon)) { cairo_save (pCairoContext); cd_rendering_draw_3D_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, FALSE); cairo_restore (pCairoContext); } ic = cairo_dock_get_next_element (ic, pDock->icons); } while (ic != pFirstDrawnElement); } } else { do { icon = ic->data; cairo_save (pCairoContext); cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE); cairo_restore (pCairoContext); ic = cairo_dock_get_next_element (ic, pDock->icons); } while (ic != pFirstDrawnElement); } }