X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=pixman%2Fpixman-image.c;h=8599a1eb100047ffb3d2f49274e345da89138f9f;hb=17acc7a4c707db4804b6bf47db30883745049fdb;hp=e66ae88268c7d9ada641a0029b5724bb9a65e10f;hpb=ac44db334066f68a837914a52d8d1368c85161ad;p=profile%2Fivi%2Fpixman.git diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index e66ae88..8599a1e 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -30,7 +30,50 @@ #include #include "pixman-private.h" -#include "pixman-combine32.h" + +static const pixman_color_t transparent_black = { 0, 0, 0, 0 }; + +static void +gradient_property_changed (pixman_image_t *image) +{ + gradient_t *gradient = &image->gradient; + int n = gradient->n_stops; + pixman_gradient_stop_t *stops = gradient->stops; + pixman_gradient_stop_t *begin = &(gradient->stops[-1]); + pixman_gradient_stop_t *end = &(gradient->stops[n]); + + switch (gradient->common.repeat) + { + default: + case PIXMAN_REPEAT_NONE: + begin->x = INT32_MIN; + begin->color = transparent_black; + end->x = INT32_MAX; + end->color = transparent_black; + break; + + case PIXMAN_REPEAT_NORMAL: + begin->x = stops[n - 1].x - pixman_fixed_1; + begin->color = stops[n - 1].color; + end->x = stops[0].x + pixman_fixed_1; + end->color = stops[0].color; + break; + + case PIXMAN_REPEAT_REFLECT: + begin->x = - stops[0].x; + begin->color = stops[0].color; + end->x = pixman_int_to_fixed (2) - stops[n - 1].x; + end->color = stops[n - 1].color; + break; + + case PIXMAN_REPEAT_PAD: + begin->x = INT32_MIN; + begin->color = stops[0].color; + end->x = INT32_MAX; + end->color = stops[n - 1].color; + break; + } +} pixman_bool_t _pixman_init_gradient (gradient_t * gradient, @@ -39,128 +82,111 @@ _pixman_init_gradient (gradient_t * gradient, { return_val_if_fail (n_stops > 0, FALSE); - gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t)); + /* We allocate two extra stops, one before the beginning of the stop list, + * and one after the end. These stops are initialized to whatever color + * would be used for positions outside the range of the stop list. + * + * This saves a bit of computation in the gradient walker. + * + * The pointer we store in the gradient_t struct still points to the + * first user-supplied struct, so when freeing, we will have to + * subtract one. + */ + gradient->stops = + pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t)); if (!gradient->stops) return FALSE; + gradient->stops += 1; memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t)); - gradient->n_stops = n_stops; - gradient->stop_range = 0xffff; - gradient->common.class = SOURCE_IMAGE_CLASS_UNKNOWN; + gradient->common.property_changed = gradient_property_changed; return TRUE; } -/* - * By default, just evaluate the image at 32bpp and expand. Individual image - * types can plug in a better scanline getter if they want to. For example - * we could produce smoother gradients by evaluating them at higher color - * depth, but that's a project for the future. - */ void -_pixman_image_get_scanline_generic_64 (pixman_image_t * image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t * mask, - uint32_t mask_bits) -{ - uint32_t *mask8 = NULL; - - /* Contract the mask image, if one exists, so that the 32-bit fetch - * function can use it. - */ - if (mask) - { - mask8 = pixman_malloc_ab (width, sizeof(uint32_t)); - if (!mask8) - return; +_pixman_image_init (pixman_image_t *image) +{ + image_common_t *common = &image->common; + + pixman_region32_init (&common->clip_region); + + common->alpha_count = 0; + common->have_clip_region = FALSE; + common->clip_sources = FALSE; + common->transform = NULL; + common->repeat = PIXMAN_REPEAT_NONE; + common->filter = PIXMAN_FILTER_NEAREST; + common->filter_params = NULL; + common->n_filter_params = 0; + common->alpha_map = NULL; + common->component_alpha = FALSE; + common->ref_count = 1; + common->property_changed = NULL; + common->client_clip = FALSE; + common->destroy_func = NULL; + common->destroy_data = NULL; + common->dirty = TRUE; +} - pixman_contract (mask8, (uint64_t *)mask, width); - } +pixman_bool_t +_pixman_image_fini (pixman_image_t *image) +{ + image_common_t *common = (image_common_t *)image; - /* Fetch the source image into the first half of buffer. */ - _pixman_image_get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8, - mask_bits); + common->ref_count--; - /* Expand from 32bpp to 64bpp in place. */ - pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width); + if (common->ref_count == 0) + { + if (image->common.destroy_func) + image->common.destroy_func (image, image->common.destroy_data); - free (mask8); -} + pixman_region32_fini (&common->clip_region); -pixman_image_t * -_pixman_image_allocate (void) -{ - pixman_image_t *image = malloc (sizeof (pixman_image_t)); + free (common->transform); + free (common->filter_params); - if (image) - { - image_common_t *common = &image->common; + if (common->alpha_map) + pixman_image_unref ((pixman_image_t *)common->alpha_map); - pixman_region32_init (&common->clip_region); + if (image->type == LINEAR || + image->type == RADIAL || + image->type == CONICAL) + { + if (image->gradient.stops) + { + /* See _pixman_init_gradient() for an explanation of the - 1 */ + free (image->gradient.stops - 1); + } - common->have_clip_region = FALSE; - common->clip_sources = FALSE; - common->transform = NULL; - common->repeat = PIXMAN_REPEAT_NONE; - common->filter = PIXMAN_FILTER_NEAREST; - common->filter_params = NULL; - common->n_filter_params = 0; - common->alpha_map = NULL; - common->component_alpha = FALSE; - common->ref_count = 1; - common->classify = NULL; - common->client_clip = FALSE; - common->destroy_func = NULL; - common->destroy_data = NULL; - common->dirty = TRUE; + /* This will trigger if someone adds a property_changed + * method to the linear/radial/conical gradient overwriting + * the general one. + */ + assert ( + image->common.property_changed == gradient_property_changed); + } + + if (image->type == BITS && image->bits.free_me) + free (image->bits.free_me); + + return TRUE; } - return image; + return FALSE; } -source_image_class_t -_pixman_image_classify (pixman_image_t *image, - int x, - int y, - int width, - int height) +pixman_image_t * +_pixman_image_allocate (void) { - if (image->common.classify) - return image->common.classify (image, x, y, width, height); - else - return SOURCE_IMAGE_CLASS_UNKNOWN; -} + pixman_image_t *image = malloc (sizeof (pixman_image_t)); -void -_pixman_image_get_scanline_32 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask, - uint32_t mask_bits) -{ - image->common.get_scanline_32 (image, x, y, width, buffer, mask, mask_bits); -} + if (image) + _pixman_image_init (image); -/* Even thought the type of buffer is uint32_t *, the function actually expects - * a uint64_t *buffer. - */ -void -_pixman_image_get_scanline_64 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *unused, - uint32_t unused2) -{ - image->common.get_scanline_64 (image, x, y, width, buffer, unused, unused2); + return image; } static void @@ -182,39 +208,9 @@ pixman_image_ref (pixman_image_t *image) PIXMAN_EXPORT pixman_bool_t pixman_image_unref (pixman_image_t *image) { - image_common_t *common = (image_common_t *)image; - - common->ref_count--; - - if (common->ref_count == 0) + if (_pixman_image_fini (image)) { - if (image->common.destroy_func) - image->common.destroy_func (image, image->common.destroy_data); - - pixman_region32_fini (&common->clip_region); - - if (common->transform) - free (common->transform); - - if (common->filter_params) - free (common->filter_params); - - if (common->alpha_map) - pixman_image_unref ((pixman_image_t *)common->alpha_map); - - if (image->type == LINEAR || - image->type == RADIAL || - image->type == CONICAL) - { - if (image->gradient.stops) - free (image->gradient.stops); - } - - if (image->type == BITS && image->bits.free_me) - free (image->bits.free_me); - free (image); - return TRUE; } @@ -242,53 +238,27 @@ _pixman_image_reset_clip_region (pixman_image_t *image) image->common.have_clip_region = FALSE; } -static pixman_bool_t out_of_bounds_workaround = TRUE; - -/* Old X servers rely on out-of-bounds accesses when they are asked - * to composite with a window as the source. They create a pixman image - * pointing to some bogus position in memory, but then they set a clip - * region to the position where the actual bits are. +/* Executive Summary: This function is a no-op that only exists + * for historical reasons. + * + * There used to be a bug in the X server where it would rely on + * out-of-bounds accesses when it was asked to composite with a + * window as the source. It would create a pixman image pointing + * to some bogus position in memory, but then set a clip region + * to the position where the actual bits were. * * Due to a bug in old versions of pixman, where it would not clip * against the image bounds when a clip region was set, this would - * actually work. So by default we allow certain out-of-bound access - * to happen unless explicitly disabled. + * actually work. So when the pixman bug was fixed, a workaround was + * added to allow certain out-of-bound accesses. This function disabled + * those workarounds. * - * Fixed X servers should call this function to disable the workaround. + * Since 0.21.2, pixman doesn't do these workarounds anymore, so now + * this function is a no-op. */ PIXMAN_EXPORT void pixman_disable_out_of_bounds_workaround (void) { - out_of_bounds_workaround = FALSE; -} - -static pixman_bool_t -source_image_needs_out_of_bounds_workaround (bits_image_t *image) -{ - if (image->common.clip_sources && - image->common.repeat == PIXMAN_REPEAT_NONE && - image->common.have_clip_region && - out_of_bounds_workaround) - { - if (!image->common.client_clip) - { - /* There is no client clip, so if the clip region extends beyond the - * drawable geometry, it must be because the X server generated the - * bogus clip region. - */ - const pixman_box32_t *extents = pixman_region32_extents (&image->common.clip_region); - - if (extents->x1 >= 0 && extents->x2 <= image->width && - extents->y1 >= 0 && extents->y2 <= image->height) - { - return FALSE; - } - } - - return TRUE; - } - - return FALSE; } static void @@ -297,61 +267,168 @@ compute_image_info (pixman_image_t *image) pixman_format_code_t code; uint32_t flags = 0; + /* Transform */ if (!image->common.transform) { - flags |= FAST_PATH_ID_TRANSFORM; + flags |= (FAST_PATH_ID_TRANSFORM | + FAST_PATH_X_UNIT_POSITIVE | + FAST_PATH_Y_UNIT_ZERO | + FAST_PATH_AFFINE_TRANSFORM); } - else if (image->common.transform && - image->common.transform->matrix[0][1] == 0 && - image->common.transform->matrix[1][0] == 0 && - image->common.transform->matrix[2][0] == 0 && - image->common.transform->matrix[2][1] == 0 && - image->common.transform->matrix[2][2] == pixman_fixed_1) + else { - flags |= FAST_PATH_SCALE_TRANSFORM; - } + flags |= FAST_PATH_HAS_TRANSFORM; - if (!image->common.alpha_map) - flags |= FAST_PATH_NO_ALPHA_MAP; + if (image->common.transform->matrix[2][0] == 0 && + image->common.transform->matrix[2][1] == 0 && + image->common.transform->matrix[2][2] == pixman_fixed_1) + { + flags |= FAST_PATH_AFFINE_TRANSFORM; - if (image->common.filter != PIXMAN_FILTER_CONVOLUTION) - { - flags |= FAST_PATH_NO_CONVOLUTION_FILTER; + if (image->common.transform->matrix[0][1] == 0 && + image->common.transform->matrix[1][0] == 0) + { + if (image->common.transform->matrix[0][0] == -pixman_fixed_1 && + image->common.transform->matrix[1][1] == -pixman_fixed_1) + { + flags |= FAST_PATH_ROTATE_180_TRANSFORM; + } + flags |= FAST_PATH_SCALE_TRANSFORM; + } + else if (image->common.transform->matrix[0][0] == 0 && + image->common.transform->matrix[1][1] == 0) + { + pixman_fixed_t m01 = image->common.transform->matrix[0][1]; + pixman_fixed_t m10 = image->common.transform->matrix[1][0]; - if (image->common.filter == PIXMAN_FILTER_NEAREST) - flags |= FAST_PATH_NEAREST_FILTER; - } + if (m01 == -1 && m10 == 1) + flags |= FAST_PATH_ROTATE_90_TRANSFORM; + else if (m01 == 1 && m10 == -1) + flags |= FAST_PATH_ROTATE_270_TRANSFORM; + } + } - if (image->common.repeat != PIXMAN_REPEAT_PAD) - flags |= FAST_PATH_NO_PAD_REPEAT; + if (image->common.transform->matrix[0][0] > 0) + flags |= FAST_PATH_X_UNIT_POSITIVE; - if (image->common.repeat != PIXMAN_REPEAT_REFLECT) - flags |= FAST_PATH_NO_REFLECT_REPEAT; + if (image->common.transform->matrix[1][0] == 0) + flags |= FAST_PATH_Y_UNIT_ZERO; + } - flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NO_WIDE_FORMAT); - if (image->common.type == BITS) + /* Filter */ + switch (image->common.filter) { - if (image->bits.read_func || image->bits.write_func) - flags &= ~FAST_PATH_NO_ACCESSORS; + case PIXMAN_FILTER_NEAREST: + case PIXMAN_FILTER_FAST: + flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); + break; + + case PIXMAN_FILTER_BILINEAR: + case PIXMAN_FILTER_GOOD: + case PIXMAN_FILTER_BEST: + flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); + + /* Here we have a chance to optimize BILINEAR filter to NEAREST if + * they are equivalent for the currently used transformation matrix. + */ + if (flags & FAST_PATH_ID_TRANSFORM) + { + flags |= FAST_PATH_NEAREST_FILTER; + } + else if ( + /* affine and integer translation components in matrix ... */ + ((flags & FAST_PATH_AFFINE_TRANSFORM) && + !pixman_fixed_frac (image->common.transform->matrix[0][2] | + image->common.transform->matrix[1][2])) && + ( + /* ... combined with a simple rotation */ + (flags & (FAST_PATH_ROTATE_90_TRANSFORM | + FAST_PATH_ROTATE_180_TRANSFORM | + FAST_PATH_ROTATE_270_TRANSFORM)) || + /* ... or combined with a simple non-rotated translation */ + (image->common.transform->matrix[0][0] == pixman_fixed_1 && + image->common.transform->matrix[1][1] == pixman_fixed_1 && + image->common.transform->matrix[0][1] == 0 && + image->common.transform->matrix[1][0] == 0) + ) + ) + { + /* FIXME: there are some affine-test failures, showing that + * handling of BILINEAR and NEAREST filter is not quite + * equivalent when getting close to 32K for the translation + * components of the matrix. That's likely some bug, but for + * now just skip BILINEAR->NEAREST optimization in this case. + */ + pixman_fixed_t magic_limit = pixman_int_to_fixed (30000); + if (image->common.transform->matrix[0][2] <= magic_limit && + image->common.transform->matrix[1][2] <= magic_limit && + image->common.transform->matrix[0][2] >= -magic_limit && + image->common.transform->matrix[1][2] >= -magic_limit) + { + flags |= FAST_PATH_NEAREST_FILTER; + } + } + break; - if (PIXMAN_FORMAT_IS_WIDE (image->bits.format)) - flags &= ~FAST_PATH_NO_WIDE_FORMAT; + case PIXMAN_FILTER_CONVOLUTION: + break; + + default: + flags |= FAST_PATH_NO_CONVOLUTION_FILTER; + break; } + /* Repeat mode */ + switch (image->common.repeat) + { + case PIXMAN_REPEAT_NONE: + flags |= + FAST_PATH_NO_REFLECT_REPEAT | + FAST_PATH_NO_PAD_REPEAT | + FAST_PATH_NO_NORMAL_REPEAT; + break; + + case PIXMAN_REPEAT_REFLECT: + flags |= + FAST_PATH_NO_PAD_REPEAT | + FAST_PATH_NO_NONE_REPEAT | + FAST_PATH_NO_NORMAL_REPEAT; + break; + + case PIXMAN_REPEAT_PAD: + flags |= + FAST_PATH_NO_REFLECT_REPEAT | + FAST_PATH_NO_NONE_REPEAT | + FAST_PATH_NO_NORMAL_REPEAT; + break; + + default: + flags |= + FAST_PATH_NO_REFLECT_REPEAT | + FAST_PATH_NO_PAD_REPEAT | + FAST_PATH_NO_NONE_REPEAT; + break; + } + + /* Component alpha */ if (image->common.component_alpha) flags |= FAST_PATH_COMPONENT_ALPHA; else flags |= FAST_PATH_UNIFIED_ALPHA; - if (image->type == SOLID) + flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT); + + /* Type specific checks */ + switch (image->type) { + case SOLID: code = PIXMAN_solid; if (image->solid.color.alpha == 0xffff) flags |= FAST_PATH_IS_OPAQUE; - } - else if (image->common.type == BITS) - { + break; + + case BITS: if (image->bits.width == 1 && image->bits.height == 1 && image->common.repeat != PIXMAN_REPEAT_NONE) @@ -361,45 +438,75 @@ compute_image_info (pixman_image_t *image) else { code = image->bits.format; - - if (!image->common.transform && - image->common.repeat == PIXMAN_REPEAT_NORMAL) - { - flags |= FAST_PATH_SIMPLE_REPEAT; - } + flags |= FAST_PATH_BITS_IMAGE; } - if (image->common.repeat != PIXMAN_REPEAT_NONE && - !PIXMAN_FORMAT_A (image->bits.format)) + if (!PIXMAN_FORMAT_A (image->bits.format) && + PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY && + PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR) { - flags |= FAST_PATH_IS_OPAQUE; + flags |= FAST_PATH_SAMPLES_OPAQUE; + + if (image->common.repeat != PIXMAN_REPEAT_NONE) + flags |= FAST_PATH_IS_OPAQUE; } - if (source_image_needs_out_of_bounds_workaround (&image->bits)) - flags |= FAST_PATH_NEEDS_WORKAROUND; - } - else - { + if (image->bits.read_func || image->bits.write_func) + flags &= ~FAST_PATH_NO_ACCESSORS; + + if (PIXMAN_FORMAT_IS_WIDE (image->bits.format)) + flags &= ~FAST_PATH_NARROW_FORMAT; + break; + + case RADIAL: code = PIXMAN_unknown; - if (image->type == LINEAR || image->type == RADIAL) - { - if (image->common.repeat != PIXMAN_REPEAT_NONE) - { - int i; + /* + * As explained in pixman-radial-gradient.c, every point of + * the plane has a valid associated radius (and thus will be + * colored) if and only if a is negative (i.e. one of the two + * circles contains the other one). + */ - flags |= FAST_PATH_IS_OPAQUE; + if (image->radial.a >= 0) + break; + + /* Fall through */ + + case CONICAL: + case LINEAR: + code = PIXMAN_unknown; + + if (image->common.repeat != PIXMAN_REPEAT_NONE) + { + int i; - for (i = 0; i < image->gradient.n_stops; ++i) + flags |= FAST_PATH_IS_OPAQUE; + for (i = 0; i < image->gradient.n_stops; ++i) + { + if (image->gradient.stops[i].color.alpha != 0xffff) { - if (image->gradient.stops[i].color.alpha != 0xffff) - { - flags &= ~FAST_PATH_IS_OPAQUE; - break; - } + flags &= ~FAST_PATH_IS_OPAQUE; + break; } } } + break; + + default: + code = PIXMAN_unknown; + break; + } + + /* Alpha map */ + if (!image->common.alpha_map) + { + flags |= FAST_PATH_NO_ALPHA_MAP; + } + else + { + if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format)) + flags &= ~FAST_PATH_NARROW_FORMAT; } /* Both alpha maps and convolution filters can introduce @@ -412,7 +519,7 @@ compute_image_info (pixman_image_t *image) image->common.filter == PIXMAN_FILTER_CONVOLUTION || image->common.component_alpha) { - flags &= ~FAST_PATH_IS_OPAQUE; + flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE); } image->common.flags = flags; @@ -431,7 +538,8 @@ _pixman_image_validate (pixman_image_t *image) * property_changed() can make use of the flags * to set up accessors etc. */ - image->common.property_changed (image); + if (image->common.property_changed) + image->common.property_changed (image); image->common.dirty = FALSE; } @@ -512,7 +620,7 @@ pixman_image_set_transform (pixman_image_t * image, if (common->transform == transform) return TRUE; - if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0) + if (!transform || memcmp (&id, transform, sizeof (pixman_transform_t)) == 0) { free (common->transform); common->transform = NULL; @@ -521,6 +629,12 @@ pixman_image_set_transform (pixman_image_t * image, goto out; } + if (common->transform && + memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0) + { + return TRUE; + } + if (common->transform == NULL) common->transform = malloc (sizeof (pixman_transform_t)); @@ -545,6 +659,9 @@ PIXMAN_EXPORT void pixman_image_set_repeat (pixman_image_t *image, pixman_repeat_t repeat) { + if (image->common.repeat == repeat) + return; + image->common.repeat = repeat; image_property_changed (image); @@ -589,6 +706,9 @@ PIXMAN_EXPORT void pixman_image_set_source_clipping (pixman_image_t *image, pixman_bool_t clip_sources) { + if (image->common.clip_sources == clip_sources) + return; + image->common.clip_sources = clip_sources; image_property_changed (image); @@ -604,6 +724,9 @@ pixman_image_set_indexed (pixman_image_t * image, { bits_image_t *bits = (bits_image_t *)image; + if (bits->indexed == indexed) + return; + bits->indexed = indexed; image_property_changed (image); @@ -619,15 +742,41 @@ pixman_image_set_alpha_map (pixman_image_t *image, return_if_fail (!alpha_map || alpha_map->type == BITS); + if (alpha_map && common->alpha_count > 0) + { + /* If this image is being used as an alpha map itself, + * then you can't give it an alpha map of its own. + */ + return; + } + + if (alpha_map && alpha_map->common.alpha_map) + { + /* If the image has an alpha map of its own, + * then it can't be used as an alpha map itself + */ + return; + } + if (common->alpha_map != (bits_image_t *)alpha_map) { if (common->alpha_map) + { + common->alpha_map->common.alpha_count--; + pixman_image_unref ((pixman_image_t *)common->alpha_map); + } if (alpha_map) + { common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map); + + common->alpha_map->common.alpha_count++; + } else + { common->alpha_map = NULL; + } } common->alpha_origin_x = x; @@ -640,11 +789,20 @@ PIXMAN_EXPORT void pixman_image_set_component_alpha (pixman_image_t *image, pixman_bool_t component_alpha) { + if (image->common.component_alpha == component_alpha) + return; + image->common.component_alpha = component_alpha; image_property_changed (image); } +PIXMAN_EXPORT pixman_bool_t +pixman_image_get_component_alpha (pixman_image_t *image) +{ + return image->common.component_alpha; +} + PIXMAN_EXPORT void pixman_image_set_accessors (pixman_image_t * image, pixman_read_memory_func_t read_func, @@ -706,13 +864,28 @@ pixman_image_get_depth (pixman_image_t *image) return 0; } +PIXMAN_EXPORT pixman_format_code_t +pixman_image_get_format (pixman_image_t *image) +{ + if (image->type == BITS) + return image->bits.format; + + return 0; +} + uint32_t -_pixman_image_get_solid (pixman_image_t * image, - pixman_format_code_t format) +_pixman_image_get_solid (pixman_implementation_t *imp, + pixman_image_t * image, + pixman_format_code_t format) { uint32_t result; + pixman_iter_t iter; + + _pixman_implementation_src_iter_init ( + imp, &iter, image, 0, 0, 1, 1, + (uint8_t *)&result, ITER_NARROW); - _pixman_image_get_scanline_32 (image, 0, 0, 1, &result, NULL, 0); + result = *iter.get_scanline (&iter, NULL); /* If necessary, convert RGB <--> BGR. */ if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)