File: | root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-source.c |
Warning: | line 1028, column 2 Value stored to 'status' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ |
2 | /* cairo - a vector graphics library with display and print output |
3 | * |
4 | * Copyright © 2002 University of Southern California |
5 | * Copyright © 2005 Red Hat, Inc. |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it either under the terms of the GNU Lesser General Public |
9 | * License version 2.1 as published by the Free Software Foundation |
10 | * (the "LGPL") or, at your option, under the terms of the Mozilla |
11 | * Public License Version 1.1 (the "MPL"). If you do not alter this |
12 | * notice, a recipient may use your version of this file under either |
13 | * the MPL or the LGPL. |
14 | * |
15 | * You should have received a copy of the LGPL along with this library |
16 | * in the file COPYING-LGPL-2.1; if not, write to the Free Software |
17 | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA |
18 | * You should have received a copy of the MPL along with this library |
19 | * in the file COPYING-MPL-1.1 |
20 | * |
21 | * The contents of this file are subject to the Mozilla Public License |
22 | * Version 1.1 (the "License"); you may not use this file except in |
23 | * compliance with the License. You may obtain a copy of the License at |
24 | * http://www.mozilla.org/MPL/ |
25 | * |
26 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY |
27 | * OF ANY KIND, either express or implied. See the LGPL or the MPL for |
28 | * the specific language governing rights and limitations. |
29 | * |
30 | * The Original Code is the cairo graphics library. |
31 | * |
32 | * The Initial Developer of the Original Code is University of Southern |
33 | * California. |
34 | * |
35 | * Contributor(s): |
36 | * Carl D. Worth <cworth@cworth.org> |
37 | * Behdad Esfahbod <behdad@behdad.org> |
38 | * Chris Wilson <chris@chris-wilson.co.uk> |
39 | * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation |
40 | */ |
41 | #include "cairoint.h" |
42 | |
43 | #if !CAIRO_HAS_XLIB_XCB_FUNCTIONS |
44 | |
45 | #include "cairo-xlib-private.h" |
46 | #include "cairo-xlib-surface-private.h" |
47 | |
48 | #include "cairo-error-private.h" |
49 | #include "cairo-image-surface-inline.h" |
50 | #include "cairo-paginated-private.h" |
51 | #include "cairo-pattern-inline.h" |
52 | #include "cairo-recording-surface-private.h" |
53 | #include "cairo-surface-backend-private.h" |
54 | #include "cairo-surface-offset-private.h" |
55 | #include "cairo-surface-observer-private.h" |
56 | #include "cairo-surface-snapshot-inline.h" |
57 | #include "cairo-surface-subsurface-inline.h" |
58 | |
59 | #define PIXMAN_MAX_INT(((((pixman_fixed_t) ((uint32_t) (1) << 16))) >> 1 ) - ((pixman_fixed_t) 1)) ((pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) >> 1) - pixman_fixed_e((pixman_fixed_t) 1)) /* need to ensure deltas also fit */ |
60 | |
61 | static cairo_xlib_surface_t * |
62 | unwrap_source (const cairo_surface_pattern_t *pattern) |
63 | { |
64 | cairo_rectangle_int_t limits; |
65 | return (cairo_xlib_surface_t *)_cairo_pattern_get_source (pattern, &limits); |
66 | } |
67 | |
68 | static cairo_status_t |
69 | _cairo_xlib_source_finish (void *abstract_surface) |
70 | { |
71 | cairo_xlib_source_t *source = abstract_surface; |
72 | |
73 | XRenderFreePicture_void_consume_free (source->dpy, source->picture); |
74 | if (source->pixmap) |
75 | XFreePixmap (source->dpy, source->pixmap); |
76 | return CAIRO_STATUS_SUCCESS; |
77 | } |
78 | |
79 | static const cairo_surface_backend_t cairo_xlib_source_backend = { |
80 | CAIRO_SURFACE_TYPE_XLIB, |
81 | _cairo_xlib_source_finish, |
82 | NULL((void*)0), /* read-only wrapper */ |
83 | }; |
84 | |
85 | static cairo_status_t |
86 | _cairo_xlib_proxy_finish (void *abstract_surface) |
87 | { |
88 | cairo_xlib_proxy_t *proxy = abstract_surface; |
89 | |
90 | _cairo_xlib_shm_surface_mark_active (proxy->owner); |
91 | XRenderFreePicture_void_consume_free (proxy->source.dpy, proxy->source.picture); |
92 | if (proxy->source.pixmap) |
93 | XFreePixmap (proxy->source.dpy, proxy->source.pixmap); |
94 | cairo_surface_destroy_moz_cairo_surface_destroy (proxy->owner); |
95 | return CAIRO_STATUS_SUCCESS; |
96 | } |
97 | |
98 | static const cairo_surface_backend_t cairo_xlib_proxy_backend = { |
99 | CAIRO_SURFACE_TYPE_XLIB, |
100 | _cairo_xlib_proxy_finish, |
101 | NULL((void*)0), /* read-only wrapper */ |
102 | }; |
103 | |
104 | static cairo_surface_t * |
105 | source (cairo_xlib_surface_t *dst, Picture picture, Pixmap pixmap) |
106 | { |
107 | cairo_xlib_source_t *source; |
108 | |
109 | if (picture == None0L) |
110 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
111 | |
112 | source = _cairo_malloc (sizeof (*source))((sizeof (*source)) != 0 ? malloc(sizeof (*source)) : ((void* )0)); |
113 | if (unlikely (source == NULL)(__builtin_expect (!!(source == ((void*)0)), 0))) { |
114 | XRenderFreePicture_void_consume_free (dst->display->display, picture); |
115 | if (pixmap) |
116 | XFreePixmap (dst->display->display, pixmap); |
117 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
118 | } |
119 | |
120 | _cairo_surface_init (&source->base, |
121 | &cairo_xlib_source_backend, |
122 | NULL((void*)0), /* device */ |
123 | CAIRO_CONTENT_COLOR_ALPHA, |
124 | FALSE0); /* is_vector */ |
125 | |
126 | /* The source exists only within an operation */ |
127 | source->picture = picture; |
128 | source->pixmap = pixmap; |
129 | source->dpy = dst->display->display; |
130 | |
131 | return &source->base; |
132 | } |
133 | |
134 | static uint32_t |
135 | hars_petruska_f54_1_random (void) |
136 | { |
137 | #define rol(x,k) ((x << k) | (x >> (32-k))) |
138 | static uint32_t x; |
139 | return x = (x ^ rol (x, 5) ^ rol (x, 24)) + 0x37798849; |
140 | #undef rol |
141 | } |
142 | |
143 | static const XTransform identity = { |
144 | { |
145 | { 1 << 16, 0x00000, 0x00000 }, |
146 | { 0x00000, 1 << 16, 0x00000 }, |
147 | { 0x00000, 0x00000, 1 << 16 }, |
148 | } |
149 | }; |
150 | |
151 | static cairo_bool_t |
152 | picture_set_matrix (cairo_xlib_display_t *display, |
153 | Picture picture, |
154 | const cairo_matrix_t *matrix, |
155 | cairo_filter_t filter, |
156 | double xc, |
157 | double yc, |
158 | int *x_offset, |
159 | int *y_offset) |
160 | { |
161 | XTransform xtransform; |
162 | pixman_transform_t *pixman_transform; |
163 | cairo_int_status_t status; |
164 | |
165 | /* Casting between pixman_transform_t and XTransform is safe because |
166 | * they happen to be the exact same type. |
167 | */ |
168 | pixman_transform = (pixman_transform_t *) &xtransform; |
169 | status = _cairo_matrix_to_pixman_matrix_offset (matrix, filter, xc, yc, |
170 | pixman_transform, |
171 | x_offset, y_offset); |
172 | if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) |
173 | return TRUE1; |
174 | if (unlikely (status != CAIRO_INT_STATUS_SUCCESS)(__builtin_expect (!!(status != CAIRO_INT_STATUS_SUCCESS), 0) )) |
175 | return FALSE0; |
176 | |
177 | if (memcmp (&xtransform, &identity, sizeof (XTransform)) == 0) |
178 | return TRUE1; |
179 | |
180 | /* a late check in case we perturb the matrix too far */ |
181 | if (! CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display)((((display))->render_major > 0) || ((((display))->render_major == 0) && (((display))->render_minor >= 6)))) |
182 | return FALSE0; |
183 | |
184 | XRenderSetPictureTransform_void_consume (display->display, picture, &xtransform); |
185 | return TRUE1; |
186 | } |
187 | |
188 | static cairo_status_t |
189 | picture_set_filter (Display *dpy, |
190 | Picture picture, |
191 | cairo_filter_t filter) |
192 | { |
193 | const char *render_filter; |
194 | |
195 | switch (filter) { |
196 | case CAIRO_FILTER_FAST: |
197 | render_filter = FilterFast"fast"; |
198 | break; |
199 | case CAIRO_FILTER_GOOD: |
200 | render_filter = FilterGood"good"; |
201 | break; |
202 | case CAIRO_FILTER_BEST: |
203 | render_filter = FilterBest"best"; |
204 | break; |
205 | case CAIRO_FILTER_NEAREST: |
206 | render_filter = FilterNearest"nearest"; |
207 | break; |
208 | case CAIRO_FILTER_BILINEAR: |
209 | render_filter = FilterBilinear"bilinear"; |
210 | break; |
211 | case CAIRO_FILTER_GAUSSIAN: |
212 | /* XXX: The GAUSSIAN value has no implementation in cairo |
213 | * whatsoever, so it was really a mistake to have it in the |
214 | * API. We could fix this by officially deprecating it, or |
215 | * else inventing semantics and providing an actual |
216 | * implementation for it. */ |
217 | default: |
218 | render_filter = FilterBest"best"; |
219 | break; |
220 | } |
221 | |
222 | XRenderSetPictureFilter_void_consume (dpy, picture, (char *) render_filter, NULL((void*)0), 0); |
223 | return CAIRO_STATUS_SUCCESS; |
224 | } |
225 | |
226 | static int |
227 | extend_to_repeat (cairo_extend_t extend) |
228 | { |
229 | switch (extend) { |
230 | default: |
231 | ASSERT_NOT_REACHEDdo { ((void) sizeof ((!"reached") ? 1 : 0), __extension__ ({ if (!"reached") ; else __assert_fail ("!\"reached\"", "/root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-source.c" , 231, __extension__ __PRETTY_FUNCTION__); })); } while (0); |
232 | case CAIRO_EXTEND_NONE: |
233 | return RepeatNone0; |
234 | case CAIRO_EXTEND_REPEAT: |
235 | return RepeatNormal1; |
236 | case CAIRO_EXTEND_REFLECT: |
237 | return RepeatReflect3; |
238 | case CAIRO_EXTEND_PAD: |
239 | return RepeatPad2; |
240 | } |
241 | } |
242 | |
243 | static cairo_bool_t |
244 | picture_set_properties (cairo_xlib_display_t *display, |
245 | Picture picture, |
246 | const cairo_pattern_t *pattern, |
247 | const cairo_matrix_t *matrix, |
248 | const cairo_rectangle_int_t *extents, |
249 | int *x_off, int *y_off) |
250 | { |
251 | XRenderPictureAttributes pa; |
252 | int mask = 0; |
253 | |
254 | if (! picture_set_matrix (display, picture, matrix, pattern->filter, |
255 | extents->x + extents->width / 2, |
256 | extents->y + extents->height / 2, |
257 | x_off, y_off)) |
258 | return FALSE0; |
259 | |
260 | picture_set_filter (display->display, picture, pattern->filter); |
261 | |
262 | if (pattern->has_component_alpha) { |
263 | pa.component_alpha = 1; |
264 | mask |= CPComponentAlpha(1 << 12); |
265 | } |
266 | |
267 | if (pattern->extend != CAIRO_EXTEND_NONE) { |
268 | pa.repeat = extend_to_repeat (pattern->extend); |
269 | mask |= CPRepeat(1 << 0); |
270 | } |
271 | |
272 | if (mask) |
273 | XRenderChangePicture_void_consume (display->display, picture, mask, &pa); |
274 | |
275 | return TRUE1; |
276 | } |
277 | |
278 | static cairo_surface_t * |
279 | render_pattern (cairo_xlib_surface_t *dst, |
280 | const cairo_pattern_t *pattern, |
281 | cairo_bool_t is_mask, |
282 | const cairo_rectangle_int_t *extents, |
283 | int *src_x, int *src_y) |
284 | { |
285 | Display *dpy = dst->display->display; |
286 | cairo_xlib_surface_t *src; |
287 | cairo_image_surface_t *image; |
288 | cairo_status_t status; |
289 | cairo_rectangle_int_t map_extents; |
290 | |
291 | src = (cairo_xlib_surface_t *) |
292 | _cairo_surface_create_scratch (&dst->base, |
293 | is_mask ? CAIRO_CONTENT_ALPHA : CAIRO_CONTENT_COLOR_ALPHA, |
294 | extents->width, |
295 | extents->height, |
296 | NULL((void*)0)); |
297 | if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) { |
298 | cairo_surface_destroy_moz_cairo_surface_destroy (&src->base); |
299 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
300 | } |
301 | |
302 | map_extents = *extents; |
303 | map_extents.x = map_extents.y = 0; |
304 | |
305 | image = _cairo_surface_map_to_image (&src->base, &map_extents); |
306 | status = _cairo_surface_offset_paint (&image->base, extents->x, extents->y, |
307 | CAIRO_OPERATOR_SOURCE, pattern, |
308 | NULL((void*)0)); |
309 | status = _cairo_surface_unmap_image (&src->base, image); |
310 | if (unlikely (status)(__builtin_expect (!!(status), 0))) { |
311 | cairo_surface_destroy_moz_cairo_surface_destroy (&src->base); |
312 | return _cairo_surface_create_in_error (status); |
313 | } |
314 | |
315 | status = _cairo_xlib_surface_put_shm (src); |
316 | if (unlikely (status)(__builtin_expect (!!(status), 0))) { |
317 | cairo_surface_destroy_moz_cairo_surface_destroy (&src->base); |
318 | return _cairo_surface_create_in_error (status); |
319 | } |
320 | |
321 | src->picture = XRenderCreatePicture_int_consume (dpy, |
322 | src->drawable, src->xrender_format, |
323 | 0, NULL((void*)0)); |
324 | |
325 | *src_x = -extents->x; |
326 | *src_y = -extents->y; |
327 | return &src->base; |
328 | } |
329 | |
330 | static cairo_surface_t * |
331 | gradient_source (cairo_xlib_surface_t *dst, |
332 | const cairo_gradient_pattern_t *gradient, |
333 | cairo_bool_t is_mask, |
334 | const cairo_rectangle_int_t *extents, |
335 | int *src_x, int *src_y) |
336 | { |
337 | cairo_xlib_display_t *display = dst->display; |
338 | cairo_matrix_t matrix = gradient->base.matrix; |
339 | char buf[CAIRO_STACK_BUFFER_SIZE(512 * sizeof (int))]; |
340 | cairo_circle_double_t extremes[2]; |
341 | XFixed *stops; |
342 | XRenderColor *colors; |
343 | Picture picture; |
344 | unsigned int i, n_stops; |
345 | |
346 | /* The RENDER specification says that the inner circle has |
347 | * to be completely contained inside the outer one. */ |
348 | if (gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL && |
349 | ! _cairo_radial_pattern_focus_is_inside ((cairo_radial_pattern_t *) gradient)) |
350 | return render_pattern (dst, &gradient->base, is_mask, extents, src_x, src_y); |
351 | |
352 | assert (gradient->n_stops > 0)((void) sizeof ((gradient->n_stops > 0) ? 1 : 0), __extension__ ({ if (gradient->n_stops > 0) ; else __assert_fail ("gradient->n_stops > 0" , "/root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-source.c" , 352, __extension__ __PRETTY_FUNCTION__); })); |
353 | n_stops = MAX (gradient->n_stops, 2)((gradient->n_stops) > (2) ? (gradient->n_stops) : ( 2)); |
354 | |
355 | if (n_stops < sizeof (buf) / (sizeof (XFixed) + sizeof (XRenderColor))) |
356 | { |
357 | stops = (XFixed *) buf; |
358 | } |
359 | else |
360 | { |
361 | stops = |
362 | _cairo_malloc_ab (n_stops, |
363 | sizeof (XFixed) + sizeof (XRenderColor)); |
364 | if (unlikely (stops == NULL)(__builtin_expect (!!(stops == ((void*)0)), 0))) |
365 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
366 | } |
367 | |
368 | colors = (XRenderColor *) (stops + n_stops); |
369 | for (i = 0; i < gradient->n_stops; i++) { |
370 | stops[i] = |
371 | _cairo_fixed_16_16_from_double (gradient->stops[i].offset); |
372 | |
373 | colors[i].red = gradient->stops[i].color.red_short; |
374 | colors[i].green = gradient->stops[i].color.green_short; |
375 | colors[i].blue = gradient->stops[i].color.blue_short; |
376 | colors[i].alpha = gradient->stops[i].color.alpha_short; |
377 | } |
378 | |
379 | /* RENDER does not support gradients with less than 2 |
380 | * stops. If a gradient has only a single stop, duplicate |
381 | * it to make RENDER happy. */ |
382 | if (gradient->n_stops == 1) { |
383 | stops[1] = |
384 | _cairo_fixed_16_16_from_double (gradient->stops[0].offset); |
385 | |
386 | colors[1].red = gradient->stops[0].color.red_short; |
387 | colors[1].green = gradient->stops[0].color.green_short; |
388 | colors[1].blue = gradient->stops[0].color.blue_short; |
389 | colors[1].alpha = gradient->stops[0].color.alpha_short; |
390 | } |
391 | |
392 | #if 0 |
393 | /* For some weird reason the X server is sometimes getting |
394 | * CreateGradient requests with bad length. So far I've only seen |
395 | * XRenderCreateLinearGradient request with 4 stops sometime end up |
396 | * with length field matching 0 stops at the server side. I've |
397 | * looked at the libXrender code and I can't see anything that |
398 | * could cause this behavior. However, for some reason having a |
399 | * XSync call here seems to avoid the issue so I'll keep it here |
400 | * until it's solved. |
401 | */ |
402 | XSync (display->display, False0); |
403 | #endif |
404 | |
405 | _cairo_gradient_pattern_fit_to_range (gradient, PIXMAN_MAX_INT(((((pixman_fixed_t) ((uint32_t) (1) << 16))) >> 1 ) - ((pixman_fixed_t) 1)) >> 1, &matrix, extremes); |
406 | |
407 | if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { |
408 | XLinearGradient grad; |
409 | |
410 | grad.p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); |
411 | grad.p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); |
412 | grad.p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); |
413 | grad.p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); |
414 | |
415 | picture = XRenderCreateLinearGradient_int_consume (display->display, &grad, |
416 | stops, colors, |
417 | n_stops); |
418 | } else { |
419 | XRadialGradient grad; |
420 | |
421 | grad.inner.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); |
422 | grad.inner.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); |
423 | grad.inner.radius = _cairo_fixed_16_16_from_double (extremes[0].radius); |
424 | grad.outer.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); |
425 | grad.outer.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); |
426 | grad.outer.radius = _cairo_fixed_16_16_from_double (extremes[1].radius); |
427 | |
428 | picture = XRenderCreateRadialGradient_int_consume (display->display, &grad, |
429 | stops, colors, |
430 | n_stops); |
431 | } |
432 | |
433 | if (stops != (XFixed *) buf) |
434 | free (stops); |
435 | |
436 | *src_x = *src_y = 0; |
437 | if (! picture_set_properties (display, picture, |
438 | &gradient->base, &gradient->base.matrix, |
439 | extents, |
440 | src_x, src_y)) { |
441 | XRenderFreePicture_void_consume_free (display->display, picture); |
442 | return render_pattern (dst, &gradient->base, is_mask, extents, src_x, src_y); |
443 | } |
444 | |
445 | return source (dst, picture, None0L); |
446 | } |
447 | |
448 | static cairo_surface_t * |
449 | color_source (cairo_xlib_surface_t *dst, const cairo_color_t *color) |
450 | { |
451 | Display *dpy = dst->display->display; |
452 | XRenderColor xcolor; |
453 | Picture picture; |
454 | Pixmap pixmap = None0L; |
455 | |
456 | xcolor.red = color->red_short; |
457 | xcolor.green = color->green_short; |
458 | xcolor.blue = color->blue_short; |
459 | xcolor.alpha = color->alpha_short; |
460 | |
461 | if (CAIRO_RENDER_HAS_GRADIENTS(dst->display)((((dst->display))->render_major > 0) || ((((dst-> display))->render_major == 0) && (((dst->display ))->render_minor >= 10)))) { |
462 | picture = XRenderCreateSolidFill_int_consume (dpy, &xcolor); |
463 | } else { |
464 | XRenderPictureAttributes pa; |
465 | int mask = 0; |
466 | |
467 | pa.repeat = RepeatNormal1; |
468 | mask |= CPRepeat(1 << 0); |
469 | |
470 | pixmap = XCreatePixmap (dpy, dst->drawable, 1, 1, 32); |
471 | picture = XRenderCreatePicture_int_consume (dpy, pixmap, |
472 | _cairo_xlib_display_get_xrender_format (dst->display, CAIRO_FORMAT_ARGB32), |
473 | mask, &pa); |
474 | |
475 | if (CAIRO_RENDER_HAS_FILL_RECTANGLES(dst->display)((((dst->display))->render_major > 0) || ((((dst-> display))->render_major == 0) && (((dst->display ))->render_minor >= 1)))) { |
476 | XRectangle r = { 0, 0, 1, 1}; |
477 | XRenderFillRectangles_void_consume (dpy, PictOpSrc1, picture, &xcolor, &r, 1); |
478 | } else { |
479 | XGCValues gcv; |
480 | GC gc; |
481 | |
482 | gc = _cairo_xlib_screen_get_gc (dst->display, dst->screen, |
483 | 32, pixmap); |
484 | if (unlikely (gc == NULL)(__builtin_expect (!!(gc == ((void*)0)), 0))) { |
485 | XFreePixmap (dpy, pixmap); |
486 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
487 | } |
488 | |
489 | gcv.foreground = 0; |
490 | gcv.foreground |= (uint32_t)color->alpha_short >> 8 << 24; |
491 | gcv.foreground |= color->red_short >> 8 << 16; |
492 | gcv.foreground |= color->green_short >> 8 << 8; |
493 | gcv.foreground |= color->blue_short >> 8 << 0; |
494 | gcv.fill_style = FillSolid0; |
495 | |
496 | XChangeGC (dpy, gc, GCFillStyle(1L<<8) | GCForeground(1L<<2), &gcv); |
497 | XFillRectangle (dpy, pixmap, gc, 0, 0, 1, 1); |
498 | |
499 | _cairo_xlib_screen_put_gc (dst->display, dst->screen, 32, gc); |
500 | } |
501 | } |
502 | |
503 | return source (dst, picture, pixmap); |
504 | } |
505 | |
506 | static cairo_surface_t * |
507 | alpha_source (cairo_xlib_surface_t *dst, uint8_t alpha) |
508 | { |
509 | cairo_xlib_display_t *display = dst->display; |
510 | |
511 | if (display->alpha[alpha] == NULL((void*)0)) { |
512 | cairo_color_t color; |
513 | |
514 | color.red_short = color.green_short = color.blue_short = 0; |
515 | color.alpha_short = alpha << 8 | alpha; |
516 | |
517 | display->alpha[alpha] = color_source (dst, &color); |
518 | } |
519 | |
520 | return cairo_surface_reference_moz_cairo_surface_reference (display->alpha[alpha]); |
521 | } |
522 | |
523 | static cairo_surface_t * |
524 | white_source (cairo_xlib_surface_t *dst) |
525 | { |
526 | cairo_xlib_display_t *display = dst->display; |
527 | |
528 | if (display->white == NULL((void*)0)) |
529 | display->white = color_source (dst, CAIRO_COLOR_WHITE_cairo_stock_color (CAIRO_STOCK_WHITE)); |
530 | |
531 | return cairo_surface_reference_moz_cairo_surface_reference (display->white); |
532 | } |
533 | |
534 | static cairo_surface_t * |
535 | opaque_source (cairo_xlib_surface_t *dst, const cairo_color_t *color) |
536 | { |
537 | cairo_xlib_display_t *display = dst->display; |
538 | uint32_t pixel = |
539 | 0xff000000 | |
540 | color->red_short >> 8 << 16 | |
541 | color->green_short >> 8 << 8 | |
542 | color->blue_short >> 8 << 0; |
543 | int i; |
544 | |
545 | if (display->last_solid_cache[0].color == pixel) |
546 | return cairo_surface_reference_moz_cairo_surface_reference (display->solid[display->last_solid_cache[0].index]); |
547 | |
548 | for (i = 0; i < 16; i++) { |
549 | if (display->solid_cache[i] == pixel) |
550 | goto done; |
551 | } |
552 | |
553 | i = hars_petruska_f54_1_random () % 16; |
554 | cairo_surface_destroy_moz_cairo_surface_destroy (display->solid[i]); |
555 | |
556 | display->solid[i] = color_source (dst, color); |
557 | display->solid_cache[i] = pixel; |
558 | |
559 | done: |
560 | display->last_solid_cache[0].color = pixel; |
561 | display->last_solid_cache[0].index = i; |
562 | return cairo_surface_reference_moz_cairo_surface_reference (display->solid[i]); |
563 | } |
564 | |
565 | static cairo_surface_t * |
566 | transparent_source (cairo_xlib_surface_t *dst, const cairo_color_t *color) |
567 | { |
568 | cairo_xlib_display_t *display = dst->display; |
569 | uint32_t pixel = |
570 | (uint32_t)color->alpha_short >> 8 << 24 | |
571 | color->red_short >> 8 << 16 | |
572 | color->green_short >> 8 << 8 | |
573 | color->blue_short >> 8 << 0; |
574 | int i; |
575 | |
576 | if (display->last_solid_cache[1].color == pixel) { |
577 | assert (display->solid[display->last_solid_cache[1].index])((void) sizeof ((display->solid[display->last_solid_cache [1].index]) ? 1 : 0), __extension__ ({ if (display->solid[ display->last_solid_cache[1].index]) ; else __assert_fail ( "display->solid[display->last_solid_cache[1].index]", "/root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-source.c" , 577, __extension__ __PRETTY_FUNCTION__); })); |
578 | return cairo_surface_reference_moz_cairo_surface_reference (display->solid[display->last_solid_cache[1].index]); |
579 | } |
580 | |
581 | for (i = 16; i < 32; i++) { |
582 | if (display->solid_cache[i] == pixel) |
583 | goto done; |
584 | } |
585 | |
586 | i = 16 + (hars_petruska_f54_1_random () % 16); |
587 | cairo_surface_destroy_moz_cairo_surface_destroy (display->solid[i]); |
588 | |
589 | display->solid[i] = color_source (dst, color); |
590 | display->solid_cache[i] = pixel; |
591 | |
592 | done: |
593 | display->last_solid_cache[1].color = pixel; |
594 | display->last_solid_cache[1].index = i; |
595 | assert (display->solid[i])((void) sizeof ((display->solid[i]) ? 1 : 0), __extension__ ({ if (display->solid[i]) ; else __assert_fail ("display->solid[i]" , "/root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-source.c" , 595, __extension__ __PRETTY_FUNCTION__); })); |
596 | return cairo_surface_reference_moz_cairo_surface_reference (display->solid[i]); |
597 | } |
598 | |
599 | static cairo_surface_t * |
600 | solid_source (cairo_xlib_surface_t *dst, |
601 | const cairo_color_t *color) |
602 | { |
603 | if ((color->red_short | color->green_short | color->blue_short) <= 0xff) |
604 | return alpha_source (dst, color->alpha_short >> 8); |
605 | |
606 | if (CAIRO_ALPHA_SHORT_IS_OPAQUE (color->alpha_short)((color->alpha_short) >= 0xff00)) { |
607 | if (color->red_short >= 0xff00 && color->green_short >= 0xff00 && color->blue_short >= 0xff00) |
608 | return white_source (dst); |
609 | |
610 | return opaque_source (dst, color); |
611 | } else |
612 | return transparent_source (dst, color); |
613 | } |
614 | |
615 | static cairo_xlib_source_t *init_source (cairo_xlib_surface_t *dst, |
616 | cairo_xlib_surface_t *src) |
617 | { |
618 | Display *dpy = dst->display->display; |
619 | cairo_xlib_source_t *source = &src->embedded_source; |
620 | |
621 | /* As these are frequent and meant to be fast, we track pictures for |
622 | * native surface and minimise update requests. |
623 | */ |
624 | if (source->picture == None0L) { |
625 | XRenderPictureAttributes pa; |
626 | |
627 | _cairo_surface_init (&source->base, |
628 | &cairo_xlib_source_backend, |
629 | NULL((void*)0), /* device */ |
630 | CAIRO_CONTENT_COLOR_ALPHA, |
631 | FALSE0); /* is_vector */ |
632 | |
633 | pa.subwindow_mode = IncludeInferiors1; |
634 | source->picture = XRenderCreatePicture_int_consume (dpy, |
635 | src->drawable, |
636 | src->xrender_format, |
637 | CPSubwindowMode(1 << 8), &pa); |
638 | |
639 | source->has_component_alpha = 0; |
640 | source->has_matrix = 0; |
641 | source->filter = CAIRO_FILTER_NEAREST; |
642 | source->extend = CAIRO_EXTEND_NONE; |
643 | } |
644 | |
645 | return (cairo_xlib_source_t *) cairo_surface_reference_moz_cairo_surface_reference (&source->base); |
646 | } |
647 | |
648 | static cairo_surface_t * |
649 | embedded_source (cairo_xlib_surface_t *dst, |
650 | const cairo_surface_pattern_t *pattern, |
651 | const cairo_rectangle_int_t *extents, |
652 | int *src_x, int *src_y, |
653 | cairo_xlib_source_t *source) |
654 | { |
655 | Display *dpy = dst->display->display; |
656 | cairo_int_status_t status; |
657 | XTransform xtransform; |
658 | XRenderPictureAttributes pa; |
659 | unsigned mask = 0; |
660 | |
661 | status = _cairo_matrix_to_pixman_matrix_offset (&pattern->base.matrix, |
662 | pattern->base.filter, |
663 | extents->x + extents->width / 2, |
664 | extents->y + extents->height / 2, |
665 | (pixman_transform_t *)&xtransform, |
666 | src_x, src_y); |
667 | |
668 | if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
669 | if (source->has_matrix) { |
670 | source->has_matrix = 0; |
671 | memcpy (&xtransform, &identity, sizeof (identity)); |
672 | status = CAIRO_INT_STATUS_SUCCESS; |
673 | } |
674 | } else |
675 | source->has_matrix = 1; |
676 | if (status == CAIRO_INT_STATUS_SUCCESS) |
677 | XRenderSetPictureTransform_void_consume (dpy, source->picture, &xtransform); |
678 | |
679 | if (source->filter != pattern->base.filter) { |
680 | picture_set_filter (dpy, source->picture, pattern->base.filter); |
681 | source->filter = pattern->base.filter; |
682 | } |
683 | |
684 | if (source->has_component_alpha != pattern->base.has_component_alpha) { |
685 | pa.component_alpha = pattern->base.has_component_alpha; |
686 | mask |= CPComponentAlpha(1 << 12); |
687 | source->has_component_alpha = pattern->base.has_component_alpha; |
688 | } |
689 | |
690 | if (source->extend != pattern->base.extend) { |
691 | pa.repeat = extend_to_repeat (pattern->base.extend); |
692 | mask |= CPRepeat(1 << 0); |
693 | source->extend = pattern->base.extend; |
694 | } |
695 | |
696 | if (mask) |
697 | XRenderChangePicture_void_consume (dpy, source->picture, mask, &pa); |
698 | |
699 | return &source->base; |
700 | } |
701 | |
702 | static cairo_surface_t * |
703 | subsurface_source (cairo_xlib_surface_t *dst, |
704 | const cairo_surface_pattern_t *pattern, |
705 | cairo_bool_t is_mask, |
706 | const cairo_rectangle_int_t *extents, |
707 | const cairo_rectangle_int_t *sample, |
708 | int *src_x, int *src_y) |
709 | { |
710 | cairo_surface_subsurface_t *sub; |
711 | cairo_xlib_surface_t *src; |
712 | cairo_xlib_source_t *source; |
713 | Display *dpy = dst->display->display; |
714 | cairo_int_status_t status; |
715 | cairo_surface_pattern_t local_pattern; |
716 | XTransform xtransform; |
717 | XRenderPictureAttributes pa; |
718 | unsigned mask = 0; |
719 | |
720 | sub = (cairo_surface_subsurface_t *) pattern->surface; |
721 | |
722 | if (sample->x >= 0 && sample->y >= 0 && |
723 | sample->x + sample->width <= sub->extents.width && |
724 | sample->y + sample->height <= sub->extents.height) |
725 | { |
726 | src = (cairo_xlib_surface_t *) sub->target; |
727 | status = _cairo_surface_flush (&src->base, 0); |
728 | if (unlikely (status)(__builtin_expect (!!(status), 0))) |
729 | return _cairo_surface_create_in_error (status); |
730 | |
731 | if (pattern->base.filter == CAIRO_FILTER_NEAREST && |
732 | _cairo_matrix_is_translation (&pattern->base.matrix)) |
733 | { |
734 | *src_x += pattern->base.matrix.x0 + sub->extents.x; |
735 | *src_y += pattern->base.matrix.y0 + sub->extents.y; |
736 | |
737 | _cairo_xlib_surface_ensure_picture (src); |
738 | return cairo_surface_reference_moz_cairo_surface_reference (&src->base); |
739 | } |
740 | else |
741 | { |
742 | cairo_surface_pattern_t local_pattern = *pattern; |
743 | local_pattern.base.matrix.x0 += sub->extents.x; |
744 | local_pattern.base.matrix.y0 += sub->extents.y; |
745 | local_pattern.base.extend = CAIRO_EXTEND_NONE; |
746 | return embedded_source (dst, &local_pattern, extents, |
747 | src_x, src_y, init_source (dst, src)); |
748 | } |
749 | } |
750 | |
751 | if (sub->snapshot && sub->snapshot->type == CAIRO_SURFACE_TYPE_XLIB) { |
752 | src = (cairo_xlib_surface_t *) cairo_surface_reference_moz_cairo_surface_reference (sub->snapshot); |
753 | source = &src->embedded_source; |
754 | } else { |
755 | src = (cairo_xlib_surface_t *) |
756 | _cairo_surface_create_scratch (&dst->base, |
757 | sub->base.content, |
758 | sub->extents.width, |
759 | sub->extents.height, |
760 | NULL((void*)0)); |
761 | if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) { |
762 | cairo_surface_destroy_moz_cairo_surface_destroy (&src->base); |
763 | return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); |
764 | } |
765 | |
766 | _cairo_pattern_init_for_surface (&local_pattern, sub->target); |
767 | cairo_matrix_init_translate_moz_cairo_matrix_init_translate (&local_pattern.base.matrix, |
768 | sub->extents.x, sub->extents.y); |
769 | local_pattern.base.filter = CAIRO_FILTER_NEAREST; |
770 | status = _cairo_surface_paint (&src->base, |
771 | CAIRO_OPERATOR_SOURCE, |
772 | &local_pattern.base, |
773 | NULL((void*)0)); |
774 | _cairo_pattern_fini (&local_pattern.base); |
775 | |
776 | if (unlikely (status)(__builtin_expect (!!(status), 0))) { |
777 | cairo_surface_destroy_moz_cairo_surface_destroy (&src->base); |
778 | return _cairo_surface_create_in_error (status); |
779 | } |
780 | |
781 | _cairo_xlib_surface_ensure_picture (src); |
782 | _cairo_surface_subsurface_set_snapshot (&sub->base, &src->base); |
783 | |
784 | source = &src->embedded_source; |
785 | source->has_component_alpha = 0; |
786 | source->has_matrix = 0; |
787 | source->filter = CAIRO_FILTER_NEAREST; |
788 | source->extend = CAIRO_EXTEND_NONE; |
789 | } |
790 | |
791 | status = _cairo_matrix_to_pixman_matrix_offset (&pattern->base.matrix, |
792 | pattern->base.filter, |
793 | extents->x + extents->width / 2, |
794 | extents->y + extents->height / 2, |
795 | (pixman_transform_t *)&xtransform, |
796 | src_x, src_y); |
797 | if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
798 | if (source->has_matrix) { |
799 | source->has_matrix = 0; |
800 | memcpy (&xtransform, &identity, sizeof (identity)); |
801 | status = CAIRO_INT_STATUS_SUCCESS; |
802 | } |
803 | } else |
804 | source->has_matrix = 1; |
805 | if (status == CAIRO_INT_STATUS_SUCCESS) |
806 | XRenderSetPictureTransform_void_consume (dpy, src->picture, &xtransform); |
807 | |
808 | if (source->filter != pattern->base.filter) { |
809 | picture_set_filter (dpy, src->picture, pattern->base.filter); |
810 | source->filter = pattern->base.filter; |
811 | } |
812 | |
813 | if (source->has_component_alpha != pattern->base.has_component_alpha) { |
814 | pa.component_alpha = pattern->base.has_component_alpha; |
815 | mask |= CPComponentAlpha(1 << 12); |
816 | source->has_component_alpha = pattern->base.has_component_alpha; |
817 | } |
818 | |
819 | if (source->extend != pattern->base.extend) { |
820 | pa.repeat = extend_to_repeat (pattern->base.extend); |
821 | mask |= CPRepeat(1 << 0); |
822 | source->extend = pattern->base.extend; |
823 | } |
824 | |
825 | if (mask) |
826 | XRenderChangePicture_void_consume (dpy, src->picture, mask, &pa); |
827 | |
828 | return &src->base; |
829 | } |
830 | |
831 | static cairo_surface_t * |
832 | native_source (cairo_xlib_surface_t *dst, |
833 | const cairo_surface_pattern_t *pattern, |
834 | cairo_bool_t is_mask, |
835 | const cairo_rectangle_int_t *extents, |
836 | const cairo_rectangle_int_t *sample, |
837 | int *src_x, int *src_y) |
838 | { |
839 | cairo_xlib_surface_t *src; |
840 | cairo_int_status_t status; |
841 | |
842 | if (_cairo_surface_is_subsurface (pattern->surface)) |
843 | return subsurface_source (dst, pattern, is_mask, |
844 | extents, sample, |
845 | src_x, src_y); |
846 | |
847 | src = unwrap_source (pattern); |
848 | status = _cairo_surface_flush (&src->base, 0); |
849 | if (unlikely (status)(__builtin_expect (!!(status), 0))) |
850 | return _cairo_surface_create_in_error (status); |
851 | |
852 | if (pattern->base.filter == CAIRO_FILTER_NEAREST && |
853 | sample->x >= 0 && sample->y >= 0 && |
854 | sample->x + sample->width <= src->width && |
855 | sample->y + sample->height <= src->height && |
856 | _cairo_matrix_is_translation (&pattern->base.matrix)) |
857 | { |
858 | *src_x += pattern->base.matrix.x0; |
859 | *src_y += pattern->base.matrix.y0; |
860 | _cairo_xlib_surface_ensure_picture (src); |
861 | return cairo_surface_reference_moz_cairo_surface_reference (&src->base); |
862 | } |
863 | |
864 | return embedded_source (dst, pattern, extents, src_x, src_y, |
865 | init_source (dst, src)); |
866 | } |
867 | |
868 | static cairo_surface_t * |
869 | recording_pattern_get_surface (const cairo_pattern_t *pattern) |
870 | { |
871 | cairo_surface_t *surface; |
872 | |
873 | surface = ((const cairo_surface_pattern_t *) pattern)->surface; |
874 | |
875 | if (_cairo_surface_is_paginated (surface)) |
876 | return cairo_surface_reference_moz_cairo_surface_reference (_cairo_paginated_surface_get_recording (surface)); |
877 | |
878 | if (_cairo_surface_is_snapshot (surface)) |
879 | return _cairo_surface_snapshot_get_target (surface); |
880 | |
881 | return cairo_surface_reference_moz_cairo_surface_reference (surface); |
882 | } |
883 | |
884 | static cairo_surface_t * |
885 | record_source (cairo_xlib_surface_t *dst, |
886 | const cairo_surface_pattern_t *pattern, |
887 | cairo_bool_t is_mask, |
888 | const cairo_rectangle_int_t *extents, |
889 | const cairo_rectangle_int_t *sample, |
890 | int *src_x, int *src_y) |
891 | { |
892 | cairo_xlib_surface_t *src; |
893 | cairo_surface_t *recording; |
894 | cairo_matrix_t matrix, m; |
895 | cairo_status_t status; |
896 | cairo_rectangle_int_t upload, limit; |
897 | |
898 | upload = *sample; |
899 | if (_cairo_surface_get_extents (pattern->surface, &limit) && |
900 | ! _cairo_rectangle_intersect (&upload, &limit)) |
901 | { |
902 | if (pattern->base.extend == CAIRO_EXTEND_NONE) |
903 | return alpha_source (dst, 0); |
904 | |
905 | upload = limit; |
906 | } |
907 | |
908 | src = (cairo_xlib_surface_t *) |
909 | _cairo_surface_create_scratch (&dst->base, |
910 | pattern->surface->content, |
911 | upload.width, |
912 | upload.height, |
913 | NULL((void*)0)); |
914 | if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) { |
915 | cairo_surface_destroy_moz_cairo_surface_destroy (&src->base); |
916 | return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); |
917 | } |
918 | |
919 | cairo_matrix_init_translate_moz_cairo_matrix_init_translate (&matrix, upload.x, upload.y); |
920 | recording = recording_pattern_get_surface (&pattern->base), |
921 | status = _cairo_recording_surface_replay_with_clip (recording, |
922 | &matrix, &src->base, |
923 | NULL((void*)0)); |
924 | cairo_surface_destroy_moz_cairo_surface_destroy (recording); |
925 | if (unlikely (status)(__builtin_expect (!!(status), 0))) { |
926 | cairo_surface_destroy_moz_cairo_surface_destroy (&src->base); |
927 | return _cairo_surface_create_in_error (status); |
928 | } |
929 | |
930 | matrix = pattern->base.matrix; |
931 | if (upload.x | upload.y) { |
932 | cairo_matrix_init_translate_moz_cairo_matrix_init_translate (&m, -upload.x, -upload.y); |
933 | cairo_matrix_multiply_moz_cairo_matrix_multiply (&matrix, &matrix, &m); |
934 | } |
935 | |
936 | _cairo_xlib_surface_ensure_picture (src); |
937 | if (! picture_set_properties (src->display, src->picture, |
938 | &pattern->base, &matrix, extents, |
939 | src_x, src_y)) |
940 | { |
941 | cairo_surface_destroy_moz_cairo_surface_destroy (&src->base); |
942 | return render_pattern (dst, &pattern->base, is_mask, |
943 | extents, src_x, src_y); |
944 | } |
945 | |
946 | return &src->base; |
947 | } |
948 | |
949 | static cairo_surface_t * |
950 | surface_source (cairo_xlib_surface_t *dst, |
951 | const cairo_surface_pattern_t *pattern, |
952 | cairo_bool_t is_mask, |
953 | const cairo_rectangle_int_t *extents, |
954 | const cairo_rectangle_int_t *sample, |
955 | int *src_x, int *src_y) |
956 | { |
957 | cairo_surface_t *src; |
958 | cairo_xlib_surface_t *xsrc; |
959 | cairo_surface_pattern_t local_pattern; |
960 | cairo_status_t status; |
961 | cairo_rectangle_int_t upload, limit; |
962 | |
963 | src = pattern->surface; |
964 | if (src->type == CAIRO_SURFACE_TYPE_IMAGE && |
965 | src->device == dst->base.device && |
966 | _cairo_xlib_shm_surface_get_pixmap (src)) { |
967 | cairo_xlib_proxy_t *proxy; |
968 | |
969 | proxy = _cairo_malloc (sizeof(*proxy))((sizeof(*proxy)) != 0 ? malloc(sizeof(*proxy)) : ((void*)0)); |
970 | if (unlikely (proxy == NULL)(__builtin_expect (!!(proxy == ((void*)0)), 0))) |
971 | return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); |
972 | |
973 | _cairo_surface_init (&proxy->source.base, |
974 | &cairo_xlib_proxy_backend, |
975 | dst->base.device, |
976 | src->content, |
977 | src->is_vector); |
978 | |
979 | proxy->source.dpy = dst->display->display; |
980 | proxy->source.picture = XRenderCreatePicture_int_consume (proxy->source.dpy, |
981 | _cairo_xlib_shm_surface_get_pixmap (src), |
982 | _cairo_xlib_shm_surface_get_xrender_format (src), |
983 | 0, NULL((void*)0)); |
984 | proxy->source.pixmap = None0L; |
985 | |
986 | proxy->source.has_component_alpha = 0; |
987 | proxy->source.has_matrix = 0; |
988 | proxy->source.filter = CAIRO_FILTER_NEAREST; |
989 | proxy->source.extend = CAIRO_EXTEND_NONE; |
990 | proxy->owner = cairo_surface_reference_moz_cairo_surface_reference (src); |
991 | |
992 | return embedded_source (dst, pattern, extents, src_x, src_y, |
993 | &proxy->source); |
994 | } |
995 | |
996 | upload = *sample; |
997 | if (_cairo_surface_get_extents (pattern->surface, &limit)) { |
998 | if (pattern->base.extend == CAIRO_EXTEND_NONE) { |
999 | if (! _cairo_rectangle_intersect (&upload, &limit)) |
1000 | return alpha_source (dst, 0); |
1001 | } else if (pattern->base.extend == CAIRO_EXTEND_PAD) { |
1002 | if (! _cairo_rectangle_intersect (&upload, &limit)) |
1003 | upload = limit; |
1004 | } else { |
1005 | if (upload.x < limit.x || |
1006 | upload.x + upload.width > limit.x + limit.width || |
1007 | upload.y < limit.y || |
1008 | upload.y + upload.height > limit.y + limit.height) |
1009 | { |
1010 | upload = limit; |
1011 | } |
1012 | } |
1013 | } |
1014 | |
1015 | xsrc = (cairo_xlib_surface_t *) |
1016 | _cairo_surface_create_scratch (&dst->base, |
1017 | src->content, |
1018 | upload.width, |
1019 | upload.height, |
1020 | NULL((void*)0)); |
1021 | if (xsrc->base.type != CAIRO_SURFACE_TYPE_XLIB) { |
1022 | cairo_surface_destroy_moz_cairo_surface_destroy (src); |
1023 | cairo_surface_destroy_moz_cairo_surface_destroy (&xsrc->base); |
1024 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
1025 | } |
1026 | |
1027 | if (_cairo_surface_is_image (src)) { |
1028 | status = _cairo_xlib_surface_draw_image (xsrc, (cairo_image_surface_t *)src, |
Value stored to 'status' is never read | |
1029 | upload.x, upload.y, |
1030 | upload.width, upload.height, |
1031 | 0, 0); |
1032 | } else { |
1033 | cairo_image_surface_t *image; |
1034 | cairo_rectangle_int_t map_extents = { 0,0, upload.width,upload.height }; |
1035 | |
1036 | image = _cairo_surface_map_to_image (&xsrc->base, &map_extents); |
1037 | |
1038 | _cairo_pattern_init_for_surface (&local_pattern, pattern->surface); |
1039 | cairo_matrix_init_translate_moz_cairo_matrix_init_translate (&local_pattern.base.matrix, |
1040 | upload.x, upload.y); |
1041 | |
1042 | status = _cairo_surface_paint (&image->base, |
1043 | CAIRO_OPERATOR_SOURCE, |
1044 | &local_pattern.base, |
1045 | NULL((void*)0)); |
1046 | _cairo_pattern_fini (&local_pattern.base); |
1047 | |
1048 | status = _cairo_surface_unmap_image (&xsrc->base, image); |
1049 | if (unlikely (status)(__builtin_expect (!!(status), 0))) { |
1050 | cairo_surface_destroy_moz_cairo_surface_destroy (&xsrc->base); |
1051 | return _cairo_surface_create_in_error (status); |
1052 | } |
1053 | |
1054 | status = _cairo_xlib_surface_put_shm (xsrc); |
1055 | if (unlikely (status)(__builtin_expect (!!(status), 0))) { |
1056 | cairo_surface_destroy_moz_cairo_surface_destroy (&xsrc->base); |
1057 | return _cairo_surface_create_in_error (status); |
1058 | } |
1059 | } |
1060 | |
1061 | _cairo_pattern_init_static_copy (&local_pattern.base, &pattern->base); |
1062 | if (upload.x | upload.y) { |
1063 | cairo_matrix_t m; |
1064 | cairo_matrix_init_translate_moz_cairo_matrix_init_translate (&m, -upload.x, -upload.y); |
1065 | cairo_matrix_multiply_moz_cairo_matrix_multiply (&local_pattern.base.matrix, |
1066 | &local_pattern.base.matrix, |
1067 | &m); |
1068 | } |
1069 | |
1070 | *src_x = *src_y = 0; |
1071 | _cairo_xlib_surface_ensure_picture (xsrc); |
1072 | if (! picture_set_properties (xsrc->display, |
1073 | xsrc->picture, |
1074 | &local_pattern.base, |
1075 | &local_pattern.base.matrix, |
1076 | extents, |
1077 | src_x, src_y)) |
1078 | { |
1079 | cairo_surface_destroy_moz_cairo_surface_destroy (&xsrc->base); |
1080 | return render_pattern (dst, &pattern->base, |
1081 | is_mask, extents, |
1082 | src_x, src_y); |
1083 | } |
1084 | |
1085 | return &xsrc->base; |
1086 | } |
1087 | |
1088 | static cairo_bool_t |
1089 | pattern_is_supported (cairo_xlib_display_t *display, |
1090 | const cairo_pattern_t *pattern) |
1091 | { |
1092 | if (pattern->type == CAIRO_PATTERN_TYPE_MESH) |
1093 | return FALSE0; |
1094 | |
1095 | if (display->buggy_pad_reflect) { |
1096 | if (pattern->extend == CAIRO_EXTEND_REPEAT || pattern->extend == CAIRO_EXTEND_PAD) |
1097 | return FALSE0; |
1098 | } |
1099 | |
1100 | if (display->buggy_gradients) { |
1101 | if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR || pattern->type == CAIRO_PATTERN_TYPE_RADIAL) |
1102 | return FALSE0; |
1103 | } |
1104 | |
1105 | switch (pattern->filter) { |
1106 | case CAIRO_FILTER_FAST: |
1107 | case CAIRO_FILTER_NEAREST: |
1108 | return CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display)((((display))->render_major > 0) || ((((display))->render_major == 0) && (((display))->render_minor >= 6))) || |
1109 | _cairo_matrix_is_integer_translation (&pattern->matrix, NULL((void*)0), NULL((void*)0)); |
1110 | case CAIRO_FILTER_GOOD: |
1111 | return CAIRO_RENDER_HAS_FILTER_GOOD (display)0; |
1112 | case CAIRO_FILTER_BEST: |
1113 | return CAIRO_RENDER_HAS_FILTER_BEST (display)0; |
1114 | case CAIRO_FILTER_BILINEAR: |
1115 | case CAIRO_FILTER_GAUSSIAN: |
1116 | default: |
1117 | return CAIRO_RENDER_HAS_FILTERS (display)((((display))->render_major > 0) || ((((display))->render_major == 0) && (((display))->render_minor >= 6))); |
1118 | } |
1119 | } |
1120 | |
1121 | cairo_surface_t * |
1122 | _cairo_xlib_source_create_for_pattern (cairo_surface_t *_dst, |
1123 | const cairo_pattern_t *pattern, |
1124 | cairo_bool_t is_mask, |
1125 | const cairo_rectangle_int_t *extents, |
1126 | const cairo_rectangle_int_t *sample, |
1127 | int *src_x, int *src_y) |
1128 | { |
1129 | cairo_xlib_surface_t *dst = (cairo_xlib_surface_t *)_dst; |
1130 | |
1131 | *src_x = *src_y = 0; |
1132 | |
1133 | if (pattern == NULL((void*)0) || pattern->type == CAIRO_PATTERN_TYPE_SOLID) { |
1134 | if (pattern == NULL((void*)0)) |
1135 | pattern = &_cairo_pattern_white.base; |
1136 | |
1137 | return solid_source (dst, &((cairo_solid_pattern_t *)pattern)->color); |
1138 | } |
1139 | |
1140 | if (pattern_is_supported (dst->display, pattern)) { |
1141 | if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { |
1142 | cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t *)pattern; |
1143 | if (spattern->surface->type == CAIRO_SURFACE_TYPE_XLIB && |
1144 | _cairo_xlib_surface_same_screen (dst, |
1145 | unwrap_source (spattern))) |
1146 | return native_source (dst, spattern, is_mask, |
1147 | extents, sample, |
1148 | src_x, src_y); |
1149 | |
1150 | if (spattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) |
1151 | return record_source (dst, spattern, is_mask, |
1152 | extents, sample, |
1153 | src_x, src_y); |
1154 | |
1155 | return surface_source (dst, spattern, is_mask, |
1156 | extents, sample, |
1157 | src_x, src_y); |
1158 | } |
1159 | |
1160 | if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR || |
1161 | pattern->type == CAIRO_PATTERN_TYPE_RADIAL) |
1162 | { |
1163 | cairo_gradient_pattern_t *gpattern = (cairo_gradient_pattern_t *)pattern; |
1164 | return gradient_source (dst, gpattern, is_mask, extents, src_x, src_y); |
1165 | } |
1166 | } |
1167 | |
1168 | return render_pattern (dst, pattern, is_mask, extents, src_x, src_y); |
1169 | } |
1170 | |
1171 | #endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ |