Changeset 846 for trunk/src/openvg


Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
17 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/openvg/openvg.pro

    r769 r846  
    1818    qpixmapfilter_vg_p.h \
    1919    qvgcompositionhelper_p.h \
    20     qvgimagepool_p.h
     20    qvgimagepool_p.h \
     21    qvgfontglyphcache_p.h
    2122SOURCES += \
    2223    qpaintengine_vg.cpp \
     
    3435}
    3536
    36 symbian: DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING
     37symbian {
     38    DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING QVG_SCISSOR_CLIP
     39    SOURCES += \
     40        qvg_symbian.cpp
     41}
    3742
    3843include(../qbase.pri)
  • trunk/src/openvg/qpaintengine_vg.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation ([email protected])
     
    4545#include "qvgcompositionhelper_p.h"
    4646#include "qvgimagepool_p.h"
     47
    4748#if !defined(QT_NO_EGL)
    48 #include <QtGui/private/qegl_p.h>
     49#include <QtGui/private/qegl_p.h>
    4950#include "qwindowsurface_vgegl_p.h"
    5051#endif
    5152#include <QtCore/qvarlengtharray.h>
    5253#include <QtGui/private/qdrawhelper_p.h>
    53 #include <QtGui/private/qtextureglyphcache_p.h>
    5454#include <QtGui/private/qtextengine_p.h>
    5555#include <QtGui/private/qfontengine_p.h>
    5656#include <QtGui/private/qpainterpath_p.h>
     57
     58
     59
     60
    5761#include <QDebug>
    5862#include <QSet>
    5963
    6064QT_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 1
    65 #endif
    6665
    6766// vgRenderToMask() only exists in OpenVG 1.1 and higher.
     
    7473#endif
    7574
     75
     76
     77
    7678#if !defined(QVG_NO_DRAW_GLYPHS)
    7779
     
    8082
    8183class QVGPaintEnginePrivate;
    82 
    83 class QVGFontGlyphCache
    84 {
    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 };
    10184
    10285typedef QHash<QFontEngine*, QVGFontGlyphCache*> QVGFontCache;
     
    120103class QVGPaintEnginePrivate : public QPaintEngineExPrivate
    121104{
     105
    122106public:
    123107    // Extra blending modes from VG_KHR_advanced_blending extension.
     
    150134    };
    151135
    152     QVGPaintEnginePrivate();
     136    QVGPaintEnginePrivate();
    153137    ~QVGPaintEnginePrivate();
    154138
     
    171155    void setupColorRamp(const QGradient *grad, VGPaint paint);
    172156    void setImageOptions();
     157
    173158#if !defined(QVG_SCISSOR_CLIP)
    174159    void ensureMask(QVGPaintEngine *engine, int width, int height);
     
    259244    {
    260245        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);
    262251            pathTransformSet = true;
    263252        }
     
    299288    // Clear all lazily-set modes.
    300289    void clearModes();
     290
     291
     292
    301293};
    302294
     
    314306        vgSeti(VG_RENDERING_QUALITY, mode);
    315307        renderingQuality = mode;
     308
    316309    }
    317310}
     
    350343}
    351344
    352 QVGPaintEnginePrivate::QVGPaintEnginePrivate()
     345QVGPaintEnginePrivate::QVGPaintEnginePrivate()
    353346{
    354347    init();
     
    968961        x1, y2 - yRadius,
    969962        x1, y1 + yRadius,                   // LineTo
    970         x1, y1 + KAPPA * yRadius,           // CurveTo
     963        x1, y1 +      // CurveTo
    971964        x1 + (1 - KAPPA) * xRadius, y1,
    972965        x1 + xRadius, y1
     
    10151008    int width = sourceImage.width();
    10161009    for (int y=0; y<height; ++y) {
    1017         uchar *source = sourceImage.scanLine(y);
     1010        canLine(y);
    10181011        QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y));
    10191012        for (int x=0; x < width; ++x)
     
    10221015    return dest;
    10231016}
    1024 
    1025 // defined in qpixmapdata_vg.cpp.
    1026 const uchar *qt_vg_imageBits(const QImage& image);
    10271017
    10281018static VGImage toVGImage
     
    10591049    }
    10601050
    1061     const uchar *pixels = qt_vg_imageBits(img);
     1051    const uchar *pixels = );
    10621052
    10631053    VGImage vgImg = QVGImagePool::instance()->createPermanentImage
     
    11031093    }
    11041094
    1105     const uchar *pixels = qt_vg_imageBits(img) + bpp * sr.x() +
     1095    const uchar *pixels = ) + bpp * sr.x() +
    11061096                          img.bytesPerLine() * sr.y();
    11071097
     
    11251115    painter.end();
    11261116
    1127     const uchar *pixels = qt_vg_imageBits(img);
     1117    const uchar *pixels = );
    11281118
    11291119    VGImage vgImg = QVGImagePool::instance()->createPermanentImage
     
    11471137    painter.end();
    11481138
    1149     const uchar *pixels = qt_vg_imageBits(img);
     1139    const uchar *pixels = );
    11501140
    11511141    VGImage vgImg = QVGImagePool::instance()->createPermanentImage
     
    14521442
    14531443QVGPaintEngine::QVGPaintEngine()
    1454     : QPaintEngineEx(*new QVGPaintEnginePrivate)
     1444    : QPaintEngineEx(*new QVGPaintEnginePrivate)
    14551445{
    14561446}
     
    15131503    ensureBrush(brush);
    15141504    setFillRule(rule);
     1505
     1506
    15151507    ensurePathTransform();
     1508
    15161509    vgDrawPath(path, VG_FILL_PATH);
    15171510}
     
    16271620                    points[5] - points[1]);
    16281621        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);
    16341667}
    16351668
     
    21692202    // Using the scissor to do clipping, so combine the systemClip
    21702203    // with the current painting clipRegion.
     2204
     2205
     2206
     2207
     2208
     2209
    21712210    QVGPainterState *s = state();
    21722211    if (s->clipEnabled) {
     
    22182257    QVector<QRect> rects = region.rects();
    22192258    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
    22222286    QVarLengthArray<VGint> params(count * 4);
    22232287    int height = paintDevice()->height();
     
    29553019}
    29563020
     3021
     3022
     3023
     3024
     3025
    29573026static void drawVGImage(QVGPaintEnginePrivate *d,
    29583027                        const QRectF& r, VGImage vgImg,
     
    30263095    d->setImageMode(VG_DRAW_IMAGE_STENCIL);
    30273096    vgDrawImage(vgImg);
     3097
     3098
     3099
     3100
     3101
     3102
     3103
     3104
     3105
     3106
     3107
     3108
     3109
     3110
     3111
    30283112}
    30293113
     
    30423126        else
    30433127            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);
    30473140}
    30483141
     
    30613154        else
    30623155            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()));
    30663168}
    30673169
     
    30843186        }
    30853187    } 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        }
    30893213    }
    30903214    vgDestroyImage(vgImg);
     
    30953219    Q_D(QVGPaintEngine);
    30963220    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) {
    30983232        vgImg = toVGImage(image);
    3099     else
     3233   
    31003234        vgImg = toVGImageWithOpacity(image, d->opacity);
     3235
    31013236    drawVGImage(d, pos, vgImg);
    31023237    vgDestroyImage(vgImg);
     
    31073242{
    31083243    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());
    31113245    brush.setTransform(xform);
    31123246    fillRect(r, brush);
     
    31173251// pixmap rather than parts of the pixmap.  Even having just one of
    31183252// these conditions will improve performance.
    3119 void QVGPaintEngine::drawPixmaps
    3120     (const QDrawPixmaps::Data *drawingData, int dataCount,
    3121      const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints)
     3253void QVGPaintEngine::drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount,
     3254                                         const QPixmap &pixmap, QFlags<QPainter::PixmapFragmentHint> hints)
    31223255{
    31233256#if !defined(QT_SHIVAVG)
     
    31303263        return; // null QPixmap
    31313264    if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
    3132         QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
     3265        QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
    31333266        return;
    31343267    }
     
    31543287
    31553288    // Select the opacity paint object.
    3156     if ((hints & QDrawPixmaps::OpaqueHint) != 0 && d->opacity == 1.0f) {
     3289    if ((hints & Q::OpaqueHint) != 0 && d->opacity == 1.0f) {
    31573290        d->setImageMode(VG_DRAW_IMAGE_NORMAL);
    31583291    }  else {
     
    31663299    for (int i = 0; i < dataCount; ++i) {
    31673300        QTransform transform(d->imageTransform);
    3168         transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
     3301        transform.translate(drawingData[i].);
    31693302        transform.rotate(drawingData[i].rotation);
    31703303
    31713304        VGImage child;
    31723305        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);
    31743308        if (sr.topLeft().isNull() && sr.size() == imageSize) {
    31753309            child = vgImg;
     
    32003334        d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
    32013335
    3202         if ((hints & QDrawPixmaps::OpaqueHint) == 0) {
     3336        if ((hints & Q::OpaqueHint) == 0) {
    32033337            qreal opacity = d->opacity * drawingData[i].opacity;
    32043338            if (opacity != 1.0f) {
     
    32263360        vgDestroyImage(cachedImages[i]);
    32273361#else
    3228     QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
     3362    QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
    32293363#endif
    32303364}
     
    32573391    font = vgCreateFont(0);
    32583392    scaleX = scaleY = 0.0;
     3393
    32593394    memset(cachedGlyphsMask, 0, sizeof(cachedGlyphsMask));
    32603395}
     
    32663401}
    32673402
    3268 void QVGFontGlyphCache::setScaleFromText(const QTextItemInt &ti)
    3269 {
    3270     QFontInfo fi(ti.font());
     3403void QVGFontGlyphCache::setScaleFromText(const Q)
     3404{
     3405    QFontInfo fi();
    32713406    qreal pixelSize = fi.pixelSize();
    3272     qreal emSquare = ti.fontEngine->properties().emSquare.toReal();
     3407    qreal emSquare = fontEngine->properties().emSquare.toReal();
    32733408    scaleX = scaleY = static_cast<VGfloat>(pixelSize / emSquare);
    32743409}
    32753410
    3276 void QVGFontGlyphCache::cacheGlyphs
    3277         (QVGPaintEnginePrivate *d, const QTextItemInt &ti,
    3278          const QVarLengthArray<glyph_t> &glyphs)
     3411void QVGFontGlyphCache::cacheGlyphs
     3412        ,
     3413         )
    32793414{
    32803415    VGfloat origin[2];
    32813416    VGfloat escapement[2];
    3282     const glyph_t *g = glyphs.constData();
    3283     int count = glyphs.size();
    32843417    glyph_metrics_t metrics;
    32853418    // Some Qt font engines don't set yoff in getUnscaledGlyph().
     
    33003433#if !defined(QVG_NO_IMAGE_GLYPHS)
    33013434        Q_UNUSED(d);
    3302         QImage scaledImage = ti.fontEngine->alphaMapForGlyph(glyph);
     3435        QImage scaledImage = fontEngine->alphaMapForGlyph(glyph);
    33033436        VGImage vgImage = VG_INVALID_HANDLE;
    3304         metrics = ti.fontEngine->boundingBox(glyph);
     3437        metrics = fontEngine->boundingBox(glyph);
    33053438        if (!scaledImage.isNull()) {  // Not a space character
    33063439            if (scaledImage.format() == QImage::Format_Indexed8) {
    33073440                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());
    33093442            } else if (scaledImage.format() == QImage::Format_Mono) {
    33103443                QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8);
    33113444                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());
    33133446            } else {
    33143447                QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
    33153448                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());
    33173450            }
    33183451        }
     
    33263459        // Calculate the path for the glyph and cache it.
    33273460        QPainterPath path;
    3328         ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics);
     3461        fontEngine->getUnscaledGlyph(glyph, &path, &metrics);
    33293462        VGPath vgPath;
    33303463        if (!path.isEmpty()) {
     
    33583491        return;
    33593492    }
    3360  
     3493
    33613494    // Get the glyphs and positions associated with the text item.
    33623495    QVarLengthArray<QFixedPoint> positions;
     
    33653498    ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
    33663499
     3500
     3501
     3502
     3503
     3504
     3505
     3506
     3507
     3508
     3509
     3510
     3511
     3512
     3513
     3514
     3515
     3516
     3517
     3518
     3519
     3520
     3521
    33673522    // Find the glyph cache for this font.
    3368     QVGFontCache::ConstIterator it = d->fontCache.constFind(ti.fontEngine);
     3523    QVGFontCache::ConstIterator it = d->fontCache.constFind(fontEngine);
    33693524    QVGFontGlyphCache *glyphCache;
    33703525    if (it != d->fontCache.constEnd()) {
    33713526        glyphCache = it.value();
    33723527    } else {
     3528
     3529
     3530
    33733531        glyphCache = new QVGFontGlyphCache();
     3532
    33743533        if (glyphCache->font == VG_INVALID_HANDLE) {
    33753534            qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine");
    33763535            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);
    33823540        if (!d->fontEngineCleaner)
    33833541            d->fontEngineCleaner = new QVGFontEngineCleaner(d);
    3384         QObject::connect(ti.fontEngine, SIGNAL(destroyed()),
     3542        QObject::connect(fontEngine, SIGNAL(destroyed()),
    33853543                         d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
    33863544    }
     
    33883546    // Set the transformation to use for drawing the current glyphs.
    33893547    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    }
    33913556#if defined(QVG_NO_IMAGE_GLYPHS)
    33923557    glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
    33933558#endif
     3559
     3560
     3561
     3562
     3563
    33943564    d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
    33953565
    33963566    // Add the glyphs from the text item into the glyph cache.
    3397     glyphCache->cacheGlyphs(d, ti, glyphs);
     3567    glyphCache->cacheGlyphs(d, lyphs);
    33983568
    33993569    // 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();
    34053575    }
    34063576
    34073577    // Set the glyph drawing origin.
    34083578    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();
    34113581    vgSetfv(VG_GLYPH_ORIGIN, 2, origin);
    34123582
     
    34223592    // the Qt pen, not the Qt brush.
    34233593    d->ensureBrush(state()->pen.brush());
    3424     vgDrawGlyphs(glyphCache->font, glyphs.size(), (VGuint*)glyphs.data(),
     3594    vgDrawGlyphs(glyphCache->font, ,
    34253595                 adjustments_x.data(), adjustments_y.data(), VG_FILL_PATH, VG_TRUE);
     3596
    34263597#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;
    34303605#endif
    34313606}
     
    35373712        d->scissorMask = false;
    35383713        d->maskRect = QRect();
     3714
    35393715        clipEnabledChanged();
    35403716    }
     
    37883964            return;
    37893965        vgImageSubData
    3790             (vgImage, qt_vg_imageBits(img) + img.bytesPerLine() * (img.height() - 1),
     3966            (vgImage, ) + img.bytesPerLine() * (img.height() - 1),
    37913967             -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0,
    37923968             img.width(), img.height());
  • trunk/src/openvg/qpaintengine_vg_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation ([email protected])
     
    5555
    5656#include <QtGui/private/qpaintengineex_p.h>
     57
    5758
    5859QT_BEGIN_NAMESPACE
    5960
     61
    6062class QVGPaintEnginePrivate;
    6163class QPixmapData;
     
    137139    void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
    138140
    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);
    140143
    141144    void drawTextItem(const QPointF &p, const QTextItem &textItem);
     145
     146
     147
     148
    142149
    143150    void setState(QPainterState *s);
     
    164171    bool isDefaultClipRect(const QRect& rect);
    165172    bool clearRect(const QRectF &rect, const QColor &color);
     173
    166174};
    167 
    168175
    169176QT_END_NAMESPACE
  • trunk/src/openvg/qpixmapdata_vg.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation ([email protected])
     
    4343#include "qpaintengine_vg_p.h"
    4444#include <QtGui/private/qdrawhelper_p.h>
     45
     46
     47
    4548#include "qvg_p.h"
    4649#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>
    5853
    5954QT_BEGIN_NAMESPACE
     
    7166    inImagePool = false;
    7267    inLRU = false;
     68
    7369#if !defined(QT_NO_EGL)
    7470    context = 0;
     
    161157        (const QImage &image, Qt::ImageConversionFlags flags)
    162158{
     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
    163208    if (image.size() == QSize(w, h))
    164209        setSerialNumber(++qt_vg_pixmap_serial);
    165210    else
    166211        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
    168232    recreate = true;
    169233}
     
    234298}
    235299
    236 // This function works around QImage::bits() making a deep copy if the
    237 // 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 
    244300VGImage QVGPixmapData::toVGImage()
    245301{
    246     if (!isValid())
     302    if (!isValid())
    247303        return VG_INVALID_HANDLE;
    248304
     
    260316    if (vgImage == VG_INVALID_HANDLE) {
    261317        vgImage = QVGImagePool::instance()->createImageForPixmap
    262             (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);
     318            (, w, h, VG_IMAGE_QUALITY_FASTER, this);
    263319
    264320        // 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;
    266323            return VG_INVALID_HANDLE;
     324
    267325
    268326        inImagePool = true;
     
    274332        vgImageSubData
    275333            (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);
    278336    }
    279337
     
    429487}
    430488
    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 stuff
    539         eglDestroyImageKHR(QEglContext::display(), eglImage);
    540         driver.Close();
    541 #endif
    542     } 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_TYPE
    548 
    549         // Rasterize extended bitmaps
    550 
    551         TUid extendedBitmapType = bitmap->ExtendedBitmapType();
    552         if (extendedBitmapType != KNullUid) {
    553             bitmap = createBlitCopy(bitmap);
    554             deleteSourceBitmap = true;
    555         }
    556 #endif
    557 
    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/solid
    576             //So invert mono bitmaps so that masks work correctly.
    577             img.invertPixels();
    578         } else if(displayMode == EColor16M) {
    579             img = img.rgbSwapped(); // EColor16M is BGR
    580         }
    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 stuff
    655         vgDestroyImage(dstVgImage);
    656         eglDestroyImageKHR(QEglContext::display(), eglImage);
    657         driver.Close();
    658         return reinterpret_cast<void*>(sgImage);
    659 #endif
    660     } 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_SYMBIAN
    684 
    685489QT_END_NAMESPACE
  • trunk/src/openvg/qpixmapdata_vg_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation ([email protected])
     
    6565class QEglContext;
    6666class QVGImagePool;
     67
    6768
    6869#if !defined(QT_NO_EGL)
     
    8889    void resize(int width, int height);
    8990    void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
     91
     92
     93
     94
     95
     96