Refactor glyph pretransform check

Move paintEngineSupportsTransformations logic from QPainter to paint
engine subclasses. Simplify and consolidate checks for cached drawing
(pretransformed) and path drawing (untransformed) in raster paint
engine. Fix unnecessary transform when paint engines actually take
the path drawing track. Fix scaling and rotation transform in raster
engine for Mac.

Task-number: QTBUG-19086
Change-Id: I1c0c1800a5173d3db765b9fccfd0e7a3628e3815
Reviewed-on: http://codereview.qt.nokia.com/298
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
This commit is contained in:
Jiang Jiang 2011-06-01 11:06:55 +02:00 committed by Qt Continuous Integration System
parent c8dead7186
commit 43c0e08ba2
9 changed files with 65 additions and 56 deletions

View File

@ -121,6 +121,8 @@ public:
void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
{ QPaintEngine::drawPolygon(points, pointCount, mode); }
bool supportsTransformations(qreal, const QTransform &) const { return true; };
protected:
friend class QMacPrintEngine;
friend class QMacPrintEnginePrivate;

View File

@ -3029,11 +3029,8 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
ensurePen();
ensureState();
QRasterPaintEngineState *s = state();
QFontEngine *fontEngine = textItem->fontEngine();
const qreal pixelSize = fontEngine->fontDef.pixelSize;
if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) < 64 * 64) {
if (!supportsTransformations(fontEngine)) {
drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
fontEngine);
} else {
@ -3061,36 +3058,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
#if defined (Q_WS_WIN) || defined(Q_WS_MAC)
bool drawCached = true;
if (s->matrix.type() >= QTransform::TxProject)
drawCached = false;
// don't try to cache huge fonts
const qreal pixelSize = ti.fontEngine->fontDef.pixelSize;
if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64)
drawCached = false;
// ### Remove the TestFontEngine and Box engine crap, in these
// ### cases we should delegate painting to the font engine
// ### directly...
#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
QFontEngine::Type fontEngineType = ti.fontEngine->type();
// qDebug() << "type" << fontEngineType << s->matrix.type();
if ((fontEngineType == QFontEngine::Win && !((QFontEngineWin *) ti.fontEngine)->ttf && s->matrix.type() > QTransform::TxTranslate)
|| (s->matrix.type() <= QTransform::TxTranslate
&& (fontEngineType == QFontEngine::TestFontEngine
|| fontEngineType == QFontEngine::Box))) {
drawCached = false;
}
#else
if (s->matrix.type() > QTransform::TxTranslate)
drawCached = false;
#endif
if (drawCached) {
QRasterPaintEngineState *s = state();
if (!supportsTransformations(ti.fontEngine)) {
QVarLengthArray<QFixedPoint> positions;
QVarLengthArray<glyph_t> glyphs;
@ -3386,6 +3354,37 @@ void QRasterPaintEngine::releaseDC(HDC) const
#endif
bool QRasterPaintEngine::supportsTransformations(const QFontEngine *fontEngine) const
{
const QTransform &m = state()->matrix;
#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
QFontEngine::Type fontEngineType = ti.fontEngine->type();
if ((fontEngineType == QFontEngine::Win && !((QFontEngineWin *) ti.fontEngine)->ttf && m.type() > QTransform::TxTranslate)
|| (m.type() <= QTransform::TxTranslate
&& (fontEngineType == QFontEngine::TestFontEngine
|| fontEngineType == QFontEngine::Box))) {
return true;
}
#endif
return supportsTransformations(fontEngine->fontDef.pixelSize, m);
}
bool QRasterPaintEngine::supportsTransformations(qreal pixelSize, const QTransform &m) const
{
#if defined(Q_WS_MAC)
// Mac font engines don't support scaling and rotation
if (m.type() > QTransform::TxTranslate)
#else
if (m.type() >= QTransform::TxProject)
#endif
return true;
if (pixelSize * pixelSize * qAbs(m.determinant()) >= 64 * 64)
return true;
return false;
}
/*!
\internal
*/

View File

@ -246,6 +246,8 @@ public:
virtual void drawBufferSpan(const uint *buffer, int bufsize,
int x, int y, int length, uint const_alpha);
#endif
bool supportsTransformations(const QFontEngine *fontEngine) const;
bool supportsTransformations(qreal pixelSize, const QTransform &m) const;
protected:
QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);

View File

@ -1093,4 +1093,14 @@ void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem)
}
}
bool QPaintEngineEx::supportsTransformations(qreal pixelSize, const QTransform &m) const
{
Q_UNUSED(pixelSize);
if (!m.isAffine())
return true;
return false;
}
QT_END_NAMESPACE

