src/openvg/qpaintengine_vg.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    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 #include "qvgimagepool_p.h"
       
    47 #include "qvgfontglyphcache_p.h"
    47 #if !defined(QT_NO_EGL)
    48 #if !defined(QT_NO_EGL)
    48 #include <QtGui/private/qeglcontext_p.h>
    49 #include <QtGui/private/qeglcontext_p.h>
    49 #include "qwindowsurface_vgegl_p.h"
    50 #include "qwindowsurface_vgegl_p.h"
    50 #endif
    51 #endif
    51 #include <QtCore/qvarlengtharray.h>
    52 #include <QtCore/qvarlengtharray.h>
    52 #include <QtGui/private/qdrawhelper_p.h>
    53 #include <QtGui/private/qdrawhelper_p.h>
    53 #include <QtGui/private/qtextengine_p.h>
    54 #include <QtGui/private/qtextengine_p.h>
    54 #include <QtGui/private/qfontengine_p.h>
    55 #include <QtGui/private/qfontengine_p.h>
    55 #include <QtGui/private/qpainterpath_p.h>
    56 #include <QtGui/private/qpainterpath_p.h>
    56 #include <QtGui/private/qstatictext_p.h>
    57 #include <QtGui/private/qstatictext_p.h>
       
    58 #include <QtCore/qmath.h>
    57 #include <QDebug>
    59 #include <QDebug>
    58 #include <QSet>
    60 #include <QSet>
    59 
    61 
    60 QT_BEGIN_NAMESPACE
    62 QT_BEGIN_NAMESPACE
    61 
    63 
    77 
    79 
    78 Q_DECL_IMPORT extern int qt_defaultDpiX();
    80 Q_DECL_IMPORT extern int qt_defaultDpiX();
    79 Q_DECL_IMPORT extern int qt_defaultDpiY();
    81 Q_DECL_IMPORT extern int qt_defaultDpiY();
    80 
    82 
    81 class QVGPaintEnginePrivate;
    83 class QVGPaintEnginePrivate;
    82 
       
    83 class QVGFontGlyphCache
       
    84 {
       
    85 public:
       
    86     QVGFontGlyphCache();
       
    87     ~QVGFontGlyphCache();
       
    88 
       
    89     void cacheGlyphs(QVGPaintEnginePrivate *d, QFontEngine *fontEngine, const glyph_t *g, int count);
       
    90 
       
    91     void setScaleFromText(const QFont &font, QFontEngine *fontEngine);
       
    92 
       
    93     VGFont font;
       
    94     VGfloat scaleX;
       
    95     VGfloat scaleY;
       
    96 
       
    97     uint cachedGlyphsMask[256 / 32];
       
    98     QSet<glyph_t> cachedGlyphs;
       
    99 };
       
   100 
    84 
   101 typedef QHash<QFontEngine*, QVGFontGlyphCache*> QVGFontCache;
    85 typedef QHash<QFontEngine*, QVGFontGlyphCache*> QVGFontCache;
   102 
    86 
   103 #endif
    87 #endif
   104 
    88 
  1620         // Convert it into a QRect and apply.
  1604         // Convert it into a QRect and apply.
  1621         const qreal *points = path.points();
  1605         const qreal *points = path.points();
  1622         QRectF rect(points[0], points[1], points[2] - points[0],
  1606         QRectF rect(points[0], points[1], points[2] - points[0],
  1623                     points[5] - points[1]);
  1607                     points[5] - points[1]);
  1624         clip(rect.toRect(), op);
  1608         clip(rect.toRect(), op);
  1625     } else {
  1609         return;
  1626         // The best we can do is clip to the bounding rectangle
  1610     }
  1627         // of all control points.
  1611 
  1628         clip(path.controlPointRect().toRect(), op);
  1612     // Try converting the path into a QRegion that tightly follows
  1629     }
  1613     // the outline of the path we want to clip with.
       
  1614     QRegion region;
       
  1615     if (!path.isEmpty())
       
  1616         region = QRegion(path.convertToPainterPath().toFillPolygon(QTransform()).toPolygon());
       
  1617 
       
  1618     switch (op) {
       
  1619         case Qt::NoClip:
       
  1620         {
       
  1621             region = defaultClipRegion();
       
  1622         }
       
  1623         break;
       
  1624 
       
  1625         case Qt::ReplaceClip:
       
  1626         {
       
  1627             region = d->transform.map(region);
       
  1628         }
       
  1629         break;
       
  1630 
       
  1631         case Qt::IntersectClip:
       
  1632         {
       
  1633             region = s->clipRegion.intersect(d->transform.map(region));
       
  1634         }
       
  1635         break;
       
  1636 
       
  1637         case Qt::UniteClip:
       
  1638         {
       
  1639             region = s->clipRegion.unite(d->transform.map(region));
       
  1640         }
       
  1641         break;
       
  1642     }
       
  1643     if (region.numRects() <= d->maxScissorRects) {
       
  1644         // We haven't reached the maximum scissor count yet, so we can
       
  1645         // still make use of this region.
       
  1646         s->clipRegion = region;
       
  1647         updateScissor();
       
  1648         return;
       
  1649     }
       
  1650 
       
  1651     // The best we can do is clip to the bounding rectangle
       
  1652     // of all control points.
       
  1653     clip(path.controlPointRect().toRect(), op);
  1630 }
  1654 }
  1631 
  1655 
  1632 void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
  1656 void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
  1633 {
  1657 {
  1634     Q_D(QVGPaintEngine);
  1658     Q_D(QVGPaintEngine);
  3250 
  3274 
  3251 QVGFontGlyphCache::QVGFontGlyphCache()
  3275 QVGFontGlyphCache::QVGFontGlyphCache()
  3252 {
  3276 {
  3253     font = vgCreateFont(0);
  3277     font = vgCreateFont(0);
  3254     scaleX = scaleY = 0.0;
  3278     scaleX = scaleY = 0.0;
       
  3279     invertedGlyphs = false;
  3255     memset(cachedGlyphsMask, 0, sizeof(cachedGlyphsMask));
  3280     memset(cachedGlyphsMask, 0, sizeof(cachedGlyphsMask));
  3256 }
  3281 }
  3257 
  3282 
  3258 QVGFontGlyphCache::~QVGFontGlyphCache()
  3283 QVGFontGlyphCache::~QVGFontGlyphCache()
  3259 {
  3284 {
  3384     QVGFontCache::ConstIterator it = d->fontCache.constFind(fontEngine);
  3409     QVGFontCache::ConstIterator it = d->fontCache.constFind(fontEngine);
  3385     QVGFontGlyphCache *glyphCache;
  3410     QVGFontGlyphCache *glyphCache;
  3386     if (it != d->fontCache.constEnd()) {
  3411     if (it != d->fontCache.constEnd()) {
  3387         glyphCache = it.value();
  3412         glyphCache = it.value();
  3388     } else {
  3413     } else {
       
  3414 #ifdef Q_OS_SYMBIAN
       
  3415         glyphCache = new QSymbianVGFontGlyphCache();
       
  3416 #else
  3389         glyphCache = new QVGFontGlyphCache();
  3417         glyphCache = new QVGFontGlyphCache();
       
  3418 #endif
  3390         if (glyphCache->font == VG_INVALID_HANDLE) {
  3419         if (glyphCache->font == VG_INVALID_HANDLE) {
  3391             qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine");
  3420             qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine");
  3392             delete glyphCache;
  3421             delete glyphCache;
  3393             return false;
  3422             return false;
  3394         }
  3423         }
  3400                          d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
  3429                          d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
  3401     }
  3430     }
  3402 
  3431 
  3403     // Set the transformation to use for drawing the current glyphs.
  3432     // Set the transformation to use for drawing the current glyphs.
  3404     QTransform glyphTransform(d->pathTransform);
  3433     QTransform glyphTransform(d->pathTransform);
  3405     glyphTransform.translate(p.x(), p.y());
  3434     if (d->transform.type() <= QTransform::TxTranslate) {
       
  3435         // Prevent blurriness of unscaled, unrotated text by using integer coordinates.
       
  3436         // Using ceil(x-0.5) instead of qRound() or int-cast, behave like other paint engines.
       
  3437         glyphTransform.translate(ceil(p.x() - 0.5), ceil(p.y() - 0.5));
       
  3438     } else {
       
  3439         glyphTransform.translate(p.x(), p.y());
       
  3440     }
  3406 #if defined(QVG_NO_IMAGE_GLYPHS)
  3441 #if defined(QVG_NO_IMAGE_GLYPHS)
  3407     glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
  3442     glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
  3408 #endif
  3443 #endif
       
  3444 
       
  3445     // Some glyph caches can create the VGImage upright
       
  3446     if (glyphCache->invertedGlyphs)
       
  3447         glyphTransform.scale(1, -1);
       
  3448 
  3409     d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
  3449     d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
  3410 
  3450 
  3411     // Add the glyphs from the text item into the glyph cache.
  3451     // Add the glyphs from the text item into the glyph cache.
  3412     glyphCache->cacheGlyphs(d, fontEngine, glyphs, numGlyphs);
  3452     glyphCache->cacheGlyphs(d, fontEngine, glyphs, numGlyphs);
  3413 
  3453