From b440068d4df72c6d564ca52d4451fe78871f9ad0 Mon Sep 17 00:00:00 2001
From: mae <qt-info@nokia.com>
Date: Wed, 2 Dec 2009 10:57:05 +0100
Subject: [PATCH] refactor search result overlay painting

---
 src/plugins/texteditor/basetexteditor.cpp    | 132 ++++++++++---------
 src/plugins/texteditor/basetexteditor_p.h    |   5 +-
 src/plugins/texteditor/texteditoroverlay.cpp |   7 +-
 3 files changed, 74 insertions(+), 70 deletions(-)

diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index f2080a75b09..4d344fd05e6 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -177,7 +177,6 @@ BaseTextEditor::BaseTextEditor(QWidget *parent)
 
     d->m_overlay = new TextEditorOverlay(this);
     d->m_searchResultOverlay = new TextEditorOverlay(this);
-    d->m_searchResultUnderlay = new TextEditorOverlay(this);
 
     d->setupDocumentSignals(d->m_document);
     d->setupDocumentSignals(d->m_document);
@@ -1865,8 +1864,7 @@ QTextBlock BaseTextEditor::collapsedBlockAt(const QPoint &pos, QRect *box) const
 }
 
 void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block,
-                                                   TextEditorOverlay *overlay,
-                                                   QVector<QTextLayout::FormatRange> *selections )
+                                                   TextEditorOverlay *overlay)
 {
     if (m_searchExpr.isEmpty())
         return;
@@ -1890,13 +1888,6 @@ void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block,
         if (m_findScope.isNull()
             || (blockPosition + idx >= m_findScope.selectionStart()
                 && blockPosition + idx + l <= m_findScope.selectionEnd())) {
-            if (selections) {
-                QTextLayout::FormatRange selection;
-                selection.start = idx;
-                selection.length = l;
-                selection.format = m_searchResultFormat;
-                selections->append(selection);
-            }
 
             overlay->addOverlaySelection(blockPosition + idx,
                                          blockPosition + idx + l,
@@ -2096,7 +2087,6 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
 //    painter.setClipRect(er);
 
     bool editable = !isReadOnly();
-
     QTextBlock block = firstVisibleBlock();
 
     QAbstractTextDocumentLayout::PaintContext context = getPaintContext();
@@ -2134,61 +2124,86 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
     QPen cursor_pen;
 
     d->m_searchResultOverlay->clear();
-    d->m_searchResultUnderlay->clear();
+    if (!d->m_searchExpr.isEmpty()) { // first pass for the search result overlays
 
-    while (block.isValid()) {
+        const int margin = 5;
+        QTextBlock blockFP = block;
+        QPointF offsetFP = offset;
+        while (blockFP.isValid()) {
+            QRectF r = blockBoundingRect(blockFP).translated(offsetFP);
 
-        QRectF r = blockBoundingRect(block).translated(offset);
+            if (r.bottom() >= er.top() - margin && r.top() <= er.bottom() + margin) {
+                d->highlightSearchResults(blockFP,
+                                          d->m_searchResultOverlay);
+            }
+            offsetFP.ry() += r.height();
 
-        if (TextEditDocumentLayout::ifdefedOut(block)) {
-            QRectF rr = r;
-            rr.setWidth(viewport()->width());
-            if (lineX > 0)
-                rr.setRight(qMin(lineX, rr.right()));
-            painter.fillRect(rr, d->m_ifdefedOutFormat.background());
+            if (offsetFP.y() > viewportRect.height() + margin)
+                break;
+
+            blockFP = blockFP.next();
         }
 
+    } // end first pass
 
-        if (!d->m_highlightBlocksInfo.isEmpty()) {
+    d->m_searchResultOverlay->fill(&painter,
+                                   d->m_searchResultFormat.background().color(),
+                                   e->rect());
 
-            int n = block.blockNumber();
-            int depth = 0;
-            foreach (int i, d->m_highlightBlocksInfo.open)
-                if (n >= i)
-                    ++depth;
-            foreach (int i, d->m_highlightBlocksInfo.close)
-                if (n > i)
-                    --depth;
 
-            int count = d->m_highlightBlocksInfo.count();
-            if (count) {
+    while (block.isValid()) {
+
+        QRectF r = blockBoundingRect(block).translated(offset);
+
+        if (r.bottom() >= er.top() && r.top() <= er.bottom()) {
+
+            if (TextEditDocumentLayout::ifdefedOut(block)) {
                 QRectF rr = r;
                 rr.setWidth(viewport()->width());
                 if (lineX > 0)
                     rr.setRight(qMin(lineX, rr.right()));
-                for (int i = 0; i <= depth; ++i) {
-                    int vi = i > 0 ? d->m_highlightBlocksInfo.visualIndent.at(i-1) : 0;
-                    painter.fillRect(rr.adjusted(vi, 0, -8*i, 0), calcBlendColor(baseColor, i, count));
+                painter.fillRect(rr, d->m_ifdefedOutFormat.background());
+            }
+
+
+            if (!d->m_highlightBlocksInfo.isEmpty()) {
+
+                int n = block.blockNumber();
+                int depth = 0;
+                foreach (int i, d->m_highlightBlocksInfo.open)
+                    if (n >= i)
+                        ++depth;
+                foreach (int i, d->m_highlightBlocksInfo.close)
+                    if (n > i)
+                        --depth;
+
+                int count = d->m_highlightBlocksInfo.count();
+                if (count) {
+                    QRectF rr = r;
+                    rr.setWidth(viewport()->width());
+                    if (lineX > 0)
+                        rr.setRight(qMin(lineX, rr.right()));
+                    for (int i = 0; i <= depth; ++i) {
+                        int vi = i > 0 ? d->m_highlightBlocksInfo.visualIndent.at(i-1) : 0;
+                        painter.fillRect(rr.adjusted(vi, 0, -8*i, 0), calcBlendColor(baseColor, i, count));
+                    }
                 }
             }
-        }
 
-        QTextLayout *layout = block.layout();
+            QTextLayout *layout = block.layout();
 
 #if 0
-        QTextOption option = layout->textOption();
-        if (TextEditDocumentLayout::ifdefedOut(block)) {
-            option.setFlags(option.flags() /*| QTextOption::SuppressColors*/);
-            painter.setPen(d->m_ifdefedOutFormat.foreground().color());
-        } else {
-            option.setFlags(option.flags() & ~QTextOption::SuppressColors);
-            painter.setPen(context.palette.text().color());
-        }
-        layout->setTextOption(option);
+            QTextOption option = layout->textOption();
+            if (TextEditDocumentLayout::ifdefedOut(block)) {
+                option.setFlags(option.flags() /*| QTextOption::SuppressColors*/);
+                painter.setPen(d->m_ifdefedOutFormat.foreground().color());
+            } else {
+                option.setFlags(option.flags() & ~QTextOption::SuppressColors);
+                painter.setPen(context.palette.text().color());
+            }
+            layout->setTextOption(option);
 #endif
 
-        if (r.bottom() >= er.top() && r.top() <= er.bottom()) {
-
             int blpos = block.position();
             int bllen = block.length();
 
@@ -2230,9 +2245,6 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
                     selections.append(o);
                 }
             }
-
-            d->highlightSearchResults(block, d->m_searchResultUnderlay, &selections);
-            d->m_searchResultOverlay->m_selections.append(d->m_searchResultUnderlay->m_selections);
             selections += prioritySelections;
 
             bool drawCursor = ((editable || true) // we want the cursor in read-only mode
@@ -2254,13 +2266,6 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
                 }
             }
 
-            if (d->m_searchResultUnderlay && !d->m_searchExpr.isEmpty()) {
-                d->m_searchResultUnderlay->fill(&painter,
-                                                d->m_searchResultFormat.background().color(),
-                                                e->rect());
-                d->m_searchResultUnderlay->clear();
-            }
-
             layout->draw(&painter, offset, selections, er);
 
             if ((drawCursor && !drawCursorAsBlock)
@@ -2276,17 +2281,15 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
                 cursor_cpos = cpos;
                 cursor_pen = painter.pen();
             }
-
-        } else if (r.bottom() >= er.top()-10 && r.top() <= er.bottom()+10) {
-                // search result overlays can cover adjacent blocks
-            d->highlightSearchResults(block, d->m_searchResultOverlay);
         }
 
         offset.ry() += r.height();
 
         if (offset.y() > viewportRect.height())
             break;
+
         block = block.next();
+
         if (!block.isVisible()) {
             if (block.blockNumber() == d->visibleCollapsedBlockNumber) {
                 visibleCollapsedBlock = block;
@@ -2496,11 +2499,10 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
     if (d->m_overlay && d->m_overlay->isVisible())
         d->m_overlay->paint(&painter, e->rect());
     
-    if (d->m_searchResultOverlay && !d->m_searchExpr.isEmpty())
+    if (!d->m_searchResultOverlay->isEmpty()) {
         d->m_searchResultOverlay->paint(&painter, e->rect());
-//        d->m_searchResultOverlay->paintInverted(&painter, e->rect(), d->m_searchResultFormat.background().color());
-
-
+        d->m_searchResultOverlay->clear();
+    }
 
     // draw the cursor last, on top of everything
     if (cursor_layout) {
diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h
index 3a7bcdc5171..88bccc86e65 100644
--- a/src/plugins/texteditor/basetexteditor_p.h
+++ b/src/plugins/texteditor/basetexteditor_p.h
@@ -189,7 +189,6 @@ public:
 
     TextEditorOverlay *m_overlay;
     TextEditorOverlay *m_searchResultOverlay;
-    TextEditorOverlay *m_searchResultUnderlay;
 
     QBasicTimer collapsedBlockTimer;
     int visibleCollapsedBlockNumber;
@@ -224,9 +223,7 @@ public:
     QTextCharFormat m_searchScopeFormat;
     QTextCharFormat m_currentLineFormat;
     QTextCharFormat m_currentLineNumberFormat;
-    void highlightSearchResults(const QTextBlock &block,
-                                TextEditorOverlay *overlay,
-                                QVector<QTextLayout::FormatRange> *selections = 0);
+    void highlightSearchResults(const QTextBlock &block, TextEditorOverlay *overlay);
     QTimer *m_delayedUpdateTimer;
 
     BaseTextEditorEditable *m_editable;
diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp
index 7c205fbbf92..162ff3157ab 100644
--- a/src/plugins/texteditor/texteditoroverlay.cpp
+++ b/src/plugins/texteditor/texteditoroverlay.cpp
@@ -61,6 +61,8 @@ void TextEditorOverlay::setVisible(bool b)
 
 void TextEditorOverlay::clear()
 {
+    if (m_selections.isEmpty())
+        return;
     m_selections.clear();
     update();
 }
@@ -90,7 +92,10 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end,
 
     selection.m_dropShadow = dropShadow;
 
-    m_selections += selection;
+    if (dropShadow)
+        m_selections.append(selection);
+    else
+        m_selections.prepend(selection);
     update();
 }
 
-- 
GitLab