bool CurveWarp::accelerated_cairorender(Context context, cairo_t *cr, int quality, const RendDesc &renddesc_, ProgressCallback *cb)const { Point start_point=param_start_point.get(Point()); Point end_point=param_end_point.get(Point()); SuperCallback stageone(cb,0,9000,10000); SuperCallback stagetwo(cb,9000,10000,10000); RendDesc renddesc(renddesc_); // Untransform the render desc if(!cairo_renddesc_untransform(cr, renddesc)) return false; int x,y; const Real pw(renddesc.get_pw()),ph(renddesc.get_ph()); Point tl(renddesc.get_tl()); Point br(renddesc.get_br()); const int w(renddesc.get_w()); const int h(renddesc.get_h()); // find a bounding rectangle for the context we need to render // todo: find a better way of doing this - this way doesn't work Rect src_rect(transform(tl)); Point pos1, pos2; Real dist, along; Real min_dist(999999), max_dist(-999999), min_along(999999), max_along(-999999); #define UPDATE_DIST \ if (dist < min_dist) min_dist = dist; \ if (dist > max_dist) max_dist = dist; \ if (along < min_along) min_along = along; \ if (along > max_along) max_along = along // look along the top and bottom edges pos1[0] = pos2[0] = tl[0]; pos1[1] = tl[1]; pos2[1] = br[1]; for (x = 0; x < w; x++, pos1[0] += pw, pos2[0] += pw) { src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST; src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST; } // look along the left and right edges pos1[0] = tl[0]; pos2[0] = br[0]; pos1[1] = pos2[1] = tl[1]; for (y = 0; y < h; y++, pos1[1] += ph, pos2[1] += ph) { src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST; src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST; } // look along the diagonals const int max_wh(std::max(w,h)); const Real inc_x((br[0]-tl[0])/max_wh),inc_y((br[1]-tl[1])/max_wh); pos1[0] = pos2[0] = tl[0]; pos1[1] = tl[1]; pos2[1] = br[1]; for (x = 0; x < max_wh; x++, pos1[0] += inc_x, pos2[0] = pos1[0], pos1[1]+=inc_y, pos2[1]-=inc_y) { src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST; src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST; } #if 0 // look at each blinepoint std::vector<synfig::BLinePoint>::const_iterator iter; for (iter=bline.begin(); iter!=bline.end(); iter++) src_rect.expand(transform(iter->get_vertex()+origin, &dist, &along)); UPDATE_DIST; #endif Point src_tl(src_rect.get_min()); Point src_br(src_rect.get_max()); Vector ab((end_point - start_point).norm()); Angle::tan ab_angle(ab[1], ab[0]); Real used_length = max_along - min_along; Real render_width = max_dist - min_dist; int src_w = (abs(used_length*Angle::cos(ab_angle).get()) + abs(render_width*Angle::sin(ab_angle).get())) / abs(pw); int src_h = (abs(used_length*Angle::sin(ab_angle).get()) + abs(render_width*Angle::cos(ab_angle).get())) / abs(ph); Real src_pw((src_br[0] - src_tl[0]) / src_w); Real src_ph((src_br[1] - src_tl[1]) / src_h); if (src_pw > abs(pw)) { src_w = int((src_br[0] - src_tl[0]) / abs(pw)); src_pw = (src_br[0] - src_tl[0]) / src_w; } if (src_ph > abs(ph)) { src_h = int((src_br[1] - src_tl[1]) / abs(ph)); src_ph = (src_br[1] - src_tl[1]) / src_h; } #define MAXPIX 10000 if (src_w > MAXPIX) src_w = MAXPIX; if (src_h > MAXPIX) src_h = MAXPIX; // this is an attempt to remove artifacts around tile edges - the // cubic interpolation uses at most 2 pixels either side of the // target pixel, so add an extra 2 pixels around the tile on all // sides src_tl -= (Point(src_pw,src_ph)*2); src_br += (Point(src_pw,src_ph)*2); src_w += 4; src_h += 4; src_pw = (src_br[0] - src_tl[0]) / src_w; src_ph = (src_br[1] - src_tl[1]) / src_h; // set up a renddesc for the context to render RendDesc src_desc(renddesc); //src_desc.clear_flags(); src_desc.set_tl(src_tl); src_desc.set_br(src_br); src_desc.set_wh(src_w, src_h); // New expanded renddesc values const double wpw=src_desc.get_pw(); const double wph=src_desc.get_ph(); const double wtlx=src_desc.get_tl()[0]; const double wtly=src_desc.get_tl()[1]; // render the context onto a new surface cairo_surface_t* csource, *cresult; csource=cairo_surface_create_similar(cairo_get_target(cr),CAIRO_CONTENT_COLOR_ALPHA, src_w, src_h); cresult=cairo_surface_create_similar(cairo_get_target(cr),CAIRO_CONTENT_COLOR_ALPHA, w, h); cairo_t *subcr=cairo_create(csource); cairo_scale(subcr, 1/wpw, 1/wph); cairo_translate(subcr, -wtlx, -wtly); if(!context.accelerated_cairorender(subcr,quality,src_desc,&stageone)) return false; // don't needed anymore cairo_destroy(subcr); //access to pixels CairoSurface source(csource); source.map_cairo_image(); CairoSurface result(cresult); result.map_cairo_image(); float u,v; Point pos, tmp; if(quality<=4) // CUBIC for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph) { for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw) { tmp=transform(pos); u=(tmp[0]-src_tl[0])/src_pw; v=(tmp[1]-src_tl[1])/src_ph; if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v)) result[y][x]=CairoColor(context.get_color(tmp)).premult_alpha(); else result[y][x]=source.cubic_sample_cooked(u,v); } if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false; } else if (quality<=6) // INTERPOLATION_LINEAR for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph) { for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw) { tmp=transform(pos); u=(tmp[0]-src_tl[0])/src_pw; v=(tmp[1]-src_tl[1])/src_ph; if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v)) result[y][x]=CairoColor(context.get_color(tmp)).premult_alpha(); else result[y][x]=source.linear_sample_cooked(u,v); } if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false; } else // NEAREST_NEIGHBOR for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph) { for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw) { tmp=transform(pos); u=(tmp[0]-src_tl[0])/src_pw; v=(tmp[1]-src_tl[1])/src_ph; if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v)) result[y][x]=CairoColor(context.get_color(tmp)).premult_alpha(); else result[y][x]=source[floor_to_int(v)][floor_to_int(u)]; } if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false; } result.unmap_cairo_image(); source.unmap_cairo_image(); cairo_surface_destroy(csource); // Now paint it on the context cairo_save(cr); cairo_translate(cr, tl[0], tl[1]); cairo_scale(cr, pw, ph); cairo_set_source_surface(cr, cresult, 0, 0); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_restore(cr); cairo_surface_destroy(cresult); // Mark our progress as finished if(cb && !cb->amount_complete(10000,10000)) return false; return true; }
static void ect_print (ECellView *ecell_view, GtkPrintContext *context, gint model_col, gint view_col, gint row, gdouble width, gdouble height) { ECellTreeView *tree_view = (ECellTreeView *) ecell_view; cairo_t *cr = gtk_print_context_get_cairo_context (context); cairo_save (cr); if (E_CELL_TREE (tree_view->cell_view.ecell)->grouped_view) { ETreeModel *tree_model = e_cell_tree_get_tree_model (ecell_view->e_table_model, row); ETreeTableAdapter *tree_table_adapter = e_cell_tree_get_tree_table_adapter (ecell_view->e_table_model, row); ETreePath node = e_cell_tree_get_node (ecell_view->e_table_model, row); gint offset = offset_of_node (ecell_view->e_table_model, row); gint subcell_offset = offset; gboolean expandable = e_tree_model_node_is_expandable (tree_model, node); /* draw our lines */ if (E_CELL_TREE (tree_view->cell_view.ecell)->draw_lines) { gint depth; if (!e_tree_model_node_is_root (tree_model, node) || e_tree_model_node_get_n_children (tree_model, node) > 0) { cairo_move_to ( cr, offset - INDENT_AMOUNT / 2, height / 2); cairo_line_to (cr, offset, height / 2); } if (visible_depth_of_node (ecell_view->e_table_model, row) != 0) { cairo_move_to ( cr, offset - INDENT_AMOUNT / 2, height); cairo_line_to ( cr, offset - INDENT_AMOUNT / 2, e_tree_table_adapter_node_get_next (tree_table_adapter, node) ? 0 : height / 2); } /* now traverse back up to the root of the tree, checking at * each level if the node has siblings, and drawing the * correct vertical pipe for it's configuration. */ node = e_tree_model_node_get_parent (tree_model, node); depth = visible_depth_of_node (ecell_view->e_table_model, row) - 1; offset -= INDENT_AMOUNT; while (node && depth != 0) { if (e_tree_table_adapter_node_get_next (tree_table_adapter, node)) { cairo_move_to ( cr, offset - INDENT_AMOUNT / 2, height); cairo_line_to ( cr, offset - INDENT_AMOUNT / 2, 0); } node = e_tree_model_node_get_parent (tree_model, node); depth--; offset -= INDENT_AMOUNT; } } /* now draw our icon if we're expandable */ if (expandable) { gboolean expanded; GdkRectangle r; gint exp_size = 0; gtk_widget_style_get (GTK_WIDGET (gtk_widget_get_parent (GTK_WIDGET (tree_view->canvas))), "expander_size", &exp_size, NULL); node = e_cell_tree_get_node (ecell_view->e_table_model, row); expanded = e_tree_table_adapter_node_is_expanded (tree_table_adapter, node); r.x = 0; r.y = 0; r.width = MIN (width, exp_size); r.height = height; draw_expander (tree_view, cr, expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED, GTK_STATE_NORMAL, &r); } cairo_stroke (cr); cairo_translate (cr, subcell_offset, 0); width -= subcell_offset; } cairo_restore (cr); e_cell_print (tree_view->subcell_view, context, model_col, view_col, row, width, height); }
static void draw_unlock_indicator() { /* Initialise the surface if not yet done */ if (unlock_indicator_surface == NULL) { button_diameter_physical = ceil(scaling_factor() * BUTTON_DIAMETER); DEBUG("scaling_factor is %.f, physical diameter is %d px\n", scaling_factor(), button_diameter_physical); unlock_indicator_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, button_diameter_physical, button_diameter_physical); } cairo_t *ctx = cairo_create(unlock_indicator_surface); /* clear the surface */ cairo_save(ctx); cairo_set_operator(ctx, CAIRO_OPERATOR_CLEAR); cairo_paint(ctx); cairo_restore(ctx); if (unlock_state >= STATE_KEY_PRESSED && unlock_indicator) { cairo_scale(ctx, scaling_factor(), scaling_factor()); /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 10.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, 0 /* start */, 2 * M_PI /* end */); /* Use the appropriate color for the different PAM states * (currently verifying, wrong password, or default) */ switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgba(ctx, 0, 114.0 / 255, 255.0 / 255, 0.75); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, 250.0 / 255, 0, 0, 0.75); break; default: cairo_set_source_rgba(ctx, 0, 0, 0, 0.75); break; } cairo_fill_preserve(ctx); switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgb(ctx, 51.0 / 255, 0, 250.0 / 255); break; case STATE_PAM_WRONG: cairo_set_source_rgb(ctx, 125.0 / 255, 51.0 / 255, 0); break; case STATE_PAM_IDLE: cairo_set_source_rgb(ctx, 51.0 / 255, 125.0 / 255, 0); break; } cairo_stroke(ctx); /* Draw an inner seperator line. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_line_width(ctx, 2.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS - 5 /* radius */, 0, 2 * M_PI); cairo_stroke(ctx); cairo_set_line_width(ctx, 10.0); /* Display a (centered) text of the current PAM state. */ char *text = NULL; /* We don't want to show more than a 3-digit number. */ char buf[4]; cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_font_size(ctx, 28.0); switch (pam_state) { case STATE_PAM_VERIFY: text = "verifying…"; break; case STATE_PAM_WRONG: text = "wrong!"; break; default: if (show_failed_attempts && failed_attempts > 0) { if (failed_attempts > 999) { text = "> 999"; } else { snprintf(buf, sizeof(buf), "%d", failed_attempts); text = buf; } cairo_set_source_rgb(ctx, 1, 0, 0); cairo_set_font_size(ctx, 32.0); } break; } if (text) { cairo_text_extents_t extents; double x, y; cairo_text_extents(ctx, text, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing); cairo_move_to(ctx, x, y); cairo_show_text(ctx, text); cairo_close_path(ctx); } if (pam_state == STATE_PAM_WRONG && (modifier_string != NULL)) { cairo_text_extents_t extents; double x, y; cairo_set_font_size(ctx, 14.0); cairo_text_extents(ctx, modifier_string, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + 28.0; cairo_move_to(ctx, x, y); cairo_show_text(ctx, modifier_string); cairo_close_path(ctx); } /* After the user pressed any valid key or the backspace key, we * highlight a random part of the unlock indicator to confirm this * keypress. */ if (unlock_state == STATE_KEY_ACTIVE || unlock_state == STATE_BACKSPACE_ACTIVE) { cairo_new_sub_path(ctx); double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0; cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start, highlight_start + (M_PI / 3.0)); if (unlock_state == STATE_KEY_ACTIVE) { /* For normal keys, we use a lighter green. */ cairo_set_source_rgb(ctx, 51.0 / 255, 219.0 / 255, 0); } else { /* For backspace, we use red. */ cairo_set_source_rgb(ctx, 219.0 / 255, 51.0 / 255, 0); } cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start /* start */, highlight_start + (M_PI / 128.0) /* end */); cairo_stroke(ctx); cairo_arc( ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start + (M_PI / 3.0) /* start */, (highlight_start + (M_PI / 3.0)) + (M_PI / 128.0) /* end */); cairo_stroke(ctx); } } cairo_destroy(ctx); }
void rendering_draw_caroussel_in_desklet (cairo_t *pCairoContext, CairoDesklet *pDesklet, gboolean bRenderOptimized) { CDCarousselParameters *pCaroussel = (CDCarousselParameters *) pDesklet->pRendererData; //g_print ("%s(%x)\n", __func__, pCaroussel); if (pCaroussel == NULL) return ; double fTheta = G_PI/2 + pCaroussel->fRotationAngle, fDeltaTheta = pCaroussel->fDeltaTheta; int iEllipseHeight = pCaroussel->iEllipseHeight; double fInclinationOnHorizon = pCaroussel->fInclinationOnHorizon; int iFrameHeight = pCaroussel->iFrameHeight; double fExtraWidth = pCaroussel->fExtraWidth; double a = pCaroussel->a, b = pCaroussel->b; Icon *pIcon; GList *ic; if (pCaroussel->b3D) { for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (fTheta > G_PI && fTheta < 2*G_PI) // arriere-plan. { pIcon->fScale = (1 + .5 * fabs (fTheta - 3 * G_PI / 2) / (G_PI / 2)) / 1.5; pIcon->fAlpha = pIcon->fScale; } else { pIcon->fScale = 1.; pIcon->fAlpha = 1.; } pIcon->fDrawX = pDesklet->iWidth / 2 + a * cos (fTheta) - pIcon->fWidth/2 * 1; pIcon->fDrawY = pDesklet->iHeight / 2 + b * sin (fTheta) - pIcon->fHeight * pIcon->fScale + myLabels.iconTextDescription.iSize; fTheta += fDeltaTheta; if (fTheta >= G_PI/2 + 2*G_PI) fTheta -= 2*G_PI; } //\____________________ On trace le cadre. double fLineWidth = g_iDockLineWidth; double fMargin = 0*myBackground.iFrameMargin; double fDockWidth = pDesklet->iWidth - fExtraWidth; int sens=1; double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre. fDockOffsetX = fExtraWidth / 2; fDockOffsetY = (pDesklet->iHeight - iEllipseHeight) / 2 + myLabels.iconTextDescription.iSize; cairo_save (pCairoContext); cairo_dock_draw_frame (pCairoContext, g_iDockRadius, fLineWidth, fDockWidth, iFrameHeight, fDockOffsetX, fDockOffsetY, sens, fInclinationOnHorizon, pDesklet->bIsHorizontal); //\____________________ On dessine les decorations dedans. cairo_set_source_rgba (pCairoContext, .8, .8, .8, .75); cairo_fill_preserve (pCairoContext); //\____________________ On dessine le cadre. if (fLineWidth > 0) { cairo_set_line_width (pCairoContext, fLineWidth); cairo_set_source_rgba (pCairoContext, .9, .9, .9, 1.); cairo_stroke (pCairoContext); } cairo_restore (pCairoContext); //\____________________ On dessine les icones dans l'ordre qui va bien. for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); if (pIcon->fDrawY + pIcon->fHeight < pDesklet->iHeight / 2 + myLabels.iconTextDescription.iSize && pIcon->fDrawX + pIcon->fWidth/2 > pDesklet->iWidth / 2) // arriere-plan droite. cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, TRUE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } } for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); if (pIcon->fDrawY + pIcon->fHeight < pDesklet->iHeight / 2 + myLabels.iconTextDescription.iSize && pIcon->fDrawX + pIcon->fWidth/2 <= pDesklet->iWidth / 2) // arriere-plan gauche. cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, TRUE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } } cairo_save (pCairoContext); pDesklet->pIcon->fDrawY = pDesklet->iHeight/2 - pDesklet->pIcon->fHeight + myLabels.iconTextDescription.iSize; cairo_dock_render_one_icon_in_desklet (pDesklet->pIcon, pCairoContext, TRUE, FALSE, pDesklet->iWidth); cairo_restore (pCairoContext); for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); if (pIcon->fDrawY + pIcon->fHeight >= pDesklet->iHeight / 2 + myLabels.iconTextDescription.iSize && pIcon->fDrawX + pIcon->fWidth/2 > pDesklet->iWidth / 2) // avant-plan droite. cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, TRUE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } } for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); if (pIcon->fDrawY + pIcon->fHeight >= pDesklet->iHeight / 2 + myLabels.iconTextDescription.iSize && pIcon->fDrawX + pIcon->fWidth/2 <= pDesklet->iWidth / 2) // avant-plan gauche. cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, TRUE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } } } else { cairo_save (pCairoContext); cairo_dock_render_one_icon_in_desklet (pDesklet->pIcon, pCairoContext, FALSE, FALSE, pDesklet->iWidth); cairo_restore (pCairoContext); gboolean bFlip = (pDesklet->pIcon->fHeight > pDesklet->pIcon->fWidth); for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); pIcon->fDrawX = pDesklet->pIcon->fDrawX + pDesklet->pIcon->fWidth / 2 + (bFlip ? b : a) * cos (fTheta) - pIcon->fWidth/2; pIcon->fDrawY = pDesklet->pIcon->fDrawY + pDesklet->pIcon->fHeight / 2 + (bFlip ? a : b) * sin (fTheta) - pIcon->fHeight/2 + myLabels.iconTextDescription.iSize; cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, FALSE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } fTheta += fDeltaTheta; if (fTheta >= G_PI/2 + 2*G_PI) fTheta -= 2*G_PI; } } }
static void eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { Render_Engine *re; Evas_Cairo_Context *ctxt; Evas_Cairo_Image *im; DATA32 *pix; re = (Render_Engine *)data; ctxt = (Evas_Cairo_Context *)context; if (!image) return; im = image; evas_common_load_image_data_from_file(im->im); pix = im->im->image->data; if (pix) { if (!im->surface) { im->mulpix = malloc(im->im->image->w * im->im->image->h * sizeof(DATA32)); if (im->mulpix) { int i, n; DATA32 *p; n = im->im->image->w * im->im->image->h; p = im->mulpix; for (i = 0; i < n; i++) { int a; a = A_VAL(pix); R_VAL(p) = (R_VAL(pix) * a) / 255; G_VAL(p) = (G_VAL(pix) * a) / 255; B_VAL(p) = (B_VAL(pix) * a) / 255; A_VAL(p) = a; p++; pix++; } im->surface = cairo_image_surface_create_for_data(im->mulpix, CAIRO_FORMAT_ARGB32, im->im->image->w, im->im->image->h, 0); im->pattern = cairo_pattern_create_for_surface(im->surface); } } if (smooth) cairo_pattern_set_filter(im->pattern, CAIRO_FILTER_BILINEAR); else cairo_pattern_set_filter(im->pattern, CAIRO_FILTER_NEAREST); cairo_save(ctxt->cairo); cairo_translate(ctxt->cairo, dst_x, dst_y); cairo_scale(ctxt->cairo, (double)src_w / (double)dst_w, (double)src_h / (double)dst_h); cairo_move_to(ctxt->cairo, 0, 0); // cairo_set_rgb_color(re->win->cairo, // (double)(R_VAL(((RGBA_Draw_Context *)context)->col.col)) / 255.0, // (double)(R_VAL(((RGBA_Draw_Context *)context)->col.col)) / 255.0, // (double)(R_VAL(((RGBA_Draw_Context *)context)->col.col)) / 255.0); // cairo_set_alpha(re->win->cairo, // (double)(A_VAL(((RGBA_Draw_Context *)context)->col.col)) / 255.0); cairo_set_source_surface(ctxt->cairo, im->surface, im->im->image->w, im->im->image->h); cairo_paint(ctxt->cairo); cairo_restore(ctxt->cairo); } }
GIcon * photos_utils_create_collection_icon (gint base_size, GList *pixbufs) { cairo_surface_t *surface; /* TODO: use g_autoptr */ cairo_t *cr; /* TODO: use g_autoptr */ GdkPixbuf *pix; GIcon *ret_val; GList *l; g_autoptr (GtkStyleContext) context = NULL; g_autoptr (GtkWidgetPath) path = NULL; gint cur_x; gint cur_y; gint padding; gint pix_height; gint pix_width; gint scale_size; gint tile_size; guint idx; guint n_grid; guint n_pixbufs; guint n_tiles; n_pixbufs = g_list_length (pixbufs); if (n_pixbufs < 3) { n_grid = 1; n_tiles = 1; } else { n_grid = 2; n_tiles = 4; } padding = MAX (base_size / 10, 4); tile_size = (base_size - ((n_grid + 1) * padding)) / n_grid; context = gtk_style_context_new (); gtk_style_context_add_class (context, "photos-collection-icon"); path = gtk_widget_path_new (); gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); gtk_style_context_set_path (context, path); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, base_size, base_size); cr = cairo_create (surface); gtk_render_background (context, cr, 0, 0, base_size, base_size); l = pixbufs; idx = 0; cur_x = padding; cur_y = padding; while (l != NULL && idx < n_tiles) { pix = l->data; pix_width = gdk_pixbuf_get_width (pix); pix_height = gdk_pixbuf_get_height (pix); scale_size = MIN (pix_width, pix_height); cairo_save (cr); cairo_translate (cr, cur_x, cur_y); cairo_rectangle (cr, 0, 0, tile_size, tile_size); cairo_clip (cr); cairo_scale (cr, (gdouble) tile_size / (gdouble) scale_size, (gdouble) tile_size / (gdouble) scale_size); gdk_cairo_set_source_pixbuf (cr, pix, 0, 0); cairo_paint (cr); cairo_restore (cr); idx++; l = l->next; if ((idx % n_grid) == 0) { cur_x = padding; cur_y += tile_size + padding; } else { cur_x += tile_size + padding; } } ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size)); cairo_surface_destroy (surface); cairo_destroy (cr); return ret_val; }
static void paint_grid_and_ticks (GsGraph *graph, cairo_t *cr) { GsPoint origin; gs_point_to_pixel (&(graph->priv->transform), &(graph->priv->origin), &origin); gint k; gdouble pos; if (!graph->priv->show_grid && !graph->priv->show_ticks) { return; } cairo_set_line_width (cr, 0.5); // Horizontal grid lines/ticks gint start_y = (gint) (floor (graph->priv->view.y1 / graph->priv->grid_dy)); gint end_y = (gint) (floor (graph->priv->view.y2 / graph->priv->grid_dy)); for (k = start_y; k <= end_y; k++) { gs_point_to_pixel_values (&(graph->priv->transform), 0, k * graph->priv->grid_dy, NULL, &pos); if (graph->priv->show_grid) { cairo_save (cr); if (graph->priv->dotted_grid) { cairo_set_dash (cr, DASH_PATTERN, 1, 0); } gdk_cairo_set_source_color (cr, graph->priv->grid_color); cairo_move_to (cr, 0, pos); cairo_line_to (cr, graph->priv->width, pos); cairo_stroke (cr); cairo_restore (cr); } if (graph->priv->show_vertical_axis && graph->priv->show_ticks) { gdk_cairo_set_source_color (cr, graph->priv->axes_color); cairo_move_to (cr, origin.x - graph->priv->tick_length, pos); cairo_line_to (cr, origin.x + graph->priv->tick_length, pos); cairo_stroke (cr); } } // Vertical grid lines/ticks gint start_x = (gint) (floor (graph->priv->view.x1 / graph->priv->grid_dx)); gint end_x = (gint) (floor (graph->priv->view.x2 / graph->priv->grid_dx)); for (k = start_x; k <= end_x; k++) { gs_point_to_pixel_values (&(graph->priv->transform), k * graph->priv->grid_dx, 0, &pos, NULL); if (graph->priv->show_grid) { cairo_save (cr); if (graph->priv->dotted_grid) { cairo_set_dash (cr, DASH_PATTERN, 1, 0); } gdk_cairo_set_source_color (cr, graph->priv->grid_color); cairo_move_to (cr, pos, 0); cairo_line_to (cr, pos, graph->priv->height); cairo_stroke (cr); cairo_restore (cr); } if (graph->priv->show_horizontal_axis && graph->priv->show_ticks) { gdk_cairo_set_source_color (cr, graph->priv->axes_color); cairo_move_to (cr, pos, origin.y + graph->priv->tick_length); cairo_line_to (cr, pos, origin.y - graph->priv->tick_length); cairo_stroke (cr); } } }
static gboolean _lib_filmstrip_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)self->data; int32_t width = widget->allocation.width; int32_t height = widget->allocation.height; gdouble pointerx = strip->pointerx; gdouble pointery = strip->pointery; if(darktable.gui->center_tooltip == 1) darktable.gui->center_tooltip++; strip->image_over = DT_VIEW_DESERT; DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, -1); /* create cairo surface */ cairo_t *cr = gdk_cairo_create(widget->window); /* fill background */ cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); int offset = strip->offset; const float wd = height; const float ht = height; int max_cols = (int)(width/(float)wd) + 2; if (max_cols%2 == 0) max_cols += 1; const int col_start = max_cols/2 - strip->offset; const int empty_edge = (width - (max_cols * wd))/2; int step_res = SQLITE_ROW; sqlite3_stmt *stmt = NULL; /* mouse over image position in filmstrip */ pointerx -= empty_edge; const int seli = (pointery > 0 && pointery <= ht) ? pointerx / (float)wd : -1; const int img_pointerx = (int)fmodf(pointerx, wd); const int img_pointery = (int)pointery; /* get the count of current collection */ strip->collection_count = dt_collection_get_count (darktable.collection); /* get the collection query */ const gchar *query=dt_collection_get_query (darktable.collection); if(!query) return FALSE; if(offset < 0) strip->offset = offset = 0; if(offset > strip->collection_count-1) strip->offset = offset = strip->collection_count-1; // dt_view_set_scrollbar(self, offset, count, max_cols, 0, 1, 1); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, offset - max_cols/2); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, max_cols); cairo_save(cr); cairo_translate(cr, empty_edge, 0.0f); for(int col = 0; col < max_cols; col++) { if(col < col_start) { cairo_translate(cr, wd, 0.0f); continue; } if(step_res != SQLITE_DONE) { step_res = sqlite3_step(stmt); } if(step_res == SQLITE_ROW) { int id = sqlite3_column_int(stmt, 0); // set mouse over id if(seli == col) { strip->mouse_over_id = id; DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, strip->mouse_over_id); } cairo_save(cr); // FIXME find out where the y translation is done, how big the value is and use it directly instead of getting it from the matrix ... cairo_matrix_t m; cairo_get_matrix(cr, &m); dt_view_image_expose(&(strip->image_over), id, cr, wd, ht, max_cols, img_pointerx, img_pointery, FALSE); cairo_restore(cr); } else if (step_res == SQLITE_DONE) { /* do nothing, just add some empty thumb frames */ } else goto failure; cairo_translate(cr, wd, 0.0f); } failure: cairo_restore(cr); sqlite3_finalize(stmt); if(darktable.gui->center_tooltip == 1) // set in this round { char* tooltip = dt_history_get_items_as_string(strip->mouse_over_id); if(tooltip != NULL) { g_object_set(G_OBJECT(strip->filmstrip), "tooltip-text", tooltip, (char *)NULL); g_free(tooltip); } } else if(darktable.gui->center_tooltip == 2) // not set in this round { darktable.gui->center_tooltip = 0; g_object_set(G_OBJECT(strip->filmstrip), "tooltip-text", "", (char *)NULL); } #ifdef _DEBUG if(darktable.unmuted & DT_DEBUG_CACHE) dt_mipmap_cache_print(darktable.mipmap_cache); #endif /* cleanup */ cairo_destroy(cr); return TRUE; }
static cairo_time_t draw_spiral (cairo_t *cr, cairo_fill_rule_t fill_rule, align_t align, close_t close, int width, int height, int loops) { int i; int n=0; double x[MAX_SEGMENTS]; double y[MAX_SEGMENTS]; int step = 3; int side = width < height ? width : height; assert(5*(side/step/2+1)+2 < MAX_SEGMENTS); #define L(x_,y_) (x[n] = (x_), y[n] = (y_), n++) #define M(x_,y_) L(x_,y_) #define v(t) L(x[n-1], y[n-1] + (t)) #define h(t) L(x[n-1] + (t), y[n-1]) switch (align) { case PIXALIGN: M(0,0); break; case NONALIGN: M(0.1415926, 0.7182818); break; } while (side >= step && side >= 0) { v(side); h(side); v(-side); h(-side+step); v(step); side -= 2*step; } switch (close) { case RECTCLOSE: L(x[n-1],y[0]); break; case DIAGCLOSE: L(x[0],y[0]); break; } assert(n < MAX_SEGMENTS); cairo_save (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); cairo_translate (cr, 1, 1); cairo_set_fill_rule (cr, fill_rule); cairo_set_source_rgb (cr, 1, 0, 0); cairo_new_path (cr); cairo_move_to (cr, x[0], y[0]); for (i = 1; i < n; i++) { cairo_line_to (cr, x[i], y[i]); } cairo_close_path (cr); cairo_perf_timer_start (); cairo_perf_set_thread_aware (cr, FALSE); while (loops--) { if (loops == 0) cairo_perf_set_thread_aware (cr, TRUE); cairo_fill_preserve (cr); } cairo_perf_timer_stop (); cairo_restore (cr); return cairo_perf_timer_elapsed (); }
void DrawResizableBackground(cairo_t *c, cairo_surface_t *background, int width, int height, int marginLeft, int marginTop, int marginRight, int marginBottom, FillRule fillV, FillRule fillH ) { int resizeHeight = cairo_image_surface_get_height(background) - marginTop - marginBottom; int resizeWidth = cairo_image_surface_get_width(background) - marginLeft - marginRight; if (resizeHeight <= 0) resizeHeight = 1; if (resizeWidth <= 0) resizeWidth = 1; cairo_save(c); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(c, background, 0, 0); /* 九宫格 * 7 8 9 * 4 5 6 * 1 2 3 */ /* part 1 */ cairo_save(c); cairo_translate(c, 0, height - marginBottom); cairo_set_source_surface(c, background, 0, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, marginLeft, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 3 */ cairo_save(c); cairo_translate(c, width - marginRight, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, marginRight, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 7 */ cairo_save(c); cairo_rectangle(c, 0, 0, marginLeft, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 9 */ cairo_save(c); cairo_translate(c, width - marginRight, 0); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, 0); cairo_rectangle(c, 0, 0, marginRight, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 & 8 */ { if (fillH == F_COPY) { int repaint_times = (width - marginLeft - marginRight) / resizeWidth; int remain_width = (width - marginLeft - marginRight) % resizeWidth; int i = 0; for (i = 0; i < repaint_times; i++) { /* part 8 */ cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth, 0); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, resizeWidth, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, resizeWidth, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } if (remain_width != 0) { /* part 8 */ cairo_save(c); cairo_translate(c, marginLeft + repaint_times * resizeWidth, 0); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, remain_width, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, marginLeft + repaint_times * resizeWidth, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, remain_width, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } else { cairo_save(c); cairo_translate(c, marginLeft, 0); cairo_scale(c, (double)(width - marginLeft - marginRight) / (double)resizeWidth, 1); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, resizeWidth, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); cairo_save(c); cairo_translate(c, marginLeft, height - marginBottom); cairo_scale(c, (double)(width - marginLeft - marginRight) / (double)resizeWidth, 1); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, resizeWidth, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } /* part 4 & 6 */ { if (fillV == F_COPY) { int repaint_times = (height - marginTop - marginBottom) / resizeHeight; int remain_height = (height - marginTop - marginBottom) % resizeHeight; int i = 0; for (i = 0; i < repaint_times; i++) { /* part 4 */ cairo_save(c); cairo_translate(c, 0, marginTop + i * resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 6 */ cairo_save(c); cairo_translate(c, width - marginRight, marginTop + i * resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); } if (remain_height != 0) { /* part 8 */ cairo_save(c); cairo_translate(c, 0, marginTop + repaint_times * resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, remain_height); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, width - marginRight, marginTop + repaint_times * resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, remain_height); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } else { cairo_save(c); cairo_translate(c, 0, marginTop); cairo_scale(c, 1, (double)(height - marginTop - marginBottom) / (double)resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); cairo_save(c); cairo_translate(c, width - marginRight, marginTop); cairo_scale(c, 1, (double)(height - marginTop - marginBottom) / (double)resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } /* part 5 */ { int repaintH = 0, repaintV = 0; int remainW = 0, remainH = 0; double scaleX = 1.0, scaleY = 1.0; if (fillH == F_COPY) { repaintH = (width - marginLeft - marginRight) / resizeWidth + 1; remainW = (width - marginLeft - marginRight) % resizeWidth; } else { repaintH = 1; scaleX = (double)(width - marginLeft - marginRight) / (double)resizeWidth; } if (fillV == F_COPY) { repaintV = (height - marginTop - marginBottom) / (double)resizeHeight + 1; remainH = (height - marginTop - marginBottom) % resizeHeight; } else { repaintV = 1; scaleY = (double)(height - marginTop - marginBottom) / (double)resizeHeight; } int i, j; for (i = 0; i < repaintH; i ++) { for (j = 0; j < repaintV; j ++) { cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth , marginTop + j * resizeHeight); cairo_scale(c, scaleX, scaleY); cairo_set_source_surface(c, background, -marginLeft, -marginTop); int w = resizeWidth, h = resizeHeight; if (fillV == F_COPY && j == repaintV - 1) h = remainH; if (fillH == F_COPY && i == repaintH - 1) w = remainW; cairo_rectangle(c, 0, 0, w, h); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } } cairo_restore(c); }
static Bool textRenderTextToSurface (CompScreen *s, const char *text, TextSurfaceData *data, const CompTextAttrib *attrib) { int width, height, layoutWidth; pango_font_description_set_family (data->font, attrib->family); pango_font_description_set_absolute_size (data->font, attrib->size * PANGO_SCALE); pango_font_description_set_style (data->font, PANGO_STYLE_NORMAL); if (attrib->flags & CompTextFlagStyleBold) pango_font_description_set_weight (data->font, PANGO_WEIGHT_BOLD); if (attrib->flags & CompTextFlagStyleItalic) pango_font_description_set_style (data->font, PANGO_STYLE_ITALIC); pango_layout_set_font_description (data->layout, data->font); if (attrib->flags & CompTextFlagEllipsized) pango_layout_set_ellipsize (data->layout, PANGO_ELLIPSIZE_END); pango_layout_set_auto_dir (data->layout, FALSE); pango_layout_set_text (data->layout, text, -1); pango_layout_get_pixel_size (data->layout, &width, &height); if (attrib->flags & CompTextFlagWithBackground) { width += 2 * attrib->bgHMargin; height += 2 * attrib->bgVMargin; } width = MIN (attrib->maxWidth, width); height = MIN (attrib->maxHeight, height); /* update the size of the pango layout */ layoutWidth = attrib->maxWidth; if (attrib->flags & CompTextFlagWithBackground) layoutWidth -= 2 * attrib->bgHMargin; pango_layout_set_width (data->layout, layoutWidth * PANGO_SCALE); if (!textUpdateSurface (s, data, width, height)) return FALSE; pango_cairo_update_layout (data->cr, data->layout); cairo_save (data->cr); cairo_set_operator (data->cr, CAIRO_OPERATOR_CLEAR); cairo_paint (data->cr); cairo_restore (data->cr); cairo_set_operator (data->cr, CAIRO_OPERATOR_OVER); if (attrib->flags & CompTextFlagWithBackground) { textDrawTextBackground (data->cr, 0, 0, width, height, MIN (attrib->bgHMargin, attrib->bgVMargin)); cairo_set_source_rgba (data->cr, attrib->bgColor[0] / 65535.0, attrib->bgColor[1] / 65535.0, attrib->bgColor[2] / 65535.0, attrib->bgColor[3] / 65535.0); cairo_fill (data->cr); cairo_move_to (data->cr, attrib->bgHMargin, attrib->bgVMargin); } cairo_set_source_rgba (data->cr, attrib->color[0] / 65535.0, attrib->color[1] / 65535.0, attrib->color[2] / 65535.0, attrib->color[3] / 65535.0); pango_cairo_show_layout (data->cr, data->layout); return TRUE; }
static void draw_dvdag_node_1(cairo_t *cr, dv_dag_node_t *node) { // Count node drawn S->nd++; // Node color double x = node->vl->c; double y = node->c; double c[4]; int v = 0; switch (S->nc) { case 0: v = node->pi->info.worker; break; case 1: v = node->pi->info.cpu; break; case 2: v = node->pi->info.kind; break; default: v = node->pi->info.worker; } lookup_color(v, c, c+1, c+2, c+3); // Alpha double alpha = 1.0; // Draw path cairo_save(cr); cairo_new_path(cr); if (dv_is_union(node)) { double xx, yy, w, h; if (dv_is_expanding(node) || dv_is_shrinking(node)) { double margin = 1.0; if (dv_is_expanding(node)) { // Fading out alpha = get_alpha_fading_out(); margin = get_alpha_fading_in(); } else { // Fading in alpha = get_alpha_fading_in(); margin = get_alpha_fading_out(); } // Large-sized box margin *= DV_UNION_NODE_MARGIN; xx = x - node->lc * DV_HDIS - DV_RADIUS - margin; yy = y - DV_RADIUS - margin; dv_dag_node_t * hd = (dv_dag_node_t *) node->heads->top->item; h = hd->dc * DV_VDIS + 2 * (DV_RADIUS + margin); w = (node->lc + node->rc) * DV_HDIS + 2 * (DV_RADIUS + margin); } else { // Normal-sized box xx = x - DV_RADIUS; yy = y - DV_RADIUS; w = 2 * DV_RADIUS; h = 2 * DV_RADIUS; if (node->lv > S->a->new_sel) { // Fading out alpha = get_alpha_fading_out(); } else if (node->lv > S->sel) { // Fading in alpha = get_alpha_fading_in(); } } // Box cairo_move_to(cr, xx, yy); cairo_line_to(cr, xx + w, yy); cairo_line_to(cr, xx + w, yy + h); cairo_line_to(cr, xx, yy + h); cairo_close_path(cr); } else { // Normal-sized circle cairo_arc(cr, x, y, DV_RADIUS, 0.0, 2*M_PI); if (node->lv > S->a->new_sel) { // Fading out alpha = get_alpha_fading_out(); } else if (node->lv > S->sel) { // Fading in alpha = get_alpha_fading_in(); } } // Draw node cairo_set_source_rgba(cr, c[0], c[1], c[2], c[3] * alpha); cairo_fill_preserve(cr); cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, alpha); cairo_stroke(cr); cairo_restore(cr); }
static gboolean dt_iop_zonesystem_bar_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self) { dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; dt_iop_zonesystem_params_t *p = (dt_iop_zonesystem_params_t *)self->params; const int inset = DT_ZONESYSTEM_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* clear background */ cairo_set_source_rgb(cr, .15, .15, .15); cairo_paint(cr); /* translate and scale */ width -= 2 * inset; height -= 2 * inset; cairo_save(cr); cairo_translate(cr, inset, inset); cairo_scale(cr, width, height); /* render the bars */ float zonemap[MAX_ZONE_SYSTEM_SIZE] = { 0 }; _iop_zonesystem_calculate_zonemap(p, zonemap); float s = (1. / (p->size - 2)); cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); for(int i = 0; i < p->size - 1; i++) { /* draw the reference zone */ float z = s * i; cairo_rectangle(cr, (1. / (p->size - 1)) * i, 0, (1. / (p->size - 1)), DT_ZONESYSTEM_REFERENCE_SPLIT - DT_ZONESYSTEM_BAR_SPLIT_WIDTH); cairo_set_source_rgb(cr, z, z, z); cairo_fill(cr); /* draw zone mappings */ cairo_rectangle(cr, zonemap[i], DT_ZONESYSTEM_REFERENCE_SPLIT + DT_ZONESYSTEM_BAR_SPLIT_WIDTH, (zonemap[i + 1] - zonemap[i]), 1.0 - DT_ZONESYSTEM_REFERENCE_SPLIT); cairo_set_source_rgb(cr, z, z, z); cairo_fill(cr); } cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); cairo_restore(cr); /* render zonebar control lines */ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr, 1.); cairo_rectangle(cr, inset, inset, width, height); cairo_set_source_rgb(cr, .1, .1, .1); cairo_stroke(cr); cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); /* render control points handles */ cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); const float arrw = DT_PIXEL_APPLY_DPI(7.0f); for(int k = 1; k < p->size - 1; k++) { float nzw = zonemap[k + 1] - zonemap[k]; float pzw = zonemap[k] - zonemap[k - 1]; if((((g->mouse_x / width) > (zonemap[k] - (pzw / 2.0))) && ((g->mouse_x / width) < (zonemap[k] + (nzw / 2.0)))) || p->zone[k] != -1) { gboolean is_under_mouse = ((width * zonemap[k]) - arrw * .5f < g->mouse_x && (width * zonemap[k]) + arrw * .5f > g->mouse_x); cairo_move_to(cr, inset + (width * zonemap[k]), height + (2 * inset) - 1); cairo_rel_line_to(cr, -arrw * .5f, 0); cairo_rel_line_to(cr, arrw * .5f, -arrw); cairo_rel_line_to(cr, arrw * .5f, arrw); cairo_close_path(cr); if(is_under_mouse) cairo_fill(cr); else cairo_stroke(cr); } } /* push mem surface into widget */ cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }
void cairo_dock_render_overlays_to_context (CairoDataRenderer *pRenderer, int iNumValue, cairo_t *pCairoContext) { if (pRenderer->pEmblems != NULL) { CairoDataRendererEmblem *pEmblem; pEmblem = &pRenderer->pEmblems[iNumValue]; if (pEmblem->pSurface != NULL) { cairo_set_source_surface (pCairoContext, pEmblem->pSurface, (.5 + pEmblem->param.fX - pEmblem->param.fWidth/2) * pRenderer->iWidth, (.5 - pEmblem->param.fY - pEmblem->param.fHeight/2) * pRenderer->iHeight); cairo_paint_with_alpha (pCairoContext, pEmblem->param.fAlpha); } } if (pRenderer->pLabels != NULL) { CairoDataRendererText *pLabel; pLabel = &pRenderer->pLabels[iNumValue]; if (pLabel->pSurface != NULL) { double f = MIN (pLabel->param.fWidth * pRenderer->iWidth / pLabel->iTextWidth, pLabel->param.fHeight * pRenderer->iHeight / pLabel->iTextHeight); // on garde le ratio du texte. if (pLabel->iTextHeight * f > 7) // sinon illisible { cairo_save (pCairoContext); cairo_scale (pCairoContext, f, f); cairo_set_source_surface (pCairoContext, pLabel->pSurface, .5+floor ((.5 + pLabel->param.fX) * pRenderer->iWidth/f - pLabel->iTextWidth /2), .5+floor ((.5 - pLabel->param.fY) * pRenderer->iHeight/f - pLabel->iTextHeight /2)); cairo_paint_with_alpha (pCairoContext, pLabel->param.pColor[3]); cairo_restore (pCairoContext); } } } if (pRenderer->bWriteValues && pRenderer->bCanRenderValueAsText) { CairoDataRendererTextParam *pText; pText = &pRenderer->pValuesText[iNumValue]; if (pText->fWidth != 0 && pText->fHeight != 0) { cairo_data_renderer_format_value (pRenderer, iNumValue); cairo_save (pCairoContext); cairo_set_source_rgb (pCairoContext, pText->pColor[0], pText->pColor[1], pText->pColor[2]); PangoLayout *pLayout = pango_cairo_create_layout (pCairoContext); PangoFontDescription *fd = pango_font_description_from_string ("Monospace 12"); pango_layout_set_font_description (pLayout, fd); PangoRectangle log; pango_layout_set_text (pLayout, pRenderer->cFormatBuffer, -1); pango_layout_get_pixel_extents (pLayout, NULL, &log); double fZoom = MIN (pText->fWidth * pRenderer->iWidth / (log.width), pText->fHeight * pRenderer->iHeight / log.height); cairo_move_to (pCairoContext, floor ((.5 + pText->fX) * pRenderer->iWidth - log.width*fZoom/2), floor ((.5 - pText->fY) * pRenderer->iHeight - log.height*fZoom/2)); cairo_scale (pCairoContext, fZoom, fZoom); pango_cairo_show_layout (pCairoContext, pLayout); g_object_unref (pLayout); cairo_restore (pCairoContext); } } }
static void ppg_ruler_draw_arrow (PpgRuler *ruler) { PpgRulerPrivate *priv; GtkStyle *style; GdkColor base_light; GdkColor base_dark; GdkColor hl_light; GdkColor hl_dark; cairo_t *cr; gint half; gint line_width; gint center; gint middle; gdouble top; gdouble bottom; gdouble left; gdouble right; g_return_if_fail(PPG_IS_RULER(ruler)); priv = ruler->priv; style = gtk_widget_get_style(GTK_WIDGET(ruler)); cr = gdk_cairo_create(priv->arrow); cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle(cr, 0, 0, ARROW_SIZE, ARROW_SIZE); cairo_fill(cr); cairo_restore(cr); center = middle = half = ARROW_SIZE / 2; line_width = half / 6; base_light = style->light[GTK_STATE_SELECTED]; base_dark = style->dark[GTK_STATE_SELECTED]; hl_light = style->light[GTK_STATE_SELECTED]; hl_dark = style->mid[GTK_STATE_SELECTED]; top = middle - half + line_width + 0.5; bottom = middle + half - line_width + 0.5; left = center - half + line_width + 0.5; right = center +half - line_width - 0.5; cairo_set_line_width(cr, line_width); cairo_move_to(cr, left + line_width, top + line_width); cairo_line_to(cr, right + line_width, top + line_width); cairo_line_to(cr, right + line_width, middle + line_width); cairo_line_to(cr, center + line_width, bottom + line_width); cairo_line_to(cr, left + line_width, middle + line_width); cairo_line_to(cr, left + line_width, top + line_width); cairo_close_path(cr); cairo_set_source_rgba(cr, 0, 0, 0, 0.5); cairo_fill(cr); cairo_move_to(cr, left, top); cairo_line_to(cr, center, top); cairo_line_to(cr, center, bottom); cairo_line_to(cr, left, middle); cairo_line_to(cr, left, top); cairo_close_path(cr); gdk_cairo_set_source_color(cr, &base_light); cairo_fill(cr); cairo_move_to(cr, center, top); cairo_line_to(cr, right, top); cairo_line_to(cr, right, middle); cairo_line_to(cr, center, bottom); cairo_line_to(cr, center, top); cairo_close_path(cr); gdk_cairo_set_source_color(cr, &base_light); cairo_fill_preserve(cr); cairo_set_source_rgba(cr, base_dark.red / 65535.0, base_dark.green / 65535.0, base_dark.blue / 65535.0, 0.5); cairo_fill(cr); cairo_move_to(cr, left + line_width, top + line_width); cairo_line_to(cr, right - line_width, top + line_width); cairo_line_to(cr, right - line_width, middle); cairo_line_to(cr, center, bottom - line_width - 0.5); cairo_line_to(cr, left + line_width, middle); cairo_line_to(cr, left + line_width, top + line_width); cairo_close_path(cr); gdk_cairo_set_source_color(cr, &hl_light); cairo_stroke(cr); cairo_move_to(cr, left, top); cairo_line_to(cr, right, top); cairo_line_to(cr, right, middle); cairo_line_to(cr, center, bottom); cairo_line_to(cr, left, middle); cairo_line_to(cr, left, top); cairo_close_path(cr); gdk_cairo_set_source_color(cr, &base_dark); cairo_stroke(cr); cairo_destroy(cr); }
static gboolean _lib_histogram_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_histogram_t *d = (dt_lib_histogram_t *)self->data; dt_develop_t *dev = darktable.develop; float *hist = dev->histogram; float hist_max = dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR?dev->histogram_max:logf(1.0 + dev->histogram_max); const int inset = DT_HIST_INSET; int width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkWidget", GTK_TYPE_WIDGET); if(!style) style = gtk_rc_get_style(widget); cairo_set_source_rgb(cr, style->bg[0].red/65535.0, style->bg[0].green/65535.0, style->bg[0].blue/65535.0); cairo_paint(cr); cairo_translate(cr, 4*inset, inset); width -= 2*4*inset; height -= 2*inset; if(d->mode_x == 0) { d->color_w = 0.06*width; d->button_spacing = 0.01*width; d->button_h = 0.06*width; d->button_y = d->button_spacing; d->mode_w = d->color_w; d->mode_x = width - 3*(d->color_w+d->button_spacing) - (d->mode_w+d->button_spacing); d->red_x = width - 3*(d->color_w+d->button_spacing); d->green_x = width - 2*(d->color_w+d->button_spacing); d->blue_x = width - (d->color_w+d->button_spacing); } // TODO: probably this should move to the configure-event callback! That would be future proof if we ever (again) allow to resize the side panels. const gint stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); // this code assumes that the first expose comes before the first (preview) pipe is processed and that the size of the widget doesn't change! if(dev->histogram_waveform_width == 0) { dev->histogram_waveform = (uint32_t*)calloc(height * stride / 4, sizeof(uint32_t)); dev->histogram_waveform_stride = stride; dev->histogram_waveform_height = height; dev->histogram_waveform_width = width; // return TRUE; // there are enough expose events following ... } #if 1 // draw shadow around float alpha = 1.0f; cairo_set_line_width(cr, 0.2); for(int k=0; k<inset; k++) { cairo_rectangle(cr, -k, -k, width + 2*k, height + 2*k); cairo_set_source_rgba(cr, 0, 0, 0, alpha); alpha *= 0.5f; cairo_fill(cr); } cairo_set_line_width(cr, 1.0); #else cairo_set_line_width(cr, 1.0); cairo_set_source_rgb (cr, .1, .1, .1); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); #endif cairo_rectangle(cr, 0, 0, width, height); cairo_clip(cr); cairo_set_source_rgb (cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); if(d->highlight == 1) { cairo_set_source_rgb (cr, .5, .5, .5); cairo_rectangle(cr, 0, 0, .2*width, height); cairo_fill(cr); } else if(d->highlight == 2) { cairo_set_source_rgb (cr, .5, .5, .5); cairo_rectangle(cr, 0.2*width, 0, width, height); cairo_fill(cr); } // draw grid cairo_set_line_width(cr, .4); cairo_set_source_rgb (cr, .1, .1, .1); if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM) dt_draw_waveform_lines(cr, 0, 0, width, height); else dt_draw_grid(cr, 4, 0, 0, width, height); if(hist_max > 0) { cairo_save(cr); if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM) { // make the color channel selector work: uint8_t *buf = (uint8_t*)malloc(sizeof(uint8_t) * height * stride); uint8_t mask[3] = {d->blue, d->green, d->red}; memcpy(buf, dev->histogram_waveform, sizeof(uint8_t) * height * stride); for(int y = 0; y < height; y++) for(int x = 0; x < width; x++) for(int k = 0; k < 3; k++) { buf[y * stride + x * 4 + k] *= mask[k]; } cairo_surface_t *source = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32, width, height, stride); cairo_set_source_surface(cr, source, 0.0, 0.0); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); cairo_paint(cr); cairo_surface_destroy(source); free(buf); } else { // cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); cairo_translate(cr, 0, height); cairo_scale(cr, width/63.0, -(height-10)/hist_max); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); // cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_line_width(cr, 1.); if(d->red) { cairo_set_source_rgba(cr, 1., 0., 0., 0.2); dt_draw_histogram_8(cr, hist, 0, dev->histogram_type); } if(d->green) { cairo_set_source_rgba(cr, 0., 1., 0., 0.2); dt_draw_histogram_8(cr, hist, 1, dev->histogram_type); } if(d->blue) { cairo_set_source_rgba(cr, 0., 0., 1., 0.2); dt_draw_histogram_8(cr, hist, 2, dev->histogram_type); } cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); } cairo_restore(cr); } cairo_set_source_rgb(cr, .25, .25, .25); cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, .1*height); char exifline[50]; cairo_move_to (cr, .02*width, .98*height); dt_image_print_exif(&dev->image_storage, exifline, 50); cairo_save(cr); // cairo_show_text(cr, exifline); cairo_set_line_width(cr, 2.0); cairo_set_source_rgba(cr, 1, 1, 1, 0.3); cairo_text_path(cr, exifline); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, .25, .25, .25); cairo_fill(cr); cairo_restore(cr); // buttons to control the display of the histogram: linear/log, r, g, b if(d->highlight != 0) { _draw_mode_toggle(cr, d->mode_x, d->button_y, d->mode_w, d->button_h, dev->histogram_type); cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.4); _draw_color_toggle(cr, d->red_x, d->button_y, d->color_w, d->button_h, d->red); cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.4); _draw_color_toggle(cr, d->green_x, d->button_y, d->color_w, d->button_h, d->green); cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 0.4); _draw_color_toggle(cr, d->blue_x, d->button_y, d->color_w, d->button_h, d->blue); } cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static void ppg_ruler_draw_ruler (PpgRuler *ruler) { PpgRulerPrivate *priv; GtkAllocation alloc; PangoLayout *layout; cairo_t *cr; GtkStyle *style; GdkColor text_color; gint text_width; gint text_height; gdouble every = 1.0; gdouble n_seconds; gdouble v; gdouble p; gint x; gint xx; gint n; gint z = 0; g_return_if_fail(PPG_IS_RULER(ruler)); priv = ruler->priv; gtk_widget_get_allocation(GTK_WIDGET(ruler), &alloc); style = gtk_widget_get_style(GTK_WIDGET(ruler)); cr = gdk_cairo_create(priv->ruler); cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle(cr, 0, 0, alloc.width, alloc.height); cairo_fill(cr); cairo_restore(cr); text_color = style->text[GTK_STATE_NORMAL]; cairo_set_line_width(cr, 1.0); gdk_cairo_set_source_color(cr, &text_color); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, priv->font_desc); pango_layout_set_markup(layout, "00:00:00", -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); text_width += 5; n_seconds = priv->upper - priv->lower; if ((alloc.width / n_seconds) < text_width) { every = ceil(text_width / (alloc.width / n_seconds)); } for (v = ceil(priv->lower); v < priv->upper; v += every) { gdk_cairo_set_source_color(cr, &text_color); x = get_x_offset(priv, &alloc, v); cairo_move_to(cr, x + 0.5, alloc.height - 1.5); cairo_line_to(cr, x + 0.5, 0.5); /* * TODO: Mini lines. */ for (p = v, n = 0, z = 0; p < v + every; p += (every / 10), n++, z++) { if (n == 0 || n == 10) { continue; } xx = get_x_offset(priv, &alloc, p); cairo_move_to(cr, xx + 0.5, alloc.height - 1.5); if (z % 2 == 0) { cairo_line_to(cr, xx + 0.5, text_height + 8.5); } else { cairo_line_to(cr, xx + 0.5, text_height + 5.5); } } cairo_stroke(cr); cairo_move_to(cr, x + 1.5, 1.5); ppg_ruler_update_layout_text(ruler, layout, v); pango_cairo_show_layout(cr, layout); } g_object_unref(layout); cairo_destroy(cr); }
void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, CompositeOperator op) { if (!m_source.initialized()) return; cairo_surface_t* image = frameAtIndex(m_currentFrame); if (!image) // If it's too early we won't have an image yet. return; IntSize intrinsicImageSize = size(); FloatRect srcRect(srcPoint, intrinsicImageSize); FloatPoint point = srcPoint; // Check and see if a single draw of the image can cover the entire area we are supposed to tile. float tileWidth = size().width(); float tileHeight = size().height(); // If the scale is not equal to the intrinsic size of the image, set transform matrix // to the appropriate scalar matrix, scale the source point, and set the size of the // scaled tile. float scaleX = 1.0; float scaleY = 1.0; cairo_matrix_t mat; cairo_matrix_init_identity(&mat); if (tileSize.width() != intrinsicImageSize.width() || tileSize.height() != intrinsicImageSize.height()) { scaleX = intrinsicImageSize.width() / tileSize.width(); scaleY = intrinsicImageSize.height() / tileSize.height(); cairo_matrix_init_scale(&mat, scaleX, scaleY); tileWidth = tileSize.width(); tileHeight = tileSize.height(); } // We could get interesting source offsets (negative ones or positive ones. Deal with both // out of bounds cases. float dstTileX = dstRect.x() + fmodf(fmodf(-point.x(), tileWidth) - tileWidth, tileWidth); float dstTileY = dstRect.y() + fmodf(fmodf(-point.y(), tileHeight) - tileHeight, tileHeight); FloatRect dstTileRect(dstTileX, dstTileY, tileWidth, tileHeight); float srcX = dstRect.x() - dstTileRect.x(); float srcY = dstRect.y() - dstTileRect.y(); // If the single image draw covers the whole area, then just draw once. if (dstTileRect.contains(dstRect)) { draw(ctxt, dstRect, FloatRect(srcX * scaleX, srcY * scaleY, dstRect.width() * scaleX, dstRect.height() * scaleY), op); return; } // We have to tile. cairo_t* context = ctxt->platformContext(); cairo_save(context); // Set the compositing operation. setCompositingOperation(context, op, frameHasAlphaAtIndex(m_currentFrame)); cairo_translate(context, dstTileRect.x(), dstTileRect.y()); cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image); cairo_pattern_set_matrix(pattern, &mat); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); // Draw the image. cairo_set_source(context, pattern); cairo_rectangle(context, srcX, srcY, dstRect.width(), dstRect.height()); cairo_fill(context); cairo_restore(context); startAnimation(); }
bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dstHeight, wxDC* source, int xsrc, int ysrc, int srcWidth, int srcHeight, wxRasterOperationMode rop, bool useMask, int xsrcMask, int ysrcMask) { wxCHECK_MSG(IsOk(), false, "invalid DC"); wxCHECK_MSG(source && source->IsOk(), false, "invalid source DC"); cairo_t* cr = NULL; if (m_graphicContext) cr = static_cast<cairo_t*>(m_graphicContext->GetNativeContext()); cairo_t* cr_src = NULL; wxGraphicsContext* gc_src = source->GetGraphicsContext(); if (gc_src) cr_src = static_cast<cairo_t*>(gc_src->GetNativeContext()); if (cr == NULL || cr_src == NULL) return false; const int xsrc_dev = source->LogicalToDeviceX(xsrc); const int ysrc_dev = source->LogicalToDeviceY(ysrc); cairo_surface_t* surface = cairo_get_target(cr_src); cairo_surface_flush(surface); cairo_save(cr); cairo_translate(cr, xdest, ydest); cairo_rectangle(cr, 0, 0, dstWidth, dstHeight); double sx, sy; source->GetUserScale(&sx, &sy); cairo_scale(cr, dstWidth / (sx * srcWidth), dstHeight / (sy * srcHeight)); cairo_set_source_surface(cr, surface, -xsrc_dev, -ysrc_dev); const wxRasterOperationMode rop_save = m_logicalFunction; SetLogicalFunction(rop); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_surface_t* maskSurf = NULL; if (useMask) { const wxBitmap& bitmap = source->GetImpl()->GetSelectedBitmap(); if (bitmap.IsOk()) { wxMask* mask = bitmap.GetMask(); if (mask) maskSurf = mask->GetBitmap(); } } if (maskSurf) { int xsrcMask_dev = xsrc_dev; int ysrcMask_dev = ysrc_dev; if (xsrcMask != -1) xsrcMask_dev = source->LogicalToDeviceX(xsrcMask); if (ysrcMask != -1) ysrcMask_dev = source->LogicalToDeviceY(ysrcMask); cairo_clip(cr); cairo_mask_surface(cr, maskSurf, -xsrcMask_dev, -ysrcMask_dev); } else { cairo_fill(cr); } cairo_restore(cr); m_logicalFunction = rop_save; return true; }
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* cr = context->platformContext(); cairo_save(cr); cairo_set_scaled_font(cr, font->platformData().scaledFont()); GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from); float offset = 0.0f; for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = 0.0f; offset += glyphBuffer.advanceAt(from + i); } Color fillColor = context->fillColor(); // Synthetic Oblique if(font->platformData().syntheticOblique()) { cairo_matrix_t mat = {1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, point.x(), point.y()}; cairo_transform(cr, &mat); } else { cairo_translate(cr, point.x(), point.y()); } // Text shadow, inspired by FontMac IntSize shadowSize; int shadowBlur = 0; Color shadowColor; bool hasShadow = context->textDrawingMode() == cTextFill && context->getShadow(shadowSize, shadowBlur, shadowColor); // TODO: Blur support if (hasShadow) { // Disable graphics context shadows (not yet implemented) and paint them manually context->clearShadow(); Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); cairo_save(cr); float red, green, blue, alpha; shadowFillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); #if ENABLE(FILTERS) cairo_text_extents_t extents; cairo_scaled_font_glyph_extents(font->platformData().scaledFont(), glyphs, numGlyphs, &extents); FloatRect rect(FloatPoint(), FloatSize(extents.width, extents.height)); IntSize shadowBufferSize; FloatRect shadowRect; float kernelSize = 0.f; GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, shadowBlur); // Draw shadow into a new ImageBuffer OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); GraphicsContext* shadowContext = shadowBuffer->context(); cairo_t* shadowCr = shadowContext->platformContext(); cairo_translate(shadowCr, kernelSize, extents.height + kernelSize); cairo_set_scaled_font(shadowCr, font->platformData().scaledFont()); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(shadowCr); cairo_translate(shadowCr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); cairo_restore(shadowCr); } cairo_translate(cr, 0.0, -extents.height); context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize); #else cairo_translate(cr, shadowSize.width(), shadowSize.height()); cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } #endif cairo_restore(cr); } if (context->textDrawingMode() & cTextFill) { if (context->fillGradient()) { cairo_set_source(cr, context->fillGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->fillPattern()) { AffineTransform affine; cairo_set_source(cr, context->fillPattern()->createPlatformPattern(affine)); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else { float red, green, blue, alpha; fillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } } if (context->textDrawingMode() & cTextStroke) { if (context->strokeGradient()) { cairo_set_source(cr, context->strokeGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->strokePattern()) { AffineTransform affine; cairo_set_source(cr, context->strokePattern()->createPlatformPattern(affine)); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else { Color strokeColor = context->strokeColor(); float red, green, blue, alpha; strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_glyph_path(cr, glyphs, numGlyphs); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Re-enable the platform shadow we disabled earlier if (hasShadow) context->setShadow(shadowSize, shadowBlur, shadowColor, DeviceColorSpace); cairo_restore(cr); }
static void e_table_group_container_print_page (EPrintable *ep, GtkPrintContext *context, gdouble width, gdouble height, gboolean quantize, ETGCPrintContext *groupcontext) { cairo_t *cr; gdouble yd = height; gdouble child_height; ETableGroupContainerChildNode *child_node; GList *child; EPrintable *child_printable; gchar *string; PangoLayout *layout; PangoFontDescription *desc; child_printable = groupcontext->child_printable; child = groupcontext->child; yd = 6.5 * 72; height = 5 * 72; if (child_printable) { if (child) child_node = child->data; else child_node = NULL; g_object_ref (child_printable); } else { if (!child) { return; } else { child_node = child->data; child_printable = e_table_group_get_printable(child_node->child); if (child_printable) g_object_ref (child_printable); e_printable_reset(child_printable); } } layout = gtk_print_context_create_pango_layout (context); desc = pango_font_description_new (); pango_font_description_set_family_static (desc, "Helvetica"); pango_font_description_set_size (desc, TEXT_HEIGHT); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); while (1) { child_height = e_printable_height(child_printable, context, width,yd + 2 * TEXT_AREA_HEIGHT, quantize); cr = gtk_print_context_get_cairo_context (context); cairo_save (cr); cairo_rectangle (cr, 0, 0, width,TEXT_AREA_HEIGHT); cairo_rectangle (cr, 0, 0, 2 * TEXT_AREA_HEIGHT, child_height + TEXT_AREA_HEIGHT); cairo_set_source_rgb (cr, .7, .7, .7) ; cairo_fill(cr) ; cairo_restore (cr); cairo_save (cr); cairo_rectangle (cr, 0, 0, width, TEXT_AREA_HEIGHT); cairo_clip (cr); cairo_restore (cr); cairo_move_to(cr, 0, 0); if (groupcontext->etgc->ecol->text) string = g_strdup_printf ("%s : %s (%d item%s)", groupcontext->etgc->ecol->text, child_node->string, (gint) child_node->count, child_node->count == 1 ? "" : "s"); else string = g_strdup_printf ("%s (%d item%s)", child_node->string, (gint) child_node->count, child_node->count == 1 ? "" : "s"); pango_layout_set_text (layout, string, -1); pango_cairo_show_layout (cr, layout); g_free(string); cairo_translate(cr, 2 * TEXT_AREA_HEIGHT, TEXT_AREA_HEIGHT) ; cairo_move_to(cr, 0, 0); cairo_rectangle (cr, 0, 0, width - 2 * TEXT_AREA_HEIGHT,child_height); cairo_clip(cr); e_printable_print_page (child_printable, context, width-2 * TEXT_AREA_HEIGHT, 0, quantize); yd += child_height + TEXT_AREA_HEIGHT; if (e_printable_data_left(child_printable)) break; child = child->next; if (!child) { child_printable = NULL; break; } child_node = child->data; if (child_printable) g_object_unref (child_printable); child_printable = e_table_group_get_printable(child_node->child); if (child_printable) g_object_ref (child_printable); e_printable_reset(child_printable); } if (groupcontext->child_printable) g_object_unref (groupcontext->child_printable); groupcontext->child_printable = child_printable; groupcontext->child = child; g_object_unref (layout); }
void HippoCanvas::onPaint(WPARAM wParam, LPARAM lParam) { RECT region; if (GetUpdateRect(window_, ®ion, true)) { int regionWidth = region.right - region.left; int regionHeight = region.bottom - region.top; #if 0 g_debug("SIZING: %p paint region %d,%d %dx%d", window_, region.left, region.top, regionWidth, regionHeight); #endif // go ahead and request/resize if necessary, so we paint the right thing ensureRequestAndAllocation(); PAINTSTRUCT paint; HDC hdc = BeginPaint(window_, &paint); //g_debug("paint.fErase=%d", paint.fErase); cairo_surface_t *surface = cairo_win32_surface_create(hdc); cairo_surface_t *buffer = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR, regionWidth, regionHeight); cairo_t *cr = cairo_create(buffer); hippo_canvas_context_win_update_pango(context_, cr); // make the buffer's coordinates look like the real coordinates cairo_translate(cr, - region.left, - region.top); // Paint a background rectangle to the buffer cairo_rectangle(cr, region.left, region.top, regionWidth, regionHeight); cairo_clip(cr); // FIXME not the right background color (on linux it's the default gtk background) // should use system color, maybe GetThemeSysColorBrush is right. Note that // this rectangle draws the little corner between the scrollbars in // addition to the viewport background. hippo_cairo_set_source_rgba32(cr, 0xffffffff); cairo_paint(cr); // Draw canvas item to the buffer if (root_ != (HippoCanvasItem*) NULL) { RECT viewport; HippoRectangle viewport_hippo; HippoRectangle region_hippo; getViewport(&viewport); hippo_rectangle_from_rect(&viewport_hippo, &viewport); hippo_rectangle_from_rect(®ion_hippo, ®ion); if (hippo_rectangle_intersect(&viewport_hippo, ®ion_hippo, ®ion_hippo)) { // we have to clip so we don't draw outside the viewport - the canvas // doesn't have its own window cairo_save(cr); cairo_rectangle(cr, region_hippo.x, region_hippo.y, region_hippo.width, region_hippo.height); cairo_clip(cr); int x, y; getCanvasOrigin(&x, &y); hippo_canvas_item_process_paint(root_, cr, ®ion_hippo, x, y); cairo_restore(cr); } } // pop the update region clip and the translation off the buffer cairo_destroy(cr); // Copy the buffer to the window cairo_t *window_cr = cairo_create(surface); cairo_rectangle(window_cr, region.left, region.top, regionWidth, regionHeight); cairo_clip(window_cr); cairo_set_source_surface(window_cr, buffer, region.left, region.top); cairo_paint(window_cr); cairo_destroy(window_cr); cairo_surface_destroy(buffer); cairo_surface_destroy(surface); EndPaint(window_, &paint); } }
static void _paint_lyrics (OlScrollWindow *scroll, cairo_t *cr) { ol_assert (OL_IS_SCROLL_WINDOW (scroll)); GtkWidget *widget = GTK_WIDGET (scroll); ol_assert (GTK_WIDGET_REALIZED (widget)); OlScrollWindowPrivate *priv = OL_SCROLL_WINDOW_GET_PRIVATE (scroll); int line_height = ol_scroll_window_get_font_height (scroll) + priv->line_margin; int count = ol_scroll_window_compute_line_count (scroll); gint width, height; gdk_drawable_get_size (gtk_widget_get_window (GTK_WIDGET (scroll)), &width, &height); /* set the font */ PangoLayout *layout = _get_pango (scroll, cr); /* paint the lyrics*/ cairo_save (cr); cairo_new_path (cr); cairo_rectangle (cr, priv->padding_x, 0, width - priv->padding_x * 2, height - priv->padding_y * 2); cairo_close_path (cr); cairo_clip (cr); int i; gint current_lyric_id; gint lrc_y; _calc_paint_pos (scroll, ¤t_lyric_id, &lrc_y); int begin = current_lyric_id - count / 2; int end = current_lyric_id + count / 2 + 1; int ypos = height / 2 - lrc_y - (count / 2 + 1) * line_height; cairo_set_source_rgb(cr, priv->inactive_color.r, priv->inactive_color.g, priv->inactive_color.b); if (scroll->whole_lyrics != NULL) { for (i = begin; i < end; i++) { ypos += line_height; if (i < 0) continue; if (i >= scroll->whole_lyrics->len) break; pango_layout_set_text (layout, g_ptr_array_index (scroll->whole_lyrics, i), -1); cairo_save (cr); double ratio = _get_active_color_ratio (scroll, i); double alpha = 1.0; if (ypos < line_height / 2.0 + priv->padding_y) alpha = 1.0 - (line_height / 2.0 + priv->padding_y - ypos) * 1.0 / line_height * 2; else if (ypos > height - line_height * 1.5 - priv->padding_y) alpha = (height - line_height - priv->padding_y - ypos) * 1.0 / line_height * 2; if (alpha < 0.0) alpha = 0.0; cairo_set_source_rgba (cr, priv->active_color.r * ratio + priv->inactive_color.r * (1 - ratio), priv->active_color.g * ratio + priv->inactive_color.g * (1 - ratio), priv->active_color.b * ratio + priv->inactive_color.b * (1 - ratio), alpha); cairo_move_to (cr, priv->padding_x, ypos); pango_cairo_update_layout (cr, layout); pango_cairo_show_layout (cr, layout); cairo_restore (cr); } } g_object_unref (layout); cairo_reset_clip (cr); cairo_restore (cr); }
void CanvasRenderingContext2D::stroke() { GraphicsContext* c = drawingContext(); if (!c) return; // FIXME: Do this through platform-independent GraphicsContext API. #if PLATFORM(CG) CGContextBeginPath(c->platformContext()); CGContextAddPath(c->platformContext(), state().m_path.platformPath()); if (!state().m_path.isEmpty()) { float lineWidth = state().m_lineWidth; float inset = -lineWidth / 2; CGRect boundingRect = CGRectInset(CGContextGetPathBoundingBox(c->platformContext()), inset, inset); willDraw(boundingRect); } if (state().m_strokeStyle->gradient()) { // Shading works on the entire clip region, so convert the current path to a clip. c->save(); CGContextReplacePathWithStrokedPath(c->platformContext()); CGContextClip(c->platformContext()); CGContextDrawShading(c->platformContext(), state().m_strokeStyle->gradient()->platformShading()); c->restore(); } else { if (state().m_strokeStyle->pattern()) applyStrokePattern(); CGContextStrokePath(c->platformContext()); } #elif PLATFORM(QT) QPainterPath* path = state().m_path.platformPath(); QPainter* p = static_cast<QPainter*>(c->platformContext()); willDraw(path->controlPointRect()); if (state().m_strokeStyle->gradient()) { p->save(); p->setBrush(*(state().m_strokeStyle->gradient()->platformShading())); p->strokePath(*path, p->pen()); p->restore(); } else { if (state().m_strokeStyle->pattern()) applyStrokePattern(); p->strokePath(*path, p->pen()); } #elif PLATFORM(CAIRO) cairo_t* pathCr = state().m_path.platformPath()->m_cr; cairo_t* cr = c->platformContext(); cairo_save(cr); // FIXME: consider inset, as in CG willDraw(state().m_path.boundingRect()); if (state().m_strokeStyle->gradient()) { cairo_set_source(cr, state().m_strokeStyle->gradient()->platformShading()); c->addPath(state().m_path); cairo_stroke(cr); } else { if (state().m_strokeStyle->pattern()) applyStrokePattern(); c->addPath(state().m_path); cairo_stroke(cr); } cairo_restore(cr); #endif clearPathForDashboardBackwardCompatibilityMode(); }
static void draw_expander (ECellTreeView *ectv, cairo_t *cr, GtkExpanderStyle expander_style, GtkStateType state, GdkRectangle *rect) { GtkStyleContext *style_context; GtkWidget *tree; GtkStateFlags flags = 0; gint exp_size; tree = gtk_widget_get_parent (GTK_WIDGET (ectv->canvas)); style_context = gtk_widget_get_style_context (tree); gtk_style_context_save (style_context); gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_EXPANDER); switch (state) { case GTK_STATE_PRELIGHT: flags |= GTK_STATE_FLAG_PRELIGHT; break; case GTK_STATE_SELECTED: flags |= GTK_STATE_FLAG_SELECTED; break; case GTK_STATE_INSENSITIVE: flags |= GTK_STATE_FLAG_INSENSITIVE; break; default: break; } /* XXX GTK 3.13.7 broke backward-compat on which state flag controls * how an expander is drawn. * * Older versions used GTK_STATE_FLAG_ACTIVE, 3.13.7 and later * changed it to GTK_STATE_FLAG_CHECKED. * * See https://bugzilla.gnome.org/733967 for details. */ if (expander_style == GTK_EXPANDER_EXPANDED) { #if GTK_CHECK_VERSION(3,13,7) flags |= GTK_STATE_FLAG_CHECKED; #else flags |= GTK_STATE_FLAG_ACTIVE; #endif } gtk_style_context_set_state (style_context, flags); gtk_widget_style_get (tree, "expander_size", &exp_size, NULL); cairo_save (cr); gtk_render_expander ( style_context, cr, (gdouble) rect->x + rect->width - exp_size, (gdouble) (rect->y + rect->height / 2) - (exp_size / 2), (gdouble) exp_size, (gdouble) exp_size); cairo_restore (cr); gtk_style_context_restore (style_context); }
void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode& ec) { ASSERT(canvas); ec = 0; FloatRect srcCanvasRect = FloatRect(FloatPoint(), canvas->size()); if (!(srcCanvasRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0 && dstRect.width() >= 0 && dstRect.height() >= 0)) { ec = INDEX_SIZE_ERR; return; } if (srcRect.isEmpty() || dstRect.isEmpty()) return; GraphicsContext* c = drawingContext(); if (!c) return; FloatRect sourceRect = c->roundToDevicePixels(srcRect); FloatRect destRect = c->roundToDevicePixels(dstRect); // FIXME: Do this through platform-independent GraphicsContext API. #if PLATFORM(CG) CGImageRef platformImage = canvas->createPlatformImage(); if (!platformImage) return; willDraw(destRect); float iw = CGImageGetWidth(platformImage); float ih = CGImageGetHeight(platformImage); if (sourceRect.x() == 0 && sourceRect.y() == 0 && iw == sourceRect.width() && ih == sourceRect.height()) { // Fast path, yay! CGContextDrawImage(c->platformContext(), destRect, platformImage); } else { // Slow path, boo! // Create a new bitmap of the appropriate size and then draw that into our context. size_t csw = static_cast<size_t>(ceilf(sourceRect.width())); size_t csh = static_cast<size_t>(ceilf(sourceRect.height())); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); size_t bytesPerRow = csw * 4; void* buffer = fastMalloc(csh * bytesPerRow); CGContextRef clippedSourceContext = CGBitmapContextCreate(buffer, csw, csh, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); CGContextTranslateCTM(clippedSourceContext, -sourceRect.x(), -sourceRect.y()); CGContextDrawImage(clippedSourceContext, CGRectMake(0, 0, iw, ih), platformImage); CGImageRef clippedSourceImage = CGBitmapContextCreateImage(clippedSourceContext); CGContextRelease(clippedSourceContext); CGContextDrawImage(c->platformContext(), destRect, clippedSourceImage); CGImageRelease(clippedSourceImage); fastFree(buffer); } CGImageRelease(platformImage); #elif PLATFORM(QT) QImage px = canvas->createPlatformImage(); if (px.isNull()) return; willDraw(dstRect); QPainter* painter = static_cast<QPainter*>(c->platformContext()); painter->drawImage(dstRect, px, srcRect); #elif PLATFORM(CAIRO) cairo_surface_t* image = canvas->createPlatformImage(); willDraw(dstRect); cairo_t* cr = c->platformContext(); cairo_save(cr); cairo_set_source_surface(cr, image, srcRect.x(), srcRect.y()); cairo_rectangle(cr, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height()); cairo_fill(cr); cairo_restore(cr); #endif }
void FirstInteractiveCompound:: draw(cairo_t * cr, double weight, double pixelsize) const { cairo_save(cr); // handles for (size_t ii(0); ii < handles_.size(); ++ii) { handles_[ii]->draw(cr, weight, pixelsize); } cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.5); cairo_set_line_width(cr, weight * 1.0 / pixelsize); cairo_move_to(cr, h_ee_.point_[0], h_ee_.point_[1]); cairo_line_to(cr, h_ee_ori_.point_[0], h_ee_ori_.point_[1]); cairo_stroke(cr); // orientation objective cairo_set_source_rgba(cr, 0.0, 1.0, 0.5, 0.3); cairo_set_line_width(cr, weight * 6.0 / pixelsize); static double const len(0.5); double const dx(len * cos(orient_ee_.goal_)); double const dy(len * sin(orient_ee_.goal_)); cairo_move_to(cr, robot_.pos_b_[0], robot_.pos_b_[1]); cairo_line_to(cr, robot_.pos_b_[0] + dx, robot_.pos_b_[1] + dy); cairo_stroke(cr); // joint limits if (joint_limits_.isActive()) { cairo_set_source_rgba(cr, 1.0, 0.2, 0.8, 0.8); cairo_set_line_width(cr, weight * 1.0 / pixelsize); for (ssize_t ii(0); ii < joint_limits_.getJacobian().rows(); ++ii) { if (0.0 < joint_limits_.getJacobian()(ii, 3)) { cairo_move_to(cr, robot_.pos_a_[0], robot_.pos_a_[1]); cairo_arc(cr, robot_.pos_a_[0], robot_.pos_a_[1], 0.1, normangle(normangle(robot_.position_[2]) + joint_limits_.limits_(3, 0)), normangle(normangle(robot_.position_[2]) + joint_limits_.limits_(3, 3))); cairo_line_to(cr, robot_.pos_a_[0], robot_.pos_a_[1]); cairo_fill(cr); } if (0.0 < joint_limits_.getJacobian()(ii, 4)) { cairo_move_to(cr, robot_.pos_b_[0], robot_.pos_b_[1]); cairo_arc(cr, robot_.pos_b_[0], robot_.pos_b_[1], 0.1, normangle(normangle(robot_.q23_) + joint_limits_.limits_(4, 0)), normangle(normangle(robot_.q23_) + joint_limits_.limits_(4, 3))); cairo_line_to(cr, robot_.pos_b_[0], robot_.pos_b_[1]); cairo_fill(cr); } } } // avoidance points cairo_set_source_rgb(cr, 1.0, 0.4, 1.0); cairo_set_line_width(cr, weight * 5.0 / pixelsize); if (avoid_base_.isActive()) { cairo_move_to(cr, avoid_base_.gpoint_[0], avoid_base_.gpoint_[1]); cairo_line_to(cr, avoid_base_.gpoint_[0], avoid_base_.gpoint_[1]); cairo_stroke(cr); } if (avoid_ellbow_.isActive()) { cairo_move_to(cr, avoid_ellbow_.gpoint_[0], avoid_ellbow_.gpoint_[1]); cairo_line_to(cr, avoid_ellbow_.gpoint_[0], avoid_ellbow_.gpoint_[1]); cairo_stroke(cr); } if (avoid_wrist_.isActive()) { cairo_move_to(cr, avoid_wrist_.gpoint_[0], avoid_wrist_.gpoint_[1]); cairo_line_to(cr, avoid_wrist_.gpoint_[0], avoid_wrist_.gpoint_[1]); cairo_stroke(cr); } if (avoid_ee_.isActive()) { cairo_move_to(cr, avoid_ee_.gpoint_[0], avoid_ee_.gpoint_[1]); cairo_line_to(cr, avoid_ee_.gpoint_[0], avoid_ee_.gpoint_[1]); cairo_stroke(cr); } // repulsion vectors cairo_set_source_rgb(cr, 0.4, 0.4, 1.0); cairo_set_line_width(cr, weight * 1.0 / pixelsize); if (repulse_base_.isActive()) { cairo_move_to(cr, repulse_base_.gpoint_[0], repulse_base_.gpoint_[1]); cairo_line_to(cr, repulse_base_.gpoint_[0] + repulse_base_.getBias()[0], repulse_base_.gpoint_[1] + repulse_base_.getBias()[1]); cairo_stroke(cr); } if (repulse_ellbow_.isActive()) { cairo_move_to(cr, repulse_ellbow_.gpoint_[0], repulse_ellbow_.gpoint_[1]); cairo_line_to(cr, repulse_ellbow_.gpoint_[0] + repulse_ellbow_.getBias()[0], repulse_ellbow_.gpoint_[1] + repulse_ellbow_.getBias()[1]); cairo_stroke(cr); } if (repulse_wrist_.isActive()) { cairo_move_to(cr, repulse_wrist_.gpoint_[0], repulse_wrist_.gpoint_[1]); cairo_line_to(cr, repulse_wrist_.gpoint_[0] + repulse_wrist_.getBias()[0], repulse_wrist_.gpoint_[1] + repulse_wrist_.getBias()[1]); cairo_stroke(cr); } if (repulse_ee_.isActive()) { cairo_move_to(cr, repulse_ee_.gpoint_[0], repulse_ee_.gpoint_[1]); cairo_line_to(cr, repulse_ee_.gpoint_[0] + repulse_ee_.getBias()[0], repulse_ee_.gpoint_[1] + repulse_ee_.getBias()[1]); cairo_stroke(cr); } cairo_restore(cr); }
// ------------------------------------------------------------------- // - Drawing services - // ------------------------------------------------------------------- bool CairoDevice::BeginDraw() { cairo_save (fNativeDevice); return true; }
static void on_screenshot_finished (GObject *source, GAsyncResult *res, gpointer user_data) { CcBackgroundPanel *panel = user_data; CcBackgroundPanelPrivate *priv = panel->priv; GError *error; GdkRectangle rect; GtkWidget *widget; GdkPixbuf *pixbuf; cairo_surface_t *surface; cairo_t *cr; int width; int height; error = NULL; g_dbus_connection_call_finish (panel->priv->connection, res, &error); if (error != NULL) { g_debug ("Unable to get screenshot: %s", error->message); g_error_free (error); /* fallback? */ goto out; } pixbuf = gdk_pixbuf_new_from_file (panel->priv->screenshot_path, &error); if (error != NULL) { g_debug ("Unable to use GNOME Shell's builtin screenshot interface: %s", error->message); g_error_free (error); goto out; } width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_paint (cr); g_object_unref (pixbuf); /* clear the workarea */ widget = WID ("background-desktop-drawingarea"); gdk_screen_get_monitor_workarea (gtk_widget_get_screen (widget), 0, &rect); cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height); cairo_fill (cr); cairo_restore (cr); g_clear_object (&panel->priv->display_screenshot); panel->priv->display_screenshot = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height); /* remove the temporary file created by the shell */ g_unlink (panel->priv->screenshot_path); g_free (priv->screenshot_path); priv->screenshot_path = NULL; cairo_destroy (cr); cairo_surface_destroy (surface); out: update_display_preview (panel); }
static void draw_image(DiaRenderer *self, Point *point, real width, real height, DiaImage *image) { DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self); cairo_surface_t *surface; guint8 *data; int w = dia_image_width(image); int h = dia_image_height(image); int rs = dia_image_rowstride(image); DIAG_NOTE(g_message("draw_image %fx%f [%d(%d),%d] @%f,%f", width, height, w, rs, h, point->x, point->y)); if (dia_image_rgba_data (image)) { const guint8 *p1 = dia_image_rgba_data (image); /* we need to make a copy to rearrange channels * (also need to use malloc, cause Cairo insists to free() it) */ guint8 *p2 = data = g_malloc (h * rs); int i; for (i = 0; i < (h * rs) / 4; i++) { # if G_BYTE_ORDER == G_LITTLE_ENDIAN p2[0] = p1[2]; /* b */ p2[1] = p1[1]; /* g */ p2[2] = p1[0]; /* r */ p2[3] = p1[3]; /* a */ # else p2[3] = p1[2]; /* b */ p2[2] = p1[1]; /* g */ p2[1] = p1[0]; /* r */ p2[0] = p1[3]; /* a */ # endif p1+=4; p2+=4; } surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, w, h, rs); } else { guint8 *p, *p2; guint8 *p1 = data = dia_image_rgb_data (image); /* need to copy to be owned by cairo/pixman, urgh. * Also cairo wants RGB24 32 bit aligned */ int x, y; p = p2 = g_malloc(h*w*4); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN /* apparently BGR is required */ p2[x*4 ] = p1[x*3+2]; p2[x*4+1] = p1[x*3+1]; p2[x*4+2] = p1[x*3 ]; p2[x*4+3] = 0x80; /* should not matter */ #else p2[x*4+3] = p1[x*3+2]; p2[x*4+2] = p1[x*3+1]; p2[x*4+1] = p1[x*3 ]; p2[x*4+0] = 0x80; /* should not matter */ #endif } p2 += (w*4); p1 += rs; } surface = cairo_image_surface_create_for_data (p, CAIRO_FORMAT_RGB24, w, h, w*4); g_free (data); data = p; } cairo_save (renderer->cr); cairo_translate (renderer->cr, point->x, point->y); cairo_scale (renderer->cr, width/w, height/h); cairo_move_to (renderer->cr, 0.0, 0.0); /* maybe just the second set_filter is required */ #if 0 cairo_surface_set_filter (renderer->surface, CAIRO_FILTER_BEST); cairo_surface_set_filter (surface, CAIRO_FILTER_BEST); #endif cairo_set_source_surface (renderer->cr, surface, 0.0, 0.0); cairo_paint (renderer->cr); cairo_restore (renderer->cr); cairo_surface_destroy (surface); g_free (data); DIAG_STATE(renderer->cr); }