src/gui/painting/qdrawhelper_p.h
changeset 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef QDRAWHELPER_P_H
       
    43 #define QDRAWHELPER_P_H
       
    44 
       
    45 //
       
    46 //  W A R N I N G
       
    47 //  -------------
       
    48 //
       
    49 // This file is not part of the Qt API.  It exists purely as an
       
    50 // implementation detail.  This header file may change from version to
       
    51 // version without notice, or even be removed.
       
    52 //
       
    53 // We mean it.
       
    54 //
       
    55 
       
    56 #include "QtCore/qglobal.h"
       
    57 #include "QtGui/qcolor.h"
       
    58 #include "QtGui/qpainter.h"
       
    59 #include "QtGui/qimage.h"
       
    60 #ifndef QT_FT_BEGIN_HEADER
       
    61 #define QT_FT_BEGIN_HEADER
       
    62 #define QT_FT_END_HEADER
       
    63 #endif
       
    64 #include "private/qrasterdefs_p.h"
       
    65 
       
    66 #ifdef Q_WS_QWS
       
    67 #include "QtGui/qscreen_qws.h"
       
    68 #endif
       
    69 
       
    70 // Disable MMX and SSE on Mac/PPC builds, or if the compiler
       
    71 // does not support -Xarch argument passing
       
    72 #if defined(QT_NO_MAC_XARCH) || (defined(Q_OS_DARWIN) && (defined(__ppc__) || defined(__ppc64__)))
       
    73 #undef QT_HAVE_SSE2
       
    74 #undef QT_HAVE_SSE
       
    75 #undef QT_HAVE_3DNOW
       
    76 #undef QT_HAVE_MMX
       
    77 #endif
       
    78 
       
    79 QT_BEGIN_NAMESPACE
       
    80 
       
    81 #if defined(Q_CC_MSVC) && _MSCVER <= 1300 && !defined(Q_CC_INTEL)
       
    82 #define Q_STATIC_TEMPLATE_SPECIALIZATION static
       
    83 #else
       
    84 #define Q_STATIC_TEMPLATE_SPECIALIZATION
       
    85 #endif
       
    86 
       
    87 #if defined(Q_CC_RVCT)
       
    88 // RVCT doesn't like static template functions
       
    89 #  define Q_STATIC_TEMPLATE_FUNCTION
       
    90 #  define Q_STATIC_INLINE_FUNCTION static __forceinline
       
    91 #else
       
    92 #  define Q_STATIC_TEMPLATE_FUNCTION static
       
    93 #  define Q_STATIC_INLINE_FUNCTION static inline
       
    94 #endif
       
    95 
       
    96 /*******************************************************************************
       
    97  * QSpan
       
    98  *
       
    99  * duplicate definition of FT_Span
       
   100  */
       
   101 typedef QT_FT_Span QSpan;
       
   102 
       
   103 struct QSolidData;
       
   104 struct QTextureData;
       
   105 struct QGradientData;
       
   106 struct QLinearGradientData;
       
   107 struct QRadialGradientData;
       
   108 struct QConicalGradientData;
       
   109 struct QSpanData;
       
   110 class QGradient;
       
   111 class QRasterBuffer;
       
   112 class QClipData;
       
   113 class QRasterPaintEngineState;
       
   114 
       
   115 typedef QT_FT_SpanFunc ProcessSpans;
       
   116 typedef void (*BitmapBlitFunc)(QRasterBuffer *rasterBuffer,
       
   117                                int x, int y, quint32 color,
       
   118                                const uchar *bitmap,
       
   119                                int mapWidth, int mapHeight, int mapStride);
       
   120 
       
   121 typedef void (*AlphamapBlitFunc)(QRasterBuffer *rasterBuffer,
       
   122                                  int x, int y, quint32 color,
       
   123                                  const uchar *bitmap,
       
   124                                  int mapWidth, int mapHeight, int mapStride,
       
   125                                  const QClipData *clip);
       
   126 
       
   127 typedef void (*AlphaRGBBlitFunc)(QRasterBuffer *rasterBuffer,
       
   128                                  int x, int y, quint32 color,
       
   129                                  const uint *rgbmask,
       
   130                                  int mapWidth, int mapHeight, int mapStride,
       
   131                                  const QClipData *clip);
       
   132 
       
   133 typedef void (*RectFillFunc)(QRasterBuffer *rasterBuffer,
       
   134                              int x, int y, int width, int height,
       
   135                              quint32 color);
       
   136 
       
   137 typedef void (*SrcOverBlendFunc)(uchar *destPixels, int dbpl,
       
   138                                  const uchar *src, int spbl,
       
   139                                  int w, int h,
       
   140                                  int const_alpha);
       
   141 
       
   142 typedef void (*SrcOverScaleFunc)(uchar *destPixels, int dbpl,
       
   143                                  const uchar *src, int spbl,
       
   144                                  const QRectF &targetRect,
       
   145                                  const QRectF &sourceRect,
       
   146                                  const QRect &clipRect,
       
   147                                  int const_alpha);
       
   148 
       
   149 typedef void (*SrcOverTransformFunc)(uchar *destPixels, int dbpl,
       
   150                                      const uchar *src, int spbl,
       
   151                                      const QRectF &targetRect,
       
   152                                      const QRectF &sourceRect,
       
   153                                      const QRect &clipRect,
       
   154                                      const QTransform &targetRectTransform,
       
   155                                      int const_alpha);
       
   156 
       
   157 
       
   158 struct DrawHelper {
       
   159     ProcessSpans blendColor;
       
   160     ProcessSpans blendGradient;
       
   161     BitmapBlitFunc bitmapBlit;
       
   162     AlphamapBlitFunc alphamapBlit;
       
   163     AlphaRGBBlitFunc alphaRGBBlit;
       
   164     RectFillFunc fillRect;
       
   165 };
       
   166 
       
   167 extern SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats];
       
   168 extern SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats];
       
   169 extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats];
       
   170 
       
   171 extern DrawHelper qDrawHelper[QImage::NImageFormats];
       
   172 
       
   173 void qBlendTexture(int count, const QSpan *spans, void *userData);
       
   174 #if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
       
   175 extern DrawHelper qDrawHelperCallback[QImage::NImageFormats];
       
   176 void qBlendTextureCallback(int count, const QSpan *spans, void *userData);
       
   177 #endif
       
   178 
       
   179 typedef void (QT_FASTCALL *CompositionFunction)(uint *dest, const uint *src, int length, uint const_alpha);
       
   180 typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha);
       
   181 
       
   182 void qInitDrawhelperAsm();
       
   183 
       
   184 class QRasterPaintEngine;
       
   185 
       
   186 struct QSolidData
       
   187 {
       
   188     uint color;
       
   189 };
       
   190 
       
   191 struct QLinearGradientData
       
   192 {
       
   193     struct {
       
   194         qreal x;
       
   195         qreal y;
       
   196     } origin;
       
   197     struct {
       
   198         qreal x;
       
   199         qreal y;
       
   200     } end;
       
   201 };
       
   202 
       
   203 struct QRadialGradientData
       
   204 {
       
   205     struct {
       
   206         qreal x;
       
   207         qreal y;
       
   208     } center;
       
   209     struct {
       
   210         qreal x;
       
   211         qreal y;
       
   212     } focal;
       
   213     qreal radius;
       
   214 };
       
   215 
       
   216 struct QConicalGradientData
       
   217 {
       
   218     struct {
       
   219         qreal x;
       
   220         qreal y;
       
   221     } center;
       
   222     qreal angle;
       
   223 };
       
   224 
       
   225 struct QGradientData
       
   226 {
       
   227     QGradient::Spread spread;
       
   228 
       
   229     union {
       
   230         QLinearGradientData linear;
       
   231         QRadialGradientData radial;
       
   232         QConicalGradientData conical;
       
   233     };
       
   234 
       
   235 #ifdef Q_WS_QWS
       
   236 #define GRADIENT_STOPTABLE_SIZE 256
       
   237 #else
       
   238 #define GRADIENT_STOPTABLE_SIZE 1024
       
   239 #endif
       
   240 
       
   241     uint* colorTable; //[GRADIENT_STOPTABLE_SIZE];
       
   242 
       
   243     uint alphaColor : 1;
       
   244 };
       
   245 
       
   246 struct QTextureData
       
   247 {
       
   248     const uchar *imageData;
       
   249     const uchar *scanLine(int y) const { return imageData + y*bytesPerLine; }
       
   250 
       
   251     int width;
       
   252     int height;
       
   253     // clip rect
       
   254     int x1;
       
   255     int y1;
       
   256     int x2;
       
   257     int y2;
       
   258     int bytesPerLine;
       
   259     QImage::Format format;
       
   260     const QVector<QRgb> *colorTable;
       
   261     bool hasAlpha;
       
   262     enum Type {
       
   263         Plain,
       
   264         Tiled
       
   265     };
       
   266     Type type;
       
   267     int const_alpha;
       
   268 };
       
   269 
       
   270 struct QSpanData
       
   271 {
       
   272     QSpanData() : tempImage(0) {}
       
   273     ~QSpanData() { delete tempImage; }
       
   274 
       
   275     QRasterBuffer *rasterBuffer;
       
   276 #ifdef Q_WS_QWS
       
   277     QRasterPaintEngine *rasterEngine;
       
   278 #endif
       
   279     ProcessSpans blend;
       
   280     ProcessSpans unclipped_blend;
       
   281     BitmapBlitFunc bitmapBlit;
       
   282     AlphamapBlitFunc alphamapBlit;
       
   283     AlphaRGBBlitFunc alphaRGBBlit;
       
   284     RectFillFunc fillRect;
       
   285     qreal m11, m12, m13, m21, m22, m23, m33, dx, dy;   // inverse xform matrix
       
   286     const QClipData *clip;
       
   287     enum Type {
       
   288         None,
       
   289         Solid,
       
   290         LinearGradient,
       
   291         RadialGradient,
       
   292         ConicalGradient,
       
   293         Texture
       
   294     } type : 8;
       
   295     int txop : 8;
       
   296     int fast_matrix : 1;
       
   297     bool bilinear;
       
   298     QImage *tempImage;
       
   299     union {
       
   300         QSolidData solid;
       
   301         QGradientData gradient;
       
   302         QTextureData texture;
       
   303     };
       
   304 
       
   305     void init(QRasterBuffer *rb, const QRasterPaintEngine *pe);
       
   306     void setup(const QBrush &brush, int alpha, QPainter::CompositionMode compositionMode);
       
   307     void setupMatrix(const QTransform &matrix, int bilinear);
       
   308     void initTexture(const QImage *image, int alpha, QTextureData::Type = QTextureData::Plain, const QRect &sourceRect = QRect());
       
   309     void adjustSpanMethods();
       
   310 };
       
   311 
       
   312 
       
   313 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) {
       
   314     a += 1;
       
   315     uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0;
       
   316     t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f;
       
   317     return t;
       
   318 }
       
   319 
       
   320 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) {
       
   321     uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0;
       
   322     t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f;
       
   323     return t;
       
   324 }
       
   325 
       
   326 #if defined(Q_CC_RVCT)
       
   327 #  pragma push
       
   328 #  pragma arm
       
   329 #endif
       
   330 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) {
       
   331     uint t = (x & 0xff00ff) * a;
       
   332     t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
       
   333     t &= 0xff00ff;
       
   334 
       
   335     x = ((x >> 8) & 0xff00ff) * a;
       
   336     x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
       
   337     x &= 0xff00ff00;
       
   338     x |= t;
       
   339     return x;
       
   340 }
       
   341 #if defined(Q_CC_RVCT)
       
   342 #  pragma pop
       
   343 #endif
       
   344 
       
   345 Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) {
       
   346     uint a = x >> 24;
       
   347     uint t = (x & 0xff00ff) * a;
       
   348     t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
       
   349     t &= 0xff00ff;
       
   350 
       
   351     x = ((x >> 8) & 0xff) * a;
       
   352     x = (x + ((x >> 8) & 0xff) + 0x80);
       
   353     x &= 0xff00;
       
   354     x |= t | (a << 24);
       
   355     return x;
       
   356 }
       
   357 
       
   358 #define INV_PREMUL(p)                                   \
       
   359     (qAlpha(p) == 0 ? 0 :                               \
       
   360     ((qAlpha(p) << 24)                                  \
       
   361      | (((255*qRed(p))/ qAlpha(p)) << 16)               \
       
   362      | (((255*qGreen(p)) / qAlpha(p))  << 8)            \
       
   363      | ((255*qBlue(p)) / qAlpha(p))))
       
   364 
       
   365 template <class DST, class SRC>
       
   366 inline DST qt_colorConvert(SRC color, DST dummy)
       
   367 {
       
   368     Q_UNUSED(dummy);
       
   369     return DST(color);
       
   370 }
       
   371 
       
   372 
       
   373 template <>
       
   374 inline quint32 qt_colorConvert(quint16 color, quint32 dummy)
       
   375 {
       
   376     Q_UNUSED(dummy);
       
   377     const int r = (color & 0xf800);
       
   378     const int g = (color & 0x07e0);
       
   379     const int b = (color & 0x001f);
       
   380     const int tr = (r >> 8) | (r >> 13);
       
   381     const int tg = (g >> 3) | (g >> 9);
       
   382     const int tb = (b << 3) | (b >> 2);
       
   383 
       
   384     return qRgb(tr, tg, tb);
       
   385 }
       
   386 
       
   387 template <>
       
   388 inline quint16 qt_colorConvert(quint32 color, quint16 dummy)
       
   389 {
       
   390     Q_UNUSED(dummy);
       
   391     const int r = qRed(color) << 8;
       
   392     const int g = qGreen(color) << 3;
       
   393     const int b = qBlue(color) >> 3;
       
   394 
       
   395     return (r & 0xf800) | (g & 0x07e0)| (b & 0x001f);
       
   396 }
       
   397 
       
   398 class quint32p
       
   399 {
       
   400 public:
       
   401     inline quint32p(quint32 v) : data(PREMUL(v)) {}
       
   402 
       
   403     inline operator quint32() const { return data; }
       
   404 
       
   405     inline operator quint16() const
       
   406     {
       
   407         return qt_colorConvert<quint16, quint32>(data, 0);
       
   408     }
       
   409 
       
   410     Q_STATIC_INLINE_FUNCTION quint32p fromRawData(quint32 v)
       
   411     {
       
   412         quint32p p;
       
   413         p.data = v;
       
   414         return p;
       
   415     }
       
   416 
       
   417 private:
       
   418     quint32p() {}
       
   419     quint32 data;
       
   420 } Q_PACKED;
       
   421 
       
   422 class qabgr8888
       
   423 {
       
   424 public:
       
   425     inline qabgr8888(quint32 v)
       
   426     {
       
   427         data = qRgba(qBlue(v), qGreen(v), qRed(v), qAlpha(v));
       
   428     }
       
   429 
       
   430     inline bool operator==(const qabgr8888 &v) const { return data == v.data; }
       
   431 
       
   432 private:
       
   433     quint32 data;
       
   434 } Q_PACKED;
       
   435 
       
   436 class qrgb565;
       
   437 
       
   438 class qargb8565
       
   439 {
       
   440 public:
       
   441     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; }
       
   442 
       
   443     inline qargb8565() {}
       
   444     inline qargb8565(quint32 v);
       
   445     inline explicit qargb8565(quint32p v);
       
   446     inline qargb8565(const qargb8565 &v);
       
   447     inline qargb8565(const qrgb565 &v);
       
   448 
       
   449     inline operator quint32() const;
       
   450     inline operator quint16() const;
       
   451 
       
   452     inline quint8 alpha() const { return data[0]; }
       
   453     inline qargb8565 truncedAlpha() {
       
   454         data[0] &= 0xf8;
       
   455         data[1] &= 0xdf;
       
   456         return *this;
       
   457     }
       
   458     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; }
       
   459     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); }
       
   460 
       
   461     inline qargb8565 byte_mul(quint8 a) const;
       
   462     inline qargb8565 operator+(qargb8565 v) const;
       
   463     inline bool operator==(const qargb8565 &v) const;
       
   464 
       
   465     inline quint32 rawValue() const;
       
   466     inline quint16 rawValue16() const;
       
   467 
       
   468 private:
       
   469     friend class qrgb565;
       
   470 
       
   471     quint8 data[3];
       
   472 } Q_PACKED;
       
   473 
       
   474 class qrgb565
       
   475 {
       
   476 public:
       
   477     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
       
   478 
       
   479     qrgb565(int v = 0) : data(v) {}
       
   480 
       
   481     inline explicit qrgb565(quint32p v);
       
   482     inline explicit qrgb565(quint32 v);
       
   483     inline explicit qrgb565(const qargb8565 &v);
       
   484 
       
   485     inline operator quint32() const;
       
   486     inline operator quint16() const;
       
   487 
       
   488     inline qrgb565 operator+(qrgb565 v) const;
       
   489 
       
   490     inline quint8 alpha() const { return 0xff; }
       
   491     inline qrgb565 truncedAlpha() { return *this; }
       
   492     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; }
       
   493     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); }
       
   494 
       
   495     inline qrgb565 byte_mul(quint8 a) const;
       
   496 
       
   497     inline bool operator==(const qrgb565 &v) const;
       
   498     inline quint16 rawValue() const { return data; }
       
   499 
       
   500 private:
       
   501     friend class qargb8565;
       
   502 
       
   503     quint16 data;
       
   504 } Q_PACKED;
       
   505 
       
   506 qargb8565::qargb8565(quint32 v)
       
   507 {
       
   508     *this = qargb8565(quint32p(v));
       
   509 }
       
   510 
       
   511 qargb8565::qargb8565(quint32p v)
       
   512 {
       
   513     data[0] = qAlpha(v);
       
   514     const int r = qRed(v);
       
   515     const int g = qGreen(v);
       
   516     const int b = qBlue(v);
       
   517     data[1] = ((g << 3) & 0xe0) | (b >> 3);
       
   518     data[2] = (r & 0xf8) | (g >> 5);
       
   519 }
       
   520 
       
   521 qargb8565::qargb8565(const qargb8565 &v)
       
   522 {
       
   523     data[0] = v.data[0];
       
   524     data[1] = v.data[1];
       
   525     data[2] = v.data[2];
       
   526 }
       
   527 
       
   528 qargb8565::qargb8565(const qrgb565 &v)
       
   529 {
       
   530     data[0] = 0xff;
       
   531     data[1] = v.data & 0xff;
       
   532     data[2] = v.data >> 8;
       
   533 }
       
   534 
       
   535 qargb8565::operator quint32() const
       
   536 {
       
   537     const quint16 rgb = (data[2] << 8) | data[1];
       
   538     const int a = data[0];
       
   539     const int r = (rgb & 0xf800);
       
   540     const int g = (rgb & 0x07e0);
       
   541     const int b = (rgb & 0x001f);
       
   542     const int tr = qMin(a, (r >> 8) | (r >> 13));
       
   543     const int tg = qMin(a, (g >> 3) | (g >> 9));
       
   544     const int tb = qMin(a, (b << 3) | (b >> 2));
       
   545     return qRgba(tr, tg, tb, data[0]);
       
   546 }
       
   547 
       
   548 qargb8565::operator quint16() const
       
   549 {
       
   550     return (data[2] << 8) | data[1];
       
   551 }
       
   552 
       
   553 qargb8565 qargb8565::operator+(qargb8565 v) const
       
   554 {
       
   555     qargb8565 t;
       
   556     t.data[0] = data[0] + v.data[0];
       
   557     const quint16 rgb =  ((data[2] + v.data[2]) << 8)
       
   558                          + (data[1] + v.data[1]);
       
   559     t.data[1] = rgb & 0xff;
       
   560     t.data[2] = rgb >> 8;
       
   561     return t;
       
   562 }
       
   563 
       
   564 qargb8565 qargb8565::byte_mul(quint8 a) const
       
   565 {
       
   566     qargb8565 result;
       
   567     result.data[0] = (data[0] * a) >> 5;
       
   568 
       
   569     const quint16 x = (data[2] << 8) | data[1];
       
   570     const quint16 t = ((((x & 0x07e0) >> 5) * a) & 0x07e0) |
       
   571                       ((((x & 0xf81f) * a) >> 5) & 0xf81f);
       
   572     result.data[1] = t & 0xff;
       
   573     result.data[2] = t >> 8;
       
   574     return result;
       
   575 }
       
   576 
       
   577 bool qargb8565::operator==(const qargb8565 &v) const
       
   578 {
       
   579     return data[0] == v.data[0]
       
   580         && data[1] == v.data[1]
       
   581         && data[2] == v.data[2];
       
   582 }
       
   583 
       
   584 quint32 qargb8565::rawValue() const
       
   585 {
       
   586     return (data[2] << 16) | (data[1] << 8) | data[0];
       
   587 }
       
   588 
       
   589 quint16 qargb8565::rawValue16() const
       
   590 {
       
   591     return (data[2] << 8) | data[1];
       
   592 }
       
   593 
       
   594 qrgb565::qrgb565(quint32p v)
       
   595 {
       
   596     *this = qrgb565(quint32(v));
       
   597 }
       
   598 
       
   599 qrgb565::qrgb565(quint32 v)
       
   600 {
       
   601     const int r = qRed(v) << 8;
       
   602     const int g = qGreen(v) << 3;
       
   603     const int b = qBlue(v) >> 3;
       
   604 
       
   605     data = (r & 0xf800) | (g & 0x07e0)| (b & 0x001f);
       
   606 }
       
   607 
       
   608 qrgb565::qrgb565(const qargb8565 &v)
       
   609 {
       
   610     data = (v.data[2] << 8) | v.data[1];
       
   611 }
       
   612 
       
   613 qrgb565::operator quint32() const
       
   614 {
       
   615     const int r = (data & 0xf800);
       
   616     const int g = (data & 0x07e0);
       
   617     const int b = (data & 0x001f);
       
   618     const int tr = (r >> 8) | (r >> 13);
       
   619     const int tg = (g >> 3) | (g >> 9);
       
   620     const int tb = (b << 3) | (b >> 2);
       
   621     return qRgb(tr, tg, tb);
       
   622 }
       
   623 
       
   624 qrgb565::operator quint16() const
       
   625 {
       
   626     return data;
       
   627 }
       
   628 
       
   629 qrgb565 qrgb565::operator+(qrgb565 v) const
       
   630 {
       
   631     qrgb565 t;
       
   632     t.data = data + v.data;
       
   633     return t;
       
   634 }
       
   635 
       
   636 qrgb565 qrgb565::byte_mul(quint8 a) const
       
   637 {
       
   638     qrgb565 result;
       
   639     result.data = ((((data & 0x07e0) >> 5) * a) & 0x07e0) |
       
   640                   ((((data & 0xf81f) * a) >> 5) & 0xf81f);
       
   641     return result;
       
   642 }
       
   643 
       
   644 bool qrgb565::operator==(const qrgb565 &v) const
       
   645 {
       
   646     return data == v.data;
       
   647 }
       
   648 
       
   649 class qbgr565
       
   650 {
       
   651 public:
       
   652     inline qbgr565(quint16 v)
       
   653     {
       
   654         data = ((v & 0x001f) << 11) |
       
   655                (v & 0x07e0) |
       
   656                ((v & 0xf800) >> 11);
       
   657     }
       
   658 
       
   659     inline bool operator==(const qbgr565 &v) const
       
   660     {
       
   661         return data == v.data;
       
   662     }
       
   663 
       
   664 private:
       
   665     quint16 data;
       
   666 } Q_PACKED;
       
   667 
       
   668 class qrgb555;
       
   669 
       
   670 class qargb8555
       
   671 {
       
   672 public:
       
   673     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; }
       
   674 
       
   675     qargb8555() {}
       
   676     inline qargb8555(quint32 v);
       
   677     inline explicit qargb8555(quint32p v);
       
   678     inline qargb8555(const qargb8555 &v);
       
   679     inline qargb8555(const qrgb555 &v);
       
   680 
       
   681     inline operator quint32() const;
       
   682 
       
   683     inline quint8 alpha() const { return data[0]; }
       
   684     inline qargb8555 truncedAlpha() { data[0] &= 0xf8; return *this; }
       
   685     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; }
       
   686     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); }
       
   687 
       
   688     inline qargb8555 operator+(qargb8555 v) const;
       
   689     inline qargb8555 byte_mul(quint8 a) const;
       
   690 
       
   691     inline bool operator==(const qargb8555 &v) const;
       
   692 
       
   693     inline quint32 rawValue() const;
       
   694 
       
   695 private:
       
   696     friend class qrgb555;
       
   697     quint8 data[3];
       
   698 } Q_PACKED;
       
   699 
       
   700 class qrgb555
       
   701 {
       
   702 public:
       
   703     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
       
   704 
       
   705     inline qrgb555(int v = 0) : data(v) {}
       
   706 
       
   707     inline explicit qrgb555(quint32p v) { *this = qrgb555(quint32(v)); }
       
   708 
       
   709     inline explicit qrgb555(quint32 v)
       
   710     {
       
   711         const int r = qRed(v) << 7;
       
   712         const int g = qGreen(v) << 2;
       
   713         const int b = qBlue(v) >> 3;
       
   714 
       
   715         data = (r & 0x7c00) | (g & 0x03e0) | (b & 0x001f);
       
   716     }
       
   717 
       
   718     inline explicit qrgb555(quint16 v)
       
   719     {
       
   720         data = ((v >> 1) & (0x7c00 | 0x03e0)) |
       
   721                (v & 0x001f);
       
   722     }
       
   723 
       
   724     inline explicit qrgb555(const qargb8555 &v);
       
   725 
       
   726     inline operator quint32() const
       
   727     {
       
   728         const int r = (data & 0x7c00);
       
   729         const int g = (data & 0x03e0);
       
   730         const int b = (data & 0x001f);
       
   731         const int tr = (r >> 7) | (r >> 12);
       
   732         const int tg = (g >> 2) | (g >> 7);
       
   733         const int tb = (b << 3) | (b >> 2);
       
   734 
       
   735         return qRgb(tr, tg, tb);
       
   736     }
       
   737 
       
   738     inline operator quint16() const
       
   739     {
       
   740         const int r = ((data & 0x7c00) << 1) & 0xf800;
       
   741         const int g = (((data & 0x03e0) << 1) | ((data >> 4) & 0x0020)) & 0x07e0;
       
   742         const int b = (data & 0x001f);
       
   743 
       
   744         return r | g | b;
       
   745     }
       
   746 
       
   747     inline qrgb555 operator+(qrgb555 v) const;
       
   748     inline qrgb555 byte_mul(quint8 a) const;
       
   749 
       
   750     inline quint8 alpha() const { return 0xff; }
       
   751     inline qrgb555 truncedAlpha() { return *this; }
       
   752     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; }
       
   753     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); }
       
   754 
       
   755     inline bool operator==(const qrgb555 &v) const { return v.data == data; }
       
   756     inline bool operator!=(const qrgb555 &v) const { return v.data != data; }
       
   757 
       
   758     inline quint16 rawValue() const { return data; }
       
   759 
       
   760 private:
       
   761     friend class qargb8555;
       
   762     friend class qbgr555;
       
   763     quint16 data;
       
   764 
       
   765 } Q_PACKED;
       
   766 
       
   767 qrgb555::qrgb555(const qargb8555 &v)
       
   768 {
       
   769     data = (v.data[2] << 8) | v.data[1];
       
   770 }
       
   771 
       
   772 qrgb555 qrgb555::operator+(qrgb555 v) const
       
   773 {
       
   774     qrgb555 t;
       
   775     t.data = data + v.data;
       
   776     return t;
       
   777 }
       
   778 
       
   779 qrgb555 qrgb555::byte_mul(quint8 a) const
       
   780 {
       
   781     quint16 t = (((data & 0x3e0) * a) >> 5) & 0x03e0;
       
   782     t |= (((data & 0x7c1f) * a) >> 5) & 0x7c1f;
       
   783 
       
   784     qrgb555 result;
       
   785     result.data = t;
       
   786     return result;
       
   787 }
       
   788 
       
   789 class qbgr555
       
   790 {
       
   791 public:
       
   792     inline qbgr555(quint32 v) { *this = qbgr555(qrgb555(v)); }
       
   793 
       
   794     inline qbgr555(qrgb555 v)
       
   795     {
       
   796         data = ((v.data & 0x001f) << 10) |
       
   797                (v.data & 0x03e0) |
       
   798                ((v.data & 0x7c00) >> 10);
       
   799     }
       
   800 
       
   801     inline bool operator==(const qbgr555 &v) const
       
   802     {
       
   803         return data == v.data;
       
   804     }
       
   805 
       
   806 private:
       
   807     quint16 data;
       
   808 } Q_PACKED;
       
   809 
       
   810 qargb8555::qargb8555(quint32 v)
       
   811 {
       
   812     v = quint32p(v);
       
   813     data[0] = qAlpha(v);
       
   814     const int r = qRed(v);
       
   815     const int g = qGreen(v);
       
   816     const int b = qBlue(v);
       
   817     data[1] = ((g << 2) & 0xe0) | (b >> 3);
       
   818     data[2] = ((r >> 1) & 0x7c) | (g >> 6);
       
   819 
       
   820 }
       
   821 
       
   822 qargb8555::qargb8555(quint32p v)
       
   823 {
       
   824     data[0] = qAlpha(v);
       
   825     const int r = qRed(v);
       
   826     const int g = qGreen(v);
       
   827     const int b = qBlue(v);
       
   828     data[1] = ((g << 2) & 0xe0) | (b >> 3);
       
   829     data[2] = ((r >> 1) & 0x7c) | (g >> 6);
       
   830 }
       
   831 
       
   832 qargb8555::qargb8555(const qargb8555 &v)
       
   833 {
       
   834     data[0] = v.data[0];
       
   835     data[1] = v.data[1];
       
   836     data[2] = v.data[2];
       
   837 }
       
   838 
       
   839 qargb8555::qargb8555(const qrgb555 &v)
       
   840 {
       
   841     data[0] = 0xff;
       
   842     data[1] = v.data & 0xff;
       
   843     data[2] = v.data >> 8;
       
   844 }
       
   845 
       
   846 qargb8555::operator quint32() const
       
   847 {
       
   848     const quint16 rgb = (data[2] << 8) | data[1];
       
   849     const int r = (rgb & 0x7c00);
       
   850     const int g = (rgb & 0x03e0);
       
   851     const int b = (rgb & 0x001f);
       
   852     const int tr = (r >> 7) | (r >> 12);
       
   853     const int tg = (g >> 2) | (g >> 7);
       
   854     const int tb = (b << 3) | (b >> 2);
       
   855 
       
   856     return qRgba(tr, tg, tb, data[0]);
       
   857 }
       
   858 
       
   859 bool qargb8555::operator==(const qargb8555 &v) const
       
   860 {
       
   861     return data[0] == v.data[0]
       
   862         && data[1] == v.data[1]
       
   863         && data[2] == v.data[2];
       
   864 }
       
   865 
       
   866 quint32 qargb8555::rawValue() const
       
   867 {
       
   868     return (data[2] << 16) | (data[1] << 8) | data[0];
       
   869 }
       
   870 
       
   871 qargb8555 qargb8555::operator+(qargb8555 v) const
       
   872 {
       
   873     qargb8555 t;
       
   874     t.data[0] = data[0] + v.data[0];
       
   875     const quint16 rgb =  ((data[2] + v.data[2]) << 8)
       
   876                          + (data[1] + v.data[1]);
       
   877     t.data[1] = rgb & 0xff;
       
   878     t.data[2] = rgb >> 8;
       
   879     return t;
       
   880 }
       
   881 
       
   882 qargb8555 qargb8555::byte_mul(quint8 a) const
       
   883 {
       
   884     qargb8555 result;
       
   885     result.data[0] = (data[0] * a) >> 5;
       
   886 
       
   887     const quint16 x = (data[2] << 8) | data[1];
       
   888     quint16 t = (((x & 0x3e0) * a) >> 5) & 0x03e0;
       
   889     t |= (((x & 0x7c1f) * a) >> 5) & 0x7c1f;
       
   890     result.data[1] = t & 0xff;
       
   891     result.data[2] = t >> 8;
       
   892     return result;
       
   893 
       
   894 }
       
   895 
       
   896 class qrgb666;
       
   897 
       
   898 class qargb6666
       
   899 {
       
   900 public:
       
   901     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; }
       
   902 
       
   903     inline qargb6666() {}
       
   904     inline qargb6666(quint32 v) { *this = qargb6666(quint32p(v)); }
       
   905     inline explicit qargb6666(quint32p v);
       
   906     inline qargb6666(const qargb6666 &v);
       
   907     inline qargb6666(const qrgb666 &v);
       
   908 
       
   909     inline operator quint32 () const;
       
   910 
       
   911     inline quint8 alpha() const;
       
   912     inline qargb6666 truncedAlpha() { return *this; }
       
   913     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 2; }
       
   914     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return (255 - a + 1) >> 2; }
       
   915 
       
   916     inline qargb6666 byte_mul(quint8 a) const;
       
   917     inline qargb6666 operator+(qargb6666 v) const;
       
   918     inline bool operator==(const qargb6666 &v) const;
       
   919 
       
   920     inline quint32 rawValue() const;
       
   921 
       
   922 private:
       
   923     friend class qrgb666;
       
   924     quint8 data[3];
       
   925 
       
   926 } Q_PACKED;
       
   927 
       
   928 class qrgb666
       
   929 {
       
   930 public:
       
   931     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
       
   932 
       
   933     inline qrgb666() {}
       
   934     inline qrgb666(quint32 v);
       
   935     inline qrgb666(const qargb6666 &v);
       
   936 
       
   937     inline operator quint32 () const;
       
   938 
       
   939     inline quint8 alpha() const { return 0xff; }
       
   940     inline qrgb666 truncedAlpha() { return *this; }
       
   941     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 2; }
       
   942     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return (255 - a + 1) >> 2; }
       
   943 
       
   944     inline qrgb666 operator+(qrgb666 v) const;
       
   945     inline qrgb666 byte_mul(quint8 a) const;
       
   946 
       
   947     inline bool operator==(const qrgb666 &v) const;
       
   948     inline bool operator!=(const qrgb666 &v) const { return !(*this == v); }
       
   949 
       
   950     inline quint32 rawValue() const
       
   951     {
       
   952         return (data[2] << 16) | (data[1] << 8) | data[0];
       
   953     }
       
   954 
       
   955 private:
       
   956     friend class qargb6666;
       
   957 
       
   958     quint8 data[3];
       
   959 } Q_PACKED;
       
   960 
       
   961 qrgb666::qrgb666(quint32 v)
       
   962 {
       
   963     const uchar b = qBlue(v);
       
   964     const uchar g = qGreen(v);
       
   965     const uchar r = qRed(v);
       
   966     const uint p = (b >> 2) | ((g >> 2) << 6) | ((r >> 2) << 12);
       
   967     data[0] = qBlue(p);
       
   968     data[1] = qGreen(p);
       
   969     data[2] = qRed(p);
       
   970 }
       
   971 
       
   972 qrgb666::qrgb666(const qargb6666 &v)
       
   973 {
       
   974     data[0] = v.data[0];
       
   975     data[1] = v.data[1];
       
   976     data[2] = v.data[2] & 0x03;
       
   977 }
       
   978 
       
   979 qrgb666::operator quint32 () const
       
   980 {
       
   981     const uchar r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3);
       
   982     const uchar g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2);
       
   983     const uchar b = (data[0] << 2) | ((data[0] & 0x3f) >> 4);
       
   984     return qRgb(r, g, b);
       
   985 }
       
   986 
       
   987 qrgb666 qrgb666::operator+(qrgb666 v) const
       
   988 {
       
   989     const quint32 x1 = (data[2] << 16) | (data[1] << 8) | data[0];
       
   990     const quint32 x2 = (v.data[2] << 16) | (v.data[1] << 8) | v.data[0];
       
   991     const quint32 t = x1 + x2;
       
   992     qrgb666 r;
       
   993     r.data[0] = t & 0xff;
       
   994     r.data[1] = (t >> 8) & 0xff;
       
   995     r.data[2] = (t >> 16) & 0xff;
       
   996     return r;
       
   997 }
       
   998 
       
   999 qrgb666 qrgb666::byte_mul(quint8 a) const
       
  1000 {
       
  1001     const quint32 x = (data[2] << 16) | (data[1] << 8) | data[0];
       
  1002     const quint32 t = ((((x & 0x03f03f) * a) >> 6) & 0x03f03f) |
       
  1003                       ((((x & 0x000fc0) * a) >> 6) & 0x000fc0);
       
  1004 
       
  1005     qrgb666 r;
       
  1006     r.data[0] = t & 0xff;
       
  1007     r.data[1] = (t >> 8) & 0xff;
       
  1008     r.data[2] = (t >> 16) & 0xff;
       
  1009     return r;
       
  1010 }
       
  1011 
       
  1012 bool qrgb666::operator==(const qrgb666 &v) const
       
  1013 {
       
  1014     return (data[0] == v.data[0] &&
       
  1015             data[1] == v.data[1] &&
       
  1016             data[2] == v.data[2]);
       
  1017 }
       
  1018 
       
  1019 qargb6666::qargb6666(quint32p v)
       
  1020 {
       
  1021     const quint8 b = qBlue(v) >> 2;
       
  1022     const quint8 g = qGreen(v) >> 2;
       
  1023     const quint8 r = qRed(v) >> 2;
       
  1024     const quint8 a = qAlpha(v) >> 2;
       
  1025     const uint p = (a << 18) | (r << 12) | (g << 6) | b;
       
  1026     data[0] = qBlue(p);
       
  1027     data[1] = qGreen(p);
       
  1028     data[2] = qRed(p);
       
  1029 }
       
  1030 
       
  1031 qargb6666::qargb6666(const qargb6666 &v)
       
  1032 {
       
  1033     data[0] = v.data[0];
       
  1034     data[1] = v.data[1];
       
  1035     data[2] = v.data[2];
       
  1036 }
       
  1037 
       
  1038 qargb6666::qargb6666(const qrgb666 &v)
       
  1039 {
       
  1040     data[0] = v.data[0];
       
  1041     data[1] = v.data[1];
       
  1042     data[2] = (v.data[2] | 0xfc);
       
  1043 }
       
  1044 
       
  1045 qargb6666::operator quint32 () const
       
  1046 {
       
  1047     const quint8 r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3);
       
  1048     const quint8 g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2);
       
  1049     const quint8 b = (data[0] << 2) | ((data[0] & 0x3f) >> 4);
       
  1050     const quint8 a = (data[2] & 0xfc) | (data[2] >> 6);
       
  1051     return qRgba(r, g, b, a);
       
  1052 }
       
  1053 
       
  1054 qargb6666 qargb6666::operator+(qargb6666 v) const
       
  1055 {
       
  1056     const quint32 x1 = (data[2] << 16) | (data[1] << 8) | data[0];
       
  1057     const quint32 x2 = (v.data[2] << 16) | (v.data[1] << 8) | v.data[0];
       
  1058     const quint32 t = x1 + x2;
       
  1059     qargb6666 r;
       
  1060     r.data[0] = t & 0xff;
       
  1061     r.data[1] = (t >> 8) & 0xff;
       
  1062     r.data[2] = (t >> 16) & 0xff;
       
  1063     return r;
       
  1064 }
       
  1065 
       
  1066 quint8 qargb6666::alpha() const
       
  1067 {
       
  1068     return (data[2] & 0xfc) | (data[2] >> 6);
       
  1069 }
       
  1070 
       
  1071 inline qargb6666 qargb6666::byte_mul(quint8 a) const
       
  1072 {
       
  1073     const quint32 x = (data[2] << 16) | (data[1] << 8) | data[0];
       
  1074     const quint32 t = ((((x & 0x03f03f) * a) >> 6) & 0x03f03f) |
       
  1075                       ((((x & 0xfc0fc0) * a) >> 6) & 0xfc0fc0);
       
  1076 
       
  1077     qargb6666 r;
       
  1078     r.data[0] = t & 0xff;
       
  1079     r.data[1] = (t >> 8) & 0xff;
       
  1080     r.data[2] = (t >> 16) & 0xff;
       
  1081     return r;
       
  1082 }
       
  1083 
       
  1084 bool qargb6666::operator==(const qargb6666 &v) const
       
  1085 {
       
  1086     return data[0] == v.data[0]
       
  1087         && data[1] == v.data[1]
       
  1088         && data[2] == v.data[2];
       
  1089 }
       
  1090 
       
  1091 quint32 qargb6666::rawValue() const
       
  1092 {
       
  1093     return (data[2] << 16) | (data[1] << 8) | data[0];
       
  1094 }
       
  1095 
       
  1096 class qrgb888
       
  1097 {
       
  1098 public:
       
  1099     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
       
  1100 
       
  1101     inline qrgb888() {}
       
  1102     inline qrgb888(quint32 v);
       
  1103 
       
  1104     inline operator quint32() const;
       
  1105 
       
  1106     inline quint8 alpha() const { return 0xff; }
       
  1107     inline qrgb888 truncedAlpha() { return *this; }
       
  1108     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return a; }
       
  1109     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 255 - a; }
       
  1110 
       
  1111     inline qrgb888 byte_mul(quint8 a) const;
       
  1112     inline qrgb888 operator+(qrgb888 v) const;
       
  1113     inline bool operator==(qrgb888 v) const;
       
  1114 
       
  1115     inline quint32 rawValue() const;
       
  1116 
       
  1117 private:
       
  1118     uchar data[3];
       
  1119 
       
  1120 } Q_PACKED;
       
  1121 
       
  1122 qrgb888::qrgb888(quint32 v)
       
  1123 {
       
  1124     data[0] = qRed(v);
       
  1125     data[1] = qGreen(v);
       
  1126     data[2] = qBlue(v);
       
  1127 }
       
  1128 
       
  1129 qrgb888::operator quint32() const
       
  1130 {
       
  1131     return qRgb(data[0], data[1], data[2]);
       
  1132 }
       
  1133 
       
  1134 qrgb888 qrgb888::operator+(qrgb888 v) const
       
  1135 {
       
  1136     qrgb888 t = *this;
       
  1137     t.data[0] += v.data[0];
       
  1138     t.data[1] += v.data[1];
       
  1139     t.data[2] += v.data[2];
       
  1140     return t;
       
  1141 }
       
  1142 
       
  1143 qrgb888 qrgb888::byte_mul(quint8 a) const
       
  1144 {
       
  1145     quint32 x(*this);
       
  1146 
       
  1147     quint32 t = (x & 0xff00ff) * a;
       
  1148     t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
       
  1149     t &= 0xff00ff;
       
  1150 
       
  1151     x = ((x >> 8) & 0xff00ff) * a;
       
  1152     x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
       
  1153     x &= 0xff00ff00;
       
  1154     x |= t;
       
  1155     return qrgb888(x);
       
  1156 }
       
  1157 
       
  1158 bool qrgb888::operator==(qrgb888 v) const
       
  1159 {
       
  1160     return (data[0] == v.data[0] &&
       
  1161             data[1] == v.data[1] &&
       
  1162             data[2] == v.data[2]);
       
  1163 }
       
  1164 
       
  1165 quint32 qrgb888::rawValue() const
       
  1166 {
       
  1167     return (data[2] << 16) | (data[1] << 8) | data[0];
       
  1168 }
       
  1169 
       
  1170 template <>
       
  1171 inline qrgb888 qt_colorConvert(quint32 color, qrgb888 dummy)
       
  1172 {
       
  1173     Q_UNUSED(dummy);
       
  1174     return qrgb888(color);
       
  1175 }
       
  1176 
       
  1177 template <>
       
  1178 inline quint32 qt_colorConvert(qrgb888 color, quint32 dummy)
       
  1179 {
       
  1180     Q_UNUSED(dummy);
       
  1181     return quint32(color);
       
  1182 }
       
  1183 
       
  1184 #ifdef QT_QWS_DEPTH_8
       
  1185 template <>
       
  1186 inline quint8 qt_colorConvert(quint32 color, quint8 dummy)
       
  1187 {
       
  1188     Q_UNUSED(dummy);
       
  1189 
       
  1190     uchar r = ((qRed(color) & 0xf8) + 0x19) / 0x33;
       
  1191     uchar g = ((qGreen(color) &0xf8) + 0x19) / 0x33;
       
  1192     uchar b = ((qBlue(color) &0xf8) + 0x19) / 0x33;
       
  1193 
       
  1194     return r*6*6 + g*6 + b;
       
  1195 }
       
  1196 
       
  1197 template <>
       
  1198 inline quint8 qt_colorConvert(quint16 color, quint8 dummy)
       
  1199 {
       
  1200     Q_UNUSED(dummy);
       
  1201 
       
  1202     uchar r = (color & 0xf800) >> (11-3);
       
  1203     uchar g = (color & 0x07c0) >> (6-3);
       
  1204     uchar b = (color & 0x001f) << 3;
       
  1205 
       
  1206     uchar tr = (r + 0x19) / 0x33;
       
  1207     uchar tg = (g + 0x19) / 0x33;
       
  1208     uchar tb = (b + 0x19) / 0x33;
       
  1209 
       
  1210     return tr*6*6 + tg*6 + tb;
       
  1211 }
       
  1212 
       
  1213 #endif // QT_QWS_DEPTH_8
       
  1214 
       
  1215 // hw: endianess??
       
  1216 class quint24
       
  1217 {
       
  1218 public:
       
  1219     inline quint24(quint32 v)
       
  1220     {
       
  1221         data[0] = qBlue(v);
       
  1222         data[1] = qGreen(v);
       
  1223         data[2] = qRed(v);
       
  1224     }
       
  1225 
       
  1226     inline operator quint32 ()
       
  1227     {
       
  1228         return qRgb(data[2], data[1], data[0]);
       
  1229     }
       
  1230 
       
  1231     inline bool operator==(const quint24 &v) const
       
  1232     {
       
  1233         return data[0] == v.data[0]
       
  1234             && data[1] == v.data[1]
       
  1235             && data[2] == v.data[2];
       
  1236     }
       
  1237 
       
  1238 private:
       
  1239     uchar data[3];
       
  1240 } Q_PACKED;
       
  1241 
       
  1242 template <>
       
  1243 inline quint24 qt_colorConvert(quint32 color, quint24 dummy)
       
  1244 {
       
  1245     Q_UNUSED(dummy);
       
  1246     return quint24(color);
       
  1247 }
       
  1248 
       
  1249 // hw: endianess??
       
  1250 class quint18
       
  1251 {
       
  1252 public:
       
  1253     inline quint18(quint32 v)
       
  1254     {
       
  1255         uchar b = qBlue(v);
       
  1256         uchar g = qGreen(v);
       
  1257         uchar r = qRed(v);
       
  1258         uint p = (b >> 2) | ((g >> 2) << 6) | ((r >> 2) << 12);
       
  1259         data[0] = qBlue(p);
       
  1260         data[1] = qGreen(p);
       
  1261         data[2] = qRed(p);
       
  1262     }
       
  1263 
       
  1264     inline operator quint32 ()
       
  1265     {
       
  1266         const uchar r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3);
       
  1267         const uchar g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2);
       
  1268         const uchar b = (data[0] << 2) | ((data[0] & 0x3f) >> 4);
       
  1269         return qRgb(r, g, b);
       
  1270     }
       
  1271 
       
  1272 private:
       
  1273     uchar data[3];
       
  1274 } Q_PACKED;
       
  1275 
       
  1276 template <>
       
  1277 inline quint18 qt_colorConvert(quint32 color, quint18 dummy)
       
  1278 {
       
  1279     Q_UNUSED(dummy);
       
  1280     return quint18(color);
       
  1281 }
       
  1282 
       
  1283 class qrgb444;
       
  1284 
       
  1285 class qargb4444
       
  1286 {
       
  1287 public:
       
  1288     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; }
       
  1289 
       
  1290     inline qargb4444() {}
       
  1291     inline qargb4444(quint32 v) { *this = qargb4444(quint32p(v)); }
       
  1292     inline explicit qargb4444(quint32p v);
       
  1293     inline qargb4444(const qrgb444 &v);
       
  1294 
       
  1295     inline operator quint32() const;
       
  1296     inline operator quint8() const;
       
  1297 
       
  1298     inline qargb4444 operator+(qargb4444 v) const;
       
  1299 
       
  1300     inline quint8 alpha() const { return ((data & 0xf000) >> 8) | ((data & 0xf000) >> 12); }
       
  1301     inline qargb4444 truncedAlpha() { return *this; }
       
  1302     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 4; }
       
  1303     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x10 - alpha(a); }
       
  1304     inline qargb4444 byte_mul(quint8 a) const;
       
  1305 
       
  1306     inline bool operator==(const qargb4444 &v) const { return data == v.data; }
       
  1307 
       
  1308     inline quint16 rawValue() const { return data; }
       
  1309 
       
  1310 private:
       
  1311     friend class qrgb444;
       
  1312     quint16 data;
       
  1313 
       
  1314 } Q_PACKED;
       
  1315 
       
  1316 class qrgb444
       
  1317 {
       
  1318 public:
       
  1319     Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
       
  1320 
       
  1321     inline qrgb444() {}
       
  1322     inline qrgb444(quint32 v);
       
  1323     inline explicit qrgb444(qargb4444 v);
       
  1324 
       
  1325     inline operator quint32() const;
       
  1326     inline operator quint8() const;
       
  1327 
       
  1328     inline qrgb444 operator+(qrgb444 v) const;
       
  1329     inline quint8 alpha() const { return 0xff; }
       
  1330     inline qrgb444 truncedAlpha() { return *this; }
       
  1331     Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 4; }
       
  1332     Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x10 - alpha(a); }
       
  1333     inline qrgb444 byte_mul(quint8 a) const;
       
  1334 
       
  1335     inline bool operator==(const qrgb444 &v) const { return data == v.data; }
       
  1336     inline bool operator!=(const qrgb444 &v) const { return data != v.data; }
       
  1337 
       
  1338     inline quint16 rawValue() const { return data; }
       
  1339 
       
  1340 private:
       
  1341     friend class qargb4444;
       
  1342     quint16 data;
       
  1343 
       
  1344 } Q_PACKED;
       
  1345 
       
  1346 
       
  1347 qargb4444::qargb4444(quint32p color)
       
  1348 {
       
  1349     quint32 v = color;
       
  1350     v &= 0xf0f0f0f0;
       
  1351     const int a = qAlpha(v) << 8;
       
  1352     const int r = qRed(v) << 4;
       
  1353     const int g = qGreen(v);
       
  1354     const int b = qBlue(v) >> 4;
       
  1355 
       
  1356     data = a | r | g | b;
       
  1357 }
       
  1358 
       
  1359 qargb4444::qargb4444(const qrgb444 &v)
       
  1360 {
       
  1361     data = v.data | 0xf000;
       
  1362 }
       
  1363 
       
  1364 qargb4444::operator quint32() const
       
  1365 {
       
  1366     const int a = (data & 0xf000);
       
  1367     const int r = (data & 0x0f00);
       
  1368     const int g = (data & 0x00f0);
       
  1369     const int b = (data & 0x000f);
       
  1370     const int ta = (a >> 8) | (a >> 12);
       
  1371     const int tr = (r >> 4) | (r >> 8);
       
  1372     const int tg = g | (g >> 4);
       
  1373     const int tb = (b << 4) | b;
       
  1374 
       
  1375     return qRgba(tr, tg, tb, ta);
       
  1376 }
       
  1377 
       
  1378 qargb4444::operator quint8() const
       
  1379 {
       
  1380     // hw: optimize!
       
  1381     return qt_colorConvert<quint8, quint32>(operator quint32(), 0);
       
  1382 }
       
  1383 
       
  1384 qargb4444 qargb4444::operator+(qargb4444 v) const
       
  1385 {
       
  1386     qargb4444 t;
       
  1387     t.data = data + v.data;
       
  1388     return t;
       
  1389 }
       
  1390 
       
  1391 qargb4444 qargb4444::byte_mul(quint8 a) const
       
  1392 {
       
  1393     quint16 t = (((data & 0xf0f0) * a) >> 4) & 0xf0f0;
       
  1394     t |= (((data & 0x0f0f) * a) >> 4) & 0x0f0f;
       
  1395 
       
  1396     qargb4444 result;
       
  1397     result.data = t;
       
  1398     return result;
       
  1399 }
       
  1400 
       
  1401 qrgb444::qrgb444(quint32 v)
       
  1402 {
       
  1403     v &= 0xf0f0f0f0;
       
  1404     const int r = qRed(v) << 4;
       
  1405     const int g = qGreen(v);
       
  1406     const int b = qBlue(v) >> 4;
       
  1407 
       
  1408     data = r | g | b;
       
  1409 }
       
  1410 
       
  1411 qrgb444::qrgb444(qargb4444 v)
       
  1412 {
       
  1413     data = v.data & 0x0fff;
       
  1414 }
       
  1415 
       
  1416 qrgb444::operator quint32() const
       
  1417 {
       
  1418     const int r = (data & 0x0f00);
       
  1419     const int g = (data & 0x00f0);
       
  1420     const int b = (data & 0x000f);
       
  1421     const int tr = (r >> 4) | (r >> 8);
       
  1422     const int tg = g | (g >> 4);
       
  1423     const int tb = (b << 4) | b;
       
  1424 
       
  1425     return qRgb(tr, tg, tb);
       
  1426 }
       
  1427 
       
  1428 qrgb444::operator quint8() const
       
  1429 {
       
  1430     // hw: optimize!
       
  1431     return qt_colorConvert<quint8, quint32>(operator quint32(), 0);
       
  1432 }
       
  1433 
       
  1434 qrgb444 qrgb444::operator+(qrgb444 v) const
       
  1435 {
       
  1436     qrgb444 t;
       
  1437     t.data = data + v.data;
       
  1438     return t;
       
  1439 }
       
  1440 
       
  1441 qrgb444 qrgb444::byte_mul(quint8 a) const
       
  1442 {
       
  1443     quint16 t = (((data & 0xf0f0) * a) >> 4) & 0xf0f0;
       
  1444     t |= (((data & 0x0f0f) * a) >> 4) & 0x0f0f;
       
  1445 
       
  1446     qrgb444 result;
       
  1447     result.data = t;
       
  1448     return result;
       
  1449 }
       
  1450 
       
  1451 #ifdef QT_QWS_DEPTH_GENERIC
       
  1452 
       
  1453 struct qrgb
       
  1454 {
       
  1455 public:
       
  1456     static int bpp;
       
  1457     static int len_red;
       
  1458     static int len_green;
       
  1459     static int len_blue;
       
  1460     static int len_alpha;
       
  1461     static int off_red;
       
  1462     static int off_green;
       
  1463     static int off_blue;
       
  1464     static int off_alpha;
       
  1465 } Q_PACKED;
       
  1466 
       
  1467 template <typename SRC>
       
  1468 Q_STATIC_TEMPLATE_FUNCTION inline quint32 qt_convertToRgb(SRC color);
       
  1469 
       
  1470 template <>
       
  1471 inline quint32 qt_convertToRgb(quint32 color)
       
  1472 {
       
  1473     const int r = qRed(color) >> (8 - qrgb::len_red);
       
  1474     const int g = qGreen(color) >> (8 - qrgb::len_green);
       
  1475     const int b = qBlue(color) >> (8 - qrgb::len_blue);
       
  1476     const int a = qAlpha(color) >> (8 - qrgb::len_alpha);
       
  1477     const quint32 v = (r << qrgb::off_red)
       
  1478                       | (g << qrgb::off_green)
       
  1479                       | (b << qrgb::off_blue)
       
  1480                       | (a << qrgb::off_alpha);
       
  1481 
       
  1482     return v;
       
  1483 }
       
  1484 
       
  1485 template <>
       
  1486 inline quint32 qt_convertToRgb(quint16 color)
       
  1487 {
       
  1488     return qt_convertToRgb(qt_colorConvert<quint32, quint16>(color, 0));
       
  1489 }
       
  1490 
       
  1491 class qrgb_generic16
       
  1492 {
       
  1493 public:
       
  1494     inline qrgb_generic16(quint32 color)
       
  1495     {
       
  1496         const int r = qRed(color) >> (8 - qrgb::len_red);
       
  1497         const int g = qGreen(color) >> (8 - qrgb::len_green);
       
  1498         const int b = qBlue(color) >> (8 - qrgb::len_blue);
       
  1499         const int a = qAlpha(color) >> (8 - qrgb::len_alpha);
       
  1500         data = (r << qrgb::off_red)
       
  1501                | (g << qrgb::off_green)
       
  1502                | (b << qrgb::off_blue)
       
  1503                | (a << qrgb::off_alpha);
       
  1504     }
       
  1505 
       
  1506     inline operator quint16 () { return data; }
       
  1507     inline quint32 operator<<(int shift) const { return data << shift; }
       
  1508 
       
  1509 private:
       
  1510     quint16 data;
       
  1511 } Q_PACKED;
       
  1512 
       
  1513 template <>
       
  1514 inline qrgb_generic16 qt_colorConvert(quint32 color, qrgb_generic16 dummy)
       
  1515 {
       
  1516     Q_UNUSED(dummy);
       
  1517     return qrgb_generic16(color);
       
  1518 }
       
  1519 
       
  1520 template <>
       
  1521 inline qrgb_generic16 qt_colorConvert(quint16 color, qrgb_generic16 dummy)
       
  1522 {
       
  1523     Q_UNUSED(dummy);
       
  1524     return qrgb_generic16(qt_colorConvert<quint32, quint16>(color, 0));
       
  1525 }
       
  1526 
       
  1527 #endif // QT_QWS_DEPTH_GENERIC
       
  1528 
       
  1529 template <class T>
       
  1530 void qt_memfill(T *dest, T value, int count);
       
  1531 
       
  1532 template<> inline void qt_memfill(quint32 *dest, quint32 color, int count)
       
  1533 {
       
  1534     extern void (*qt_memfill32)(quint32 *dest, quint32 value, int count);
       
  1535     qt_memfill32(dest, color, count);
       
  1536 }
       
  1537 
       
  1538 template<> inline void qt_memfill(quint16 *dest, quint16 color, int count)
       
  1539 {
       
  1540     extern void (*qt_memfill16)(quint16 *dest, quint16 value, int count);
       
  1541     qt_memfill16(dest, color, count);
       
  1542 }
       
  1543 
       
  1544 template<> inline void qt_memfill(quint8 *dest, quint8 color, int count)
       
  1545 {
       
  1546     memset(dest, color, count);
       
  1547 }
       
  1548 
       
  1549 template <class T>
       
  1550 inline void qt_memfill(T *dest, T value, int count)
       
  1551 {
       
  1552     int n = (count + 7) / 8;
       
  1553     switch (count & 0x07)
       
  1554     {
       
  1555     case 0: do { *dest++ = value;
       
  1556     case 7:      *dest++ = value;
       
  1557     case 6:      *dest++ = value;
       
  1558     case 5:      *dest++ = value;
       
  1559     case 4:      *dest++ = value;
       
  1560     case 3:      *dest++ = value;
       
  1561     case 2:      *dest++ = value;
       
  1562     case 1:      *dest++ = value;
       
  1563     } while (--n > 0);
       
  1564     }
       
  1565 }
       
  1566 
       
  1567 template <class T>
       
  1568 inline void qt_rectfill(T *dest, T value,
       
  1569                         int x, int y, int width, int height, int stride)
       
  1570 {
       
  1571     char *d = reinterpret_cast<char*>(dest + x) + y * stride;
       
  1572     if (uint(stride) == (width * sizeof(T))) {
       
  1573         qt_memfill(reinterpret_cast<T*>(d), value, width * height);
       
  1574     } else {
       
  1575         for (int j = 0; j < height; ++j) {
       
  1576             dest = reinterpret_cast<T*>(d);
       
  1577             qt_memfill(dest, value, width);
       
  1578             d += stride;
       
  1579         }
       
  1580     }
       
  1581 }
       
  1582 
       
  1583 template <class DST, class SRC>
       
  1584 inline void qt_memconvert(DST *dest, const SRC *src, int count)
       
  1585 {
       
  1586     if (sizeof(DST) == 1) {
       
  1587         while (count) {
       
  1588             int n = 1;
       
  1589             const SRC color = *src++;
       
  1590             const DST dstColor = qt_colorConvert<DST, SRC>(color, 0);
       
  1591             while (--count && (*src == color || dstColor == qt_colorConvert<DST, SRC>(*src, 0))) {
       
  1592                 ++n;
       
  1593                 ++src;
       
  1594             }
       
  1595             qt_memfill(dest, dstColor, n);
       
  1596             dest += n;
       
  1597         }
       
  1598     } else {
       
  1599         /* Duff's device */
       
  1600         int n = (count + 7) / 8;
       
  1601         switch (count & 0x07)
       
  1602         {
       
  1603         case 0: do { *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
       
  1604             case 7:      *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
       
  1605             case 6:      *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
       
  1606             case 5:      *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
       
  1607             case 4:      *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
       
  1608             case 3:      *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
       
  1609             case 2:      *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
       
  1610             case 1:      *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
       
  1611             } while (--n > 0);
       
  1612         }
       
  1613     }
       
  1614 }
       
  1615 
       
  1616 #define QT_TRIVIAL_MEMCONVERT_IMPL(T) \
       
  1617     template <> \
       
  1618     inline void qt_memconvert(T *dest, const T *src, int count) \
       
  1619     { \
       
  1620         memcpy(dest, src, count * sizeof(T)); \
       
  1621     }
       
  1622 QT_TRIVIAL_MEMCONVERT_IMPL(quint32)
       
  1623 QT_TRIVIAL_MEMCONVERT_IMPL(qrgb888)
       
  1624 QT_TRIVIAL_MEMCONVERT_IMPL(qargb6666)
       
  1625 QT_TRIVIAL_MEMCONVERT_IMPL(qrgb666)
       
  1626 QT_TRIVIAL_MEMCONVERT_IMPL(quint16)
       
  1627 #ifdef Q_WS_QWS
       
  1628 QT_TRIVIAL_MEMCONVERT_IMPL(qrgb565)
       
  1629 #endif
       
  1630 QT_TRIVIAL_MEMCONVERT_IMPL(qargb8565)
       
  1631 QT_TRIVIAL_MEMCONVERT_IMPL(qargb8555)
       
  1632 QT_TRIVIAL_MEMCONVERT_IMPL(qrgb555)
       
  1633 QT_TRIVIAL_MEMCONVERT_IMPL(qargb4444)
       
  1634 QT_TRIVIAL_MEMCONVERT_IMPL(qrgb444)
       
  1635 #undef QT_TRIVIAL_MEMCONVERT_IMPL
       
  1636 
       
  1637 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
       
  1638 template <>
       
  1639 inline void qt_memconvert(qrgb666 *dest, const quint32 *src, int count)
       
  1640 {
       
  1641     if (count < 3) {
       
  1642         switch (count) {
       
  1643         case 2: *dest++ = qrgb666(*src++);
       
  1644         case 1: *dest = qrgb666(*src);
       
  1645         }
       
  1646         return;
       
  1647     }
       
  1648 
       
  1649     const int align = (long(dest) & 3);
       
  1650     switch (align) {
       
  1651     case 1: *dest++ = qrgb666(*src++); --count;
       
  1652     case 2: *dest++ = qrgb666(*src++); --count;
       
  1653     case 3: *dest++ = qrgb666(*src++); --count;
       
  1654     }
       
  1655 
       
  1656     quint32 *dest32 = reinterpret_cast<quint32*>(dest);
       
  1657     int sourceCount = count >> 2;
       
  1658     while (sourceCount--) {
       
  1659         dest32[0] = ((src[1] & 0x00000c00) << 20)
       
  1660                     | ((src[1] & 0x000000fc) << 22)
       
  1661                     | ((src[0] & 0x00fc0000) >> 6)
       
  1662                     | ((src[0] & 0x0000fc00) >> 4)
       
  1663                     |  ((src[0] & 0x000000fc) >> 2);
       
  1664         dest32[1] = ((src[2] & 0x003c0000) << 10)
       
  1665                     | ((src[2] & 0x0000fc00) << 12)
       
  1666                     | ((src[2] & 0x000000fc) << 14)
       
  1667                     | ((src[1] & 0x00fc0000) >> 14)
       
  1668                     | ((src[1] & 0x0000f000) >> 12);
       
  1669         dest32[2] = ((src[3] & 0x00fc0000) << 2)
       
  1670                     | ((src[3] & 0x0000fc00) << 4)
       
  1671                     | ((src[3] & 0x000000fc) << 6)
       
  1672                     | ((src[2] & 0x00c00000) >> 22);
       
  1673         dest32 += 3;
       
  1674         src += 4;
       
  1675     }
       
  1676 
       
  1677     dest = reinterpret_cast<qrgb666*>(dest32);
       
  1678     switch (count & 3) {
       
  1679     case 3: *dest++ = qrgb666(*src++);
       
  1680     case 2: *dest++ = qrgb666(*src++);
       
  1681     case 1: *dest = qrgb666(*src);
       
  1682     }
       
  1683 }
       
  1684 #endif // Q_BYTE_ORDER
       
  1685 
       
  1686 template <class T>
       
  1687 inline void qt_rectcopy(T *dest, const T *src,
       
  1688                         int x, int y, int width, int height,
       
  1689                         int dstStride, int srcStride)
       
  1690 {
       
  1691     char *d = (char*)(dest + x) + y * dstStride;
       
  1692     const char *s = (char*)(src);
       
  1693     for (int i = 0; i < height; ++i) {
       
  1694         ::memcpy(d, s, width * sizeof(T));
       
  1695         d += dstStride;
       
  1696         s += srcStride;
       
  1697     }
       
  1698 }
       
  1699 
       
  1700 template <class DST, class SRC>
       
  1701 inline void qt_rectconvert(DST *dest, const SRC *src,
       
  1702                            int x, int y, int width, int height,
       
  1703                            int dstStride, int srcStride)
       
  1704 {
       
  1705     char *d = (char*)(dest + x) + y * dstStride;
       
  1706     const char *s = (char*)(src);
       
  1707     for (int i = 0; i < height; ++i) {
       
  1708         qt_memconvert<DST,SRC>((DST*)d, (const SRC*)s, width);
       
  1709         d += dstStride;
       
  1710         s += srcStride;
       
  1711     }
       
  1712 }
       
  1713 
       
  1714 #define QT_RECTCONVERT_TRIVIAL_IMPL(T)                                  \
       
  1715     template <>                                                         \
       
  1716     inline void qt_rectconvert(T *dest, const T *src,                   \
       
  1717                                int x, int y, int width, int height,     \
       
  1718                                int dstStride, int srcStride)            \
       
  1719     {                                                                   \
       
  1720         qt_rectcopy(dest, src, x, y, width, height, dstStride, srcStride); \
       
  1721     }
       
  1722 QT_RECTCONVERT_TRIVIAL_IMPL(quint32)
       
  1723 QT_RECTCONVERT_TRIVIAL_IMPL(qrgb888)
       
  1724 QT_RECTCONVERT_TRIVIAL_IMPL(qargb6666)
       
  1725 QT_RECTCONVERT_TRIVIAL_IMPL(qrgb666)
       
  1726 #ifdef Q_WS_QWS
       
  1727 QT_RECTCONVERT_TRIVIAL_IMPL(qrgb565)
       
  1728 #endif
       
  1729 QT_RECTCONVERT_TRIVIAL_IMPL(qargb8565)
       
  1730 QT_RECTCONVERT_TRIVIAL_IMPL(quint16)
       
  1731 QT_RECTCONVERT_TRIVIAL_IMPL(qargb8555)
       
  1732 QT_RECTCONVERT_TRIVIAL_IMPL(qrgb555)
       
  1733 QT_RECTCONVERT_TRIVIAL_IMPL(qargb4444)
       
  1734 QT_RECTCONVERT_TRIVIAL_IMPL(qrgb444)
       
  1735 #undef QT_RECTCONVERT_TRIVIAL_IMPL
       
  1736 
       
  1737 #ifdef QT_QWS_DEPTH_GENERIC
       
  1738 template <> void qt_rectconvert(qrgb *dest, const quint32 *src,
       
  1739                                 int x, int y, int width, int height,
       
  1740                                 int dstStride, int srcStride);
       
  1741 
       
  1742 template <> void qt_rectconvert(qrgb *dest, const quint16 *src,
       
  1743                                 int x, int y, int width, int height,
       
  1744                                 int dstStride, int srcStride);
       
  1745 #endif // QT_QWS_DEPTH_GENERIC
       
  1746 
       
  1747 #define QT_MEMFILL_UINT(dest, length, color)            \
       
  1748     qt_memfill<quint32>(dest, color, length);
       
  1749 
       
  1750 #define QT_MEMFILL_USHORT(dest, length, color) \
       
  1751     qt_memfill<quint16>(dest, color, length);
       
  1752 
       
  1753 #define QT_MEMCPY_REV_UINT(dest, src, length) \
       
  1754 do {                                          \
       
  1755     /* Duff's device */                       \
       
  1756     uint *_d = (uint*)(dest) + length;         \
       
  1757     const uint *_s = (uint*)(src) + length;    \
       
  1758     register int n = ((length) + 7) / 8;      \
       
  1759     switch ((length) & 0x07)                  \
       
  1760     {                                         \
       
  1761     case 0: do { *--_d = *--_s;                 \
       
  1762     case 7:      *--_d = *--_s;                 \
       
  1763     case 6:      *--_d = *--_s;                 \
       
  1764     case 5:      *--_d = *--_s;                 \
       
  1765     case 4:      *--_d = *--_s;                 \
       
  1766     case 3:      *--_d = *--_s;                 \
       
  1767     case 2:      *--_d = *--_s;                 \
       
  1768     case 1:      *--_d = *--_s;                 \
       
  1769     } while (--n > 0);                        \
       
  1770     }                                         \
       
  1771 } while (0)
       
  1772 
       
  1773 #define QT_MEMCPY_USHORT(dest, src, length) \
       
  1774 do {                                          \
       
  1775     /* Duff's device */                       \
       
  1776     ushort *_d = (ushort*)(dest);         \
       
  1777     const ushort *_s = (ushort*)(src);    \
       
  1778     register int n = ((length) + 7) / 8;      \
       
  1779     switch ((length) & 0x07)                  \
       
  1780     {                                         \
       
  1781     case 0: do { *_d++ = *_s++;                 \
       
  1782     case 7:      *_d++ = *_s++;                 \
       
  1783     case 6:      *_d++ = *_s++;                 \
       
  1784     case 5:      *_d++ = *_s++;                 \
       
  1785     case 4:      *_d++ = *_s++;                 \
       
  1786     case 3:      *_d++ = *_s++;                 \
       
  1787     case 2:      *_d++ = *_s++;                 \
       
  1788     case 1:      *_d++ = *_s++;                 \
       
  1789     } while (--n > 0);                        \
       
  1790     }                                         \
       
  1791 } while (0)
       
  1792 
       
  1793 #if defined(Q_CC_RVCT)
       
  1794 #  pragma push
       
  1795 #  pragma arm
       
  1796 #endif
       
  1797 Q_STATIC_INLINE_FUNCTION int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
       
  1798 #if defined(Q_CC_RVCT)
       
  1799 #  pragma pop
       
  1800 #endif
       
  1801 
       
  1802 inline ushort qConvertRgb32To16(uint c)
       
  1803 {
       
  1804    return (((c) >> 3) & 0x001f)
       
  1805        | (((c) >> 5) & 0x07e0)
       
  1806        | (((c) >> 8) & 0xf800);
       
  1807 }
       
  1808 
       
  1809 #if defined(Q_WS_QWS) || (QT_VERSION >= 0x040400)
       
  1810 inline quint32 qConvertRgb32To16x2(quint64 c)
       
  1811 {
       
  1812     c = (((c) >> 3) & Q_UINT64_C(0x001f0000001f))
       
  1813         | (((c) >> 5) & Q_UINT64_C(0x07e0000007e0))
       
  1814         | (((c) >> 8) & Q_UINT64_C(0xf8000000f800));
       
  1815     return c | (c >> 16);
       
  1816 }
       
  1817 #endif
       
  1818 
       
  1819 inline QRgb qConvertRgb16To32(uint c)
       
  1820 {
       
  1821     return 0xff000000
       
  1822         | ((((c) << 3) & 0xf8) | (((c) >> 2) & 0x7))
       
  1823         | ((((c) << 5) & 0xfc00) | (((c) >> 1) & 0x300))
       
  1824         | ((((c) << 8) & 0xf80000) | (((c) << 3) & 0x70000));
       
  1825 }
       
  1826 
       
  1827 inline int qRed565(quint16 rgb) {
       
  1828     const int r = (rgb & 0xf800);
       
  1829     return (r >> 8) | (r >> 13);
       
  1830 }
       
  1831 
       
  1832 inline int qGreen565(quint16 rgb) {
       
  1833     const int g = (rgb & 0x07e0);
       
  1834     return (g >> 3) | (g >> 9);
       
  1835 }
       
  1836 
       
  1837 inline int qBlue565(quint16 rgb) {
       
  1838     const int b = (rgb & 0x001f);
       
  1839     return (b << 3) | (b >> 2);
       
  1840 }
       
  1841 
       
  1842 #if 1
       
  1843 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
       
  1844     uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
       
  1845     t >>= 8;
       
  1846     t &= 0xff00ff;
       
  1847 
       
  1848     x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
       
  1849     x &= 0xff00ff00;
       
  1850     x |= t;
       
  1851     return x;
       
  1852 }
       
  1853 
       
  1854 #if defined(Q_CC_RVCT)
       
  1855 #  pragma push
       
  1856 #  pragma arm
       
  1857 #endif
       
  1858 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) {
       
  1859     uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
       
  1860     t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
       
  1861     t &= 0xff00ff;
       
  1862 
       
  1863     x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
       
  1864     x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
       
  1865     x &= 0xff00ff00;
       
  1866     x |= t;
       
  1867     return x;
       
  1868 }
       
  1869 #if defined(Q_CC_RVCT)
       
  1870 #  pragma pop
       
  1871 #endif
       
  1872 #else
       
  1873 // possible implementation for 64 bit
       
  1874 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
       
  1875     ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
       
  1876     t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b;
       
  1877     t >>= 8;
       
  1878     t &= 0x00ff00ff00ff00ff;
       
  1879     return (uint(t)) | (uint(t >> 24));
       
  1880 }
       
  1881 
       
  1882 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) {
       
  1883     ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
       
  1884     t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b;
       
  1885     t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);
       
  1886     t &= 0x00ff00ff00ff00ff;
       
  1887     return (uint(t)) | (uint(t >> 24));
       
  1888 }
       
  1889 
       
  1890 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) {
       
  1891     ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
       
  1892     t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);
       
  1893     t &= 0x00ff00ff00ff00ff;
       
  1894     return (uint(t)) | (uint(t >> 24));
       
  1895 }
       
  1896 
       
  1897 Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) {
       
  1898     uint a = x >> 24;
       
  1899     ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
       
  1900     t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);
       
  1901     t &= 0x00ff00ff00ff00ff;
       
  1902     return (uint(t)) | (uint(t >> 24)) | 0xff000000;
       
  1903 }
       
  1904 #endif
       
  1905 
       
  1906 const uint qt_bayer_matrix[16][16] = {
       
  1907     { 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
       
  1908       0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},
       
  1909     { 0x80, 0x40, 0xb0, 0x70, 0x8c, 0x4c, 0xbc, 0x7c,
       
  1910       0x83, 0x43, 0xb3, 0x73, 0x8f, 0x4f, 0xbf, 0x7f},
       
  1911     { 0x20, 0xe0, 0x10, 0xd0, 0x2c, 0xec, 0x1c, 0xdc,
       
  1912       0x23, 0xe3, 0x13, 0xd3, 0x2f, 0xef, 0x1f, 0xdf},
       
  1913     { 0xa0, 0x60, 0x90, 0x50, 0xac, 0x6c, 0x9c, 0x5c,
       
  1914       0xa3, 0x63, 0x93, 0x53, 0xaf, 0x6f, 0x9f, 0x5f},
       
  1915     { 0x8, 0xc8, 0x38, 0xf8, 0x4, 0xc4, 0x34, 0xf4,
       
  1916       0xb, 0xcb, 0x3b, 0xfb, 0x7, 0xc7, 0x37, 0xf7},
       
  1917     { 0x88, 0x48, 0xb8, 0x78, 0x84, 0x44, 0xb4, 0x74,
       
  1918       0x8b, 0x4b, 0xbb, 0x7b, 0x87, 0x47, 0xb7, 0x77},
       
  1919     { 0x28, 0xe8, 0x18, 0xd8, 0x24, 0xe4, 0x14, 0xd4,
       
  1920       0x2b, 0xeb, 0x1b, 0xdb, 0x27, 0xe7, 0x17, 0xd7},
       
  1921     { 0xa8, 0x68, 0x98, 0x58, 0xa4, 0x64, 0x94, 0x54,
       
  1922       0xab, 0x6b, 0x9b, 0x5b, 0xa7, 0x67, 0x97, 0x57},
       
  1923     { 0x2, 0xc2, 0x32, 0xf2, 0xe, 0xce, 0x3e, 0xfe,
       
  1924       0x1, 0xc1, 0x31, 0xf1, 0xd, 0xcd, 0x3d, 0xfd},
       
  1925     { 0x82, 0x42, 0xb2, 0x72, 0x8e, 0x4e, 0xbe, 0x7e,
       
  1926       0x81, 0x41, 0xb1, 0x71, 0x8d, 0x4d, 0xbd, 0x7d},
       
  1927     { 0x22, 0xe2, 0x12, 0xd2, 0x2e, 0xee, 0x1e, 0xde,
       
  1928       0x21, 0xe1, 0x11, 0xd1, 0x2d, 0xed, 0x1d, 0xdd},
       
  1929     { 0xa2, 0x62, 0x92, 0x52, 0xae, 0x6e, 0x9e, 0x5e,
       
  1930       0xa1, 0x61, 0x91, 0x51, 0xad, 0x6d, 0x9d, 0x5d},
       
  1931     { 0xa, 0xca, 0x3a, 0xfa, 0x6, 0xc6, 0x36, 0xf6,
       
  1932       0x9, 0xc9, 0x39, 0xf9, 0x5, 0xc5, 0x35, 0xf5},
       
  1933     { 0x8a, 0x4a, 0xba, 0x7a, 0x86, 0x46, 0xb6, 0x76,
       
  1934       0x89, 0x49, 0xb9, 0x79, 0x85, 0x45, 0xb5, 0x75},
       
  1935     { 0x2a, 0xea, 0x1a, 0xda, 0x26, 0xe6, 0x16, 0xd6,
       
  1936       0x29, 0xe9, 0x19, 0xd9, 0x25, 0xe5, 0x15, 0xd5},
       
  1937     { 0xaa, 0x6a, 0x9a, 0x5a, 0xa6, 0x66, 0x96, 0x56,
       
  1938       0xa9, 0x69, 0x99, 0x59, 0xa5, 0x65, 0x95, 0x55}
       
  1939 };
       
  1940 
       
  1941 #define ARGB_COMBINE_ALPHA(argb, alpha) \
       
  1942     ((((argb >> 24) * alpha) >> 8) << 24) | (argb & 0x00ffffff)
       
  1943 
       
  1944 
       
  1945 QT_END_NAMESPACE
       
  1946 
       
  1947 #endif // QDRAWHELPER_P_H