Subversion Repositories Kolibri OS

Rev

Rev 1891 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1891 Rev 3931
1
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
1
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
2
/*
2
/*
3
 * Copyright © 2000 SuSE, Inc.
3
 * Copyright © 2000 SuSE, Inc.
4
 * Copyright © 2007 Red Hat, Inc.
4
 * Copyright © 2007 Red Hat, Inc.
5
 *
5
 *
6
 * Permission to use, copy, modify, distribute, and sell this software and its
6
 * Permission to use, copy, modify, distribute, and sell this software and its
7
 * documentation for any purpose is hereby granted without fee, provided that
7
 * documentation for any purpose is hereby granted without fee, provided that
8
 * the above copyright notice appear in all copies and that both that
8
 * the above copyright notice appear in all copies and that both that
9
 * copyright notice and this permission notice appear in supporting
9
 * copyright notice and this permission notice appear in supporting
10
 * documentation, and that the name of SuSE not be used in advertising or
10
 * documentation, and that the name of SuSE not be used in advertising or
11
 * publicity pertaining to distribution of the software without specific,
11
 * publicity pertaining to distribution of the software without specific,
12
 * written prior permission.  SuSE makes no representations about the
12
 * written prior permission.  SuSE makes no representations about the
13
 * suitability of this software for any purpose.  It is provided "as is"
13
 * suitability of this software for any purpose.  It is provided "as is"
14
 * without express or implied warranty.
14
 * without express or implied warranty.
15
 *
15
 *
16
 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
16
 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
 *
22
 *
23
 * Author:  Keith Packard, SuSE, Inc.
23
 * Author:  Keith Packard, SuSE, Inc.
24
 */
24
 */
25
 
25
 
26
#ifdef HAVE_CONFIG_H
26
#ifdef HAVE_CONFIG_H
27
#include 
27
#include 
28
#endif
28
#endif
29
#include "pixman-private.h"
29
#include "pixman-private.h"
30
 
30
 
31
#include 
31
#include 
32
 
-
 
33
static force_inline pixman_implementation_t *
-
 
34
get_implementation (void)
-
 
35
{
32
 
-
 
33
pixman_implementation_t *global_implementation;
36
    static pixman_implementation_t *global_implementation;
34
 
-
 
35
#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
-
 
36
static void __attribute__((constructor))
37
 
37
pixman_constructor (void)
38
    if (!global_implementation)
-
 
39
	global_implementation = _pixman_choose_implementation ();
-
 
40
 
38
{
-
 
39
    global_implementation = _pixman_choose_implementation ();
41
    return global_implementation;
40
}
42
}
41
#endif
43
 
42
 
44
typedef struct operator_info_t operator_info_t;
43
typedef struct operator_info_t operator_info_t;
45
 
44
 
46
struct operator_info_t
45
struct operator_info_t
47
{
46
{
48
    uint8_t	opaque_info[4];
47
    uint8_t	opaque_info[4];
49
};
48
};
50
 
49
 
