Browse Source

VTextDocumentLayout: draw block background for HRULE

Le Tan 7 years ago
parent
commit
4d953542f2

+ 27 - 3
src/peghighlighterresult.cpp

@@ -2,7 +2,6 @@
 
 #include <QTextDocument>
 #include <QTextBlock>
-#include <QDebug>
 
 #include "pegmarkdownhighlighter.h"
 #include "utils/vutils.h"
@@ -47,6 +46,8 @@ PegHighlighterResult::PegHighlighterResult(const PegMarkdownHighlighter *p_peg,
     parseFencedCodeBlocks(p_peg, p_result);
 
     parseMathjaxBlocks(p_peg, p_result);
+
+    parseHRuleBlocks(p_peg, p_result);
 }
 
 static bool compHLUnit(const HLUnit &p_a, const HLUnit &p_b)
@@ -251,7 +252,7 @@ void PegHighlighterResult::parseMathjaxBlocks(const PegMarkdownHighlighter *p_pe
     const QTextDocument *doc = p_peg->getDocument();
 
     // Inline equations.
-    const QVector<VElementRegion> inlineRegs = p_result->m_inlineEquationRegions;
+    const QVector<VElementRegion> &inlineRegs = p_result->m_inlineEquationRegions;
 
     for (auto it = inlineRegs.begin(); it != inlineRegs.end(); ++it) {
         const VElementRegion &r = *it;
@@ -278,7 +279,7 @@ void PegHighlighterResult::parseMathjaxBlocks(const PegMarkdownHighlighter *p_pe
 
     // Display formulas.
     // One block may be split into several regions due to list indentation.
-    const QVector<VElementRegion> formulaRegs = p_result->m_displayFormulaRegions;
+    const QVector<VElementRegion> &formulaRegs = p_result->m_displayFormulaRegions;
     VMathjaxBlock item;
     bool inBlock = false;
     QString marker("$$");
@@ -327,3 +328,26 @@ void PegHighlighterResult::parseMathjaxBlocks(const PegMarkdownHighlighter *p_pe
         }
     }
 }
+
+void PegHighlighterResult::parseHRuleBlocks(const PegMarkdownHighlighter *p_peg,
+                                            const QSharedPointer<PegParseResult> &p_result)
+{
+    const QTextDocument *doc = p_peg->getDocument();
+    const QVector<VElementRegion> &regs = p_result->m_hruleRegions;
+
+    for (auto it = regs.begin(); it != regs.end(); ++it) {
+        QTextBlock block = doc->findBlock(it->m_startPos);
+        int lastBlock = doc->findBlock(it->m_endPos - 1).blockNumber();
+
+        while (block.isValid()) {
+            int blockNumber = block.blockNumber();
+            if (blockNumber > lastBlock) {
+                break;
+            }
+
+            m_hruleBlocks.insert(blockNumber);
+
+            block = block.next();
+        }
+    }
+}

+ 7 - 1
src/peghighlighterresult.h

@@ -72,6 +72,8 @@ public:
     // All MathJax blocks.
     QVector<VMathjaxBlock> m_mathjaxBlocks;
 
+    QSet<int> m_hruleBlocks;
+
 private:
     // Parse highlight elements for blocks from one parse result.
     static void parseBlocksHighlightOne(QVector<QVector<HLUnit>> &p_blocksHighlights,
@@ -84,10 +86,14 @@ private:
     void parseFencedCodeBlocks(const PegMarkdownHighlighter *p_peg,
                                const QSharedPointer<PegParseResult> &p_result);
 
-    // Parse fenced code blocks from parse results.
+    // Parse mathjax blocks from parse results.
     void parseMathjaxBlocks(const PegMarkdownHighlighter *p_peg,
                             const QSharedPointer<PegParseResult> &p_result);
 
+    // Parse HRule blocks from parse results.
+    void parseHRuleBlocks(const PegMarkdownHighlighter *p_peg,
+                          const QSharedPointer<PegParseResult> &p_result);
+
     void parseBlocksElementRegionOne(QHash<int, QVector<VElementRegion>> &p_regs,
                                      const QTextDocument *p_doc,
                                      unsigned long p_pos,

+ 2 - 0
src/pegmarkdownhighlighter.cpp

@@ -468,6 +468,8 @@ void PegMarkdownHighlighter::updateBlockUserState(const QSharedPointer<PegHighli
             Q_ASSERT(false);
             break;
         }
+    } else if (p_result->m_hruleBlocks.contains(p_blockNum)) {
+        state = HighlightBlockState::HRule;
     }
 
     // Set code block state.

+ 25 - 0
src/pegparser.cpp

@@ -23,6 +23,8 @@ void PegParseResult::parse(QAtomicInt &p_stop, bool p_fast)
     parseInlineEquationRegions(p_stop);
 
     parseDisplayFormulaRegions(p_stop);
+
+    parseHRuleRegions(p_stop);
 }
 
 void PegParseResult::parseImageRegions(QAtomicInt &p_stop)
@@ -161,6 +163,29 @@ void PegParseResult::parseDisplayFormulaRegions(QAtomicInt &p_stop)
     std::sort(m_displayFormulaRegions.begin(), m_displayFormulaRegions.end());
 }
 
+void PegParseResult::parseHRuleRegions(QAtomicInt &p_stop)
+{
+    m_hruleRegions.clear();
+    if (isEmpty()) {
+        return;
+    }
+
+    pmh_element *elem = m_pmhElements[pmh_HRULE];
+    while (elem != NULL) {
+        if (elem->end <= elem->pos) {
+            elem = elem->next;
+            continue;
+        }
+
+        if (p_stop.load() == 1) {
+            return;
+        }
+
+        m_hruleRegions.push_back(VElementRegion(m_offset + elem->pos, m_offset + elem->end));
+        elem = elem->next;
+    }
+}
+
 
 PegParserWorker::PegParserWorker(QObject *p_parent)
     : QThread(p_parent),

+ 5 - 0
src/pegparser.h

@@ -111,6 +111,9 @@ struct PegParseResult
     // Sorted by start position.
     QVector<VElementRegion> m_displayFormulaRegions;
 
+    // HRule regions.
+    QVector<VElementRegion> m_hruleRegions;
+
 private:
     void parseImageRegions(QAtomicInt &p_stop);
 
@@ -121,6 +124,8 @@ private:
     void parseInlineEquationRegions(QAtomicInt &p_stop);
 
     void parseDisplayFormulaRegions(QAtomicInt &p_stop);
+
+    void parseHRuleRegions(QAtomicInt &p_stop);
 };
 
 class PegParserWorker : public QThread

+ 2 - 1
src/resources/themes/v_detorte/v_detorte.mdhl

@@ -86,7 +86,8 @@ font-style: bold
 font-size: +2
 
 HRULE
-foreground: 9885ba
+foreground: dadada
+background: 614145
 
 LIST_BULLET
 foreground: e37c84

+ 2 - 1
src/resources/themes/v_moonlight/v_moonlight.mdhl

@@ -86,7 +86,8 @@ font-style: bold
 font-size: +2
 
 HRULE
-foreground: 8b90f3
+foreground: abb2bf
+background: 493134
 
 LIST_BULLET
 foreground: e06c75

+ 2 - 1
src/resources/themes/v_native/v_native.mdhl

@@ -83,7 +83,8 @@ font-style: bold
 font-size: +2
 
 HRULE
-foreground: 586e75
+foreground: 363636
+background: dac7c9
 
 LIST_BULLET
 foreground: d33682

+ 2 - 1
src/resources/themes/v_pure/v_pure.mdhl

@@ -84,7 +84,8 @@ font-style: bold
 font-size: +2
 
 HRULE
-foreground: 586e75
+foreground: 222222
+background: dac7c9
 
 LIST_BULLET
 foreground: d33682

+ 3 - 1
src/vconstants.h

@@ -119,7 +119,9 @@ enum HighlightBlockState
     // A fenced code block.
     CodeBlockStart,
     CodeBlock,
-    CodeBlockEnd
+    CodeBlockEnd,
+
+    HRule
 };
 
 // Pages to open on start up.

+ 12 - 1
src/vtextdocumentlayout.cpp

@@ -8,7 +8,6 @@
 #include <QFontMetrics>
 #include <QFont>
 #include <QPainter>
-#include <QDebug>
 
 #include "vimageresourcemanager2.h"
 #include "vtextedit.h"
@@ -236,6 +235,18 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
                            bg);
         }
 
+        // Draw block background for HRULE.
+        if (block.userState() == HighlightBlockState::HRule) {
+            QVector<QTextLayout::FormatRange> fmts = layout->formats();
+            if (fmts.size() == 1) {
+                int x = offset.x();
+                int y = offset.y();
+                fillBackground(p_painter,
+                               rect.adjusted(x, y, x, y),
+                               fmts[0].format.background());
+            }
+        }
+
         auto selections = formatRangeFromSelection(block, p_context.selections);
 
         // Draw the cursor.