Clean up addTextDecorations code
authorJiang Jiang <jiang.jiang@nokia.com>
Mon, 27 Jun 2011 14:39:42 +0000 (16:39 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 29 Jun 2011 13:22:30 +0000 (15:22 +0200)
Try avoid using QRawFont::fromFont since it requires shaping on Mac.

Change-Id: I90cc177662ecf6d0a95e722cdd0b06a01e5d0eaa
Reviewed-on: http://codereview.qt.nokia.com/793
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
src/declarative/items/qsgtextnode.cpp
src/declarative/items/qsgtextnode_p.h

index 3120d7e..c9bd7be 100644 (file)
@@ -119,32 +119,26 @@ void QSGTextNode::setStyleColor(const QColor &styleColor)
 }
 #endif
 
-void QSGTextNode::addTextDecorations(const QPointF &position, const QRawFont &font, const QColor &color,
-                                     qreal width, bool hasOverline, bool hasStrikeOut, bool hasUnderline)
+void QSGTextNode::addTextDecorations(Decoration decorations, const QPointF &position,
+                                     const QColor &color, qreal width, qreal lineThickness,
+                                     qreal underlinePos, qreal ascent)
 {
-    Q_ASSERT(font.isValid());
-    QRawFontPrivate *dptrFont = QRawFontPrivate::get(font);
-    QFontEngine *fontEngine = dptrFont->fontEngine;
-
-    qreal lineThickness = fontEngine->lineThickness().toReal();
-
     QRectF line(position.x(), position.y() - lineThickness / 2.0, width, lineThickness);
 
-    if (hasUnderline) {
-        int underlinePosition = fontEngine->underlinePosition().ceil().toInt();
+    if (decorations & Underline) {
+        int underlinePosition = qCeil(underlinePos);
         QRectF underline(line);
         underline.translate(0.0, underlinePosition);
         appendChildNode(new QSGSimpleRectNode(underline, color));
     }
 
-    qreal ascent = font.ascent();
-    if (hasOverline) {
+    if (decorations & Overline) {
         QRectF overline(line);
         overline.translate(0.0, -ascent);
         appendChildNode(new QSGSimpleRectNode(overline, color));
     }
 
-    if (hasStrikeOut) {
+    if (decorations & StrikeOut) {
         QRectF strikeOut(line);
         strikeOut.translate(0.0, ascent / -3.0);
         appendChildNode(new QSGSimpleRectNode(strikeOut, color));
@@ -171,14 +165,6 @@ QSGGlyphNode *QSGTextNode::addGlyphs(const QPointF &position, const QGlyphRun &g
         appendChildNode(node);
     }
 
-
-    if (glyphs.overline() || glyphs.strikeOut() || glyphs.underline()) {
-        QPointF baseLine = node->baseLine();
-        qreal width = node->boundingRect().width();
-        addTextDecorations(baseLine, glyphs.rawFont(), color, width,
-                           glyphs.overline(), glyphs.strikeOut(), glyphs.underline());
-    }
-
     return node;
 }
 
@@ -203,18 +189,45 @@ void QSGTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout
 
     QSGGlyphNode *prevNode = 0;
 
+    QFont font = textLayout->font();
+    qreal underlinePosition, ascent, lineThickness;
+    int decorations = NoDecoration;
+    decorations |= (font.underline() ? Underline : 0);
+    decorations |= (font.overline()  ? Overline  : 0);
+    decorations |= (font.strikeOut() ? StrikeOut : 0);
+
+    underlinePosition = ascent = lineThickness = 0;
     for (int i=0; i<glyphsList.size(); ++i) {
         QGlyphRun glyphs = glyphsList.at(i);
-        QRawFont font = glyphs.rawFont();
-        addGlyphs(position + QPointF(0, font.ascent()), glyphs, color, style, styleColor);
+        QRawFont rawfont = glyphs.rawFont();
+        prevNode = addGlyphs(position + QPointF(0, rawfont.ascent()), glyphs, color, style, styleColor);
+
+        if (decorations) {
+            qreal rawAscent = rawfont.ascent();
+            if (decorations & Underline) {
+                ascent = qMax(ascent, rawAscent);
+                qreal pos = rawfont.underlinePosition();
+                if (pos > underlinePosition) {
+                    underlinePosition = pos;
+                    // take line thickness from the rawfont with maximum underline
+                    // position in this case
+                    lineThickness = rawfont.lineThickness();
+                }
+            } else {
+                // otherwise it's strike out or overline, we take line thickness
+                // from the rawfont with maximum ascent
+                if (rawAscent > ascent) {
+                    ascent = rawAscent;
+                    lineThickness = rawfont.lineThickness();
+                }
+            }
+        }
     }
 
-    QFont font = textLayout->font();
-    QRawFont rawFont = QRawFont::fromFont(font);
-    if (font.strikeOut() || font.underline() || font.overline()) {
-        addTextDecorations(position + QPointF(0, rawFont.ascent()),
-                           rawFont, color, textLayout->boundingRect().width(),
-                           font.overline(), font.strikeOut(), font.underline());
+    if (decorations) {
+        addTextDecorations(Decoration(decorations), position + QPointF(0, ascent), color,
+                           textLayout->boundingRect().width(),
+                           lineThickness, underlinePosition, ascent);
     }
 }
 
@@ -376,8 +389,17 @@ void QSGTextNode::addTextBlock(const QPointF &position, QTextDocument *textDocum
             for (int i=0; i<glyphsList.size(); ++i) {
                 QGlyphRun glyphs = glyphsList.at(i);
                 QRawFont font = glyphs.rawFont();
-                addGlyphs(position + blockPosition + QPointF(0, font.ascent()),
-                          glyphs, color, style, styleColor);
+                QSGGlyphNode *glyphNode = addGlyphs(position + blockPosition + QPointF(0, font.ascent()),
+                                                    glyphs, color, style, styleColor);
+                int decorations = (glyphs.overline() ? Overline : 0) |
+                                  (glyphs.strikeOut() ? StrikeOut : 0) |
+                                  (glyphs.underline() ? Underline : 0);
+                if (decorations) {
+                    QPointF baseLine = glyphNode->baseLine();
+                    qreal width = glyphNode->boundingRect().width();
+                    addTextDecorations(Decoration(decorations), baseLine, color, width,
+                                       font.lineThickness(), font.underlinePosition(), font.ascent());
+                }
             }
         }
 
index e442b4c..dd4ab67 100644 (file)
@@ -70,13 +70,20 @@ public:
                          QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor());
 
 private:
+    enum Decoration {
+        NoDecoration = 0x0,
+        Underline    = 0x1,
+        Overline     = 0x2,
+        StrikeOut    = 0x4
+    };
+
     void addTextBlock(const QPointF &position, QTextDocument *textDocument, const QTextBlock &block,
                       const QColor &overrideColor, QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor());
     QSGGlyphNode *addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
                                   QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor(),
                             QSGGlyphNode *node = 0);
-    void addTextDecorations(const QPointF &position, const QRawFont &font, const QColor &color,
-                            qreal width, bool hasOverline, bool hasStrikeOut, bool hasUnderline);
+    void addTextDecorations(Decoration decorations, const QPointF &position, const QColor &color,
+                            qreal width, qreal lineThickness, qreal underlinePosition, qreal ascent);
     QSGContext *m_context;
 };