51
#define PACK(neither, src, dest, both)			\
50
#define PACK(neither, src, dest, both)			\
52
    {{	    (uint8_t)PIXMAN_OP_ ## neither,		\
51
    {{	    (uint8_t)PIXMAN_OP_ ## neither,		\
53
	    (uint8_t)PIXMAN_OP_ ## src,			\
52
	    (uint8_t)PIXMAN_OP_ ## src,			\
54
	    (uint8_t)PIXMAN_OP_ ## dest,		\
53
	    (uint8_t)PIXMAN_OP_ ## dest,		\
55
	    (uint8_t)PIXMAN_OP_ ## both		}}
54
	    (uint8_t)PIXMAN_OP_ ## both		}}
56
 
55
 
57
static const operator_info_t operator_table[] =
56
static const operator_info_t operator_table[] =
58
{
57
{
59
    /*    Neither Opaque         Src Opaque             Dst Opaque             Both Opaque */
58
    /*    Neither Opaque         Src Opaque             Dst Opaque             Both Opaque */
60
    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
59
    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
61
    PACK (SRC,                   SRC,                   SRC,                   SRC),
60
    PACK (SRC,                   SRC,                   SRC,                   SRC),
62
    PACK (DST,                   DST,                   DST,                   DST),
61
    PACK (DST,                   DST,                   DST,                   DST),
63
    PACK (OVER,                  SRC,                   OVER,                  SRC),
62
    PACK (OVER,                  SRC,                   OVER,                  SRC),
64
    PACK (OVER_REVERSE,          OVER_REVERSE,          DST,                   DST),
63
    PACK (OVER_REVERSE,          OVER_REVERSE,          DST,                   DST),
65
    PACK (IN,                    IN,                    SRC,                   SRC),
64
    PACK (IN,                    IN,                    SRC,                   SRC),
66
    PACK (IN_REVERSE,            DST,                   IN_REVERSE,            DST),
65
    PACK (IN_REVERSE,            DST,                   IN_REVERSE,            DST),
67
    PACK (OUT,                   OUT,                   CLEAR,                 CLEAR),
66
    PACK (OUT,                   OUT,                   CLEAR,                 CLEAR),
68
    PACK (OUT_REVERSE,           CLEAR,                 OUT_REVERSE,           CLEAR),
67
    PACK (OUT_REVERSE,           CLEAR,                 OUT_REVERSE,           CLEAR),
69
    PACK (ATOP,                  IN,                    OVER,                  SRC),
68
    PACK (ATOP,                  IN,                    OVER,                  SRC),
70
    PACK (ATOP_REVERSE,          OVER_REVERSE,          IN_REVERSE,            DST),
69
    PACK (ATOP_REVERSE,          OVER_REVERSE,          IN_REVERSE,            DST),
71
    PACK (XOR,                   OUT,                   OUT_REVERSE,           CLEAR),
70
    PACK (XOR,                   OUT,                   OUT_REVERSE,           CLEAR),
72
    PACK (ADD,                   ADD,                   ADD,                   ADD),
71
    PACK (ADD,                   ADD,                   ADD,                   ADD),
73
    PACK (SATURATE,              OVER_REVERSE,          DST,                   DST),
72
    PACK (SATURATE,              OVER_REVERSE,          DST,                   DST),
74
 
73
 
75
    {{ 0 /* 0x0e */ }},
74
    {{ 0 /* 0x0e */ }},
76
    {{ 0 /* 0x0f */ }},
75
    {{ 0 /* 0x0f */ }},
77
 
76
 
78
    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
77
    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
79
    PACK (SRC,                   SRC,                   SRC,                   SRC),
78
    PACK (SRC,                   SRC,                   SRC,                   SRC),
80
    PACK (DST,                   DST,                   DST,                   DST),
79
    PACK (DST,                   DST,                   DST,                   DST),
81
    PACK (DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER),
80
    PACK (DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER),
82
    PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
81
    PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
83
    PACK (DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN),
82
    PACK (DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN),
84
    PACK (DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE),
83
    PACK (DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE),
85
    PACK (DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT),
84
    PACK (DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT),
86
    PACK (DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE),
85
    PACK (DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE),
87
    PACK (DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP),
86
    PACK (DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP),
88
    PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
87
    PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
89
    PACK (DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR),
88
    PACK (DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR),
90
 
89
 
91
    {{ 0 /* 0x1c */ }},
90
    {{ 0 /* 0x1c */ }},
92
    {{ 0 /* 0x1d */ }},
91
    {{ 0 /* 0x1d */ }},
93
    {{ 0 /* 0x1e */ }},
92
    {{ 0 /* 0x1e */ }},
94
    {{ 0 /* 0x1f */ }},
93
    {{ 0 /* 0x1f */ }},
95
 
94
 
96
    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
95
    PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
97
    PACK (SRC,                   SRC,                   SRC,                   SRC),
96
    PACK (SRC,                   SRC,                   SRC,                   SRC),
98
    PACK (DST,                   DST,                   DST,                   DST),
97
    PACK (DST,                   DST,                   DST,                   DST),
99
    PACK (CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER),
98
    PACK (CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER),
100
    PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
99
    PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
101
    PACK (CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN),
100
    PACK (CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN),
102
    PACK (CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE),
101
    PACK (CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE),
103
    PACK (CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT),
102
    PACK (CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT),
104
    PACK (CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE),
103
    PACK (CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE),
105
    PACK (CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP),
104
    PACK (CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP),
106
    PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
105
    PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
107
    PACK (CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR),
106
    PACK (CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR),
108
 
107
 
109
    {{ 0 /* 0x2c */ }},
108
    {{ 0 /* 0x2c */ }},
110
    {{ 0 /* 0x2d */ }},
109
    {{ 0 /* 0x2d */ }},
111
    {{ 0 /* 0x2e */ }},
110
    {{ 0 /* 0x2e */ }},
112
    {{ 0 /* 0x2f */ }},
111
    {{ 0 /* 0x2f */ }},
113
 
112
 
114
    PACK (MULTIPLY,              MULTIPLY,              MULTIPLY,              MULTIPLY),
113
    PACK (MULTIPLY,              MULTIPLY,              MULTIPLY,              MULTIPLY),
115
    PACK (SCREEN,                SCREEN,                SCREEN,                SCREEN),
114
    PACK (SCREEN,                SCREEN,                SCREEN,                SCREEN),
116
    PACK (OVERLAY,               OVERLAY,               OVERLAY,               OVERLAY),
115
    PACK (OVERLAY,               OVERLAY,               OVERLAY,               OVERLAY),
117
    PACK (DARKEN,                DARKEN,                DARKEN,                DARKEN),
116
    PACK (DARKEN,                DARKEN,                DARKEN,                DARKEN),
118
    PACK (LIGHTEN,               LIGHTEN,               LIGHTEN,               LIGHTEN),
117
    PACK (LIGHTEN,               LIGHTEN,               LIGHTEN,               LIGHTEN),
119
    PACK (COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE),
118
    PACK (COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE),
120
    PACK (COLOR_BURN,            COLOR_BURN,            COLOR_BURN,            COLOR_BURN),
119
    PACK (COLOR_BURN,            COLOR_BURN,            COLOR_BURN,            COLOR_BURN),
121
    PACK (HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT),
120
    PACK (HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT),
122
    PACK (SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT),
121
    PACK (SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT),
123
    PACK (DIFFERENCE,            DIFFERENCE,            DIFFERENCE,            DIFFERENCE),
122
    PACK (DIFFERENCE,            DIFFERENCE,            DIFFERENCE,            DIFFERENCE),
124
    PACK (EXCLUSION,             EXCLUSION,             EXCLUSION,             EXCLUSION),
123
    PACK (EXCLUSION,             EXCLUSION,             EXCLUSION,             EXCLUSION),
125
    PACK (HSL_HUE,               HSL_HUE,               HSL_HUE,               HSL_HUE),
124
    PACK (HSL_HUE,               HSL_HUE,               HSL_HUE,               HSL_HUE),
126
    PACK (HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION),
125
    PACK (HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION),
127
    PACK (HSL_COLOR,             HSL_COLOR,             HSL_COLOR,             HSL_COLOR),
126
    PACK (HSL_COLOR,             HSL_COLOR,             HSL_COLOR,             HSL_COLOR),
128
    PACK (HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY),
127
    PACK (HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY),
129
};
128
};
130
 
129
 
131
/*
130
/*
132
 * Optimize the current operator based on opacity of source or destination
131
 * Optimize the current operator based on opacity of source or destination
133
 * The output operator should be mathematically equivalent to the source.
132
 * The output operator should be mathematically equivalent to the source.
134
 */
133
 */
135
static pixman_op_t
134
static pixman_op_t
136
optimize_operator (pixman_op_t     op,
135
optimize_operator (pixman_op_t     op,
137
		   uint32_t        src_flags,
136
		   uint32_t        src_flags,
138
		   uint32_t        mask_flags,
137
		   uint32_t        mask_flags,
139
		   uint32_t        dst_flags)
138
		   uint32_t        dst_flags)
140
{
139
{
141
    pixman_bool_t is_source_opaque, is_dest_opaque;
140
    pixman_bool_t is_source_opaque, is_dest_opaque;
142
 
141
 
143
#define OPAQUE_SHIFT 13
142
#define OPAQUE_SHIFT 13
144
    
143
    
145
    COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
144
    COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
146
    
145
    
147
    is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
146
    is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
148
    is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
147
    is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
149
 
148
 
150
    is_dest_opaque >>= OPAQUE_SHIFT - 1;
149
    is_dest_opaque >>= OPAQUE_SHIFT - 1;
151
    is_source_opaque >>= OPAQUE_SHIFT;
150
    is_source_opaque >>= OPAQUE_SHIFT;
152
 
151
 
153
    return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
152
    return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
154
}
153
}
155
 
-
 
156
static void
-
 
157
apply_workaround (pixman_image_t *image,
-
 
158
		  int32_t *       x,
-
 
159
		  int32_t *       y,
-
 
160
		  uint32_t **     save_bits,
-
 
161
		  int *           save_dx,
-
 
162
		  int *           save_dy)
-
 
163
{
-
 
164
    if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
-
 
165
    {
-
 
166
	/* Some X servers generate images that point to the
-
 
167
	 * wrong place in memory, but then set the clip region
-
 
168
	 * to point to the right place. Because of an old bug
-
 
169
	 * in pixman, this would actually work.
-
 
170
	 *
-
 
171
	 * Here we try and undo the damage
-
 
172
	 */
-
 
173
	int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
-
 
174
	pixman_box32_t *extents;
-
 
175
	uint8_t *t;
-
 
176
	int dx, dy;
-
 
177
	
-
 
178
	extents = pixman_region32_extents (&(image->common.clip_region));
-
 
179
	dx = extents->x1;
-
 
180
	dy = extents->y1;
-
 
181
	
-
 
182
	*save_bits = image->bits.bits;
-
 
183
	
-
 
184
	*x -= dx;
-
 
185
	*y -= dy;
-
 
186
	pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
-
 
187
	
-
 
188
	t = (uint8_t *)image->bits.bits;
-
 
189
	t += dy * image->bits.rowstride * 4 + dx * bpp;
-
 
190
	image->bits.bits = (uint32_t *)t;
-
 
191
	
-
 
192
	*save_dx = dx;
-
 
193
	*save_dy = dy;
-
 
194
    }
-
 
195
}
-
 
196
 
-
 
197
static void
-
 
198
unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
-
 
199
{
-
 
200
    if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
-
 
201
    {
-
 
202
	image->bits.bits = bits;
-
 
203
	pixman_region32_translate (&image->common.clip_region, dx, dy);
-
 
204
    }
-
 
205
}
-
 
206
 
154
 
207
/*
155
/*
208
 * Computing composite region
156
 * Computing composite region
209
 */
157
 */
210
static inline pixman_bool_t
158
static inline pixman_bool_t
211
clip_general_image (pixman_region32_t * region,
159
clip_general_image (pixman_region32_t * region,
212
                    pixman_region32_t * clip,
160
                    pixman_region32_t * clip,
213
                    int                 dx,
161
                    int                 dx,
214
                    int                 dy)
162
                    int                 dy)
215
{
163
{
216
    if (pixman_region32_n_rects (region) == 1 &&
164
    if (pixman_region32_n_rects (region) == 1 &&
217
        pixman_region32_n_rects (clip) == 1)
165
        pixman_region32_n_rects (clip) == 1)
218
    {
166
    {
219
	pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
167
	pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
220
	pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
168
	pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
221
	int v;
169
	int v;
222
 
170
 
223
	if (rbox->x1 < (v = cbox->x1 + dx))
171
	if (rbox->x1 < (v = cbox->x1 + dx))
224
	    rbox->x1 = v;
172
	    rbox->x1 = v;
225
	if (rbox->x2 > (v = cbox->x2 + dx))
173
	if (rbox->x2 > (v = cbox->x2 + dx))
226
	    rbox->x2 = v;
174
	    rbox->x2 = v;
227
	if (rbox->y1 < (v = cbox->y1 + dy))
175
	if (rbox->y1 < (v = cbox->y1 + dy))
228
	    rbox->y1 = v;
176
	    rbox->y1 = v;
229
	if (rbox->y2 > (v = cbox->y2 + dy))
177
	if (rbox->y2 > (v = cbox->y2 + dy))
230
	    rbox->y2 = v;
178
	    rbox->y2 = v;
231
	if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
179
	if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
232
	{
180
	{
233
	    pixman_region32_init (region);
181
	    pixman_region32_init (region);
234
	    return FALSE;
182
	    return FALSE;
235
	}
183
	}
236
    }
184
    }
237
    else if (!pixman_region32_not_empty (clip))
185
    else if (!pixman_region32_not_empty (clip))
238
    {
186
    {
239
	return FALSE;
187
	return FALSE;
240
    }
188
    }
241
    else
189
    else
242
    {
190
    {
243
	if (dx || dy)
191
	if (dx || dy)
244
	    pixman_region32_translate (region, -dx, -dy);
192
	    pixman_region32_translate (region, -dx, -dy);
245
 
193
 
246
	if (!pixman_region32_intersect (region, region, clip))
194
	if (!pixman_region32_intersect (region, region, clip))
247
	    return FALSE;
195
	    return FALSE;
248
 
196
 
249
	if (dx || dy)
197
	if (dx || dy)
250
	    pixman_region32_translate (region, dx, dy);
198
	    pixman_region32_translate (region, dx, dy);
251
    }
199
    }
252
 
200
 
253
    return pixman_region32_not_empty (region);
201
    return pixman_region32_not_empty (region);
254
}
202
}
255
 
203
 
256
static inline pixman_bool_t
204
static inline pixman_bool_t
257
clip_source_image (pixman_region32_t * region,
205
clip_source_image (pixman_region32_t * region,
258
                   pixman_image_t *    image,
206
                   pixman_image_t *    image,
259
                   int                 dx,
207
                   int                 dx,
260
                   int                 dy)
208
                   int                 dy)
261
{
209
{
262
    /* Source clips are ignored, unless they are explicitly turned on
210
    /* Source clips are ignored, unless they are explicitly turned on
263
     * and the clip in question was set by an X client. (Because if
211
     * and the clip in question was set by an X client. (Because if
264
     * the clip was not set by a client, then it is a hierarchy
212
     * the clip was not set by a client, then it is a hierarchy
265
     * clip and those should always be ignored for sources).
213
     * clip and those should always be ignored for sources).
266
     */
214
     */
267
    if (!image->common.clip_sources || !image->common.client_clip)
215
    if (!image->common.clip_sources || !image->common.client_clip)
268
	return TRUE;
216
	return TRUE;
269
 
217
 
270
    return clip_general_image (region,
218
    return clip_general_image (region,
271
                               &image->common.clip_region,
219
                               &image->common.clip_region,
272
                               dx, dy);
220
                               dx, dy);
273
}
221
}
274
 
222
 
275
/*
223
/*
276
 * returns FALSE if the final region is empty.  Indistinguishable from
224
 * returns FALSE if the final region is empty.  Indistinguishable from
277
 * an allocation failure, but rendering ignores those anyways.
225
 * an allocation failure, but rendering ignores those anyways.
278
 */
226
 */
279
static pixman_bool_t
227
pixman_bool_t
280
pixman_compute_composite_region32 (pixman_region32_t * region,
228
_pixman_compute_composite_region32 (pixman_region32_t * region,
281
                                   pixman_image_t *    src_image,
229
				    pixman_image_t *    src_image,
282
                                   pixman_image_t *    mask_image,
230
				    pixman_image_t *    mask_image,
283
                                   pixman_image_t *    dst_image,
231
				    pixman_image_t *    dest_image,
284
                                   int32_t             src_x,
232
				    int32_t             src_x,
285
                                   int32_t             src_y,
233
				    int32_t             src_y,
286
                                   int32_t             mask_x,
234
				    int32_t             mask_x,
287
                                   int32_t             mask_y,
235
				    int32_t             mask_y,
288
                                   int32_t             dest_x,
236
				    int32_t             dest_x,
289
                                   int32_t             dest_y,
237
				    int32_t             dest_y,
290
                                   int32_t             width,
238
				    int32_t             width,
291
                                   int32_t             height)
239
				    int32_t             height)
292
{
240
{
293
    region->extents.x1 = dest_x;
241
    region->extents.x1 = dest_x;
294
    region->extents.x2 = dest_x + width;
242
    region->extents.x2 = dest_x + width;
295
    region->extents.y1 = dest_y;
243
    region->extents.y1 = dest_y;
296
    region->extents.y2 = dest_y + height;
244
    region->extents.y2 = dest_y + height;
297
 
245
 
298
    region->extents.x1 = MAX (region->extents.x1, 0);
246
    region->extents.x1 = MAX (region->extents.x1, 0);
299
    region->extents.y1 = MAX (region->extents.y1, 0);
247
    region->extents.y1 = MAX (region->extents.y1, 0);
300
    region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
248
    region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
301
    region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
249
    region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
302
 
250
 
303
    region->data = 0;
251
    region->data = 0;
304
 
252
 
305
    /* Check for empty operation */
253
    /* Check for empty operation */
306
    if (region->extents.x1 >= region->extents.x2 ||
254
    if (region->extents.x1 >= region->extents.x2 ||
307
        region->extents.y1 >= region->extents.y2)
255
        region->extents.y1 >= region->extents.y2)
308
    {
256
    {
309
	region->extents.x1 = 0;
257
	region->extents.x1 = 0;
310
	region->extents.x2 = 0;
258
	region->extents.x2 = 0;
311
	region->extents.y1 = 0;
259
	region->extents.y1 = 0;
312
	region->extents.y2 = 0;
260
	region->extents.y2 = 0;
313
	return FALSE;
261
	return FALSE;
314
    }
262
    }
315
 
263
 
316
    if (dst_image->common.have_clip_region)
264
    if (dest_image->common.have_clip_region)
317
    {
265
    {
318
	if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
266
	if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
319
	    return FALSE;
267
	    return FALSE;
320
    }
268
    }
321
 
269
 
322
    if (dst_image->common.alpha_map)
270
    if (dest_image->common.alpha_map)
323
    {
271
    {
324
	if (!pixman_region32_intersect_rect (region, region,
272
	if (!pixman_region32_intersect_rect (region, region,
325
					     dst_image->common.alpha_origin_x,
273
					     dest_image->common.alpha_origin_x,
326
					     dst_image->common.alpha_origin_y,
274
					     dest_image->common.alpha_origin_y,
327
					     dst_image->common.alpha_map->width,
275
					     dest_image->common.alpha_map->width,
328
					     dst_image->common.alpha_map->height))
276
					     dest_image->common.alpha_map->height))
329
	{
277
	{
330
	    return FALSE;
278
	    return FALSE;
331
	}
279
	}
332
	if (!pixman_region32_not_empty (region))
280
	if (!pixman_region32_not_empty (region))
333
	    return FALSE;
281
	    return FALSE;
334
	if (dst_image->common.alpha_map->common.have_clip_region)
282
	if (dest_image->common.alpha_map->common.have_clip_region)
335
	{
283
	{
336
	    if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
284
	    if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
337
				     -dst_image->common.alpha_origin_x,
285
				     -dest_image->common.alpha_origin_x,
338
				     -dst_image->common.alpha_origin_y))
286
				     -dest_image->common.alpha_origin_y))
339
	    {
287
	    {
340
		return FALSE;
288
		return FALSE;
341
	    }
289
	    }
342
	}
290
	}
343
    }
291
    }
344
 
292
 
345
    /* clip against src */
293
    /* clip against src */
346
    if (src_image->common.have_clip_region)
294
    if (src_image->common.have_clip_region)
347
    {
295
    {
348
	if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
296
	if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
349
	    return FALSE;
297
	    return FALSE;
350
    }
298
    }
351
    if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
299
    if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
352
    {
300
    {
353
	if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
301
	if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
354
	                        dest_x - (src_x - src_image->common.alpha_origin_x),
302
	                        dest_x - (src_x - src_image->common.alpha_origin_x),
355
	                        dest_y - (src_y - src_image->common.alpha_origin_y)))
303
	                        dest_y - (src_y - src_image->common.alpha_origin_y)))
