cairo_surface_t * CairoSurface::Cairo () { return cairo_surface_create_for_rectangle (surface, 0, 0, size[0], size[1]); }
static cairo_test_status_t test_cairo_surface_create_for_rectangle (cairo_surface_t *surface) { cairo_surface_t *similar; similar = cairo_surface_create_for_rectangle (surface, 1, 1, 8, 8); cairo_surface_destroy (similar); return CAIRO_TEST_SUCCESS; }
void workrave_timerbox_update_time_bars(WorkraveTimerbox *self, cairo_t *cr) { WorkraveTimerboxPrivate *priv = self->priv; if (priv->enabled) { int x = 0, y = 0; int bar_width, bar_height; workrave_timebar_get_dimensions(priv->slot_to_time_bar[0], &bar_width, &bar_height); int icon_width = gdk_pixbuf_get_width(priv->break_to_icon[0]); int icon_height = gdk_pixbuf_get_height(priv->break_to_icon[0]); int icon_bar_width = icon_width + 2 * PADDING_X + bar_width; int icon_dy = 0; int bar_dy = 0; if (bar_height > icon_height) { icon_dy = (bar_height - icon_height + 1) / 2; } else { bar_dy = (icon_height - bar_height + 1) / 2; } for (int i = 0; i < BREAK_ID_SIZEOF; i++) { WorkraveBreakId bid = priv->slot_to_break[i]; if (bid != BREAK_ID_NONE) { WorkraveTimebar *bar = priv->slot_to_time_bar[bid]; cairo_surface_t *surface = cairo_get_target(cr); cairo_surface_t *bar_surface = cairo_surface_create_for_rectangle(surface, x+icon_width+PADDING_X, y + bar_dy, bar_width, bar_height); cairo_t *bar_cr = cairo_create(bar_surface); workrave_timebar_draw(bar, bar_cr); cairo_surface_destroy(bar_surface); cairo_destroy(bar_cr); gdk_cairo_set_source_pixbuf(cr, priv->break_to_icon[bid], x, y + icon_dy); cairo_fill(cr); cairo_paint(cr); x += icon_bar_width + 2 * PADDING_X; } } } }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_surface_t *region[5]; const char *text = "Cairo"; int i; cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); cairo_set_source_rgb (cr, 0, 0, 0); for (i = 0; i < 5; i++) { cairo_t *cr_region; cairo_text_extents_t extents; char buf[2] = { text[i], '\0' }; region[i] = cairo_surface_create_for_rectangle (cairo_get_target (cr), 20 * i, 0, 20, 20); cr_region = cairo_create (region[i]); cairo_surface_destroy (region[i]); cairo_select_font_face (cr_region, "@cairo:", CAIRO_FONT_WEIGHT_NORMAL, CAIRO_FONT_SLANT_NORMAL); cairo_set_font_size (cr_region, 20); cairo_text_extents (cr_region, buf, &extents); cairo_move_to (cr_region, 10 - (extents.width/2 + extents.x_bearing), 10 - (extents.height/2 + extents.y_bearing)); cairo_show_text (cr_region, buf); region[i] = cairo_surface_reference (cairo_get_target (cr_region)); cairo_destroy (cr_region); } for (i = 0; i < 5; i++) { cairo_set_source_surface (cr, region[5-i-1], 20 * i, 20); cairo_paint (cr); } for (i = 0; i < 5; i++) { cairo_set_source_surface (cr, region[5-i-1], 20 * i, 40); cairo_paint_with_alpha (cr, .5); } for (i = 0; i < 5; i++) cairo_surface_destroy (region[i]); return CAIRO_TEST_SUCCESS; }
static int create_for_rectangle(lua_State *L) { SurfaceUserdata *surface; cairo_surface_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_SURFACE); double x = luaL_checknumber(L, 2); double y = luaL_checknumber(L, 3); double width = luaL_checknumber(L, 4); double height = luaL_checknumber(L, 5); luaL_argcheck(L, width >= 0, 3, "surface width cannot be negative"); luaL_argcheck(L, height >= 0, 4, "surface height cannot be negative"); surface = create_surface_userdata(L); surface->surface = cairo_surface_create_for_rectangle(*obj, x, y, width, height); return 1; }
static void dv_export_viewports_to_img_r(dv_viewport_t * VP, cairo_surface_t * surface, double x, double y) { if (!VP) { return; } else if (!VP->split) { /* resize to remove ruler areas */ double surface_width = VP->vpw;// - 2 * DVG->opts.ruler_width; double surface_height = VP->vph;// - 2 * DVG->opts.ruler_width; cairo_surface_t * surface_child = cairo_surface_create_for_rectangle(surface, x, y, surface_width, surface_height); dv_viewport_export_to_surface(VP, surface_child); } else { double w1, h1; dv_export_viewports_get_size_r(VP->vp1, &w1, &h1); if (VP->orientation == GTK_ORIENTATION_HORIZONTAL) { dv_export_viewports_to_img_r(VP->vp1, surface, x, y); dv_export_viewports_to_img_r(VP->vp2, surface, x + w1, y); } else { dv_export_viewports_to_img_r(VP->vp1, surface, x, y); dv_export_viewports_to_img_r(VP->vp2, surface, x, y + h1); } } }
static void brush_end_element (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error) { GXPSBrush *brush = (GXPSBrush *)user_data; if (strcmp (element_name, "SolidColorBrush") == 0) { } else if (strcmp (element_name, "LinearGradientBrush") == 0) { g_markup_parse_context_pop (context); } else if (strcmp (element_name, "RadialGradientBrush") == 0) { g_markup_parse_context_pop (context); } else if (strcmp (element_name, "ImageBrush") == 0) { GXPSBrushImage *brush_image; GXPSImage *image; GError *err = NULL; brush_image = g_markup_parse_context_pop (context); GXPS_DEBUG (g_message ("set_fill_pattern (image)")); image = gxps_page_get_image (brush->ctx->page, brush_image->image_uri, &err); if (image) { cairo_matrix_t matrix; gdouble x_scale, y_scale; cairo_surface_t *clip_surface; /* viewbox units is 1/96 inch, convert to pixels */ brush_image->viewbox.x *= image->res_x / 96; brush_image->viewbox.y *= image->res_y / 96; brush_image->viewbox.width *= image->res_x / 96; brush_image->viewbox.height *= image->res_y / 96; clip_surface = cairo_surface_create_for_rectangle (image->surface, brush_image->viewbox.x, brush_image->viewbox.y, brush_image->viewbox.width, brush_image->viewbox.height); brush_image->brush->pattern = cairo_pattern_create_for_surface (clip_surface); cairo_pattern_set_extend (brush_image->brush->pattern, brush_image->extend); x_scale = brush_image->viewport.width / brush_image->viewbox.width; y_scale = brush_image->viewport.height / brush_image->viewbox.height; cairo_matrix_init (&matrix, x_scale, 0, 0, y_scale, brush_image->viewport.x, brush_image->viewport.y); cairo_matrix_multiply (&matrix, &matrix, &brush_image->matrix); cairo_matrix_invert (&matrix); cairo_pattern_set_matrix (brush_image->brush->pattern, &matrix); if (brush->opacity != 1.0) { cairo_push_group (brush->ctx->cr); cairo_set_source (brush->ctx->cr, brush_image->brush->pattern); cairo_pattern_destroy (brush_image->brush->pattern); cairo_paint_with_alpha (brush->ctx->cr, brush->opacity); brush_image->brush->pattern = cairo_pop_group (brush->ctx->cr); } if (cairo_pattern_status (brush_image->brush->pattern)) { GXPS_DEBUG (g_debug ("%s", cairo_status_to_string (cairo_pattern_status (brush_image->brush->pattern)))); cairo_pattern_destroy (brush_image->brush->pattern); brush_image->brush->pattern = NULL; } cairo_surface_destroy (clip_surface); } else if (err) { GXPS_DEBUG (g_debug ("%s", err->message)); g_error_free (err); } gxps_brush_image_free (brush_image); } else if (strcmp (element_name, "VisualBrush") == 0) { GXPSRenderContext *sub_ctx; GXPSBrushVisual *visual; cairo_matrix_t matrix; sub_ctx = g_markup_parse_context_pop (context); visual = sub_ctx->visual; g_slice_free (GXPSRenderContext, sub_ctx); GXPS_DEBUG (g_message ("set_fill_pattern (visual)")); visual->brush->pattern = cairo_pop_group (brush->ctx->cr); /* Undo the clip */ cairo_restore (brush->ctx->cr); cairo_pattern_set_extend (visual->brush->pattern, visual->extend); cairo_pattern_get_matrix (visual->brush->pattern, &matrix); cairo_matrix_multiply (&matrix, &visual->matrix, &matrix); cairo_pattern_set_matrix (visual->brush->pattern, &matrix); if (cairo_pattern_status (visual->brush->pattern)) { GXPS_DEBUG (g_debug ("%s", cairo_status_to_string (cairo_pattern_status (visual->brush->pattern)))); cairo_pattern_destroy (visual->brush->pattern); visual->brush->pattern = NULL; } gxps_brush_visual_free (visual); } else { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_UNKNOWN_ELEMENT, element_name, NULL, NULL, error); } }
/* We double buffer the image. It looks nice and it enables * grabbing the graph with the pointer and translating it. * We draw on our own larger surface and then copy part of that * to the gdk surface. * * We assume that this function is drawing to an exposed/showing * drawing area, so the status update will reflect the current * exposed/showing drawing area. */ void qp_graph_draw(struct qp_graph *gr, cairo_t *gdk_cr) { GtkAllocation allocation; if(gr->waiting_to_resize_draw && !gr->qp->shape) { //WARN("gr=%p gr->name=\"%s\" gr->ref_count=%d\n", gr, gr->name, gr->ref_count); cairo_set_source_rgba(gdk_cr, gr->background_color.r, gr->background_color.g, gr->background_color.b, gr->background_color.a); cairo_paint(gdk_cr); g_idle_add_full(G_PRIORITY_LOW, idle_callback, gr, NULL); /* fight qp_graph_destroy() race condition with flag */ ++gr->ref_count; /* We draw after the other widgets are drawn, in case drawing * takes a long time. This waiting also gives a chance * for the watch cursor to show. But that seems to only * show if the window had focus at the right time. */ return; } gtk_widget_get_allocation(gr->drawing_area, &allocation); if(gr->pixbuf_needs_draw) { cairo_t *db_cr; /* double buffer cr */ db_cr = cairo_create(gr->pixbuf_surface); graph_draw(gr, db_cr, gr->pixbuf_x, gr->pixbuf_y, gr->pixbuf_width, gr->pixbuf_height); cairo_destroy(db_cr); // debuging //cairo_surface_write_to_png(gr->pixbuf_surface, "x.png"); qp_win_set_status(gr->qp); } /* the GTK cairo_t *gdk_cr has no alpha bits so all the * alpha drawn to it will be smushed. */ //WARN("content=0x%lx\n", (unsigned long)cairo_get_target(gdk_cr)); if(!gr->qp->shape) { /* Not using the shape X11 extension */ /* This is where we go from the back buffer to the drawing area */ draw_from_pixbuf(gdk_cr, gr, allocation.width, allocation.height); if(gr->draw_zoom_box == 1) draw_zoom_box(gdk_cr, gr); if(gr->draw_value_pick) draw_value_pick_line(gdk_cr, gr, allocation.width, allocation.height); if(gr->pixbuf_needs_draw) { gdk_window_set_cursor(gtk_widget_get_window(gr->qp->window), NULL); gr->pixbuf_needs_draw = 0; // gr->qp->wait_warning_showing = 0; } } else { /* Use the X11 shape extension */ /* TODO: This is a resource pig. Fix it. */ cairo_region_t *reg_draw_area, *window_region; /* empty flag */ int empty; cairo_surface_t *mask_surface; GtkAllocation all; /* Make sure the surface is up to date */ //cairo_surface_flush(gr->pixbuf_surface); /* make a sub surface that is the size of the graph drawing area */ mask_surface = cairo_surface_create_for_rectangle(gr->pixbuf_surface, INT(gr->pixbuf_x+gr->grab_x), INT(gr->pixbuf_y+gr->grab_y), allocation.width, allocation.height); reg_draw_area = get_cairo_region_create_from_surface(gr, mask_surface, allocation.width, allocation.height); cairo_surface_destroy(mask_surface); cairo_region_translate(reg_draw_area, allocation.x, allocation.y); gtk_widget_get_allocation(gr->qp->window, &all); all.x = all.y = 0; window_region = cairo_region_create_rectangle(&all); cairo_region_subtract_rectangle(window_region, &allocation); empty = cairo_region_is_empty(reg_draw_area); if(!empty) cairo_region_union(window_region, reg_draw_area); cairo_region_destroy(reg_draw_area); /* window_region is a region with a hole in it the * size of the drawing area with the graph and grid added back. */ if(gr->draw_zoom_box && !empty) { cairo_rectangle_int_t rec; rec.x = allocation.x + gr->z_x; rec.y = allocation.y + gr->z_y; rec.width = gr->z_w; rec.height = gr->z_h; /* regions do not like negitive values or * maybe shapes do not like negitive values * in any case we keep width and height * positive */ if(rec.width < 0) { rec.width *= -1; rec.x -= rec.width; } if(rec.height < 0) { rec.height *= -1; rec.y -= rec.height; } cairo_region_union_rectangle(window_region, &rec); /* now we have the zoom box added to window_region */ } /* This is where we go from the back buffer to the drawing area */ draw_from_pixbuf(gdk_cr, gr, allocation.width, allocation.height); if(gr->draw_zoom_box) draw_zoom_box(gdk_cr, gr); if(gr->draw_value_pick) draw_value_pick_line(gdk_cr, gr, allocation.width, allocation.height); if(empty) { /* we have nothing to make a shape with */ if(gr->qp->last_shape_region) { cairo_region_destroy(gr->qp->last_shape_region); gr->qp->last_shape_region = NULL; } cairo_region_destroy(window_region); /* remove the old shape region */ gtk_widget_shape_combine_region(gr->qp->window, NULL); } else if(!gr->qp->last_shape_region || !cairo_region_equal(gr->qp->last_shape_region, window_region)) { // DEBUG("creating new shape region\n"); /* We need to undo the old shape first */ gtk_widget_shape_combine_region(gr->qp->window, NULL); gtk_widget_shape_combine_region(gr->qp->window, window_region); if(gr->qp->last_shape_region) cairo_region_destroy(gr->qp->last_shape_region); gr->qp->last_shape_region = window_region; } else cairo_region_destroy(window_region); gr->pixbuf_needs_draw = 0; gdk_window_set_cursor(gtk_widget_get_window(gr->qp->window), NULL); // debuging //cairo_surface_write_to_png(cairo_get_target(gdk_cr), "y.png"); } if(gr->qp->update_graph_detail && gr->qp->graph_detail) { gr->qp->update_graph_detail = 0; /* make the graph configure window show stuff about this graph */ qp_win_graph_detail_init(gr->qp); } }
static void gtk_border_image_render (GtkBorderImage *image, const double border_width[4], cairo_t *cr, gdouble x, gdouble y, gdouble width, gdouble height) { cairo_surface_t *surface, *slice; GtkBorderImageSliceSize vertical_slice[3], horizontal_slice[3]; GtkBorderImageSliceSize vertical_border[3], horizontal_border[3]; double source_width, source_height; int h, v; _gtk_css_image_get_concrete_size (image->source, 0, 0, width, height, &source_width, &source_height); /* XXX: Optimize for (source_width == width && source_height == height) */ surface = _gtk_css_image_get_surface (image->source, cairo_get_target (cr), source_width, source_height); gtk_border_image_compute_slice_size (horizontal_slice, source_width, _gtk_css_number_value_get (_gtk_css_border_value_get_left (image->slice), source_width), _gtk_css_number_value_get (_gtk_css_border_value_get_right (image->slice), source_width)); gtk_border_image_compute_slice_size (vertical_slice, source_height, _gtk_css_number_value_get (_gtk_css_border_value_get_top (image->slice), source_height), _gtk_css_number_value_get (_gtk_css_border_value_get_bottom (image->slice), source_height)); gtk_border_image_compute_border_size (horizontal_border, x, width, border_width[GTK_CSS_LEFT], border_width[GTK_CSS_RIGHT], _gtk_css_border_value_get_left (image->width), _gtk_css_border_value_get_right (image->width)); gtk_border_image_compute_border_size (vertical_border, y, height, border_width[GTK_CSS_TOP], border_width[GTK_CSS_BOTTOM], _gtk_css_border_value_get_top (image->width), _gtk_css_border_value_get_bottom(image->width)); for (v = 0; v < 3; v++) { if (vertical_slice[v].size == 0 || vertical_border[v].size == 0) continue; for (h = 0; h < 3; h++) { if (horizontal_slice[h].size == 0 || horizontal_border[h].size == 0) continue; if (h == 1 && v == 1) continue; slice = cairo_surface_create_for_rectangle (surface, horizontal_slice[h].offset, vertical_slice[v].offset, horizontal_slice[h].size, vertical_slice[v].size); gtk_border_image_render_slice (cr, slice, horizontal_slice[h].size, vertical_slice[v].size, horizontal_border[h].offset, vertical_border[v].offset, horizontal_border[h].size, vertical_border[v].size, h == 1 ? _gtk_css_border_repeat_value_get_x (image->repeat) : GTK_CSS_REPEAT_STYLE_STRETCH, v == 1 ? _gtk_css_border_repeat_value_get_y (image->repeat) : GTK_CSS_REPEAT_STYLE_STRETCH); cairo_surface_destroy (slice); } } cairo_surface_destroy (surface); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_surface_t *region, *similar; cairo_t *cr_region, *cr_similar; cairo_set_source_rgb (cr, .5, .5, .5); cairo_paint (cr); similar = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR_ALPHA, 20, 20); /* copy the centre */ cr_similar = cairo_create (similar); cairo_surface_destroy (similar); cairo_set_source_surface (cr_similar, cairo_get_target (cr), -20, -20); cairo_paint (cr_similar); similar = cairo_surface_reference (cairo_get_target (cr_similar)); cairo_destroy (cr_similar); /* fill the centre */ region = cairo_surface_create_for_rectangle (cairo_get_target (cr), 20, 20, 20, 20); cr_region = cairo_create (region); cairo_surface_destroy (region); cairo_set_source_rgb (cr_region, 1, 1, 1); cairo_rectangle (cr_region, 0, 0, 10, 10); cairo_fill (cr_region); cairo_set_source_rgb (cr_region, 1, 0, 0); cairo_rectangle (cr_region, 10, 0, 10, 10); cairo_fill (cr_region); cairo_set_source_rgb (cr_region, 0, 1, 0); cairo_rectangle (cr_region, 0, 10, 10, 10); cairo_fill (cr_region); cairo_set_source_rgb (cr_region, 0, 0, 1); cairo_rectangle (cr_region, 10, 10, 10, 10); cairo_fill (cr_region); cairo_destroy (cr_region); /* copy the centre, again */ cr_similar = cairo_create (similar); cairo_surface_destroy (similar); cairo_set_source_surface (cr_similar, cairo_get_target (cr), -20, -20); cairo_paint (cr_similar); similar = cairo_surface_reference (cairo_get_target (cr_similar)); cairo_destroy (cr_similar); /* repeat the pattern around the outside, but do not overwrite...*/ cairo_set_source_surface (cr, similar, 20, 20); cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT); cairo_rectangle (cr, 0, 0, width, height); cairo_rectangle (cr, 20, 40, 20, -20); cairo_fill (cr); cairo_surface_destroy (similar); return CAIRO_TEST_SUCCESS; }
void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, GraphicsContext* context) { FloatRect srcRect = originalSrcRect; // We need to account for negative source dimensions by flipping the rectangle. if (originalSrcRect.width() < 0) { srcRect.setX(originalSrcRect.x() + originalSrcRect.width()); srcRect.setWidth(std::fabs(originalSrcRect.width())); } if (originalSrcRect.height() < 0) { srcRect.setY(originalSrcRect.y() + originalSrcRect.height()); srcRect.setHeight(std::fabs(originalSrcRect.height())); } // Cairo subsurfaces don't support floating point boundaries well, so we expand the rectangle. IntRect expandedSrcRect(enclosingIntRect(srcRect)); // We use a subsurface here so that we don't end up sampling outside the originalSrcRect rectangle. // See https://bugs.webkit.org/show_bug.cgi?id=58309 RefPtr<cairo_surface_t> subsurface = adoptRef(cairo_surface_create_for_rectangle( surface, expandedSrcRect.x(), expandedSrcRect.y(), expandedSrcRect.width(), expandedSrcRect.height())); RefPtr<cairo_pattern_t> pattern = adoptRef(cairo_pattern_create_for_surface(subsurface.get())); ASSERT(m_state); switch (m_state->m_imageInterpolationQuality) { case InterpolationNone: case InterpolationLow: cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_FAST); break; case InterpolationMedium: case InterpolationHigh: cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BILINEAR); break; case InterpolationDefault: cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BILINEAR); break; } cairo_pattern_set_extend(pattern.get(), CAIRO_EXTEND_PAD); // The pattern transformation properly scales the pattern for when the source rectangle is a // different size than the destination rectangle. We also account for any offset we introduced // by expanding floating point source rectangle sizes. It's important to take the absolute value // of the scale since the original width and height might be negative. float scaleX = std::fabs(srcRect.width() / destRect.width()); float scaleY = std::fabs(srcRect.height() / destRect.height()); float leftPadding = static_cast<float>(expandedSrcRect.x()) - floorf(srcRect.x()); float topPadding = static_cast<float>(expandedSrcRect.y()) - floorf(srcRect.y()); cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, leftPadding, topPadding }; cairo_pattern_set_matrix(pattern.get(), &matrix); ShadowBlur& shadow = context->platformContext()->shadowBlur(); if (shadow.type() != ShadowBlur::NoShadow) { if (GraphicsContext* shadowContext = shadow.beginShadowLayer(context, destRect)) { drawPatternToCairoContext(shadowContext->platformContext()->cr(), pattern.get(), destRect, 1); shadow.endShadowLayer(context); } } cairo_save(m_cr.get()); drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, globalAlpha()); cairo_restore(m_cr.get()); }