📄 icimage.c
字号:
/* * Copyright © 2000 SuSE, 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. * * Author: Keith Packard, SuSE, Inc. */#include "pixman-xserver-compat.h"pixman_image_t *pixman_image_create (pixman_format_t *format, int width, int height){ pixman_image_t *image; FbPixels *pixels; pixels = FbPixelsCreate (width, height, format->depth); if (pixels == NULL) return NULL; image = pixman_image_createForPixels (pixels, format); if (image == NULL) { FbPixelsDestroy (pixels); return NULL; } image->owns_pixels = 1; return image;}slim_hidden_def(pixman_image_create);pixman_image_t *pixman_image_create_for_data (FbBits *data, pixman_format_t *format, int width, int height, int bpp, int stride){ pixman_image_t *image; FbPixels *pixels; pixels = FbPixelsCreateForData (data, width, height, format->depth, bpp, stride); if (pixels == NULL) return NULL; image = pixman_image_createForPixels (pixels, format); if (image == NULL) { FbPixelsDestroy (pixels); return NULL; } image->owns_pixels = 1; return image;}pixman_image_t *pixman_image_createForPixels (FbPixels *pixels, pixman_format_t *format){ pixman_image_t *image; image = malloc (sizeof (pixman_image_t)); if (!image) { return NULL; } image->pixels = pixels; image->image_format = *format; image->format_code = format->format_code;/* XXX: What's all this about? if (pDrawable->type == DRAWABLE_PIXMAP) { ++((PixmapPtr)pDrawable)->refcnt; image->pNext = 0; } else { image->pNext = GetPictureWindow(((WindowPtr) pDrawable)); SetPictureWindow(((WindowPtr) pDrawable), image); }*/ pixman_image_init (image); return image;}static CARD32 xRenderColorToCard32(pixman_color_t c){ return (c.alpha >> 8 << 24) | (c.red >> 8 << 16) | (c.green & 0xff00) | (c.blue >> 8);}static uint32_t premultiply(uint32_t x){ uint32_t a = x >> 24; uint32_t t = (x & 0xff00ff) * a + 0x800080; t = (t + ((t >> 8) & 0xff00ff)) >> 8; t &= 0xff00ff; x = ((x >> 8) & 0xff) * a + 0x80; x = (x + ((x >> 8) & 0xff)); x &= 0xff00; x |= t | (a << 24); return x;}static uint32_t INTERPOLATE_PIXEL_256(uint32_t x, uint32_t a, uint32_t y, uint32_t b){ CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; t >>= 8; t &= 0xff00ff; x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; x &= 0xff00ff00; x |= t; return x;}uint32_tpixman_gradient_color (pixman_gradient_stop_t *stop1, pixman_gradient_stop_t *stop2, uint32_t x){ uint32_t current_color, next_color; int dist, idist; current_color = xRenderColorToCard32 (stop1->color); next_color = xRenderColorToCard32 (stop2->color); dist = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x)); idist = 256 - dist; return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist, next_color, dist));}static int_pixman_init_gradient (pixman_gradient_image_t *gradient, const pixman_gradient_stop_t *stops, int n_stops){ pixman_fixed16_16_t dpos; int i; if (n_stops <= 0) return 1; dpos = -1; for (i = 0; i < n_stops; i++) { if (stops[i].x < dpos || stops[i].x > (1 << 16)) return 1; dpos = stops[i].x; } gradient->class = SourcePictClassUnknown; gradient->stopRange = 0xffff; gradient->colorTable = NULL; gradient->colorTableSize = 0; return 0;}static pixman_image_t *_pixman_create_source_image (void){ pixman_image_t *image; image = (pixman_image_t *) malloc (sizeof (pixman_image_t)); image->pDrawable = 0; image->pixels = 0; image->format_code = PICT_a8r8g8b8; pixman_image_init (image); return image;}pixman_image_t *pixman_image_create_linear_gradient (const pixman_linear_gradient_t *gradient, const pixman_gradient_stop_t *stops, int n_stops){ pixman_linear_gradient_image_t *linear; pixman_image_t *image; if (n_stops < 2) return 0; image = _pixman_create_source_image (); if (!image) return 0; linear = malloc (sizeof (pixman_linear_gradient_image_t) + sizeof (pixman_gradient_stop_t) * n_stops); if (!linear) { free (image); return 0; } linear->stops = (pixman_gradient_stop_t *) (linear + 1); linear->nstops = n_stops; memcpy (linear->stops, stops, sizeof (pixman_gradient_stop_t) * n_stops); linear->type = SourcePictTypeLinear; linear->p1 = gradient->p1; linear->p2 = gradient->p2; image->pSourcePict = (pixman_source_image_t *) linear; if (_pixman_init_gradient (&image->pSourcePict->gradient, stops, n_stops)) { free (image); return 0; } return image;}pixman_image_t *pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient, const pixman_gradient_stop_t *stops, int n_stops){ pixman_radial_gradient_image_t *radial; pixman_image_t *image; double x; if (n_stops < 2) return 0; image = _pixman_create_source_image (); if (!image) return 0; radial = malloc (sizeof (pixman_radial_gradient_image_t) + sizeof (pixman_gradient_stop_t) * n_stops); if (!radial) { free (image); return 0; } radial->stops = (pixman_gradient_stop_t *) (radial + 1); radial->nstops = n_stops; memcpy (radial->stops, stops, sizeof (pixman_gradient_stop_t) * n_stops); radial->type = SourcePictTypeRadial; x = (double) gradient->inner.radius / (double) gradient->outer.radius; radial->dx = (gradient->outer.x - gradient->inner.x); radial->dy = (gradient->outer.y - gradient->inner.y); radial->fx = (gradient->inner.x) - x * radial->dx; radial->fy = (gradient->inner.y) - x * radial->dy; radial->m = 1. / (1 + x); radial->b = -x * radial->m; radial->dx /= 65536.; radial->dy /= 65536.; radial->fx /= 65536.; radial->fy /= 65536.; x = gradient->outer.radius / 65536.; radial->a = x * x - radial->dx * radial->dx - radial->dy * radial->dy; image->pSourcePict = (pixman_source_image_t *) radial; if (_pixman_init_gradient (&image->pSourcePict->gradient, stops, n_stops)) { free (image); return 0; } return image;}voidpixman_image_init (pixman_image_t *image){ image->refcnt = 1; image->repeat = PIXMAN_REPEAT_NONE; image->graphicsExposures = 0; image->subWindowMode = ClipByChildren; image->polyEdge = PolyEdgeSharp; image->polyMode = PolyModePrecise; /* * In the server this was 0 because the composite clip list * can be referenced from a window (and often is) */ image->freeCompClip = 0; image->freeSourceClip = 0; image->clientClipType = CT_NONE; image->componentAlpha = 0; image->compositeClipSource = 0; image->alphaMap = NULL; image->alphaOrigin.x = 0; image->alphaOrigin.y = 0; image->clipOrigin.x = 0; image->clipOrigin.y = 0; image->clientClip = NULL; image->dither = 0L; image->stateChanges = (1 << (CPLastBit+1)) - 1;/* XXX: What to lodge here? image->serialNumber = GC_CHANGE_SERIAL_BIT;*/ if (image->pixels) { image->pCompositeClip = pixman_region_create(); pixman_region_union_rect (image->pCompositeClip, image->pCompositeClip, 0, 0, image->pixels->width, image->pixels->height); image->freeCompClip = 1; image->pSourceClip = pixman_region_create (); pixman_region_union_rect (image->pSourceClip, image->pSourceClip, 0, 0, image->pixels->width, image->pixels->height); image->freeSourceClip = 1; } else { image->pCompositeClip = NULL; image->pSourceClip = NULL; } image->transform = NULL; image->filter = PIXMAN_FILTER_NEAREST; image->filter_params = NULL; image->filter_nparams = 0; image->owns_pixels = 0; image->pSourcePict = NULL;}voidpixman_image_set_component_alpha (pixman_image_t *image, int component_alpha){ if (image) image->componentAlpha = component_alpha;}slim_hidden_def(pixman_image_set_component_alpha);intpixman_image_set_transform (pixman_image_t *image, pixman_transform_t *transform){ static const pixman_transform_t identity = { { { xFixed1, 0x00000, 0x00000 }, { 0x00000, xFixed1, 0x00000 }, { 0x00000, 0x00000, xFixed1 }, } }; if (transform && memcmp (transform, &identity, sizeof (pixman_transform_t)) == 0) transform = NULL; if (transform) { if (!image->transform) { image->transform = malloc (sizeof (pixman_transform_t)); if (!image->transform) return 1; } *image->transform = *transform; } else { if (image->transform) { free (image->transform); image->transform = NULL; } } return 0;}voidpixman_image_set_repeat (pixman_image_t *image, pixman_repeat_t repeat){ if (image) image->repeat = repeat;}slim_hidden_def(pixman_image_set_repeat);voidpixman_image_set_filter (pixman_image_t *image, pixman_filter_t filter){ if (image) image->filter = filter;}intpixman_image_get_width (pixman_image_t *image){ if (image->pixels) return image->pixels->width; return 0;}intpixman_image_get_height (pixman_image_t *image){ if (image->pixels) return image->pixels->height; return 0;}intpixman_image_get_depth (pixman_image_t *image){ if (image->pixels) return image->pixels->depth; return 0;}intpixman_image_get_stride (pixman_image_t *image){ if (image->pixels) return image->pixels->stride; return 0;}pixman_format_t *pixman_image_get_format (pixman_image_t *image){ return &image->image_format;}FbBits *pixman_image_get_data (pixman_image_t *image){ if (image->pixels) return image->pixels->data; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -