Exemplo n.º 1
0
static cairo_int_status_t
_cairo_type3_glyph_surface_paint (void			*abstract_surface,
				  cairo_operator_t	 op,
				  cairo_pattern_t	*source)
{
    cairo_type3_glyph_surface_t *surface = abstract_surface;
    cairo_surface_pattern_t *pattern;
    cairo_image_surface_t *image;
    void *image_extra;
    cairo_status_t status;

    if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
	return CAIRO_INT_STATUS_IMAGE_FALLBACK;

    pattern = (cairo_surface_pattern_t *) source;
    status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
    if (status)
	goto fail;

    status = _cairo_type3_glyph_surface_emit_image_pattern (surface,
							    image,
							    &pattern->base.matrix);

fail:
    _cairo_surface_release_source_image (pattern->surface, image, image_extra);

    return status;
}
Exemplo n.º 2
0
static cairo_status_t
_cairo_xml_emit_surface (cairo_xml_t *xml,
			 const cairo_surface_pattern_t *pattern)
{
    cairo_surface_t *source = pattern->surface;
    cairo_status_t status;

    if (_cairo_surface_is_recording (source)) {
	status = cairo_xml_for_recording_surface (&xml->base, source);
    } else {
	cairo_image_surface_t *image;
	void *image_extra;

	status = _cairo_surface_acquire_source_image (source,
						      &image, &image_extra);
	if (unlikely (status))
	    return status;

	status = _cairo_xml_emit_image (xml, image);

	_cairo_surface_release_source_image (source, image, image_extra);
    }

    return status;
}
Exemplo n.º 3
0
static cairo_status_t
_cairo_surface_snapshot_acquire_source_image (void                    *abstract_surface,
					      cairo_image_surface_t  **image_out,
					      void                   **extra_out)
{
    cairo_surface_snapshot_t *surface = abstract_surface;

    return _cairo_surface_acquire_source_image (surface->target, image_out, extra_out);
}
Exemplo n.º 4
0
static cairo_status_t
_test_fallback_surface_acquire_source_image (void	     *abstract_surface,
					     cairo_image_surface_t **image_out,
					     void		 **image_extra)
{
    test_fallback_surface_t *surface = abstract_surface;

    return _cairo_surface_acquire_source_image (surface->backing,
						image_out, image_extra);
}
Exemplo n.º 5
0
cairo_status_t
_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper,
					     cairo_image_surface_t  **image_out,
					     void                   **image_extra)
{
    if (unlikely (wrapper->target->status))
	return wrapper->target->status;

    return _cairo_surface_acquire_source_image (wrapper->target,
						image_out, image_extra);
}
Exemplo n.º 6
0
static void
_cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface)
{
    cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface;
    cairo_image_surface_t *image;
    cairo_image_surface_t *clone;
    void *extra;
    cairo_status_t status;

    /* We need to make an image copy of the original surface since the
     * snapshot may exceed the lifetime of the original device, i.e.
     * when we later need to use the snapshot the data may have already
     * been lost.
     */

    status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra);
    if (unlikely (status)) {
	snapshot->target = _cairo_surface_create_in_error (status);
	status = _cairo_surface_set_error (surface, status);
	return;
    }

    clone = (cairo_image_surface_t *)
	_cairo_image_surface_create_with_pixman_format (NULL,
							image->pixman_format,
							image->width,
							image->height,
							0);
    if (likely (clone->base.status == CAIRO_STATUS_SUCCESS)) {
	if (clone->stride == image->stride) {
	    memcpy (clone->data, image->data, image->stride * image->height);
	} else {
	    pixman_image_composite32 (PIXMAN_OP_SRC,
				      image->pixman_image, NULL, clone->pixman_image,
				      0, 0,
				      0, 0,
				      0, 0,
				      image->width, image->height);
	}
	clone->base.is_clear = FALSE;

	snapshot->clone = &clone->base;
    } else {
	snapshot->clone = &clone->base;
	status = _cairo_surface_set_error (surface, clone->base.status);
    }

    _cairo_surface_release_source_image (snapshot->target, image, extra);
    snapshot->target = snapshot->clone;
    snapshot->base.type = snapshot->target->type;
}
Exemplo n.º 7
0
cairo_surface_t *
_cairo_surface_fallback_snapshot (cairo_surface_t *surface)
{
    cairo_surface_t *snapshot;
    cairo_status_t status;
    cairo_pattern_union_t pattern;
    cairo_image_surface_t *image;
    void *image_extra;

    status = _cairo_surface_acquire_source_image (surface,
						  &image, &image_extra);
    if (status)
	return _cairo_surface_create_in_error (status);

    snapshot = cairo_image_surface_create (image->format,
					   image->width,
					   image->height);
    if (cairo_surface_status (snapshot)) {
	_cairo_surface_release_source_image (surface,
					     image, image_extra);
	return snapshot;
    }

    _cairo_pattern_init_for_surface (&pattern.surface, &image->base);

    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
			               &pattern.base,
				       NULL,
				       snapshot,
				       0, 0,
				       0, 0,
				       0, 0,
				       image->width,
				       image->height);

    _cairo_pattern_fini (&pattern.base);
    _cairo_surface_release_source_image (surface,
					 image, image_extra);

    if (status) {
	cairo_surface_destroy (snapshot);
	return _cairo_surface_create_in_error (status);
    }

    snapshot->device_transform = surface->device_transform;
    snapshot->device_transform_inverse = surface->device_transform_inverse;

    snapshot->is_snapshot = TRUE;

    return snapshot;
}
Exemplo n.º 8
0
cairo_surface_t *
_cairo_surface_fallback_snapshot (cairo_surface_t *surface)
{
    cairo_surface_t *snapshot;
    cairo_status_t status;
    cairo_format_t format;
    cairo_surface_pattern_t pattern;
    cairo_image_surface_t *image;
    void *image_extra;

    status = _cairo_surface_acquire_source_image (surface,
						  &image, &image_extra);
    if (unlikely (status))
	return _cairo_surface_create_in_error (status);

    format = image->format;
    if (format == CAIRO_FORMAT_INVALID) {
	/* Non-standard images formats can be generated when retrieving
	 * images from unusual xservers, for example.
	 */
	format = _cairo_format_from_content (image->base.content);
    }
    snapshot = cairo_image_surface_create (format,
					   image->width,
					   image->height);
    if (cairo_surface_status (snapshot)) {
	_cairo_surface_release_source_image (surface, image, image_extra);
	return snapshot;
    }

    _cairo_pattern_init_for_surface (&pattern, &image->base);
    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
			               &pattern.base,
				       NULL,
				       snapshot,
				       0, 0,
				       0, 0,
				       0, 0,
				       image->width,
				       image->height);
    _cairo_pattern_fini (&pattern.base);
    _cairo_surface_release_source_image (surface, image, image_extra);
    if (unlikely (status)) {
	cairo_surface_destroy (snapshot);
	return _cairo_surface_create_in_error (status);
    }

    return snapshot;
}
Exemplo n.º 9
0
static void
_cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface)
{
    cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface;
    cairo_image_surface_t *image;
    cairo_surface_t *clone;
    void *extra;
    cairo_status_t status;

    TRACE ((stderr, "%s: target=%d\n",
	    __FUNCTION__, snapshot->target->unique_id));

    /* We need to make an image copy of the original surface since the
     * snapshot may exceed the lifetime of the original device, i.e.
     * when we later need to use the snapshot the data may have already
     * been lost.
     */

    CAIRO_MUTEX_LOCK (snapshot->mutex);

    if (snapshot->target->backend->snapshot != NULL) {
	clone = snapshot->target->backend->snapshot (snapshot->target);
	if (clone != NULL) {
	    assert (clone->status || ! _cairo_surface_is_snapshot (clone));
	    goto done;
	}
    }

    /* XXX copy to a similar surface, leave acquisition till later?
     * We should probably leave such decisions to the backend in case we
     * rely upon devices/connections like Xlib.
    */
    status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra);
    if (unlikely (status)) {
	snapshot->target = _cairo_surface_create_in_error (status);
	status = _cairo_surface_set_error (surface, status);
	goto unlock;
    }
    clone = image->base.backend->snapshot (&image->base);
    _cairo_surface_release_source_image (snapshot->target, image, extra);

