changeset 3 | 41300fa6a67c |
parent 0 | 1918ee327afb |
child 4 | 3b1da2848fc7 |
child 7 | f7bc934e204c |
child 18 | 2f34d5167611 |
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 ®ion, Qt::ClipOperation op) |
1804 void QVGPaintEngine::clip(const QRegion ®ion, 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(); |