src/openvg/qpaintengine_vg.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    41 
    41 
    42 #include "qpaintengine_vg_p.h"
    42 #include "qpaintengine_vg_p.h"
    43 #include "qpixmapdata_vg_p.h"
    43 #include "qpixmapdata_vg_p.h"
    44 #include "qpixmapfilter_vg_p.h"
    44 #include "qpixmapfilter_vg_p.h"
    45 #include "qvgcompositionhelper_p.h"
    45 #include "qvgcompositionhelper_p.h"
       
    46 #include "qvgimagepool_p.h"
    46 #if !defined(QT_NO_EGL)
    47 #if !defined(QT_NO_EGL)
    47 #include <QtGui/private/qegl_p.h>
    48 #include <QtGui/private/qegl_p.h>
    48 #include "qwindowsurface_vgegl_p.h"
    49 #include "qwindowsurface_vgegl_p.h"
    49 #endif
    50 #endif
    50 #include <QtCore/qvarlengtharray.h>
    51 #include <QtCore/qvarlengtharray.h>
  1016         break;
  1017         break;
  1017     }
  1018     }
  1018 
  1019 
  1019     const uchar *pixels = img.bits();
  1020     const uchar *pixels = img.bits();
  1020 
  1021 
  1021     VGImage vgImg = vgCreateImage
  1022     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1022         (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1023         (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1023     vgImageSubData
  1024     vgImageSubData
  1024         (vgImg, pixels, img.bytesPerLine(), format, 0, 0,
  1025         (vgImg, pixels, img.bytesPerLine(), format, 0, 0,
  1025          img.width(), img.height());
  1026          img.width(), img.height());
  1026 
  1027 
  1061     }
  1062     }
  1062 
  1063 
  1063     const uchar *pixels = img.bits() + bpp * sr.x() +
  1064     const uchar *pixels = img.bits() + bpp * sr.x() +
  1064                           img.bytesPerLine() * sr.y();
  1065                           img.bytesPerLine() * sr.y();
  1065 
  1066 
  1066     VGImage vgImg = vgCreateImage
  1067     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1067         (format, sr.width(), sr.height(), VG_IMAGE_QUALITY_FASTER);
  1068         (format, sr.width(), sr.height(), VG_IMAGE_QUALITY_FASTER);
  1068     vgImageSubData
  1069     vgImageSubData
  1069         (vgImg, pixels, img.bytesPerLine(), format, 0, 0,
  1070         (vgImg, pixels, img.bytesPerLine(), format, 0, 0,
  1070          sr.width(), sr.height());
  1071          sr.width(), sr.height());
  1071 
  1072 
  1082     painter.drawImage(0, 0, image);
  1083     painter.drawImage(0, 0, image);
  1083     painter.end();
  1084     painter.end();
  1084 
  1085 
  1085     const uchar *pixels = img.bits();
  1086     const uchar *pixels = img.bits();
  1086 
  1087 
  1087     VGImage vgImg = vgCreateImage
  1088     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1088         (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1089         (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1089     vgImageSubData
  1090     vgImageSubData
  1090         (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
  1091         (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
  1091          img.width(), img.height());
  1092          img.width(), img.height());
  1092 
  1093 
  1104     painter.drawImage(QPoint(0, 0), image, sr);
  1105     painter.drawImage(QPoint(0, 0), image, sr);
  1105     painter.end();
  1106     painter.end();
  1106 
  1107 
  1107     const uchar *pixels = img.bits();
  1108     const uchar *pixels = img.bits();
  1108 
  1109 
  1109     VGImage vgImg = vgCreateImage
  1110     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1110         (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1111         (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1111     vgImageSubData
  1112     vgImageSubData
  1112         (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
  1113         (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
  1113          img.width(), img.height());
  1114          img.width(), img.height());
  1114 
  1115 
  1176     }
  1177     }
  1177 
  1178 
  1178     case Qt::TexturePattern: {
  1179     case Qt::TexturePattern: {
  1179         // The brush is a texture specified by a QPixmap/QImage.
  1180         // The brush is a texture specified by a QPixmap/QImage.
  1180         QPixmapData *pd = brush.texture().pixmapData();
  1181         QPixmapData *pd = brush.texture().pixmapData();
       
  1182         if (!pd)
       
  1183             break;  // null QPixmap
  1181         VGImage vgImg;
  1184         VGImage vgImg;
  1182         bool deref = false;
  1185         bool deref = false;
  1183         if (pd->pixelType() == QPixmapData::BitmapType) {
  1186         if (pd->pixelType() == QPixmapData::BitmapType) {
  1184             // Colorize bitmaps using the brush color and opacity.
  1187             // Colorize bitmaps using the brush color and opacity.
  1185             QColor color = brush.color();
  1188             QColor color = brush.color();
  1190             deref = true;
  1193             deref = true;
  1191         } else if (opacity == 1.0) {
  1194         } else if (opacity == 1.0) {
  1192             if (pd->classId() == QPixmapData::OpenVGClass) {
  1195             if (pd->classId() == QPixmapData::OpenVGClass) {
  1193                 QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  1196                 QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  1194                 vgImg = vgpd->toVGImage();
  1197                 vgImg = vgpd->toVGImage();
       
  1198 
       
  1199                 // We don't want the pool to reclaim this image
       
  1200                 // because we cannot predict when the paint object
       
  1201                 // will stop using it.  Replacing the image with
       
  1202                 // new data will make the paint object invalid.
       
  1203                 vgpd->detachImageFromPool();
  1195             } else {
  1204             } else {
  1196                 vgImg = toVGImage(*(pd->buffer()));
  1205                 vgImg = toVGImage(*(pd->buffer()));
  1197                 deref = true;
  1206                 deref = true;
  1198             }
  1207             }
  1199         } else if (pd->classId() == QPixmapData::OpenVGClass) {
  1208         } else if (pd->classId() == QPixmapData::OpenVGClass) {
  1200             QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  1209             QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  1201             vgImg = vgpd->toVGImage(opacity);
  1210             vgImg = vgpd->toVGImage(opacity);
       
  1211             vgpd->detachImageFromPool();
  1202         } else {
  1212         } else {
  1203             vgImg = toVGImageWithOpacity(*(pd->buffer()), opacity);
  1213             vgImg = toVGImageWithOpacity(*(pd->buffer()), opacity);
  1204             deref = true;
  1214             deref = true;
  1205         }
  1215         }
  1206         if (vgImg == VG_INVALID_HANDLE)
  1216         if (vgImg == VG_INVALID_HANDLE)
  1566     Q_D(QVGPaintEngine);
  1576     Q_D(QVGPaintEngine);
  1567     QVGPainterState *s = state();
  1577     QVGPainterState *s = state();
  1568 
  1578 
  1569     d->dirty |= QPaintEngine::DirtyClipRegion;
  1579     d->dirty |= QPaintEngine::DirtyClipRegion;
  1570 
  1580 
  1571     // If we have a non-simple transform, then use path-based clipping.
       
  1572     if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) {
       
  1573         QPaintEngineEx::clip(rect, op);
       
  1574         return;
       
  1575     }
       
  1576 
       
  1577     switch (op) {
  1581     switch (op) {
  1578         case Qt::NoClip:
  1582         case Qt::NoClip:
  1579         {
  1583         {
  1580             s->clipRegion = defaultClipRegion();
  1584             s->clipRegion = defaultClipRegion();
  1581         }
  1585         }
  1607 {
  1611 {
  1608     Q_D(QVGPaintEngine);
  1612     Q_D(QVGPaintEngine);
  1609     QVGPainterState *s = state();
  1613     QVGPainterState *s = state();
  1610 
  1614 
  1611     d->dirty |= QPaintEngine::DirtyClipRegion;
  1615     d->dirty |= QPaintEngine::DirtyClipRegion;
  1612 
       
  1613     // If we have a non-simple transform, then use path-based clipping.
       
  1614     if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) {
       
  1615         QPaintEngineEx::clip(region, op);
       
  1616         return;
       
  1617     }
       
  1618 
  1616 
  1619     switch (op) {
  1617     switch (op) {
  1620         case Qt::NoClip:
  1618         case Qt::NoClip:
  1621         {
  1619         {
  1622             s->clipRegion = defaultClipRegion();
  1620             s->clipRegion = defaultClipRegion();
  1749                 // clip and "r" is a single rectangle, then use the
  1747                 // clip and "r" is a single rectangle, then use the
  1750                 // scissor for clipping.  We try to avoid allocating a
  1748                 // scissor for clipping.  We try to avoid allocating a
  1751                 // QRegion copy on the heap for the test if we can.
  1749                 // QRegion copy on the heap for the test if we can.
  1752                 QRegion clip = d->systemClip; // Reference-counted, no alloc.
  1750                 QRegion clip = d->systemClip; // Reference-counted, no alloc.
  1753                 QRect clipRect;
  1751                 QRect clipRect;
  1754                 if (clip.numRects() == 1) {
  1752                 if (clip.rectCount() == 1) {
  1755                     clipRect = clip.boundingRect().intersected(r);
  1753                     clipRect = clip.boundingRect().intersected(r);
  1756                 } else if (clip.isEmpty()) {
  1754                 } else if (clip.isEmpty()) {
  1757                     clipRect = r;
  1755                     clipRect = r;
  1758                 } else {
  1756                 } else {
  1759                     clip = clip.intersect(r);
  1757                     clip = clip.intersect(r);
  1760                     if (clip.numRects() != 1) {
  1758                     if (clip.rectCount() != 1) {
  1761                         d->maskValid = false;
  1759                         d->maskValid = false;
  1762                         d->maskIsSet = false;
  1760                         d->maskIsSet = false;
  1763                         d->maskRect = QRect();
  1761                         d->maskRect = QRect();
  1764                         d->modifyMask(this, VG_FILL_MASK, r);
  1762                         d->modifyMask(this, VG_FILL_MASK, r);
  1765                         break;
  1763                         break;
  1806 void QVGPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
  1804 void QVGPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
  1807 {
  1805 {
  1808     Q_D(QVGPaintEngine);
  1806     Q_D(QVGPaintEngine);
  1809 
  1807 
  1810     // Use the QRect case if the region consists of a single rectangle.
  1808     // Use the QRect case if the region consists of a single rectangle.
  1811     if (region.numRects() == 1) {
  1809     if (region.rectCount() == 1) {
  1812         clip(region.boundingRect(), op);
  1810         clip(region.boundingRect(), op);
  1813         return;
  1811         return;
  1814     }
  1812     }
  1815 
  1813 
  1816     d->dirty |= QPaintEngine::DirtyClipRegion;
  1814     d->dirty |= QPaintEngine::DirtyClipRegion;
  1849                 QRegion clip = d->systemClip;
  1847                 QRegion clip = d->systemClip;
  1850                 if (clip.isEmpty())
  1848                 if (clip.isEmpty())
  1851                     clip = r;
  1849                     clip = r;
  1852                 else
  1850                 else
  1853                     clip = clip.intersect(r);
  1851                     clip = clip.intersect(r);
  1854                 if (clip.numRects() == 1) {
  1852                 if (clip.rectCount() == 1) {
  1855                     d->maskValid = false;
  1853                     d->maskValid = false;
  1856                     d->maskIsSet = false;
  1854                     d->maskIsSet = false;
  1857                     d->maskRect = clip.boundingRect();
  1855                     d->maskRect = clip.boundingRect();
  1858                     vgSeti(VG_MASKING, VG_FALSE);
  1856                     vgSeti(VG_MASKING, VG_FALSE);
  1859                     updateScissor();
  1857                     updateScissor();
  1867         }
  1865         }
  1868         break;
  1866         break;
  1869 
  1867 
  1870         case Qt::IntersectClip:
  1868         case Qt::IntersectClip:
  1871         {
  1869         {
  1872             if (region.numRects() != 1) {
  1870             if (region.rectCount() != 1) {
  1873                 // If there is more than one rectangle, then intersecting
  1871                 // If there is more than one rectangle, then intersecting
  1874                 // the rectangles one by one in modifyMask() will not give
  1872                 // the rectangles one by one in modifyMask() will not give
  1875                 // the desired result.  So fall back to path-based clipping.
  1873                 // the desired result.  So fall back to path-based clipping.
  1876                 QPaintEngineEx::clip(region, op);
  1874                 QPaintEngineEx::clip(region, op);
  1877                 return;
  1875                 return;
  2144     return QRegion(0, 0, pdev->width(), pdev->height());
  2142     return QRegion(0, 0, pdev->width(), pdev->height());
  2145 }
  2143 }
  2146 
  2144 
  2147 bool QVGPaintEngine::isDefaultClipRegion(const QRegion& region)
  2145 bool QVGPaintEngine::isDefaultClipRegion(const QRegion& region)
  2148 {
  2146 {
  2149     if (region.numRects() != 1)
  2147     if (region.rectCount() != 1)
  2150         return false;
  2148         return false;
  2151 
  2149 
  2152     QPaintDevice *pdev = paintDevice();
  2150     QPaintDevice *pdev = paintDevice();
  2153     int width = pdev->width();
  2151     int width = pdev->width();
  2154     int height = pdev->height();
  2152     int height = pdev->height();
  2891 }
  2889 }
  2892 
  2890 
  2893 void QVGPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
  2891 void QVGPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
  2894 {
  2892 {
  2895     QPixmapData *pd = pm.pixmapData();
  2893     QPixmapData *pd = pm.pixmapData();
       
  2894     if (!pd)
       
  2895         return; // null QPixmap
  2896     if (pd->classId() == QPixmapData::OpenVGClass) {
  2896     if (pd->classId() == QPixmapData::OpenVGClass) {
  2897         Q_D(QVGPaintEngine);
  2897         Q_D(QVGPaintEngine);
  2898         QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  2898         QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  2899         if (!vgpd->isValid())
  2899         if (!vgpd->isValid())
  2900             return;
  2900             return;
  2908 }
  2908 }
  2909 
  2909 
  2910 void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
  2910 void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
  2911 {
  2911 {
  2912     QPixmapData *pd = pm.pixmapData();
  2912     QPixmapData *pd = pm.pixmapData();
       
  2913     if (!pd)
       
  2914         return; // null QPixmap
  2913     if (pd->classId() == QPixmapData::OpenVGClass) {
  2915     if (pd->classId() == QPixmapData::OpenVGClass) {
  2914         Q_D(QVGPaintEngine);
  2916         Q_D(QVGPaintEngine);
  2915         QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  2917         QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  2916         if (!vgpd->isValid())
  2918         if (!vgpd->isValid())
  2917             return;
  2919             return;
  2983     Q_D(QVGPaintEngine);
  2985     Q_D(QVGPaintEngine);
  2984 
  2986 
  2985     // If the pixmap is not VG, or the transformation is projective,
  2987     // If the pixmap is not VG, or the transformation is projective,
  2986     // then fall back to the default implementation.
  2988     // then fall back to the default implementation.
  2987     QPixmapData *pd = pixmap.pixmapData();
  2989     QPixmapData *pd = pixmap.pixmapData();
       
  2990     if (!pd)
       
  2991         return; // null QPixmap
  2988     if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
  2992     if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
  2989         QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
  2993         QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
  2990         return;
  2994         return;
  2991     }
  2995     }
  2992 
  2996 
  3397 #else
  3401 #else
  3398     updateScissor();
  3402     updateScissor();
  3399 #endif
  3403 #endif
  3400 }
  3404 }
  3401 
  3405 
       
  3406 void QVGPaintEngine::fillRegion
       
  3407     (const QRegion& region, const QColor& color, const QSize& surfaceSize)
       
  3408 {
       
  3409     Q_D(QVGPaintEngine);
       
  3410     if (d->clearColor != color || d->clearOpacity != 1.0f) {
       
  3411         VGfloat values[4];
       
  3412         values[0] = color.redF();
       
  3413         values[1] = color.greenF();
       
  3414         values[2] = color.blueF();
       
  3415         values[3] = color.alphaF();
       
  3416         vgSetfv(VG_CLEAR_COLOR, 4, values);
       
  3417         d->clearColor = color;
       
  3418         d->clearOpacity = 1.0f;
       
  3419     }
       
  3420     if (region.rectCount() == 1) {
       
  3421         QRect r = region.boundingRect();
       
  3422         vgClear(r.x(), surfaceSize.height() - r.y() - r.height(),
       
  3423                 r.width(), r.height());
       
  3424     } else {
       
  3425         const QVector<QRect> rects = region.rects();
       
  3426         for (int i = 0; i < rects.size(); ++i) {
       
  3427             QRect r = rects.at(i);
       
  3428             vgClear(r.x(), surfaceSize.height() - r.y() - r.height(),
       
  3429                     r.width(), r.height());
       
  3430         }
       
  3431     }
       
  3432 }
       
  3433 
  3402 #if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QT_NO_EGL)
  3434 #if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QT_NO_EGL)
  3403 
  3435 
  3404 QVGCompositionHelper::QVGCompositionHelper()
  3436 QVGCompositionHelper::QVGCompositionHelper()
  3405 {
  3437 {
  3406     d = qt_vg_create_paint_engine()->vgPrivate();
  3438     d = qt_vg_create_paint_engine()->vgPrivate();
  3421 {
  3453 {
  3422     clearScissor();
  3454     clearScissor();
  3423 }
  3455 }
  3424 
  3456 
  3425 void QVGCompositionHelper::blitWindow
  3457 void QVGCompositionHelper::blitWindow
  3426     (QVGEGLWindowSurfacePrivate *surface, const QRect& rect,
  3458     (VGImage image, const QSize& imageSize,
  3427      const QPoint& topLeft, int opacity)
  3459      const QRect& rect, const QPoint& topLeft, int opacity)
  3428 {
  3460 {
  3429     // Get the VGImage that is acting as a back buffer for the window.
       
  3430     VGImage image = surface->surfaceImage();
       
  3431     if (image == VG_INVALID_HANDLE)
  3461     if (image == VG_INVALID_HANDLE)
  3432         return;
  3462         return;
  3433     QSize imageSize = surface->surfaceSize();
       
  3434 
  3463 
  3435     // Determine which sub rectangle of the window to draw.
  3464     // Determine which sub rectangle of the window to draw.
  3436     QRect sr = rect.translated(-topLeft);
  3465     QRect sr = rect.translated(-topLeft);
  3437 
  3466 
  3438     if (opacity >= 255) {
  3467     if (opacity >= 255) {
  3453         }
  3482         }
  3454 
  3483 
  3455         // Set the image transform.
  3484         // Set the image transform.
  3456         QTransform transform;
  3485         QTransform transform;
  3457         int y = screenSize.height() - (rect.bottom() + 1);
  3486         int y = screenSize.height() - (rect.bottom() + 1);
  3458         transform.translate(rect.x() + 0.5f, y + 0.5f);
  3487         transform.translate(rect.x() - 0.5f, y - 0.5f);
  3459         d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
  3488         d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
  3460 
  3489 
  3461         // Enable opacity for image drawing if necessary.
  3490         // Enable opacity for image drawing if necessary.
  3462         if (opacity < 255) {
  3491         if (opacity != d->paintOpacity) {
  3463             if (opacity != d->paintOpacity) {
  3492             VGfloat values[4];
  3464                 VGfloat values[4];
  3493             values[0] = 1.0f;
  3465                 values[0] = 1.0f;
  3494             values[1] = 1.0f;
  3466                 values[1] = 1.0f;
  3495             values[2] = 1.0f;
  3467                 values[2] = 1.0f;
  3496             values[3] = ((VGfloat)opacity) / 255.0f;
  3468                 values[3] = ((VGfloat)opacity) / 255.0f;
  3497             vgSetParameterfv(d->opacityPaint, VG_PAINT_COLOR, 4, values);
  3469                 vgSetParameterfv(d->opacityPaint, VG_PAINT_COLOR, 4, values);
  3498             d->paintOpacity = values[3];
  3470                 d->paintOpacity = values[3];
  3499         }
  3471             }
  3500         if (d->fillPaint != d->opacityPaint) {
  3472             if (d->fillPaint != d->opacityPaint) {
  3501             vgSetPaint(d->opacityPaint, VG_FILL_PATH);
  3473                 vgSetPaint(d->opacityPaint, VG_FILL_PATH);
  3502             d->fillPaint = d->opacityPaint;
  3474                 d->fillPaint = d->opacityPaint;
  3503         }
  3475             }
  3504         d->setImageMode(VG_DRAW_IMAGE_MULTIPLY);
  3476             d->setImageMode(VG_DRAW_IMAGE_MULTIPLY);
       
  3477         } else {
       
  3478             d->setImageMode(VG_DRAW_IMAGE_NORMAL);
       
  3479         }
       
  3480 
  3505 
  3481         // Draw the child image.
  3506         // Draw the child image.
  3482         vgDrawImage(child);
  3507         vgDrawImage(child);
  3483 
  3508 
  3484         // Destroy the child image.
  3509         // Destroy the child image.
  3525 }
  3550 }
  3526 
  3551 
  3527 void QVGCompositionHelper::fillBackground
  3552 void QVGCompositionHelper::fillBackground
  3528     (const QRegion& region, const QBrush& brush)
  3553     (const QRegion& region, const QBrush& brush)
  3529 {
  3554 {
  3530     // Set the path transform to the default viewport transformation.
  3555     if (brush.style() == Qt::SolidPattern) {
  3531     VGfloat devh = screenSize.height() - 1;
  3556         // Use vgClear() to quickly fill the background.
  3532     QTransform viewport(1.0f, 0.0f, 0.0f,
  3557         QColor color = brush.color();
  3533                         0.0f, -1.0f, 0.0f,
  3558         if (d->clearColor != color || d->clearOpacity != 1.0f) {
  3534                         0.5f, devh + 0.5f, 1.0f);
  3559             VGfloat values[4];
  3535     d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport);
  3560             values[0] = color.redF();
  3536 
  3561             values[1] = color.greenF();
  3537     // Set the brush to use to fill the background.
  3562             values[2] = color.blueF();
  3538     d->ensureBrush(brush);
  3563             values[3] = color.alphaF();
  3539     d->setFillRule(VG_EVEN_ODD);
  3564             vgSetfv(VG_CLEAR_COLOR, 4, values);
  3540 
  3565             d->clearColor = color;
  3541     if (region.numRects() == 1) {
  3566             d->clearOpacity = 1.0f;
  3542         fillBackgroundRect(region.boundingRect(), d);
  3567         }
       
  3568         if (region.rectCount() == 1) {
       
  3569             QRect r = region.boundingRect();
       
  3570             vgClear(r.x(), screenSize.height() - r.y() - r.height(),
       
  3571                     r.width(), r.height());
       
  3572         } else {
       
  3573             const QVector<QRect> rects = region.rects();
       
  3574             for (int i = 0; i < rects.size(); ++i) {
       
  3575                 QRect r = rects.at(i);
       
  3576                 vgClear(r.x(), screenSize.height() - r.y() - r.height(),
       
  3577                         r.width(), r.height());
       
  3578             }
       
  3579         }
       
  3580 
  3543     } else {
  3581     } else {
  3544         const QVector<QRect> rects = region.rects();
  3582         // Set the path transform to the default viewport transformation.
  3545         for (int i = 0; i < rects.size(); ++i)
  3583         VGfloat devh = screenSize.height() - 1;
  3546             fillBackgroundRect(rects.at(i), d);
  3584         QTransform viewport(1.0f, 0.0f, 0.0f,
  3547     }
  3585                             0.0f, -1.0f, 0.0f,
  3548 
  3586                             -0.5f, devh + 0.5f, 1.0f);
  3549     // We will need to reset the path transform during the next paint.
  3587         d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport);
  3550     d->pathTransformSet = false;
  3588 
  3551 }
  3589         // Set the brush to use to fill the background.
  3552 
  3590         d->ensureBrush(brush);
  3553 void QVGCompositionHelper::drawCursorImage
  3591         d->setFillRule(VG_EVEN_ODD);
  3554     (const QImage& image, const QPoint& offset)
  3592 
  3555 {
  3593         if (region.rectCount() == 1) {
  3556     QImage img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
  3594             fillBackgroundRect(region.boundingRect(), d);
  3557 
  3595         } else {
  3558     VGImage vgImg = vgCreateImage
  3596             const QVector<QRect> rects = region.rects();
  3559         (VG_sARGB_8888_PRE, img.width(), img.height(),
  3597             for (int i = 0; i < rects.size(); ++i)
  3560          VG_IMAGE_QUALITY_FASTER);
  3598                 fillBackgroundRect(rects.at(i), d);
  3561     vgImageSubData
  3599         }
  3562         (vgImg, img.bits() + img.bytesPerLine() * (img.height() - 1),
  3600 
  3563          -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0,
  3601         // We will need to reset the path transform during the next paint.
  3564          img.width(), img.height());
  3602         d->pathTransformSet = false;
  3565 
  3603     }
  3566     QTransform transform;
       
  3567     int y = screenSize.height() - (offset.y() + img.height());
       
  3568     transform.translate(offset.x() + 0.5f, y + 0.5f);
       
  3569     d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
       
  3570 
       
  3571     d->setImageMode(VG_DRAW_IMAGE_NORMAL);
       
  3572     vgDrawImage(vgImg);
       
  3573 
       
  3574     vgDestroyImage(vgImg);
       
  3575 }
  3604 }
  3576 
  3605 
  3577 void QVGCompositionHelper::drawCursorPixmap
  3606 void QVGCompositionHelper::drawCursorPixmap
  3578     (const QPixmap& pixmap, const QPoint& offset)
  3607     (const QPixmap& pixmap, const QPoint& offset)
  3579 {
  3608 {
       
  3609     VGImage vgImage = VG_INVALID_HANDLE;
       
  3610 
       
  3611     // Fetch the VGImage from the pixmap if possible.
  3580     QPixmapData *pd = pixmap.pixmapData();
  3612     QPixmapData *pd = pixmap.pixmapData();
       
  3613     if (!pd)
       
  3614         return; // null QPixmap
  3581     if (pd->classId() == QPixmapData::OpenVGClass) {
  3615     if (pd->classId() == QPixmapData::OpenVGClass) {
  3582         QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  3616         QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
  3583         if (vgpd->isValid()) {
  3617         if (vgpd->isValid())
  3584             VGfloat devh = screenSize.height() - 1;
  3618             vgImage = vgpd->toVGImage();
  3585             QTransform transform(1.0f, 0.0f, 0.0f,
  3619     }
  3586                                  0.0f, -1.0f, 0.0f,
  3620 
  3587                                  0.5f, devh + 0.5f, 1.0f);
  3621     // Set the image transformation and modes.
  3588             transform.translate(offset.x(), offset.y());
  3622     VGfloat devh = screenSize.height() - 1;
  3589             d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
  3623     QTransform transform(1.0f, 0.0f, 0.0f,
  3590 
  3624                          0.0f, -1.0f, 0.0f,
  3591             d->setImageMode(VG_DRAW_IMAGE_NORMAL);
  3625                          -0.5f, devh + 0.5f, 1.0f);
  3592             vgDrawImage(vgpd->toVGImage());
  3626     transform.translate(offset.x(), offset.y());
       
  3627     d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
       
  3628     d->setImageMode(VG_DRAW_IMAGE_NORMAL);
       
  3629 
       
  3630     // Draw the VGImage.
       
  3631     if (vgImage != VG_INVALID_HANDLE) {
       
  3632         vgDrawImage(vgImage);
       
  3633     } else {
       
  3634         QImage img = pixmap.toImage().convertToFormat
       
  3635             (QImage::Format_ARGB32_Premultiplied);
       
  3636 
       
  3637         vgImage = vgCreateImage
       
  3638             (VG_sARGB_8888_PRE, img.width(), img.height(),
       
  3639              VG_IMAGE_QUALITY_FASTER);
       
  3640         if (vgImage == VG_INVALID_HANDLE)
  3593             return;
  3641             return;
  3594         }
  3642         vgImageSubData
  3595     }
  3643             (vgImage, img.bits() + img.bytesPerLine() * (img.height() - 1),
  3596 
  3644              -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0,
  3597     drawCursorImage(pixmap.toImage(), offset);
  3645              img.width(), img.height());
       
  3646 
       
  3647         vgDrawImage(vgImage);
       
  3648         vgDestroyImage(vgImage);
       
  3649     }
  3598 }
  3650 }
  3599 
  3651 
  3600 void QVGCompositionHelper::setScissor(const QRegion& region)
  3652 void QVGCompositionHelper::setScissor(const QRegion& region)
  3601 {
  3653 {
  3602     QVector<QRect> rects = region.rects();
  3654     QVector<QRect> rects = region.rects();