Example #1
0
static cairo_pattern_t *
transition_pattern (cairo_pattern_t *start,
                    cairo_pattern_t *end,
                    double           progress)
{
  double sx0, sy0, sx1, sy1, sr0, sr1, ex0, ey0, ex1, ey1, er0, er1;
  cairo_pattern_t *result;
  int i, n;

  progress = CLAMP (progress, 0.0, 1.0);

  if (end == NULL)
    return fade_pattern (start, 1.0 - progress);

  g_assert (cairo_pattern_get_type (start) == cairo_pattern_get_type (end));

  switch (cairo_pattern_get_type (start))
    {
    case CAIRO_PATTERN_TYPE_LINEAR:
      cairo_pattern_get_linear_points (start, &sx0, &sy0, &sx1, &sy1);
      cairo_pattern_get_linear_points (end, &ex0, &ey0, &ex1, &ey1);
      result = cairo_pattern_create_linear ((1 - progress) * sx0 + progress * ex0,
                                            (1 - progress) * sx1 + progress * ex1,
                                            (1 - progress) * sy0 + progress * ey0,
                                            (1 - progress) * sy1 + progress * ey1);
      break;
    case CAIRO_PATTERN_TYPE_RADIAL:
      cairo_pattern_get_radial_circles (start, &sx0, &sy0, &sr0, &sx1, &sy1, &sr1);
      cairo_pattern_get_radial_circles (end, &ex0, &ey0, &er0, &ex1, &ey1, &er1);
      result = cairo_pattern_create_radial ((1 - progress) * sx0 + progress * ex0,
                                            (1 - progress) * sy0 + progress * ey0,
                                            (1 - progress) * sr0 + progress * er0,
                                            (1 - progress) * sx1 + progress * ex1,
                                            (1 - progress) * sy1 + progress * ey1,
                                            (1 - progress) * sr1 + progress * er1);
      break;
    default:
      g_return_val_if_reached (NULL);
    }

  cairo_pattern_get_color_stop_count (start, &n);
  for (i = 0; i < n; i++)
    {
      double so, sr, sg, sb, sa, eo, er, eg, eb, ea;

      cairo_pattern_get_color_stop_rgba (start, i, &so, &sr, &sg, &sb, &sa);
      cairo_pattern_get_color_stop_rgba (end, i, &eo, &er, &eg, &eb, &ea);

      cairo_pattern_add_color_stop_rgba (result,
                                         (1 - progress) * so + progress * eo,
                                         (1 - progress) * sr + progress * er,
                                         (1 - progress) * sg + progress * eg,
                                         (1 - progress) * sb + progress * eb,
                                         (1 - progress) * sa + progress * ea);
    }

  return result;
}
Example #2
0
int
main (void)
{
    cairo_test_context_t ctx;
    cairo_surface_t *surface;
    cairo_pattern_t *solid_rgb, *solid_rgba, *surface_pattern, *linear, *radial;
    cairo_test_status_t result = CAIRO_TEST_SUCCESS;

    cairo_test_init (&ctx, "pattern-get-type");
    cairo_test_log (&ctx, "Creating patterns of all types\n");

    solid_rgb = cairo_pattern_create_rgb (0.0, 0.1, 0.2);
    solid_rgba = cairo_pattern_create_rgba (0.3, 0.4, 0.5, 0.6);
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
					  1, 1);
    surface_pattern = cairo_pattern_create_for_surface (surface);
    linear = cairo_pattern_create_linear (0.0, 0.0, 10.0, 10.0);
    radial = cairo_pattern_create_radial (10.0, 10.0, 0.1,
					  10.0, 10.0, 1.0);

    cairo_test_log (&ctx, "Verifying return values of cairo_pattern_get_type\n");

    if (cairo_pattern_get_type (solid_rgb) != CAIRO_PATTERN_TYPE_SOLID)
	result = CAIRO_TEST_FAILURE;

    if (cairo_pattern_get_type (solid_rgba) != CAIRO_PATTERN_TYPE_SOLID)
	result = CAIRO_TEST_FAILURE;

    if (cairo_pattern_get_type (surface_pattern) != CAIRO_PATTERN_TYPE_SURFACE)
	result = CAIRO_TEST_FAILURE;

    if (cairo_pattern_get_type (linear) != CAIRO_PATTERN_TYPE_LINEAR)
	result = CAIRO_TEST_FAILURE;

    if (cairo_pattern_get_type (radial) != CAIRO_PATTERN_TYPE_RADIAL)
	result = CAIRO_TEST_FAILURE;

    cairo_test_log (&ctx, "Cleaning up\n");

    cairo_pattern_destroy (solid_rgb);
    cairo_pattern_destroy (solid_rgba);
    cairo_pattern_destroy (surface_pattern);
    cairo_surface_destroy (surface);
    cairo_pattern_destroy (linear);
    cairo_pattern_destroy (radial);

    cairo_test_fini (&ctx);

    return result;
}
Example #3
0
static cairo_pattern_t *
fade_pattern (cairo_pattern_t *pattern,
              double           opacity)
{
  double x0, y0, x1, y1, r0, r1;
  cairo_pattern_t *result;
  int i, n;

  switch (cairo_pattern_get_type (pattern))
    {
    case CAIRO_PATTERN_TYPE_LINEAR:
      cairo_pattern_get_linear_points (pattern, &x0, &y0, &x1, &y1);
      result = cairo_pattern_create_linear (x0, y0, x1, y1);
      break;
    case CAIRO_PATTERN_TYPE_RADIAL:
      cairo_pattern_get_radial_circles (pattern, &x0, &y0, &r0, &x1, &y1, &r1);
      result = cairo_pattern_create_radial (x0, y0, r0, x1, y1, r1);
      break;
    default:
      g_return_val_if_reached (NULL);
    }

  cairo_pattern_get_color_stop_count (pattern, &n);
  for (i = 0; i < n; i++)
    {
      double o, r, g, b, a;

      cairo_pattern_get_color_stop_rgba (pattern, i, &o, &r, &g, &b, &a);
      cairo_pattern_add_color_stop_rgba (result, o, r, g, b, a * opacity);
    }

  return result;
}
static cairo_int_status_t
_prevent_overlapping_drawing (cairo_gl_context_t 		*ctx,
			      cairo_gl_composite_t 		*setup,
			      cairo_composite_rectangles_t 	*composite,
			      const cairo_path_fixed_t		*path,
			      const cairo_stroke_style_t	*style,
			      const cairo_matrix_t		*ctm)
{
    cairo_rectangle_int_t stroke_extents;
    const cairo_pattern_t *pattern = composite->original_source_pattern;
    cairo_pattern_type_t type = cairo_pattern_get_type ((cairo_pattern_t *) pattern);

    if (! _cairo_gl_ensure_stencil (ctx, setup->dst))
	return CAIRO_INT_STATUS_UNSUPPORTED;


    /* XXX: improve me - since we have lazy init, we cannot use sample
       area */
    if (type == CAIRO_PATTERN_TYPE_SOLID &&
	_cairo_pattern_is_opaque_solid (pattern))
	return CAIRO_INT_STATUS_SUCCESS;

   if (glIsEnabled (GL_STENCIL_TEST) == FALSE) {
       /* In case we have pending operations we have to flush before
	  adding the stencil buffer. */
       _cairo_gl_composite_flush (ctx);

	/* Enable the stencil buffer, even if we are not using it for clipping,
	   so we can use it below to prevent overlapping shapes. We initialize
	   it all to one here which represents infinite clip. */
	if (! ctx->states_cache.depth_mask) {
	    glDepthMask (GL_TRUE);
	    ctx->states_cache.depth_mask = TRUE;
	}
	glEnable (GL_STENCIL_TEST);

	/* If we don't have clip, then we will setup clip extents based on
	   approximate stroke extent. */
	if (! setup->clip) {
	    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm,
							  &stroke_extents);
	    _cairo_gl_scissor_to_extents (setup->dst, &stroke_extents);
	}

	glClearStencil (1);
	glClear (GL_STENCIL_BUFFER_BIT);
	glStencilFunc (GL_EQUAL, 1, 1);
    }

    /* This means that once we draw to a particular pixel nothing else can
       be drawn there until the stencil buffer is reset or the stencil test
       is disabled. */
    glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO);

    /* we need to clean up clip cache */
    _cairo_clip_destroy (ctx->clip);
    ctx->clip = NULL;

    return CAIRO_INT_STATUS_SUCCESS;
}
static inline cairo_bool_t
_cairo_composite_rectangles_check_lazy_init (cairo_composite_rectangles_t *extents,
					       cairo_surface_t *surface,
					       const cairo_pattern_t *pattern)
{
    cairo_pattern_type_t type;

    if (! extents->is_bounded)
	return FALSE;

    type = cairo_pattern_get_type ((cairo_pattern_t *)pattern);

    if (type == CAIRO_PATTERN_TYPE_SURFACE) {
    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
    cairo_surface_t *pattern_surface = pattern_surface = surface_pattern->surface;

	/* XXX: both source and target are GL surface */
	if (cairo_surface_get_type (pattern_surface) == CAIRO_SURFACE_TYPE_GL &&
		pattern_surface->backend->type == CAIRO_SURFACE_TYPE_GL &&
		cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_GL &&
		surface->device == pattern_surface->device)
        return TRUE;
	} else	if (type == CAIRO_PATTERN_TYPE_SOLID ||
                type == CAIRO_PATTERN_TYPE_RADIAL ||
                type == CAIRO_PATTERN_TYPE_LINEAR)
        return TRUE;

    return FALSE;
}
Example #6
0
static void
pattern_value_print (const GValue *value,
                     GString      *string)
{
  cairo_pattern_t *pattern;
  cairo_surface_t *surface;

  pattern = g_value_get_boxed (value);

  if (pattern == NULL)
    {
      g_string_append (string, "none");
      return;
    }

  switch (cairo_pattern_get_type (pattern))
    {
    case CAIRO_PATTERN_TYPE_SURFACE:
      if (cairo_pattern_get_surface (pattern, &surface) != CAIRO_STATUS_SUCCESS)
        {
          g_assert_not_reached ();
        }
      surface_print (surface, string);
      break;
    case CAIRO_PATTERN_TYPE_LINEAR:
    case CAIRO_PATTERN_TYPE_RADIAL:
      g_string_append (string, "none /* FIXME: add support for printing gradients */");
      break;
    case CAIRO_PATTERN_TYPE_SOLID:
    default:
      g_assert_not_reached ();
      break;
    }
}
Example #7
0
static void bg(GtkStyleContext* sc, wxColour& color, int state = GTK_STATE_FLAG_NORMAL)
{
    GdkRGBA* rgba;
    cairo_pattern_t* pattern = NULL;
    gtk_style_context_set_state(sc, GtkStateFlags(state));
    gtk_style_context_get(sc, GtkStateFlags(state),
        "background-color", &rgba, "background-image", &pattern, NULL);
    color = wxColour(*rgba);
    gdk_rgba_free(rgba);

    // "background-image" takes precedence over "background-color".
    // If there is an image, try to get a color out of it.
    if (pattern)
    {
        if (cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_SURFACE)
        {
            cairo_surface_t* surf;
            cairo_pattern_get_surface(pattern, &surf);
            if (cairo_surface_get_type(surf) == CAIRO_SURFACE_TYPE_IMAGE)
            {
                const guchar* data = cairo_image_surface_get_data(surf);
                const int stride = cairo_image_surface_get_stride(surf);
                // choose a pixel in the middle vertically,
                // images often have a vertical gradient
                const int i = stride * (cairo_image_surface_get_height(surf) / 2);
                const unsigned* p = reinterpret_cast<const unsigned*>(data + i);
                const unsigned pixel = *p;
                guchar r, g, b, a = 0xff;
                switch (cairo_image_surface_get_format(surf))
                {
                case CAIRO_FORMAT_ARGB32:
                    a = guchar(pixel >> 24);
                    // fallthrough
                case CAIRO_FORMAT_RGB24:
                    r = guchar(pixel >> 16);
                    g = guchar(pixel >> 8);
                    b = guchar(pixel);
                    break;
                default:
                    a = 0;
                    break;
                }
                if (a != 0)
                {
                    if (a != 0xff)
                    {
                        // un-premultiply
                        r = guchar((r * 0xff) / a);
                        g = guchar((g * 0xff) / a);
                        b = guchar((b * 0xff) / a);
                    }
                    color.Set(r, g, b, a);
                }
            }
        }
        cairo_pattern_destroy(pattern);
    }
static void releasePattern(cairo_pattern_t *pat)
{
  if (!pat)
    return;

  if (cairo_pattern_get_type(pat) == CAIRO_PATTERN_TYPE_SURFACE)
  {
    cairo_surface_t *surface;
    cairo_pattern_get_surface(pat, &surface);
    cairo_surface_destroy(surface);
  }

  cairo_pattern_destroy(pat);
}
Example #9
0
/**
 * gjs_cairo_pattern_from_pattern:
 * @context: the context
 * @pattern: cairo_pattern to attach to the object
 *
 * Constructs a pattern wrapper given cairo pattern.
 * A reference to @pattern will be taken.
 *
 */
JSObject *
gjs_cairo_pattern_from_pattern(JSContext       *context,
                               cairo_pattern_t *pattern)
{
    g_return_val_if_fail(context != NULL, NULL);
    g_return_val_if_fail(pattern != NULL, NULL);

    switch (cairo_pattern_get_type(pattern)) {
    case CAIRO_PATTERN_TYPE_SOLID:
        return gjs_cairo_solid_pattern_from_pattern(context, pattern);
    case CAIRO_PATTERN_TYPE_SURFACE:
        return gjs_cairo_surface_pattern_from_pattern(context, pattern);
    case CAIRO_PATTERN_TYPE_LINEAR:
        return gjs_cairo_linear_gradient_from_pattern(context, pattern);
    case CAIRO_PATTERN_TYPE_RADIAL:
        return gjs_cairo_radial_gradient_from_pattern(context, pattern);
    default:
        break;
    }

    gjs_throw(context, "failed to create pattern, unsupported pattern type %d",
              cairo_pattern_get_type(pattern));
    return NULL;
}
Example #10
0
static gboolean
gtk_css_image_gradient_draw_circle (GtkCssImageGradient *image,
                                    cairo_t              *cr,
                                    double               width,
                                    double               height)
{
  cairo_pattern_t *pattern = image->pattern;
  double x0, y0, x1, y1, r0, r1;
  GdkRGBA color0, color1;
  double offset0, offset1;
  int n_stops;

  if (cairo_pattern_get_type (pattern) != CAIRO_PATTERN_TYPE_RADIAL)
    return FALSE;
  if (cairo_pattern_get_extend (pattern) != CAIRO_EXTEND_PAD)
    return FALSE;

  cairo_pattern_get_radial_circles (pattern, &x0, &y0, &r0, &x1, &y1, &r1);

  if (x0 != x1 ||
      y0 != y1 ||
      r0 != 0.0)
    return FALSE;

  cairo_pattern_get_color_stop_count (pattern, &n_stops);
  if (n_stops != 2)
    return FALSE;

  cairo_pattern_get_color_stop_rgba (pattern, 0, &offset0, &color0.red, &color0.green, &color0.blue, &color0.alpha);
  cairo_pattern_get_color_stop_rgba (pattern, 1, &offset1, &color1.red, &color1.green, &color1.blue, &color1.alpha);
  if (offset0 != offset1)
    return FALSE;

  cairo_scale (cr, width, height);

  cairo_rectangle (cr, 0, 0, 1, 1);
  cairo_clip (cr);

  gdk_cairo_set_source_rgba (cr, &color1);
  cairo_paint (cr);

  gdk_cairo_set_source_rgba (cr, &color0);
  cairo_arc (cr, x1, y1, r1 * offset1, 0, 2 * G_PI);
  cairo_fill (cr);

  return TRUE;
}
JSObject *
gjs_cairo_surface_pattern_from_pattern(JSContext       *context,
                                       cairo_pattern_t *pattern)
{
    JSObject *object;

    g_return_val_if_fail(context != NULL, NULL);
    g_return_val_if_fail(pattern != NULL, NULL);
    g_return_val_if_fail(cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_SURFACE, NULL);

    object = JS_NewObject(context, &gjs_cairo_surface_pattern_class, NULL, NULL);
    if (!object) {
        gjs_throw(context, "failed to create surface pattern");
        return NULL;
    }

    gjs_cairo_pattern_construct(context, object, pattern);

    return object;
}
Example #12
0
/* PycairoPattern_FromPattern
 * Create a new
 *   PycairoSolidPattern,
 *   PycairoSurfacePattern,
 *   PycairoLinearGradient, or
 *   PycairoRadialGradient from a cairo_pattern_t.
 * pattern - a cairo_pattern_t to 'wrap' into a Python object.
 *   It is unreferenced if the PycairoPattern creation fails, or if the
 *   pattern has an error status.
 * base - the base object used to create the pattern, or NULL.
 *   It is referenced to keep it alive while the cairo_pattern_t is being used.
 *   For PycairoSurfacePattern base should be the PycairoSurface, for other
 #   patterns it should be NULL.
 * Return value: New reference or NULL on failure
 */
PyObject *
PycairoPattern_FromPattern (cairo_pattern_t *pattern, PyObject *base) {
  PyTypeObject *type = NULL;
  PyObject *o;

  assert (pattern != NULL);

  if (Pycairo_Check_Status (cairo_pattern_status (pattern))) {
    cairo_pattern_destroy (pattern);
    return NULL;
  }

  switch (cairo_pattern_get_type (pattern)) {
  case CAIRO_PATTERN_TYPE_SOLID:
    type = &PycairoSolidPattern_Type;
    break;
  case CAIRO_PATTERN_TYPE_SURFACE:
    type = &PycairoSurfacePattern_Type;
    break;
  case CAIRO_PATTERN_TYPE_LINEAR:
    type = &PycairoLinearGradient_Type;
    break;
  case CAIRO_PATTERN_TYPE_RADIAL:
    type = &PycairoRadialGradient_Type;
    break;
  default:
    type = &PycairoPattern_Type;
    break;
  }

  o = type->tp_alloc(type, 0);
  if (o == NULL) {
    cairo_pattern_destroy (pattern);
  } else {
    ((PycairoPattern *)o)->pattern = pattern;
    Py_XINCREF(base);
    ((PycairoPattern *)o)->base = base;
  }
  return o;
}
/* PycairoPattern_FromPattern
 * Create a new
 *   PycairoSolidPattern,
 *   PycairoSurfacePattern,
 *   PycairoLinearGradient, or
 *   PycairoRadialGradient from a cairo_pattern_t.
 * pattern - a cairo_pattern_t to 'wrap' into a Python object.
 *           it is unreferenced if the PycairoPattern creation fails, or if the
 *           pattern has an error status.
 * Return value: New reference or NULL on failure
 */
PyObject *
PycairoPattern_FromPattern (cairo_pattern_t *pattern)
{
    PyTypeObject *type = NULL;
    PyObject *o;

    assert (pattern != NULL);

    if (Pycairo_Check_Status (cairo_pattern_status (pattern))) {
	cairo_pattern_destroy (pattern);
	return NULL;
    }

    switch (cairo_pattern_get_type (pattern)) {
    case CAIRO_PATTERN_TYPE_SOLID:
	type = &PycairoSolidPattern_Type;
	break;
    case CAIRO_PATTERN_TYPE_SURFACE:
	type = &PycairoSurfacePattern_Type;
	break;
    case CAIRO_PATTERN_TYPE_LINEAR:
	type = &PycairoLinearGradient_Type;
	break;
    case CAIRO_PATTERN_TYPE_RADIAL:
	type = &PycairoRadialGradient_Type;
	break;
    default:
	PyErr_SetString(CairoError, "Unsupported Pattern type");
	return NULL;
    }

    o = type->tp_alloc(type, 0);
    if (o == NULL)
	cairo_pattern_destroy (pattern);
    else
	((PycairoPattern *)o)->pattern = pattern;
    return o;
}
Example #14
0
static JSBool
getType_func(JSContext *context,
             unsigned   argc,
             jsval     *vp)
{
    JSObject *obj = JS_THIS_OBJECT(context, vp);
    cairo_pattern_t *pattern;
    cairo_pattern_type_t type;

    if (argc > 1) {
        gjs_throw(context, "Pattern.getType() takes no arguments");
        return JS_FALSE;
    }

    pattern = gjs_cairo_pattern_get_pattern(context, obj);
    type = cairo_pattern_get_type(pattern);

    if (!gjs_cairo_check_status(context, cairo_pattern_status(pattern), "pattern"))
        return JS_FALSE;

    JS_SET_RVAL(context, vp, INT_TO_JSVAL(type));
    return JS_TRUE;
}
static void
_gl_pattern_fix_reference_count (const cairo_pattern_t *pattern)
{
   cairo_pattern_type_t pattern_type = cairo_pattern_get_type ((cairo_pattern_t *)pattern);

   /* We need to increase reference count on surface and gradient if
      the original_source_pattern is a cairo_gl_source_t type. */
    if (pattern_type == CAIRO_PATTERN_TYPE_SURFACE) {

	cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *)pattern;
	cairo_surface_t *pattern_surface = surface_pattern->surface;

	if (cairo_surface_get_type (pattern_surface) == CAIRO_SURFACE_TYPE_GL &&
	    ! pattern_surface->device &&
	    ! _cairo_surface_is_subsurface (pattern_surface)) {

	    cairo_gl_source_t *_source = (cairo_gl_source_t *)pattern_surface;

	    switch (_source->operand.type) {
	    case CAIRO_GL_OPERAND_TEXTURE:
		cairo_surface_reference (&(_source->operand.texture.owns_surface)->base);
		break;
	    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
	    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
	    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
	    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
		_cairo_gl_gradient_reference (_source->operand.gradient.gradient);
		break;
	    default:
	    case CAIRO_GL_OPERAND_NONE:
	    case CAIRO_GL_OPERAND_CONSTANT:
	    case CAIRO_GL_OPERAND_COUNT:
		break;
	    }
	}
    }
}
Example #16
0
static VALUE
cr_pattern_get_klass (cairo_pattern_t *pattern)
{
  VALUE klass;
  cairo_pattern_type_t type;

  type = cairo_pattern_get_type (pattern);
  switch (type)
    {
    case CAIRO_PATTERN_TYPE_SOLID:
      klass = rb_cCairo_SolidPattern;
      break;
    case CAIRO_PATTERN_TYPE_SURFACE:
      klass = rb_cCairo_SurfacePattern;
      break;
    case CAIRO_PATTERN_TYPE_LINEAR:
      klass = rb_cCairo_LinearPattern;
      break;
    case CAIRO_PATTERN_TYPE_RADIAL:
      klass = rb_cCairo_RadialPattern;
      break;
#if CAIRO_CHECK_VERSION(1, 11, 4)
    case CAIRO_PATTERN_TYPE_MESH:
      klass = rb_cCairo_MeshPattern;
      break;
    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
      klass = rb_cCairo_RasterSourcePattern;
      break;
#endif
    default:
      rb_raise (rb_eArgError, "unknown pattern type: %d", type);
      break;
    }

  return klass;
}
Example #17
0
JNIEXPORT jint JNICALL Java_org_jclutter_cairo_CairoPattern_getType(JNIEnv *env, jobject obj){
return (jint)cairo_pattern_get_type();
}
Example #18
0
static void
_gtk_pixel_cache_create_surface_if_needed (GtkPixelCache         *cache,
					   GdkWindow             *window,
					   cairo_rectangle_int_t *view_rect,
					   cairo_rectangle_int_t *canvas_rect)
{
  cairo_rectangle_int_t rect;
  int surface_w, surface_h;
  cairo_content_t content;
  cairo_pattern_t *bg;
  double red, green, blue, alpha;

  content = CAIRO_CONTENT_COLOR_ALPHA;
  bg = gdk_window_get_background_pattern (window);
  if (bg != NULL &&
      cairo_pattern_get_type (bg) == CAIRO_PATTERN_TYPE_SOLID &&
      cairo_pattern_get_rgba (bg, &red, &green, &blue, &alpha) == CAIRO_STATUS_SUCCESS &&
      alpha == 1.0)
    content = CAIRO_CONTENT_COLOR;

  surface_w = view_rect->width;
  if (canvas_rect->width > surface_w)
    surface_w = MIN (surface_w + EXTRA_SIZE, canvas_rect->width);

  surface_h = view_rect->height;
  if (canvas_rect->height > surface_h)
    surface_h = MIN (surface_h + EXTRA_SIZE, canvas_rect->height);

  /* If current surface can't fit view_rect or is too large, kill it */
  if (cache->surface != NULL &&
      (cairo_surface_get_content (cache->surface) != content ||
       cache->surface_w < view_rect->width ||
       cache->surface_w > surface_w + ALLOW_LARGER_SIZE ||
       cache->surface_h < view_rect->height ||
       cache->surface_h > surface_h + ALLOW_LARGER_SIZE ||
       cache->surface_scale != gdk_window_get_scale_factor (window)))
    {
      cairo_surface_destroy (cache->surface);
      cache->surface = NULL;
      if (cache->surface_dirty)
	cairo_region_destroy (cache->surface_dirty);
      cache->surface_dirty = NULL;
    }

  /* Don't allocate a surface if view >= canvas, as we won't
     be scrolling then anyway */
  if (cache->surface == NULL &&
      (view_rect->width < canvas_rect->width ||
       view_rect->height < canvas_rect->height))
    {
      cache->surface_x = -canvas_rect->x;
      cache->surface_y = -canvas_rect->y;
      cache->surface_w = surface_w;
      cache->surface_h = surface_h;
      cache->surface_scale = gdk_window_get_scale_factor (window);

      cache->surface =
	gdk_window_create_similar_surface (window, content,
					   surface_w, surface_h);
      rect.x = 0;
      rect.y = 0;
      rect.width = surface_w;
      rect.height = surface_h;
      cache->surface_dirty =
	cairo_region_create_rectangle (&rect);
    }
}
Example #19
0
/*
 * Implements
 *   org.freedesktop.cairo.Plumbing.createPattern(long pointer)
 */
