javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/library/graphics/qt/pixmap.cpp
changeset 80 d6dafc5d983f
parent 57 59b3b4473dc8
--- a/javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/library/graphics/qt/pixmap.cpp	Mon Oct 04 11:29:25 2010 +0300
+++ b/javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/library/graphics/qt/pixmap.cpp	Fri Oct 15 12:29:39 2010 +0300
@@ -14,18 +14,18 @@
 
 namespace Java { namespace GFX {
 
-Pixmap::Pixmap() : mAlpha(-1), mHasMask(false)
-{
+Pixmap::Pixmap() : ImageBase()
+    {
     GFX_LOG_FUNC_CALL();
-}
+    }
 
 Pixmap::~Pixmap()
-{
+    {
     GFX_LOG_FUNC_CALL();
-}
+    }
 
 void Pixmap::createBySize(int aWidth, int aHeight, int aFillColor, TImageFormat /*aFormat*/)
-{
+    {
     GFX_LOG_FUNC_CALL();
     Q_ASSERT(mPixmap.isNull());
 
@@ -34,19 +34,19 @@
 
     // Check if creation was successful
     if(mPixmap.isNull())
-    {
+        {
         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
-    }
+        }
 
     // Finally fill with given fillColor, also clears the image mem area
     // otherwise there might be some random coloured pixels in image
     QColor color;
     color.setRgb(aFillColor);
     mPixmap.fill(color);
-}
+    }
 
 void Pixmap::createFromQImage(const QImage& aImage)
-{
+    {
     GFX_LOG_FUNC_CALL();
     Q_ASSERT(mPixmap.isNull());
 
@@ -55,13 +55,13 @@
 
     // Validate allocation
     if(mPixmap.isNull())
-    {
+        {
         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
+        }
     }
-}
 
 void Pixmap::createFromQPixmap(const QPixmap& aPixmap)
-{
+    {
     GFX_LOG_FUNC_CALL();
     Q_ASSERT(mPixmap.isNull());
 
@@ -69,150 +69,63 @@
 
     // Validate allocation
     if(mPixmap.isNull())
-    {
+        {
         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
-    }
-}
-
-void Pixmap::createFromImage(Image* aImage, int aX, int aY, int aWidth, int aHeight)
-{
-    GFX_LOG_FUNC_CALL();
-    Q_ASSERT(mPixmap.isNull());
-
-    // Get QPixmap from original
-    QPixmap* src = aImage->getPixmap();
-    if(!src)
-    {
-        throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed");
+        }
     }
 
-    // If specific values were given and they represent the whole pixmap exactly
-    bool isWholePixmap = (src->size() == QSize(aWidth, aHeight)) && (aX == aY == 0);
-
-    // Also an empty area means that the whole pixmap needs to be copied
-    bool isEmptyArea = QRect(aX, aY, aWidth, aHeight).isEmpty();
-
-    if( isWholePixmap || isEmptyArea )
-    {
-        // Assign to our copy using implicit sharing
-        mPixmap = *src;
-    }
-    else
+void Pixmap::createFromImage(Image* aImage, int aX, int aY, int aWidth, int aHeight)
     {
-        // Convert to QImage, copy the pixel data area, convert back to QPixmap
-        mPixmap = src->copy(aX, aY, aWidth, aHeight);
-    }
-
-    if(mPixmap.isNull())
-    {
-        throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed");
-    }
-}
-
-void Pixmap::createFromImageData(ImageDataWrapper* aData)
-{
     GFX_LOG_FUNC_CALL();
     Q_ASSERT(mPixmap.isNull());
 
-    if(aData->getDepth() != 32)
-    {
-        // Java side always converts the ImageData to 32 bit before passing it
-        // to native side, bail out if we get something else
-        throw GfxException(EGfxErrorNoMemory, "Only 32 bit ImageData is supported in Image creation");
-    }
-
-    int bpp = 4; // bit depth = 32, 4 bytes per pixel
-    int size = aData->getWidth()*aData->getHeight()*bpp;
-    char* pixelData = aData->getData(ImageDataWrapper::EPixelData);
-
-    for(int index = 0; index < size; index += bpp)
-    {
-        int pixel = *(reinterpret_cast<int*>(pixelData+index));
-
-        pixelData[index]   = (uchar)(pixel >> 24) & 0xFF;
-        pixelData[index+1] = (uchar)(pixel >> 16) & 0xFF;
-        pixelData[index+2] = (uchar)(pixel >> 8) & 0xFF;
-        pixelData[index+3] = 0xFF; // Set alpha to opaque here, alpha channel data will be handled later
-    }
-
-    QImage image(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EPixelData)),
-                                          aData->getWidth(),
-                                          aData->getHeight(),
-                                          aData->getBytesPerLine(),
-                                          QImage::Format_ARGB32);
-    if(image.isNull())
-  {
-    throw GfxException(EGfxErrorNoMemory, "QImage (Pixmap) creation failed");
-    }
-
-    // Set indexed palette (if one is set)
-    if(!aData->isDirect())
-    {
-        image.setColorTable(*aData->getPaletteData()->getIndexedPalette());
+    // Check if the copy should be exactly same as the original
+    if((aImage->getWidth() == aWidth) && (aImage->getHeight() == aHeight) || 
+        QRect(aX, aY, aWidth, aHeight).isEmpty())
+        {
+        mPixmap = aImage->toPixmap();
+        }
+    // it's needed to make partial copy of the original
+    else
+        {
+        switch(aImage->type())
+            {
+            case EImage:
+                {
+                mPixmap = QPixmap::fromImage(aImage->getConstImage()->copy(aX, aY, aWidth, aHeight));
+                break;
+                }
+            case EPixmap:
+                {
+                mPixmap = aImage->getConstPixmap()->copy(aX, aY, aWidth, aHeight);
+                break;
+                }
+            default:
+                throw GfxException(EGfxErrorIllegalArgument, "Unsupported source image type");
+            }
+        
+        }
+    if(mPixmap.isNull())
+        {
+        throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed");
+        }
     }
 
-    mHasMask = false;
-    mAlpha = aData->getAlpha();
-
-    if(aData->getData(ImageDataWrapper::EMaskData))
+void Pixmap::createFromImageData(ImageDataWrapper* aData)
     {
-        QImage mask(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EMaskData)),
-                                             aData->getWidth(),
-                                             aData->getHeight(),
-                                             QImage::Format_Mono);
-        if(mask.isNull())
-      {
-        throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed");
-        }
-        image.setAlphaChannel(mask);
-        mHasMask = true;
-    }
-    else if(mAlpha != -1)
-    {
-        // Global alpha is set, overrides alpha channel data
-        QImage alpha(aData->getWidth(), aData->getHeight(), QImage::Format_Indexed8);
-        if(alpha.isNull())
-      {
-        throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed");
-        }
+    GFX_LOG_FUNC_CALL();
+    Q_ASSERT(mPixmap.isNull());
 
-        alpha.fill(aData->getAlpha());
-        image.setAlphaChannel(alpha);
-    }
-    else if(aData->getData(ImageDataWrapper::EAlphaData))
-    {
-        // Alpha channel data is set
-        const int w = aData->getWidth();
-        QImage alpha(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EAlphaData)),
-                                              w,
-                                              aData->getHeight(),
-                                              w,
-                                              QImage::Format_Indexed8);
-        QVector<QRgb> colors(255);
-        for(int i=0; i<255; i++)
-            {
-            colors[i] = qRgb(i, i, i);
-            }
-        alpha.setColorTable(colors);
-        colors.clear();
+    mPixmap = QPixmap::fromImage(imageDataToQImage(aData));
 