View File

@ -227,6 +227,7 @@ public:
IsEmulationEngine = 0x02 // If set, this object is a QEmulationEngine.
};
virtual uint flags() const {return 0;}
virtual bool supportsTransformations(qreal pixelSize, const QTransform &m) const;
protected:
QPaintEngineEx(QPaintEngineExPrivate &data);

View File

@ -152,14 +152,6 @@ static inline uint line_emulation(uint emulation)
| QPaintEngine_OpaqueBackground);
}
static bool qt_paintengine_supports_transformations(QPaintEngine::Type type)
{
return type == QPaintEngine::OpenGL2
|| type == QPaintEngine::OpenVG
|| type == QPaintEngine::OpenGL
|| type == QPaintEngine::CoreGraphics;
}
#ifndef QT_NO_DEBUG
static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false)
{
@ -5815,20 +5807,19 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun)
int count = qMin(glyphIndexes.size(), glyphPositions.size());
QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
bool paintEngineSupportsTransformations =
d->extended != 0
? qt_paintengine_supports_transformations(d->extended->type())
: qt_paintengine_supports_transformations(d->engine->type());
// If the matrix is not affine, the paint engine will fall back to
// drawing the glyphs as paths, which in turn means we should not
// preprocess the glyph positions
if (!d->state->matrix.isAffine())
paintEngineSupportsTransformations = true;
QRawFontPrivate *fontD = QRawFontPrivate::get(font);
bool supportsTransformations;
if (d->extended != 0) {
supportsTransformations = d->extended->supportsTransformations(fontD->fontEngine->fontDef.pixelSize,
d->state->matrix);
} else {
supportsTransformations = d->engine->type() == QPaintEngine::CoreGraphics
|| d->state->matrix.isAffine();
}
for (int i=0; i<count; ++i) {
QPointF processedPosition = position + glyphPositions.at(i);
if (!paintEngineSupportsTransformations)
if (!supportsTransformations)
processedPosition = d->state->transform().map(processedPosition);
fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
}
@ -6004,11 +5995,12 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
return;
}
bool paintEngineSupportsTransformations = qt_paintengine_supports_transformations(d->extended->type());
if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) {
bool supportsTransformations = d->extended->supportsTransformations(staticText_d->font.pixelSize(),
d->state->matrix);
if (supportsTransformations && !staticText_d->untransformedCoordinates) {
staticText_d->untransformedCoordinates = true;
staticText_d->needsRelayout = true;
} else if (!paintEngineSupportsTransformations && staticText_d->untransformedCoordinates) {
} else if (!supportsTransformations && staticText_d->untransformedCoordinates) {
staticText_d->untransformedCoordinates = false;
staticText_d->needsRelayout = true;
}

View File

@ -158,6 +158,7 @@ public:
void setRenderTextActive(bool);
bool isNativePaintingActive() const;
bool supportsTransformations(qreal, const QTransform &) const { return true; }
private:
Q_DISABLE_COPY(QGL2PaintEngineEx)
};

View File

@ -143,6 +143,7 @@ public:
Qt::HANDLE handle() const;
#endif
inline Type type() const { return QPaintEngine::OpenGL; }
bool supportsTransformations(qreal, const QTransform &) const { return true; }
private:
void drawPolyInternal(const QPolygonF &pa, bool close = true);

View File

@ -159,6 +159,7 @@ public:
QVGPaintEnginePrivate *vgPrivate() { Q_D(QVGPaintEngine); return d; }
void fillRegion(const QRegion& region, const QColor& color, const QSize& surfaceSize);
bool supportsTransformations(qreal, const QTransform &) const { return true; }
protected:
QVGPaintEngine(QVGPaintEnginePrivate &data);