static PyObject * pattern_get_matrix (PycairoPattern *o) { cairo_matrix_t matrix; cairo_pattern_get_matrix (o->pattern, &matrix); return PycairoMatrix_FromMatrix (&matrix); }
value lime_cairo_pattern_get_matrix (value handle) { cairo_matrix_t cm; cairo_pattern_get_matrix ((cairo_pattern_t*)val_data (handle), &cm); Matrix3 mat3 = Matrix3 (cm.xx, cm.yx, cm.xy, cm.yy, cm.x0, cm.y0); return mat3.Value (); }
void set_origin(double x, double y) { cairo_matrix_t matrix; cairo_pattern_get_matrix(pattern_,&matrix); matrix.x0 = -x; matrix.y0 = -y; cairo_pattern_set_matrix(pattern_,&matrix); }
value lime_cairo_pattern_get_matrix (double handle) { cairo_matrix_t cm; cairo_pattern_get_matrix ((cairo_pattern_t*)(intptr_t)handle, &cm); Matrix3 mat3 = Matrix3 (cm.xx, cm.yx, cm.xy, cm.yy, cm.x0, cm.y0); return mat3.Value (); }
static VALUE cr_pattern_get_matrix (VALUE self) { cairo_matrix_t matrix; cairo_pattern_get_matrix (_SELF (self), &matrix); cr_pattern_check_status (_SELF (self)); return CRMATRIX2RVAL (&matrix); }
void mume_bitblt_image( cairo_t *cr, int x1, int y1, int w1, int h1, cairo_pattern_t *p, int x2, int y2) { cairo_matrix_t om; cairo_pattern_get_matrix(p, &om); cairo_save(cr); cairo_new_path(cr); _mume_bitblt_image(cr, x1, y1, w1, h1, p, x2, y2); cairo_restore(cr); cairo_pattern_set_matrix(p, &om); }
void cairo_context::set_gradient(cairo_gradient const& pattern, const box2d<double> &bbox) { cairo_pattern_t * gradient = pattern.gradient(); double bx1=bbox.minx(); double by1=bbox.miny(); double bx2=bbox.maxx(); double by2=bbox.maxy(); if (pattern.units() != USER_SPACE_ON_USE) { if (pattern.units() == OBJECT_BOUNDING_BOX) { cairo_path_extents(cairo_.get(), &bx1, &by1, &bx2, &by2); } cairo_matrix_t cairo_matrix; cairo_pattern_get_matrix(gradient, &cairo_matrix); cairo_matrix_scale(&cairo_matrix,1.0/(bx2-bx1),1.0/(by2-by1)); cairo_matrix_translate(&cairo_matrix, -bx1,-by1); cairo_pattern_set_matrix(gradient, &cairo_matrix); } cairo_set_source(cairo_.get(), const_cast<cairo_pattern_t*>(gradient)); check_object_status_and_throw_exception(*this); }
static void mech_surface_render_impl (MechSurface *surface, cairo_t *cr) { cairo_surface_t *cairo_surface; cairo_pattern_t *pattern; MechSurfacePrivate *priv; cairo_matrix_t matrix; priv = mech_surface_get_instance_private (surface); cairo_surface = MECH_SURFACE_GET_CLASS (surface)->get_surface (surface); g_assert (cairo_surface != NULL); cairo_set_source_surface (cr, cairo_surface, 0, 0); pattern = cairo_get_source (cr); cairo_pattern_get_matrix (pattern, &matrix); cairo_matrix_scale (&matrix, priv->scale_x, priv->scale_y); cairo_matrix_translate (&matrix, -priv->cached_rect.x, -priv->cached_rect.y); cairo_pattern_set_matrix (pattern, &matrix); cairo_paint (cr); }
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); } }
/*********************************************** * ge_cairo_pattern_fill - * * Fill an area with some pattern * Scaling or tiling if needed ***********************************************/ void ge_cairo_pattern_fill(cairo_t *canvas, CairoPattern *pattern, gint x, gint y, gint width, gint height) { cairo_matrix_t original_matrix, current_matrix; if (pattern->operator == CAIRO_OPERATOR_DEST) return; if (width <= 0 || height <= 0) return; cairo_pattern_get_matrix(pattern->handle, &original_matrix); current_matrix = original_matrix; if (pattern->scale != GE_DIRECTION_NONE) { gdouble scale_x = 1.0; gdouble scale_y = 1.0; if ((pattern->scale == GE_DIRECTION_VERTICAL) || (pattern->scale == GE_DIRECTION_BOTH)) { scale_x = 1.0/width; } if ((pattern->scale == GE_DIRECTION_HORIZONTAL) || (pattern->scale == GE_DIRECTION_BOTH)) { scale_y = 1.0/height; } cairo_matrix_scale(¤t_matrix, scale_x, scale_y); } if (pattern->translate != GE_DIRECTION_NONE) { gdouble translate_x = 0; gdouble translate_y = 0; if ((pattern->translate == GE_DIRECTION_VERTICAL) || (pattern->translate == GE_DIRECTION_BOTH)) { translate_x = 0.0-x; } if ((pattern->translate == GE_DIRECTION_HORIZONTAL) || (pattern->translate == GE_DIRECTION_BOTH)) { translate_y = 0.0-y; } cairo_matrix_translate(¤t_matrix, translate_x, translate_y); } cairo_pattern_set_matrix(pattern->handle, ¤t_matrix); cairo_save(canvas); cairo_set_source(canvas, pattern->handle); cairo_set_operator(canvas, pattern->operator); cairo_rectangle(canvas, x, y, width, height); cairo_fill (canvas); cairo_restore(canvas); cairo_pattern_set_matrix(pattern->handle, &original_matrix); }
/** * _st_create_shadow_cairo_pattern: * @shadow_spec: the definition of the shadow * @src_pattern: surface pattern for which we create the shadow * (must be a surface pattern) * * This is a utility function for creating shadows used by * st-theme-node.c; it's in this file to share the gaussian * blur implementation. The usage of this function is quite different * depending on whether shadow_spec->inset is %TRUE or not. If * shadow_spec->inset is %TRUE, the caller should pass in a @src_pattern * which is the <i>inverse</i> of what they want shadowed, and must take * care of the spread and offset from the shadow spec themselves. If * shadow_spec->inset is %FALSE then the caller should pass in what they * want shadowed directly, and this function takes care of the spread and * the offset. */ cairo_pattern_t * _st_create_shadow_cairo_pattern (StShadow *shadow_spec, cairo_pattern_t *src_pattern) { static cairo_user_data_key_t shadow_pattern_user_data; cairo_t *cr; cairo_surface_t *src_surface; cairo_surface_t *surface_in; cairo_surface_t *surface_out; cairo_pattern_t *dst_pattern; guchar *pixels_in, *pixels_out; gint width_in, height_in, rowstride_in; gint width_out, height_out, rowstride_out; cairo_matrix_t shadow_matrix; int i, j; g_return_val_if_fail (shadow_spec != NULL, NULL); g_return_val_if_fail (src_pattern != NULL, NULL); cairo_pattern_get_surface (src_pattern, &src_surface); width_in = cairo_image_surface_get_width (src_surface); height_in = cairo_image_surface_get_height (src_surface); /* We want the output to be a color agnostic alpha mask, * so we need to strip the color channels from the input */ if (cairo_image_surface_get_format (src_surface) != CAIRO_FORMAT_A8) { surface_in = cairo_image_surface_create (CAIRO_FORMAT_A8, width_in, height_in); cr = cairo_create (surface_in); cairo_set_source_surface (cr, src_surface, 0, 0); cairo_paint (cr); cairo_destroy (cr); } else { surface_in = cairo_surface_reference (src_surface); } pixels_in = cairo_image_surface_get_data (surface_in); rowstride_in = cairo_image_surface_get_stride (surface_in); pixels_out = blur_pixels (pixels_in, width_in, height_in, rowstride_in, shadow_spec->blur, &width_out, &height_out, &rowstride_out); cairo_surface_destroy (surface_in); /* Invert pixels for inset shadows */ if (shadow_spec->inset) { for (j = 0; j < height_out; j++) { guchar *p = pixels_out + rowstride_out * j; for (i = 0; i < width_out; i++, p++) *p = ~*p; } } surface_out = cairo_image_surface_create_for_data (pixels_out, CAIRO_FORMAT_A8, width_out, height_out, rowstride_out); cairo_surface_set_user_data (surface_out, &shadow_pattern_user_data, pixels_out, (cairo_destroy_func_t) g_free); dst_pattern = cairo_pattern_create_for_surface (surface_out); cairo_surface_destroy (surface_out); cairo_pattern_get_matrix (src_pattern, &shadow_matrix); if (shadow_spec->inset) { /* For inset shadows, offsets and spread radius have already been * applied to the original pattern, so all left to do is shift the * blurred image left, so that it aligns centered under the * unblurred one */ cairo_matrix_translate (&shadow_matrix, (width_out - width_in) / 2.0, (height_out - height_in) / 2.0); cairo_pattern_set_matrix (dst_pattern, &shadow_matrix); return dst_pattern; } /* Read all the code from the cairo_pattern_set_matrix call * at the end of this function to here from bottom to top, * because each new affine transformation is applied in * front of all the previous ones */ /* 6. Invert the matrix back */ cairo_matrix_invert (&shadow_matrix); /* 5. Adjust based on specified offsets */ cairo_matrix_translate (&shadow_matrix, shadow_spec->xoffset, shadow_spec->yoffset); /* 4. Recenter the newly scaled image */ cairo_matrix_translate (&shadow_matrix, - shadow_spec->spread, - shadow_spec->spread); /* 3. Scale up the blurred image to fill the spread */ cairo_matrix_scale (&shadow_matrix, (width_in + 2.0 * shadow_spec->spread) / width_in, (height_in + 2.0 * shadow_spec->spread) / height_in); /* 2. Shift the blurred image left, so that it aligns centered * under the unblurred one */ cairo_matrix_translate (&shadow_matrix, - (width_out - width_in) / 2.0, - (height_out - height_in) / 2.0); /* 1. Invert the matrix so we can work with it in pattern space */ cairo_matrix_invert (&shadow_matrix); cairo_pattern_set_matrix (dst_pattern, &shadow_matrix); return dst_pattern; }
Matrix Pattern::getMatrix() const { Matrix result; cairo_pattern_get_matrix( mCairoPattern, &result.getCairoMatrix() ); return result; }
/* print a GdkPixbuf to cairo at the specified position and with the * specified scale */ gboolean cairo_print_pixbuf(cairo_t * cairo_ctx, const GdkPixbuf * pixbuf, gdouble c_at_x, gdouble c_at_y, gdouble scale) { guchar *raw_image; gint n_chans; guint32 *surface_buf; gint width; gint height; gint rowstride; guint32 *dest; cairo_format_t format; cairo_surface_t *surface; cairo_pattern_t *pattern; cairo_matrix_t matrix; /* paranoia checks */ g_return_val_if_fail(cairo_ctx && pixbuf, FALSE); /* must have 8 bpp */ g_return_val_if_fail(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8, FALSE); /* must have 3 (no alpha) or 4 (with alpha) channels */ n_chans = gdk_pixbuf_get_n_channels(pixbuf); g_return_val_if_fail(n_chans == 3 || n_chans == 4, FALSE); /* allocate a new buffer */ /* FIXME: does this work on 64 bit machines if the witdth is odd? */ width = gdk_pixbuf_get_width(pixbuf); height = gdk_pixbuf_get_height(pixbuf); if (!(surface_buf = g_new0(guint32, width * height))) return FALSE; /* copy pixbuf to a cairo buffer */ dest = surface_buf; raw_image = gdk_pixbuf_get_pixels(pixbuf); rowstride = gdk_pixbuf_get_rowstride(pixbuf); if (n_chans == 4) { /* 4 channels: copy 32-bit vals, converting R-G-B-Alpha to * Alpha-R-G-B... */ gint line; format = CAIRO_FORMAT_ARGB32; for (line = 0; line < height; line++) { guchar *src = raw_image + line * rowstride; gint col; for (col = width; col; col--, src += 4) *dest++ = (((((src[3] << 8) + src[0]) << 8) + src[1]) << 8) + src[2]; } } else { /* 3 channels: copy 3 byte R-G-B to Alpha-R-G-B... */ gint line; format = CAIRO_FORMAT_RGB24; for (line = 0; line < height; line++) { guchar *src = raw_image + line * rowstride; gint col; for (col = width; col; col--, src += 3) *dest++ = (((src[0] << 8) + src[1]) << 8) + src[2]; } } /* save current state */ cairo_save(cairo_ctx); /* create the curface */ surface = cairo_image_surface_create_for_data((unsigned char *) surface_buf, format, width, height, 4 * width); cairo_set_source_surface(cairo_ctx, surface, c_at_x, c_at_y); /* scale */ pattern = cairo_get_source(cairo_ctx); cairo_pattern_get_matrix(pattern, &matrix); matrix.xx /= scale; matrix.yy /= scale; matrix.x0 /= scale; matrix.y0 /= scale; cairo_pattern_set_matrix(pattern, &matrix); /* clip around the image */ cairo_new_path(cairo_ctx); cairo_move_to(cairo_ctx, c_at_x, c_at_y); cairo_line_to(cairo_ctx, c_at_x + width * scale, c_at_y); cairo_line_to(cairo_ctx, c_at_x + width * scale, c_at_y + height * scale); cairo_line_to(cairo_ctx, c_at_x, c_at_y + height * scale); cairo_close_path(cairo_ctx); cairo_clip(cairo_ctx); /* paint, restore and clean up */ cairo_paint(cairo_ctx); cairo_restore(cairo_ctx); cairo_surface_destroy(surface); g_free(surface_buf); return TRUE; }