-        if(alpha.isNull())
-      {
-        throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed");
+    if(mPixmap.isNull())
+        {
+        throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
         }
-        image.setAlphaChannel(alpha);
     }
 
-    mPixmap = QPixmap::fromImage(image);
-
-    if(mPixmap.isNull())
+void Pixmap::createFromRGB(int* aRgbdata, int aWidth, int aHeight, bool aHasAlpha)
     {
-        throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
-    }
-}
-
-void Pixmap::createFromRGB(int* aRgbdata, int aWidth, int aHeight, bool aHasAlpha)
-{
     GFX_LOG_FUNC_CALL();
     Q_ASSERT(mPixmap.isNull());
 
@@ -222,96 +135,82 @@
 
     // Validate creation
     if(tmpImage.isNull())
-    {
+        {
         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
-    }
+        }
 
     // Store as QPixmap
     mPixmap = QPixmap::fromImage(tmpImage);
 
     // Validate conversion
     if(mPixmap.isNull())
-    {
+        {
         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
+        }
     }
-}
 
 void Pixmap::dispose()
-{
+    {
     GFX_LOG_FUNC_CALL();
     delete this;
-}
+    }
 
 QPaintDevice* Pixmap::getBindable()
-{
+    {
     GFX_LOG_FUNC_CALL();
     return static_cast<QPaintDevice*>(&mPixmap);
-}
+    }
 
