📄 pixman-image.c
字号:
/* * Copyright © 2000 SuSE, Inc. * Copyright © 2007 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of SuSE not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. SuSE makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#include "pixman-private.h"static voidinit_source_image (source_image_t *image){ image->class = SOURCE_IMAGE_CLASS_UNKNOWN;}static pixman_bool_tinit_gradient (gradient_t *gradient, const pixman_gradient_stop_t *stops, int n_stops){ return_val_if_fail (n_stops > 0, FALSE); init_source_image (&gradient->common); gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t)); if (!gradient->stops) return FALSE; memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t)); gradient->n_stops = n_stops; gradient->stop_range = 0xffff; gradient->color_table = NULL; gradient->color_table_size = 0; return TRUE;}static uint32_tcolor_to_uint32 (const pixman_color_t *color){ return (color->alpha >> 8 << 24) | (color->red >> 8 << 16) | (color->green & 0xff00) | (color->blue >> 8);}static pixman_image_t *allocate_image (void){ pixman_image_t *image = malloc (sizeof (pixman_image_t)); if (image) { image_common_t *common = &image->common; pixman_region_init (&common->full_region); pixman_region_init (&common->clip_region); common->src_clip = &common->full_region; common->has_client_clip = 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->read_func = NULL; common->write_func = NULL; } return image;}/* Ref Counting */pixman_image_t *pixman_image_ref (pixman_image_t *image){ image->common.ref_count++; return image;}/* returns TRUE when the image is freed */pixman_bool_tpixman_image_unref (pixman_image_t *image){ image_common_t *common = (image_common_t *)image; common->ref_count--; if (common->ref_count == 0) { pixman_region_fini (&common->clip_region); pixman_region_fini (&common->full_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 0 if (image->type == BITS && image->bits.indexed) free (image->bits.indexed);#endif#if 0 memset (image, 0xaa, sizeof (pixman_image_t));#endif 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; } return FALSE;}/* Constructors */pixman_image_t *pixman_image_create_solid_fill (pixman_color_t *color){ pixman_image_t *img = allocate_image(); if (!img) return NULL; init_source_image (&img->solid.common); img->type = SOLID; img->solid.color = color_to_uint32 (color); return img;}pixman_image_t *pixman_image_create_linear_gradient (pixman_point_fixed_t *p1, pixman_point_fixed_t *p2, const pixman_gradient_stop_t *stops, int n_stops){ pixman_image_t *image; linear_gradient_t *linear; return_val_if_fail (n_stops >= 2, NULL); image = allocate_image(); if (!image) return NULL; linear = &image->linear; if (!init_gradient (&linear->common, stops, n_stops)) { free (image); return NULL; } linear->p1 = *p1; linear->p2 = *p2; image->type = LINEAR; return image;}pixman_image_t *pixman_image_create_radial_gradient (pixman_point_fixed_t *inner, pixman_point_fixed_t *outer, pixman_fixed_t inner_radius, pixman_fixed_t outer_radius, const pixman_gradient_stop_t *stops, int n_stops){ pixman_image_t *image; radial_gradient_t *radial; return_val_if_fail (n_stops >= 2, NULL); image = allocate_image(); if (!image) return NULL; radial = &image->radial; if (!init_gradient (&radial->common, stops, n_stops)) { free (image); return NULL; } image->type = RADIAL; radial->c1.x = inner->x; radial->c1.y = inner->y; radial->c1.radius = inner_radius; radial->c2.x = outer->x; radial->c2.y = outer->y; radial->c2.radius = outer_radius; radial->cdx = pixman_fixed_to_double (radial->c2.x - radial->c1.x); radial->cdy = pixman_fixed_to_double (radial->c2.y - radial->c1.y); radial->dr = pixman_fixed_to_double (radial->c2.radius - radial->c1.radius); radial->A = (radial->cdx * radial->cdx + radial->cdy * radial->cdy - radial->dr * radial->dr); return image;}pixman_image_t *pixman_image_create_conical_gradient (pixman_point_fixed_t *center, pixman_fixed_t angle, const pixman_gradient_stop_t *stops, int n_stops){ pixman_image_t *image = allocate_image(); conical_gradient_t *conical; if (!image) return NULL; conical = &image->conical; if (!init_gradient (&conical->common, stops, n_stops)) { free (image); return NULL; } image->type = CONICAL; conical->center = *center; conical->angle = angle; return image;}static uint32_t *create_bits (pixman_format_code_t format, int width, int height, int *rowstride_bytes){ int stride; int buf_size; int bpp; /* what follows is a long-winded way, avoiding any possibility of integer * overflows, of saying: * stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (uint32_t); */ bpp = PIXMAN_FORMAT_BPP (format); if (pixman_multiply_overflows_int (width, bpp)) return NULL; stride = width * bpp; if (pixman_addition_overflows_int (stride, FB_MASK)) return NULL; stride += FB_MASK; stride >>= FB_SHIFT;#if FB_SHIFT < 2 if (pixman_multiply_overflows_int (stride, sizeof (uint32_t))) return NULL;#endif stride *= sizeof (uint32_t); if (pixman_multiply_overflows_int (height, stride)) return NULL; buf_size = height * stride; if (rowstride_bytes) *rowstride_bytes = stride; return calloc (buf_size, 1);}static voidreset_clip_region (pixman_image_t *image){ pixman_region_fini (&image->common.clip_region); if (image->type == BITS) { pixman_region_init_rect (&image->common.clip_region, 0, 0, image->bits.width, image->bits.height); } else { pixman_region_init (&image->common.clip_region); }}pixman_image_t *pixman_image_create_bits (pixman_format_code_t format, int width, int height, uint32_t *bits, int rowstride_bytes){ pixman_image_t *image; uint32_t *free_me = NULL; /* must be a whole number of uint32_t's */ return_val_if_fail (bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL); if (!bits && width && height) { free_me = bits = create_bits (format, width, height, &rowstride_bytes); if (!bits) return NULL; } image = allocate_image();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -