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