-int Pixmap::getFormat()
-{
+TImageFormat Pixmap::getFormat()
+    {
     GFX_LOG_FUNC_CALL();
     QImage img = mPixmap.toImage();
     // Validate conversion
-    if(img.isNull()) {
+    if(img.isNull()) 
+        {
         throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed");
+        }
+    return mapQtFormatToInternal(img.format());
     }
-    int imgFormat = img.format();
-
-    switch (imgFormat) {
-        case QImage::Format_ARGB32:
-            return EFormatARGB32;
-        case QImage::Format_RGB32:
-            return EFormatRGB32;
-        case QImage::Format_ARGB32_Premultiplied:
-            return EFormatARGB32Premultiplied;
-         case QImage::Format_RGB16:
-            return EFormatRGB16;
-         case QImage::Format_RGB555:
-            return EFormatRGB555;
-         case QImage::Format_RGB444:
-            return EFormatRGB444;
-         case QImage::Format_ARGB4444_Premultiplied:
-            return EFormatARGB4444Premultiplied;
-         case QImage::Format_Mono:
-            return EFormatMONO;
-         default:
-            return EFormatNone;
-    }
-}
 
 int Pixmap::getHeight()
-{
+    {
     GFX_LOG_FUNC_CALL();
     return mPixmap.height();
-}
+    }
+
+const QImage* Pixmap::getConstImage()
+    {
+    GFX_LOG_FUNC_CALL();
+    return NULL;
+    }
+
+QImage* Pixmap::getImage()
+    {
+    GFX_LOG_FUNC_CALL();
+    return NULL;
+    }
+
+const QPixmap* Pixmap::getConstPixmap()
+    {
+    GFX_LOG_FUNC_CALL();
+    return &mPixmap;
+    }
 
 QPixmap* Pixmap::getPixmap()
-{
+    {
     GFX_LOG_FUNC_CALL();
     return &mPixmap;
-}
+    }
 
 int Pixmap::getWidth()
-{
+    {
     GFX_LOG_FUNC_CALL();
     return mPixmap.width();
-}
-
-int Pixmap::getAlpha()
-{
-    GFX_LOG_FUNC_CALL();
-    return mAlpha;
-}
-
-bool Pixmap::hasMask()
-{
-    GFX_LOG_FUNC_CALL();
-    return mHasMask;
-}
+    }
 
 void Pixmap::getRgb(int* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight)
-{
+    {
     GFX_LOG_FUNC_CALL();
 
     // Convert to QImage in order to access pixels
@@ -322,61 +221,11 @@
         {
         throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed");
         }
-
-    if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height())
-        {
-        image = image.copy(aX, aY, aWidth, aHeight);
-        if(image.isNull())
-            {
-            throw GfxException(EGfxErrorNoMemory, "copying from original image failed");
-            }
-        }
+    doGetRgb(image, aRgbdata, aOffset, aScanlength, aX, aY, aWidth, aHeight);
+    }
 
 
-    // If image is not 32bpp we need to convert it
-    if(image.format() != QImage::Format_RGB32 &&
-       image.format() != QImage::Format_ARGB32)
-        {
-        image = image.convertToFormat(QImage::Format_ARGB32);
-        if(image.isNull())
-            {
-            throw GfxException(EGfxErrorNoMemory, "format convertion to 32bpp failed");
-            }
-        }
-
-    // Temporary storage for pixels
-    QRgb* pixel = NULL;
-
-    // dataArray index, start from offset
-    int targetIndex = aOffset;
-
-    // Iterate through lines
-    for(int b = 0; b < aHeight; ++b)
-    {
-        // Obtain pointer to start of current line (y)
-        const unsigned char* lineStart = image.scanLine(b);
-
-        // Iterate through pixels on each line
-        for (int a = 0; a < aWidth; ++a)
-        {
-            // Set the current pixel, relative to line start
-            pixel = ((QRgb*)lineStart) + a;
-
-            // Move target pointer to the next slot
-            targetIndex = aOffset + a + (b * aScanlength);
-            // Shift pixels to correct places, needed for 32-bit format
-            // as the bits order in memory may vary between systems
-            aRgbdata[targetIndex] =  ((qAlpha(*pixel) & 0xff) << 24) |
-                                     ((qRed(*pixel)   & 0xff) << 16) |
-                                     ((qGreen(*pixel) & 0xff) << 8 ) |
-                                     ((qBlue(*pixel)  & 0xff));
-        }
-    }
-
-}
-
-
-void Pixmap::getRgb(char* aRgbdata, char* aTransparencyMask,int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int /*aFormat*/) {
+void Pixmap::getRgb(char* aRgbdata, char* aTransparencyMask,int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) {
 
     GFX_LOG_FUNC_CALL();
 
@@ -384,229 +233,67 @@
     QImage image = mPixmap.toImage();
 
     // Validate conversion
-    if(image.isNull()) {
-        throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed");
-    }
-
-     if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height())
-        {
-        image = image.copy(aX, aY, aWidth, aHeight);
-        if(image.isNull())
-            {
-            throw GfxException(EGfxErrorNoMemory, "copying from original image failed");
-            }
-        }
-
-    if(aScanlength < 0)
+    if(image.isNull()) 
         {
-         image = image.mirrored(false, true);
-         if(image.isNull())
-             {
-             throw GfxException(EGfxErrorNoMemory, "Mirroring failed");
-             }
+        throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed");
         }
-
-    // If image is not monochrome we need to convert it
-    if(image.format() != QImage::Format_Mono)
-    {
-        image = image.convertToFormat(QImage::Format_Mono);
-        if(image.isNull())
-        {
-            throw GfxException(EGfxErrorNoMemory, "Format conversion to 8bpp failed");
-        }
+    doGetRgb(image, aRgbdata, aTransparencyMask, aOffset, aScanlength, aX, aY, aWidth, aHeight, aFormat);
     }
 
-    // dataArray index, start from offset
-    int targetIndex = aOffset;
-
-    const unsigned char* imageStart = image.bits();
-    QImage mask = image.alphaChannel();
-    const unsigned char* maskStart = mask.bits();
-
-    // Find the number of full bytes
-    int fullBytes = aWidth/8;
-    int bpl = image.bytesPerLine();
-
-    if(bpl == fullBytes)
+void Pixmap::getRgb(short* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) 
     {
-        memcpy(aRgbdata+targetIndex, imageStart, bpl*aHeight);
-        memcpy(aTransparencyMask+targetIndex, maskStart, bpl*aHeight);
-    }
-    else
-    {
-        memcpy(aRgbdata+targetIndex, imageStart, fullBytes*aHeight + aHeight);
-        memcpy(aTransparencyMask+targetIndex, maskStart, fullBytes*aHeight + aHeight);
-    }
-
-}
-
-void Pixmap::getRgb(short* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) {
     GFX_LOG_FUNC_CALL();
 
-    // Match format to QT
-    int format;
-    switch (aFormat) {
-        case EFormatRGB555:
-            format = QImage::Format_RGB555;
-            break;
-        case EFormatRGB16:
-            format = QImage::Format_RGB16;
-            break;
-         case EFormatRGB444:
-            format = QImage::Format_RGB444;
-            break;
-         case EFormatARGB4444Premultiplied:
-            format = QImage::Format_ARGB4444_Premultiplied;
-            break;
-         default:
-            format = QImage::Format_RGB16;
-    }
     // Convert to QImage in order to access pixels
     QImage image = mPixmap.toImage();
 
     // Validate conversion
     if(image.isNull())
+        {
+        throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed");
+        }
+    doGetRgb(image, aRgbdata, aOffset, aScanlength, aX, aY, aWidth, aHeight, aFormat);
+    }
+
+const QImage Pixmap::toConstImage()
     {
-        throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed");
+    GFX_LOG_FUNC_CALL();
+    return mPixmap.toImage();
     }
 
