Rect Geometry::ComputePathBounds() { if (!IsBuilt ()) Build (); if (!path || (path->cairo.num_data == 0)) return Rect (); cairo_t *cr = measuring_context_create (); cairo_append_path (cr, &path->cairo); double x1, y1, x2, y2; cairo_path_extents (cr, &x1, &y1, &x2, &y2); Rect bounds = Rect (MIN (x1, x2), MIN (y1, y2), fabs (x2 - x1), fabs (y2 - y1)); measuring_context_destroy (cr); return bounds; }
static void _adg_render(AdgEntity *entity, cairo_t *cr) { AdgStroke *stroke; AdgStrokePrivate *data; const cairo_path_t *cairo_path; stroke = (AdgStroke *) entity; data = stroke->data; cairo_path = adg_trail_get_cairo_path(data->trail); if (cairo_path != NULL) { cairo_transform(cr, adg_entity_get_global_matrix(entity)); cairo_save(cr); cairo_transform(cr, adg_entity_get_local_matrix(entity)); cairo_append_path(cr, cairo_path); cairo_restore(cr); adg_entity_apply_dress(entity, data->line_dress, cr); cairo_stroke(cr); } }
void CairoPathContext::DuplicateContextAndPath() { // Duplicate the path. cairo_path_t* path = cairo_copy_path(mContext); // Duplicate the context. cairo_surface_t* surf = cairo_get_target(mContext); cairo_matrix_t matrix; cairo_get_matrix(mContext, &matrix); cairo_destroy(mContext); mContext = cairo_create(surf); // Set the matrix to match the source context so that the path is copied in // device space. After this point it doesn't matter what the transform is // set to because it's always swapped out before use. cairo_set_matrix(mContext, &matrix); // Add the path, and throw away our duplicate. cairo_append_path(mContext, path); cairo_path_destroy(path); }
static void _adg_render(AdgEntity *entity, cairo_t *cr) { AdgADim *adim; AdgDim *dim; AdgADimPrivate *data; AdgDimStyle *dim_style; AdgDress dress; const cairo_path_t *cairo_path; adim = (AdgADim *) entity; data = adim->data; if (!data->geometry_arranged) { /* Entity not arranged, probably due to undefined pair found */ return; } dim = (AdgDim *) entity; dim_style = _ADG_GET_DIM_STYLE(dim); adg_style_apply((AdgStyle *) dim_style, entity, cr); adg_entity_render((AdgEntity *) adg_dim_get_quote(dim), cr); if (data->marker1 != NULL) adg_entity_render((AdgEntity *) data->marker1, cr); if (data->marker2 != NULL) adg_entity_render((AdgEntity *) data->marker2, cr); cairo_transform(cr, adg_entity_get_global_matrix(entity)); dress = adg_dim_style_get_line_dress(dim_style); adg_entity_apply_dress(entity, dress, cr); cairo_path = adg_trail_get_cairo_path(data->trail); cairo_append_path(cr, cairo_path); cairo_stroke(cr); }
void Geometry::Draw (cairo_t *cr) { Transform *transform = GetTransform (); cairo_matrix_t saved; cairo_get_matrix (cr, &saved); if (transform) { cairo_matrix_t matrix; transform->GetTransform (&matrix); cairo_transform (cr, &matrix); } if (!IsBuilt ()) Build (); // Geometry is used for Clip so Fill (normally setting the fill rule) is never called cairo_set_fill_rule (cr, convert_fill_rule (GetFillRule ())); if (path) cairo_append_path (cr, &path->cairo); cairo_set_matrix (cr, &saved); }
static bool appendPath_func(JSContext *context, unsigned argc, JS::Value *vp) { GJS_GET_PRIV(context, argc, vp, argv, obj, GjsCairoContext, priv); JS::RootedObject path_wrapper(context); cairo_path_t *path; cairo_t *cr = priv ? priv->cr : NULL; if (!gjs_parse_call_args(context, "path", argv, "o", "path", &path_wrapper)) return false; path = gjs_cairo_path_get_path(context, path_wrapper); if (!path) { gjs_throw(context, "first argument to appendPath() should be a path"); return false; } cairo_append_path(cr, path); argv.rval().setUndefined(); return true; }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_path_t *path; cairo_t *cr_error; /* Ensure that calling cairo_copy_path on an in-error cairo_t will * propagate the error. */ cr_error = cairo_create (NULL); path = cairo_copy_path (cr_error); if (path->status != CAIRO_STATUS_NULL_POINTER) { cairo_test_log (ctx, "Error: cairo_copy_path returned status of %s rather than propagating %s\n", cairo_status_to_string (path->status), cairo_status_to_string (CAIRO_STATUS_NULL_POINTER)); cairo_path_destroy (path); cairo_destroy (cr_error); return CAIRO_TEST_FAILURE; } cairo_path_destroy (path); path = cairo_copy_path_flat (cr_error); if (path->status != CAIRO_STATUS_NULL_POINTER) { cairo_test_log (ctx, "Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n", cairo_status_to_string (path->status), cairo_status_to_string (CAIRO_STATUS_NULL_POINTER)); cairo_path_destroy (path); cairo_destroy (cr_error); return CAIRO_TEST_FAILURE; } cairo_path_destroy (path); cairo_destroy (cr_error); /* first check that we can copy an empty path */ cairo_new_path (cr); path = cairo_copy_path (cr); if (path->status != CAIRO_STATUS_SUCCESS) { cairo_status_t status = path->status; cairo_test_log (ctx, "Error: cairo_copy_path returned status of %s\n", cairo_status_to_string (status)); cairo_path_destroy (path); return cairo_test_status_from_status (ctx, status); } if (path->num_data != 0) { cairo_test_log (ctx, "Error: cairo_copy_path did not copy an empty path, returned path contains %d elements\n", path->num_data); cairo_path_destroy (path); return CAIRO_TEST_FAILURE; } cairo_append_path (cr, path); cairo_path_destroy (path); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_test_log (ctx, "Error: cairo_append_path failed with a copy of an empty path, returned status of %s\n", cairo_status_to_string (cairo_status (cr))); return cairo_test_status_from_status (ctx, cairo_status (cr)); } /* We draw in the default black, so paint white first. */ cairo_save (cr); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_paint (cr); cairo_restore (cr); /* copy path, munge, and fill */ cairo_translate (cr, 5, 5); make_path (cr); path = cairo_copy_path (cr); cairo_new_path (cr); munge_and_set_path (cr, path, scale_by_two); cairo_path_destroy (path); cairo_fill (cr); /* copy flattened path, munge, and fill */ cairo_translate (cr, 0, 15); make_path (cr); path = cairo_copy_path_flat (cr); cairo_new_path (cr); munge_and_set_path (cr, path, scale_by_two); cairo_path_destroy (path); cairo_fill (cr); /* append two copies of path, and fill */ cairo_translate (cr, 0, 15); cairo_scale (cr, 2.0, 2.0); make_path (cr); path = cairo_copy_path (cr); cairo_new_path (cr); cairo_append_path (cr, path); cairo_translate (cr, 2.5, 2.5); cairo_append_path (cr, path); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_fill (cr); cairo_path_destroy (path); return CAIRO_TEST_SUCCESS; }
static cairo_test_status_t preamble (cairo_test_context_t *ctx) { cairo_t *cr; cairo_path_data_t data; cairo_path_t path; cairo_surface_t *surface; cairo_status_t status; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); status = cairo_surface_status (surface); if (status) { cairo_surface_destroy (surface); return cairo_test_status_from_status (ctx, status); } /* Test a few error cases for cairo_append_path_data */ #define CAIRO_CREATE() do {\ cr = cairo_create (surface); \ status = cairo_status (cr); \ if (status) { \ cairo_destroy (cr); \ cairo_surface_destroy (surface); \ return cairo_test_status_from_status (ctx, status); \ } \ } while (0) CAIRO_CREATE (); cairo_append_path (cr, NULL); status = cairo_status (cr); cairo_destroy (cr); if (status != CAIRO_STATUS_NULL_POINTER) { cairo_surface_destroy (surface); return cairo_test_status_from_status (ctx, status); } CAIRO_CREATE (); path.status = -1; cairo_append_path (cr, &path); status = cairo_status (cr); cairo_destroy (cr); if (status != CAIRO_STATUS_INVALID_STATUS) { cairo_surface_destroy (surface); return cairo_test_status_from_status (ctx, status); } CAIRO_CREATE (); path.status = CAIRO_STATUS_NO_MEMORY; cairo_append_path (cr, &path); status = cairo_status (cr); cairo_destroy (cr); if (status != CAIRO_STATUS_NO_MEMORY) { cairo_surface_destroy (surface); return cairo_test_status_from_status (ctx, status); } CAIRO_CREATE (); path.data = NULL; path.num_data = 0; path.status = CAIRO_STATUS_SUCCESS; cairo_append_path (cr, &path); status = cairo_status (cr); cairo_destroy (cr); if (status != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); return cairo_test_status_from_status (ctx, status); } CAIRO_CREATE (); path.data = NULL; path.num_data = 1; path.status = CAIRO_STATUS_SUCCESS; cairo_append_path (cr, &path); status = cairo_status (cr); cairo_destroy (cr); if (status != CAIRO_STATUS_NULL_POINTER) { cairo_surface_destroy (surface); return cairo_test_status_from_status (ctx, status); } CAIRO_CREATE (); /* Intentionally insert bogus header.length value (otherwise would be 2) */ data.header.type = CAIRO_PATH_MOVE_TO; data.header.length = 1; path.data = &data; path.num_data = 1; cairo_append_path (cr, &path); status = cairo_status (cr); cairo_destroy (cr); if (status != CAIRO_STATUS_INVALID_PATH_DATA) { cairo_surface_destroy (surface); return cairo_test_status_from_status (ctx, status); } /* And test the degnerate case */ CAIRO_CREATE (); path.num_data = 0; cairo_append_path (cr, &path); status = cairo_status (cr); cairo_destroy (cr); if (status != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); return cairo_test_status_from_status (ctx, status); } cairo_surface_destroy (surface); return CAIRO_TEST_SUCCESS; }
/*! \private * \brief Render the swatch into the cell * * \param [in] cell this cell renderer * \param [in] window the window to renter to * \param [in] widget the widget owning the window * \param [in] background_area entire cell area * \param [in] cell_area area rendered normally * \param [in] expose_area the area requiring update * \param [in] flags */ static void render (GtkCellRenderer *cell, GdkWindow *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { GschemFillSwatchCellRenderer *swatch = GSCHEM_FILL_SWATCH_CELL_RENDERER (cell); if (swatch->enabled) { GdkColor color; cairo_t *cr = gdk_cairo_create (window); double offset = SWATCH_BORDER_WIDTH / 2.0; gboolean success; if (expose_area) { gdk_cairo_rectangle (cr, expose_area); cairo_clip (cr); } /* Paint the swatch using the text color to match the user's desktop theme. */ success = gtk_style_lookup_color (gtk_widget_get_style (widget), "text_color", &color); if (success) { cairo_set_source_rgb (cr, color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0); } cairo_move_to (cr, (double) cell_area->x + offset, (double) cell_area->y + offset); cairo_line_to (cr, (double) cell_area->x + (double) cell_area->width - offset, (double) cell_area->y + offset); cairo_line_to (cr, (double) cell_area->x + (double) cell_area->width - offset, (double) cell_area->y + (double) cell_area->height - offset); cairo_line_to (cr, (double) cell_area->x + offset, (double) cell_area->y + (double) cell_area->height - offset); cairo_close_path (cr); if ((swatch->fill_type == FILLING_HATCH) || (swatch->fill_type == FILLING_MESH)) { BOX box; int index; GArray *lines = g_array_new (FALSE, FALSE, sizeof (LINE)); cairo_path_t *save_path = cairo_copy_path (cr); cairo_save (cr); cairo_clip (cr); box.lower_x = cell_area->x; box.lower_y = cell_area->y; box.upper_x = cell_area->x + cell_area->width; box.upper_y = cell_area->y + cell_area->height; m_hatch_box (&box, 135, SWATCH_LINE_PITCH, lines); if (swatch->fill_type == FILLING_MESH) { m_hatch_box (&box, 45, SWATCH_LINE_PITCH, lines); } for (index=0; index<lines->len; index++) { LINE *line = &g_array_index (lines, LINE, index); cairo_move_to (cr, line->x[0], line->y[0]); cairo_line_to (cr, line->x[1], line->y[1]); } g_array_free (lines, TRUE); cairo_set_line_width (cr, SWATCH_LINE_WIDTH); cairo_stroke (cr); cairo_restore (cr); cairo_append_path (cr, save_path); cairo_path_destroy (save_path); } if (swatch->fill_type == FILLING_FILL) { cairo_fill_preserve (cr); } cairo_set_line_width (cr, SWATCH_BORDER_WIDTH); cairo_stroke (cr); cairo_destroy (cr); } }
static void render (GtkWidget * widget) { GSMColorButton *color_button = GSM_COLOR_BUTTON (widget); GdkColor *color, tmp_color = color_button->priv->color; color = &tmp_color; cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget)); cairo_path_t *path = NULL; gint width, height; gdouble radius, arc_start, arc_end; gint highlight_factor; if (color_button->priv->highlight > 0) { highlight_factor = 8192 * color_button->priv->highlight; if (color->red + highlight_factor > 65535) color->red = 65535; else color->red = color->red + highlight_factor; if (color->blue + highlight_factor > 65535) color->blue = 65535; else color->blue = color->blue + highlight_factor; if (color->green + highlight_factor > 65535) color->green = 65535; else color->green = color->green + highlight_factor; } gdk_cairo_set_source_color (cr, color); gdk_drawable_get_size (gtk_widget_get_window (widget), &width, &height); switch (color_button->priv->type) { case GSMCP_TYPE_CPU: //gtk_widget_set_size_request (widget, GSMCP_MIN_WIDTH, GSMCP_MIN_HEIGHT); cairo_paint (cr); cairo_set_line_width (cr, 1); cairo_set_source_rgba (cr, 0, 0, 0, 0.5); cairo_rectangle (cr, 0.5, 0.5, width - 1, height - 1); cairo_stroke (cr); cairo_set_line_width (cr, 1); cairo_set_source_rgba (cr, 1, 1, 1, 0.4); cairo_rectangle (cr, 1.5, 1.5, width - 3, height - 3); cairo_stroke (cr); break; case GSMCP_TYPE_PIE: if (width < 32) // 32px minimum size gtk_widget_set_size_request (widget, 32, 32); if (width < height) radius = width / 2; else radius = height / 2; arc_start = -G_PI_2 + 2 * G_PI * color_button->priv->fraction; arc_end = -G_PI_2; cairo_set_line_width (cr, 1); // Draw external stroke and fill if (color_button->priv->fraction < 0.01) { cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, 4.5, 0, 2 * G_PI); } else if (color_button->priv->fraction > 0.99) { cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 2.25, 0, 2 * G_PI); } else { cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, radius - 2.25, arc_start, arc_end); cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, 4.5, arc_end, arc_start); cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, radius - 2.25, arc_start, arc_start); } cairo_fill_preserve (cr); cairo_set_source_rgba (cr, 0, 0, 0, 0.7); cairo_stroke (cr); // Draw internal highlight cairo_set_source_rgba (cr, 1, 1, 1, 0.45); cairo_set_line_width (cr, 1); if (color_button->priv->fraction < 0.03) { cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, 3.25, 0, 2 * G_PI); } else if (color_button->priv->fraction > 0.99) { cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 3.5, 0, 2 * G_PI); } else { cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, radius - 3.5, arc_start + (1 / (radius - 3.75)), arc_end - (1 / (radius - 3.75))); cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, 3.25, arc_end - (1 / (radius - 3.75)), arc_start + (1 / (radius - 3.75))); cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, radius - 3.5, arc_start + (1 / (radius - 3.75)), arc_start + (1 / (radius - 3.75))); } cairo_stroke (cr); // Draw external shape cairo_set_line_width (cr, 1); cairo_set_source_rgba (cr, 0, 0, 0, 0.2); cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 1.25, 0, G_PI * 2); cairo_stroke (cr); break; case GSMCP_TYPE_NETWORK_IN: if (color_button->priv->image_buffer == NULL) color_button->priv->image_buffer = fill_image_buffer_from_file (cr, DATADIR "/pixmaps/gnome-system-monitor/download.svg"); gtk_widget_set_size_request (widget, 32, 32); cairo_move_to (cr, 8.5, 1.5); cairo_line_to (cr, 23.5, 1.5); cairo_line_to (cr, 23.5, 11.5); cairo_line_to (cr, 29.5, 11.5); cairo_line_to (cr, 16.5, 27.5); cairo_line_to (cr, 15.5, 27.5); cairo_line_to (cr, 2.5, 11.5); cairo_line_to (cr, 8.5, 11.5); cairo_line_to (cr, 8.5, 1.5); cairo_close_path (cr); path = cairo_copy_path (cr); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); cairo_set_line_width (cr, 1); cairo_fill_preserve (cr); cairo_set_miter_limit (cr, 5.0); cairo_stroke (cr); cairo_set_source_rgba (cr, 0, 0, 0, 0.5); cairo_append_path (cr, path); cairo_path_destroy(path); cairo_stroke (cr); cairo_set_source_surface (cr, color_button->priv->image_buffer, 0.0, 0.0); cairo_paint (cr); break; case GSMCP_TYPE_NETWORK_OUT: if (color_button->priv->image_buffer == NULL) color_button->priv->image_buffer = fill_image_buffer_from_file (cr, DATADIR "/pixmaps/gnome-system-monitor/upload.svg"); gtk_widget_set_size_request (widget, 32, 32); cairo_move_to (cr, 16.5, 1.5); cairo_line_to (cr, 29.5, 17.5); cairo_line_to (cr, 23.5, 17.5); cairo_line_to (cr, 23.5, 27.5); cairo_line_to (cr, 8.5, 27.5); cairo_line_to (cr, 8.5, 17.5); cairo_line_to (cr, 2.5, 17.5); cairo_line_to (cr, 15.5, 1.5); cairo_line_to (cr, 16.5, 1.5); cairo_close_path (cr); path = cairo_copy_path (cr); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); cairo_set_line_width (cr, 1); cairo_fill_preserve (cr); cairo_set_miter_limit (cr, 5.0); cairo_stroke (cr); cairo_set_source_rgba (cr, 0, 0, 0, 0.5); cairo_append_path (cr, path); cairo_path_destroy(path); cairo_stroke (cr); cairo_set_source_surface (cr, color_button->priv->image_buffer, 0.0, 0.0); cairo_paint (cr); break; } cairo_destroy (cr); }
void appendPathToCairoContext(cairo_t* to, cairo_t* from) { OwnPtr<cairo_path_t> cairoPath = adoptPtr(cairo_copy_path(from)); cairo_append_path(to, cairoPath.get()); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_path_data_t path_data[] = { { { CAIRO_PATH_MOVE_TO, 2 }, }, { { 95.000000, 40.000000 }, }, { { CAIRO_PATH_LINE_TO, 2 }, }, { { 94.960533, 41.255810 }, }, { { CAIRO_PATH_LINE_TO, 2 }, }, { { 94.842293, 42.50666 }, }, { { CAIRO_PATH_LINE_TO, 2 }, }, { { 94.645744, 43.747627 }, }, { { CAIRO_PATH_LINE_TO, 2 }, }, { { 94.371666, 44.973797 }, }, }; const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_path_t path, *path_copy; int i, j, n; cairo_test_status_t result = CAIRO_TEST_SUCCESS; path.status = CAIRO_STATUS_SUCCESS; path.num_data = sizeof (path_data) / sizeof (path_data[0]); path.data = path_data; cairo_new_path (cr); cairo_append_path (cr, &path); path_copy = cairo_copy_path (cr); if (path_copy->status) return cairo_test_status_from_status (ctx, path_copy->status); for (i = j = n = 0; i < path.num_data && j < path_copy->num_data; i += path.data[i].header.length, j += path_copy->data[j].header.length, n++) { const cairo_path_data_t *src, *dst; src = &path.data[i]; dst = &path_copy->data[j]; if (src->header.type != dst->header.type) { cairo_test_log (ctx, "Paths differ in header type after %d operations.\n" "Expected path operation %d, found %d.\n", n, src->header.type, dst->header.type); result = FAIL; break; } if (memcmp (&src[1].point, &dst[1].point, sizeof (src->point))) { cairo_test_log (ctx, "Paths differ in coordinates after %d operations.\n" "Expected point (%f, %f), found (%f, %f).\n", n, src[1].point.x, src[1].point.y, dst[1].point.x, dst[1].point.y); result = FAIL; break; } } cairo_path_destroy (path_copy); return result; }
/** * gimp_scan_convert_render_full: * @sc: a #GimpScanConvert context * @buffer: the #GeglBuffer to render to * @off_x: horizontal offset into the @buffer * @off_y: vertical offset into the @buffer * @replace: if true the original content of the @buffer gets estroyed * @antialias: if true the rendering happens antialiased * @value: value to use for covered pixels * * This function renders the area described by the path to the * @buffer, taking the offset @off_x and @off_y in the buffer into * account. The rendering can happen antialiased and be rendered on * top of existing content or replacing it completely. The @value * specifies the opacity value to be used for the objects in the @sc. * * You cannot add additional polygons after this command. */ void gimp_scan_convert_render_full (GimpScanConvert *sc, GeglBuffer *buffer, gint off_x, gint off_y, gboolean replace, gboolean antialias, gdouble value) { const Babl *format; GeglBufferIterator *iter; GeglRectangle *roi; cairo_t *cr; cairo_surface_t *surface; cairo_path_t path; gint bpp; gint x, y; gint width, height; g_return_if_fail (sc != NULL); g_return_if_fail (GEGL_IS_BUFFER (buffer)); x = 0; y = 0; width = gegl_buffer_get_width (buffer); height = gegl_buffer_get_height (buffer); if (sc->clip && ! gimp_rectangle_intersect (x, y, width, height, sc->clip_x, sc->clip_y, sc->clip_w, sc->clip_h, &x, &y, &width, &height)) return; path.status = CAIRO_STATUS_SUCCESS; path.data = (cairo_path_data_t *) sc->path_data->data; path.num_data = sc->path_data->len; format = babl_format ("Y u8"); bpp = babl_format_get_bytes_per_pixel (format); iter = gegl_buffer_iterator_new (buffer, NULL, 0, format, GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE); roi = &iter->roi[0]; while (gegl_buffer_iterator_next (iter)) { guchar *data = iter->data[0]; guchar *tmp_buf = NULL; const gint stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, roi->width); /* cairo rowstrides are always multiples of 4, whereas * maskPR.rowstride can be anything, so to be able to create an * image surface, we maybe have to create our own temporary * buffer */ if (roi->width * bpp != stride) { tmp_buf = g_alloca (stride * roi->height); if (! replace) { const guchar *src = data; guchar *dest = tmp_buf; gint i; for (i = 0; i < roi->height; i++) { memcpy (dest, src, roi->width * bpp); src += roi->width * bpp; dest += stride; } } } surface = cairo_image_surface_create_for_data (tmp_buf ? tmp_buf : data, CAIRO_FORMAT_A8, roi->width, roi->height, stride); cairo_surface_set_device_offset (surface, -off_x - roi->x, -off_y - roi->y); cr = cairo_create (surface); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); if (replace) { cairo_set_source_rgba (cr, 0, 0, 0, 0); cairo_paint (cr); } cairo_set_source_rgba (cr, 0, 0, 0, value); cairo_append_path (cr, &path); cairo_set_antialias (cr, antialias ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE); cairo_set_miter_limit (cr, sc->miter); if (sc->do_stroke) { cairo_set_line_cap (cr, sc->cap == GIMP_CAP_BUTT ? CAIRO_LINE_CAP_BUTT : sc->cap == GIMP_CAP_ROUND ? CAIRO_LINE_CAP_ROUND : CAIRO_LINE_CAP_SQUARE); cairo_set_line_join (cr, sc->join == GIMP_JOIN_MITER ? CAIRO_LINE_JOIN_MITER : sc->join == GIMP_JOIN_ROUND ? CAIRO_LINE_JOIN_ROUND : CAIRO_LINE_JOIN_BEVEL); cairo_set_line_width (cr, sc->width); if (sc->dash_info) cairo_set_dash (cr, (double *) sc->dash_info->data, sc->dash_info->len, sc->dash_offset); cairo_scale (cr, 1.0, sc->ratio_xy); cairo_stroke (cr); } else { cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_fill (cr); } cairo_destroy (cr); cairo_surface_destroy (surface); if (tmp_buf) { const guchar *src = tmp_buf; guchar *dest = data; gint i; for (i = 0; i < roi->height; i++) { memcpy (dest, src, roi->width * bpp); src += stride; dest += roi->width * bpp; } } } }
void gfxContext::AppendPath(gfxPath* path) { if (path->mPath->status == CAIRO_STATUS_SUCCESS && path->mPath->num_data != 0) cairo_append_path(mCairo, path->mPath); }
svg_status_t _svg_android_set_pattern (svg_android_t *svg_android, svg_element_t *pattern_element, svg_android_render_type_t type) { svg_pattern_t *pattern = svg_element_pattern (pattern_element); jobject pattern_bitmap; jobject pattern_shader; double x_px, y_px, width_px, height_px; jobject path; _svg_android_length_to_pixel (svg_android, &pattern->x, &x_px); _svg_android_length_to_pixel (svg_android, &pattern->y, &y_px); _svg_android_length_to_pixel (svg_android, &pattern->width, &width_px); _svg_android_length_to_pixel (svg_android, &pattern->height, &height_px); /* OK. We've got the final path to be filled/stroked inside the * android context right now. But we're also going to re-use that * same context to draw the pattern. And since the path is no * longer in the graphics state, android_save/restore will not help * us here. * * Currently we deal with this by manually saving/restoring the * path. * * It might be simpler to just use a new cairo_t for drawing the * pattern. */ path = svg_android->state->path; //cairo_copy_path (svg_android->cr); svg_android->state->path = ANDROID_PATH_CREATE(svg_android); // cairo_new_path (svg_android->cr); ANDROID_SAVE(svg_android); pattern_bitmap = ANDROID_CREATE_BITMAP(svg_android, (int) (width_px + 0.5), (int) (height_px + 0.5)); #if 0 pattern_surface = cairo_surface_create_similar (cairo_get_target (svg_android->cr), CAIRO_FORMAT_ARGB32, (int) (width_px + 0.5), (int) (height_px + 0.5)); #endif _svg_android_push_state (svg_android, pattern_bitmap); svg_android->state->matrix = ANDROID_IDENTITY_MATRIX(svg_android); //cairo_identity_matrix (svg_android->cr); svg_android->state->fill_paint.type = SVG_PAINT_TYPE_NONE; svg_android->state->stroke_paint.type = SVG_PAINT_TYPE_NONE; svg_element_render (pattern->group_element, &SVG_ANDROID_RENDER_ENGINE, svg_android); _svg_android_pop_state (svg_android); ANDROID_RESTORE(svg_android); svg_android->state->path = path ; #if 0 cairo_new_path (svg_android->cr); cairo_append_path (svg_android->cr, path); cairo_path_destroy (path); #endif pattern_shader = ANDROID_CREATE_BITMAP_SHADER(svg_android, pattern_bitmap); ANDROID_PAINT_SET_SHADER(svg_android, pattern_shader); #if 0 surface_pattern = cairo_pattern_create_for_surface (pattern_surface); cairo_surface_destroy (pattern_surface); cairo_pattern_set_extend (surface_pattern, CAIRO_EXTEND_REPEAT); cairo_set_source (svg_android->cr, surface_pattern); cairo_pattern_destroy (surface_pattern); #endif return SVG_STATUS_SUCCESS; }
gboolean draw_callback (GtkWidget *widget, GdkEventExpose *event, UNUSED gpointer data) { guint width, height; cairo_pattern_t *color; cairo_path_t *bolt, *fill, *text; // Grab our widget size width = widget->allocation.width; height = widget->allocation.height; // Set up Cairo cairo_t *cr = gdk_cairo_create(widget->window); cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST); // Clear canvas #ifdef BACKGROUND_FILL_ENTIRE_WIDGET cairo_rectangle(cr, 0, 0, width, height); #else cairo_rectangle(cr, (MARGIN / 2) + STROKE_WIDTH, (MARGIN / 2) + STROKE_WIDTH, BATTERY_WIDTH, BATTERY_HEIGHT); #endif cairo_set_source_rgba(cr, COLOR_BACKGROUND, OPACITY_BACKGROUND); cairo_fill(cr); // Decide on a color color = cairo_pattern_create_rgb(COLOR_DEFAULT); if (battery_get_charging()) color = cairo_pattern_create_rgb(COLOR_CHARGING); if (battery_get_critical()) color = cairo_pattern_create_rgb(COLOR_CRITICAL); battery_border_draw(cr, color, (int)CENTERED(width, BATTERY_WIDTH), (int)CENTERED(height, BATTERY_HEIGHT), BATTERY_WIDTH, BATTERY_HEIGHT, STROKE_WIDTH, PEG_WIDTH, PEG_HEIGHT); int fill_x = CENTERED(width, BATTERY_WIDTH); int fill_y = CENTERED(height, BATTERY_HEIGHT); // Set fill style cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); // Generate battery fill fill = battery_fill_generate(BATTERY_WIDTH, BATTERY_HEIGHT, battery_get_percent()); cairo_translate(cr, fill_x, fill_y); cairo_append_path(cr, fill); if (battery_get_charging()) { int bolt_x = CENTERED(BATTERY_WIDTH, BOLT_WIDTH); int bolt_y = CENTERED(BATTERY_HEIGHT, BOLT_HEIGHT); cairo_translate(cr, bolt_x, bolt_y); bolt = battery_bolt_generate(BOLT_WIDTH, BOLT_HEIGHT); cairo_append_path(cr, bolt); cairo_translate(cr, bolt_x, bolt_y); } else { cairo_text_extents_t extents; char strpercent[5]; snprintf(strpercent, 5, "%i%%", (int)(battery_get_percent() * 100)); cairo_select_font_face(cr, FONT_FACE, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, FONT_SIZE); cairo_text_extents(cr, strpercent, &extents); int text_x = CENTERED(BATTERY_WIDTH, extents.width); int text_y = CENTERED(BATTERY_HEIGHT, extents.height + extents.y_bearing*2); text = battery_text_generate(strpercent, FONT_FACE, FONT_SIZE); cairo_translate(cr, text_x, text_y); cairo_append_path(cr, text); cairo_translate(cr, -text_x, -text_y); } cairo_translate(cr, -fill_x, -fill_y); cairo_set_source(cr, color); cairo_fill(cr); return FALSE; }