JNIEXPORT jobject JNICALL
Java_org_freedesktop_cairo_Plumbing_createPattern
(
	JNIEnv* env,
	jclass cls,
	jlong _pointer
)
{
	cairo_pattern_t* pattern;
	jclass found;
	static jclass SolidPattern = NULL;
	static jclass SurfacePattern = NULL;	
	static jclass LinearPattern = NULL;	
	static jclass RadialPattern = NULL;	
	jclass type;
	jmethodID constructor;
	jobject proxy;
	
	// convert pointer
	pattern = (cairo_pattern_t*) _pointer;

	// increment reference count
	cairo_pattern_reference(pattern);

	// now figure out Proxy class and create
	switch (cairo_pattern_get_type(pattern)) {
	case CAIRO_PATTERN_TYPE_SOLID:
		if (SolidPattern == NULL) {
			found = (*env)->FindClass(env, "org/freedesktop/cairo/SolidPattern");
			SolidPattern = (*env)->NewGlobalRef(env, found);
		}
		type = SolidPattern;
		break;

	case CAIRO_PATTERN_TYPE_SURFACE:
		if (SurfacePattern == NULL) {
			found = (*env)->FindClass(env, "org/freedesktop/cairo/SurfacePattern");
			SurfacePattern = (*env)->NewGlobalRef(env, found);
		}
		type = SurfacePattern;
		break;

	case CAIRO_PATTERN_TYPE_LINEAR:
		if (LinearPattern == NULL) {
			found = (*env)->FindClass(env, "org/freedesktop/cairo/LinearPattern");
			LinearPattern = (*env)->NewGlobalRef(env, found);
		}
		type = LinearPattern;
		break;

	case CAIRO_PATTERN_TYPE_RADIAL:		
		if (RadialPattern == NULL) {
			found = (*env)->FindClass(env, "org/freedesktop/cairo/RadialPattern");
			RadialPattern = (*env)->NewGlobalRef(env, found);
		}
		type = RadialPattern;
		break;

	default:
		g_critical("Unimplemented pattern type");
		return NULL;
	}
	if (type == NULL) {
		bindings_java_throw(env, "FindClass() failed");
		return NULL;
	}

	constructor = (*env)->GetMethodID(env, type, "<init>", "(J)V");
	if (constructor == NULL) {
		g_error("Constructor methodID not found");
		return NULL;
	}
	
	proxy = (*env)->NewObject(env, type, constructor, _pointer);
	return proxy;
}