diff options
author | Alessandro Portale <alessandro.portale@nokia.com> | 2010-02-01 20:29:47 (GMT) |
---|---|---|
committer | Jesper Thomschutz <jesper.thomschutz@nokia.com> | 2010-02-03 12:40:21 (GMT) |
commit | 12075ff6fd06ce1ad758cc088deabecddf2aee8e (patch) | |
tree | e43c173303cd93a81a727d2f0a778f878a0afdc7 /src | |
parent | 7c25b9829aed56df6e3cfbc9ec8f771e7673df82 (diff) | |
download | Qt-12075ff6fd06ce1ad758cc088deabecddf2aee8e.zip Qt-12075ff6fd06ce1ad758cc088deabecddf2aee8e.tar.gz Qt-12075ff6fd06ce1ad758cc088deabecddf2aee8e.tar.bz2 |
Fixed text rendering via scaled QPainter on rasterPaintEngine / Symbian
Text rendering in Qt for Symbian looks very bad on a scaled QPainter.
Instead of simply using a Symbian font with the right size it followed
the code path that is usually used for "tricky transformation":
Use the glyph outlines and rasterize them in Qt as QPainterPath.
That's slow and especially ugly on Symbian since we do not (yet)
get the glyph outlines from Symbian.
This patch adds QFontEngineS60::setFontScale() so that QFontEngineS60
has one additional native font handle with the scaled size. The raster
paint engine will call that function in case that the painter is scaled.
Since we already have QFontEngineS60 specific code in the raster paint
engine, this patch did not have to add #ifdefs.
http://bugreports.qt.nokia.com/browse/QTBUG-7614
Task-number: QTBUG-7614
Reviewed-by: Jason Barron
modified: gui/painting/qpaintengine_raster.cpp
modified: gui/text/qfontengine_s60.cpp
modified: gui/text/qfontengine_s60_p.h
(cherry picked from commit 5a64033f89e07505bb77d3c172597b8df3cbd762)
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 9 | ||||
-rw-r--r-- | src/gui/text/qfontengine_s60.cpp | 68 | ||||
-rw-r--r-- | src/gui/text/qfontengine_s60_p.h | 10 |
3 files changed, 68 insertions, 19 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 1b88e2c..c05588f 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3081,6 +3081,8 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti) QVarLengthArray<glyph_t> glyphs; QTransform matrix = s->matrix; matrix.translate(p.x(), p.y()); + if (matrix.type() == QTransform::TxScale) + fe->setFontScale(matrix.m11()); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); const QFixed aliasDelta = QFixed::fromReal(aliasedCoordinateDelta); @@ -3097,6 +3099,9 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti) alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight); } + if (matrix.type() == QTransform::TxScale) + fe->setFontScale(1.0); + return; } #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE @@ -3269,7 +3274,9 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte } #elif defined (Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) // Q_WS_WIN || Q_WS_MAC - if (s->matrix.type() <= QTransform::TxTranslate) { + if (s->matrix.type() <= QTransform::TxTranslate + || (s->matrix.type() == QTransform::TxScale + && (qFuzzyCompare(s->matrix.m11(), s->matrix.m22())))) { drawGlyphsS60(p, ti); return; } diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index 731b052..76eb2fa 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -129,26 +129,62 @@ static inline unsigned int getChar(const QChar *str, int &i, const int len) return uc; } +CFont *QFontEngineS60::fontWithSize(qreal size) const +{ + CFont *result = 0; + TFontSpec fontSpec(qt_QString2TPtrC(QFontEngine::fontDef.family), TInt(size)); + fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap); + fontSpec.iFontStyle.SetPosture(QFontEngine::fontDef.style == QFont::StyleNormal?EPostureUpright:EPostureItalic); + fontSpec.iFontStyle.SetStrokeWeight(QFontEngine::fontDef.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal); + const TInt errorCode = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(result, fontSpec); + Q_ASSERT(result && (errorCode == 0)); + return result; +} + +void QFontEngineS60::setFontScale(qreal scale) +{ + if (qFuzzyCompare(scale, qreal(1))) { + if (!m_originalFont) + m_originalFont = fontWithSize(m_originalFontSizeInPixels); + m_activeFont = m_originalFont; + } else { + const qreal scaledFontSizeInPixels = m_originalFontSizeInPixels * scale; + if (!m_scaledFont || + (TInt(scaledFontSizeInPixels) != TInt(m_scaledFontSizeInPixels))) { + releaseFont(m_scaledFont); + m_scaledFontSizeInPixels = scaledFontSizeInPixels; + m_scaledFont = fontWithSize(m_scaledFontSizeInPixels); + } + m_activeFont = m_scaledFont; + } +} + +void QFontEngineS60::releaseFont(CFont *&font) +{ + if (font) { + S60->screenDevice()->ReleaseFont(font); + font = 0; + } +} + QFontEngineS60::QFontEngineS60(const QFontDef &request, const QFontEngineS60Extensions *extensions) : m_extensions(extensions) + , m_originalFont(0) + , m_originalFontSizeInPixels((request.pixelSize >= 0)? + request.pixelSize:pointsToPixels(request.pointSize)) + , m_scaledFont(0) + , m_scaledFontSizeInPixels(0) + , m_activeFont(0) { QFontEngine::fontDef = request; - m_fontSizeInPixels = (request.pixelSize >= 0)? - request.pixelSize:pointsToPixels(request.pointSize); - - TFontSpec fontSpec(qt_QString2TPtrC(request.family), m_fontSizeInPixels); - fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap); - fontSpec.iFontStyle.SetPosture(request.style == QFont::StyleNormal?EPostureUpright:EPostureItalic); - fontSpec.iFontStyle.SetStrokeWeight(request.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal); - const TInt errorCode = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(m_font, fontSpec); - Q_ASSERT(errorCode == 0); - + setFontScale(1.0); cache_cost = sizeof(QFontEngineS60); } QFontEngineS60::~QFontEngineS60() { - S60->screenDevice()->ReleaseFont(m_font); + releaseFont(m_originalFont); + releaseFont(m_scaledFont); } bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const @@ -251,12 +287,12 @@ glyph_metrics_t QFontEngineS60::boundingBox(glyph_t glyph) QFixed QFontEngineS60::ascent() const { - return m_font->FontMaxAscent(); + return m_originalFont->FontMaxAscent(); } QFixed QFontEngineS60::descent() const { - return m_font->FontMaxDescent(); + return m_originalFont->FontMaxDescent(); } QFixed QFontEngineS60::leading() const @@ -266,7 +302,7 @@ QFixed QFontEngineS60::leading() const qreal QFontEngineS60::maxCharWidth() const { - return m_font->MaxCharWidthInPixels(); + return m_originalFont->MaxCharWidthInPixels(); } const char *QFontEngineS60::name() const @@ -302,11 +338,11 @@ void QFontEngineS60::getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metri const TUint specialCode = (TUint)glyph | 0x80000000; const CFont::TCharacterDataAvailability availability = - m_font->GetCharacterData(specialCode, metrics, bitmap, bitmapSize); + m_activeFont->GetCharacterData(specialCode, metrics, bitmap, bitmapSize); const glyph_t fallbackGlyph = '?'; if (availability != CFont::EAllCharacterData) { const CFont::TCharacterDataAvailability fallbackAvailability = - m_font->GetCharacterData(fallbackGlyph, metrics, bitmap, bitmapSize); + m_activeFont->GetCharacterData(fallbackGlyph, metrics, bitmap, bitmapSize); Q_ASSERT(fallbackAvailability == CFont::EAllCharacterData); } } diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h index 2384a04..a3edd3b 100644 --- a/src/gui/text/qfontengine_s60_p.h +++ b/src/gui/text/qfontengine_s60_p.h @@ -120,15 +120,21 @@ public: Type type() const; void getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metrics, const TUint8*& bitmap, TSize& bitmapSize) const; + void setFontScale(qreal scale); private: friend class QFontPrivate; QFixed glyphAdvance(HB_Glyph glyph) const; + CFont *fontWithSize(qreal size) const; + static void releaseFont(CFont *&font); - CFont* m_font; const QFontEngineS60Extensions *m_extensions; - qreal m_fontSizeInPixels; + CFont* m_originalFont; + const qreal m_originalFontSizeInPixels; + CFont* m_scaledFont; + qreal m_scaledFontSizeInPixels; + CFont* m_activeFont; }; class QFontEngineMultiS60 : public QFontEngineMulti |