Rev 1891 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1891 | Rev 3931 | ||
---|---|---|---|
Line 28... | Line 28... | ||
28 | #include |
28 | #include |
29 | #include |
29 | #include |
30 | #include |
30 | #include |
Line 31... | Line 31... | ||
31 | 31 | ||
- | 32 | #include "pixman-private.h" |
|
- | 33 | ||
- | 34 | static const pixman_color_t transparent_black = { 0, 0, 0, 0 }; |
|
- | 35 | ||
- | 36 | static void |
|
- | 37 | gradient_property_changed (pixman_image_t *image) |
|
- | 38 | { |
|
- | 39 | gradient_t *gradient = &image->gradient; |
|
- | 40 | int n = gradient->n_stops; |
|
- | 41 | pixman_gradient_stop_t *stops = gradient->stops; |
|
- | 42 | pixman_gradient_stop_t *begin = &(gradient->stops[-1]); |
|
- | 43 | pixman_gradient_stop_t *end = &(gradient->stops[n]); |
|
32 | #include "pixman-private.h" |
44 | |
- | 45 | switch (gradient->common.repeat) |
|
- | 46 | { |
|
- | 47 | default: |
|
- | 48 | case PIXMAN_REPEAT_NONE: |
|
- | 49 | begin->x = INT32_MIN; |
|
- | 50 | begin->color = transparent_black; |
|
- | 51 | end->x = INT32_MAX; |
|
- | 52 | end->color = transparent_black; |
|
- | 53 | break; |
|
- | 54 | ||
- | 55 | case PIXMAN_REPEAT_NORMAL: |
|
- | 56 | begin->x = stops[n - 1].x - pixman_fixed_1; |
|
- | 57 | begin->color = stops[n - 1].color; |
|
- | 58 | end->x = stops[0].x + pixman_fixed_1; |
|
- | 59 | end->color = stops[0].color; |
|
- | 60 | break; |
|
- | 61 | ||
- | 62 | case PIXMAN_REPEAT_REFLECT: |
|
- | 63 | begin->x = - stops[0].x; |
|
- | 64 | begin->color = stops[0].color; |
|
- | 65 | end->x = pixman_int_to_fixed (2) - stops[n - 1].x; |
|
- | 66 | end->color = stops[n - 1].color; |
|
- | 67 | break; |
|
- | 68 | ||
- | 69 | case PIXMAN_REPEAT_PAD: |
|
- | 70 | begin->x = INT32_MIN; |
|
- | 71 | begin->color = stops[0].color; |
|
- | 72 | end->x = INT32_MAX; |
|
- | 73 | end->color = stops[n - 1].color; |
|
- | 74 | break; |
|
- | 75 | } |
|
Line 33... | Line 76... | ||
33 | #include "pixman-combine32.h" |
76 | } |
34 | 77 | ||
35 | pixman_bool_t |
78 | pixman_bool_t |
36 | _pixman_init_gradient (gradient_t * gradient, |
79 | _pixman_init_gradient (gradient_t * gradient, |
37 | const pixman_gradient_stop_t *stops, |
80 | const pixman_gradient_stop_t *stops, |
38 | int n_stops) |
81 | int n_stops) |
Line -... | Line 82... | ||
- | 82 | { |
|
- | 83 | return_val_if_fail (n_stops > 0, FALSE); |
|
- | 84 | ||
- | 85 | /* We allocate two extra stops, one before the beginning of the stop list, |
|
- | 86 | * and one after the end. These stops are initialized to whatever color |
|
- | 87 | * would be used for positions outside the range of the stop list. |
|
- | 88 | * |
|
- | 89 | * This saves a bit of computation in the gradient walker. |
|
- | 90 | * |
|
- | 91 | * The pointer we store in the gradient_t struct still points to the |
|
- | 92 | * first user-supplied struct, so when freeing, we will have to |
|
39 | { |
93 | * subtract one. |
40 | return_val_if_fail (n_stops > 0, FALSE); |
94 | */ |
41 | 95 | gradient->stops = |
|
Line -... | Line 96... | ||
- | 96 | pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t)); |
|
42 | gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t)); |
97 | if (!gradient->stops) |
43 | if (!gradient->stops) |
- | |
44 | return FALSE; |
98 | return FALSE; |
Line 45... | Line 99... | ||
45 | 99 | ||
Line 46... | Line 100... | ||
46 | memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t)); |
100 | gradient->stops += 1; |
47 | 101 | memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t)); |
|
Line 48... | Line -... | ||
48 | gradient->n_stops = n_stops; |
- | |
49 | - | ||
50 | gradient->stop_range = 0xffff; |
- | |
51 | - | ||
52 | return TRUE; |
- | |
53 | } |
- | |
54 | 102 | gradient->n_stops = n_stops; |
|
55 | /* |
103 | |
56 | * By default, just evaluate the image at 32bpp and expand. Individual image |
- | |
57 | * types can plug in a better scanline getter if they want to. For example |
- | |
58 | * we could produce smoother gradients by evaluating them at higher color |
- | |
59 | * depth, but that's a project for the future. |
- | |
60 | */ |
- | |
61 | void |
- | |
62 | _pixman_image_get_scanline_generic_64 (pixman_image_t * image, |
- | |
63 | int x, |
- | |
64 | int y, |
- | |
65 | int width, |
- | |
66 | uint32_t * buffer, |
- | |
67 | const uint32_t * mask) |
- | |
68 | { |
- | |
69 | uint32_t *mask8 = NULL; |
- | |
70 | - | ||
71 | /* Contract the mask image, if one exists, so that the 32-bit fetch |
- | |
72 | * function can use it. |
- | |
73 | */ |
- | |
74 | if (mask) |
- | |
75 | { |
- | |
76 | mask8 = pixman_malloc_ab (width, sizeof(uint32_t)); |
- | |
77 | if (!mask8) |
- | |
78 | return; |
- | |
79 | - | ||
80 | pixman_contract (mask8, (uint64_t *)mask, width); |
- | |
81 | } |
- | |
82 | - | ||
83 | /* Fetch the source image into the first half of buffer. */ |
- | |
84 | _pixman_image_get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8); |
- | |
85 | - | ||
86 | /* Expand from 32bpp to 64bpp in place. */ |
- | |
87 | pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width); |
- | |
88 | - | ||
89 | free (mask8); |
- | |
90 | } |
- | |
91 | 104 | gradient->common.property_changed = gradient_property_changed; |
|
92 | pixman_image_t * |
105 | |
Line 93... | Line 106... | ||
93 | _pixman_image_allocate (void) |
106 | return TRUE; |
Line 109... | Line 122... | ||
109 | common->filter_params = NULL; |
122 | common->filter_params = NULL; |
110 | common->n_filter_params = 0; |
123 | common->n_filter_params = 0; |
111 | common->alpha_map = NULL; |
124 | common->alpha_map = NULL; |
112 | common->component_alpha = FALSE; |
125 | common->component_alpha = FALSE; |
113 | common->ref_count = 1; |
126 | common->ref_count = 1; |
114 | common->classify = NULL; |
127 | common->property_changed = NULL; |
115 | common->client_clip = FALSE; |
128 | common->client_clip = FALSE; |
116 | common->destroy_func = NULL; |
129 | common->destroy_func = NULL; |
117 | common->destroy_data = NULL; |
130 | common->destroy_data = NULL; |
118 | common->dirty = TRUE; |
131 | common->dirty = TRUE; |
119 | } |
132 | } |
Line 120... | Line 133... | ||
120 | 133 | ||
- | 134 | pixman_bool_t |
|
121 | return image; |
135 | _pixman_image_fini (pixman_image_t *image) |
- | 136 | { |
|
- | 137 | image_common_t *common = (image_common_t *)image; |
|
- | 138 | ||
Line 122... | Line -... | ||
122 | } |
- | |
123 | - | ||
124 | source_image_class_t |
- | |
125 | _pixman_image_classify (pixman_image_t *image, |
139 | common->ref_count--; |
126 | int x, |
- | |
127 | int y, |
- | |
128 | int width, |
140 | |
129 | int height) |
141 | if (common->ref_count == 0) |
130 | { |
142 | { |
131 | if (image->common.classify) |
- | |
132 | return image->common.classify (image, x, y, width, height); |
- | |
133 | else |
- | |
Line -... | Line 143... | ||
- | 143 | if (image->common.destroy_func) |
|
134 | return SOURCE_IMAGE_CLASS_UNKNOWN; |
144 | image->common.destroy_func (image, image->common.destroy_data); |
- | 145 | ||
135 | } |
146 | pixman_region32_fini (&common->clip_region); |
- | 147 | ||
- | 148 | free (common->transform); |
|
136 | 149 | free (common->filter_params); |
|
- | 150 | ||
137 | void |
151 | if (common->alpha_map) |
138 | _pixman_image_get_scanline_32 (pixman_image_t *image, |
152 | pixman_image_unref ((pixman_image_t *)common->alpha_map); |
139 | int x, |
153 | |
- | 154 | if (image->type == LINEAR || |
|
140 | int y, |
155 | image->type == RADIAL || |
141 | int width, |
156 | image->type == CONICAL) |
142 | uint32_t * buffer, |
157 | { |
- | 158 | if (image->gradient.stops) |
|
143 | const uint32_t *mask) |
159 | { |
Line -... | Line 160... | ||
- | 160 | /* See _pixman_init_gradient() for an explanation of the - 1 */ |
|
144 | { |
161 | free (image->gradient.stops - 1); |
145 | image->common.get_scanline_32 (image, x, y, width, buffer, mask); |
162 | } |
146 | } |
163 | |
147 | 164 | /* This will trigger if someone adds a property_changed |
|
148 | /* Even thought the type of buffer is uint32_t *, the function actually expects |
165 | * method to the linear/radial/conical gradient overwriting |
- | 166 | * the general one. |
|
- | 167 | */ |
|
149 | * a uint64_t *buffer. |
168 | assert ( |
150 | */ |
169 | image->common.property_changed == gradient_property_changed); |
- | 170 | } |
|
- | 171 | ||
- | 172 | if (image->type == BITS && image->bits.free_me) |
|
- | 173 | free (image->bits.free_me); |
|
151 | void |
174 | |
- | 175 | return TRUE; |
|
- | 176 | } |
|
152 | _pixman_image_get_scanline_64 (pixman_image_t *image, |
177 | |
153 | int x, |
178 | return FALSE; |
154 | int y, |
179 | } |
155 | int width, |
180 | |
- | 181 | pixman_image_t * |
|
- | 182 | _pixman_image_allocate (void) |
|
- | 183 | { |
|
- | 184 | pixman_image_t *image = malloc (sizeof (pixman_image_t)); |
|
- | 185 | ||
156 | uint32_t * buffer, |
186 | if (image) |
Line 157... | Line 187... | ||
157 | const uint32_t *unused) |
187 | _pixman_image_init (image); |
158 | { |
188 | |
159 | image->common.get_scanline_64 (image, x, y, width, buffer, unused); |
189 | return image; |
Line 176... | Line 206... | ||
176 | 206 | ||
177 | /* returns TRUE when the image is freed */ |
207 | /* returns TRUE when the image is freed */ |
178 | PIXMAN_EXPORT pixman_bool_t |
208 | PIXMAN_EXPORT pixman_bool_t |
179 | pixman_image_unref (pixman_image_t *image) |
209 | pixman_image_unref (pixman_image_t *image) |
180 | { |
- | |
181 | image_common_t *common = (image_common_t *)image; |
- | |
182 | - | ||
183 | common->ref_count--; |
- | |
184 | 210 | { |
|
185 | if (common->ref_count == 0) |
- | |
186 | { |
- | |
187 | if (image->common.destroy_func) |
- | |
188 | image->common.destroy_func (image, image->common.destroy_data); |
- | |
189 | - | ||
190 | pixman_region32_fini (&common->clip_region); |
- | |
191 | - | ||
192 | if (common->transform) |
- | |
193 | free (common->transform); |
- | |
194 | - | ||
195 | if (common->filter_params) |
- | |
196 | free (common->filter_params); |
- | |
197 | - | ||
198 | if (common->alpha_map) |
- | |
199 | pixman_image_unref ((pixman_image_t *)common->alpha_map); |
- | |
200 | - | ||
201 | if (image->type == LINEAR || |
- | |
202 | image->type == RADIAL || |
- | |
203 | image->type == CONICAL) |
211 | if (_pixman_image_fini (image)) |
204 | { |
- | |
205 | if (image->gradient.stops) |
- | |
206 | free (image->gradient.stops); |
- | |
207 | } |
- | |
208 | - | ||
209 | if (image->type == BITS && image->bits.free_me) |
- | |
210 | free (image->bits.free_me); |
- | |
211 | 212 | { |
|
212 | free (image); |
- | |
213 | 213 | free (image); |
|
214 | return TRUE; |
214 | return TRUE; |
Line 215... | Line 215... | ||
215 | } |
215 | } |
216 | 216 | ||
Line 236... | Line 236... | ||
236 | _pixman_image_reset_clip_region (pixman_image_t *image) |
236 | _pixman_image_reset_clip_region (pixman_image_t *image) |
237 | { |
237 | { |
238 | image->common.have_clip_region = FALSE; |
238 | image->common.have_clip_region = FALSE; |
239 | } |
239 | } |
Line 240... | Line 240... | ||
240 | 240 | ||
- | 241 | /* Executive Summary: This function is a no-op that only exists |
|
241 | static pixman_bool_t out_of_bounds_workaround = TRUE; |
242 | * for historical reasons. |
- | 243 | * |
|
242 | 244 | * There used to be a bug in the X server where it would rely on |
|
243 | /* Old X servers rely on out-of-bounds accesses when they are asked |
245 | * out-of-bounds accesses when it was asked to composite with a |
244 | * to composite with a window as the source. They create a pixman image |
246 | * window as the source. It would create a pixman image pointing |
245 | * pointing to some bogus position in memory, but then they set a clip |
247 | * to some bogus position in memory, but then set a clip region |
246 | * region to the position where the actual bits are. |
248 | * to the position where the actual bits were. |
247 | * |
249 | * |
248 | * Due to a bug in old versions of pixman, where it would not clip |
250 | * Due to a bug in old versions of pixman, where it would not clip |
249 | * against the image bounds when a clip region was set, this would |
251 | * against the image bounds when a clip region was set, this would |
250 | * actually work. So by default we allow certain out-of-bound access |
252 | * actually work. So when the pixman bug was fixed, a workaround was |
- | 253 | * added to allow certain out-of-bound accesses. This function disabled |
|
251 | * to happen unless explicitly disabled. |
254 | * those workarounds. |
252 | * |
255 | * |
- | 256 | * Since 0.21.2, pixman doesn't do these workarounds anymore, so now |
|
253 | * Fixed X servers should call this function to disable the workaround. |
257 | * this function is a no-op. |
254 | */ |
258 | */ |
255 | PIXMAN_EXPORT void |
259 | PIXMAN_EXPORT void |
256 | pixman_disable_out_of_bounds_workaround (void) |
260 | pixman_disable_out_of_bounds_workaround (void) |
257 | { |
- | |
258 | out_of_bounds_workaround = FALSE; |
- | |
259 | } |
- | |
260 | - | ||
261 | static pixman_bool_t |
- | |
262 | source_image_needs_out_of_bounds_workaround (bits_image_t *image) |
- | |
263 | { |
- | |
264 | if (image->common.clip_sources && |
- | |
265 | image->common.repeat == PIXMAN_REPEAT_NONE && |
- | |
266 | image->common.have_clip_region && |
- | |
267 | out_of_bounds_workaround) |
- | |
268 | { |
- | |
269 | if (!image->common.client_clip) |
- | |
270 | { |
- | |
271 | /* There is no client clip, so if the clip region extends beyond the |
- | |
272 | * drawable geometry, it must be because the X server generated the |
- | |
273 | * bogus clip region. |
- | |
274 | */ |
- | |
275 | const pixman_box32_t *extents = |
- | |
276 | pixman_region32_extents (&image->common.clip_region); |
- | |
277 | - | ||
278 | if (extents->x1 >= 0 && extents->x2 <= image->width && |
- | |
279 | extents->y1 >= 0 && extents->y2 <= image->height) |
- | |
280 | { |
- | |
281 | return FALSE; |
- | |
282 | } |
- | |
283 | } |
- | |
284 | - | ||
285 | return TRUE; |
- | |
286 | } |
- | |
287 | - | ||
288 | return FALSE; |
261 | { |
Line 289... | Line 262... | ||
289 | } |
262 | } |
290 | 263 | ||
291 | static void |
264 | static void |
Line 313... | Line 286... | ||
313 | flags |= FAST_PATH_AFFINE_TRANSFORM; |
286 | flags |= FAST_PATH_AFFINE_TRANSFORM; |
Line 314... | Line 287... | ||
314 | 287 | ||
315 | if (image->common.transform->matrix[0][1] == 0 && |
288 | if (image->common.transform->matrix[0][1] == 0 && |
316 | image->common.transform->matrix[1][0] == 0) |
289 | image->common.transform->matrix[1][0] == 0) |
- | 290 | { |
|
- | 291 | if (image->common.transform->matrix[0][0] == -pixman_fixed_1 && |
|
- | 292 | image->common.transform->matrix[1][1] == -pixman_fixed_1) |
|
- | 293 | { |
|
- | 294 | flags |= FAST_PATH_ROTATE_180_TRANSFORM; |
|
317 | { |
295 | } |
318 | flags |= FAST_PATH_SCALE_TRANSFORM; |
296 | flags |= FAST_PATH_SCALE_TRANSFORM; |
- | 297 | } |
|
- | 298 | else if (image->common.transform->matrix[0][0] == 0 && |
|
- | 299 | image->common.transform->matrix[1][1] == 0) |
|
- | 300 | { |
|
- | 301 | pixman_fixed_t m01 = image->common.transform->matrix[0][1]; |
|
- | 302 | pixman_fixed_t m10 = image->common.transform->matrix[1][0]; |
|
- | 303 | ||
- | 304 | if (m01 == -pixman_fixed_1 && m10 == pixman_fixed_1) |
|
- | 305 | flags |= FAST_PATH_ROTATE_90_TRANSFORM; |
|
- | 306 | else if (m01 == pixman_fixed_1 && m10 == -pixman_fixed_1) |
|
- | 307 | flags |= FAST_PATH_ROTATE_270_TRANSFORM; |
|
319 | } |
308 | } |
Line 320... | Line 309... | ||
320 | } |
309 | } |
321 | 310 | ||
Line 336... | Line 325... | ||
336 | 325 | ||
337 | case PIXMAN_FILTER_BILINEAR: |
326 | case PIXMAN_FILTER_BILINEAR: |
338 | case PIXMAN_FILTER_GOOD: |
327 | case PIXMAN_FILTER_GOOD: |
339 | case PIXMAN_FILTER_BEST: |
328 | case PIXMAN_FILTER_BEST: |
- | 329 | flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); |
|
- | 330 | ||
- | 331 | /* Here we have a chance to optimize BILINEAR filter to NEAREST if |
|
- | 332 | * they are equivalent for the currently used transformation matrix. |
|
- | 333 | */ |
|
- | 334 | if (flags & FAST_PATH_ID_TRANSFORM) |
|
- | 335 | { |
|
- | 336 | flags |= FAST_PATH_NEAREST_FILTER; |
|
- | 337 | } |
|
- | 338 | else if ( |
|
- | 339 | /* affine and integer translation components in matrix ... */ |
|
- | 340 | ((flags & FAST_PATH_AFFINE_TRANSFORM) && |
|
- | 341 | !pixman_fixed_frac (image->common.transform->matrix[0][2] | |
|
- | 342 | image->common.transform->matrix[1][2])) && |
|
- | 343 | ( |
|
- | 344 | /* ... combined with a simple rotation */ |
|
- | 345 | (flags & (FAST_PATH_ROTATE_90_TRANSFORM | |
|
- | 346 | FAST_PATH_ROTATE_180_TRANSFORM | |
|
- | 347 | FAST_PATH_ROTATE_270_TRANSFORM)) || |
|
- | 348 | /* ... or combined with a simple non-rotated translation */ |
|
- | 349 | (image->common.transform->matrix[0][0] == pixman_fixed_1 && |
|
- | 350 | image->common.transform->matrix[1][1] == pixman_fixed_1 && |
|
- | 351 | image->common.transform->matrix[0][1] == 0 && |
|
- | 352 | image->common.transform->matrix[1][0] == 0) |
|
- | 353 | ) |
|
- | 354 | ) |
|
- | 355 | { |
|
- | 356 | /* FIXME: there are some affine-test failures, showing that |
|
- | 357 | * handling of BILINEAR and NEAREST filter is not quite |
|
- | 358 | * equivalent when getting close to 32K for the translation |
|
- | 359 | * components of the matrix. That's likely some bug, but for |
|
- | 360 | * now just skip BILINEAR->NEAREST optimization in this case. |
|
- | 361 | */ |
|
- | 362 | pixman_fixed_t magic_limit = pixman_int_to_fixed (30000); |
|
- | 363 | if (image->common.transform->matrix[0][2] <= magic_limit && |
|
- | 364 | image->common.transform->matrix[1][2] <= magic_limit && |
|
- | 365 | image->common.transform->matrix[0][2] >= -magic_limit && |
|
- | 366 | image->common.transform->matrix[1][2] >= -magic_limit) |
|
- | 367 | { |
|
- | 368 | flags |= FAST_PATH_NEAREST_FILTER; |
|
- | 369 | } |
|
340 | flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); |
370 | } |
Line 341... | Line 371... | ||
341 | break; |
371 | break; |
342 | 372 | ||
Line -... | Line 373... | ||
- | 373 | case PIXMAN_FILTER_CONVOLUTION: |
|
- | 374 | break; |
|
- | 375 | ||
- | 376 | case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: |
|
343 | case PIXMAN_FILTER_CONVOLUTION: |
377 | flags |= FAST_PATH_SEPARABLE_CONVOLUTION_FILTER; |
344 | break; |
378 | break; |
345 | 379 | ||
346 | default: |
380 | default: |
Line 406... | Line 440... | ||
406 | code = PIXMAN_solid; |
440 | code = PIXMAN_solid; |
407 | } |
441 | } |
408 | else |
442 | else |
409 | { |
443 | { |
410 | code = image->bits.format; |
444 | code = image->bits.format; |
- | 445 | flags |= FAST_PATH_BITS_IMAGE; |
|
411 | } |
446 | } |
Line 412... | Line 447... | ||
412 | 447 | ||
413 | if (!PIXMAN_FORMAT_A (image->bits.format) && |
448 | if (!PIXMAN_FORMAT_A (image->bits.format) && |
414 | PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY && |
449 | PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY && |
Line 418... | Line 453... | ||
418 | 453 | ||
419 | if (image->common.repeat != PIXMAN_REPEAT_NONE) |
454 | if (image->common.repeat != PIXMAN_REPEAT_NONE) |
420 | flags |= FAST_PATH_IS_OPAQUE; |
455 | flags |= FAST_PATH_IS_OPAQUE; |
Line 421... | Line -... | ||
421 | } |
- | |
422 | - | ||
423 | if (source_image_needs_out_of_bounds_workaround (&image->bits)) |
- | |
424 | flags |= FAST_PATH_NEEDS_WORKAROUND; |
456 | } |
425 | 457 | ||
Line 426... | Line 458... | ||
426 | if (image->bits.read_func || image->bits.write_func) |
458 | if (image->bits.read_func || image->bits.write_func) |
427 | flags &= ~FAST_PATH_NO_ACCESSORS; |
459 | flags &= ~FAST_PATH_NO_ACCESSORS; |
Line 443... | Line 475... | ||
443 | if (image->radial.a >= 0) |
475 | if (image->radial.a >= 0) |
444 | break; |
476 | break; |
Line 445... | Line 477... | ||
445 | 477 | ||
Line -... | Line 478... | ||
- | 478 | /* Fall through */ |
|
446 | /* Fall through */ |
479 | |
447 | 480 | case CONICAL: |
|
Line 448... | Line 481... | ||
448 | case LINEAR: |
481 | case LINEAR: |
449 | code = PIXMAN_unknown; |
482 | code = PIXMAN_unknown; |
Line 486... | Line 519... | ||
486 | * if all channels are opaque, so we simply turn it off |
519 | * if all channels are opaque, so we simply turn it off |
487 | * unconditionally for those images. |
520 | * unconditionally for those images. |
488 | */ |
521 | */ |
489 | if (image->common.alpha_map || |
522 | if (image->common.alpha_map || |
490 | image->common.filter == PIXMAN_FILTER_CONVOLUTION || |
523 | image->common.filter == PIXMAN_FILTER_CONVOLUTION || |
- | 524 | image->common.filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION || |
|
491 | image->common.component_alpha) |
525 | image->common.component_alpha) |
492 | { |
526 | { |
493 | flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE); |
527 | flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE); |
494 | } |
528 | } |
Line 507... | Line 541... | ||
507 | /* It is important that property_changed is |
541 | /* It is important that property_changed is |
508 | * called *after* compute_image_info() because |
542 | * called *after* compute_image_info() because |
509 | * property_changed() can make use of the flags |
543 | * property_changed() can make use of the flags |
510 | * to set up accessors etc. |
544 | * to set up accessors etc. |
511 | */ |
545 | */ |
- | 546 | if (image->common.property_changed) |
|
512 | image->common.property_changed (image); |
547 | image->common.property_changed (image); |
Line 513... | Line 548... | ||
513 | 548 | ||
514 | image->common.dirty = FALSE; |
549 | image->common.dirty = FALSE; |
Line 588... | Line 623... | ||
588 | pixman_bool_t result; |
623 | pixman_bool_t result; |
Line 589... | Line 624... | ||
589 | 624 | ||
590 | if (common->transform == transform) |
625 | if (common->transform == transform) |
Line 591... | Line 626... | ||
591 | return TRUE; |
626 | return TRUE; |
592 | 627 | ||
593 | if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0) |
628 | if (!transform || memcmp (&id, transform, sizeof (pixman_transform_t)) == 0) |
594 | { |
629 | { |
595 | free (common->transform); |
630 | free (common->transform); |
Line 596... | Line 631... | ||
596 | common->transform = NULL; |
631 | common->transform = NULL; |
597 | result = TRUE; |
632 | result = TRUE; |
Line -... | Line 633... | ||
- | 633 | ||
- | 634 | goto out; |
|
- | 635 | } |
|
- | 636 | ||
- | 637 | if (common->transform && |
|
- | 638 | memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0) |
|
598 | 639 | { |
|
599 | goto out; |
640 | return TRUE; |
Line 600... | Line 641... | ||
600 | } |
641 | } |
601 | 642 | ||
Line 621... | Line 662... | ||
621 | 662 | ||
622 | PIXMAN_EXPORT void |
663 | PIXMAN_EXPORT void |
623 | pixman_image_set_repeat (pixman_image_t *image, |
664 | pixman_image_set_repeat (pixman_image_t *image, |
624 | pixman_repeat_t repeat) |
665 | pixman_repeat_t repeat) |
- | 666 | { |
|
- | 667 | if (image->common.repeat == repeat) |
|
- | 668 | return; |
|
625 | { |
669 | |
Line 626... | Line 670... | ||
626 | image->common.repeat = repeat; |
670 | image->common.repeat = repeat; |
627 | 671 | ||
Line 638... | Line 682... | ||
638 | pixman_fixed_t *new_params; |
682 | pixman_fixed_t *new_params; |
Line 639... | Line 683... | ||
639 | 683 | ||
640 | if (params == common->filter_params && filter == common->filter) |
684 | if (params == common->filter_params && filter == common->filter) |
Line -... | Line 685... | ||
- | 685 | return TRUE; |
|
- | 686 | ||
- | 687 | if (filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION) |
|
- | 688 | { |
|
- | 689 | int width = pixman_fixed_to_int (params[0]); |
|
- | 690 | int height = pixman_fixed_to_int (params[1]); |
|
- | 691 | int x_phase_bits = pixman_fixed_to_int (params[2]); |
|
- | 692 | int y_phase_bits = pixman_fixed_to_int (params[3]); |
|
- | 693 | int n_x_phases = (1 << x_phase_bits); |
|
- | 694 | int n_y_phases = (1 << y_phase_bits); |
|
- | 695 | ||
- | 696 | return_val_if_fail ( |
|
- | 697 | n_params == 4 + n_x_phases * width + n_y_phases * height, FALSE); |
|
641 | return TRUE; |
698 | } |
642 | 699 | ||
643 | new_params = NULL; |
700 | new_params = NULL; |
644 | if (params) |
701 | if (params) |
645 | { |
702 | { |
Line 665... | Line 722... | ||
665 | 722 | ||
666 | PIXMAN_EXPORT void |
723 | PIXMAN_EXPORT void |
667 | pixman_image_set_source_clipping (pixman_image_t *image, |
724 | pixman_image_set_source_clipping (pixman_image_t *image, |
668 | pixman_bool_t clip_sources) |
725 | pixman_bool_t clip_sources) |
- | 726 | { |
|
- | 727 | if (image->common.clip_sources == clip_sources) |
|
- | 728 | return; |
|
669 | { |
729 | |
Line 670... | Line 730... | ||
670 | image->common.clip_sources = clip_sources; |
730 | image->common.clip_sources = clip_sources; |
671 | 731 | ||
Line 680... | Line 740... | ||
680 | pixman_image_set_indexed (pixman_image_t * image, |
740 | pixman_image_set_indexed (pixman_image_t * image, |
681 | const pixman_indexed_t *indexed) |
741 | const pixman_indexed_t *indexed) |
682 | { |
742 | { |
683 | bits_image_t *bits = (bits_image_t *)image; |
743 | bits_image_t *bits = (bits_image_t *)image; |
Line -... | Line 744... | ||
- | 744 | ||
- | 745 | if (bits->indexed == indexed) |
|
- | 746 | return; |
|
684 | 747 | ||
Line 685... | Line 748... | ||
685 | bits->indexed = indexed; |
748 | bits->indexed = indexed; |
686 | 749 | ||
Line 742... | Line 805... | ||
742 | 805 | ||
743 | PIXMAN_EXPORT void |
806 | PIXMAN_EXPORT void |
744 | pixman_image_set_component_alpha (pixman_image_t *image, |
807 | pixman_image_set_component_alpha (pixman_image_t *image, |
745 | pixman_bool_t component_alpha) |
808 | pixman_bool_t component_alpha) |
- | 809 | { |
|
- | 810 | if (image->common.component_alpha == component_alpha) |
|
- | 811 | return; |
|
746 | { |
812 | |
Line 747... | Line 813... | ||
747 | image->common.component_alpha = component_alpha; |
813 | image->common.component_alpha = component_alpha; |
748 | 814 | ||
Line 820... | Line 886... | ||
820 | pixman_image_get_format (pixman_image_t *image) |
886 | pixman_image_get_format (pixman_image_t *image) |
821 | { |
887 | { |
822 | if (image->type == BITS) |
888 | if (image->type == BITS) |
823 | return image->bits.format; |
889 | return image->bits.format; |
Line 824... | Line 890... | ||
824 | 890 | ||
825 | return 0; |
891 | return PIXMAN_null; |
Line 826... | Line 892... | ||
826 | } |
892 | } |
827 | 893 | ||
- | 894 | uint32_t |
|
828 | uint32_t |
895 | _pixman_image_get_solid (pixman_implementation_t *imp, |
829 | _pixman_image_get_solid (pixman_image_t * image, |
896 | pixman_image_t * image, |
830 | pixman_format_code_t format) |
897 | pixman_format_code_t format) |
Line -... | Line 898... | ||
- | 898 | { |
|
- | 899 | uint32_t result; |
|
- | 900 | ||
- | 901 | if (image->type == SOLID) |
|
- | 902 | { |
|
- | 903 | result = image->solid.color_32; |
|
- | 904 | } |
|
- | 905 | else if (image->type == BITS) |
|
- | 906 | { |
|
- | 907 | if (image->bits.format == PIXMAN_a8r8g8b8) |
|
- | 908 | result = image->bits.bits[0]; |
|
- | 909 | else if (image->bits.format == PIXMAN_x8r8g8b8) |
|
- | 910 | result = image->bits.bits[0] | 0xff000000; |
|
- | 911 | else if (image->bits.format == PIXMAN_a8) |
|
- | 912 | result = (*(uint8_t *)image->bits.bits) << 24; |
|
- | 913 | else |
|
- | 914 | goto otherwise; |
|
- | 915 | } |
|
- | 916 | else |
|
- | 917 | { |
|
- | 918 | pixman_iter_t iter; |
|
- | 919 | ||
- | 920 | otherwise: |
|
- | 921 | _pixman_implementation_src_iter_init ( |
|
- | 922 | imp, &iter, image, 0, 0, 1, 1, |
|
831 | { |
923 | (uint8_t *)&result, |
- | 924 | ITER_NARROW, image->common.flags); |
|
Line 832... | Line 925... | ||
832 | uint32_t result; |
925 | |
833 | 926 | result = *iter.get_scanline (&iter, NULL); |
|
- | 927 | } |
|
834 | _pixman_image_get_scanline_32 (image, 0, 0, 1, &result, NULL); |
928 | |
835 | 929 | /* If necessary, convert RGB <--> BGR. */ |
|
836 | /* If necessary, convert RGB <--> BGR. */ |
930 | if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB |
837 | if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB) |
931 | && PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB_SRGB) |
838 | { |
932 | { |