356
	{
304
	{
357
	    return FALSE;
305
	    return FALSE;
358
	}
306
	}
359
    }
307
    }
360
    /* clip against mask */
308
    /* clip against mask */
361
    if (mask_image && mask_image->common.have_clip_region)
309
    if (mask_image && mask_image->common.have_clip_region)
362
    {
310
    {
363
	if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
311
	if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
364
	    return FALSE;
312
	    return FALSE;
365
 
313
 
366
	if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
314
	if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
367
	{
315
	{
368
	    if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
316
	    if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
369
	                            dest_x - (mask_x - mask_image->common.alpha_origin_x),
317
	                            dest_x - (mask_x - mask_image->common.alpha_origin_x),
370
	                            dest_y - (mask_y - mask_image->common.alpha_origin_y)))
318
	                            dest_y - (mask_y - mask_image->common.alpha_origin_y)))
371
	    {
319
	    {
372
		return FALSE;
320
		return FALSE;
373
	    }
321
	    }
374
	}
322
	}
375
    }
323
    }
376
 
324
 
377
    return TRUE;
325
    return TRUE;
378
}
326
}
379
 
-
 
380
#define N_CACHED_FAST_PATHS 8
-
 
381
 
327
 
382
typedef struct
328
typedef struct
383
{
-
 
384
    struct
-
 
385
    {
329
{
386
	pixman_implementation_t *	imp;
-
 
387
	pixman_fast_path_t		fast_path;
-
 
388
    } cache [N_CACHED_FAST_PATHS];
-
 
389
} cache_t;
-
 
390
 
-
 
391
PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
-
 
392
 
-
 
393
static force_inline pixman_bool_t
-
 
394
lookup_composite_function (pixman_op_t			op,
330
    pixman_fixed_48_16_t	x1;
395
			   pixman_format_code_t		src_format,
-
 
396
			   uint32_t			src_flags,
-
 
397
			   pixman_format_code_t		mask_format,
-
 
398
			   uint32_t			mask_flags,
331
    pixman_fixed_48_16_t	y1;
399
			   pixman_format_code_t		dest_format,
-
 
400
			   uint32_t			dest_flags,
-
 
401
			   pixman_implementation_t    **out_imp,
-
 
402
			   pixman_composite_func_t     *out_func)
-
 
403
{
332
    pixman_fixed_48_16_t	x2;
404
    pixman_implementation_t *imp;
-
 
405
    cache_t *cache;
-
 
406
    int i;
-
 
407
 
-
 
408
    /* Check cache for fast paths */
-
 
409
    cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
-
 
410
 
-
 
411
    for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
-
 
412
    {
-
 
413
	const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
-
 
414
 
-
 
415
	/* Note that we check for equality here, not whether
-
 
416
	 * the cached fast path matches. This is to prevent
-
 
417
	 * us from selecting an overly general fast path
-
 
418
	 * when a more specific one would work.
-
 
419
	 */
-
 
420
	if (info->op == op			&&
-
 
421
	    info->src_format == src_format	&&
-
 
422
	    info->mask_format == mask_format	&&
-
 
423
	    info->dest_format == dest_format	&&
-
 
424
	    info->src_flags == src_flags	&&
-
 
425
	    info->mask_flags == mask_flags	&&
-
 
426
	    info->dest_flags == dest_flags	&&
-
 
427
	    info->func)
-
 
428
	{
-
 
429
	    *out_imp = cache->cache[i].imp;
-
 
430
	    *out_func = cache->cache[i].fast_path.func;
-
 
431
 
-
 
432
	    goto update_cache;
-
 
433
	}
-
 
434
    }
-
 
435
 
-
 
436
    for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
-
 
437
    {
-
 
438
	const pixman_fast_path_t *info = imp->fast_paths;
-
 
439
 
-
 
440
	while (info->op != PIXMAN_OP_NONE)
-
 
441
	{
-
 
442
	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
-
 
443
		/* Formats */
-
 
444
		((info->src_format == src_format) ||
-
 
445
		 (info->src_format == PIXMAN_any))			&&
-
 
446
		((info->mask_format == mask_format) ||
-
 
447
		 (info->mask_format == PIXMAN_any))			&&
-
 
448
		((info->dest_format == dest_format) ||
-
 
449
		 (info->dest_format == PIXMAN_any))			&&
-
 
450
		/* Flags */
-
 
451
		(info->src_flags & src_flags) == info->src_flags	&&
-
 
452
		(info->mask_flags & mask_flags) == info->mask_flags	&&
-
 
453
		(info->dest_flags & dest_flags) == info->dest_flags)
-
 
454
	    {
-
 
455
		*out_imp = imp;
-
 
456
		*out_func = info->func;
-
 
457
 
-
 
458
		/* Set i to the last spot in the cache so that the
-
 
459
		 * move-to-front code below will work
-
 
460
		 */
-
 
461
		i = N_CACHED_FAST_PATHS - 1;
-
 
462
 
-
 
463
		goto update_cache;
-
 
464
	    }
-
 
465
 
333
    pixman_fixed_48_16_t	y2;
466
	    ++info;
-
 
467
	}
-
 
468
    }
-
 
469
    return FALSE;
-
 
470
 
-
 
471
update_cache:
-
 
472
    if (i)
-
 
473
    {
-
 
474
	while (i--)
-
 
475
	    cache->cache[i + 1] = cache->cache[i];
-
 
476
 
-
 
477
	cache->cache[0].imp = *out_imp;
-
 
478
	cache->cache[0].fast_path.op = op;
-
 
479
	cache->cache[0].fast_path.src_format = src_format;
-
 
480
	cache->cache[0].fast_path.src_flags = src_flags;
-
 
481
	cache->cache[0].fast_path.mask_format = mask_format;
-
 
482
	cache->cache[0].fast_path.mask_flags = mask_flags;
-
 
483
	cache->cache[0].fast_path.dest_format = dest_format;
-
 
484
	cache->cache[0].fast_path.dest_flags = dest_flags;
-
 
485
	cache->cache[0].fast_path.func = *out_func;
-
 
486
    }
-
 
487
 
-
 
488
    return TRUE;
-
 
489
}
334
} box_48_16_t;
490
 
335
 