done:
    status = _cairo_surface_set_error (surface, clone->status);
    snapshot->target = snapshot->clone = clone;
    snapshot->base.type = clone->type;
unlock:
    CAIRO_MUTEX_UNLOCK (snapshot->mutex);
}
Exemplo n.º 10
0
static SkBitmap *
pattern_to_sk_bitmap (cairo_skia_surface_t *dst,
		      const cairo_pattern_t *pattern,
		      SkMatrix *matrix,
		      cairo_image_surface_t **image,
		      void **image_extra)
{
    if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
	return NULL;

    if (pattern->extend != CAIRO_EXTEND_NONE)
	return NULL;

    cairo_surface_t *surface = surface_from_pattern (pattern);
    SkBitmap *bitmap;

    if (surface->type == CAIRO_SURFACE_TYPE_SKIA) {
	bitmap = new SkBitmap (*((cairo_skia_surface_t *) surface)->bitmap);
    } else {
	if (surface->type != CAIRO_SURFACE_TYPE_IMAGE) {
	    cairo_status_t status;

	    status = _cairo_surface_acquire_source_image (surface,
							  image, image_extra);
	    if (unlikely (status))
		return NULL;

	    surface = &(*image)->base;
	}

	bitmap = new SkBitmap;
	if (unlikely (! surface_to_sk_bitmap (surface, *bitmap)))
	    return NULL;
    }

    *matrix = matrix_inverse_to_sk (pattern->matrix);
    return bitmap;
}
Exemplo n.º 11
0
static cairo_status_t
_cairo_xcb_surface_acquire_source_image (void *abstract_surface,
					 cairo_image_surface_t **image_out,
					 void **image_extra)
{
    cairo_xcb_surface_t *surface = abstract_surface;
    cairo_image_surface_t *image;
    cairo_status_t status;

    if (surface->drm != NULL && ! surface->marked_dirty) {
	return _cairo_surface_acquire_source_image (surface->drm,
						    image_out, image_extra);
    }

    if (surface->fallback != NULL) {
	image = (cairo_image_surface_t *) cairo_surface_reference (surface->fallback);
	goto DONE;
    }

    image = (cairo_image_surface_t *)
	_cairo_surface_has_snapshot (&surface->base,
				     &_cairo_image_surface_backend);
    if (image != NULL) {
	image = (cairo_image_surface_t *) cairo_surface_reference (&image->base);
	goto DONE;
    }

    status = _get_image (surface, FALSE, &image);
    if (unlikely (status))
	return status;

    _cairo_surface_attach_snapshot (&surface->base, &image->base, NULL);

DONE:
    *image_out = image;
    *image_extra = NULL;
    return CAIRO_STATUS_SUCCESS;
}
Exemplo n.º 12
0
static cairo_status_t
_cairo_surface_snapshot_acquire_source_image (void                    *abstract_surface,
					      cairo_image_surface_t  **image_out,
					      void                   **extra_out)
{
    cairo_surface_snapshot_t *surface = abstract_surface;
    struct snapshot_extra *extra;
    cairo_status_t status;

    extra = malloc (sizeof (*extra));
    if (unlikely (extra == NULL))
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    extra->target = _cairo_surface_snapshot_get_target (&surface->base);
    status =  _cairo_surface_acquire_source_image (extra->target, image_out, &extra->extra);
    if (unlikely (status)) {
	cairo_surface_destroy (extra->target);
	free (extra);
    }

    *extra_out = extra;
    return status;
}
static SkShader*
source_to_sk_shader (cairo_skia_context_t *cr,
		     const cairo_pattern_t *pattern)
{
    SkShader *shader = NULL;

    if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
	cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern;
	return new SkColorShader (color_to_sk (solid->color));
    } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
	cairo_surface_t *surface = surface_from_pattern (pattern);

	cr->source = cairo_surface_reference (surface);

	if (surface->type == CAIRO_SURFACE_TYPE_SKIA) {
	    cairo_skia_surface_t *esurf = (cairo_skia_surface_t *) surface;

	    shader = SkShader::CreateBitmapShader (*esurf->bitmap,
						   extend_to_sk (pattern->extend),
						   extend_to_sk (pattern->extend));
	} else {
	    SkBitmap bitmap;

	    if (! _cairo_surface_is_image (surface)) {
		cairo_status_t status;

		status = _cairo_surface_acquire_source_image (surface,
							      &cr->source_image,
							      &cr->source_extra);
		if (status)
		    return NULL;

		surface = &cr->source_image->base;
	    }

	    if (unlikely (! surface_to_sk_bitmap (surface, bitmap)))
		return NULL;

	    shader = SkShader::CreateBitmapShader (bitmap,
						   extend_to_sk (pattern->extend),
						   extend_to_sk (pattern->extend));
	}
    } else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR
	       /* || pattern->type == CAIRO_PATTERN_TYPE_RADIAL */)
    {
	cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *) pattern;
	SkColor colors_stack[10];
	SkScalar pos_stack[10];
	SkColor *colors = colors_stack;
	SkScalar *pos = pos_stack;

	if (gradient->n_stops > 10) {
	    colors = new SkColor[gradient->n_stops];
	    pos = new SkScalar[gradient->n_stops];
	}

	for (unsigned int i = 0; i < gradient->n_stops; i++) {
	    pos[i] = CAIRO_FIXED_TO_SK_SCALAR (gradient->stops[i].offset);
	    colors[i] = color_stop_to_sk (gradient->stops[i].color);
	}

	if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
	    cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient;
	    SkPoint points[2];

	    points[0].set (SkFloatToScalar (linear->pd1.x),
			   SkFloatToScalar (linear->pd1.y));
	    points[1].set (SkFloatToScalar (linear->pd2.x),
			   SkFloatToScalar (linear->pd2.y));
	    shader = SkGradientShader::CreateLinear (points, colors, pos, gradient->n_stops,
						     extend_to_sk (pattern->extend));
	} else {
	    // XXX todo -- implement real radial shaders in Skia
	}

	if (gradient->n_stops > 10) {
	    delete [] colors;
	    delete [] pos;
	}
    }

    if (shader && ! _cairo_matrix_is_identity (&pattern->matrix))
	shader->setLocalMatrix (matrix_inverse_to_sk (pattern->matrix));

    return shader;
}
static cairo_status_t
upload_boxes (cairo_win32_display_surface_t *dst,
	      const cairo_pattern_t *source,
	      cairo_boxes_t *boxes)
{
    const cairo_surface_pattern_t *pattern;
    struct upload_box cb;
    cairo_surface_t *surface;
    cairo_image_surface_t *image;
    void *image_extra;
    cairo_status_t status;

    TRACE ((stderr, "%s\n", __FUNCTION__));

    if ((dst->win32.flags & CAIRO_WIN32_SURFACE_CAN_STRETCHDIB) == 0)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    if (! _cairo_matrix_is_integer_translation (&source->matrix,
						&cb.tx, &cb.ty))
	return CAIRO_INT_STATUS_UNSUPPORTED;

    pattern = (const cairo_surface_pattern_t *) source;
    surface = _cairo_surface_get_source (pattern->surface, &cb.limit);

    /* First check that the data is entirely within the image */
    if (! _cairo_boxes_for_each_box (boxes, source_contains_box, &cb))
	return CAIRO_INT_STATUS_UNSUPPORTED;

    if (surface->type != CAIRO_SURFACE_TYPE_IMAGE) {
	status = _cairo_surface_acquire_source_image (surface,
						      &image, &image_extra);
	if (status)
	    return status;
    } else
	image = to_image_surface(surface);

    status = CAIRO_INT_STATUS_UNSUPPORTED;
    if (!(image->format == CAIRO_FORMAT_ARGB32 ||
	  image->format == CAIRO_FORMAT_RGB24))
	goto err;
    if (image->stride != 4*image->width)
	goto err;

    cb.dst = dst->win32.dc;
    cb.data = image->data;

    cb.bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
    cb.bi.bmiHeader.biWidth = image->width;
    cb.bi.bmiHeader.biHeight = -image->height;
    cb.bi.bmiHeader.biSizeImage = 0;
    cb.bi.bmiHeader.biXPelsPerMeter = PELS_72DPI;
    cb.bi.bmiHeader.biYPelsPerMeter = PELS_72DPI;
    cb.bi.bmiHeader.biPlanes = 1;
    cb.bi.bmiHeader.biBitCount = 32;
    cb.bi.bmiHeader.biCompression = BI_RGB;
    cb.bi.bmiHeader.biClrUsed = 0;
    cb.bi.bmiHeader.biClrImportant = 0;

    cb.tx += cb.limit.x;
    cb.ty += cb.limit.y;
    status = CAIRO_STATUS_SUCCESS;
    if (! _cairo_boxes_for_each_box (boxes, upload_box, &cb))
	status = CAIRO_INT_STATUS_UNSUPPORTED;

    _cairo_win32_display_surface_discard_fallback (dst);
err:
    if (&image->base != surface)
	_cairo_surface_release_source_image (surface, image, image_extra);

    return status;
}
Exemplo n.º 15
0
    PatternToBrushConverter (const cairo_pattern_t *pattern) :
	mAcquiredImageParent(0),
	mAcquiredImage(0),
	mAcquiredImageExtra(0)
    {
	if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
	    cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) pattern;
	    QColor color;
	    color.setRgbF(solid->color.red,
			  solid->color.green,
			  solid->color.blue,
			  solid->color.alpha);

	    mBrush = QBrush(color);
	} else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
	    cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) pattern;
	    cairo_surface_t *surface = spattern->surface;

	    if (surface->type == CAIRO_SURFACE_TYPE_QT) {
		cairo_qt_surface_t *qs = (cairo_qt_surface_t*) surface;

		if (qs->image) {
		    mBrush = QBrush(*qs->image);
		} else if (qs->pixmap) {
		    mBrush = QBrush(*qs->pixmap);
		} else {
		    // do something smart
		    mBrush = QBrush(0xff0000ff);
		}
	    } else {
		cairo_image_surface_t *isurf = NULL;

		if (surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
		    isurf = (cairo_image_surface_t*) surface;
		} else {
		    void *image_extra;

		    if (_cairo_surface_acquire_source_image (surface, &isurf, &image_extra) == CAIRO_STATUS_SUCCESS) {
			mAcquiredImageParent = surface;
			mAcquiredImage = isurf;
			mAcquiredImageExtra = image_extra;
		    } else {
			isurf = NULL;
		    }
		}

		if (isurf) {
		    mBrush = QBrush (QImage ((const uchar *) isurf->data,
						 isurf->width,
						 isurf->height,
						 isurf->stride,
						 _qimage_format_from_cairo_format (isurf->format)));
		} else {
		    mBrush = QBrush(0x0000ffff);
		}
	    }
	} else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR ||
		   pattern->type == CAIRO_PATTERN_TYPE_RADIAL)
	{
	    QGradient *grad;
	    cairo_bool_t reverse_stops = FALSE;
	    cairo_bool_t emulate_reflect = FALSE;
	    double offset = 0.0;

	    cairo_extend_t extend = pattern->extend;

	    cairo_gradient_pattern_t *gpat = (cairo_gradient_pattern_t *) pattern;

	    if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
		cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t *) pattern;
		grad = new QLinearGradient (lpat->pd1.x, lpat->pd1.y,
					    lpat->pd2.x, lpat->pd2.y);
	    } else if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) {
		cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t *) pattern;

		/* Based on the SVG surface code */

		cairo_circle_double_t *c0, *c1;
		double x0, y0, r0, x1, y1, r1;

		if (rpat->cd1.radius < rpat->cd2.radius) {
		    c0 = &rpat->cd1;
		    c1 = &rpat->cd2;
		    reverse_stops = FALSE;
		} else {
		    c0 = &rpat->cd2;
		    c1 = &rpat->cd1;
		    reverse_stops = TRUE;
		}

		x0 = c0->center.x;
		y0 = c0->center.y;
		r0 = c0->radius;
		x1 = c1->center.x;
		y1 = c1->center.y;
		r1 = c1->radius;

		if (r0 == r1) {
		    grad = new QRadialGradient (x1, y1, r1, x1, y1);
		} else {
		    double fx = (r1 * x0 - r0 * x1) / (r1 - r0);
		    double fy = (r1 * y0 - r0 * y1) / (r1 - r0);

		    /* QPainter doesn't support the inner circle and use instead a gradient focal.
		     * That means we need to emulate the cairo behaviour by processing the
		     * cairo gradient stops.
		     * The CAIRO_EXTENT_NONE and CAIRO_EXTENT_PAD modes are quite easy to handle,
		     * it's just a matter of stop position translation and calculation of
		     * the corresponding SVG radial gradient focal.
		     * The CAIRO_EXTENT_REFLECT and CAIRO_EXTEND_REPEAT modes require to compute a new
		     * radial gradient, with an new outer circle, equal to r1 - r0 in the CAIRO_EXTEND_REPEAT
		     * case, and 2 * (r1 - r0) in the CAIRO_EXTENT_REFLECT case, and a new gradient stop
		     * list that maps to the original cairo stop list.
		     */
		    if ((extend == CAIRO_EXTEND_REFLECT || extend == CAIRO_EXTEND_REPEAT) && r0 > 0.0) {
			double r_org = r1;
			double r, x, y;

			if (extend == CAIRO_EXTEND_REFLECT) {
			    r1 = 2 * r1 - r0;
			    emulate_reflect = TRUE;
			}

			offset = fmod (r1, r1 - r0) / (r1 - r0) - 1.0;
			r = r1 - r0;

			/* New position of outer circle. */
			x = r * (x1 - fx) / r_org + fx;
			y = r * (y1 - fy) / r_org + fy;

			x1 = x;
			y1 = y;
			r1 = r;
			r0 = 0.0;
		    } else {
			offset = r0 / r1;
		    }

		    grad = new QRadialGradient (x1, y1, r1, fx, fy);

		    if (extend == CAIRO_EXTEND_NONE && r0 != 0.0)
			grad->setColorAt (r0 / r1, Qt::transparent);
		}
	    }

	    switch (extend) {
		case CAIRO_EXTEND_NONE:
		case CAIRO_EXTEND_PAD:
		    grad->setSpread(QGradient::PadSpread);

		    grad->setColorAt (0.0, Qt::transparent);
		    grad->setColorAt (1.0, Qt::transparent);
		    break;

		case CAIRO_EXTEND_REFLECT:
		    grad->setSpread(QGradient::ReflectSpread);
		    break;

		case CAIRO_EXTEND_REPEAT:
		    grad->setSpread(QGradient::RepeatSpread);
		    break;
	    }

	    for (unsigned int i = 0; i < gpat->n_stops; i++) {
		int index = i;
		if (reverse_stops)
		    index = gpat->n_stops - i - 1;

		double offset = gpat->stops[i].offset;
		QColor color;
		color.setRgbF (gpat->stops[i].color.red,
			       gpat->stops[i].color.green,
			       gpat->stops[i].color.blue,
			       gpat->stops[i].color.alpha);

		if (emulate_reflect) {
		    offset = offset / 2.0;
		    grad->setColorAt (1.0 - offset, color);
		}

		grad->setColorAt (offset, color);
	    }

	    mBrush = QBrush(*grad);

	    delete grad;
	}

	if (mBrush.style() != Qt::NoBrush  &&
            pattern->type != CAIRO_PATTERN_TYPE_SOLID &&
            ! _cairo_matrix_is_identity (&pattern->matrix))
	{
	    cairo_matrix_t pm = pattern->matrix;
	    cairo_status_t status = cairo_matrix_invert (&pm);
	    assert (status == CAIRO_STATUS_SUCCESS);
	    mBrush.setMatrix (_qmatrix_from_cairo_matrix (pm));
	}
    }