11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2000 SuSE, Inc.
31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2007 Red Hat, Inc.
41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Permission to use, copy, modify, distribute, and sell this software and its
61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation for any purpose is hereby granted without fee, provided that
71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the above copyright notice appear in all copies and that both that
81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * copyright notice and this permission notice appear in supporting
91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation, and that the name of SuSE not be used in advertising or
101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * publicity pertaining to distribution of the software without specific,
111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * written prior permission.  SuSE makes no representations about the
121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * suitability of this software for any purpose.  It is provided "as is"
131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * without express or implied warranty.
141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifdef HAVE_CONFIG_H
241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <config.h>
251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif
261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdlib.h>
281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdio.h>
291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <string.h>
301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <assert.h>
311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "pixman-private.h"
331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
341176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic const pixman_color_t transparent_black = { 0, 0, 0, 0 };
351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
361176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void
371176bdada62cabc6ec4b0308a930e83b679d5d36John Reckgradient_property_changed (pixman_image_t *image)
381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gradient_t *gradient = &image->gradient;
401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int n = gradient->n_stops;
411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_gradient_stop_t *stops = gradient->stops;
421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_gradient_stop_t *end = &(gradient->stops[n]);
441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    switch (gradient->common.repeat)
461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    default:
481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_REPEAT_NONE:
491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	begin->x = INT32_MIN;
501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	begin->color = transparent_black;
511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	end->x = INT32_MAX;
521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	end->color = transparent_black;
531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_REPEAT_NORMAL:
561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	begin->x = stops[n - 1].x - pixman_fixed_1;
571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	begin->color = stops[n - 1].color;
581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	end->x = stops[0].x + pixman_fixed_1;
591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	end->color = stops[0].color;
601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_REPEAT_REFLECT:
631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	begin->x = - stops[0].x;
641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	begin->color = stops[0].color;
651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	end->x = pixman_int_to_fixed (2) - stops[n - 1].x;
661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	end->color = stops[n - 1].color;
671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_REPEAT_PAD:
701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	begin->x = INT32_MIN;
711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	begin->color = stops[0].color;
721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	end->x = INT32_MAX;
731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	end->color = stops[n - 1].color;
741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
781176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t
791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_init_gradient (gradient_t *                  gradient,
801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                       const pixman_gradient_stop_t *stops,
811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                       int                           n_stops)
821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return_val_if_fail (n_stops > 0, FALSE);
841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* We allocate two extra stops, one before the beginning of the stop list,
861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * and one after the end. These stops are initialized to whatever color
871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * would be used for positions outside the range of the stop list.
881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     *
891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * This saves a bit of computation in the gradient walker.
901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     *
911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * The pointer we store in the gradient_t struct still points to the
921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * first user-supplied struct, so when freeing, we will have to
931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * subtract one.
941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gradient->stops =
961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!gradient->stops)
981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gradient->stops += 1;
1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gradient->n_stops = n_stops;
1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gradient->common.property_changed = gradient_property_changed;
1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return TRUE;
1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reckvoid
1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_image_init (pixman_image_t *image)
1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_common_t *common = &image->common;
1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_region32_init (&common->clip_region);
1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->alpha_count = 0;
1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->have_clip_region = FALSE;
1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->clip_sources = FALSE;
1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->transform = NULL;
1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->repeat = PIXMAN_REPEAT_NONE;
1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->filter = PIXMAN_FILTER_NEAREST;
1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->filter_params = NULL;
1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->n_filter_params = 0;
1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->alpha_map = NULL;
1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->component_alpha = FALSE;
1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->ref_count = 1;
1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->property_changed = NULL;
1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->client_clip = FALSE;
1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->destroy_func = NULL;
1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->destroy_data = NULL;
1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->dirty = TRUE;
1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t
1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_image_fini (pixman_image_t *image)
1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_common_t *common = (image_common_t *)image;
1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->ref_count--;
1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (common->ref_count == 0)
1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->common.destroy_func)
1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->common.destroy_func (image, image->common.destroy_data);
1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_region32_fini (&common->clip_region);
1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	free (common->transform);
1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	free (common->filter_params);
1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (common->alpha_map)
1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_image_unref ((pixman_image_t *)common->alpha_map);
1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->type == LINEAR ||
1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->type == RADIAL ||
1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->type == CONICAL)
1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (image->gradient.stops)
1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		/* See _pixman_init_gradient() for an explanation of the - 1 */
1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		free (image->gradient.stops - 1);
1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    /* This will trigger if someone adds a property_changed
1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     * method to the linear/radial/conical gradient overwriting
1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     * the general one.
1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     */
1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    assert (
1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		image->common.property_changed == gradient_property_changed);
1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->type == BITS && image->bits.free_me)
1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    free (image->bits.free_me);
1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return FALSE;
1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_t *
1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_image_allocate (void)
1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_t *image = malloc (sizeof (pixman_image_t));
1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image)
1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	_pixman_image_init (image);
1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return image;
1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1921176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void
1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reckimage_property_changed (pixman_image_t *image)
1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.dirty = TRUE;
1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* Ref Counting */
1991176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_image_t *
2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_ref (pixman_image_t *image)
2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.ref_count++;
2031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return image;
2051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* returns TRUE when the image is freed */
2081176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
2091176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_unref (pixman_image_t *image)
2101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (_pixman_image_fini (image))
2121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	free (image);
2141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
2151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return FALSE;
2181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2201176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
2211176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_destroy_function (pixman_image_t *            image,
2221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                   pixman_image_destroy_func_t func,
2231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                   void *                      data)
2241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.destroy_func = func;
2261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.destroy_data = data;
2271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2291176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void *
2301176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_get_destroy_data (pixman_image_t *image)
2311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  return image->common.destroy_data;
2331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2351176bdada62cabc6ec4b0308a930e83b679d5d36John Reckvoid
2361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_image_reset_clip_region (pixman_image_t *image)
2371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.have_clip_region = FALSE;
2391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* Executive Summary: This function is a no-op that only exists
2421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * for historical reasons.
2431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
2441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * There used to be a bug in the X server where it would rely on
2451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * out-of-bounds accesses when it was asked to composite with a
2461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * window as the source. It would create a pixman image pointing
2471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * to some bogus position in memory, but then set a clip region
2481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * to the position where the actual bits were.
2491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
2501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Due to a bug in old versions of pixman, where it would not clip
2511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * against the image bounds when a clip region was set, this would
2521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * actually work. So when the pixman bug was fixed, a workaround was
2531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * added to allow certain out-of-bound accesses. This function disabled
2541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * those workarounds.
2551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
2561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Since 0.21.2, pixman doesn't do these workarounds anymore, so now
2571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * this function is a no-op.
2581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
2591176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
2601176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_disable_out_of_bounds_workaround (void)
2611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2641176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void
2651176bdada62cabc6ec4b0308a930e83b679d5d36John Reckcompute_image_info (pixman_image_t *image)
2661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_format_code_t code;
2681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t flags = 0;
2691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Transform */
2711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!image->common.transform)
2721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= (FAST_PATH_ID_TRANSFORM	|
2741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		  FAST_PATH_X_UNIT_POSITIVE	|
2751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		  FAST_PATH_Y_UNIT_ZERO		|
2761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		  FAST_PATH_AFFINE_TRANSFORM);
2771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
2791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= FAST_PATH_HAS_TRANSFORM;
2811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->common.transform->matrix[2][0] == 0			&&
2831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->common.transform->matrix[2][1] == 0			&&
2841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->common.transform->matrix[2][2] == pixman_fixed_1)
2851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags |= FAST_PATH_AFFINE_TRANSFORM;
2871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (image->common.transform->matrix[0][1] == 0 &&
2891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		image->common.transform->matrix[1][0] == 0)
2901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
2911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		if (image->common.transform->matrix[0][0] == -pixman_fixed_1 &&
2921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		    image->common.transform->matrix[1][1] == -pixman_fixed_1)
2931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		{
2941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		    flags |= FAST_PATH_ROTATE_180_TRANSFORM;
2951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		}
2961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		flags |= FAST_PATH_SCALE_TRANSFORM;
2971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
2981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    else if (image->common.transform->matrix[0][0] == 0 &&
2991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	             image->common.transform->matrix[1][1] == 0)
3001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
3011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		pixman_fixed_t m01 = image->common.transform->matrix[0][1];
3021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		pixman_fixed_t m10 = image->common.transform->matrix[1][0];
3031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		if (m01 == -pixman_fixed_1 && m10 == pixman_fixed_1)
3051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		    flags |= FAST_PATH_ROTATE_90_TRANSFORM;
3061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		else if (m01 == pixman_fixed_1 && m10 == -pixman_fixed_1)
3071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		    flags |= FAST_PATH_ROTATE_270_TRANSFORM;
3081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
3091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
3101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->common.transform->matrix[0][0] > 0)
3121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags |= FAST_PATH_X_UNIT_POSITIVE;
3131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->common.transform->matrix[1][0] == 0)
3151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags |= FAST_PATH_Y_UNIT_ZERO;
3161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Filter */
3191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    switch (image->common.filter)
3201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_FILTER_NEAREST:
3221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_FILTER_FAST:
3231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
3241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
3251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_FILTER_BILINEAR:
3271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_FILTER_GOOD:
3281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_FILTER_BEST:
3291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
3301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* Here we have a chance to optimize BILINEAR filter to NEAREST if
3321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * they are equivalent for the currently used transformation matrix.
3331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 */
3341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (flags & FAST_PATH_ID_TRANSFORM)
3351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
3361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags |= FAST_PATH_NEAREST_FILTER;
3371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
3381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else if (
3391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    /* affine and integer translation components in matrix ... */
3401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ((flags & FAST_PATH_AFFINE_TRANSFORM) &&
3411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     !pixman_fixed_frac (image->common.transform->matrix[0][2] |
3421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				 image->common.transform->matrix[1][2])) &&
3431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    (
3441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		/* ... combined with a simple rotation */
3451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		(flags & (FAST_PATH_ROTATE_90_TRANSFORM |
3461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			  FAST_PATH_ROTATE_180_TRANSFORM |
3471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			  FAST_PATH_ROTATE_270_TRANSFORM)) ||
3481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		/* ... or combined with a simple non-rotated translation */
3491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		(image->common.transform->matrix[0][0] == pixman_fixed_1 &&
3501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		 image->common.transform->matrix[1][1] == pixman_fixed_1 &&
3511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		 image->common.transform->matrix[0][1] == 0 &&
3521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		 image->common.transform->matrix[1][0] == 0)
3531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		)
3541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    )
3551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
3561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    /* FIXME: there are some affine-test failures, showing that
3571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     * handling of BILINEAR and NEAREST filter is not quite
3581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     * equivalent when getting close to 32K for the translation
3591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     * components of the matrix. That's likely some bug, but for
3601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     * now just skip BILINEAR->NEAREST optimization in this case.
3611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     */
3621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_fixed_t magic_limit = pixman_int_to_fixed (30000);
3631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (image->common.transform->matrix[0][2] <= magic_limit  &&
3641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	        image->common.transform->matrix[1][2] <= magic_limit  &&
3651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	        image->common.transform->matrix[0][2] >= -magic_limit &&
3661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	        image->common.transform->matrix[1][2] >= -magic_limit)
3671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
3681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		flags |= FAST_PATH_NEAREST_FILTER;
3691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
3701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
3711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
3721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_FILTER_CONVOLUTION:
3741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
3751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
3771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= FAST_PATH_SEPARABLE_CONVOLUTION_FILTER;
3781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
3791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    default:
3811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
3821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
3831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Repeat mode */
3861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    switch (image->common.repeat)
3871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_REPEAT_NONE:
3891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |=
3901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_REFLECT_REPEAT		|
3911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_PAD_REPEAT		|
3921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_NORMAL_REPEAT;
3931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
3941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_REPEAT_REFLECT:
3961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |=
3971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_PAD_REPEAT		|
3981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_NONE_REPEAT		|
3991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_NORMAL_REPEAT;
4001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
4011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_REPEAT_PAD:
4031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |=
4041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_REFLECT_REPEAT		|
4051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_NONE_REPEAT		|
4061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_NORMAL_REPEAT;
4071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
4081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    default:
4101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |=
4111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_REFLECT_REPEAT		|
4121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_PAD_REPEAT		|
4131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    FAST_PATH_NO_NONE_REPEAT;
4141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
4151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
4161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Component alpha */
4181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.component_alpha)
4191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= FAST_PATH_COMPONENT_ALPHA;
4201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
4211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= FAST_PATH_UNIFIED_ALPHA;
4221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);
4241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Type specific checks */
4261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    switch (image->type)
4271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
4281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case SOLID:
4291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	code = PIXMAN_solid;
4301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->solid.color.alpha == 0xffff)
4321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags |= FAST_PATH_IS_OPAQUE;
4331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
4341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case BITS:
4361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->bits.width == 1	&&
4371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->bits.height == 1	&&
4381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->common.repeat != PIXMAN_REPEAT_NONE)
4391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
4401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    code = PIXMAN_solid;
4411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
4421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else
4431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
4441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    code = image->bits.format;
4451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags |= FAST_PATH_BITS_IMAGE;
4461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
4471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!PIXMAN_FORMAT_A (image->bits.format)				&&
4491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY		&&
4501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
4511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
4521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags |= FAST_PATH_SAMPLES_OPAQUE;
4531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (image->common.repeat != PIXMAN_REPEAT_NONE)
4551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		flags |= FAST_PATH_IS_OPAQUE;
4561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
4571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->bits.read_func || image->bits.write_func)
4591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags &= ~FAST_PATH_NO_ACCESSORS;
4601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
4621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags &= ~FAST_PATH_NARROW_FORMAT;
4631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
4641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case RADIAL:
4661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	code = PIXMAN_unknown;
4671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/*
4691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * As explained in pixman-radial-gradient.c, every point of
4701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * the plane has a valid associated radius (and thus will be
4711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * colored) if and only if a is negative (i.e. one of the two
4721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * circles contains the other one).
4731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 */
4741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        if (image->radial.a >= 0)
4761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
4771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* Fall through */
4791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case CONICAL:
4811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case LINEAR:
4821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	code = PIXMAN_unknown;
4831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->common.repeat != PIXMAN_REPEAT_NONE)
4851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
4861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    int i;
4871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags |= FAST_PATH_IS_OPAQUE;
4891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    for (i = 0; i < image->gradient.n_stops; ++i)
4901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
4911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		if (image->gradient.stops[i].color.alpha != 0xffff)
4921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		{
4931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		    flags &= ~FAST_PATH_IS_OPAQUE;
4941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		    break;
4951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		}
4961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
4971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
4981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
4991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    default:
5011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	code = PIXMAN_unknown;
5021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
5031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Alpha map */
5061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!image->common.alpha_map)
5071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags |= FAST_PATH_NO_ALPHA_MAP;
5091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
5111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
5131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    flags &= ~FAST_PATH_NARROW_FORMAT;
5141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Both alpha maps and convolution filters can introduce
5171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * non-opaqueness in otherwise opaque images. Also
5181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * an image with component alpha turned on is only opaque
5191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * if all channels are opaque, so we simply turn it off
5201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * unconditionally for those images.
5211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
5221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.alpha_map						||
5231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	image->common.filter == PIXMAN_FILTER_CONVOLUTION		||
5241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        image->common.filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION     ||
5251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	image->common.component_alpha)
5261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
5281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.flags = flags;
5311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.extended_format_code = code;
5321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
5331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5341176bdada62cabc6ec4b0308a930e83b679d5d36John Reckvoid
5351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_image_validate (pixman_image_t *image)
5361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
5371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.dirty)
5381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	compute_image_info (image);
5401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* It is important that property_changed is
5421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * called *after* compute_image_info() because
5431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * property_changed() can make use of the flags
5441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * to set up accessors etc.
5451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 */
5461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->common.property_changed)
5471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->common.property_changed (image);
5481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	image->common.dirty = FALSE;
5501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.alpha_map)
5531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	_pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
5541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
5551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5561176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
5571176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_clip_region32 (pixman_image_t *   image,
5581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                pixman_region32_t *region)
5591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
5601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_common_t *common = (image_common_t *)image;
5611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_bool_t result;
5621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (region)
5641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if ((result = pixman_region32_copy (&common->clip_region, region)))
5661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->common.have_clip_region = TRUE;
5671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
5691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	_pixman_image_reset_clip_region (image);
5711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	result = TRUE;
5731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
5761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return result;
5781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
5791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5801176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
5811176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_clip_region (pixman_image_t *   image,
5821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              pixman_region16_t *region)
5831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
5841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_common_t *common = (image_common_t *)image;
5851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_bool_t result;
5861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (region)
5881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
5901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    image->common.have_clip_region = TRUE;
5911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
5931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	_pixman_image_reset_clip_region (image);
5951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	result = TRUE;
5971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
6001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return result;
6021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
6031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6041176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
6051176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_has_client_clip (pixman_image_t *image,
6061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                  pixman_bool_t   client_clip)
6071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
6081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.client_clip = client_clip;
6091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
6101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6111176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
6121176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_transform (pixman_image_t *          image,
6131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            const pixman_transform_t *transform)
6141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
6151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    static const pixman_transform_t id =
6161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{ { pixman_fixed_1, 0, 0 },
6181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	  { 0, pixman_fixed_1, 0 },
6191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	  { 0, 0, pixman_fixed_1 } }
6201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
6211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_common_t *common = (image_common_t *)image;
6231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_bool_t result;
6241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (common->transform == transform)
6261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
6271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!transform || memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
6291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	free (common->transform);
6311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	common->transform = NULL;
6321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	result = TRUE;
6331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	goto out;
6351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (common->transform &&
6381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0)
6391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
6411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (common->transform == NULL)
6441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	common->transform = malloc (sizeof (pixman_transform_t));
6451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (common->transform == NULL)
6471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	result = FALSE;
6491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	goto out;
6511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    memcpy (common->transform, transform, sizeof(pixman_transform_t));
6541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    result = TRUE;
6561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6571176bdada62cabc6ec4b0308a930e83b679d5d36John Reckout:
6581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
6591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return result;
6611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
6621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6631176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
6641176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_repeat (pixman_image_t *image,
6651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         pixman_repeat_t repeat)
6661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
6671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.repeat == repeat)
6681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return;
6691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.repeat = repeat;
6711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
6731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
6741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6751176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
6761176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_filter (pixman_image_t *      image,
6771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         pixman_filter_t       filter,
6781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         const pixman_fixed_t *params,
6791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         int                   n_params)
6801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
6811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_common_t *common = (image_common_t *)image;
6821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_t *new_params;
6831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (params == common->filter_params && filter == common->filter)
6851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
6861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION)
6881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int width = pixman_fixed_to_int (params[0]);
6901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int height = pixman_fixed_to_int (params[1]);
6911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int x_phase_bits = pixman_fixed_to_int (params[2]);
6921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int y_phase_bits = pixman_fixed_to_int (params[3]);
6931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int n_x_phases = (1 << x_phase_bits);
6941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int n_y_phases = (1 << y_phase_bits);
6951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return_val_if_fail (
6971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    n_params == 4 + n_x_phases * width + n_y_phases * height, FALSE);
6981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    new_params = NULL;
7011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (params)
7021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
7031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
7041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!new_params)
7051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
7061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	memcpy (new_params,
7081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	        params, n_params * sizeof (pixman_fixed_t));
7091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
7101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->filter = filter;
7121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (common->filter_params)
7141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	free (common->filter_params);
7151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->filter_params = new_params;
7171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->n_filter_params = n_params;
7181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
7201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return TRUE;
7211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
7221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7231176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
7241176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_source_clipping (pixman_image_t *image,
7251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                  pixman_bool_t   clip_sources)
7261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
7271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.clip_sources == clip_sources)
7281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return;
7291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.clip_sources = clip_sources;
7311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
7331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
7341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* Unlike all the other property setters, this function does not
7361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * copy the content of indexed. Doing this copying is simply
7371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * way, way too expensive.
7381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
7391176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
7401176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_indexed (pixman_image_t *        image,
7411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          const pixman_indexed_t *indexed)
7421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
7431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    bits_image_t *bits = (bits_image_t *)image;
7441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (bits->indexed == indexed)
7461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return;
7471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    bits->indexed = indexed;
7491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
7511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
7521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7531176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
7541176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_alpha_map (pixman_image_t *image,
7551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            pixman_image_t *alpha_map,
7561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int16_t         x,
7571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int16_t         y)
7581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
7591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_common_t *common = (image_common_t *)image;
7601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return_if_fail (!alpha_map || alpha_map->type == BITS);
7621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (alpha_map && common->alpha_count > 0)
7641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
7651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* If this image is being used as an alpha map itself,
7661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * then you can't give it an alpha map of its own.
7671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 */
7681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return;
7691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
7701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (alpha_map && alpha_map->common.alpha_map)
7721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
7731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* If the image has an alpha map of its own,
7741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * then it can't be used as an alpha map itself
7751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 */
7761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return;
7771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
7781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (common->alpha_map != (bits_image_t *)alpha_map)
7801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
7811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (common->alpha_map)
7821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
7831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    common->alpha_map->common.alpha_count--;
7841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_image_unref ((pixman_image_t *)common->alpha_map);
7861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
7871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (alpha_map)
7891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
7901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
7911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    common->alpha_map->common.alpha_count++;
7931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
7941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else
7951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
7961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    common->alpha_map = NULL;
7971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
7981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
7991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->alpha_origin_x = x;
8011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    common->alpha_origin_y = y;
8021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
8041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8061176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
8071176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_component_alpha   (pixman_image_t *image,
8081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                    pixman_bool_t   component_alpha)
8091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.component_alpha == component_alpha)
8111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return;
8121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image->common.component_alpha = component_alpha;
8141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_property_changed (image);
8161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8181176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
8191176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_get_component_alpha   (pixman_image_t       *image)
8201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return image->common.component_alpha;
8221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8241176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
8251176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_set_accessors (pixman_image_t *           image,
8261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            pixman_read_memory_func_t  read_func,
8271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            pixman_write_memory_func_t write_func)
8281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return_if_fail (image != NULL);
8301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->type == BITS)
8321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	image->bits.read_func = read_func;
8341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	image->bits.write_func = write_func;
8351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	image_property_changed (image);
8371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
8381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8401176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT uint32_t *
8411176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_get_data (pixman_image_t *image)
8421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->type == BITS)
8441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return image->bits.bits;
8451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return NULL;
8471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8491176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT int
8501176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_get_width (pixman_image_t *image)
8511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->type == BITS)
8531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return image->bits.width;
8541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return 0;
8561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8581176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT int
8591176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_get_height (pixman_image_t *image)
8601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->type == BITS)
8621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return image->bits.height;
8631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return 0;
8651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8671176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT int
8681176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_get_stride (pixman_image_t *image)
8691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->type == BITS)
8711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return image->bits.rowstride * (int) sizeof (uint32_t);
8721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return 0;
8741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8761176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT int
8771176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_get_depth (pixman_image_t *image)
8781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->type == BITS)
8801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return PIXMAN_FORMAT_DEPTH (image->bits.format);
8811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return 0;
8831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8851176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_format_code_t
8861176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_get_format (pixman_image_t *image)
8871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->type == BITS)
8891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return image->bits.format;
8901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return PIXMAN_null;
8921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8941176bdada62cabc6ec4b0308a930e83b679d5d36John Reckuint32_t
8951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_image_get_solid (pixman_implementation_t *imp,
8961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			 pixman_image_t *         image,
8971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         pixman_format_code_t     format)
8981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t result;
9001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->type == SOLID)
9021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
9031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	result = image->solid.color_32;
9041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
9051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else if (image->type == BITS)
9061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
9071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->bits.format == PIXMAN_a8r8g8b8)
9081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    result = image->bits.bits[0];
9091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else if (image->bits.format == PIXMAN_x8r8g8b8)
9101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    result = image->bits.bits[0] | 0xff000000;
9111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else if (image->bits.format == PIXMAN_a8)
9121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    result = (*(uint8_t *)image->bits.bits) << 24;
9131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else
9141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    goto otherwise;
9151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
9161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
9171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
9181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_iter_t iter;
9191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    otherwise:
9211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	_pixman_implementation_src_iter_init (
9221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    imp, &iter, image, 0, 0, 1, 1,
9231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    (uint8_t *)&result,
9241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ITER_NARROW, image->common.flags);
9251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	result = *iter.get_scanline (&iter, NULL);
9271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
9281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* If necessary, convert RGB <--> BGR. */
9301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB
9311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	&& PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB_SRGB)
9321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
9331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	result = (((result & 0xff000000) >>  0) |
9341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	          ((result & 0x00ff0000) >> 16) |
9351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	          ((result & 0x0000ff00) >>  0) |
9361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	          ((result & 0x000000ff) << 16));
9371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
9381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return result;
9401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
941