491
static pixman_bool_t
336
static pixman_bool_t
492
compute_sample_extents (pixman_transform_t *transform,
337
compute_transformed_extents (pixman_transform_t *transform,
493
			pixman_box32_t *extents, int x, int y, 
-
 
494
			pixman_fixed_t x_off, pixman_fixed_t y_off,
338
			     const pixman_box32_t *extents,
495
			pixman_fixed_t width, pixman_fixed_t height)
-
 
496
{
339
			     box_48_16_t *transformed)
-
 
340
{
-
 
341
    pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
497
    pixman_fixed_t x1, y1, x2, y2;
-
 
498
    pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
342
    pixman_fixed_t x1, y1, x2, y2;
499
 
343
    int i;
500
    /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
344
 
501
    x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
345
    x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
502
    y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
346
    y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
503
    x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
347
    x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
504
    y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
348
    y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
505
 
349
 
506
    if (!transform)
350
    if (!transform)
507
    {
351
    {
508
	tx1 = (pixman_fixed_48_16_t)x1;
352
	transformed->x1 = x1;
509
	ty1 = (pixman_fixed_48_16_t)y1;
353
	transformed->y1 = y1;
510
	tx2 = (pixman_fixed_48_16_t)x2;
354
	transformed->x2 = x2;
511
	ty2 = (pixman_fixed_48_16_t)y2;
355
	transformed->y2 = y2;
-
 
356
 
-
 
357
	return TRUE;
512
    }
358
    }
513
    else
-
 
514
    {
-
 
515
	int i;
-
 
516
 
359
 
517
	/* Silence GCC */
360
    tx1 = ty1 = INT64_MAX;
518
	tx1 = ty1 = tx2 = ty2 = 0;
361
    tx2 = ty2 = INT64_MIN;
519
    
362
 
520
	for (i = 0; i < 4; ++i)
363
    for (i = 0; i < 4; ++i)
521
	{
364
    {
522
	    pixman_fixed_48_16_t tx, ty;
365
	pixman_fixed_48_16_t tx, ty;
523
	    pixman_vector_t v;
366
	pixman_vector_t v;
524
 
367
 
525
	    v.vector[0] = (i & 0x01)? x1 : x2;
368
	v.vector[0] = (i & 0x01)? x1 : x2;
526
	    v.vector[1] = (i & 0x02)? y1 : y2;
369
	v.vector[1] = (i & 0x02)? y1 : y2;
527
	    v.vector[2] = pixman_fixed_1;
370
	v.vector[2] = pixman_fixed_1;
528
 
371
 
529
	    if (!pixman_transform_point (transform, &v))
372
	if (!pixman_transform_point (transform, &v))
530
		return FALSE;
373
	    return FALSE;
531
 
374
 
532
	    tx = (pixman_fixed_48_16_t)v.vector[0];
375
	tx = (pixman_fixed_48_16_t)v.vector[0];
533
	    ty = (pixman_fixed_48_16_t)v.vector[1];
376
	ty = (pixman_fixed_48_16_t)v.vector[1];
534
 
-
 
535
	    if (i == 0)
-
 
536
	    {
-
 
537
		tx1 = tx;
-
 
538
		ty1 = ty;
-
 
539
		tx2 = tx;
-
 
540
		ty2 = ty;
-
 
541
	    }
-
 
542
	    else
-
 
543
	    {
377
 
544
		if (tx < tx1)
378
	if (tx < tx1)
545
		    tx1 = tx;
379
	    tx1 = tx;
546
		if (ty < ty1)
380
	if (ty < ty1)
547
		    ty1 = ty;
381
	    ty1 = ty;
548
		if (tx > tx2)
382
	if (tx > tx2)
549
		    tx2 = tx;
383
	    tx2 = tx;
550
		if (ty > ty2)
384
	if (ty > ty2)
551
		    ty2 = ty;
385
	    ty2 = ty;
552
	    }
386
    }
553
	}
-
 
554
    }
-
 
555
 
-
 
556
    /* Expand the source area by a tiny bit so account of different rounding that
-
 
557
     * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
-
 
558
     * 0.5 so this won't cause the area computed to be overly pessimistic.
-
 
559
     */
387
 
560
    tx1 += x_off - 8 * pixman_fixed_e;
388
    transformed->x1 = tx1;
561
    ty1 += y_off - 8 * pixman_fixed_e;
-
 
562
    tx2 += x_off + width + 8 * pixman_fixed_e;
-
 
563
    ty2 += y_off + height + 8 * pixman_fixed_e;
-
 
564
 
-
 
565
    if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
-
 
566
	ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
-
 
567
	tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
-
 
568
	ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
-
 
569
    {
-
 
570
	return FALSE;
-
 
571
    }
-
 
572
    else
-
 
573
    {
389
    transformed->y1 = ty1;
574
	extents->x1 = pixman_fixed_to_int (tx1);
390
    transformed->x2 = tx2;
575
	extents->y1 = pixman_fixed_to_int (ty1);
-
 
576
	extents->x2 = pixman_fixed_to_int (tx2) + 1;
-
 
577
	extents->y2 = pixman_fixed_to_int (ty2) + 1;
391
    transformed->y2 = ty2;
578
 
392
 
579
	return TRUE;
393
    return TRUE;
580
    }
394
}
581
}
-
 
582
 
395
 
-
 
396
#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
-
 
397
#define ABS(f)      (((f) < 0)?  (-(f)) : (f))
583
#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
398
#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
584
 
399
 
585
static pixman_bool_t
400
static pixman_bool_t
-
 
401
analyze_extent (pixman_image_t       *image,
586
analyze_extent (pixman_image_t *image, int x, int y,
402
		const pixman_box32_t *extents,
587
		const pixman_box32_t *extents, uint32_t *flags)
403
		uint32_t             *flags)
588
{
-
 
589
    pixman_transform_t *transform;
404
{
590
    pixman_fixed_t *params;
405
    pixman_transform_t *transform;
-
 
406
    pixman_fixed_t x_off, y_off;
-
 
407
    pixman_fixed_t width, height;
591
    pixman_fixed_t x_off, y_off;
408
    pixman_fixed_t *params;
592
    pixman_fixed_t width, height;
409
    box_48_16_t transformed;
593
    pixman_box32_t ex;
410
    pixman_box32_t exp_extents;
594
 
411
 
595
    if (!image)
412
    if (!image)
596
	return TRUE;
413
	return TRUE;
597
 
414
 
598
    /* Some compositing functions walk one step
415
    /* Some compositing functions walk one step
599
     * outside the destination rectangle, so we
416
     * outside the destination rectangle, so we
600
     * check here that the expanded-by-one source
417
     * check here that the expanded-by-one source
601
     * extents in destination space fits in 16 bits
418
     * extents in destination space fits in 16 bits
602
     */
419
     */
603
    if (!IS_16BIT (extents->x1 - x - 1)		||
420
    if (!IS_16BIT (extents->x1 - 1)		||
604
	!IS_16BIT (extents->y1 - y - 1)		||
421
	!IS_16BIT (extents->y1 - 1)		||
605
	!IS_16BIT (extents->x2 - x + 1)		||
422
	!IS_16BIT (extents->x2 + 1)		||
606
	!IS_16BIT (extents->y2 - y + 1))
423
	!IS_16BIT (extents->y2 + 1))
607
    {
424
    {
608
	return FALSE;
425
	return FALSE;
609
    }
426
    }
610
 
427
 
611
    transform = image->common.transform;
428
    transform = image->common.transform;
612
    if (image->common.type == BITS)
429
    if (image->common.type == BITS)
613
    {
430
    {
614
	/* During repeat mode calculations we might convert the
431
	/* During repeat mode calculations we might convert the
615
	 * width/height of an image to fixed 16.16, so we need
432
	 * width/height of an image to fixed 16.16, so we need
616
	 * them to be smaller than 16 bits.
433
	 * them to be smaller than 16 bits.
617
	 */
434
	 */
618
	if (image->bits.width >= 0x7fff	|| image->bits.height >= 0x7fff)
435
	if (image->bits.width >= 0x7fff	|| image->bits.height >= 0x7fff)
619
	    return FALSE;
436
	    return FALSE;
620
 
-
 
621
#define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
-
 
622
	
437
 
623
	if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
438
	if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
624
	    extents->x1 - x >= 0 &&
439
	    extents->x1 >= 0 &&
625
	    extents->y1 - y >= 0 &&
440
	    extents->y1 >= 0 &&
626
	    extents->x2 - x <= image->bits.width &&
441
	    extents->x2 <= image->bits.width &&
627
	    extents->y2 - y <= image->bits.height)
442
	    extents->y2 <= image->bits.height)
628
	{
443
	{
629
	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
444
	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
630
	    return TRUE;
445
	    return TRUE;
631
	}
446
	}
632
    
447
 
633
	switch (image->common.filter)
448
	switch (image->common.filter)
634
	{
449
	{
635
	case PIXMAN_FILTER_CONVOLUTION:
450
	case PIXMAN_FILTER_CONVOLUTION:
636
	    params = image->common.filter_params;
451
	    params = image->common.filter_params;
637
	    x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
452
	    x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
638
	    y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
453
	    y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
639
	    width = params[0];
454
	    width = params[0];
640
	    height = params[1];
455
	    height = params[1];
641
	    break;
456
	    break;
-
 
457
 
-
 
458
	case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
-
 
459
	    params = image->common.filter_params;
-
 
460
	    x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
-
 
461
	    y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
-
 
462
	    width = params[0];
-
 
463
	    height = params[1];
-
 
464
	    break;
642
 
465
	    
643
	case PIXMAN_FILTER_GOOD:
466
	case PIXMAN_FILTER_GOOD:
644
	case PIXMAN_FILTER_BEST:
467
	case PIXMAN_FILTER_BEST:
645
	case PIXMAN_FILTER_BILINEAR:
468
	case PIXMAN_FILTER_BILINEAR:
646
	    x_off = - pixman_fixed_1 / 2;
469
	    x_off = - pixman_fixed_1 / 2;
647
	    y_off = - pixman_fixed_1 / 2;
470
	    y_off = - pixman_fixed_1 / 2;
648
	    width = pixman_fixed_1;
471
	    width = pixman_fixed_1;
649
	    height = pixman_fixed_1;
472
	    height = pixman_fixed_1;
650
	    break;
473
	    break;
651
 
474
 
652
	case PIXMAN_FILTER_FAST:
475
	case PIXMAN_FILTER_FAST:
653
	case PIXMAN_FILTER_NEAREST:
476
	case PIXMAN_FILTER_NEAREST:
654
	    x_off = - pixman_fixed_e;
477
	    x_off = - pixman_fixed_e;
655
	    y_off = - pixman_fixed_e;
478
	    y_off = - pixman_fixed_e;
656
	    width = 0;
479
	    width = 0;
657
	    height = 0;
480
	    height = 0;
658
	    break;
481
	    break;
659
 
482
 
660
	default:
483
	default:
661
	    return FALSE;
484
	    return FALSE;
662
	}
485
	}
663
 
-
 
664
	/* Check whether the non-expanded, transformed extent is entirely within
-
 
665
	 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
-
 
666
	 */
-
 
667
	ex = *extents;
-
 
668
	if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
-
 
669
	    ex.x1 >= 0 && ex.y1 >= 0 &&
-
 
670
	    ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
-
 
671
	{
-
 
672
	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
-
 
673
	}
-
 
674
    }
486
    }
675
    else
487
    else
676
    {
488
    {
677
	x_off = 0;
489
	x_off = 0;
678
	y_off = 0;
490
	y_off = 0;
679
	width = 0;
491
	width = 0;
680
	height = 0;
492
	height = 0;
681
    }
493
    }
-
 
494
 
-
 
495
    if (!compute_transformed_extents (transform, extents, &transformed))
-
 
496
	return FALSE;
682
 
497
 
683
    /* Check that the extents expanded by one don't overflow. This ensures that
498
    /* Expand the source area by a tiny bit so account of different rounding that
684
     * compositing functions can simply walk the source space using 16.16
499
     * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
685
     * variables without worrying about overflow.
500
     * 0.5 so this won't cause the area computed to be overly pessimistic.
686
     */
501
     */
687
    ex.x1 = extents->x1 - 1;
502
    transformed.x1 -= 8 * pixman_fixed_e;
688
    ex.y1 = extents->y1 - 1;
503
    transformed.y1 -= 8 * pixman_fixed_e;
689
    ex.x2 = extents->x2 + 1;
504
    transformed.x2 += 8 * pixman_fixed_e;
-
 
505
    transformed.y2 += 8 * pixman_fixed_e;
-
 
506
 
-
 
507
    if (image->common.type == BITS)
-
 
508
    {
-
 
509
	if (pixman_fixed_to_int (transformed.x1) >= 0			&&
-
 
510
	    pixman_fixed_to_int (transformed.y1) >= 0			&&
-
 
511
	    pixman_fixed_to_int (transformed.x2) < image->bits.width	&&
-
 
512
	    pixman_fixed_to_int (transformed.y2) < image->bits.height)
-
 
513
	{
-
 
514
	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
-
 
515
	}
-
 
516
 
-
 
517
	if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0		  &&
-
 
518
	    pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0		  &&
-
 
519
	    pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
-
 
520
	    pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
-
 
521
	{
-
 
522
	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
-
 
523
	}
-
 
524
    }
-
 
525
 
-
 
526
    /* Check we don't overflow when the destination extents are expanded by one.
-
 
527
     * This ensures that compositing functions can simply walk the source space
-
 
528
     * using 16.16 variables without worrying about overflow.
-
 
529
     */
-
 
530
    exp_extents = *extents;
-
 
531
    exp_extents.x1 -= 1;
-
 
532
    exp_extents.y1 -= 1;
-
 
533
    exp_extents.x2 += 1;
690
    ex.y2 = extents->y2 + 1;
534
    exp_extents.y2 += 1;
691
 
535
 
-
 
536
    if (!compute_transformed_extents (transform, &exp_extents, &transformed))
-
 
537
	return FALSE;
-
 
538
    
-
 
539
    if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e)	||
-
 
540
	!IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e)	||
-
 
541
	!IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width)	||
-
 
542
	!IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
-
 
543
    {
692
    if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
544
	return FALSE;
693
	return FALSE;
545
    }
694
 
546
 
695
    return TRUE;
547
    return TRUE;
696
}
548
}
697
 
549
 
698
/*
550
/*
699
 * Work around GCC bug causing crashes in Mozilla with SSE2
551
 * Work around GCC bug causing crashes in Mozilla with SSE2
700
 *
552
 *
701
 * When using -msse, gcc generates movdqa instructions assuming that
553
 * When using -msse, gcc generates movdqa instructions assuming that
702
 * the stack is 16 byte aligned. Unfortunately some applications, such
554
 * the stack is 16 byte aligned. Unfortunately some applications, such
703
 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
555
 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
704
 * causes the movdqa instructions to fail.
556
 * causes the movdqa instructions to fail.
705
 *
557
 *
706
 * The __force_align_arg_pointer__ makes gcc generate a prologue that
558
 * The __force_align_arg_pointer__ makes gcc generate a prologue that
707
 * realigns the stack pointer to 16 bytes.
559
 * realigns the stack pointer to 16 bytes.
708
 *
560
 *
709
 * On x86-64 this is not necessary because the standard ABI already
561
 * On x86-64 this is not necessary because the standard ABI already
710
 * calls for a 16 byte aligned stack.
562
 * calls for a 16 byte aligned stack.
711
 *
563
 *
712
 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
564
 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
713
 */
565
 */
714
#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
566
#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
715
__attribute__((__force_align_arg_pointer__))
567
__attribute__((__force_align_arg_pointer__))
716
#endif
568
#endif
717
PIXMAN_EXPORT void
569
PIXMAN_EXPORT void
718
pixman_image_composite32 (pixman_op_t      op,
570
pixman_image_composite32 (pixman_op_t      op,
719
                          pixman_image_t * src,
571
                          pixman_image_t * src,
720
                          pixman_image_t * mask,
572
                          pixman_image_t * mask,
721
                          pixman_image_t * dest,
573
                          pixman_image_t * dest,
722
                          int32_t          src_x,
574
                          int32_t          src_x,
723
                          int32_t          src_y,
575
                          int32_t          src_y,
724
                          int32_t          mask_x,
576
                          int32_t          mask_x,
725
                          int32_t          mask_y,
577
                          int32_t          mask_y,
726
                          int32_t          dest_x,
578
                          int32_t          dest_x,
727
                          int32_t          dest_y,
579
                          int32_t          dest_y,
728
                          int32_t          width,
580
                          int32_t          width,
729
                          int32_t          height)
581
                          int32_t          height)
730
{
582
{
731
    pixman_format_code_t src_format, mask_format, dest_format;
583
    pixman_format_code_t src_format, mask_format, dest_format;
732
    uint32_t src_flags, mask_flags, dest_flags;
-
 
733
    pixman_region32_t region;
584
    pixman_region32_t region;
734
    pixman_box32_t *extents;
585
    pixman_box32_t extents;
735
    uint32_t *src_bits;
-
 
736
    int src_dx, src_dy;
-
 
737
    uint32_t *mask_bits;
-
 
738
    int mask_dx, mask_dy;
-
 
739
    uint32_t *dest_bits;
-
 
740
    int dest_dx, dest_dy;
-
 
741
    pixman_bool_t need_workaround;
-
 
742
    pixman_implementation_t *imp;
586
    pixman_implementation_t *imp;
743
    pixman_composite_func_t func;
587
    pixman_composite_func_t func;
-
 
588
    pixman_composite_info_t info;
-
 
589
    const pixman_box32_t *pbox;
-
 
590
    int n;
744
 
591
 
745
    _pixman_image_validate (src);
592
    _pixman_image_validate (src);
746
    if (mask)
593
    if (mask)
747
	_pixman_image_validate (mask);
594
	_pixman_image_validate (mask);
748
    _pixman_image_validate (dest);
595
    _pixman_image_validate (dest);
749
 
596
 
750
    src_format = src->common.extended_format_code;
597
    src_format = src->common.extended_format_code;
751
    src_flags = src->common.flags;
598
    info.src_flags = src->common.flags;
752
 
599
 
753
    if (mask)
600
    if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE))
754
    {
601
    {
755
	mask_format = mask->common.extended_format_code;
602
	mask_format = mask->common.extended_format_code;
756
	mask_flags = mask->common.flags;
603
	info.mask_flags = mask->common.flags;
757
    }
604
    }
758
    else
605
    else
759
    {
606
    {
760
	mask_format = PIXMAN_null;
607
	mask_format = PIXMAN_null;
761
	mask_flags = FAST_PATH_IS_OPAQUE;
608
	info.mask_flags = FAST_PATH_IS_OPAQUE;
762
    }
609
    }
763
 
610
 
764
    dest_format = dest->common.extended_format_code;
611
    dest_format = dest->common.extended_format_code;
765
    dest_flags = dest->common.flags;
612
    info.dest_flags = dest->common.flags;
766
 
613
 
767
    /* Check for pixbufs */
614
    /* Check for pixbufs */
768
    if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
615
    if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
769
	(src->type == BITS && src->bits.bits == mask->bits.bits)	   &&
616
	(src->type == BITS && src->bits.bits == mask->bits.bits)	   &&
770
	(src->common.repeat == mask->common.repeat)			   &&
617
	(src->common.repeat == mask->common.repeat)			   &&
-
 
618
	(info.src_flags & info.mask_flags & FAST_PATH_ID_TRANSFORM)	   &&
771
	(src_x == mask_x && src_y == mask_y))
619
	(src_x == mask_x && src_y == mask_y))
772
    {
620
    {
773
	if (src_format == PIXMAN_x8b8g8r8)
621
	if (src_format == PIXMAN_x8b8g8r8)
774
	    src_format = mask_format = PIXMAN_pixbuf;
622
	    src_format = mask_format = PIXMAN_pixbuf;
775
	else if (src_format == PIXMAN_x8r8g8b8)
623
	else if (src_format == PIXMAN_x8r8g8b8)
776
	    src_format = mask_format = PIXMAN_rpixbuf;
624
	    src_format = mask_format = PIXMAN_rpixbuf;
777
    }
625
    }
778
 
-
 
779
    /* Check for workaround */
-
 
780
    need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
-
 
781
 
-
 
782
    if (need_workaround)
-
 
783
    {
-
 
784
	apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
-
 
785
	apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
-
 
786
	apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
-
 
787
    }
-
 
788
 
626
 
789
    pixman_region32_init (®ion);
627
    pixman_region32_init (®ion);
790
 
628
 
