📄 pixman-transformed.c
字号:
/* * * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * 2005 Lars Knoll & Zack Rusin, Trolltech * * 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 Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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 "pixman-private.h"#ifdef PIXMAN_FB_ACCESSORS#define FETCH_PROC_FOR_PICTURE pixman_fetchProcForPicture_accessors#define FETCH_PIXEL_PROC_FOR_PICTURE pixman_fetchPixelProcForPicture_accessors#define STORE_PROC_FOR_PICTURE pixman_storeProcForPicture_accessors#define FB_FETCH_TRANSFORMED fbFetchTransformed_accessors#define FB_FETCH_EXTERNAL_ALPHA fbFetchExternalAlpha_accessors#define FB_STORE_EXTERNAL_ALPHA fbStoreExternalAlpha_accessors#else#define FETCH_PROC_FOR_PICTURE pixman_fetchProcForPicture#define FETCH_PIXEL_PROC_FOR_PICTURE pixman_fetchPixelProcForPicture#define STORE_PROC_FOR_PICTURE pixman_storeProcForPicture#define FB_FETCH_TRANSFORMED fbFetchTransformed#define FB_FETCH_EXTERNAL_ALPHA fbFetchExternalAlpha#define FB_STORE_EXTERNAL_ALPHA fbStoreExternalAlpha#endif/* * Fetch from region strategies */typedef FASTCALL uint32_t (*fetchFromRegionProc)(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc fetch, pixman_box16_t *box);static inline uint32_tfbFetchFromNoRegion(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc fetch, pixman_box16_t *box){ return fetch (pict, x, y);}static uint32_tfbFetchFromNRectangles(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc fetch, pixman_box16_t *box){ pixman_box16_t box2; if (pixman_region_contains_point (pict->common.src_clip, x, y, &box2)) return fbFetchFromNoRegion(pict, x, y, buffer, fetch, box); else return 0;}static uint32_tfbFetchFromOneRectangle(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc fetch, pixman_box16_t *box){ pixman_box16_t box2 = *box; return ((x < box2.x1) | (x >= box2.x2) | (y < box2.y1) | (y >= box2.y2)) ? 0 : fbFetchFromNoRegion(pict, x, y, buffer, fetch, box);}/* * Fetching Algorithms */static voidfbFetchTransformed_Nearest_Normal(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit){ pixman_box16_t* box = NULL; fetchPixelProc fetch; fetchFromRegionProc fetchFromRegion; int x, y, i; /* initialize the two function pointers */ fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict); if(pixman_region_n_rects (pict->common.src_clip) == 1) fetchFromRegion = fbFetchFromNoRegion; else fetchFromRegion = fbFetchFromNRectangles; for ( i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { if (!v.vector[2]) { *(buffer + i) = 0; } else { if (!affine) { y = MOD(DIV(v.vector[1],v.vector[2]), pict->height); x = MOD(DIV(v.vector[0],v.vector[2]), pict->width); } else { y = MOD(v.vector[1]>>16, pict->height); x = MOD(v.vector[0]>>16, pict->width); } *(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box); } } v.vector[0] += unit.vector[0]; v.vector[1] += unit.vector[1]; v.vector[2] += unit.vector[2]; }}static voidfbFetchTransformed_Nearest_Pad(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit){ pixman_box16_t *box = NULL; fetchPixelProc fetch; fetchFromRegionProc fetchFromRegion; int x, y, i; /* initialize the two function pointers */ fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict); if(pixman_region_n_rects (pict->common.src_clip) == 1) fetchFromRegion = fbFetchFromNoRegion; else fetchFromRegion = fbFetchFromNRectangles; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { if (!v.vector[2]) { *(buffer + i) = 0; } else { if (!affine) { y = CLIP(DIV(v.vector[1], v.vector[2]), 0, pict->height-1); x = CLIP(DIV(v.vector[0], v.vector[2]), 0, pict->width-1); } else { y = CLIP(v.vector[1]>>16, 0, pict->height-1); x = CLIP(v.vector[0]>>16, 0, pict->width-1); } *(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box); } } v.vector[0] += unit.vector[0]; v.vector[1] += unit.vector[1]; v.vector[2] += unit.vector[2]; }}static voidfbFetchTransformed_Nearest_General(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit){ pixman_box16_t *box = NULL; fetchPixelProc fetch; fetchFromRegionProc fetchFromRegion; int x, y, i; /* initialize the two function pointers */ fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict); if(pixman_region_n_rects (pict->common.src_clip) == 1) { box = &(pict->common.src_clip->extents); fetchFromRegion = fbFetchFromOneRectangle; } else { fetchFromRegion = fbFetchFromNRectangles; } for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { if (!v.vector[2]) { *(buffer + i) = 0; } else { if (!affine) { y = DIV(v.vector[1],v.vector[2]); x = DIV(v.vector[0],v.vector[2]); } else { y = v.vector[1]>>16; x = v.vector[0]>>16; } *(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box); } } v.vector[0] += unit.vector[0]; v.vector[1] += unit.vector[1]; v.vector[2] += unit.vector[2]; }}static voidfbFetchTransformed_Bilinear_Normal(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit){ pixman_box16_t *box = NULL; fetchPixelProc fetch; fetchFromRegionProc fetchFromRegion; int i; /* initialize the two function pointers */ fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict); if(pixman_region_n_rects (pict->common.src_clip) == 1) fetchFromRegion = fbFetchFromNoRegion; else fetchFromRegion = fbFetchFromNRectangles; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { if (!v.vector[2]) { *(buffer + i) = 0; } else { int x1, x2, y1, y2, distx, idistx, disty, idisty; uint32_t tl, tr, bl, br, r; uint32_t ft, fb; if (!affine) { pixman_fixed_48_16_t div; div = ((pixman_fixed_48_16_t)v.vector[0] << 16)/v.vector[2]; x1 = div >> 16; distx = ((pixman_fixed_t)div >> 8) & 0xff; div = ((pixman_fixed_48_16_t)v.vector[1] << 16)/v.vector[2]; y1 = div >> 16; disty = ((pixman_fixed_t)div >> 8) & 0xff; } else { x1 = v.vector[0] >> 16; distx = (v.vector[0] >> 8) & 0xff; y1 = v.vector[1] >> 16; disty = (v.vector[1] >> 8) & 0xff; } x2 = x1 + 1; y2 = y1 + 1; idistx = 256 - distx; idisty = 256 - disty; x1 = MOD (x1, pict->width); x2 = MOD (x2, pict->width); y1 = MOD (y1, pict->height); y2 = MOD (y2, pict->height); tl = fetchFromRegion(pict, x1, y1, buffer, fetch, box); tr = fetchFromRegion(pict, x2, y1, buffer, fetch, box); bl = fetchFromRegion(pict, x1, y2, buffer, fetch, box); br = fetchFromRegion(pict, x2, y2, buffer, fetch, box); ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx; r = (((ft * idisty + fb * disty) >> 16) & 0xff); ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx; fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx; r |= (((ft * idisty + fb * disty) >> 8) & 0xff00); ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx; fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx; r |= (((ft * idisty + fb * disty)) & 0xff0000); ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx; fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx; r |= (((ft * idisty + fb * disty) << 8) & 0xff000000); *(buffer + i) = r; } } v.vector[0] += unit.vector[0]; v.vector[1] += unit.vector[1]; v.vector[2] += unit.vector[2]; }}static voidfbFetchTransformed_Bilinear_Pad(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit){ pixman_box16_t *box = NULL; fetchPixelProc fetch; fetchFromRegionProc fetchFromRegion; int i; /* initialize the two function pointers */ fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict); if(pixman_region_n_rects (pict->common.src_clip) == 1) fetchFromRegion = fbFetchFromNoRegion; else fetchFromRegion = fbFetchFromNRectangles; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { if (!v.vector[2]) { *(buffer + i) = 0; } else { int x1, x2, y1, y2, distx, idistx, disty, idisty; uint32_t tl, tr, bl, br, r; uint32_t ft, fb; if (!affine) { pixman_fixed_48_16_t div; div = ((pixman_fixed_48_16_t)v.vector[0] << 16)/v.vector[2]; x1 = div >> 16; distx = ((pixman_fixed_t)div >> 8) & 0xff; div = ((pixman_fixed_48_16_t)v.vector[1] << 16)/v.vector[2]; y1 = div >> 16; disty = ((pixman_fixed_t)div >> 8) & 0xff; } else { x1 = v.vector[0] >> 16; distx = (v.vector[0] >> 8) & 0xff; y1 = v.vector[1] >> 16; disty = (v.vector[1] >> 8) & 0xff; } x2 = x1 + 1; y2 = y1 + 1; idistx = 256 - distx; idisty = 256 - disty; x1 = CLIP (x1, 0, pict->width-1); x2 = CLIP (x2, 0, pict->width-1); y1 = CLIP (y1, 0, pict->height-1); y2 = CLIP (y2, 0, pict->height-1); tl = fetchFromRegion(pict, x1, y1, buffer, fetch, box); tr = fetchFromRegion(pict, x2, y1, buffer, fetch, box); bl = fetchFromRegion(pict, x1, y2, buffer, fetch, box); br = fetchFromRegion(pict, x2, y2, buffer, fetch, box); ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx; r = (((ft * idisty + fb * disty) >> 16) & 0xff); ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx; fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx; r |= (((ft * idisty + fb * disty) >> 8) & 0xff00); ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx; fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx; r |= (((ft * idisty + fb * disty)) & 0xff0000);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -