Back to index

lightning-sunbird  0.9+nobinonly
fbpict.h
Go to the documentation of this file.
00001 /*
00002  * $Id: fbpict.h,v 1.1.6.3 2005/10/04 03:28:22 vladimir%pobox.com Exp $
00003  *
00004  * Copyright © 2000 Keith Packard
00005  *             2005 Lars Knoll & Zack Rusin, Trolltech
00006  *
00007  * Permission to use, copy, modify, distribute, and sell this software and its
00008  * documentation for any purpose is hereby granted without fee, provided that
00009  * the above copyright notice appear in all copies and that both that
00010  * copyright notice and this permission notice appear in supporting
00011  * documentation, and that the name of Keith Packard not be used in
00012  * advertising or publicity pertaining to distribution of the software without
00013  * specific, written prior permission.  Keith Packard makes no
00014  * representations about the suitability of this software for any purpose.  It
00015  * is provided "as is" without express or implied warranty.
00016  *
00017  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
00018  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
00019  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
00020  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00021  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
00022  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
00023  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00024  * SOFTWARE.
00025  */
00026 
00027 #ifndef _FBPICT_H_
00028 #define _FBPICT_H_
00029 
00030 #include "pixman-xserver-compat.h"
00031 #include "renderedge.h"
00032 
00033 #define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
00034 #define FbIntDiv(a,b)        (((CARD16) (a) * 255) / (b))
00035 
00036 #define FbGet8(v,i)   ((CARD16) (CARD8) ((v) >> i))
00037 
00038 /*
00039  * There are two ways of handling alpha -- either as a single unified value or
00040  * a separate value for each component, hence each macro must have two
00041  * versions.  The unified alpha version has a 'U' at the end of the name,
00042  * the component version has a 'C'.  Similarly, functions which deal with
00043  * this difference will have two versions using the same convention.
00044  */
00045 
00046 #define FbOverU(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),(a),(t)) + FbGet8(x,i),\
00047                         (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
00048 
00049 #define FbOverC(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),FbGet8(a,i),(t)) + FbGet8(x,i),\
00050                          (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
00051 
00052 #define FbInU(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),(a),(t)) << (i))
00053 
00054 #define FbInC(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),FbGet8(a,i),(t)) << (i))
00055 
00056 #define FbGen(x,y,i,ax,ay,t,u,v) ((t) = (FbIntMult(FbGet8(y,i),ay,(u)) + \
00057                                     FbIntMult(FbGet8(x,i),ax,(v))),\
00058                               (CARD32) ((CARD8) ((t) | \
00059                                                (0 - ((t) >> 8)))) << (i))
00060 
00061 #define FbAdd(x,y,i,t)      ((t) = FbGet8(x,i) + FbGet8(y,i), \
00062                       (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
00063 
00064 
00065 #define Alpha(x) ((x) >> 24)
00066 #define Red(x) (((x) >> 16) & 0xff)
00067 #define Green(x) (((x) >> 8) & 0xff)
00068 #define Blue(x) ((x) & 0xff)
00069 
00070 #define IsRGB(pict) ((pict)->image_format.red > (pict)->image_format.blue)
00071 
00072 #define fbComposeGetSolid(pict, dest, bits) { \
00073     FbBits    *__bits__; \
00074     FbStride  __stride__; \
00075     int              __bpp__; \
00076     int              __xoff__,__yoff__; \
00077 \
00078     fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
00079     switch (__bpp__) { \
00080     case 32: \
00081        (bits) = *(CARD32 *) __bits__; \
00082        break; \
00083     case 24: \
00084        (bits) = Fetch24 ((CARD8 *) __bits__); \
00085        break; \
00086     case 16: \
00087        (bits) = *(CARD16 *) __bits__; \
00088        (bits) = cvt0565to0888(bits); \
00089        break; \
00090     case 8: \
00091        (bits) = *(CARD8 *) __bits__; \
00092        (bits) = (bits) << 24; \
00093        break; \
00094     case 1: \
00095        (bits) = *(CARD32 *) __bits__; \
00096        (bits) = FbLeftStipBits((bits),1) ? 0xff000000 : 0x00000000;\
00097        break; \
00098     default: \
00099        return; \
00100     } \
00101     /* manage missing src alpha */ \
00102     if ((pict)->image_format.alphaMask == 0) \
00103        (bits) |= 0xff000000; \
00104     /* Handle RGB/BGR mismatch */ \
00105     if (dest && IsRGB(dest) != IsRGB(pict)) \
00106         bits = (((bits & 0xff000000)) | \
00107               ((bits & 0x00ff0000) >> 16) | \
00108               ((bits & 0x0000ff00)) | \
00109               ((bits & 0x000000ff) << 16)); \
00110 }
00111 
00112 #define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
00113     FbBits    *__bits__; \
00114     FbStride  __stride__; \
00115     int              __bpp__; \
00116     int              __xoff__,__yoff__; \
00117 \
00118     fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
00119     (stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
00120     (line) = ((type *) __bits__) + (stride) * ((y) + __yoff__) + (mul) * ((x) + __xoff__); \
00121 }
00122 
00123 #define cvt8888to0565(s)    ((((s) >> 3) & 0x001f) | \
00124                           (((s) >> 5) & 0x07e0) | \
00125                           (((s) >> 8) & 0xf800))
00126 #define cvt0565to0888(s)    (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
00127                           ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
00128                           ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
00129 
00130 #if IMAGE_BYTE_ORDER == MSBFirst
00131 #define Fetch24(a)  ((unsigned long) (a) & 1 ? \
00132                    ((*(a) << 16) | *((CARD16 *) ((a)+1))) : \
00133                    ((*((CARD16 *) (a)) << 8) | *((a)+2)))
00134 #define Store24(a,v) ((unsigned long) (a) & 1 ? \
00135                     ((*(a) = (CARD8) ((v) >> 16)), \
00136                      (*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \
00137                     ((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \
00138                      (*((a)+2) = (CARD8) (v))))
00139 #else
00140 #define Fetch24(a)  ((unsigned long) (a) & 1 ? \
00141                    ((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \
00142                    ((*((CARD16 *) (a))) | (*((a)+2) << 16)))
00143 #define Store24(a,v) ((unsigned long) (a) & 1 ? \
00144                     ((*(a) = (CARD8) (v)), \
00145                      (*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \
00146                     ((*((CARD16 *) (a)) = (CARD16) (v)),\
00147                      (*((a)+2) = (CARD8) ((v) >> 16))))
00148 #endif
00149                     
00150 /*
00151   The methods below use some tricks to be able to do two color
00152   components at the same time.
00153 */
00154 
00155 /*
00156   x_c = (x_c * a) / 255
00157 */
00158 #define FbByteMul(x, a) do {                                      \
00159         CARD32 t = ((x & 0xff00ff) * a) + 0x800080;               \
00160         t = (t + ((t >> 8) & 0xff00ff)) >> 8;                     \
00161         t &= 0xff00ff;                                            \
00162                                                                   \
00163         x = (((x >> 8) & 0xff00ff) * a) + 0x800080;               \
00164         x = (x + ((x >> 8) & 0xff00ff));                          \
00165         x &= 0xff00ff00;                                          \
00166         x += t;                                                   \
00167     } while (0)
00168 
00169 /*
00170   x_c = (x_c * a) / 255 + y
00171 */
00172 #define FbByteMulAdd(x, a, y) do {                                \
00173         CARD32 t = ((x & 0xff00ff) * a) + 0x800080;               \
00174         t = (t + ((t >> 8) & 0xff00ff)) >> 8;                     \
00175         t &= 0xff00ff;                                            \
00176         t += y & 0xff00ff;                                        \
00177         t |= 0x1000100 - ((t >> 8) & 0xff00ff);                   \
00178         t &= 0xff00ff;                                            \
00179                                                                   \
00180         x = (((x >> 8) & 0xff00ff) * a) + 0x800080;                 \
00181         x = (x + ((x >> 8) & 0xff00ff)) >> 8;                       \
00182         x &= 0xff00ff;                                              \
00183         x += (y >> 8) & 0xff00ff;                                   \
00184         x |= 0x1000100 - ((t >> 8) & 0xff00ff);                     \
00185         x &= 0xff00ff;                                              \
00186         x <<= 8;                                                    \
00187         x += t;                                                     \
00188     } while (0)
00189 
00190 /*
00191   x_c = (x_c * a + y_c * b) / 255
00192 */
00193 #define FbByteAddMul(x, a, y, b) do {                                   \
00194         CARD32 t;                                                       \
00195         CARD32 r = (x >> 24) * a + (y >> 24) * b + 0x80;                \
00196         r += (r >> 8);                                                  \
00197         r >>= 8;                                                        \
00198                                                                         \
00199         t = (x & 0xff00) * a + (y & 0xff00) * b + 0x8000;               \
00200         t += (t >> 8);                                                  \
00201         t >>= 16;                                                       \
00202                                                                         \
00203         t |= r << 16;                                                   \
00204         t |= 0x1000100 - ((t >> 8) & 0xff00ff);                         \
00205         t &= 0xff00ff;                                                  \
00206         t <<= 8;                                                        \
00207                                                                         \
00208         r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80;     \
00209         r += (r >> 8);                                                  \
00210         r >>= 8;                                                        \
00211                                                                         \
00212         x = (x & 0xff) * a + (y & 0xff) * b + 0x80;                     \
00213         x += (x >> 8);                                                  \
00214         x >>= 8;                                                        \
00215         x |= r << 16;                                                   \
00216         x |= 0x1000100 - ((x >> 8) & 0xff00ff);                         \
00217         x &= 0xff00ff;                                                  \
00218         x |= t;                                                         \
00219 } while (0)
00220 
00221 /*
00222   x_c = (x_c * a + y_c *b) / 256
00223 */
00224 #define FbByteAddMul_256(x, a, y, b) do {                               \
00225         CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;             \
00226         t >>= 8;                                                        \
00227         t &= 0xff00ff;                                                  \
00228                                                                         \
00229         x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;      \
00230         x &= 0xff00ff00;                                                \
00231         x += t;                                                         \
00232 } while (0)
00233 /*
00234   x_c = (x_c * a_c) / 255
00235 */
00236 #define FbByteMulC(x, a) do {                                   \
00237         CARD32 t;                                               \
00238         CARD32 r = (x & 0xff) * (a & 0xff);                     \
00239         r |= (x & 0xff0000) * ((a >> 16) & 0xff);               \
00240         r += 0x800080;                                          \
00241         r = (r + ((r >> 8) & 0xff00ff)) >> 8;                   \
00242         r &= 0xff00ff;                                          \
00243                                                                 \
00244         x >>= 8;                                                \
00245         t = (x & 0xff) * ((a >> 8) & 0xff);                     \
00246         t |= (x & 0xff0000) * (a >> 24);                        \
00247         t += 0x800080;                                          \
00248         t = t + ((t >> 8) & 0xff00ff);                          \
00249         x = r | (t & 0xff00ff00);                               \
00250                                                                 \
00251     } while (0)
00252 
00253 /*
00254   x_c = (x_c * a) / 255 + y
00255 */
00256 #define FbByteMulAddC(x, a, y) do {                                \
00257         CARD32 t;                                                  \
00258         CARD32 r = (x & 0xff) * (a & 0xff);                        \
00259         r |= (x & 0xff0000) * ((a >> 16) & 0xff);                  \
00260         r += 0x800080;                                             \
00261         r = (r + ((r >> 8) & 0xff00ff)) >> 8;                      \
00262         r &= 0xff00ff;                                             \
00263         r += y & 0xff00ff;                                         \
00264         r |= 0x1000100 - ((r >> 8) & 0xff00ff);                    \
00265         r &= 0xff00ff;                                             \
00266                                                                    \
00267         x >>= 8;                                                   \
00268         t = (x & 0xff) * ((a >> 8) & 0xff);                        \
00269         t |= (x & 0xff0000) * (a >> 24);                              \
00270         t += 0x800080;                                                \
00271         t = (t + ((t >> 8) & 0xff00ff)) >> 8;                         \
00272         t &= 0xff00ff;                                                \
00273         t += (y >> 8) & 0xff00ff;                                     \
00274         t |= 0x1000100 - ((t >> 8) & 0xff00ff);                       \
00275         t &= 0xff00ff;                                                \
00276         x = r | (t << 8);                                             \
00277     } while (0)
00278 
00279 /*
00280   x_c = (x_c * a_c + y_c * b) / 255
00281 */
00282 #define FbByteAddMulC(x, a, y, b) do {                                  \
00283         CARD32 t;                                                       \
00284         CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b + 0x80;        \
00285         r += (r >> 8);                                                  \
00286         r >>= 8;                                                        \
00287                                                                         \
00288         t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b + 0x8000; \
00289         t += (t >> 8);                                                  \
00290         t >>= 16;                                                       \
00291                                                                         \
00292         t |= r << 16;                                                   \
00293         t |= 0x1000100 - ((t >> 8) & 0xff00ff);                         \
00294         t &= 0xff00ff;                                                  \
00295         t <<= 8;                                                        \
00296                                                                         \
00297         r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \
00298         r += (r >> 8);                                                  \
00299         r >>= 8;                                                        \
00300                                                                         \
00301         x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80;            \
00302         x += (x >> 8);                                                  \
00303         x >>= 8;                                                        \
00304         x |= r << 16;                                                   \
00305         x |= 0x1000100 - ((x >> 8) & 0xff00ff);                         \
00306         x &= 0xff00ff;                                                  \
00307         x |= t;                                                         \
00308 } while (0)
00309 
00310 /*
00311   x_c = min(x_c + y_c, 255)
00312 */
00313 #define FbByteAdd(x, y) do {                                            \
00314         CARD32 t;                                                       \
00315         CARD32 r = (x & 0xff00ff) + (y & 0xff00ff);                     \
00316         r |= 0x1000100 - ((r >> 8) & 0xff00ff);                         \
00317         r &= 0xff00ff;                                                  \
00318                                                                         \
00319         t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff);              \
00320         t |= 0x1000100 - ((t >> 8) & 0xff00ff);                         \
00321         r |= (t & 0xff00ff) << 8;                                       \
00322         x = r;                                                          \
00323     } while (0)
00324 
00325 #define div_255(x) (((x) + 0x80 + (((x) + 0x80) >> 8)) >> 8)
00326 
00327 #if defined(__i386__) && defined(__GNUC__)
00328 #define FASTCALL __attribute__((regparm(3)))
00329 #else
00330 #define FASTCALL
00331 #endif
00332 
00333 #if defined(__GNUC__)
00334 #define INLINE __inline__
00335 #else
00336 #define INLINE
00337 #endif
00338 
00339 typedef struct _FbComposeData {
00340     CARD8     op;
00341     PicturePtr       src;
00342     PicturePtr       mask;
00343     PicturePtr       dest;
00344     INT16     xSrc;
00345     INT16     ySrc;
00346     INT16     xMask;
00347     INT16     yMask;
00348     INT16     xDest;
00349     INT16     yDest;
00350     CARD16    width;
00351     CARD16    height;
00352 } FbComposeData;
00353 
00354 typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask, int width);
00355 typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src, int width);
00356 typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask, int width);
00357 
00358 typedef struct _FbComposeFunctions {
00359     CombineFuncU *combineU;
00360     CombineFuncC *combineC;
00361     CombineMaskU combineMaskU;
00362 } FbComposeFunctions;
00363 
00364 #endif /* _FBPICT_H_ */