LCOV - app.info - objdir/dist/include/gfxColor.h

LCOV - code coverage report
| Current view: | directory - objdir/dist/include - gfxColor.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 42 | 9 | 21.4 %
| Date: | 2012-06-02 | Functions: | 6 | 1 | 16.7 %

           1                 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is Oracle Corporation code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is Oracle Corporation.
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2005
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *   Stuart Parmenter <pavlov@pavlov.net>
          23                 :  *
          24                 :  * Alternatively, the contents of this file may be used under the terms of
          25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          28                 :  * of those above. If you wish to allow use of your version of this file only
          29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          30                 :  * use your version of this file under the terms of the MPL, indicate your
          31                 :  * decision by deleting the provisions above and replace them with the notice
          32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          33                 :  * the provisions above, a recipient may use your version of this file under
          34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          35                 :  *
          36                 :  * ***** END LICENSE BLOCK ***** */
          37                 :
          38                 : #ifndef GFX_COLOR_H
          39                 : #define GFX_COLOR_H
          40                 :
          41                 : #include "gfxTypes.h"
          42                 :
          43                 : #include "prbit.h" // for PR_ROTATE_(LEFT,RIGHT)32
          44                 : #include "prio.h"  // for ntohl
          45                 :
          46                 : #define GFX_UINT32_FROM_BPTR(pbptr,i) (((PRUint32*)(pbptr))[i])
          47                 :
          48                 : #if defined(IS_BIG_ENDIAN)
          49                 :   #define GFX_NTOHL(x) (x)
          50                 :   #define GFX_HAVE_CHEAP_NTOHL
          51                 : #elif defined(_WIN32)
          52                 :   #if (_MSC_VER >= 1300) // also excludes MinGW
          53                 :     #include <stdlib.h>
          54                 :     #pragma intrinsic(_byteswap_ulong)
          55                 :     #define GFX_NTOHL(x) _byteswap_ulong(x)
          56                 :     #define GFX_HAVE_CHEAP_NTOHL
          57                 :   #else
          58                 :     // A reasonably fast generic little-endian implementation.
          59                 :     #define GFX_NTOHL(x) \
          60                 :          ( (PR_ROTATE_RIGHT32((x),8) & 0xFF00FF00) | \
          61                 :            (PR_ROTATE_LEFT32((x),8)  & 0x00FF00FF) )
          62                 :   #endif
          63                 : #else
          64                 :   #define GFX_NTOHL(x) ntohl(x)
          65                 :   #define GFX_HAVE_CHEAP_NTOHL
          66                 : #endif
          67                 :
          68                 : /**
          69                 :  * GFX_0XFF_PPIXEL_FROM_BPTR(x)
          70                 :  *
          71                 :  * Avoid tortured construction of 32-bit ARGB pixel from 3 individual bytes
          72                 :  *   of memory plus constant 0xFF.  RGB bytes are already contiguous!
          73                 :  * Equivalent to: GFX_PACKED_PIXEL(0xff,r,g,b)
          74                 :  *
          75                 :  * Attempt to use fast byte-swapping instruction(s), e.g. bswap on x86, in
          76                 :  *   preference to a sequence of shift/or operations.
          77                 :  */
          78                 : #if defined(GFX_HAVE_CHEAP_NTOHL)
          79                 :   #define GFX_0XFF_PPIXEL_FROM_UINT32(x) \
          80                 :        ( (GFX_NTOHL(x) >> 8) | (0xFF << 24) )
          81                 : #else
          82                 :   // A reasonably fast generic little-endian implementation.
          83                 :   #define GFX_0XFF_PPIXEL_FROM_UINT32(x) \
          84                 :        ( (PR_ROTATE_LEFT32((x),16) | 0xFF00FF00) & ((x) | 0xFFFF00FF) )
          85                 : #endif
          86                 :
          87                 : #define GFX_0XFF_PPIXEL_FROM_BPTR(x) \
          88                 :      ( GFX_0XFF_PPIXEL_FROM_UINT32(GFX_UINT32_FROM_BPTR((x),0)) )
          89                 :
          90                 : /**
          91                 :  * GFX_BLOCK_RGB_TO_FRGB(from,to)
          92                 :  *   sizeof(*from) == sizeof(char)
          93                 :  *   sizeof(*to)   == sizeof(PRUint32)
          94                 :  *
          95                 :  * Copy 4 pixels at a time, reading blocks of 12 bytes (RGB x4)
          96                 :  *   and writing blocks of 16 bytes (FRGB x4)
          97                 :  */
          98                 : #define GFX_BLOCK_RGB_TO_FRGB(from,to) \
          99                 :   PR_BEGIN_MACRO \
         100                 :     PRUint32 m0 = GFX_UINT32_FROM_BPTR(from,0), \
         101                 :              m1 = GFX_UINT32_FROM_BPTR(from,1), \
         102                 :              m2 = GFX_UINT32_FROM_BPTR(from,2), \
         103                 :              rgbr = GFX_NTOHL(m0), \
         104                 :              gbrg = GFX_NTOHL(m1), \
         105                 :              brgb = GFX_NTOHL(m2), \
         106                 :              p0, p1, p2, p3; \
         107                 :     p0 = 0xFF000000 | ((rgbr) >>  8); \
         108                 :     p1 = 0xFF000000 | ((rgbr) << 16) | ((gbrg) >> 16); \
         109                 :     p2 = 0xFF000000 | ((gbrg) <<  8) | ((brgb) >> 24); \
         110                 :     p3 = 0xFF000000 | (brgb); \
         111                 :     to[0] = p0; to[1] = p1; to[2] = p2; to[3] = p3; \
         112                 :   PR_END_MACRO
         113                 :
         114                 : /**
         115                 :  * Fast approximate division by 255. It has the property that
         116                 :  * for all 0 <= n <= 255*255, GFX_DIVIDE_BY_255(n) == n/255.
         117                 :  * But it only uses two adds and two shifts instead of an
         118                 :  * integer division (which is expensive on many processors).
         119                 :  *
         120                 :  * equivalent to ((v)/255)
         121                 :  */
         122                 : #define GFX_DIVIDE_BY_255(v)  \
         123                 :      (((((unsigned)(v)) << 8) + ((unsigned)(v)) + 255) >> 16)
         124                 :
         125                 : /**
         126                 :  * Fast premultiply macro
         127                 :  *
         128                 :  * equivalent to (((c)*(a))/255)
         129                 :  */
         130                 : #define GFX_PREMULTIPLY(c,a) GFX_DIVIDE_BY_255((c)*(a))
         131                 :
         132                 : /**
         133                 :  * Macro to pack the 4 8-bit channels (A,R,G,B)
         134                 :  * into a 32-bit packed premultiplied pixel.
         135                 :  *
         136                 :  * The checks for 0 alpha or max alpha ensure that the
         137                 :  * compiler selects the quicked calculation when alpha is constant.
         138                 :  */
         139                 : #define GFX_PACKED_PIXEL(a,r,g,b)                                       \
         140                 :     ((a) == 0x00) ? 0x00000000 :                                        \
         141                 :     ((a) == 0xFF) ? ((0xFF << 24) | ((r) << 16) | ((g) << 8) | (b))     \
         142                 :                   : ((a) << 24) |                                       \
         143                 :                     (GFX_PREMULTIPLY(r,a) << 16) |                      \
         144                 :                     (GFX_PREMULTIPLY(g,a) << 8) |                       \
         145                 :                     (GFX_PREMULTIPLY(b,a))
         146                 :
         147                 : /**
         148                 :  * Macro to pack the 4 8-bit channels (A,R,G,B)
         149                 :  * into a 32-bit packed NON-premultiplied pixel.
         150                 :  */
         151                 : #define GFX_PACKED_PIXEL_NO_PREMULTIPLY(a,r,g,b)                        \
         152                 :     (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
         153                 :
         154                 :
         155                 : /**
         156                 :  * A color value, storing red, green, blue and alpha components.
         157                 :  * This class does not use premultiplied alpha.
         158                 :  *
         159                 :  * XXX should this use doubles (instead of gfxFloat), for consistency with
         160                 :  * cairo?
         161                 :  */
         162                 : struct THEBES_API gfxRGBA {
         163                 :     gfxFloat r, g, b, a;
         164                 :
         165                 :     enum PackedColorType {
         166                 :         PACKED_ABGR,
         167                 :         PACKED_ABGR_PREMULTIPLIED,
         168                 :
         169                 :         PACKED_ARGB,
         170                 :         PACKED_ARGB_PREMULTIPLIED,
         171                 :
         172                 :         PACKED_XRGB
         173                 :     };
         174                 :
         175               0 :     gfxRGBA() { }
         176                 :     /**
         177                 :      * Intialize this color using explicit red, green, blue and alpha
         178                 :      * values.
         179                 :      */
         180               0 :     gfxRGBA(gfxFloat _r, gfxFloat _g, gfxFloat _b, gfxFloat _a=1.0) : r(_r), g(_g), b(_b), a(_a) {}
         181                 :
         182                 :     /**
         183                 :      * Initialize this color from a packed 32-bit color.
         184                 :      * The color value is interpreted based on colorType;
         185                 :      * all values use the native platform endianness.
         186                 :      *
         187                 :      * @see gfxRGBA::Packed
         188                 :      */
         189              19 :     gfxRGBA(PRUint32 c, PackedColorType colorType = PACKED_ABGR) {
         190              19 :         if (colorType == PACKED_ABGR ||
         191                 :             colorType == PACKED_ABGR_PREMULTIPLIED)
         192                 :         {
         193              19 :             r = ((c >> 0) & 0xff) * (1.0 / 255.0);
         194              19 :             g = ((c >> 8) & 0xff) * (1.0 / 255.0);
         195              19 :             b = ((c >> 16) & 0xff) * (1.0 / 255.0);
         196              19 :             a = ((c >> 24) & 0xff) * (1.0 / 255.0);
         197               0 :         } else if (colorType == PACKED_ARGB ||
         198                 :                    colorType == PACKED_XRGB ||
         199                 :                    colorType == PACKED_ARGB_PREMULTIPLIED)
         200                 :         {
         201               0 :             b = ((c >> 0) & 0xff) * (1.0 / 255.0);
         202               0 :             g = ((c >> 8) & 0xff) * (1.0 / 255.0);
         203               0 :             r = ((c >> 16) & 0xff) * (1.0 / 255.0);
         204               0 :             a = ((c >> 24) & 0xff) * (1.0 / 255.0);
         205                 :         }
         206                 :
         207              19 :         if (colorType == PACKED_ABGR_PREMULTIPLIED ||
         208                 :             colorType == PACKED_ARGB_PREMULTIPLIED)
         209                 :         {
         210               0 :             if (a > 0.0) {
         211               0 :                 r /= a;
         212               0 :                 g /= a;
         213               0 :                 b /= a;
         214                 :             }
         215              19 :         } else if (colorType == PACKED_XRGB) {
         216               0 :             a = 1.0;
         217                 :         }
         218              19 :     }
         219                 :
         220               0 :     bool operator==(const gfxRGBA& other) const
         221                 :     {
         222               0 :         return r == other.r && g == other.g && b == other.b && a == other.a;
         223                 :     }
         224               0 :     bool operator!=(const gfxRGBA& other) const
         225                 :     {
         226               0 :         return !(*this == other);
         227                 :     }
         228                 :
         229                 :     /**
         230                 :      * Returns this color value as a packed 32-bit integer. This reconstructs
         231                 :      * the int32 based on the given colorType, always in the native byte order.
         232                 :      *
         233                 :      * Note: gcc 4.2.3 on at least Ubuntu (x86) does something strange with
         234                 :      * (PRUint8)(c * 255.0) << x, where the result is different than
         235                 :      * double d = c * 255.0; v = ((PRUint8) d) << x.
         236                 :      */
         237               0 :     PRUint32 Packed(PackedColorType colorType = PACKED_ABGR) const {
         238               0 :         gfxFloat rb = (r * 255.0);
         239               0 :         gfxFloat gb = (g * 255.0);
         240               0 :         gfxFloat bb = (b * 255.0);
         241               0 :         gfxFloat ab = (a * 255.0);
         242                 :
         243               0 :         if (colorType == PACKED_ABGR) {
         244                 :             return (PRUint8(ab) << 24) |
         245                 :                    (PRUint8(bb) << 16) |
         246                 :                    (PRUint8(gb) << 8) |
         247               0 :                    (PRUint8(rb) << 0);
         248                 :         }
         249               0 :         if (colorType == PACKED_ARGB || colorType == PACKED_XRGB) {
         250                 :             return (PRUint8(ab) << 24) |
         251                 :                    (PRUint8(rb) << 16) |
         252                 :                    (PRUint8(gb) << 8) |
         253               0 :                    (PRUint8(bb) << 0);
         254                 :         }
         255                 :
         256               0 :         rb *= a;
         257               0 :         gb *= a;
         258               0 :         bb *= a;
         259                 :
         260               0 :         if (colorType == PACKED_ABGR_PREMULTIPLIED) {
         261                 :             return (((PRUint8)(ab) << 24) |
         262                 :                     ((PRUint8)(bb) << 16) |
         263                 :                     ((PRUint8)(gb) << 8) |
         264               0 :                     ((PRUint8)(rb) << 0));
         265                 :         }
         266               0 :         if (colorType == PACKED_ARGB_PREMULTIPLIED) {
         267                 :             return (((PRUint8)(ab) << 24) |
         268                 :                     ((PRUint8)(rb) << 16) |
         269                 :                     ((PRUint8)(gb) << 8) |
         270               0 :                     ((PRUint8)(bb) << 0));
         271                 :         }
         272                 :
         273               0 :         return 0;
         274                 :     }
         275                 : };
         276                 :
         277                 : #endif /* _GFX_COLOR_H */

Generated by: LCOV version 1.7