Bug Summary

File:root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-source.c
Warning:line 306, column 5
Value stored to 'status' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cairo-xlib-source.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D HAVE_FT_LOAD_SFNT_TABLE -D PACKAGE_VERSION="moz" -D PACKAGE_BUGREPORT="http://bugzilla.mozilla.org/" -D CAIRO_HAS_PTHREAD -D _GNU_SOURCE -D MOZ_TREE_PIXMAN -D SIZEOF_VOID_P=__SIZEOF_POINTER__ -D SIZEOF_INT=__SIZEOF_INT__ -D SIZEOF_LONG=__SIZEOF_LONG__ -D SIZEOF_LONG_LONG=__SIZEOF_LONG_LONG__ -D HAVE_UINT64_T -D HAVE_CXX11_ATOMIC_PRIMITIVES -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/gfx/cairo/cairo/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/libpng16 -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-enum-compare -Wno-int-to-pointer-cast -Wno-int-conversion -Wno-incompatible-pointer-types -Wno-sign-compare -Wno-type-limits -Wno-missing-field-initializers -Wno-conversion -Wno-narrowing -Wno-switch -Wno-unused -Wno-unused-variable -Wno-error=uninitialized -Wno-absolute-value -Wno-deprecated-register -Wno-incompatible-pointer-types -Wno-macro-redefined -Wno-shift-negative-value -Wno-tautological-compare -Wno-tautological-constant-out-of-range-compare -Wno-unreachable-code -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-26-231904-1820671-1 -x c /root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-source.c
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
61static cairo_xlib_surface_t *
62unwrap_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
68static 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
79static 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
85static 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
98static 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
104static cairo_surface_t *
105source (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
134static uint32_t
135hars_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
143static const XTransform identity = {
144 {
145 { 1 << 16, 0x00000, 0x00000 },
146 { 0x00000, 1 << 16, 0x00000 },
147 { 0x00000, 0x00000, 1 << 16 },
148 }
149};
150
151static cairo_bool_t
152picture_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
188static cairo_status_t
189picture_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
226static int
227extend_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
243static cairo_bool_t
244picture_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
278static cairo_surface_t *
279render_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,
Value stored to 'status' is never read
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
330static cairo_surface_t *
331gradient_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
448static cairo_surface_t *
449color_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
506static cairo_surface_t *
507alpha_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
523static cairo_surface_t *
524white_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
534static cairo_surface_t *
535opaque_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
559done:
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
565static cairo_surface_t *
566transparent_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
592done:
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
599static cairo_surface_t *
600solid_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
615static 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
648static cairo_surface_t *
649embedded_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
702static cairo_surface_t *
703subsurface_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
831static cairo_surface_t *
832native_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
868static cairo_surface_t *
869recording_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
884static cairo_surface_t *
885record_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
949static cairo_surface_t *
950surface_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,
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
1088static cairo_bool_t
1089pattern_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
1121cairo_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 */