Changeset 846 for trunk/src/openvg
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 17 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/openvg/openvg.pro
r769 r846 18 18 qpixmapfilter_vg_p.h \ 19 19 qvgcompositionhelper_p.h \ 20 qvgimagepool_p.h 20 qvgimagepool_p.h \ 21 qvgfontglyphcache_p.h 21 22 SOURCES += \ 22 23 qpaintengine_vg.cpp \ … … 34 35 } 35 36 36 symbian: DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING 37 symbian { 38 DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING QVG_SCISSOR_CLIP 39 SOURCES += \ 40 qvg_symbian.cpp 41 } 37 42 38 43 include(../qbase.pri) -
trunk/src/openvg/qpaintengine_vg.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation ([email protected]) … … 45 45 #include "qvgcompositionhelper_p.h" 46 46 #include "qvgimagepool_p.h" 47 47 48 #if !defined(QT_NO_EGL) 48 #include <QtGui/private/qegl _p.h>49 #include <QtGui/private/qegl_p.h> 49 50 #include "qwindowsurface_vgegl_p.h" 50 51 #endif 51 52 #include <QtCore/qvarlengtharray.h> 52 53 #include <QtGui/private/qdrawhelper_p.h> 53 #include <QtGui/private/qtextureglyphcache_p.h>54 54 #include <QtGui/private/qtextengine_p.h> 55 55 #include <QtGui/private/qfontengine_p.h> 56 56 #include <QtGui/private/qpainterpath_p.h> 57 58 59 60 57 61 #include <QDebug> 58 62 #include <QSet> 59 63 60 64 QT_BEGIN_NAMESPACE 61 62 // vgDrawGlyphs() only exists in OpenVG 1.1 and higher.63 #if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_DRAW_GLYPHS)64 #define QVG_NO_DRAW_GLYPHS 165 #endif66 65 67 66 // vgRenderToMask() only exists in OpenVG 1.1 and higher. … … 74 73 #endif 75 74 75 76 77 76 78 #if !defined(QVG_NO_DRAW_GLYPHS) 77 79 … … 80 82 81 83 class QVGPaintEnginePrivate; 82 83 class QVGFontGlyphCache84 {85 public:86 QVGFontGlyphCache();87 ~QVGFontGlyphCache();88 89 void cacheGlyphs(QVGPaintEnginePrivate *d,90 const QTextItemInt &ti,91 const QVarLengthArray<glyph_t> &glyphs);92 void setScaleFromText(const QTextItemInt &ti);93 94 VGFont font;95 VGfloat scaleX;96 VGfloat scaleY;97 98 uint cachedGlyphsMask[256 / 32];99 QSet<glyph_t> cachedGlyphs;100 };101 84 102 85 typedef QHash<QFontEngine*, QVGFontGlyphCache*> QVGFontCache; … … 120 103 class QVGPaintEnginePrivate : public QPaintEngineExPrivate 121 104 { 105 122 106 public: 123 107 // Extra blending modes from VG_KHR_advanced_blending extension. … … 150 134 }; 151 135 152 QVGPaintEnginePrivate( );136 QVGPaintEnginePrivate(); 153 137 ~QVGPaintEnginePrivate(); 154 138 … … 171 155 void setupColorRamp(const QGradient *grad, VGPaint paint); 172 156 void setImageOptions(); 157 173 158 #if !defined(QVG_SCISSOR_CLIP) 174 159 void ensureMask(QVGPaintEngine *engine, int width, int height); … … 259 244 { 260 245 if (!pathTransformSet) { 261 setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, pathTransform); 246 QTransform aliasedTransform = pathTransform; 247 if (renderingQuality == VG_RENDERING_QUALITY_NONANTIALIASED && currentPen != Qt::NoPen) 248 aliasedTransform = aliasedTransform 249 * QTransform::fromTranslate(aliasedCoordinateDelta, -aliasedCoordinateDelta); 250 setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, aliasedTransform); 262 251 pathTransformSet = true; 263 252 } … … 299 288 // Clear all lazily-set modes. 300 289 void clearModes(); 290 291 292 301 293 }; 302 294 … … 314 306 vgSeti(VG_RENDERING_QUALITY, mode); 315 307 renderingQuality = mode; 308 316 309 } 317 310 } … … 350 343 } 351 344 352 QVGPaintEnginePrivate::QVGPaintEnginePrivate( )345 QVGPaintEnginePrivate::QVGPaintEnginePrivate() 353 346 { 354 347 init(); … … 968 961 x1, y2 - yRadius, 969 962 x1, y1 + yRadius, // LineTo 970 x1, y1 + KAPPA * yRadius,// CurveTo963 x1, y1 + // CurveTo 971 964 x1 + (1 - KAPPA) * xRadius, y1, 972 965 x1 + xRadius, y1 … … 1015 1008 int width = sourceImage.width(); 1016 1009 for (int y=0; y<height; ++y) { 1017 uchar *source = sourceImage.scanLine(y);1010 canLine(y); 1018 1011 QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y)); 1019 1012 for (int x=0; x < width; ++x) … … 1022 1015 return dest; 1023 1016 } 1024 1025 // defined in qpixmapdata_vg.cpp.1026 const uchar *qt_vg_imageBits(const QImage& image);1027 1017 1028 1018 static VGImage toVGImage … … 1059 1049 } 1060 1050 1061 const uchar *pixels = qt_vg_imageBits(img);1051 const uchar *pixels = ); 1062 1052 1063 1053 VGImage vgImg = QVGImagePool::instance()->createPermanentImage … … 1103 1093 } 1104 1094 1105 const uchar *pixels = qt_vg_imageBits(img) + bpp * sr.x() +1095 const uchar *pixels = ) + bpp * sr.x() + 1106 1096 img.bytesPerLine() * sr.y(); 1107 1097 … … 1125 1115 painter.end(); 1126 1116 1127 const uchar *pixels = qt_vg_imageBits(img);1117 const uchar *pixels = ); 1128 1118 1129 1119 VGImage vgImg = QVGImagePool::instance()->createPermanentImage … … 1147 1137 painter.end(); 1148 1138 1149 const uchar *pixels = qt_vg_imageBits(img);1139 const uchar *pixels = ); 1150 1140 1151 1141 VGImage vgImg = QVGImagePool::instance()->createPermanentImage … … 1452 1442 1453 1443 QVGPaintEngine::QVGPaintEngine() 1454 : QPaintEngineEx(*new QVGPaintEnginePrivate )1444 : QPaintEngineEx(*new QVGPaintEnginePrivate) 1455 1445 { 1456 1446 } … … 1513 1503 ensureBrush(brush); 1514 1504 setFillRule(rule); 1505 1506 1515 1507 ensurePathTransform(); 1508 1516 1509 vgDrawPath(path, VG_FILL_PATH); 1517 1510 } … … 1627 1620 points[5] - points[1]); 1628 1621 clip(rect.toRect(), op); 1629 } else { 1630 // The best we can do is clip to the bounding rectangle 1631 // of all control points. 1632 clip(path.controlPointRect().toRect(), op); 1633 } 1622 return; 1623 } 1624 1625 // Try converting the path into a QRegion that tightly follows 1626 // the outline of the path we want to clip with. 1627 QRegion region; 1628 if (!path.isEmpty()) 1629 region = QRegion(path.convertToPainterPath().toFillPolygon(QTransform()).toPolygon()); 1630 1631 switch (op) { 1632 case Qt::NoClip: 1633 { 1634 region = defaultClipRegion(); 1635 } 1636 break; 1637 1638 case Qt::ReplaceClip: 1639 { 1640 region = d->transform.map(region); 1641 } 1642 break; 1643 1644 case Qt::IntersectClip: 1645 { 1646 region = s->clipRegion.intersect(d->transform.map(region)); 1647 } 1648 break; 1649 1650 case Qt::UniteClip: 1651 { 1652 region = s->clipRegion.unite(d->transform.map(region)); 1653 } 1654 break; 1655 } 1656 if (region.numRects() <= d->maxScissorRects) { 1657 // We haven't reached the maximum scissor count yet, so we can 1658 // still make use of this region. 1659 s->clipRegion = region; 1660 updateScissor(); 1661 return; 1662 } 1663 1664 // The best we can do is clip to the bounding rectangle 1665 // of all control points. 1666 clip(path.controlPointRect().toRect(), op); 1634 1667 } 1635 1668 … … 2169 2202 // Using the scissor to do clipping, so combine the systemClip 2170 2203 // with the current painting clipRegion. 2204 2205 2206 2207 2208 2209 2171 2210 QVGPainterState *s = state(); 2172 2211 if (s->clipEnabled) { … … 2218 2257 QVector<QRect> rects = region.rects(); 2219 2258 int count = rects.count(); 2220 if (count > d->maxScissorRects) 2221 count = d->maxScissorRects; 2259 if (count > d->maxScissorRects) { 2260 #if !defined(QVG_SCISSOR_CLIP) 2261 count = d->maxScissorRects; 2262 #else 2263 // Use masking 2264 int width = paintDevice()->width(); 2265 int height = paintDevice()->height(); 2266 vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 2267 0, 0, width, height); 2268 for (int i = 0; i < rects.size(); ++i) { 2269 vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 2270 rects[i].x(), height - rects[i].y() - rects[i].height(), 2271 rects[i].width(), rects[i].height()); 2272 } 2273 2274 vgSeti(VG_SCISSORING, VG_FALSE); 2275 vgSeti(VG_MASKING, VG_TRUE); 2276 d->maskValid = true; 2277 d->maskIsSet = false; 2278 d->scissorMask = false; 2279 d->scissorActive = false; 2280 d->scissorDirty = false; 2281 d->scissorRegion = region; 2282 return; 2283 #endif 2284 } 2285 2222 2286 QVarLengthArray<VGint> params(count * 4); 2223 2287 int height = paintDevice()->height(); … … 2955 3019 } 2956 3020 3021 3022 3023 3024 3025 2957 3026 static void drawVGImage(QVGPaintEnginePrivate *d, 2958 3027 const QRectF& r, VGImage vgImg, … … 3026 3095 d->setImageMode(VG_DRAW_IMAGE_STENCIL); 3027 3096 vgDrawImage(vgImg); 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3028 3112 } 3029 3113 … … 3042 3126 else 3043 3127 drawVGImage(d, r, vgpd->toVGImage(d->opacity), vgpd->size(), sr); 3044 } else { 3045 drawImage(r, *(pd->buffer()), sr, Qt::AutoColor); 3046 } 3128 3129 if(!vgpd->failedToAlloc) 3130 return; 3131 3132 // try to reallocate next time if reasonable small pixmap 3133 QSize screenSize = QApplication::desktop()->screenGeometry().size(); 3134 if (pm.size().width() <= screenSize.width() 3135 && pm.size().height() <= screenSize.height()) 3136 vgpd->failedToAlloc = false; 3137 } 3138 3139 drawImage(r, *(pd->buffer()), sr, Qt::AutoColor); 3047 3140 } 3048 3141 … … 3061 3154 else 3062 3155 drawVGImage(d, pos, vgpd->toVGImage(d->opacity)); 3063 } else { 3064 drawImage(pos, *(pd->buffer())); 3065 } 3156 3157 if (!vgpd->failedToAlloc) 3158 return; 3159 3160 // try to reallocate next time if reasonable small pixmap 3161 QSize screenSize = QApplication::desktop()->screenGeometry().size(); 3162 if (pm.size().width() <= screenSize.width() 3163 && pm.size().height() <= screenSize.height()) 3164 vgpd->failedToAlloc = false; 3165 } 3166 3167 drawImage(pos, *(pd->buffer())); 3066 3168 } 3067 3169 … … 3084 3186 } 3085 3187 } else { 3086 // Monochrome images need to use the vgChildImage() path. 3087 vgImg = toVGImage(image, flags); 3088 drawVGImage(d, r, vgImg, image.size(), sr); 3188 if (canVgWritePixels(image) && (r.size() == sr.size()) && !flags) { 3189 // Optimization for straight blits, no blending 3190 int x = sr.x(); 3191 int y = sr.y(); 3192 int bpp = image.depth() >> 3; // bytes 3193 int offset = 0; 3194 int bpl = image.bytesPerLine(); 3195 if (d->imageTransform.m22() < 0) { 3196 // inverted 3197 offset = ((y + sr.height()) * bpl) - ((image.width() - x) * bpp); 3198 bpl = -bpl; 3199 } else { 3200 offset = (y * bpl) + (x * bpp); 3201 } 3202 const uchar *bits = image.constBits() + offset; 3203 3204 QPointF mapped = d->imageTransform.map(r.topLeft()); 3205 vgWritePixels(bits, bpl, qt_vg_image_to_vg_format(image.format()), 3206 mapped.x(), mapped.y() - sr.height(), r.width(), r.height()); 3207 return; 3208 } else { 3209 // Monochrome images need to use the vgChildImage() path. 3210 vgImg = toVGImage(image, flags); 3211 drawVGImage(d, r, vgImg, image.size(), sr); 3212 } 3089 3213 } 3090 3214 vgDestroyImage(vgImg); … … 3095 3219 Q_D(QVGPaintEngine); 3096 3220 VGImage vgImg; 3097 if (d->simpleTransform || d->opacity == 1.0f) 3221 if (canVgWritePixels(image)) { 3222 // Optimization for straight blits, no blending 3223 bool inverted = (d->imageTransform.m22() < 0); 3224 const uchar *bits = inverted ? image.constBits() + image.byteCount() : image.constBits(); 3225 int bpl = inverted ? -image.bytesPerLine() : image.bytesPerLine(); 3226 3227 QPointF mapped = d->imageTransform.map(pos); 3228 vgWritePixels(bits, bpl, qt_vg_image_to_vg_format(image.format()), 3229 mapped.x(), mapped.y() - image.height(), image.width(), image.height()); 3230 return; 3231 } else if (d->simpleTransform || d->opacity == 1.0f) { 3098 3232 vgImg = toVGImage(image); 3099 else3233 3100 3234 vgImg = toVGImageWithOpacity(image, d->opacity); 3235 3101 3236 drawVGImage(d, pos, vgImg); 3102 3237 vgDestroyImage(vgImg); … … 3107 3242 { 3108 3243 QBrush brush(state()->pen.color(), pixmap); 3109 QTransform xform; 3110 xform.translate(-s.x(), -s.y()); 3244 QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y()); 3111 3245 brush.setTransform(xform); 3112 3246 fillRect(r, brush); … … 3117 3251 // pixmap rather than parts of the pixmap. Even having just one of 3118 3252 // these conditions will improve performance. 3119 void QVGPaintEngine::drawPixmaps 3120 (const QDrawPixmaps::Data *drawingData, int dataCount, 3121 const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints) 3253 void QVGPaintEngine::drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount, 3254 const QPixmap &pixmap, QFlags<QPainter::PixmapFragmentHint> hints) 3122 3255 { 3123 3256 #if !defined(QT_SHIVAVG) … … 3130 3263 return; // null QPixmap 3131 3264 if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) { 3132 QPaintEngineEx::drawPixmap s(drawingData, dataCount, pixmap, hints);3265 QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints); 3133 3266 return; 3134 3267 } … … 3154 3287 3155 3288 // Select the opacity paint object. 3156 if ((hints & Q DrawPixmaps::OpaqueHint) != 0 && d->opacity == 1.0f) {3289 if ((hints & Q::OpaqueHint) != 0 && d->opacity == 1.0f) { 3157 3290 d->setImageMode(VG_DRAW_IMAGE_NORMAL); 3158 3291 } else { … … 3166 3299 for (int i = 0; i < dataCount; ++i) { 3167 3300 QTransform transform(d->imageTransform); 3168 transform.translate(drawingData[i]. point.x(), drawingData[i].point.y());3301 transform.translate(drawingData[i].); 3169 3302 transform.rotate(drawingData[i].rotation); 3170 3303 3171 3304 VGImage child; 3172 3305 QSize imageSize = vgpd->size(); 3173 QRectF sr = drawingData[i].source; 3306 QRectF sr(drawingData[i].sourceLeft, drawingData[i].sourceTop, 3307 drawingData[i].width, drawingData[i].height); 3174 3308 if (sr.topLeft().isNull() && sr.size() == imageSize) { 3175 3309 child = vgImg; … … 3200 3334 d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform); 3201 3335 3202 if ((hints & Q DrawPixmaps::OpaqueHint) == 0) {3336 if ((hints & Q::OpaqueHint) == 0) { 3203 3337 qreal opacity = d->opacity * drawingData[i].opacity; 3204 3338 if (opacity != 1.0f) { … … 3226 3360 vgDestroyImage(cachedImages[i]); 3227 3361 #else 3228 QPaintEngineEx::drawPixmap s(drawingData, dataCount, pixmap, hints);3362 QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints); 3229 3363 #endif 3230 3364 } … … 3257 3391 font = vgCreateFont(0); 3258 3392 scaleX = scaleY = 0.0; 3393 3259 3394 memset(cachedGlyphsMask, 0, sizeof(cachedGlyphsMask)); 3260 3395 } … … 3266 3401 } 3267 3402 3268 void QVGFontGlyphCache::setScaleFromText(const Q TextItemInt &ti)3269 { 3270 QFontInfo fi( ti.font());3403 void QVGFontGlyphCache::setScaleFromText(const Q) 3404 { 3405 QFontInfo fi(); 3271 3406 qreal pixelSize = fi.pixelSize(); 3272 qreal emSquare = ti.fontEngine->properties().emSquare.toReal();3407 qreal emSquare = fontEngine->properties().emSquare.toReal(); 3273 3408 scaleX = scaleY = static_cast<VGfloat>(pixelSize / emSquare); 3274 3409 } 3275 3410 3276 void QVGFontGlyphCache::cacheGlyphs 3277 (QVGPaintEnginePrivate *d, const QTextItemInt &ti,3278 const QVarLengthArray<glyph_t> &glyphs)3411 void QVGFontGlyphCache::cacheGlyphs 3412 , 3413 ) 3279 3414 { 3280 3415 VGfloat origin[2]; 3281 3416 VGfloat escapement[2]; 3282 const glyph_t *g = glyphs.constData();3283 int count = glyphs.size();3284 3417 glyph_metrics_t metrics; 3285 3418 // Some Qt font engines don't set yoff in getUnscaledGlyph(). … … 3300 3433 #if !defined(QVG_NO_IMAGE_GLYPHS) 3301 3434 Q_UNUSED(d); 3302 QImage scaledImage = ti.fontEngine->alphaMapForGlyph(glyph);3435 QImage scaledImage = fontEngine->alphaMapForGlyph(glyph); 3303 3436 VGImage vgImage = VG_INVALID_HANDLE; 3304 metrics = ti.fontEngine->boundingBox(glyph);3437 metrics = fontEngine->boundingBox(glyph); 3305 3438 if (!scaledImage.isNull()) { // Not a space character 3306 3439 if (scaledImage.format() == QImage::Format_Indexed8) { 3307 3440 vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER); 3308 vgImageSubData(vgImage, qt_vg_imageBits(scaledImage), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height());3441 vgImageSubData(vgImage, ), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height()); 3309 3442 } else if (scaledImage.format() == QImage::Format_Mono) { 3310 3443 QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8); 3311 3444 vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); 3312 vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height());3445 vgImageSubData(vgImage, ), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height()); 3313 3446 } else { 3314 3447 QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); 3315 3448 vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); 3316 vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());3449 vgImageSubData(vgImage, ), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height()); 3317 3450 } 3318 3451 } … … 3326 3459 // Calculate the path for the glyph and cache it. 3327 3460 QPainterPath path; 3328 ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics);3461 fontEngine->getUnscaledGlyph(glyph, &path, &metrics); 3329 3462 VGPath vgPath; 3330 3463 if (!path.isEmpty()) { … … 3358 3491 return; 3359 3492 } 3360 3493 3361 3494 // Get the glyphs and positions associated with the text item. 3362 3495 QVarLengthArray<QFixedPoint> positions; … … 3365 3498 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); 3366 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3367 3522 // Find the glyph cache for this font. 3368 QVGFontCache::ConstIterator it = d->fontCache.constFind( ti.fontEngine);3523 QVGFontCache::ConstIterator it = d->fontCache.constFind(fontEngine); 3369 3524 QVGFontGlyphCache *glyphCache; 3370 3525 if (it != d->fontCache.constEnd()) { 3371 3526 glyphCache = it.value(); 3372 3527 } else { 3528 3529 3530 3373 3531 glyphCache = new QVGFontGlyphCache(); 3532 3374 3533 if (glyphCache->font == VG_INVALID_HANDLE) { 3375 3534 qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine"); 3376 3535 delete glyphCache; 3377 QPaintEngineEx::drawTextItem(p, textItem); 3378 return; 3379 } 3380 glyphCache->setScaleFromText(ti); 3381 d->fontCache.insert(ti.fontEngine, glyphCache); 3536 return false; 3537 } 3538 glyphCache->setScaleFromText(font, fontEngine); 3539 d->fontCache.insert(fontEngine, glyphCache); 3382 3540 if (!d->fontEngineCleaner) 3383 3541 d->fontEngineCleaner = new QVGFontEngineCleaner(d); 3384 QObject::connect( ti.fontEngine, SIGNAL(destroyed()),3542 QObject::connect(fontEngine, SIGNAL(destroyed()), 3385 3543 d->fontEngineCleaner, SLOT(fontEngineDestroyed())); 3386 3544 } … … 3388 3546 // Set the transformation to use for drawing the current glyphs. 3389 3547 QTransform glyphTransform(d->pathTransform); 3390 glyphTransform.translate(p.x(), p.y()); 3548 if (d->transform.type() <= QTransform::TxTranslate) { 3549 // Prevent blurriness of unscaled, unrotated text by forcing integer coordinates. 3550 glyphTransform.translate( 3551 floor(p.x() + glyphTransform.dx() + aliasedCoordinateDelta) - glyphTransform.dx(), 3552 floor(p.y() - glyphTransform.dy() + aliasedCoordinateDelta) + glyphTransform.dy()); 3553 } else { 3554 glyphTransform.translate(p.x(), p.y()); 3555 } 3391 3556 #if defined(QVG_NO_IMAGE_GLYPHS) 3392 3557 glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY); 3393 3558 #endif 3559 3560 3561 3562 3563 3394 3564 d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform); 3395 3565 3396 3566 // Add the glyphs from the text item into the glyph cache. 3397 glyphCache->cacheGlyphs(d, ti, glyphs);3567 glyphCache->cacheGlyphs(d, lyphs); 3398 3568 3399 3569 // Create the array of adjustments between glyphs 3400 QVarLengthArray<VGfloat> adjustments_x( glyphs.size());3401 QVarLengthArray<VGfloat> adjustments_y( glyphs.size());3402 for (int i = 1; i < glyphs.size(); ++i) {3403 adjustments_x[i-1] = (positions[i].x - positions[i-1].x). toReal();3404 adjustments_y[i-1] = (positions[i].y - positions[i-1].y). toReal();3570 QVarLengthArray<VGfloat> adjustments_x(); 3571 QVarLengthArray<VGfloat> adjustments_y(); 3572 for (int i = 1; i < ; ++i) { 3573 adjustments_x[i-1] = (positions[i].x - positions[i-1].x).toReal(); 3574 adjustments_y[i-1] = (positions[i].y - positions[i-1].y).toReal(); 3405 3575 } 3406 3576 3407 3577 // Set the glyph drawing origin. 3408 3578 VGfloat origin[2]; 3409 origin[0] = positions[0].x. toReal();3410 origin[1] = positions[0].y. toReal();3579 origin[0] = positions[0].x.toReal(); 3580 origin[1] = positions[0].y.toReal(); 3411 3581 vgSetfv(VG_GLYPH_ORIGIN, 2, origin); 3412 3582 … … 3422 3592 // the Qt pen, not the Qt brush. 3423 3593 d->ensureBrush(state()->pen.brush()); 3424 vgDrawGlyphs(glyphCache->font, glyphs.size(), (VGuint*)glyphs.data(),3594 vgDrawGlyphs(glyphCache->font, , 3425 3595 adjustments_x.data(), adjustments_y.data(), VG_FILL_PATH, VG_TRUE); 3596 3426 3597 #else 3427 // OpenGL 1.0 does not have support for VGFont and glyphs, 3428 // so fall back to the default Qt path stroking algorithm. 3429 QPaintEngineEx::drawTextItem(p, textItem); 3598 Q_UNUSED(numGlyphs); 3599 Q_UNUSED(glyphs); 3600 Q_UNUSED(font); 3601 Q_UNUSED(fontEngine); 3602 Q_UNUSED(p); 3603 Q_UNUSED(positions); 3604 return false; 3430 3605 #endif 3431 3606 } … … 3537 3712 d->scissorMask = false; 3538 3713 d->maskRect = QRect(); 3714 3539 3715 clipEnabledChanged(); 3540 3716 } … … 3788 3964 return; 3789 3965 vgImageSubData 3790 (vgImage, qt_vg_imageBits(img) + img.bytesPerLine() * (img.height() - 1),3966 (vgImage, ) + img.bytesPerLine() * (img.height() - 1), 3791 3967 -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0, 3792 3968 img.width(), img.height()); -
trunk/src/openvg/qpaintengine_vg_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation ([email protected]) … … 55 55 56 56 #include <QtGui/private/qpaintengineex_p.h> 57 57 58 58 59 QT_BEGIN_NAMESPACE 59 60 61 60 62 class QVGPaintEnginePrivate; 61 63 class QPixmapData; … … 137 139 void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); 138 140 139 void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints); 141 void drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount, const QPixmap &pixmap, 142 QFlags<QPainter::PixmapFragmentHint> hints); 140 143 141 144 void drawTextItem(const QPointF &p, const QTextItem &textItem); 145 146 147 148 142 149 143 150 void setState(QPainterState *s); … … 164 171 bool isDefaultClipRect(const QRect& rect); 165 172 bool clearRect(const QRectF &rect, const QColor &color); 173 166 174 }; 167 168 175 169 176 QT_END_NAMESPACE -
trunk/src/openvg/qpixmapdata_vg.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation ([email protected]) … … 43 43 #include "qpaintengine_vg_p.h" 44 44 #include <QtGui/private/qdrawhelper_p.h> 45 46 47 45 48 #include "qvg_p.h" 46 49 #include "qvgimagepool_p.h" 47 48 #if defined(Q_OS_SYMBIAN) 49 #include <private/qt_s60_p.h> 50 #include <fbs.h> 51 #endif 52 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE 53 #include <sgresource/sgimage.h> 54 typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); 55 typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); 56 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); 57 #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE 50 #include <QBuffer> 51 #include <QImageReader> 52 #include <QtGui/private/qimage_p.h> 58 53 59 54 QT_BEGIN_NAMESPACE … … 71 66 inImagePool = false; 72 67 inLRU = false; 68 73 69 #if !defined(QT_NO_EGL) 74 70 context = 0; … … 161 157 (const QImage &image, Qt::ImageConversionFlags flags) 162 158 { 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 163 208 if (image.size() == QSize(w, h)) 164 209 setSerialNumber(++qt_vg_pixmap_serial); 165 210 else 166 211 resize(image.width(), image.height()); 167 source = image.convertToFormat(sourceFormat(), flags); 212 213 QImage::Format format = sourceFormat(); 214 int d = image.depth(); 215 if (d == 1 || d == 16 || d == 24 || (d == 32 && !image.hasAlphaChannel())) 216 format = QImage::Format_RGB32; 217 else if (!(flags & Qt::NoOpaqueDetection) && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) 218 format = sourceFormat(); 219 else 220 format = image.hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32; 221 222 if (inPlace && image.data_ptr()->convertInPlace(format, flags)) { 223 source = image; 224 } else { 225 source = image.convertToFormat(format); 226 227 // convertToFormat won't detach the image if format stays the same. 228 if (image.format() == format) 229 source.detach(); 230 } 231 168 232 recreate = true; 169 233 } … … 234 298 } 235 299 236 // This function works around QImage::bits() making a deep copy if the237 // QImage is not const. We force it to be const and then get the bits.238 // XXX: Should add a QImage::constBits() in the future to replace this.239 const uchar *qt_vg_imageBits(const QImage& image)240 {241 return image.bits();242 }243 244 300 VGImage QVGPixmapData::toVGImage() 245 301 { 246 if (!isValid() )302 if (!isValid()) 247 303 return VG_INVALID_HANDLE; 248 304 … … 260 316 if (vgImage == VG_INVALID_HANDLE) { 261 317 vgImage = QVGImagePool::instance()->createImageForPixmap 262 ( VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);318 (, w, h, VG_IMAGE_QUALITY_FASTER, this); 263 319 264 320 // Bail out if we run out of GPU memory - try again next time. 265 if (vgImage == VG_INVALID_HANDLE) 321 if (vgImage == VG_INVALID_HANDLE) { 322 failedToAlloc = true; 266 323 return VG_INVALID_HANDLE; 324 267 325 268 326 inImagePool = true; … … 274 332 vgImageSubData 275 333 (vgImage, 276 qt_vg_imageBits(source), source.bytesPerLine(),277 VG_sARGB_8888_PRE, 0, 0, w, h);334 ), source.bytesPerLine(), 335 , 0, 0, w, h); 278 336 } 279 337 … … 429 487 } 430 488 431 #if defined(Q_OS_SYMBIAN)432 433 static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)434 {435 CFbsBitmap *copy = q_check_ptr(new CFbsBitmap);436 if(!copy)437 return 0;438 439 if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {440 delete copy;441 copy = 0;442 443 return 0;444 }445 446 CFbsBitmapDevice* bitmapDevice = 0;447 CFbsBitGc *bitmapGc = 0;448 QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy));449 QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());450 bitmapGc->Activate(bitmapDevice);451 452 bitmapGc->BitBlt(TPoint(), bitmap);453 454 delete bitmapGc;455 delete bitmapDevice;456 457 return copy;458 }459 460 void QVGPixmapData::cleanup()461 {462 is_null = w = h = 0;463 recreate = false;464 source = QImage();465 }466 467 void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)468 {469 if (type == QPixmapData::SgImage && pixmap) {470 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)471 RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);472 473 destroyImages();474 prevSize = QSize();475 476 TInt err = 0;477 478 RSgDriver driver;479 err = driver.Open();480 if (err != KErrNone) {481 cleanup();482 return;483 }484 485 if (sgImage->IsNull()) {486 cleanup();487 driver.Close();488 return;489 }490 491 TSgImageInfo sgImageInfo;492 err = sgImage->GetInfo(sgImageInfo);493 if (err != KErrNone) {494 cleanup();495 driver.Close();496 return;497 }498 499 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");500 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");501 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");502 503 if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {504 cleanup();505 driver.Close();506 return;507 }508 509 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};510 EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),511 EGL_NO_CONTEXT,512 EGL_NATIVE_PIXMAP_KHR,513 (EGLClientBuffer)sgImage,514 (EGLint*)KEglImageAttribs);515 516 if (eglGetError() != EGL_SUCCESS) {517 cleanup();518 driver.Close();519 return;520 }521 522 vgImage = vgCreateEGLImageTargetKHR(eglImage);523 if (vgGetError() != VG_NO_ERROR) {524 cleanup();525 eglDestroyImageKHR(QEglContext::display(), eglImage);526 driver.Close();527 return;528 }529 530 w = sgImageInfo.iSizeInPixels.iWidth;531 h = sgImageInfo.iSizeInPixels.iHeight;532 d = 32; // We always use ARGB_Premultiplied for VG pixmaps.533 is_null = (w <= 0 || h <= 0);534 source = QImage();535 recreate = false;536 prevSize = QSize(w, h);537 setSerialNumber(++qt_vg_pixmap_serial);538 // release stuff539 eglDestroyImageKHR(QEglContext::display(), eglImage);540 driver.Close();541 #endif542 } else if (type == QPixmapData::FbsBitmap) {543 CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);544 545 bool deleteSourceBitmap = false;546 547 #ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE548 549 // Rasterize extended bitmaps550 551 TUid extendedBitmapType = bitmap->ExtendedBitmapType();552 if (extendedBitmapType != KNullUid) {553 bitmap = createBlitCopy(bitmap);554 deleteSourceBitmap = true;555 }556 #endif557 558 if (bitmap->IsCompressedInRAM()) {559 bitmap = createBlitCopy(bitmap);560 deleteSourceBitmap = true;561 }562 563 TDisplayMode displayMode = bitmap->DisplayMode();564 QImage::Format format = qt_TDisplayMode2Format(displayMode);565 566 TSize size = bitmap->SizeInPixels();567 568 bitmap->BeginDataAccess();569 uchar *bytes = (uchar*)bitmap->DataAddress();570 QImage img = QImage(bytes, size.iWidth, size.iHeight, format);571 img = img.copy();572 bitmap->EndDataAccess();573 574 if(displayMode == EGray2) {575 //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid576 //So invert mono bitmaps so that masks work correctly.577 img.invertPixels();578 } else if(displayMode == EColor16M) {579 img = img.rgbSwapped(); // EColor16M is BGR580 }581 582 fromImage(img, Qt::AutoColor);583 584 if(deleteSourceBitmap)585 delete bitmap;586 }587 }588 589 void* QVGPixmapData::toNativeType(NativeType type)590 {591 if (type == QPixmapData::SgImage) {592 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)593 toVGImage();594 595 if (!isValid() || vgImage == VG_INVALID_HANDLE)596 return 0;597 598 TInt err = 0;599 600 RSgDriver driver;601 err = driver.Open();602 if (err != KErrNone)603 return 0;604 605 TSgImageInfo sgInfo;606 sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;607 sgInfo.iSizeInPixels.SetSize(w, h);608 sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;609 610 RSgImage *sgImage = q_check_ptr(new RSgImage());611 err = sgImage->Create(sgInfo, NULL, NULL);612 if (err != KErrNone) {613 driver.Close();614 return 0;615 }616 617 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");618 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");619 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");620 621 if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {622 driver.Close();623 return 0;624 }625 626 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};627 EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),628 EGL_NO_CONTEXT,629 EGL_NATIVE_PIXMAP_KHR,630 (EGLClientBuffer)sgImage,631 (EGLint*)KEglImageAttribs);632 if (eglGetError() != EGL_SUCCESS) {633 sgImage->Close();634 driver.Close();635 return 0;636 }637 638 VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);639 if (vgGetError() != VG_NO_ERROR) {640 eglDestroyImageKHR(QEglContext::display(), eglImage);641 sgImage->Close();642 driver.Close();643 return 0;644 }645 646 vgCopyImage(dstVgImage, 0, 0,647 vgImage, 0, 0,648 w, h, VG_FALSE);649 650 if (vgGetError() != VG_NO_ERROR) {651 sgImage->Close();652 sgImage = 0;653 }654 // release stuff655 vgDestroyImage(dstVgImage);656 eglDestroyImageKHR(QEglContext::display(), eglImage);657 driver.Close();658 return reinterpret_cast<void*>(sgImage);659 #endif660 } else if (type == QPixmapData::FbsBitmap) {661 CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);662 663 if (bitmap) {664 if (bitmap->Create(TSize(source.width(), source.height()),665 EColor16MAP) == KErrNone) {666 const uchar *sptr = qt_vg_imageBits(source);667 bitmap->BeginDataAccess();668 669 uchar *dptr = (uchar*)bitmap->DataAddress();670 Mem::Copy(dptr, sptr, source.byteCount());671 672 bitmap->EndDataAccess();673 } else {674 delete bitmap;675 bitmap = 0;676 }677 }678 679 return reinterpret_cast<void*>(bitmap);680 }681 return 0;682 }683 #endif //Q_OS_SYMBIAN684 685 489 QT_END_NAMESPACE -
trunk/src/openvg/qpixmapdata_vg_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation ([email protected]) … … 65 65 class QEglContext; 66 66 class QVGImagePool; 67 67 68 68 69 #if !defined(QT_NO_EGL) … … 88 89 void resize(int width, int height); 89 90 void fromImage(const QImage &image, Qt::ImageConversionFlags flags); 91 92 93 94 95 96