-    if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height())
-        {
-        image = image.copy(aX, aY, aWidth, aHeight);
-        if(image.isNull())
-            {
-            throw GfxException(EGfxErrorNoMemory, "copying from original image failed");
-            }
-        }
+QImage Pixmap::toImage()
+    {
+    GFX_LOG_FUNC_CALL();
+    return mPixmap.toImage();
+    }
 
-
-    // If image is not format we need, convert it
-    if(image.format() != format)
+QPixmap Pixmap::toPixmap()
     {
-        image = image.convertToFormat((QImage::Format)format);
-        if(image.isNull())
+    GFX_LOG_FUNC_CALL();
+    return QPixmap(mPixmap);
+    }
+
+void Pixmap::transform(TTransform aTransform)
+    {
+    GFX_LOG_FUNC_CALL();
+    mPixmap = mPixmap.transformed(generateTransformMatrix(aTransform), Qt::FastTransformation);
+    if(mPixmap.isNull())
         {
-            throw GfxException(EGfxErrorNoMemory, "format convertion to 16bpp failed");
+        throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
         }
     }
 
-    // Temporary storage for pixels
-    short* pixel = NULL;
-    // dataArray index, start from offset
-    int targetIndex = aOffset;
-
-    // Iterate through lines
-    for(int b=0; b < aHeight; b++)
+TImageType Pixmap::type()
     {
-        // Obtain pointer to start of current line (y)
-        const unsigned char* lineStart = image.scanLine(b);
-        // Iterate through pixels on each line
-        for(int a=0; a < aWidth; a++)
-        {
-            // Set the current pixel, relative to line start
-            pixel = ((short*)lineStart) + a;
-            // Move target pointer to the next slot
-            targetIndex = aOffset + a + (b * aScanlength);
-            aRgbdata[targetIndex] =  *pixel;
-        }
-    }
-}
-
-QImage Pixmap::toImage()
-{
-    return mPixmap.toImage();
-}
-
-void Pixmap::transform(TTransform aTransform)
-{
     GFX_LOG_FUNC_CALL();
-
-    // For rotation along z-axis
-    QTransform imageTransform;
-    bool flip = false;
-    bool rotate = true;
-
-    switch(aTransform) {
-        case ETransNone:
-            // No transform or mirror
-            return;
-        case ETransRot90:
-            imageTransform.rotate(90, Qt::ZAxis);
-            break;
-        case ETransRot180:
-            imageTransform.rotate(180, Qt::ZAxis);
-            break;
-        case ETransRot270:
-            imageTransform.rotate(270, Qt::ZAxis);
-            break;
-        case ETransMirror:
-            flip = true;
-            rotate = false;
-            break;
-        case ETransMirrorRot90:
-            imageTransform.rotate(90, Qt::ZAxis);
-            flip = true;
-            break;
-        case ETransMirrorRot180:
-            imageTransform.rotate(180, Qt::ZAxis);
-            flip = true;
-            break;
-        case ETransMirrorRot270:
-            imageTransform.rotate(270, Qt::ZAxis);
-            flip = true;
-            break;
-        default:
-            Q_ASSERT_X(false, "Graphics", "Transform type not recognized");
-            return;
+    return EPixmap;
     }
 
-    // Mirror image first if requested
-    if(flip)
-    {
-        QTransform flipTransform;
-        flipTransform.rotate(180,Qt::YAxis);
-
-        // Create temp pixmap for flipped
-        QPixmap temp = mPixmap.transformed(flipTransform, Qt::FastTransformation);
-
-        // Validate transformation
-        if(temp.isNull())
-        {
-            throw GfxException(EGfxErrorNoMemory, "temp buffer alloc failed");
-        }
-
-        // Free original pixmap and store new
-        mPixmap = temp;
-    }
-
-    // Then rotate
-    if(rotate)
+bool Pixmap::hasAlphaChannel()
     {
-        // Create temp pixmap for rotate
-        QPixmap temp = mPixmap.transformed(imageTransform, Qt::FastTransformation);
-
-        // Validate alloc
-        if(temp.isNull())
-        {
-            throw GfxException(EGfxErrorNoMemory, "temp buffer alloc failed");
-        }
-
-        // Free original image and store new
-        mPixmap = temp;
-    }
-}
-
-TImageType Pixmap::type()
-{
-    GFX_LOG_FUNC_CALL();
-    return EPixmap;
-}
-
-bool Pixmap::hasAlphaChannel()
-{
     GFX_LOG_FUNC_CALL();
     return mPixmap.hasAlphaChannel();
-}
+    }
 
 } // namespace GFX
 } // namespace Java