static gboolean dt_iop_zonesystem_bar_expose (GtkWidget *widget, GdkEventExpose *event, 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 = 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_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; }
/** * Sends the given character to the terminal at the given row and column, * rendering the character immediately. This bypasses the guac_terminal_display * mechanism and is intended for flushing of updates only. */ int __guac_terminal_set(guac_terminal_display* display, int row, int col, int codepoint) { int width; int bytes; char utf8[4]; /* Use foreground color */ const guac_terminal_color* color = &display->glyph_foreground; /* Use background color */ const guac_terminal_color* background = &display->glyph_background; cairo_surface_t* surface; cairo_t* cairo; int surface_width, surface_height; PangoLayout* layout; int layout_width, layout_height; int ideal_layout_width, ideal_layout_height; /* Calculate width in columns */ width = wcwidth(codepoint); if (width < 0) width = 1; /* Do nothing if glyph is empty */ if (width == 0) return 0; /* Convert to UTF-8 */ bytes = guac_terminal_encode_utf8(codepoint, utf8); surface_width = width * display->char_width; surface_height = display->char_height; ideal_layout_width = surface_width * PANGO_SCALE; ideal_layout_height = surface_height * PANGO_SCALE; /* Prepare surface */ surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, surface_width, surface_height); cairo = cairo_create(surface); /* Fill background */ cairo_set_source_rgb(cairo, background->red / 255.0, background->green / 255.0, background->blue / 255.0); cairo_rectangle(cairo, 0, 0, surface_width, surface_height); cairo_fill(cairo); /* Get layout */ layout = pango_cairo_create_layout(cairo); pango_layout_set_font_description(layout, display->font_desc); pango_layout_set_text(layout, utf8, bytes); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); pango_layout_get_size(layout, &layout_width, &layout_height); /* If layout bigger than available space, scale it back */ if (layout_width > ideal_layout_width || layout_height > ideal_layout_height) { double scale = fmin(ideal_layout_width / (double) layout_width, ideal_layout_height / (double) layout_height); cairo_scale(cairo, scale, scale); /* Update layout to reflect scaled surface */ pango_layout_set_width(layout, ideal_layout_width / scale); pango_layout_set_height(layout, ideal_layout_height / scale); pango_cairo_update_layout(cairo, layout); } /* Draw */ cairo_set_source_rgb(cairo, color->red / 255.0, color->green / 255.0, color->blue / 255.0); cairo_move_to(cairo, 0.0, 0.0); pango_cairo_show_layout(cairo, layout); /* Draw */ guac_common_surface_draw(display->display_surface, display->char_width * col, display->char_height * row, surface); /* Free all */ g_object_unref(layout); cairo_destroy(cairo); cairo_surface_destroy(surface); return 0; }
void setup_tile (gint w, gint h) { cairo_status_t status; cairo_t* cr = NULL; cairo_surface_t* cr_surf = NULL; cairo_surface_t* tmp = NULL; cairo_surface_t* dummy_surf = NULL; cairo_surface_t* norm_surf = NULL; cairo_surface_t* blur_surf = NULL; gdouble width = (gdouble) w; gdouble height = (gdouble) h; raico_blur_t* blur = NULL; cr_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 3 * BUBBLE_SHADOW_SIZE, 3 * BUBBLE_SHADOW_SIZE); status = cairo_surface_status (cr_surf); if (status != CAIRO_STATUS_SUCCESS) g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); cr = cairo_create (cr_surf); status = cairo_status (cr); if (status != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (cr_surf); g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); } // clear and render drop-shadow and bubble-background cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (g_composited) { draw_shadow (cr, width, height, BUBBLE_SHADOW_SIZE, CORNER_RADIUS); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); draw_round_rect (cr, 1.0f, (gdouble) BUBBLE_SHADOW_SIZE, (gdouble) BUBBLE_SHADOW_SIZE, (gdouble) CORNER_RADIUS, (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE), (gdouble) (height - 2.0f* BUBBLE_SHADOW_SIZE)); cairo_fill (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, BUBBLE_BG_COLOR_R, BUBBLE_BG_COLOR_G, BUBBLE_BG_COLOR_B, 0.95f); } else cairo_set_source_rgb (cr, BUBBLE_BG_COLOR_R, BUBBLE_BG_COLOR_G, BUBBLE_BG_COLOR_B); draw_round_rect (cr, 1.0f, BUBBLE_SHADOW_SIZE, BUBBLE_SHADOW_SIZE, CORNER_RADIUS, (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE), (gdouble) (height - 2.0f * BUBBLE_SHADOW_SIZE)); cairo_fill (cr); tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (cr_surf), cairo_image_surface_get_format (cr_surf), 3 * BUBBLE_SHADOW_SIZE, 3 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (cr_surf)); dummy_surf = copy_surface (tmp); cairo_surface_destroy (tmp); tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (dummy_surf), cairo_image_surface_get_format (dummy_surf), 2 * BUBBLE_SHADOW_SIZE, 2 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (dummy_surf)); norm_surf = copy_surface (tmp); cairo_surface_destroy (tmp); blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, 6); raico_blur_apply (blur, dummy_surf); raico_blur_destroy (blur); tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (dummy_surf), cairo_image_surface_get_format (dummy_surf), 2 * BUBBLE_SHADOW_SIZE, 2 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (dummy_surf)); blur_surf = copy_surface (tmp); cairo_surface_destroy (tmp); cairo_surface_destroy (dummy_surf); g_tile = tile_new_for_padding (norm_surf, blur_surf); cairo_surface_destroy (norm_surf); cairo_surface_destroy (blur_surf); cairo_surface_destroy (cr_surf); cairo_destroy (cr); }
cairo_surface_t* render_text_to_surface (gchar* text, gint width, gint height, const cairo_font_options_t* font_opts, gdouble dpi) { cairo_surface_t* surface; cairo_t* cr; PangoFontDescription* desc; PangoLayout* layout; // sanity check if (!text || width <= 0 || height <= 0) return NULL; // create surface surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) return NULL; // create context cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); return NULL; } // clear context cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); // layout = pango_cairo_create_layout (cr); desc = pango_font_description_new (); pango_font_description_set_size (desc, 12 * PANGO_SCALE); pango_font_description_set_family_static (desc, "Candara"); pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL); pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_wrap (layout, PANGO_WRAP_WORD); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_width (layout, width * PANGO_SCALE); pango_layout_set_height (layout, height * PANGO_SCALE); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); // print and layout string (pango-wise) pango_layout_set_text (layout, text, -1); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options (pango_layout_get_context (layout), font_opts); pango_cairo_context_set_resolution (pango_layout_get_context (layout), dpi); pango_layout_context_changed (layout); // draw pango-text to our cairo-context cairo_move_to (cr, 0.0f, 0.0f); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); // this call leaks 3803 bytes, I've no idea how to fix that pango_cairo_show_layout (cr, layout); // clean up g_object_unref (layout); cairo_destroy (cr); return surface; }
void setup_tile (gint w, gint h) { cairo_status_t status; cairo_t* cr = NULL; cairo_surface_t* cr_surf = NULL; gdouble width = (gdouble) w; gdouble height = (gdouble) h; cairo_surface_t* tmp = NULL; cairo_surface_t* dummy_surf = NULL; cairo_surface_t* norm_surf = NULL; cairo_surface_t* blur_surf = NULL; raico_blur_t* blur = NULL; tile_t* tile = NULL; // create tmp. surface for scratch cr_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 3 * BUBBLE_SHADOW_SIZE, 3 * BUBBLE_SHADOW_SIZE); status = cairo_surface_status (cr_surf); if (status != CAIRO_STATUS_SUCCESS) g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); // create context for that tmp. scratch surface cr = cairo_create (cr_surf); status = cairo_status (cr); if (status != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (cr_surf); g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); } // clear, render drop-shadow and bubble-background in scratch-surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (g_composited) { draw_shadow (cr, width, height, BUBBLE_SHADOW_SIZE, CORNER_RADIUS); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); draw_round_rect (cr, 1.0f, (gdouble) BUBBLE_SHADOW_SIZE, (gdouble) BUBBLE_SHADOW_SIZE, (gdouble) CORNER_RADIUS, (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE), (gdouble) (height - 2.0f* BUBBLE_SHADOW_SIZE)); cairo_fill (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, BUBBLE_BG_COLOR_R, BUBBLE_BG_COLOR_G, BUBBLE_BG_COLOR_B, 0.95f); } else cairo_set_source_rgb (cr, BUBBLE_BG_COLOR_R, BUBBLE_BG_COLOR_G, BUBBLE_BG_COLOR_B); draw_round_rect (cr, 1.0f, BUBBLE_SHADOW_SIZE, BUBBLE_SHADOW_SIZE, CORNER_RADIUS, (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE), (gdouble) (height - 2.0f * BUBBLE_SHADOW_SIZE)); cairo_fill (cr); // create tmp. copy of scratch-surface tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (cr_surf), cairo_image_surface_get_format (cr_surf), 3 * BUBBLE_SHADOW_SIZE, 3 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (cr_surf)); dummy_surf = copy_surface (tmp); cairo_surface_destroy (tmp); // create normal-state surface for tile from copy of scratch-surface tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (dummy_surf), cairo_image_surface_get_format (dummy_surf), 2 * BUBBLE_SHADOW_SIZE, 2 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (dummy_surf)); norm_surf = copy_surface (tmp); cairo_surface_destroy (tmp); // blur tmp. copy of scratch-surface blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, 6); raico_blur_apply (blur, dummy_surf); raico_blur_destroy (blur); // create blurred-state surface for tile tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (dummy_surf), cairo_image_surface_get_format (dummy_surf), 2 * BUBBLE_SHADOW_SIZE, 2 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (dummy_surf)); blur_surf = copy_surface (tmp); cairo_surface_destroy (tmp); // actually create the tile with padding in mind tile = tile_new_for_padding (norm_surf, blur_surf); destroy_cloned_surface (norm_surf); destroy_cloned_surface (blur_surf); destroy_cloned_surface (dummy_surf); cairo_destroy (cr); cairo_surface_destroy (cr_surf); norm_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); cr = cairo_create (norm_surf); cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); tile_paint_with_padding (tile, cr, 0.0f, 0.0f, w, h, 1.0f, 0.0f); cairo_destroy (cr); blur_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); cr = cairo_create (blur_surf); cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); tile_paint_with_padding (tile, cr, 0.0f, 0.0f, w, h, 0.0f, 1.0f); cairo_destroy (cr); g_tile = tile_new_for_padding (norm_surf, blur_surf); // clean up tile_destroy (tile); cairo_surface_destroy (norm_surf); cairo_surface_destroy (blur_surf); }
void Initialize_Graphics(cairo_t *cr) { // int Height,OldMaxX; // int t,t1; // t is unused // int t1; int x,dx; MaxX = WINDOW_WIDTH; MaxY = WINDOW_WIDTH; #ifdef GUI_INTERFACE cairo_scale(SF_rgb_context, 1, 1); #endif #ifdef GUI cairo_scale(cr, 1, 1); #else cairo_scale(cr, 1.0/SCALE_F, 1.0/SCALE_F); #endif cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST); cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); if(cairo_surface_get_type(cairo_get_target(cr)) == CAIRO_SURFACE_TYPE_XLIB) { // Supply a value VAL between 100.0 and 240.0 (as a double) cairo_set_line_width(cr, (435.0 * 1) / ((double) MaxY * 1)); } else if(cairo_surface_get_type(cairo_get_target(cr)) == CAIRO_SURFACE_TYPE_IMAGE) { #ifdef __APPLE__ cairo_set_line_width(cr, DEFAULT_LINE_WIDTH); #else cairo_set_line_width(cr, DEFAULT_LINE_WIDTH); #endif } else // Mostly quartz? { cairo_set_line_width(cr, (390.1 * 1) / ((double) MaxY * 1)); // for image_surf use 239 } // cairo_set_line_width(cr, (90.1 * 1) / ((double) MaxY * 1)); //// Cairo uses a different coordinate system than graphics.h, so we reflect Cairo's through //// the x-asis to make it equal to that of graphics.h. //// cairo_matrix_t x_reflection_matrix; // Reflecting it however means that text will also be reflected. We therefore also use a // reflection matrix for drawing fonts to reflect text back. // cairo_matrix_t font_reflection_matrix; // We need the options to turn off font anti-aliasing cairo_font_options_t *font_options = cairo_font_options_create(); // cairo_matrix_init_identity(&x_reflection_matrix); // x_reflection_matrix.yy = -1.0; // cairo_set_matrix(cr, &x_reflection_matrix); cairo_set_font_size(cr, POINTS_FONT_SIZE); // cairo_set_font_size(cr, 5.9); // cairo_get_font_matrix(cr, &font_reflection_matrix); // font_reflection_matrix.yy = font_reflection_matrix.yy * -1; // font_reflection_matrix.x0 += side_panel_size; // see (1) // cairo_set_font_matrix(cr, &font_reflection_matrix); // Translate negative height down because the reflection draws on top of the drawing surface // (i.e. out of frame, directly on top of the frame) // (1) Also translate the matrix over the x-axis to emulate the fact that DOS places the SF // square in the middle. // cairo_translate(cr, side_panel_size, -MaxY); // cairo_translate(cr, 0, -MaxY); // Turning off anti-alaising cairo_get_font_options(cr, font_options); cairo_font_options_set_antialias(font_options, CAIRO_ANTIALIAS_BEST); cairo_set_font_options(cr, font_options); cairo_select_font_face(cr,"DriodSans",CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_NORMAL); cairo_font_options_destroy(font_options); // Sets all the values in the array to the empty path // Gives a vague warning, probably because this only works for types with the size of an int // (source: SO) // memset(PrevMissile, empty_path, MAX_NO_OF_MISSILES); // PrevMissile = {empty_path}; // Attemps above don't work, so we initialize manually // clears the screen, probably the dos screen, and sets the current graphics write // pointer to (0,0) // cleardevice(); // The "textheight" function returns the height of a string in pixels. // Height=textheight("H"); /* Get basic text height */ // Height = TEXT_HEIGHT; // // OldMaxX=MaxX; // t1=4*Height; // // Panel_Y_End=MaxY; // Panel_Y_Start=MaxY-t1+2; // MaxY_Panel=Panel_Y_End-Panel_Y_Start; // MaxY=MaxY-t1; // MaxX=MaxY; // Any modern graphics library should handle this "if" statements themselves, if needed at // all because we don't really need to know anymore wether or not we are on a vga display. // This aspect ratio stuff has to do with the fact if your display has square pixels or not. // AspectRatio is defined in opengraphics. Pixels are always square nowadays // if(AspectRatio==1.0) /* VGA HI */ square pixel ratio // MaxX=MaxY; // else /* for all others */ // { // MaxX=MaxX*AspectRatio; /********* MaxX and MaxY give a square */ // MaxX=MaxX-t1/AspectRatio; /******** less two panel lines */ // } // Xmargin=OldMaxX/2-MaxX/2; // printf("Xmargin: %d", Xmargin); // cairo_translate(cr, Xmargin, 0); // -- void setviewport(int left, int top, int right, int bottom, int clip); // setviewport function is used to restrict drawing to a particular portion on the screen. // For example "setviewport(100 , 100, 200, 200, 1)" will restrict our drawing activity // inside the rectangle(100,100, 200, 200). // // left, top, right, bottom are the coordinates of main diagonal of rectangle in which we wish to restrict our drawing. Also note that the point (left, top) becomes the new origin. // setviewport( Xmargin, 0, Xmargin+MaxX, MaxY, 1); dx=MaxX/8; Points_X=x=2*TEXT_WIDTH; x=x+dx; Control_X=x; x=x+dx; Velocity_X=x; x=x+dx; Vulner_X=x; x=x+dx; IFF_X=x; x=x+dx; Interval_X=x; x=x+dx; Speed_X=x; x=x+dx; Shots_X=x; }
void gui_post_expose(struct dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery) { dt_develop_t *dev = self->dev; dt_iop_graduatednd_gui_data_t *g = (dt_iop_graduatednd_gui_data_t *)self->gui_data; dt_iop_graduatednd_params_t *p = (dt_iop_graduatednd_params_t *)self->params; float wd = dev->preview_pipe->backbuf_width; float ht = dev->preview_pipe->backbuf_height; float zoom_y = dt_control_get_dev_zoom_y(); float zoom_x = dt_control_get_dev_zoom_x(); dt_dev_zoom_t zoom = dt_control_get_dev_zoom(); int closeup = dt_control_get_dev_closeup(); float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1); cairo_translate(cr, width / 2.0, height / 2.0f); cairo_scale(cr, zoom_scale, zoom_scale); cairo_translate(cr, -.5f * wd - zoom_x * wd, -.5f * ht - zoom_y * ht); // we get the extremities of the line if(g->define == 0) { if(!set_points_from_grad(self, &g->xa, &g->ya, &g->xb, &g->yb, p->rotation, p->offset)) return; g->define = 1; } float xa = g->xa * wd, xb = g->xb * wd, ya = g->ya * ht, yb = g->yb * ht; // the lines cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); if(g->selected == 3 || g->dragging == 3) cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(5.0) / zoom_scale); else cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(3.0) / zoom_scale); cairo_set_source_rgba(cr, .3, .3, .3, .8); cairo_move_to(cr, xa, ya); cairo_line_to(cr, xb, yb); cairo_stroke(cr); if(g->selected == 3 || g->dragging == 3) cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0) / zoom_scale); else cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0) / zoom_scale); cairo_set_source_rgba(cr, .8, .8, .8, .8); cairo_move_to(cr, xa, ya); cairo_line_to(cr, xb, yb); cairo_stroke(cr); // the extremities float x1, y1, x2, y2; float l = sqrt((xb - xa) * (xb - xa) + (yb - ya) * (yb - ya)); const float ext = wd * 0.01f / zoom_scale; x1 = xa + (xb - xa) * ext / l; y1 = ya + (yb - ya) * ext / l; x2 = (xa + x1) / 2.0; y2 = (ya + y1) / 2.0; y2 += (x1 - xa); x2 -= (y1 - ya); cairo_move_to(cr, xa, ya); cairo_line_to(cr, x1, y1); cairo_line_to(cr, x2, y2); cairo_close_path(cr); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0) / zoom_scale); if(g->selected == 1 || g->dragging == 1) cairo_set_source_rgba(cr, .8, .8, .8, 1.0); else cairo_set_source_rgba(cr, .8, .8, .8, .5); cairo_fill_preserve(cr); if(g->selected == 1 || g->dragging == 1) cairo_set_source_rgba(cr, .3, .3, .3, 1.0); else cairo_set_source_rgba(cr, .3, .3, .3, .5); cairo_stroke(cr); x1 = xb - (xb - xa) * ext / l; y1 = yb - (yb - ya) * ext / l; x2 = (xb + x1) / 2.0; y2 = (yb + y1) / 2.0; y2 += (xb - x1); x2 -= (yb - y1); cairo_move_to(cr, xb, yb); cairo_line_to(cr, x1, y1); cairo_line_to(cr, x2, y2); cairo_close_path(cr); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0) / zoom_scale); if(g->selected == 2 || g->dragging == 2) cairo_set_source_rgba(cr, .8, .8, .8, 1.0); else cairo_set_source_rgba(cr, .8, .8, .8, .5); cairo_fill_preserve(cr); if(g->selected == 2 || g->dragging == 2) cairo_set_source_rgba(cr, .3, .3, .3, 1.0); else cairo_set_source_rgba(cr, .3, .3, .3, .5); cairo_stroke(cr); }
static void paint_darker_background (GthImageRotator *self, cairo_t *cr) { cairo_rectangle_int_t crop_region; GtkAllocation allocation; cairo_save (cr); cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5); gtk_widget_get_allocation (GTK_WIDGET (self->priv->viewer), &allocation); switch (self->priv->resize) { case GTH_TRANSFORM_RESIZE_BOUNDING_BOX: case GTH_TRANSFORM_RESIZE_CLIP: crop_region = self->priv->clip_area; break; case GTH_TRANSFORM_RESIZE_CROP: /* the crop_region is not zoomed the clip_area is already zoomed */ cairo_scale (cr, self->priv->preview_zoom, self->priv->preview_zoom); crop_region = self->priv->crop_region; crop_region.x += self->priv->clip_area.x / self->priv->preview_zoom; crop_region.y += self->priv->clip_area.y / self->priv->preview_zoom; allocation.width /= self->priv->preview_zoom; allocation.height /= self->priv->preview_zoom; break; } /* left side */ cairo_rectangle (cr, 0, 0, crop_region.x, allocation.height); /* right side */ cairo_rectangle (cr, crop_region.x + crop_region.width, 0, allocation.width - crop_region.x - crop_region.width, allocation.height); /* top */ cairo_rectangle (cr, crop_region.x, 0, crop_region.width, crop_region.y); /* bottom */ cairo_rectangle (cr, crop_region.x, crop_region.y + crop_region.height, crop_region.width, allocation.height - crop_region.y - crop_region.height); cairo_fill (cr); cairo_restore (cr); }
void PreviewJob::run() { XOJ_CHECK_TYPE(PreviewJob); GtkAllocation alloc; gtk_widget_get_allocation(this->sidebarPreview->widget, &alloc); cairo_surface_t * crBuffer = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, alloc.width, alloc.height); double zoom = this->sidebarPreview->sidebar->getZoom(); cairo_t * cr2 = cairo_create(crBuffer); cairo_matrix_t defaultMatrix = { 0 }; cairo_get_matrix(cr2, &defaultMatrix); cairo_translate(cr2, Shadow::getShadowTopLeftSize() + 2, Shadow::getShadowTopLeftSize() + 2); cairo_scale(cr2, zoom, zoom); Document * doc = this->sidebarPreview->sidebar->getDocument(); doc->lock(); if (this->sidebarPreview->page.getBackgroundType() == BACKGROUND_TYPE_PDF) { int pgNo = this->sidebarPreview->page.getPdfPageNr(); XojPopplerPage * popplerPage = doc->getPdfPage(pgNo); PdfView::drawPage(this->sidebarPreview->sidebar->getCache(), popplerPage, cr2, zoom, this->sidebarPreview->page.getWidth(), this->sidebarPreview->page.getHeight()); } DocumentView view; view.drawPage(this->sidebarPreview->page, cr2, true); cairo_set_matrix(cr2, &defaultMatrix); cairo_set_operator(cr2, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgb(cr2, 1, 1, 1); cairo_rectangle(cr2, 0, 0, Shadow::getShadowTopLeftSize() + 2, alloc.height); cairo_rectangle(cr2, 0, 0, alloc.height, Shadow::getShadowTopLeftSize() + 2); cairo_rectangle(cr2, alloc.width - Shadow::getShadowBottomRightSize() - 2, 0, Shadow::getShadowBottomRightSize() + 2, alloc.height); cairo_rectangle(cr2, 0, alloc.height - Shadow::getShadowBottomRightSize() - 2, alloc.width, Shadow::getShadowBottomRightSize() + 2); cairo_fill(cr2); cairo_destroy(cr2); doc->unlock(); g_mutex_lock(this->sidebarPreview->drawingMutex); if (this->sidebarPreview->crBuffer) { cairo_surface_destroy(this->sidebarPreview->crBuffer); } this->sidebarPreview->crBuffer = crBuffer; gdk_threads_enter(); gtk_widget_queue_draw(this->sidebarPreview->widget); gdk_threads_leave(); g_mutex_unlock(this->sidebarPreview->drawingMutex); }
static GstFlowReturn gst_rsvg_decode_image (GstRsvgDec * rsvg, GstBuffer * buffer, GstVideoCodecFrame * frame) { GstVideoDecoder *decoder = GST_VIDEO_DECODER (rsvg); GstFlowReturn ret = GST_FLOW_OK; cairo_t *cr; cairo_surface_t *surface; RsvgHandle *handle; GError *error = NULL; RsvgDimensionData dimension; gdouble scalex, scaley; GstMapInfo minfo; GstVideoFrame vframe; GstVideoCodecState *output_state; GST_LOG_OBJECT (rsvg, "parsing svg"); if (!gst_buffer_map (buffer, &minfo, GST_MAP_READ)) { GST_ERROR_OBJECT (rsvg, "Failed to get SVG image"); return GST_FLOW_ERROR; } handle = rsvg_handle_new_from_data (minfo.data, minfo.size, &error); if (!handle) { GST_ERROR_OBJECT (rsvg, "Failed to parse SVG image: %s", error->message); g_error_free (error); return GST_FLOW_ERROR; } rsvg_handle_get_dimensions (handle, &dimension); output_state = gst_video_decoder_get_output_state (decoder); if ((output_state == NULL) || GST_VIDEO_INFO_WIDTH (&output_state->info) != dimension.width || GST_VIDEO_INFO_HEIGHT (&output_state->info) != dimension.height) { /* Create the output state */ gst_video_decoder_set_output_state (decoder, GST_RSVG_VIDEO_FORMAT, dimension.width, dimension.height, rsvg->input_state); if (output_state) gst_video_codec_state_unref (output_state); output_state = gst_video_decoder_get_output_state (decoder); } ret = gst_video_decoder_allocate_output_frame (decoder, frame); if (ret != GST_FLOW_OK) { g_object_unref (handle); GST_ERROR_OBJECT (rsvg, "Buffer allocation failed %s", gst_flow_get_name (ret)); return ret; } GST_LOG_OBJECT (rsvg, "render image at %d x %d", GST_VIDEO_INFO_HEIGHT (&output_state->info), GST_VIDEO_INFO_WIDTH (&output_state->info)); if (!gst_video_frame_map (&vframe, &gst_video_decoder_get_output_state (decoder)->info, frame->output_buffer, GST_MAP_READWRITE)) { GST_ERROR_OBJECT (rsvg, "Failed to get SVG image"); return GST_FLOW_ERROR; } surface = cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0), CAIRO_FORMAT_ARGB32, GST_VIDEO_FRAME_WIDTH (&vframe), GST_VIDEO_FRAME_HEIGHT (&vframe), GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 0)); cr = cairo_create (surface); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); scalex = scaley = 1.0; if (GST_VIDEO_INFO_WIDTH (&output_state->info) != dimension.width) { scalex = ((gdouble) GST_VIDEO_INFO_WIDTH (&output_state->info)) / ((gdouble) dimension.width); } if (GST_VIDEO_INFO_HEIGHT (&output_state->info) != dimension.height) { scaley = ((gdouble) GST_VIDEO_INFO_HEIGHT (&output_state->info)) / ((gdouble) dimension.height); } cairo_scale (cr, scalex, scaley); rsvg_handle_render_cairo (handle, cr); g_object_unref (handle); cairo_destroy (cr); cairo_surface_destroy (surface); /* Now unpremultiply Cairo's ARGB to match GStreamer's */ gst_rsvg_decode_unpremultiply (GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0), GST_VIDEO_FRAME_WIDTH (&vframe), GST_VIDEO_FRAME_HEIGHT (&vframe)); gst_video_codec_state_unref (output_state); gst_buffer_unmap (buffer, &minfo); gst_video_frame_unmap (&vframe); return ret; }
static void _call_invalidaterect_ptac(void *param) { struct pp_instance_s *pp_i = param; NPRect npr = {.top = 0, .left = 0, .bottom = pp_i->height, .right = pp_i->width}; npn.invalidaterect(pp_i->npp, &npr); npn.forceredraw(pp_i->npp); } int32_t ppb_graphics2d_flush(PP_Resource graphics_2d, struct PP_CompletionCallback callback) { struct pp_graphics2d_s *g2d = pp_resource_acquire(graphics_2d, PP_RESOURCE_GRAPHICS2D); if (!g2d) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } struct pp_instance_s *pp_i = g2d->instance; pthread_mutex_lock(&pp_i->lock); if (pp_i->graphics != graphics_2d) { pp_resource_release(graphics_2d); pthread_mutex_unlock(&pp_i->lock); return PP_ERROR_FAILED; } if (pp_i->graphics_in_progress) { pp_resource_release(graphics_2d); pthread_mutex_unlock(&pp_i->lock); return PP_ERROR_INPROGRESS; } pp_i->graphics_ccb = callback; pp_i->graphics_in_progress = 1; pthread_mutex_unlock(&pp_i->lock); while (g2d->task_list) { GList *link = g_list_first(g2d->task_list); struct g2d_paint_task_s *pt = link->data; struct pp_image_data_s *id; cairo_t *cr; g2d->task_list = g_list_delete_link(g2d->task_list, link); switch (pt->type) { case gpt_paint_id: id = pp_resource_acquire(pt->image_data, PP_RESOURCE_IMAGE_DATA); if (!id) break; cairo_surface_mark_dirty(g2d->cairo_surf); cr = cairo_create(g2d->cairo_surf); cairo_set_source_surface(cr, id->cairo_surf, pt->ofs.x, pt->ofs.y); if (pt->src_is_set) { cairo_rectangle(cr, pt->src.point.x + pt->ofs.x, pt->src.point.y + pt->ofs.y, pt->src.size.width, pt->src.size.height); cairo_fill(cr); } else { cairo_paint(cr); } cairo_surface_flush(g2d->cairo_surf); cairo_destroy(cr); pp_resource_release(pt->image_data); pp_resource_unref(pt->image_data); break; case gpt_replace_contents: id = pp_resource_acquire(pt->image_data, PP_RESOURCE_IMAGE_DATA); if (!id) break; if (id->width == g2d->width || id->height == g2d->height) { void *tmp; cairo_surface_t *tmp_surf; cairo_surface_flush(id->cairo_surf); cairo_surface_flush(g2d->cairo_surf); tmp = g2d->data; g2d->data = id->data; id->data = tmp; tmp_surf = g2d->cairo_surf; g2d->cairo_surf = id->cairo_surf; id->cairo_surf = tmp_surf; } pp_resource_release(pt->image_data); pp_resource_unref(pt->image_data); break; } g_slice_free(struct g2d_paint_task_s, pt); } // scale image { cairo_surface_t *surf; surf = cairo_image_surface_create_for_data((unsigned char *)g2d->second_buffer, CAIRO_FORMAT_ARGB32, g2d->scaled_width, g2d->scaled_height, g2d->scaled_stride); cairo_t *cr = cairo_create(surf); cairo_scale(cr, g2d->scale, g2d->scale); cairo_set_source_surface(cr, g2d->cairo_surf, 0, 0); cairo_paint(cr); cairo_destroy(cr); cairo_surface_destroy(surf); } pp_resource_release(graphics_2d); pthread_mutex_lock(&pp_i->lock); if (!callback.func) pthread_barrier_init(&pp_i->graphics_barrier, NULL, 2); if (pp_i->is_fullscreen) { XGraphicsExposeEvent ev = { .type = GraphicsExpose, .drawable = pp_i->fs_wnd, .width = pp_i->width, .height = pp_i->height }; XSendEvent(pp_i->dpy, pp_i->fs_wnd, True, ExposureMask, (void *)&ev); XFlush(pp_i->dpy); pthread_mutex_unlock(&pp_i->lock); } else { pthread_mutex_unlock(&pp_i->lock); ppb_core_call_on_browser_thread(_call_invalidaterect_ptac, pp_i); } if (callback.func) return PP_OK_COMPLETIONPENDING; pthread_barrier_wait(&pp_i->graphics_barrier); return PP_OK; }
/* * Draws global image with fill color onto a pixmap with the given * resolution and returns it. * */ xcb_pixmap_t draw_image(uint32_t *resolution) { xcb_pixmap_t bg_pixmap = XCB_NONE; int button_diameter_physical = ceil(scaling_factor() * BUTTON_DIAMETER); DEBUG("scaling_factor is %.f, physical diameter is %d px\n", scaling_factor(), button_diameter_physical); if (!vistype) vistype = get_root_visual_type(screen); bg_pixmap = create_bg_pixmap(conn, screen, resolution, color); /* Initialize cairo: Create one in-memory surface to render the unlock * indicator on, create one XCB surface to actually draw (one or more, * depending on the amount of screens) unlock indicators on. */ cairo_surface_t *output = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, resolution[0], resolution[1]); cairo_t *ctx = cairo_create(output); cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); cairo_t *xcb_ctx = cairo_create(xcb_output); if (img) { if (!tile) { cairo_set_source_surface(xcb_ctx, img, 0, 0); cairo_paint(xcb_ctx); } else { /* create a pattern and fill a rectangle as big as the screen */ cairo_pattern_t *pattern; pattern = cairo_pattern_create_for_surface(img); cairo_set_source(xcb_ctx, pattern); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); cairo_fill(xcb_ctx); cairo_pattern_destroy(pattern); } } else { char strgroups[3][3] = {{color[0], color[1], '\0'}, {color[2], color[3], '\0'}, {color[4], color[5], '\0'}}; uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)), (strtol(strgroups[1], NULL, 16)), (strtol(strgroups[2], NULL, 16))}; cairo_set_source_rgb(xcb_ctx, rgb16[0] / 255.0, rgb16[1] / 255.0, rgb16[2] / 255.0); cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); cairo_fill(xcb_ctx); } if (unlock_indicator) { cairo_scale(ctx, scaling_factor(), scaling_factor()); cairo_set_source_rgb(ctx, 1, 1, 1); cairo_set_font_size(ctx, 60.0); cairo_select_font_face(ctx, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); if (pam_state == STATE_PAM_VERIFY) { passwdlength = 0; } if (unlock_state == STATE_KEY_ACTIVE) { passwdlength = passwdlength + 1; } else if (unlock_state == STATE_BACKSPACE_ACTIVE && passwdlength > 0){ passwdlength = passwdlength - 1; } else if (unlock_state == STATE_ESCAPE_ACTIVE) { passwdlength = 0; } char passwd[passwdlength + 1]; for (int i = 0; i < passwdlength; ++i) { passwd[i] = '*'; } passwd[passwdlength] = '\0'; cairo_text_extents_t extents; double x, y; cairo_text_extents(ctx, passwd, &extents); x = BUTTON_RADIUS - ((extents.width / 2) + extents.x_bearing); y = BUTTON_RADIUS - ((extents.height / 2) + extents.y_bearing); cairo_move_to(ctx, x, y); /* cairo_show_text(ctx, passwd); */ cairo_text_path(ctx, passwd); cairo_fill_preserve(ctx); cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_line_width(ctx, 1.0); cairo_stroke(ctx); cairo_close_path(ctx); } if (xr_screens > 0) { /* Composite the unlock indicator in the middle of each screen. */ for (int screen = 0; screen < xr_screens; screen++) { int x = (xr_resolutions[screen].x + ((xr_resolutions[screen].width / 2) - (button_diameter_physical / 2))); int y = (xr_resolutions[screen].y + ((xr_resolutions[screen].height / 2) - (button_diameter_physical / 2))); cairo_set_source_surface(xcb_ctx, output, x, y); cairo_rectangle(xcb_ctx, x, y, button_diameter_physical, button_diameter_physical); cairo_fill(xcb_ctx); } } else { /* We have no information about the screen sizes/positions, so we just * place the unlock indicator in the middle of the X root window and * hope for the best. */ int x = (last_resolution[0] / 2) - (button_diameter_physical / 2); int y = (last_resolution[1] / 2) - (button_diameter_physical / 2); cairo_set_source_surface(xcb_ctx, output, x, y); cairo_rectangle(xcb_ctx, x, y, button_diameter_physical, button_diameter_physical); cairo_fill(xcb_ctx); } cairo_surface_destroy(xcb_output); cairo_surface_destroy(output); cairo_destroy(ctx); cairo_destroy(xcb_ctx); return bg_pixmap; }
int msRenderSVGToPixmap(symbolObj *symbol, symbolStyleObj *style) { #ifdef USE_SVG_CAIRO unsigned int svg_width, svg_height; svg_cairo_status_t status; cairo_t *cr; svg_cairo_t *svgc; cairo_surface_t *surface; unsigned char *pb; rasterBufferObj *rb; //rendering_buffer *rc; int width, height, surface_w, surface_h,row; double scale; //already rendered at the right size and scale? return if (symbol->pixmap_buffer) { if (style->scale == symbol->pixmap_buffer->scale && style->rotation == symbol->pixmap_buffer->rotation) { return MS_SUCCESS; } else { if(symbol->renderer!=NULL) symbol->renderer->freeSymbol(symbol); msFreeRasterBuffer(symbol->pixmap_buffer); } } if (!symbol->svg_cairo_surface ) msPreloadSVGSymbol(symbol); if (!symbol->svg_cairo_surface) return MS_FAILURE; //set up raster svgc =symbol->svg_cairo_surface; svg_cairo_get_size (svgc, &svg_width, &svg_height); width = surface_w = svg_width; height = surface_h = svg_height; //scale such that the SVG is rendered at the desired size in pixels scale = style->scale; /*MS_MIN(style->scale / (double) svg_width, style->scale / (double) svg_height);*/ //increase pixmap size to accomodate scaling/rotation if (scale != 1.0 && style->scale != 1.0) { width = surface_w = (svg_width * scale + 0.5); height = surface_h = (svg_height * scale + 0.5); } if (style->rotation != 0) { surface_w = MS_NINT(width * 1.415); surface_h = MS_NINT(height * 1.415); } surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, surface_w, surface_h); cr = cairo_create(surface); if (style->rotation != 0) { cairo_translate (cr, surface_w/2, surface_h/2); cairo_rotate(cr, -style->rotation); cairo_translate (cr, -width/2, -height/2); } if (style->scale != 1.0) { cairo_scale(cr,scale,scale); } status = svg_cairo_render(svgc, cr); pb = cairo_image_surface_get_data(surface); //set up raster symbol->pixmap_buffer = (rasterBufferObj*)calloc(1,sizeof(rasterBufferObj)); MS_CHECK_ALLOC(symbol->pixmap_buffer, sizeof(rasterBufferObj), MS_FAILURE); initializeRasterBufferCairo(symbol->pixmap_buffer, surface_w, surface_h, 0); rb = symbol->pixmap_buffer; memcpy(rb->data.rgba.pixels, pb, surface_w * surface_h * 4 * sizeof(unsigned char)); /* unpremultiply the data */ for(row=0; row<rb->height; row++) { int col; unsigned char *a,*r,*g,*b; r=rb->data.rgba.r+row*rb->data.rgba.row_step; g=rb->data.rgba.g+row*rb->data.rgba.row_step; b=rb->data.rgba.b+row*rb->data.rgba.row_step; a=rb->data.rgba.a+row*rb->data.rgba.row_step; for(col=0; col<rb->width; col++) { if(*a && *a < 255) { double da = *a/255.0; *r/=da; *g/=da; *b/=da; } a+=rb->data.rgba.pixel_step; r+=rb->data.rgba.pixel_step; g+=rb->data.rgba.pixel_step; b+=rb->data.rgba.pixel_step; } } rb->scale = style->scale; rb->rotation = style->rotation; cairo_destroy(cr); cairo_surface_destroy(surface); return MS_SUCCESS; #else msSetError(MS_MISCERR, "SVG Symbols requested but MapServer is not built with libsvgcairo", "renderSVGSymbolCairo()"); return MS_FAILURE; #endif }
static gboolean dt_iop_zonesystem_preview_expose (GtkWidget *widget, GdkEventExpose *event, dt_iop_module_t *self) { const int inset = DT_PIXEL_APPLY_DPI(2); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; 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; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* clear background */ GtkStateType state = gtk_widget_get_state(self->expander); GtkStyle *style = gtk_widget_get_style(self->expander); float bg_red = style->bg[state].red/65535.0, bg_green = style->bg[state].green/65535.0, bg_blue = style->bg[state].blue/65535.0; cairo_set_source_rgb (cr, bg_red, bg_green, bg_blue); cairo_paint (cr); width -= 2*inset; height -= 2*inset; cairo_translate(cr, inset, inset); dt_pthread_mutex_lock(&g->lock); if( g->in_preview_buffer && g->out_preview_buffer && self->enabled) { /* calculate the zonemap */ float zonemap[MAX_ZONE_SYSTEM_SIZE]= {-1}; _iop_zonesystem_calculate_zonemap (p,zonemap); /* let's generate a pixbuf from pixel zone buffer */ guchar *image = g_malloc_n((size_t)4*g->preview_width*g->preview_height, sizeof(guchar)); guchar *buffer = g->mouse_over_output_zones ? g->out_preview_buffer : g->in_preview_buffer; for (int k=0; k<g->preview_width*g->preview_height; k++) { int zone = 255*CLIP (((1.0/(p->size-1))*buffer[k])); image[4*k+2] = (g->hilite_zone && buffer[k]==g->zone_under_mouse)?255:zone; image[4*k+1] = (g->hilite_zone && buffer[k]==g->zone_under_mouse)?255:zone; image[4*k+0] = (g->hilite_zone && buffer[k]==g->zone_under_mouse)?0:zone; } dt_pthread_mutex_unlock(&g->lock); const int wd = g->preview_width, ht = g->preview_height; const float scale = fminf(width/(float)wd, height/(float)ht); const int stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, wd); cairo_surface_t *surface = cairo_image_surface_create_for_data (image, CAIRO_FORMAT_RGB24, wd, ht, stride); cairo_translate(cr, width/2.0, height/2.0f); cairo_scale(cr, scale, scale); cairo_translate(cr, -.5f*wd, -.5f*ht); cairo_rectangle(cr, DT_PIXEL_APPLY_DPI(1), DT_PIXEL_APPLY_DPI(1), wd-DT_PIXEL_APPLY_DPI(2), ht-DT_PIXEL_APPLY_DPI(2)); cairo_set_source_surface (cr, surface, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD); cairo_fill_preserve(cr); cairo_surface_destroy (surface); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0)); cairo_set_source_rgb(cr, .1, .1, .1); cairo_stroke(cr); g_free(image); } else { dt_pthread_mutex_unlock(&g->lock); // draw a big, subdued dt logo if(g->image) { cairo_set_source_surface(cr, g->image, (width - g->image_width) * 0.5, (height - g->image_height) * 0.5); cairo_rectangle(cr, 0, 0, width, height); cairo_set_operator(cr, CAIRO_OPERATOR_HSL_LUMINOSITY); cairo_fill_preserve(cr); cairo_set_operator(cr, CAIRO_OPERATOR_DARKEN); cairo_set_source_rgb(cr, bg_red + 0.02, bg_green + 0.02, bg_blue+ 0.02); cairo_fill_preserve(cr); cairo_set_operator(cr, CAIRO_OPERATOR_LIGHTEN); cairo_set_source_rgb(cr, bg_red - 0.02, bg_green - 0.02, bg_blue- 0.02); cairo_fill(cr); } } 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 gboolean dt_iop_levels_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_levels_gui_data_t *c = (dt_iop_levels_gui_data_t *)self->gui_data; dt_iop_levels_params_t *p = (dt_iop_levels_params_t *)self->params; const int inset = DT_GUI_CURVE_EDITOR_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); // clear bg cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2*inset; height -= 2*inset; 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); cairo_set_source_rgb (cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); // draw grid cairo_set_line_width(cr, .4); cairo_set_source_rgb (cr, .1, .1, .1); dt_draw_vertical_lines(cr, 4, 0, 0, width, height); // Drawing the vertical line indicators cairo_set_line_width(cr, 2.); for(int k = 0; k < 3; k++) { if(k == c->handle_move && c->mouse_x > 0) cairo_set_source_rgb(cr, 1, 1, 1); else cairo_set_source_rgb(cr, .7, .7, .7); cairo_move_to(cr, width*p->levels[k], height); cairo_rel_line_to(cr, 0, -height); cairo_stroke(cr); } // draw x positions cairo_set_line_width(cr, 1.); const float arrw = 7.0f; for(int k=0; k<3; k++) { switch(k) { case 0: cairo_set_source_rgb(cr, 0, 0, 0); break; case 1: cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); break; default: cairo_set_source_rgb(cr, 1, 1, 1); break; } cairo_move_to(cr, width*p->levels[k], height+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(c->handle_move == k && c->mouse_x > 0) cairo_fill(cr); else cairo_stroke(cr); } cairo_translate(cr, 0, height); // draw lum histogram in background // only if the module is enabled if (self->enabled) { dt_develop_t *dev = darktable.develop; float *hist, hist_max; hist = dev->histogram_pre_levels; hist_max = dev->histogram_pre_levels_max; if(hist_max > 0) { cairo_save(cr); cairo_scale(cr, width/63.0, -(height-5)/(float)hist_max); cairo_set_source_rgba(cr, .2, .2, .2, 0.5); dt_draw_histogram_8(cr, hist, 3); cairo_restore(cr); } } // Cleaning up 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; }
void shadow_setup (cairo_t *_cr, int w, int h) { clock_surface = cairo_surface_create_similar (cairo_get_target (_cr), CAIRO_CONTENT_COLOR_ALPHA, CLOCK_W, CLOCK_H); clock_bg_surface = cairo_surface_create_similar (cairo_get_target (_cr), CAIRO_CONTENT_COLOR_ALPHA, CLOCK_W, CLOCK_H); bg_surface = cairo_glitz_surface_create_from_png (_cr, "desktop.png", &bg_width, &bg_height); if (cairo_surface_status (bg_surface)) { printf ("error reading desktop.png\n"); exit(1); } fakewin_surface = cairo_glitz_surface_create_from_png (_cr, "fakewin.png", &fakewin_width, &fakewin_height); if (cairo_surface_status (fakewin_surface)) { printf ("error reading fakewin.png\n"); exit(1); } glider_surface = cairo_glitz_surface_create_from_png (_cr, "glider.png", &glider_width, &glider_height); if (cairo_surface_status (glider_surface)) { printf ("error reading glider.png\n"); exit(1); } cr = cairo_create (clock_bg_surface); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0); cairo_rectangle (cr, 0, 0, CLOCK_W, CLOCK_H); cairo_fill (cr); cairo_save (cr); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.25); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_scale (cr, CLOCK_W, CLOCK_H); cairo_translate (cr, 0.5, 0.5); cairo_arc (cr, 0, 0, 0.5, 0, 2 * M_PI); cairo_fill (cr); cairo_restore (cr); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); fdface_draw (cr, CLOCK_W, CLOCK_H); cairo_destroy (cr); render_clock (); render_fakewin (); cr = _cr; }
void TextPainter::redrawText(const util::rect<double>& roi, const util::point<double>& resolution) { // make a copy of the data needed to draw the text string __text; double __textSize; double __padding; std::vector<double> __textColor; { boost::mutex::scoped_lock lock(_dataMutex); __text = _text; __textSize = _textSize; __padding = _padding; __textColor = _textColor; } LOG_ALL(textpainterlog) << "[redrawText] redrawing text..." << std::endl; // Each Gl unit represents resolution.* pixels. This gives the target pixel // size. [cu] util::rect<double> cairoSize = _glSize*resolution; util::point<double> cairoPadding = _glPadding*resolution; util::point<double> glToCairoScale = resolution; util::point<double> textToGlScale(1.0, 1.0); util::point<double> textToCairoScale = textToGlScale*glToCairoScale; LOG_ALL(textpainterlog) << "[redrawText] according to current resolution (" << resolution << "), this is " << cairoSize << "[cu]" << std::endl; _glRoi = roi; LOG_ALL(textpainterlog) << "[redrawText] ROI is " << _glRoi << "[gu]" << std::endl; // Find portion of target region that is within ROI. [gu] _glRoi.minX = std::max(_glRoi.minX, _glSize.minX); _glRoi.minY = std::max(_glRoi.minY, _glSize.minY); _glRoi.maxX = std::min(_glRoi.maxX, _glSize.maxX); _glRoi.maxY = std::min(_glRoi.maxY, _glSize.maxY); // Determine ROI region of target region. [cu] util::rect<double> cairoRoi = _glRoi*glToCairoScale; LOG_ALL(textpainterlog) << "[redrawText] relevant part is " << cairoRoi << "[cu]" << std::endl; if (cairoRoi.width() <= 0 || cairoRoi.height() <= 0) return; // The target size. [cu] _cairoWidth = (int)round(cairoRoi.width()); _cairoHeight = (int)round(cairoRoi.height()); LOG_ALL(textpainterlog) << "[redrawText] rounded, this is " << _cairoWidth << "x" << _cairoHeight << " pixels" << std::endl; LOG_ALL(textpainterlog) << "[redrawText] scaling is " << textToCairoScale << std::endl; // Next, we prepare the cairo surface for the text. if (!prepareBuffer()) { LOG_DEBUG(textpainterlog) << "[redrawText] failed to create buffer" << std::endl; return; } LOG_ALL(textpainterlog) << "[redrawText] prepared new cairo surface" << std::endl; // Scale the cairo text to fill the scaled surface. _cairoTextSize = __textSize*textToCairoScale.x; // this will be incorrect for anisotropic resolutions setFont(_context, __textColor); LOG_ALL(textpainterlog) << "[redrawText] cairo text size is now " << _cairoTextSize << std::endl; // Determine the starting point of the text drawing with respect to padding. // [ncu] util::point<double> textStart(-_extents.x_bearing, -_extents.y_bearing); LOG_ALL(textpainterlog) << "[redrawText] text starting point according to bearing is " << textStart << "[ncu]" << std::endl; textStart += util::point<double>(_padding, _padding); LOG_ALL(textpainterlog) << "[redrawText] with padding this makes " << textStart << "[ncu]" << std::endl; // Determine the starting point of the text drawing relative to ROI [cu]. util::point<double> cairoRoiStart = textStart*textToCairoScale; LOG_ALL(textpainterlog) << "[redrawText] in target units this is " << cairoRoiStart << "[cu]" << std::endl; cairoRoiStart -= util::point<double>(cairoRoi.minX - cairoSize.minX, cairoRoi.minY - cairoSize.minY); LOG_ALL(textpainterlog) << "[redrawText] taking into account the ROI, we have finally " << cairoRoiStart << "[cu]" << std::endl; // We have to draw upside down to be OpenGl compatible cairo_scale(_context, 1.0, -1.0); // Move to the starting point. cairo_move_to( _context, cairoRoiStart.x, cairoRoiStart.y - _cairoHeight); // Draw the text. cairo_show_text(_context, __text.c_str()); finishBuffer(); }
void shadow_render (int w, int h) { double scale_x, scale_y; int move_done; double shadow_offset_x, shadow_offset_y; double light_x, light_y; light_x = w / 2.0; light_y = h / 2.0; cairo_save (cr); cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); scale_x = ((double) w) / (double) bg_width; scale_y = ((double) h) / (double) bg_height; cairo_scale (cr, scale_x, scale_y); cairo_set_source_surface (cr, bg_surface, 0.0, 0.0); cairo_paint (cr); cairo_restore (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (!(shadow_cnt % 10)) render_clock (); else if (!(shadow_cnt % 5)) render_fakewin (); shadow_cnt++; if (shadow_cnt >= 1000000) shadow_cnt = 0; cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); shadow_offset_x = max_shadow_offset * ((fw_x + fakewin_width / 2) - light_x) / (w / 2.0); shadow_offset_y = max_shadow_offset * ((fw_y + fakewin_height / 2) - light_y) / (h / 2.0); cairo_save (cr); cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, shadow_alpha); cairo_mask_surface (cr, fakewin_surface, fw_x + shadow_offset_x - 0.05 * fakewin_width, fw_y + shadow_offset_y - 0.05 * fakewin_height); cairo_paint (cr); cairo_restore (cr); cairo_save (cr); cairo_translate (cr, (int) fw_x, (int) fw_y); cairo_set_source_surface (cr, fakewin_surface, 0.0, 0.0); cairo_paint (cr); cairo_restore (cr); shadow_offset_x = max_shadow_offset * ((cl_x + CLOCK_W / 2) - light_x) / (w / 2.0); shadow_offset_y = max_shadow_offset * ((cl_y + CLOCK_H / 2) - light_y) / (h / 2.0); cairo_save (cr); cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, shadow_alpha); cairo_mask_surface (cr, clock_surface, cl_x + shadow_offset_x - 0.05 * CLOCK_W, cl_y + shadow_offset_y - 0.05 * CLOCK_H); cairo_paint (cr); cairo_restore (cr); cairo_save (cr); cairo_translate (cr, (int) cl_x, (int) cl_y); cairo_set_source_surface (cr, clock_surface, 0.0, 0.0); cairo_paint (cr); cairo_restore (cr); if (which) { move_done = shadow_move_towards_point (&fw_x, &fw_y); } else { move_done = shadow_move_towards_point (&cl_x, &cl_y); } if (move_done) { which = (int) (drand48 () + 0.5); dst_x = drand48 () * (w - ((which)? fakewin_width : CLOCK_W) - max_shadow_offset); dst_y = drand48 () * (h - ((which)? fakewin_height: CLOCK_H) - max_shadow_offset); if (which) { start_x = fw_x; start_y = fw_y; } else { start_x = cl_x; start_y = cl_y; } } cairo_restore (cr); }
static gboolean gtk_gst_widget_draw (GtkWidget * widget, cairo_t * cr) { GtkGstBaseWidget *gst_widget = (GtkGstBaseWidget *) widget; guint widget_width, widget_height; cairo_surface_t *surface; GstVideoFrame frame; widget_width = gtk_widget_get_allocated_width (widget); widget_height = gtk_widget_get_allocated_height (widget); GTK_GST_BASE_WIDGET_LOCK (gst_widget); /* There is not much to optimize in term of redisplay, so simply swap the * pending_buffer with the active buffer */ if (gst_widget->pending_buffer) { if (gst_widget->buffer) gst_buffer_unref (gst_widget->buffer); gst_widget->buffer = gst_widget->pending_buffer; gst_widget->pending_buffer = NULL; } /* failed to map the video frame */ if (gst_widget->negotiated && gst_widget->buffer && gst_video_frame_map (&frame, &gst_widget->v_info, gst_widget->buffer, GST_MAP_READ)) { gdouble scale_x = (gdouble) widget_width / gst_widget->display_width; gdouble scale_y = (gdouble) widget_height / gst_widget->display_height; GstVideoRectangle result; cairo_format_t format; gst_widget->v_info = frame.info; if (frame.info.finfo->format == GST_VIDEO_FORMAT_ARGB || frame.info.finfo->format == GST_VIDEO_FORMAT_BGRA) { format = CAIRO_FORMAT_ARGB32; } else { format = CAIRO_FORMAT_RGB24; } surface = cairo_image_surface_create_for_data (frame.data[0], format, frame.info.width, frame.info.height, frame.info.stride[0]); if (gst_widget->force_aspect_ratio) { GstVideoRectangle src, dst; src.x = 0; src.y = 0; src.w = gst_widget->display_width; src.h = gst_widget->display_height; dst.x = 0; dst.y = 0; dst.w = widget_width; dst.h = widget_height; gst_video_sink_center_rect (src, dst, &result, TRUE); scale_x = scale_y = MIN (scale_x, scale_y); } else { result.x = 0; result.y = 0; result.w = widget_width; result.h = widget_height; } if (gst_widget->ignore_alpha) { GdkRGBA color = { 0.0, 0.0, 0.0, 1.0 }; gdk_cairo_set_source_rgba (cr, &color); if (result.x > 0) { cairo_rectangle (cr, 0, 0, result.x, widget_height); cairo_fill (cr); } if (result.y > 0) { cairo_rectangle (cr, 0, 0, widget_width, result.y); cairo_fill (cr); } if (result.w < widget_width) { cairo_rectangle (cr, result.x + result.w, 0, widget_width - result.w, widget_height); cairo_fill (cr); } if (result.h < widget_height) { cairo_rectangle (cr, 0, result.y + result.h, widget_width, widget_height - result.h); cairo_fill (cr); } } scale_x *= (gdouble) gst_widget->display_width / (gdouble) frame.info.width; scale_y *= (gdouble) gst_widget->display_height / (gdouble) frame.info.height; cairo_translate (cr, result.x, result.y); cairo_scale (cr, scale_x, scale_y); cairo_rectangle (cr, 0, 0, result.w, result.h); cairo_set_source_surface (cr, surface, 0, 0); cairo_paint (cr); cairo_surface_destroy (surface); gst_video_frame_unmap (&frame); } else { GdkRGBA color; if (gst_widget->ignore_alpha) { color.red = color.blue = color.green = 0.0; color.alpha = 1.0; } else { gtk_style_context_get_color (gtk_widget_get_style_context (widget), GTK_STATE_FLAG_NORMAL, &color); } gdk_cairo_set_source_rgba (cr, &color); cairo_rectangle (cr, 0, 0, widget_width, widget_height); cairo_fill (cr); } GTK_GST_BASE_WIDGET_UNLOCK (gst_widget); return FALSE; }
GIcon * photos_utils_create_collection_icon (gint base_size, GList *pixbufs) { cairo_surface_t *surface; cairo_t *cr; GdkPixbuf *pix; GIcon *ret_val; GList *l; GtkStyleContext *context; GtkWidgetPath *path; gint cur_x; gint cur_y; gint idx; gint padding; gint pix_height; gint pix_width; gint scale_size; gint tile_size; /* TODO: do not hardcode 4, but scale to another layout if more * pixbufs are provided. */ padding = MAX (floor (base_size / 10), 4); tile_size = (base_size - (3 * padding)) / 2; 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); gtk_widget_path_unref (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 < 4) { 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); if ((idx % 2) == 0) { cur_x += tile_size + padding; } else { cur_x = padding; cur_y += tile_size + padding; } idx++; l = l->next; } ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size)); cairo_surface_destroy (surface); cairo_destroy (cr); g_object_unref (context); return ret_val; }
gboolean expose_handler (GtkWidget* window, cairo_t* cr, gpointer data) { cairo_pattern_t* pattern = NULL; cairo_pattern_t* mask = NULL; // clear and render drop-shadow and bubble-background cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (g_distance < 1.0f) { tile_paint (g_tile, cr, 0.0f, 0.0f, g_distance, 1.0f - g_distance); cairo_push_group (cr); tile_paint (g_text, cr, 2 * BUBBLE_SHADOW_SIZE, BUBBLE_SHADOW_SIZE - g_offset, g_distance, 1.0f - g_distance); pattern = cairo_pop_group (cr); cairo_set_source (cr, pattern); mask = cairo_pattern_create_linear (0.0f, 2 * BUBBLE_SHADOW_SIZE, 0.0f, BUBBLE_HEIGHT); cairo_pattern_add_color_stop_rgba (mask, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); cairo_pattern_add_color_stop_rgba (mask, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (mask, 0.8f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (mask, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); cairo_mask (cr, mask); cairo_pattern_destroy (mask); cairo_pattern_destroy (pattern); gtk_window_set_opacity (GTK_WINDOW (window), 0.3f + g_distance * 0.7f); } else { tile_paint (g_tile, cr, 0.0f, 0.0f, g_distance, 0.0f); cairo_push_group (cr); tile_paint (g_text, cr, 2 * BUBBLE_SHADOW_SIZE, BUBBLE_SHADOW_SIZE - g_offset, g_distance, 0.0f); pattern = cairo_pop_group (cr); cairo_set_source (cr, pattern); mask = cairo_pattern_create_linear (0.0f, 2 * BUBBLE_SHADOW_SIZE, 0.0f, BUBBLE_HEIGHT); cairo_pattern_add_color_stop_rgba (mask, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); cairo_pattern_add_color_stop_rgba (mask, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (mask, 0.8f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (mask, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); cairo_mask (cr, mask); cairo_pattern_destroy (pattern); gtk_window_set_opacity (GTK_WINDOW (window), 1.0f); } return TRUE; }
static void photos_print_operation_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr) { PhotosPrintOperation *self = PHOTOS_PRINT_OPERATION (operation); GeglRectangle bbox; GdkPixbuf *pixbuf = NULL; GtkPageSetup *page_setup; cairo_t *cr; gdouble dpi_x; gdouble dpi_y; gdouble page_height; gdouble page_width; gdouble scale_factor_n; gdouble x0; gdouble y0; scale_factor_n = self->scale_factor / 100.0; bbox = gegl_node_get_bounding_box (self->node); dpi_x = gtk_print_context_get_dpi_x (context); dpi_y = gtk_print_context_get_dpi_x (context); switch (self->unit) { case GTK_UNIT_INCH: x0 = self->left_margin * dpi_x; y0 = self->top_margin * dpi_y; break; case GTK_UNIT_MM: x0 = self->left_margin * dpi_x / 25.4; y0 = self->top_margin * dpi_y / 25.4; break; case GTK_UNIT_NONE: case GTK_UNIT_POINTS: default: g_assert_not_reached (); } cr = gtk_print_context_get_cairo_context (context); cairo_translate (cr, x0, y0); page_setup = gtk_print_context_get_page_setup (context); page_width = gtk_page_setup_get_page_width (page_setup, GTK_UNIT_POINTS); page_height = gtk_page_setup_get_page_height (page_setup, GTK_UNIT_POINTS); /* This is both a workaround for a bug in cairo's PDF backend, and * a way to ensure we are not printing outside the page margins. */ cairo_rectangle (cr, 0, 0, MIN (bbox.width * scale_factor_n, page_width), MIN (bbox.height * scale_factor_n, page_height)); cairo_clip (cr); cairo_scale (cr, scale_factor_n, scale_factor_n); pixbuf = photos_utils_create_pixbuf_from_node (self->node); if (pixbuf == NULL) goto out; gdk_cairo_set_source_pixbuf (cr, pixbuf, 0.0, 0.0); cairo_paint (cr); out: g_clear_object (&pixbuf); }
tile_t* setup_text_tile (const cairo_font_options_t* font_opts, gdouble dpi, gint w, gint h) { tile_t* tile = NULL; cairo_status_t status; cairo_surface_t* surface = NULL; cairo_surface_t* text = NULL; cairo_surface_t* shadow = NULL; cairo_t* cr; gdouble width = (gdouble) w; gdouble height = (gdouble) h; raico_blur_t* blur = NULL; cairo_pattern_t* pattern = NULL; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); status = cairo_surface_status (surface); if (status != CAIRO_STATUS_SUCCESS) g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); cr = cairo_create (surface); status = cairo_status (cr); if (status != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); } // clear and render drop-shadow and bubble-background cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); text = render_text_to_surface ( "After an evening of hacking at the" " Fataga hotel here at GUADEC I " "can present you even text-scroll " "with blur-cache and fade-out mask" " and I dedicate this to Behdad who" " sadly burst his upper lip during " "the evening and had to go to the " "hospital. Some spanish KDE-folks " "kindly accompanied him to help out" " with translation. True collaboration!\0", width, height, font_opts, dpi); shadow = render_text_to_surface ( "After an evening of hacking at the" " Fataga hotel here at GUADEC I " "can present you even text-scroll " "with blur-cache and fade-out mask" " and I dedicate this to Behdad who" " sadly burst his upper lip during " "the evening and had to go to the " "hospital. Some spanish KDE-folks " "kindly accompanied him to help out" " with translation. True collaboration!\0", width, height, font_opts, dpi); // create and setup blur blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, 4); // now blur it raico_blur_apply (blur, shadow); // blur no longer needed raico_blur_destroy (blur); cairo_push_group (cr); cairo_set_source_surface (cr, shadow, 0.0f, 0.0f); cairo_paint (cr); pattern = cairo_pop_group (cr); cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 1.0f); cairo_mask (cr, pattern); cairo_surface_destroy (shadow); cairo_pattern_destroy (pattern); cairo_set_source_surface (cr, text, 0.0f, 0.0f); cairo_paint (cr); cairo_destroy (cr); cairo_surface_destroy (text); tile = tile_new (surface, 6); cairo_surface_destroy (surface); return tile; }
void process (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, void *ivoid, void *ovoid, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out) { dt_iop_watermark_data_t *data = (dt_iop_watermark_data_t *)piece->data; float *in = (float *)ivoid; float *out = (float *)ovoid; const int ch = piece->colors; /* Load svg if not loaded */ gchar *svgdoc = _watermark_get_svgdoc (self, data, &piece->pipe->image); if (!svgdoc) { memcpy(ovoid, ivoid, sizeof(float)*ch*roi_out->width*roi_out->height); return; } /* create the rsvghandle from parsed svg data */ GError *error = NULL; RsvgHandle *svg = rsvg_handle_new_from_data ((const guint8 *)svgdoc,strlen (svgdoc),&error); g_free (svgdoc); if (!svg || error) { memcpy(ovoid, ivoid, sizeof(float)*ch*roi_out->width*roi_out->height); return; } /* get the dimension of svg */ RsvgDimensionData dimension; rsvg_handle_get_dimensions (svg,&dimension); /* calculate aligment of watermark */ const float iw=piece->buf_in.width*roi_out->scale; const float ih=piece->buf_in.height*roi_out->scale; float scale=1.0; if ((dimension.width/dimension.height)>1.0) scale = iw/dimension.width; else scale = ih/dimension.height; scale *= (data->scale/100.0); /* setup stride for performance */ int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,roi_out->width); /* create cairo memory surface */ guint8 *image= (guint8 *)g_malloc (stride*roi_out->height); memset (image,0,stride*roi_out->height); cairo_surface_t *surface = cairo_image_surface_create_for_data (image,CAIRO_FORMAT_ARGB32,roi_out->width,roi_out->height,stride); if (cairo_surface_status(surface)!= CAIRO_STATUS_SUCCESS) { // fprintf(stderr,"Cairo surface error: %s\n",cairo_status_to_string(cairo_surface_status(surface))); g_free (image); memcpy(ovoid, ivoid, sizeof(float)*ch*roi_out->width*roi_out->height); return; } /* create cairo context and setup transformation/scale */ cairo_t *cr = cairo_create (surface); float ty=0,tx=0; if( data->alignment >=0 && data->alignment <3) // Align to verttop ty=0; else if( data->alignment >=3 && data->alignment <6) // Align to vertcenter ty=(ih/2.0)-((dimension.height*scale)/2.0); else if( data->alignment >=6 && data->alignment <9) // Align to vertbottom ty=ih-(dimension.height*scale); if( data->alignment == 0 || data->alignment == 3 || data->alignment==6 ) tx=0; else if( data->alignment == 1 || data->alignment == 4 || data->alignment==7 ) tx=(iw/2.0)-((dimension.width*scale)/2.0); else if( data->alignment == 2 || data->alignment == 5 || data->alignment==8 ) tx=iw-(dimension.width*scale); /* translate to position */ cairo_translate (cr,-roi_in->x,-roi_in->y); cairo_translate (cr,tx,ty); /* scale */ cairo_scale (cr,scale,scale); /* translate x and y offset */ cairo_translate (cr,data->xoffset*iw/roi_out->scale,data->yoffset*ih/roi_out->scale); /* render svg into surface*/ dt_pthread_mutex_lock(&darktable.plugin_threadsafe); rsvg_handle_render_cairo (svg,cr); dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); /* ensure that all operations on surface finishing up */ cairo_surface_flush (surface); /* render surface on output */ guint8 *sd = image; float opacity = data->opacity/100.0; /* #ifdef _OPENMP #pragma omp parallel for default(none) shared(roi_out, in, out,sd,opacity) schedule(static) #endif */ for(int j=0; j<roi_out->height; j++) for(int i=0; i<roi_out->width; i++) { float alpha = (sd[3]/255.0)*opacity; out[0] = ((1.0-alpha)*in[0]) + (alpha*(sd[2]/255.0)); out[1] = ((1.0-alpha)*in[1]) + (alpha*(sd[1]/255.0)); out[2] = ((1.0-alpha)*in[2]) + (alpha*(sd[0]/255.0)); out[3] = in[3]; out+=ch; in+=ch; sd+=4; } /* clean up */ cairo_surface_destroy (surface); g_object_unref (svg); g_free (image); }
void icCanvasManager::CanvasView::draw_tiles(cairo_t* ctxt, cairo_rectangle_t* rect) { float square_size = std::max(rect->width, rect->height); int lowest_zoom = std::floor(31 - log2(square_size * this->zoom)); int highest_zoom = this->highest_zoom(); int canvas_x_min = this->x_scroll + (rect->x * this->zoom), canvas_x_max = this->x_scroll + (rect->x + rect->width) * this->zoom, canvas_y_min = this->y_scroll + (rect->y * this->zoom), canvas_y_max = this->y_scroll + (rect->y + rect->height) * this->zoom; //Phase 1: Look up tiles from cache icCanvasManager::TileCache::TileCacheQuery qu1; qu1.query_x_gte(canvas_x_min); qu1.query_x_lt(canvas_x_max); qu1.query_y_gte(canvas_y_min); qu1.query_y_lt(canvas_y_max); qu1.query_size_gte(lowest_zoom); qu1.query_size_lt(highest_zoom+2); qu1.query_time_limit(1); auto tilecache = this->drawing->get_tilecache(); auto tilelist = tilecache->execute(qu1); auto begin = tilelist.begin(), end = tilelist.end(); RefPtr<DisplaySuite> currentDS = tilecache->display_suite(), cairoDS = dynamic_cast<icCanvasManager::Cairo::DisplaySuite*>((icCanvasManager::DisplaySuite*)currentDS); bool must_copy = false, must_copy_direct = false; if (!cairoDS) { cairoDS = new icCanvasManager::Cairo::DisplaySuite(); must_copy = true; must_copy_direct = cairoDS->can_direct_transfer(currentDS); } //Phase 2: Copy/scale tiles onto view for (; begin != end; begin++) { auto &tile = tilecache->tile_at(*begin); cairo_surface_t* image; if (must_copy) { if (must_copy_direct) { image = (cairo_surface_t*)cairoDS->direct_transfer(currentDS, tile.current_tile, true); } else { auto generic_data = currentDS->export_tile(tile.current_tile); image = (cairo_surface_t*)cairoDS->import_tile(generic_data); delete[] generic_data; } } else { image = (cairo_surface_t*)tile.current_tile; } cairo_save(ctxt); auto tile_size = UINT32_MAX >> tile.size; auto tile_wndsize = tile_size / this->zoom; auto scale_factor = tile_wndsize / (float)icCanvasManager::TileCache::TILE_SIZE; int txpos, typos; //yes I know, typos this->coordToWindowspace(tile.x - tile_size / 2, tile.y - tile_size / 2, &txpos, &typos); cairo_translate(ctxt, (double)txpos, (double)typos); cairo_scale(ctxt, scale_factor, scale_factor); cairo_move_to(ctxt, 0, 0); cairo_line_to(ctxt, icCanvasManager::TileCache::TILE_SIZE, 0); cairo_line_to(ctxt, icCanvasManager::TileCache::TILE_SIZE, icCanvasManager::TileCache::TILE_SIZE); cairo_line_to(ctxt, 0, icCanvasManager::TileCache::TILE_SIZE); cairo_line_to(ctxt, 0, 0); cairo_set_operator(ctxt, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(ctxt, 1.0, 1.0, 1.0, 1.0); cairo_fill_preserve(ctxt); cairo_set_operator(ctxt, CAIRO_OPERATOR_OVER); cairo_set_source_surface(ctxt, image, 0, 0); cairo_fill(ctxt); cairo_restore(ctxt); if (must_copy) { cairoDS->free_tile((DisplaySuiteTILE)image); } } };
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 draw_shadow (cairo_t* cr, gdouble width, gdouble height, gint shadow_radius, gint corner_radius) { cairo_surface_t* tmp_surface = NULL; cairo_surface_t* new_surface = NULL; cairo_pattern_t* pattern = NULL; cairo_t* cr_surf = NULL; cairo_matrix_t matrix; raico_blur_t* blur = NULL; tmp_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4 * shadow_radius, 4 * shadow_radius); if (cairo_surface_status (tmp_surface) != CAIRO_STATUS_SUCCESS) return; cr_surf = cairo_create (tmp_surface); if (cairo_status (cr_surf) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); return; } cairo_scale (cr_surf, 1.0f, 1.0f); cairo_set_operator (cr_surf, CAIRO_OPERATOR_CLEAR); cairo_paint (cr_surf); cairo_set_operator (cr_surf, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr_surf, 0.0f, 0.0f, 0.0f, 0.75f); cairo_arc (cr_surf, 2 * shadow_radius, 2 * shadow_radius, 2.0f * corner_radius, 0.0f, 360.0f * (G_PI / 180.f)); cairo_fill (cr_surf); cairo_destroy (cr_surf); // create and setup blur blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, shadow_radius); // now blur it raico_blur_apply (blur, tmp_surface); // blur no longer needed raico_blur_destroy (blur); new_surface = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (tmp_surface), cairo_image_surface_get_format (tmp_surface), cairo_image_surface_get_width (tmp_surface) / 2, cairo_image_surface_get_height (tmp_surface) / 2, cairo_image_surface_get_stride (tmp_surface)); pattern = cairo_pattern_create_for_surface (new_surface); if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); return; } // top left cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_source (cr, pattern); cairo_rectangle (cr, 0.0f, 0.0f, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // bottom left cairo_matrix_init_scale (&matrix, 1.0f, -1.0f); cairo_matrix_translate (&matrix, 0.0f, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 0.0f, 2 * shadow_radius, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // top right cairo_matrix_init_scale (&matrix, -1.0f, 1.0f); cairo_matrix_translate (&matrix, -width, 0.0f); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, width - 2 * shadow_radius, 0.0f, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // bottom right cairo_matrix_init_scale (&matrix, -1.0f, -1.0f); cairo_matrix_translate (&matrix, -width, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 2 * shadow_radius, height - 2 * shadow_radius, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // clean up cairo_pattern_destroy (pattern); cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); }
void gui_init(dt_lib_module_t *self) { char filename[PATH_MAX] = { 0 }; char datadir[PATH_MAX] = { 0 }; /* initialize ui widgets */ dt_lib_darktable_t *d = (dt_lib_darktable_t *)g_malloc0(sizeof(dt_lib_darktable_t)); self->data = (void *)d; /* create drawing area */ self->widget = gtk_event_box_new(); /* connect callbacks */ g_signal_connect(G_OBJECT(self->widget), "draw", G_CALLBACK(_lib_darktable_draw_callback), self); g_signal_connect(G_OBJECT(self->widget), "button-press-event", G_CALLBACK(_lib_darktable_button_press_callback), self); /* create a cairo surface of dt icon */ char *logo; dt_logo_season_t season = get_logo_season(); if(season != DT_LOGO_SEASON_NONE) logo = g_strdup_printf("%%s/pixmaps/idbutton-%d.%%s", (int)season); else logo = g_strdup("%s/pixmaps/idbutton.%s"); dt_loc_get_datadir(datadir, sizeof(datadir)); snprintf(filename, sizeof(filename), logo, datadir, "svg"); // first we try the SVG { GError *error = NULL; RsvgHandle *svg = rsvg_handle_new_from_file(filename, &error); if(!svg || error) { fprintf(stderr, "warning: can't load darktable logo from SVG file `%s', falling back to PNG version\n%s\n", filename, error->message); g_error_free(error); error = NULL; goto png_fallback; } cairo_surface_t *surface; cairo_t *cr; RsvgDimensionData dimension; rsvg_handle_get_dimensions(svg, &dimension); int width = DT_PIXEL_APPLY_DPI(dimension.width) * darktable.gui->ppd, height = DT_PIXEL_APPLY_DPI(dimension.height) * darktable.gui->ppd; int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); d->image_buffer = (guint8 *)calloc(stride * height, sizeof(guint8)); surface = dt_cairo_image_surface_create_for_data(d->image_buffer, CAIRO_FORMAT_ARGB32, width, height, stride); if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { free(d->image_buffer); d->image_buffer = NULL; g_object_unref(svg); fprintf(stderr, "warning: can't load darktable logo from SVG file `%s', falling back to PNG version\n", filename); goto png_fallback; } cr = cairo_create(surface); cairo_scale(cr, darktable.gui->dpi_factor, darktable.gui->dpi_factor); rsvg_handle_render_cairo(svg, cr); cairo_destroy(cr); cairo_surface_flush(surface); d->image = surface; g_object_unref(svg); } goto done; png_fallback: // let's fall back to the PNG { cairo_surface_t *surface; cairo_t *cr; snprintf(filename, sizeof(filename), logo, datadir, "png"); surface = cairo_image_surface_create_from_png(filename); if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "warning: can't load darktable logo from PNG file `%s'\n", filename); d->image = NULL; goto done; } int png_width = cairo_image_surface_get_width(surface), png_height = cairo_image_surface_get_height(surface); // blow up the PNG. Ugly, but at least it has the correct size afterwards :-/ int width = DT_PIXEL_APPLY_DPI(png_width) * darktable.gui->ppd, height = DT_PIXEL_APPLY_DPI(png_height) * darktable.gui->ppd; int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); d->image_buffer = (guint8 *)calloc(stride * height, sizeof(guint8)); d->image = dt_cairo_image_surface_create_for_data(d->image_buffer, CAIRO_FORMAT_ARGB32, width, height, stride); if(cairo_surface_status(d->image) != CAIRO_STATUS_SUCCESS) { free(d->image_buffer); d->image_buffer = NULL; cairo_surface_destroy(surface); fprintf(stderr, "warning: can't load darktable logo from PNG file `%s'\n", filename); d->image = NULL; goto done; } cr = cairo_create(d->image); cairo_rectangle(cr, 0, 0, width, height); cairo_scale(cr, darktable.gui->dpi_factor, darktable.gui->dpi_factor); cairo_set_source_surface(cr, surface, 0, 0); cairo_fill(cr); cairo_destroy(cr); cairo_surface_flush(d->image); cairo_surface_destroy(surface); } done: g_free(logo); d->image_width = d->image ? dt_cairo_image_surface_get_width(d->image) : 0; d->image_height = d->image ? dt_cairo_image_surface_get_height(d->image) : 0; /* set size of drawing area */ gtk_widget_set_size_request(self->widget, d->image_width + (int)DT_PIXEL_APPLY_DPI(180), d->image_height + (int)DT_PIXEL_APPLY_DPI(8)); }
static void rotated_text_draw (GtkDrawingArea *da, cairo_t *cr, int width, int height, gpointer data) { #define RADIUS 150 #define N_WORDS 5 #define FONT "Serif 18" PangoContext *context; PangoLayout *layout; PangoFontDescription *desc; cairo_pattern_t *pattern; PangoAttrList *attrs; double device_radius; int i; /* Create a cairo context and set up a transformation matrix so that the user * space coordinates for the centered square where we draw are [-RADIUS, RADIUS], * [-RADIUS, RADIUS]. * We first center, then change the scale. */ device_radius = MIN (width, height) / 2.; cairo_translate (cr, device_radius + (width - 2 * device_radius) / 2, device_radius + (height - 2 * device_radius) / 2); cairo_scale (cr, device_radius / RADIUS, device_radius / RADIUS); /* Create and a subtle gradient source and use it. */ pattern = cairo_pattern_create_linear (-RADIUS, -RADIUS, RADIUS, RADIUS); cairo_pattern_add_color_stop_rgb (pattern, 0., .5, .0, .0); cairo_pattern_add_color_stop_rgb (pattern, 1., .0, .0, .5); cairo_set_source (cr, pattern); /* Create a PangoContext and set up our shape renderer */ context = gtk_widget_create_pango_context (GTK_WIDGET (da)); pango_cairo_context_set_shape_renderer (context, fancy_shape_renderer, NULL, NULL); /* Create a PangoLayout, set the text, font, and attributes */ layout = pango_layout_new (context); pango_layout_set_text (layout, text, -1); desc = pango_font_description_from_string (FONT); pango_layout_set_font_description (layout, desc); attrs = create_fancy_attr_list_for_layout (layout); pango_layout_set_attributes (layout, attrs); pango_attr_list_unref (attrs); /* Draw the layout N_WORDS times in a circle */ for (i = 0; i < N_WORDS; i++) { int width, height; /* Inform Pango to re-layout the text with the new transformation matrix */ pango_cairo_update_layout (cr, layout); pango_layout_get_pixel_size (layout, &width, &height); cairo_move_to (cr, - width / 2, - RADIUS * .9); pango_cairo_show_layout (cr, layout); /* Rotate for the next turn */ cairo_rotate (cr, G_PI*2 / N_WORDS); } /* free the objects we created */ pango_font_description_free (desc); g_object_unref (layout); g_object_unref (context); cairo_pattern_destroy (pattern); }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_zonesystem_gui_data_t)); dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; g->in_preview_buffer = g->out_preview_buffer = NULL; g->is_dragging = FALSE; g->hilite_zone = FALSE; g->preview_width=g->preview_height = 0; g->mouse_over_output_zones = FALSE; dt_pthread_mutex_init(&g->lock, NULL); self->widget = gtk_vbox_new (FALSE,DT_GUI_IOP_MODULE_CONTROL_SPACING); /* create the zone preview widget */ const int panel_width = dt_conf_get_int("panel_width") * 0.8; g->preview = gtk_drawing_area_new(); g_signal_connect (G_OBJECT (g->preview), "expose-event", G_CALLBACK (dt_iop_zonesystem_preview_expose), self); gtk_widget_add_events (GTK_WIDGET (g->preview), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK); gtk_widget_set_size_request(g->preview, panel_width, panel_width); /* create the zonesystem bar widget */ g->zones = gtk_drawing_area_new(); g_object_set (GTK_OBJECT(g->zones), "tooltip-text", _("lightness zones\nuse mouse scrollwheel to change the number of zones\nleft-click on a border to create a marker\nright-click on a marker to delete it"), (char *)NULL); g_signal_connect (G_OBJECT (g->zones), "expose-event", G_CALLBACK (dt_iop_zonesystem_bar_expose), self); g_signal_connect (G_OBJECT (g->zones), "motion-notify-event", G_CALLBACK (dt_iop_zonesystem_bar_motion_notify), self); g_signal_connect (G_OBJECT (g->zones), "leave-notify-event", G_CALLBACK (dt_iop_zonesystem_bar_leave_notify), self); g_signal_connect (G_OBJECT (g->zones), "button-press-event", G_CALLBACK (dt_iop_zonesystem_bar_button_press), self); g_signal_connect (G_OBJECT (g->zones), "button-release-event", G_CALLBACK (dt_iop_zonesystem_bar_button_release), self); g_signal_connect (G_OBJECT (g->zones), "scroll-event", G_CALLBACK (dt_iop_zonesystem_bar_scrolled), self); gtk_widget_add_events (GTK_WIDGET (g->zones), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK); gtk_widget_set_size_request(g->zones, -1, DT_PIXEL_APPLY_DPI(40)); gtk_box_pack_start (GTK_BOX (self->widget),g->preview,TRUE,TRUE,0); gtk_box_pack_start (GTK_BOX (self->widget),g->zones,TRUE,TRUE,0); /* add signal handler for preview pipe finish to redraw the preview */ dt_control_signal_connect(darktable.signals, DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED, G_CALLBACK(_iop_zonesystem_redraw_preview_callback), self); /* load the dt logo as a brackground */ g->image = NULL; g->image_buffer = NULL; g->image_width = 0; g->image_height = 0; char filename[PATH_MAX]; char datadir[PATH_MAX]; const char *logo = is_it_xmas()?"%s/pixmaps/idbutton-2.svg":"%s/pixmaps/idbutton.svg"; dt_loc_get_datadir(datadir, sizeof(datadir)); snprintf(filename, sizeof(filename), logo, datadir); RsvgHandle *svg = rsvg_handle_new_from_file(filename, NULL); if(svg) { cairo_surface_t *surface; cairo_t *cr; RsvgDimensionData dimension; rsvg_handle_get_dimensions(svg, &dimension); float svg_size = MAX(dimension.width, dimension.height); float final_size = panel_width * 0.75; float factor = final_size / svg_size; float final_width = dimension.width * factor, final_height = dimension.height * factor; int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, final_width); g->image_buffer = (guint8 *)calloc(stride * final_height, sizeof(guint8)); surface = cairo_image_surface_create_for_data(g->image_buffer, CAIRO_FORMAT_ARGB32, final_width, final_height, stride); if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { free(g->image_buffer); g->image_buffer = NULL; } else { cr = cairo_create(surface); cairo_scale(cr, factor, factor); rsvg_handle_render_cairo(svg, cr); cairo_surface_flush(surface); g->image = surface; g->image_width = final_width; g->image_height = final_height; } g_object_unref(svg); } }