791
    if (!pixman_compute_composite_region32 (
629
    if (!_pixman_compute_composite_region32 (
792
	    ®ion, src, mask, dest,
630
	    ®ion, src, mask, dest,
793
	    src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
631
	    src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
794
    {
632
    {
795
	goto out;
633
	goto out;
796
    }
634
    }
797
 
635
 
-
 
636
    extents = *pixman_region32_extents (®ion);
-
 
637
 
-
 
638
    extents.x1 -= dest_x - src_x;
-
 
639
    extents.y1 -= dest_y - src_y;
-
 
640
    extents.x2 -= dest_x - src_x;
798
    extents = pixman_region32_extents (®ion);
641
    extents.y2 -= dest_y - src_y;
799
 
642
 
-
 
643
    if (!analyze_extent (src, &extents, &info.src_flags))
-
 
644
	goto out;
-
 
645
 
-
 
646
    extents.x1 -= src_x - mask_x;
-
 
647
    extents.y1 -= src_y - mask_y;
800
    if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
648
    extents.x2 -= src_x - mask_x;
801
	goto out;
649
    extents.y2 -= src_y - mask_y;
802
 
650
 
803
    if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
651
    if (!analyze_extent (mask, &extents, &info.mask_flags))
804
	goto out;
652
	goto out;
-
 
653
 
-
 
654
    /* If the clip is within the source samples, and the samples are
-
 
655
     * opaque, then the source is effectively opaque.
805
 
656
     */
-
 
657
#define NEAREST_OPAQUE	(FAST_PATH_SAMPLES_OPAQUE |			\
-
 
658
			 FAST_PATH_NEAREST_FILTER |			\
806
    /* If the clip is within the source samples, and the samples are opaque,
659
			 FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
-
 
660
#define BILINEAR_OPAQUE	(FAST_PATH_SAMPLES_OPAQUE |			\
-
 
661
			 FAST_PATH_BILINEAR_FILTER |			\
807
     * then the source is effectively opaque.
662
			 FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
-
 
663
 
808
     */
664
    if ((info.src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
-
 
665
	(info.src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
-
 
666
    {
809
#define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
667
	info.src_flags |= FAST_PATH_IS_OPAQUE;
-
 
668
    }
810
 
669
 
811
    if ((src_flags & BOTH) == BOTH)
670
    if ((info.mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
812
	src_flags |= FAST_PATH_IS_OPAQUE;
671
	(info.mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
813
    
672
    {
814
    if ((mask_flags & BOTH) == BOTH)
673
	info.mask_flags |= FAST_PATH_IS_OPAQUE;
815
	mask_flags |= FAST_PATH_IS_OPAQUE;
674
    }
816
    
675
 
817
    /*
676
    /*
818
     * Check if we can replace our operator by a simpler one
677
     * Check if we can replace our operator by a simpler one
819
     * if the src or dest are opaque. The output operator should be
678
     * if the src or dest are opaque. The output operator should be
820
     * mathematically equivalent to the source.
679
     * mathematically equivalent to the source.
821
     */
680
     */
822
    op = optimize_operator (op, src_flags, mask_flags, dest_flags);
681
    info.op = optimize_operator (op, info.src_flags, info.mask_flags, info.dest_flags);
823
    if (op == PIXMAN_OP_DST)
-
 
824
	goto out;
-
 
825
 
682
 
-
 
683
    _pixman_implementation_lookup_composite (
826
    if (lookup_composite_function (op,
684
	get_implementation (), info.op,
827
				   src_format, src_flags,
685
	src_format, info.src_flags,
828
				   mask_format, mask_flags,
686
	mask_format, info.mask_flags,
829
				   dest_format, dest_flags,
687
	dest_format, info.dest_flags,
830
				   &imp, &func))
688
	&imp, &func);
-
 
689
 
831
    {
690
    info.src_image = src;
832
	const pixman_box32_t *pbox;
691
    info.mask_image = mask;
833
	int n;
692
    info.dest_image = dest;
834
 
693
 
835
	pbox = pixman_region32_rectangles (®ion, &n);
694
    pbox = pixman_region32_rectangles (®ion, &n);
836
	
695
 
837
	while (n--)
696
    while (n--)
838
	{
697
    {
839
	    func (imp, op,
-
 
840
		  src, mask, dest,
-
 
841
		  pbox->x1 + src_x - dest_x,
698
	info.src_x = pbox->x1 + src_x - dest_x;
842
		  pbox->y1 + src_y - dest_y,
699
	info.src_y = pbox->y1 + src_y - dest_y;
843
		  pbox->x1 + mask_x - dest_x,
700
	info.mask_x = pbox->x1 + mask_x - dest_x;
844
		  pbox->y1 + mask_y - dest_y,
701
	info.mask_y = pbox->y1 + mask_y - dest_y;
845
		  pbox->x1,
702
	info.dest_x = pbox->x1;
846
		  pbox->y1,
703
	info.dest_y = pbox->y1;
847
		  pbox->x2 - pbox->x1,
704
	info.width = pbox->x2 - pbox->x1;
848
		  pbox->y2 - pbox->y1);
705
	info.height = pbox->y2 - pbox->y1;
-
 
706
 
-
 
707
	func (imp, &info);
849
	    
708
 
850
	    pbox++;
709
	pbox++;
851
	}
710
    }
852
    }
-
 
853
 
711
 
854
out:
-
 
855
    if (need_workaround)
-
 
856
    {
-
 
857
	unapply_workaround (src, src_bits, src_dx, src_dy);
-
 
858
	unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
-
 
859
	unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
-
 
860
    }
-
 
861
 
712
out:
862
    pixman_region32_fini (®ion);
713
    pixman_region32_fini (®ion);
863
}
714
}
864
 
715
 
865
PIXMAN_EXPORT void
716
PIXMAN_EXPORT void
866
pixman_image_composite (pixman_op_t      op,
717
pixman_image_composite (pixman_op_t      op,
867
                        pixman_image_t * src,
718
                        pixman_image_t * src,
868
                        pixman_image_t * mask,
719
                        pixman_image_t * mask,
869
                        pixman_image_t * dest,
720
                        pixman_image_t * dest,
870
                        int16_t          src_x,
721
                        int16_t          src_x,
871
                        int16_t          src_y,
722
                        int16_t          src_y,
872
                        int16_t          mask_x,
723
                        int16_t          mask_x,
873
                        int16_t          mask_y,
724
                        int16_t          mask_y,
874
                        int16_t          dest_x,
725
                        int16_t          dest_x,
875
                        int16_t          dest_y,
726
                        int16_t          dest_y,
876
                        uint16_t         width,
727
                        uint16_t         width,
877
                        uint16_t         height)
728
                        uint16_t         height)
878
{
729
{
879
    pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 
730
    pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 
880
                              mask_x, mask_y, dest_x, dest_y, width, height);
731
                              mask_x, mask_y, dest_x, dest_y, width, height);
881
}
732
}
882
 
733
 
883
PIXMAN_EXPORT pixman_bool_t
734
PIXMAN_EXPORT pixman_bool_t
884
pixman_blt (uint32_t *src_bits,
735
pixman_blt (uint32_t *src_bits,
885
            uint32_t *dst_bits,
736
            uint32_t *dst_bits,
886
            int       src_stride,
737
            int       src_stride,
887
            int       dst_stride,
738
            int       dst_stride,
888
            int       src_bpp,
739
            int       src_bpp,
889
            int       dst_bpp,
740
            int       dst_bpp,
890
            int       src_x,
741
            int       src_x,
891
            int       src_y,
742
            int       src_y,
892
            int       dst_x,
743
            int       dest_x,
893
            int       dst_y,
744
            int       dest_y,
894
            int       width,
745
            int       width,
895
            int       height)
746
            int       height)
896
{
747
{
897
    return _pixman_implementation_blt (get_implementation(),
748
    return _pixman_implementation_blt (get_implementation(),
898
				       src_bits, dst_bits, src_stride, dst_stride,
749
				       src_bits, dst_bits, src_stride, dst_stride,
899
                                       src_bpp, dst_bpp,
750
                                       src_bpp, dst_bpp,
900
                                       src_x, src_y,
751
                                       src_x, src_y,
901
                                       dst_x, dst_y,
752
                                       dest_x, dest_y,
902
                                       width, height);
753
                                       width, height);
903
}
754
}
904
 
755
 
905
PIXMAN_EXPORT pixman_bool_t
756
PIXMAN_EXPORT pixman_bool_t
906
pixman_fill (uint32_t *bits,
757
pixman_fill (uint32_t *bits,
907
             int       stride,
758
             int       stride,
908
             int       bpp,
759
             int       bpp,
909
             int       x,
760
             int       x,
910
             int       y,
761
             int       y,
911
             int       width,
762
             int       width,
912
             int       height,
763
             int       height,
913
             uint32_t xor)
764
             uint32_t  filler)
914
{
765
{
915
    return _pixman_implementation_fill (
766
    return _pixman_implementation_fill (
916
	get_implementation(), bits, stride, bpp, x, y, width, height, xor);
767
	get_implementation(), bits, stride, bpp, x, y, width, height, filler);
917
}
768
}
918
 
769
 
919
static uint32_t
770
static uint32_t
920
color_to_uint32 (const pixman_color_t *color)
771
color_to_uint32 (const pixman_color_t *color)
921
{
772
{
922
    return
773
    return
923
        (color->alpha >> 8 << 24) |
774
        (color->alpha >> 8 << 24) |
924
        (color->red >> 8 << 16) |
775
        (color->red >> 8 << 16) |
925
        (color->green & 0xff00) |
776
        (color->green & 0xff00) |
926
        (color->blue >> 8);
777
        (color->blue >> 8);
927
}
778
}
928
 
779
 
929
static pixman_bool_t
780
static pixman_bool_t
930
color_to_pixel (pixman_color_t *     color,
781
color_to_pixel (const pixman_color_t *color,
931
                uint32_t *           pixel,
782
                uint32_t *            pixel,
932
                pixman_format_code_t format)
783
                pixman_format_code_t  format)
933
{
784
{
934
    uint32_t c = color_to_uint32 (color);
785
    uint32_t c = color_to_uint32 (color);
935
 
786
 
936
    if (!(format == PIXMAN_a8r8g8b8     ||
787
    if (!(format == PIXMAN_a8r8g8b8     ||
937
          format == PIXMAN_x8r8g8b8     ||
788
          format == PIXMAN_x8r8g8b8     ||
938
          format == PIXMAN_a8b8g8r8     ||
789
          format == PIXMAN_a8b8g8r8     ||
939
          format == PIXMAN_x8b8g8r8     ||
790
          format == PIXMAN_x8b8g8r8     ||
940
          format == PIXMAN_b8g8r8a8     ||
791
          format == PIXMAN_b8g8r8a8     ||
941
          format == PIXMAN_b8g8r8x8     ||
792
          format == PIXMAN_b8g8r8x8     ||
-
 
793
          format == PIXMAN_r8g8b8a8     ||
-
 
794
          format == PIXMAN_r8g8b8x8     ||
942
          format == PIXMAN_r5g6b5       ||
795
          format == PIXMAN_r5g6b5       ||
943
          format == PIXMAN_b5g6r5       ||
796
          format == PIXMAN_b5g6r5       ||
-
 
797
          format == PIXMAN_a8           ||
944
          format == PIXMAN_a8))
798
          format == PIXMAN_a1))
945
    {
799
    {
946
	return FALSE;
800
	return FALSE;
947
    }
801
    }
948
 
802
 
949
    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
803
    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
950
    {
804
    {
951
	c = ((c & 0xff000000) >>  0) |
805
	c = ((c & 0xff000000) >>  0) |
952
	    ((c & 0x00ff0000) >> 16) |
806
	    ((c & 0x00ff0000) >> 16) |
953
	    ((c & 0x0000ff00) >>  0) |
807
	    ((c & 0x0000ff00) >>  0) |
954
	    ((c & 0x000000ff) << 16);
808
	    ((c & 0x000000ff) << 16);
955
    }
809
    }
956
    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
810
    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
957
    {
811
    {
958
	c = ((c & 0xff000000) >> 24) |
812
	c = ((c & 0xff000000) >> 24) |
959
	    ((c & 0x00ff0000) >>  8) |
813
	    ((c & 0x00ff0000) >>  8) |
960
	    ((c & 0x0000ff00) <<  8) |
814
	    ((c & 0x0000ff00) <<  8) |
961
	    ((c & 0x000000ff) << 24);
815
	    ((c & 0x000000ff) << 24);
962
    }
816
    }
-
 
817
    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
-
 
818
	c = ((c & 0xff000000) >> 24) | (c << 8);
963
 
819
 
-
 
820
    if (format == PIXMAN_a1)
-
 
821
	c = c >> 31;
964
    if (format == PIXMAN_a8)
822
    else if (format == PIXMAN_a8)
965
	c = c >> 24;
823
	c = c >> 24;
966
    else if (format == PIXMAN_r5g6b5 ||
824
    else if (format == PIXMAN_r5g6b5 ||
967
             format == PIXMAN_b5g6r5)
825
             format == PIXMAN_b5g6r5)
968
	c = CONVERT_8888_TO_0565 (c);
826
	c = convert_8888_to_0565 (c);
969
 
827
 
970
#if 0
828
#if 0
971
    printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
829
    printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
972
    printf ("pixel: %x\n", c);
830
    printf ("pixel: %x\n", c);
973
#endif
831
#endif
974
 
832
 
975
    *pixel = c;
833
    *pixel = c;
976
    return TRUE;
834
    return TRUE;
977
}
835
}
978
 
836
 
979
PIXMAN_EXPORT pixman_bool_t
837
PIXMAN_EXPORT pixman_bool_t
980
pixman_image_fill_rectangles (pixman_op_t                 op,
838
pixman_image_fill_rectangles (pixman_op_t                 op,
981
                              pixman_image_t *            dest,
839
                              pixman_image_t *            dest,
982
                              pixman_color_t *            color,
840
			      const pixman_color_t *      color,
983
                              int                         n_rects,
841
                              int                         n_rects,
984
                              const pixman_rectangle16_t *rects)
842
                              const pixman_rectangle16_t *rects)
985
{
843
{
986
    pixman_box32_t stack_boxes[6];
844
    pixman_box32_t stack_boxes[6];
987
    pixman_box32_t *boxes;
845
    pixman_box32_t *boxes;
988
    pixman_bool_t result;
846
    pixman_bool_t result;
989
    int i;
847
    int i;
990
 
848
 
991
    if (n_rects > 6)
849
    if (n_rects > 6)
992
    {
850
    {
993
        boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
851
        boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
994
        if (boxes == NULL)
852
        if (boxes == NULL)
995
            return FALSE;
853
            return FALSE;
996
    }
854
    }
997
    else
855
    else
998
    {
856
    {
999
        boxes = stack_boxes;
857
        boxes = stack_boxes;
1000
    }
858
    }
1001
 
859
 
1002
    for (i = 0; i < n_rects; ++i)
860
    for (i = 0; i < n_rects; ++i)
1003
    {
861
    {
1004
        boxes[i].x1 = rects[i].x;
862
        boxes[i].x1 = rects[i].x;
1005
        boxes[i].y1 = rects[i].y;
863
        boxes[i].y1 = rects[i].y;
1006
        boxes[i].x2 = boxes[i].x1 + rects[i].width;
864
        boxes[i].x2 = boxes[i].x1 + rects[i].width;
1007
        boxes[i].y2 = boxes[i].y1 + rects[i].height;
865
        boxes[i].y2 = boxes[i].y1 + rects[i].height;
1008
    }
866
    }
1009
 
867
 
1010
    result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
868
    result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1011
 
869
 
1012
    if (boxes != stack_boxes)
870
    if (boxes != stack_boxes)
1013
        free (boxes);
871
        free (boxes);
1014
    
872
    
1015
    return result;
873
    return result;
1016
}
874
}
1017
 
875
 
1018
PIXMAN_EXPORT pixman_bool_t
876
PIXMAN_EXPORT pixman_bool_t
1019
pixman_image_fill_boxes (pixman_op_t           op,
877
pixman_image_fill_boxes (pixman_op_t           op,
1020
                         pixman_image_t *      dest,
878
                         pixman_image_t *      dest,
1021
                         pixman_color_t *      color,
879
                         const pixman_color_t *color,
1022
                         int                   n_boxes,
880
                         int                   n_boxes,
1023
                         const pixman_box32_t *boxes)
881
                         const pixman_box32_t *boxes)
1024
{
882
{
1025
    pixman_image_t *solid;
883
    pixman_image_t *solid;
1026
    pixman_color_t c;
884
    pixman_color_t c;
1027
    int i;
885
    int i;
1028
 
886
 
1029
    _pixman_image_validate (dest);
887
    _pixman_image_validate (dest);
1030
    
888
    
1031
    if (color->alpha == 0xffff)
889
    if (color->alpha == 0xffff)
1032
    {
890
    {
1033
        if (op == PIXMAN_OP_OVER)
891
        if (op == PIXMAN_OP_OVER)
1034
            op = PIXMAN_OP_SRC;
892
            op = PIXMAN_OP_SRC;
1035
    }
893
    }
1036
 
894
 
1037
    if (op == PIXMAN_OP_CLEAR)
895
    if (op == PIXMAN_OP_CLEAR)
1038
    {
896
    {
1039
        c.red = 0;
897
        c.red = 0;
1040
        c.green = 0;
898
        c.green = 0;
1041
        c.blue = 0;
899
        c.blue = 0;
1042
        c.alpha = 0;
900
        c.alpha = 0;
1043
 
901
 
1044
        color = &c;
902
        color = &c;
1045
 
903
 
1046
        op = PIXMAN_OP_SRC;
904
        op = PIXMAN_OP_SRC;
1047
    }
905
    }
1048
 
906
 
1049
    if (op == PIXMAN_OP_SRC)
907
    if (op == PIXMAN_OP_SRC)
1050
    {
908
    {
1051
        uint32_t pixel;
909
        uint32_t pixel;
1052
 
910
 
1053
        if (color_to_pixel (color, &pixel, dest->bits.format))
911
        if (color_to_pixel (color, &pixel, dest->bits.format))
1054
        {
912
        {
1055
            pixman_region32_t fill_region;
913
            pixman_region32_t fill_region;
1056
            int n_rects, j;
914
            int n_rects, j;
1057
            pixman_box32_t *rects;
915
            pixman_box32_t *rects;
1058
 
916
 
1059
            if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
917
            if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1060
                return FALSE;
918
                return FALSE;
1061
 
919
 
1062
            if (dest->common.have_clip_region)
920
            if (dest->common.have_clip_region)
1063
            {
921
            {
1064
                if (!pixman_region32_intersect (&fill_region,
922
                if (!pixman_region32_intersect (&fill_region,
1065
                                                &fill_region,
923
                                                &fill_region,
1066
                                                &dest->common.clip_region))
924
                                                &dest->common.clip_region))
1067
                    return FALSE;
925
                    return FALSE;
1068
            }
926
            }
1069
 
927
 
1070
            rects = pixman_region32_rectangles (&fill_region, &n_rects);
928
            rects = pixman_region32_rectangles (&fill_region, &n_rects);
1071
            for (j = 0; j < n_rects; ++j)
929
            for (j = 0; j < n_rects; ++j)
1072
            {
930
            {
1073
                const pixman_box32_t *rect = &(rects[j]);
931
                const pixman_box32_t *rect = &(rects[j]);
1074
                pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
932
                pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1075
                             rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
933
                             rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1076
                             pixel);
934
                             pixel);
1077
            }
935
            }
1078
 
936
 
1079
            pixman_region32_fini (&fill_region);
937
            pixman_region32_fini (&fill_region);
1080
            return TRUE;
938
            return TRUE;
1081
        }
939
        }
1082
    }
940
    }
1083
 
941
 
1084
    solid = pixman_image_create_solid_fill (color);
942
    solid = pixman_image_create_solid_fill (color);
1085
    if (!solid)
943
    if (!solid)
1086
        return FALSE;
944
        return FALSE;
1087
 
945
 
1088
    for (i = 0; i < n_boxes; ++i)
946
    for (i = 0; i < n_boxes; ++i)
1089
    {
947
    {
1090
        const pixman_box32_t *box = &(boxes[i]);
948
        const pixman_box32_t *box = &(boxes[i]);
1091
 
949
 
1092
        pixman_image_composite32 (op, solid, NULL, dest,
950
        pixman_image_composite32 (op, solid, NULL, dest,
1093
                                  0, 0, 0, 0,
951
                                  0, 0, 0, 0,
1094
                                  box->x1, box->y1,
952
                                  box->x1, box->y1,
1095
                                  box->x2 - box->x1, box->y2 - box->y1);
953
                                  box->x2 - box->x1, box->y2 - box->y1);
1096
    }
954
    }
1097
 
955
 
1098
    pixman_image_unref (solid);
956
    pixman_image_unref (solid);
1099
 
957
 
1100
    return TRUE;
958
    return TRUE;
1101
}
959
}
1102
 
960
 
1103
/**
961
/**
1104
 * pixman_version:
962
 * pixman_version:
1105
 *
963
 *
1106
 * Returns the version of the pixman library encoded in a single
964
 * Returns the version of the pixman library encoded in a single
1107
 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
965
 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1108
 * later versions compare greater than earlier versions.
966
 * later versions compare greater than earlier versions.
1109
 *
967
 *
1110
 * A run-time comparison to check that pixman's version is greater than
968
 * A run-time comparison to check that pixman's version is greater than
1111
 * or equal to version X.Y.Z could be performed as follows:
969
 * or equal to version X.Y.Z could be performed as follows:
1112
 *
970
 *
1113
 * 
971
 * 
1114
 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
972
 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1115
 * 
973
 * 
1116
 *
974
 *
1117
 * See also pixman_version_string() as well as the compile-time
975
 * See also pixman_version_string() as well as the compile-time
1118
 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
976
 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1119
 *
977
 *
1120
 * Return value: the encoded version.
978
 * Return value: the encoded version.
1121
 **/
979
 **/
1122
PIXMAN_EXPORT int
980
PIXMAN_EXPORT int
1123
pixman_version (void)
981
pixman_version (void)
1124
{
982
{
1125
    return PIXMAN_VERSION;
983
    return PIXMAN_VERSION;
1126
}
984
}
1127
 
985
 
1128
/**
986
/**
1129
 * pixman_version_string:
987
 * pixman_version_string:
1130
 *
988
 *
1131
 * Returns the version of the pixman library as a human-readable string
989
 * Returns the version of the pixman library as a human-readable string
1132
 * of the form "X.Y.Z".
990
 * of the form "X.Y.Z".
1133
 *
991
 *
1134
 * See also pixman_version() as well as the compile-time equivalents
992
 * See also pixman_version() as well as the compile-time equivalents
1135
 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
993
 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1136
 *
994
 *
1137
 * Return value: a string containing the version.
995
 * Return value: a string containing the version.
1138
 **/
996
 **/
1139
PIXMAN_EXPORT const char*
997
PIXMAN_EXPORT const char*
1140
pixman_version_string (void)
998
pixman_version_string (void)
1141
{
999
{
1142
    return PIXMAN_VERSION_STRING;
1000
    return PIXMAN_VERSION_STRING;
1143
}
1001
}
1144
 
1002
 
1145
/**
1003
/**
1146
 * pixman_format_supported_source:
1004
 * pixman_format_supported_source:
1147
 * @format: A pixman_format_code_t format
1005
 * @format: A pixman_format_code_t format
1148
 *
1006
 *
1149
 * Return value: whether the provided format code is a supported
1007
 * Return value: whether the provided format code is a supported
1150
 * format for a pixman surface used as a source in
1008
 * format for a pixman surface used as a source in
1151
 * rendering.
1009
 * rendering.
1152
 *
1010
 *
1153
 * Currently, all pixman_format_code_t values are supported.
1011
 * Currently, all pixman_format_code_t values are supported.
1154
 **/
1012
 **/
1155
PIXMAN_EXPORT pixman_bool_t
1013
PIXMAN_EXPORT pixman_bool_t
1156
pixman_format_supported_source (pixman_format_code_t format)
1014
pixman_format_supported_source (pixman_format_code_t format)
1157
{
1015
{
1158
    switch (format)
1016
    switch (format)
1159
    {
1017
    {
1160
    /* 32 bpp formats */
1018
    /* 32 bpp formats */
1161
    case PIXMAN_a2b10g10r10:
1019
    case PIXMAN_a2b10g10r10:
1162
    case PIXMAN_x2b10g10r10:
1020
    case PIXMAN_x2b10g10r10:
1163
    case PIXMAN_a2r10g10b10:
1021
    case PIXMAN_a2r10g10b10:
1164
    case PIXMAN_x2r10g10b10:
1022
    case PIXMAN_x2r10g10b10:
1165
    case PIXMAN_a8r8g8b8:
1023
    case PIXMAN_a8r8g8b8:
-
 
1024
    case PIXMAN_a8r8g8b8_sRGB:
1166
    case PIXMAN_x8r8g8b8:
1025
    case PIXMAN_x8r8g8b8:
1167
    case PIXMAN_a8b8g8r8:
1026
    case PIXMAN_a8b8g8r8:
1168
    case PIXMAN_x8b8g8r8:
1027
    case PIXMAN_x8b8g8r8:
1169
    case PIXMAN_b8g8r8a8:
1028
    case PIXMAN_b8g8r8a8:
1170
    case PIXMAN_b8g8r8x8:
1029
    case PIXMAN_b8g8r8x8:
-
 
1030
    case PIXMAN_r8g8b8a8:
-
 
1031
    case PIXMAN_r8g8b8x8:
1171
    case PIXMAN_r8g8b8:
1032
    case PIXMAN_r8g8b8:
1172
    case PIXMAN_b8g8r8:
1033
    case PIXMAN_b8g8r8:
1173
    case PIXMAN_r5g6b5:
1034
    case PIXMAN_r5g6b5:
1174
    case PIXMAN_b5g6r5:
1035
    case PIXMAN_b5g6r5:
1175
    case PIXMAN_x14r6g6b6:
1036
    case PIXMAN_x14r6g6b6:
1176
    /* 16 bpp formats */
1037
    /* 16 bpp formats */
1177
    case PIXMAN_a1r5g5b5:
1038
    case PIXMAN_a1r5g5b5:
1178
    case PIXMAN_x1r5g5b5:
1039
    case PIXMAN_x1r5g5b5:
1179
    case PIXMAN_a1b5g5r5:
1040
    case PIXMAN_a1b5g5r5:
1180
    case PIXMAN_x1b5g5r5:
1041
    case PIXMAN_x1b5g5r5:
1181
    case PIXMAN_a4r4g4b4:
1042
    case PIXMAN_a4r4g4b4:
1182
    case PIXMAN_x4r4g4b4:
1043
    case PIXMAN_x4r4g4b4:
1183
    case PIXMAN_a4b4g4r4:
1044
    case PIXMAN_a4b4g4r4:
1184
    case PIXMAN_x4b4g4r4:
1045
    case PIXMAN_x4b4g4r4:
1185
    /* 8bpp formats */
1046
    /* 8bpp formats */
1186
    case PIXMAN_a8:
1047
    case PIXMAN_a8:
1187
    case PIXMAN_r3g3b2:
1048
    case PIXMAN_r3g3b2:
1188
    case PIXMAN_b2g3r3:
1049
    case PIXMAN_b2g3r3:
1189
    case PIXMAN_a2r2g2b2:
1050
    case PIXMAN_a2r2g2b2:
1190
    case PIXMAN_a2b2g2r2:
1051
    case PIXMAN_a2b2g2r2:
1191
    case PIXMAN_c8:
1052
    case PIXMAN_c8:
1192
    case PIXMAN_g8:
1053
    case PIXMAN_g8:
1193
    case PIXMAN_x4a4:
1054
    case PIXMAN_x4a4:
1194
    /* Collides with PIXMAN_c8
1055
    /* Collides with PIXMAN_c8
1195
       case PIXMAN_x4c4:
1056
       case PIXMAN_x4c4:
1196
     */
1057
     */
1197
    /* Collides with PIXMAN_g8
1058
    /* Collides with PIXMAN_g8
1198
       case PIXMAN_x4g4:
1059
       case PIXMAN_x4g4:
1199
     */
1060
     */
1200
    /* 4bpp formats */
1061
    /* 4bpp formats */
1201
    case PIXMAN_a4:
1062
    case PIXMAN_a4:
1202
    case PIXMAN_r1g2b1:
1063
    case PIXMAN_r1g2b1:
1203
    case PIXMAN_b1g2r1:
1064
    case PIXMAN_b1g2r1:
1204
    case PIXMAN_a1r1g1b1:
1065
    case PIXMAN_a1r1g1b1:
1205
    case PIXMAN_a1b1g1r1:
1066
    case PIXMAN_a1b1g1r1:
1206
    case PIXMAN_c4:
1067
    case PIXMAN_c4:
1207
    case PIXMAN_g4:
1068
    case PIXMAN_g4:
1208
    /* 1bpp formats */
1069
    /* 1bpp formats */
1209
    case PIXMAN_a1:
1070
    case PIXMAN_a1:
1210
    case PIXMAN_g1:
1071
    case PIXMAN_g1:
1211
    /* YUV formats */
1072
    /* YUV formats */
1212
    case PIXMAN_yuy2:
1073
    case PIXMAN_yuy2:
1213
    case PIXMAN_yv12:
1074
    case PIXMAN_yv12:
1214
	return TRUE;
1075
	return TRUE;
1215
 
1076
 
1216
    default:
1077
    default:
1217
	return FALSE;
1078
	return FALSE;
1218
    }
1079
    }
1219
}
1080
}
1220
 
1081
 
1221
/**
1082
/**
1222
 * pixman_format_supported_destination:
1083
 * pixman_format_supported_destination:
1223
 * @format: A pixman_format_code_t format
1084
 * @format: A pixman_format_code_t format
1224
 *
1085
 *
1225
 * Return value: whether the provided format code is a supported
1086
 * Return value: whether the provided format code is a supported
1226
 * format for a pixman surface used as a destination in
1087
 * format for a pixman surface used as a destination in
1227
 * rendering.
1088
 * rendering.
1228
 *
1089
 *
1229
 * Currently, all pixman_format_code_t values are supported
1090
 * Currently, all pixman_format_code_t values are supported
1230
 * except for the YUV formats.
1091
 * except for the YUV formats.
1231
 **/
1092
 **/
1232
PIXMAN_EXPORT pixman_bool_t
1093
PIXMAN_EXPORT pixman_bool_t
1233
pixman_format_supported_destination (pixman_format_code_t format)
1094
pixman_format_supported_destination (pixman_format_code_t format)
1234
{
1095
{
1235
    /* YUV formats cannot be written to at the moment */
1096
    /* YUV formats cannot be written to at the moment */
1236
    if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1097
    if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1237
	return FALSE;
1098
	return FALSE;
1238
 
1099
 
1239
    return pixman_format_supported_source (format);
1100
    return pixman_format_supported_source (format);
1240
}
1101
}
1241
 
1102
 
1242
PIXMAN_EXPORT pixman_bool_t
1103
PIXMAN_EXPORT pixman_bool_t
1243
pixman_compute_composite_region (pixman_region16_t * region,
1104
pixman_compute_composite_region (pixman_region16_t * region,
1244
                                 pixman_image_t *    src_image,
1105
                                 pixman_image_t *    src_image,
1245
                                 pixman_image_t *    mask_image,
1106
                                 pixman_image_t *    mask_image,
1246
                                 pixman_image_t *    dst_image,
1107
                                 pixman_image_t *    dest_image,
1247
                                 int16_t             src_x,
1108
                                 int16_t             src_x,
1248
                                 int16_t             src_y,
1109
                                 int16_t             src_y,
1249
                                 int16_t             mask_x,
1110
                                 int16_t             mask_x,
1250
                                 int16_t             mask_y,
1111
                                 int16_t             mask_y,
1251
                                 int16_t             dest_x,
1112
                                 int16_t             dest_x,
1252
                                 int16_t             dest_y,
1113
                                 int16_t             dest_y,
1253
                                 uint16_t            width,
1114
                                 uint16_t            width,
1254
                                 uint16_t            height)
1115
                                 uint16_t            height)
1255
{
1116
{
1256
    pixman_region32_t r32;
1117
    pixman_region32_t r32;
1257
    pixman_bool_t retval;
1118
    pixman_bool_t retval;
1258
 
1119
 
1259
    pixman_region32_init (&r32);
1120
    pixman_region32_init (&r32);
1260
 
1121
 
1261
    retval = pixman_compute_composite_region32 (
1122
    retval = _pixman_compute_composite_region32 (
1262
	&r32, src_image, mask_image, dst_image,
1123
	&r32, src_image, mask_image, dest_image,
1263
	src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1124
	src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1264
	width, height);
1125
	width, height);
1265
 
1126
 
1266
    if (retval)
1127
    if (retval)
1267
    {
1128
    {
1268
	if (!pixman_region16_copy_from_region32 (region, &r32))
1129
	if (!pixman_region16_copy_from_region32 (region, &r32))
1269
	    retval = FALSE;
1130
	    retval = FALSE;
1270
    }
1131
    }
1271
 
1132
 
1272
    pixman_region32_fini (&r32);
1133
    pixman_region32_fini (&r32);
1273
    return retval;
1134
    return retval;
1274
}
1135
}