pixman.c revision 1176bdada62cabc6ec4b0308a930e83b679d5d36
11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2000 SuSE, Inc.
41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2007 Red Hat, Inc.
51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Permission to use, copy, modify, distribute, and sell this software and its
71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation for any purpose is hereby granted without fee, provided that
81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the above copyright notice appear in all copies and that both that
91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * copyright notice and this permission notice appear in supporting
101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation, and that the name of SuSE not be used in advertising or
111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * publicity pertaining to distribution of the software without specific,
121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * written prior permission.  SuSE makes no representations about the
131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * suitability of this software for any purpose.  It is provided "as is"
141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * without express or implied warranty.
151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Author:  Keith Packard, SuSE, Inc.
241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifdef HAVE_CONFIG_H
271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <config.h>
281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif
291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "pixman-private.h"
301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdlib.h>
321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
331176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_implementation_t *global_implementation;
341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
361176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void __attribute__((constructor))
371176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_constructor (void)
381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    global_implementation = _pixman_choose_implementation ();
401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif
421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
431176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef struct operator_info_t operator_info_t;
441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
451176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstruct operator_info_t
461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint8_t	opaque_info[4];
481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck};
491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define PACK(neither, src, dest, both)			\
511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{	    (uint8_t)PIXMAN_OP_ ## neither,		\
521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    (uint8_t)PIXMAN_OP_ ## src,			\
531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    (uint8_t)PIXMAN_OP_ ## dest,		\
541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    (uint8_t)PIXMAN_OP_ ## both		}}
551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
561176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic const operator_info_t operator_table[] =
571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /*    Neither Opaque         Src Opaque             Dst Opaque             Both Opaque */
591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (SRC,                   SRC,                   SRC,                   SRC),
611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DST,                   DST,                   DST,                   DST),
621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (OVER,                  SRC,                   OVER,                  SRC),
631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (OVER_REVERSE,          OVER_REVERSE,          DST,                   DST),
641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (IN,                    IN,                    SRC,                   SRC),
651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (IN_REVERSE,            DST,                   IN_REVERSE,            DST),
661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (OUT,                   OUT,                   CLEAR,                 CLEAR),
671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (OUT_REVERSE,           CLEAR,                 OUT_REVERSE,           CLEAR),
681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (ATOP,                  IN,                    OVER,                  SRC),
691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (ATOP_REVERSE,          OVER_REVERSE,          IN_REVERSE,            DST),
701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (XOR,                   OUT,                   OUT_REVERSE,           CLEAR),
711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (ADD,                   ADD,                   ADD,                   ADD),
721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (SATURATE,              OVER_REVERSE,          DST,                   DST),
731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x0e */ }},
751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x0f */ }},
761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (SRC,                   SRC,                   SRC,                   SRC),
791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DST,                   DST,                   DST,                   DST),
801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER),
811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN),
831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE),
841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT),
851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE),
861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP),
871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR),
891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x1c */ }},
911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x1d */ }},
921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x1e */ }},
931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x1f */ }},
941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (SRC,                   SRC,                   SRC,                   SRC),
971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DST,                   DST,                   DST,                   DST),
981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER),
991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN),
1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE),
1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT),
1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE),
1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP),
1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR),
1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x2c */ }},
1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x2d */ }},
1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x2e */ }},
1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {{ 0 /* 0x2f */ }},
1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (MULTIPLY,              MULTIPLY,              MULTIPLY,              MULTIPLY),
1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (SCREEN,                SCREEN,                SCREEN,                SCREEN),
1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (OVERLAY,               OVERLAY,               OVERLAY,               OVERLAY),
1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DARKEN,                DARKEN,                DARKEN,                DARKEN),
1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (LIGHTEN,               LIGHTEN,               LIGHTEN,               LIGHTEN),
1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE),
1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (COLOR_BURN,            COLOR_BURN,            COLOR_BURN,            COLOR_BURN),
1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT),
1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT),
1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (DIFFERENCE,            DIFFERENCE,            DIFFERENCE,            DIFFERENCE),
1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (EXCLUSION,             EXCLUSION,             EXCLUSION,             EXCLUSION),
1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (HSL_HUE,               HSL_HUE,               HSL_HUE,               HSL_HUE),
1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION),
1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (HSL_COLOR,             HSL_COLOR,             HSL_COLOR,             HSL_COLOR),
1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    PACK (HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY),
1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck};
1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Optimize the current operator based on opacity of source or destination
1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * The output operator should be mathematically equivalent to the source.
1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic pixman_op_t
1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reckoptimize_operator (pixman_op_t     op,
1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		   uint32_t        src_flags,
1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		   uint32_t        mask_flags,
1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		   uint32_t        dst_flags)
1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_bool_t is_source_opaque, is_dest_opaque;
1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define OPAQUE_SHIFT 13
1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    is_dest_opaque >>= OPAQUE_SHIFT - 1;
1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    is_source_opaque >>= OPAQUE_SHIFT;
1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Computing composite region
1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic inline pixman_bool_t
1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reckclip_general_image (pixman_region32_t * region,
1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                    pixman_region32_t * clip,
1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                    int                 dx,
1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                    int                 dy)
1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (pixman_region32_n_rects (region) == 1 &&
1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        pixman_region32_n_rects (clip) == 1)
1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int v;
1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (rbox->x1 < (v = cbox->x1 + dx))
1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    rbox->x1 = v;
1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (rbox->x2 > (v = cbox->x2 + dx))
1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    rbox->x2 = v;
1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (rbox->y1 < (v = cbox->y1 + dy))
1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    rbox->y1 = v;
1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (rbox->y2 > (v = cbox->y2 + dy))
1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    rbox->y2 = v;
1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_region32_init (region);
1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else if (!pixman_region32_not_empty (clip))
1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (dx || dy)
1921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_region32_translate (region, -dx, -dy);
1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!pixman_region32_intersect (region, region, clip))
1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (dx || dy)
1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_region32_translate (region, dx, dy);
1991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return pixman_region32_not_empty (region);
2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2041176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic inline pixman_bool_t
2051176bdada62cabc6ec4b0308a930e83b679d5d36John Reckclip_source_image (pixman_region32_t * region,
2061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                   pixman_image_t *    image,
2071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                   int                 dx,
2081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                   int                 dy)
2091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Source clips are ignored, unless they are explicitly turned on
2111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * and the clip in question was set by an X client. (Because if
2121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * the clip was not set by a client, then it is a hierarchy
2131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * clip and those should always be ignored for sources).
2141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
2151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!image->common.clip_sources || !image->common.client_clip)
2161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
2171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return clip_general_image (region,
2191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                               &image->common.clip_region,
2201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                               dx, dy);
2211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
2241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * returns FALSE if the final region is empty.  Indistinguishable from
2251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * an allocation failure, but rendering ignores those anyways.
2261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
2271176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t
2281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_compute_composite_region32 (pixman_region32_t * region,
2291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    pixman_image_t *    src_image,
2301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    pixman_image_t *    mask_image,
2311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    pixman_image_t *    dest_image,
2321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    int32_t             src_x,
2331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    int32_t             src_y,
2341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    int32_t             mask_x,
2351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    int32_t             mask_y,
2361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    int32_t             dest_x,
2371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    int32_t             dest_y,
2381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    int32_t             width,
2391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    int32_t             height)
2401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->extents.x1 = dest_x;
2421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->extents.x2 = dest_x + width;
2431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->extents.y1 = dest_y;
2441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->extents.y2 = dest_y + height;
2451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->extents.x1 = MAX (region->extents.x1, 0);
2471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->extents.y1 = MAX (region->extents.y1, 0);
2481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
2491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
2501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    region->data = 0;
2521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Check for empty operation */
2541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (region->extents.x1 >= region->extents.x2 ||
2551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        region->extents.y1 >= region->extents.y2)
2561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	region->extents.x1 = 0;
2581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	region->extents.x2 = 0;
2591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	region->extents.y1 = 0;
2601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	region->extents.y2 = 0;
2611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
2621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (dest_image->common.have_clip_region)
2651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
2671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
2681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (dest_image->common.alpha_map)
2711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!pixman_region32_intersect_rect (region, region,
2731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					     dest_image->common.alpha_origin_x,
2741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					     dest_image->common.alpha_origin_y,
2751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					     dest_image->common.alpha_map->width,
2761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					     dest_image->common.alpha_map->height))
2771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
2791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
2801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!pixman_region32_not_empty (region))
2811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
2821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (dest_image->common.alpha_map->common.have_clip_region)
2831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
2851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				     -dest_image->common.alpha_origin_x,
2861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				     -dest_image->common.alpha_origin_y))
2871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
2881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		return FALSE;
2891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
2901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
2911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* clip against src */
2941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (src_image->common.have_clip_region)
2951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
2971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
2981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
3001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
3021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	                        dest_x - (src_x - src_image->common.alpha_origin_x),
3031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	                        dest_y - (src_y - src_image->common.alpha_origin_y)))
3041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
3051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
3061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
3071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* clip against mask */
3091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (mask_image && mask_image->common.have_clip_region)
3101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
3121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
3131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
3151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
3161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
3171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	                            dest_x - (mask_x - mask_image->common.alpha_origin_x),
3181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	                            dest_y - (mask_y - mask_image->common.alpha_origin_y)))
3191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
3201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		return FALSE;
3211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
3221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
3231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return TRUE;
3261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
3271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3281176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef struct
3291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
3301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_48_16_t	x1;
3311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_48_16_t	y1;
3321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_48_16_t	x2;
3331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_48_16_t	y2;
3341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} box_48_16_t;
3351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3361176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic pixman_bool_t
3371176bdada62cabc6ec4b0308a930e83b679d5d36John Reckcompute_transformed_extents (pixman_transform_t *transform,
3381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			     const pixman_box32_t *extents,
3391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			     box_48_16_t *transformed)
3401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
3411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
3421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_t x1, y1, x2, y2;
3431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int i;
3441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
3461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
3471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
3481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
3491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!transform)
3511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	transformed->x1 = x1;
3531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	transformed->y1 = y1;
3541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	transformed->x2 = x2;
3551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	transformed->y2 = y2;
3561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
3581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    tx1 = ty1 = INT64_MAX;
3611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    tx2 = ty2 = INT64_MIN;
3621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (i = 0; i < 4; ++i)
3641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_fixed_48_16_t tx, ty;
3661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_vector_t v;
3671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	v.vector[0] = (i & 0x01)? x1 : x2;
3691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	v.vector[1] = (i & 0x02)? y1 : y2;
3701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	v.vector[2] = pixman_fixed_1;
3711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!pixman_transform_point (transform, &v))
3731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
3741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	tx = (pixman_fixed_48_16_t)v.vector[0];
3761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	ty = (pixman_fixed_48_16_t)v.vector[1];
3771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (tx < tx1)
3791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    tx1 = tx;
3801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (ty < ty1)
3811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ty1 = ty;
3821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (tx > tx2)
3831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    tx2 = tx;
3841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (ty > ty2)
3851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ty2 = ty;
3861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transformed->x1 = tx1;
3891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transformed->y1 = ty1;
3901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transformed->x2 = tx2;
3911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transformed->y2 = ty2;
3921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return TRUE;
3941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
3951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
3971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define ABS(f)      (((f) < 0)?  (-(f)) : (f))
3981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
3991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4001176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic pixman_bool_t
4011176bdada62cabc6ec4b0308a930e83b679d5d36John Reckanalyze_extent (pixman_image_t       *image,
4021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		const pixman_box32_t *extents,
4031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		uint32_t             *flags)
4041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
4051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_transform_t *transform;
4061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_t x_off, y_off;
4071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_t width, height;
4081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_t *params;
4091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    box_48_16_t transformed;
4101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_box32_t exp_extents;
4111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!image)
4131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
4141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Some compositing functions walk one step
4161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * outside the destination rectangle, so we
4171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * check here that the expanded-by-one source
4181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * extents in destination space fits in 16 bits
4191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
4201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!IS_16BIT (extents->x1 - 1)		||
4211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	!IS_16BIT (extents->y1 - 1)		||
4221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	!IS_16BIT (extents->x2 + 1)		||
4231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	!IS_16BIT (extents->y2 + 1))
4241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
4251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
4261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
4271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transform = image->common.transform;
4291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.type == BITS)
4301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
4311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* During repeat mode calculations we might convert the
4321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * width/height of an image to fixed 16.16, so we need
4331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * them to be smaller than 16 bits.
4341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 */
4351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (image->bits.width >= 0x7fff	|| image->bits.height >= 0x7fff)
4361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
4371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
4391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    extents->x1 >= 0 &&
4401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    extents->y1 >= 0 &&
4411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    extents->x2 <= image->bits.width &&
4421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    extents->y2 <= image->bits.height)
4431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
4441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
4451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return TRUE;
4461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
4471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	switch (image->common.filter)
4491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
4501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case PIXMAN_FILTER_CONVOLUTION:
4511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    params = image->common.filter_params;
4521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
4531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
4541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    width = params[0];
4551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    height = params[1];
4561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
4571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
4591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    params = image->common.filter_params;
4601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
4611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
4621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    width = params[0];
4631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    height = params[1];
4641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
4651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case PIXMAN_FILTER_GOOD:
4671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case PIXMAN_FILTER_BEST:
4681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case PIXMAN_FILTER_BILINEAR:
4691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    x_off = - pixman_fixed_1 / 2;
4701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    y_off = - pixman_fixed_1 / 2;
4711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    width = pixman_fixed_1;
4721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    height = pixman_fixed_1;
4731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
4741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case PIXMAN_FILTER_FAST:
4761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case PIXMAN_FILTER_NEAREST:
4771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    x_off = - pixman_fixed_e;
4781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    y_off = - pixman_fixed_e;
4791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    width = 0;
4801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    height = 0;
4811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
4821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	default:
4841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return FALSE;
4851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
4861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
4871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
4881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
4891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	x_off = 0;
4901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	y_off = 0;
4911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	width = 0;
4921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	height = 0;
4931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
4941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!compute_transformed_extents (transform, extents, &transformed))
4961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
4971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Expand the source area by a tiny bit so account of different rounding that
4991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
5001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * 0.5 so this won't cause the area computed to be overly pessimistic.
5011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
5021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transformed.x1 -= 8 * pixman_fixed_e;
5031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transformed.y1 -= 8 * pixman_fixed_e;
5041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transformed.x2 += 8 * pixman_fixed_e;
5051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    transformed.y2 += 8 * pixman_fixed_e;
5061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (image->common.type == BITS)
5081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (pixman_fixed_to_int (transformed.x1) >= 0			&&
5101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_fixed_to_int (transformed.y1) >= 0			&&
5111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_fixed_to_int (transformed.x2) < image->bits.width	&&
5121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_fixed_to_int (transformed.y2) < image->bits.height)
5131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
5141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
5151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
5161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0		  &&
5181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0		  &&
5191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
5201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
5211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
5221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
5231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
5241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Check we don't overflow when the destination extents are expanded by one.
5271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * This ensures that compositing functions can simply walk the source space
5281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * using 16.16 variables without worrying about overflow.
5291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
5301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    exp_extents = *extents;
5311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    exp_extents.x1 -= 1;
5321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    exp_extents.y1 -= 1;
5331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    exp_extents.x2 += 1;
5341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    exp_extents.y2 += 1;
5351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!compute_transformed_extents (transform, &exp_extents, &transformed))
5371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
5381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e)	||
5401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	!IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e)	||
5411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	!IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width)	||
5421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	!IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
5431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
5441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
5451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
5461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return TRUE;
5481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
5491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
5511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Work around GCC bug causing crashes in Mozilla with SSE2
5521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
5531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * When using -msse, gcc generates movdqa instructions assuming that
5541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the stack is 16 byte aligned. Unfortunately some applications, such
5551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
5561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * causes the movdqa instructions to fail.
5571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
5581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * The __force_align_arg_pointer__ makes gcc generate a prologue that
5591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * realigns the stack pointer to 16 bytes.
5601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
5611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * On x86-64 this is not necessary because the standard ABI already
5621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * calls for a 16 byte aligned stack.
5631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
5641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
5651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
5661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
5671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck__attribute__((__force_align_arg_pointer__))
5681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif
5691176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
5701176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_composite32 (pixman_op_t      op,
5711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          pixman_image_t * src,
5721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          pixman_image_t * mask,
5731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          pixman_image_t * dest,
5741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          int32_t          src_x,
5751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          int32_t          src_y,
5761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          int32_t          mask_x,
5771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          int32_t          mask_y,
5781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          int32_t          dest_x,
5791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          int32_t          dest_y,
5801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          int32_t          width,
5811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                          int32_t          height)
5821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
5831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_format_code_t src_format, mask_format, dest_format;
5841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_region32_t region;
5851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_box32_t extents;
5861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_implementation_t *imp;
5871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_composite_func_t func;
5881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_composite_info_t info;
5891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    const pixman_box32_t *pbox;
5901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int n;
5911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    _pixman_image_validate (src);
5931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (mask)
5941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	_pixman_image_validate (mask);
5951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    _pixman_image_validate (dest);
5961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
5971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_format = src->common.extended_format_code;
5981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    info.src_flags = src->common.flags;
5991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE))
6011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	mask_format = mask->common.extended_format_code;
6031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.mask_flags = mask->common.flags;
6041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
6061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	mask_format = PIXMAN_null;
6081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.mask_flags = FAST_PATH_IS_OPAQUE;
6091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dest_format = dest->common.extended_format_code;
6121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    info.dest_flags = dest->common.flags;
6131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Check for pixbufs */
6151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
6161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	(src->type == BITS && src->bits.bits == mask->bits.bits)	   &&
6171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	(src->common.repeat == mask->common.repeat)			   &&
6181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	(info.src_flags & info.mask_flags & FAST_PATH_ID_TRANSFORM)	   &&
6191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	(src_x == mask_x && src_y == mask_y))
6201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (src_format == PIXMAN_x8b8g8r8)
6221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    src_format = mask_format = PIXMAN_pixbuf;
6231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else if (src_format == PIXMAN_x8r8g8b8)
6241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    src_format = mask_format = PIXMAN_rpixbuf;
6251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_region32_init (&region);
6281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!_pixman_compute_composite_region32 (
6301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    &region, src, mask, dest,
6311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
6321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	goto out;
6341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents = *pixman_region32_extents (&region);
6371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents.x1 -= dest_x - src_x;
6391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents.y1 -= dest_y - src_y;
6401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents.x2 -= dest_x - src_x;
6411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents.y2 -= dest_y - src_y;
6421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!analyze_extent (src, &extents, &info.src_flags))
6441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	goto out;
6451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents.x1 -= src_x - mask_x;
6471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents.y1 -= src_y - mask_y;
6481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents.x2 -= src_x - mask_x;
6491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    extents.y2 -= src_y - mask_y;
6501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!analyze_extent (mask, &extents, &info.mask_flags))
6521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	goto out;
6531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* If the clip is within the source samples, and the samples are
6551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * opaque, then the source is effectively opaque.
6561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
6571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define NEAREST_OPAQUE	(FAST_PATH_SAMPLES_OPAQUE |			\
6581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			 FAST_PATH_NEAREST_FILTER |			\
6591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			 FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
6601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define BILINEAR_OPAQUE	(FAST_PATH_SAMPLES_OPAQUE |			\
6611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			 FAST_PATH_BILINEAR_FILTER |			\
6621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			 FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
6631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if ((info.src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
6651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	(info.src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
6661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.src_flags |= FAST_PATH_IS_OPAQUE;
6681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if ((info.mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
6711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	(info.mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
6721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.mask_flags |= FAST_PATH_IS_OPAQUE;
6741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
6751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /*
6771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * Check if we can replace our operator by a simpler one
6781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * if the src or dest are opaque. The output operator should be
6791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     * mathematically equivalent to the source.
6801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
6811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    info.op = optimize_operator (op, info.src_flags, info.mask_flags, info.dest_flags);
6821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    _pixman_implementation_lookup_composite (
6841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	get_implementation (), info.op,
6851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	src_format, info.src_flags,
6861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	mask_format, info.mask_flags,
6871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	dest_format, info.dest_flags,
6881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	&imp, &func);
6891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    info.src_image = src;
6911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    info.mask_image = mask;
6921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    info.dest_image = dest;
6931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pbox = pixman_region32_rectangles (&region, &n);
6951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
6961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    while (n--)
6971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
6981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.src_x = pbox->x1 + src_x - dest_x;
6991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.src_y = pbox->y1 + src_y - dest_y;
7001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.mask_x = pbox->x1 + mask_x - dest_x;
7011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.mask_y = pbox->y1 + mask_y - dest_y;
7021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.dest_x = pbox->x1;
7031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.dest_y = pbox->y1;
7041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.width = pbox->x2 - pbox->x1;
7051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	info.height = pbox->y2 - pbox->y1;
7061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	func (imp, &info);
7081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pbox++;
7101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
7111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7121176bdada62cabc6ec4b0308a930e83b679d5d36John Reckout:
7131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_region32_fini (&region);
7141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
7151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7161176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT void
7171176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_composite (pixman_op_t      op,
7181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        pixman_image_t * src,
7191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        pixman_image_t * mask,
7201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        pixman_image_t * dest,
7211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        int16_t          src_x,
7221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        int16_t          src_y,
7231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        int16_t          mask_x,
7241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        int16_t          mask_y,
7251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        int16_t          dest_x,
7261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        int16_t          dest_y,
7271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        uint16_t         width,
7281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                        uint16_t         height)
7291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
7301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
7311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              mask_x, mask_y, dest_x, dest_y, width, height);
7321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
7331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7341176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
7351176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_blt (uint32_t *src_bits,
7361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            uint32_t *dst_bits,
7371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       src_stride,
7381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       dst_stride,
7391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       src_bpp,
7401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       dst_bpp,
7411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       src_x,
7421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       src_y,
7431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       dest_x,
7441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       dest_y,
7451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       width,
7461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int       height)
7471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
7481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return _pixman_implementation_blt (get_implementation(),
7491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       src_bits, dst_bits, src_stride, dst_stride,
7501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       src_bpp, dst_bpp,
7511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       src_x, src_y,
7521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       dest_x, dest_y,
7531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       width, height);
7541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
7551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7561176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
7571176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_fill (uint32_t *bits,
7581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck             int       stride,
7591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck             int       bpp,
7601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck             int       x,
7611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck             int       y,
7621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck             int       width,
7631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck             int       height,
7641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck             uint32_t  filler)
7651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
7661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return _pixman_implementation_fill (
7671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	get_implementation(), bits, stride, bpp, x, y, width, height, filler);
7681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
7691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7701176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t
7711176bdada62cabc6ec4b0308a930e83b679d5d36John Reckcolor_to_uint32 (const pixman_color_t *color)
7721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
7731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return
7741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        (color->alpha >> 8 << 24) |
7751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        (color->red >> 8 << 16) |
7761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        (color->green & 0xff00) |
7771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        (color->blue >> 8);
7781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
7791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7801176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic pixman_bool_t
7811176bdada62cabc6ec4b0308a930e83b679d5d36John Reckcolor_to_pixel (const pixman_color_t *color,
7821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                uint32_t *            pixel,
7831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                pixman_format_code_t  format)
7841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
7851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t c = color_to_uint32 (color);
7861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
7871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!(format == PIXMAN_a8r8g8b8     ||
7881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_x8r8g8b8     ||
7891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_a8b8g8r8     ||
7901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_x8b8g8r8     ||
7911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_b8g8r8a8     ||
7921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_b8g8r8x8     ||
7931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_r8g8b8a8     ||
7941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_r8g8b8x8     ||
7951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_r5g6b5       ||
7961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_b5g6r5       ||
7971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_a8           ||
7981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck          format == PIXMAN_a1))
7991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
8011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
8021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
8041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	c = ((c & 0xff000000) >>  0) |
8061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ((c & 0x00ff0000) >> 16) |
8071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ((c & 0x0000ff00) >>  0) |
8081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ((c & 0x000000ff) << 16);
8091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
8101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
8111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	c = ((c & 0xff000000) >> 24) |
8131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ((c & 0x00ff0000) >>  8) |
8141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ((c & 0x0000ff00) <<  8) |
8151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ((c & 0x000000ff) << 24);
8161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
8171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
8181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	c = ((c & 0xff000000) >> 24) | (c << 8);
8191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (format == PIXMAN_a1)
8211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	c = c >> 31;
8221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else if (format == PIXMAN_a8)
8231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	c = c >> 24;
8241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else if (format == PIXMAN_r5g6b5 ||
8251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck             format == PIXMAN_b5g6r5)
8261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	c = convert_8888_to_0565 (c);
8271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if 0
8291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
8301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    printf ("pixel: %x\n", c);
8311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif
8321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    *pixel = c;
8341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return TRUE;
8351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8371176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
8381176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_fill_rectangles (pixman_op_t                 op,
8391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              pixman_image_t *            dest,
8401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			      const pixman_color_t *      color,
8411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              int                         n_rects,
8421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              const pixman_rectangle16_t *rects)
8431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_box32_t stack_boxes[6];
8451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_box32_t *boxes;
8461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_bool_t result;
8471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int i;
8481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (n_rects > 6)
8501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
8521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        if (boxes == NULL)
8531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            return FALSE;
8541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
8551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
8561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        boxes = stack_boxes;
8581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
8591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (i = 0; i < n_rects; ++i)
8611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        boxes[i].x1 = rects[i].x;
8631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        boxes[i].y1 = rects[i].y;
8641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        boxes[i].x2 = boxes[i].x1 + rects[i].width;
8651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        boxes[i].y2 = boxes[i].y1 + rects[i].height;
8661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
8671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
8691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (boxes != stack_boxes)
8711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        free (boxes);
8721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return result;
8741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
8751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8761176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
8771176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_fill_boxes (pixman_op_t           op,
8781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         pixman_image_t *      dest,
8791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         const pixman_color_t *color,
8801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         int                   n_boxes,
8811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         const pixman_box32_t *boxes)
8821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
8831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_t *solid;
8841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_color_t c;
8851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int i;
8861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    _pixman_image_validate (dest);
8881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (color->alpha == 0xffff)
8901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        if (op == PIXMAN_OP_OVER)
8921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            op = PIXMAN_OP_SRC;
8931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
8941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
8951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (op == PIXMAN_OP_CLEAR)
8961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
8971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        c.red = 0;
8981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        c.green = 0;
8991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        c.blue = 0;
9001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        c.alpha = 0;
9011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        color = &c;
9031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        op = PIXMAN_OP_SRC;
9051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
9061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (op == PIXMAN_OP_SRC)
9081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
9091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        uint32_t pixel;
9101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        if (color_to_pixel (color, &pixel, dest->bits.format))
9121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        {
9131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            pixman_region32_t fill_region;
9141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            int n_rects, j;
9151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            pixman_box32_t *rects;
9161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
9181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                return FALSE;
9191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            if (dest->common.have_clip_region)
9211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            {
9221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                if (!pixman_region32_intersect (&fill_region,
9231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                                &fill_region,
9241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                                &dest->common.clip_region))
9251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                    return FALSE;
9261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            }
9271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            rects = pixman_region32_rectangles (&fill_region, &n_rects);
9291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            for (j = 0; j < n_rects; ++j)
9301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            {
9311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                const pixman_box32_t *rect = &(rects[j]);
9321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
9331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
9341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             pixel);
9351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            }
9361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            pixman_region32_fini (&fill_region);
9381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck            return TRUE;
9391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        }
9401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
9411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    solid = pixman_image_create_solid_fill (color);
9431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!solid)
9441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        return FALSE;
9451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (i = 0; i < n_boxes; ++i)
9471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
9481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        const pixman_box32_t *box = &(boxes[i]);
9491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        pixman_image_composite32 (op, solid, NULL, dest,
9511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                  0, 0, 0, 0,
9521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                  box->x1, box->y1,
9531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                  box->x2 - box->x1, box->y2 - box->y1);
9541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
9551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_unref (solid);
9571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return TRUE;
9591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
9601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/**
9621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * pixman_version:
9631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
9641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Returns the version of the pixman library encoded in a single
9651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
9661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * later versions compare greater than earlier versions.
9671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
9681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * A run-time comparison to check that pixman's version is greater than
9691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * or equal to version X.Y.Z could be performed as follows:
9701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
9711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * <informalexample><programlisting>
9721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
9731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * </programlisting></informalexample>
9741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
9751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * See also pixman_version_string() as well as the compile-time
9761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
9771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
9781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Return value: the encoded version.
9791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck **/
9801176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT int
9811176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_version (void)
9821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
9831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return PIXMAN_VERSION;
9841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
9851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
9861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/**
9871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * pixman_version_string:
9881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
9891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Returns the version of the pixman library as a human-readable string
9901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * of the form "X.Y.Z".
9911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
9921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * See also pixman_version() as well as the compile-time equivalents
9931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
9941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
9951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Return value: a string containing the version.
9961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck **/
9971176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT const char*
9981176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_version_string (void)
9991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
10001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return PIXMAN_VERSION_STRING;
10011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
10021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
10031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/**
10041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * pixman_format_supported_source:
10051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * @format: A pixman_format_code_t format
10061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
10071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Return value: whether the provided format code is a supported
10081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * format for a pixman surface used as a source in
10091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * rendering.
10101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
10111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Currently, all pixman_format_code_t values are supported.
10121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck **/
10131176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
10141176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_format_supported_source (pixman_format_code_t format)
10151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
10161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    switch (format)
10171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
10181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* 32 bpp formats */
10191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a2b10g10r10:
10201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x2b10g10r10:
10211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a2r10g10b10:
10221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x2r10g10b10:
10231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a8r8g8b8:
10241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a8r8g8b8_sRGB:
10251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x8r8g8b8:
10261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a8b8g8r8:
10271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x8b8g8r8:
10281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_b8g8r8a8:
10291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_b8g8r8x8:
10301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_r8g8b8a8:
10311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_r8g8b8x8:
10321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_r8g8b8:
10331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_b8g8r8:
10341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_r5g6b5:
10351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_b5g6r5:
10361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x14r6g6b6:
10371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* 16 bpp formats */
10381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a1r5g5b5:
10391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x1r5g5b5:
10401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a1b5g5r5:
10411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x1b5g5r5:
10421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a4r4g4b4:
10431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x4r4g4b4:
10441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a4b4g4r4:
10451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x4b4g4r4:
10461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* 8bpp formats */
10471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a8:
10481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_r3g3b2:
10491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_b2g3r3:
10501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a2r2g2b2:
10511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a2b2g2r2:
10521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_c8:
10531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_g8:
10541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_x4a4:
10551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Collides with PIXMAN_c8
10561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck       case PIXMAN_x4c4:
10571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
10581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Collides with PIXMAN_g8
10591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck       case PIXMAN_x4g4:
10601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck     */
10611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* 4bpp formats */
10621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a4:
10631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_r1g2b1:
10641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_b1g2r1:
10651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a1r1g1b1:
10661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a1b1g1r1:
10671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_c4:
10681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_g4:
10691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* 1bpp formats */
10701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_a1:
10711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_g1:
10721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* YUV formats */
10731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_yuy2:
10741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case PIXMAN_yv12:
10751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return TRUE;
10761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
10771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    default:
10781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
10791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
10801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
10811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
10821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/**
10831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * pixman_format_supported_destination:
10841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * @format: A pixman_format_code_t format
10851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
10861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Return value: whether the provided format code is a supported
10871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * format for a pixman surface used as a destination in
10881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * rendering.
10891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
10901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Currently, all pixman_format_code_t values are supported
10911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * except for the YUV formats.
10921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck **/
10931176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
10941176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_format_supported_destination (pixman_format_code_t format)
10951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
10961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* YUV formats cannot be written to at the moment */
10971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
10981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return FALSE;
10991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
11001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return pixman_format_supported_source (format);
11011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
11021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
11031176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_bool_t
11041176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_compute_composite_region (pixman_region16_t * region,
11051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 pixman_image_t *    src_image,
11061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 pixman_image_t *    mask_image,
11071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 pixman_image_t *    dest_image,
11081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 int16_t             src_x,
11091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 int16_t             src_y,
11101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 int16_t             mask_x,
11111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 int16_t             mask_y,
11121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 int16_t             dest_x,
11131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 int16_t             dest_y,
11141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 uint16_t            width,
11151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 uint16_t            height)
11161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
11171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_region32_t r32;
11181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_bool_t retval;
11191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
11201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_region32_init (&r32);
11211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
11221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    retval = _pixman_compute_composite_region32 (
11231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	&r32, src_image, mask_image, dest_image,
11241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	src_x, src_y, mask_x, mask_y, dest_x, dest_y,
11251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	width, height);
11261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
11271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (retval)
11281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
11291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (!pixman_region16_copy_from_region32 (region, &r32))
11301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    retval = FALSE;
11311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
11321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
11331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_region32_fini (&r32);
11341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return retval;
11351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1136