VTextDocumentLayout: draw block background for HRULE

This commit is contained in:
Le Tan 2018-07-17 20:43:43 +08:00
parent 48db50fd5e
commit 4d953542f2
11 changed files with 89 additions and 10 deletions

View File

@ -2,7 +2,6 @@
#include <QTextDocument> #include <QTextDocument>
#include <QTextBlock> #include <QTextBlock>
#include <QDebug>
#include "pegmarkdownhighlighter.h" #include "pegmarkdownhighlighter.h"
#include "utils/vutils.h" #include "utils/vutils.h"
@ -47,6 +46,8 @@ PegHighlighterResult::PegHighlighterResult(const PegMarkdownHighlighter *p_peg,
parseFencedCodeBlocks(p_peg, p_result); parseFencedCodeBlocks(p_peg, p_result);
parseMathjaxBlocks(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) 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(); const QTextDocument *doc = p_peg->getDocument();
// Inline equations. // 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) { for (auto it = inlineRegs.begin(); it != inlineRegs.end(); ++it) {
const VElementRegion &r = *it; const VElementRegion &r = *it;
@ -278,7 +279,7 @@ void PegHighlighterResult::parseMathjaxBlocks(const PegMarkdownHighlighter *p_pe
// Display formulas. // Display formulas.
// One block may be split into several regions due to list indentation. // 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; VMathjaxBlock item;
bool inBlock = false; bool inBlock = false;
QString marker("$$"); 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();
}
}
}

View File

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

View File

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

View File

@ -23,6 +23,8 @@ void PegParseResult::parse(QAtomicInt &p_stop, bool p_fast)
parseInlineEquationRegions(p_stop); parseInlineEquationRegions(p_stop);
parseDisplayFormulaRegions(p_stop); parseDisplayFormulaRegions(p_stop);
parseHRuleRegions(p_stop);
} }
void PegParseResult::parseImageRegions(QAtomicInt &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()); 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) PegParserWorker::PegParserWorker(QObject *p_parent)
: QThread(p_parent), : QThread(p_parent),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,7 +8,6 @@
#include <QFontMetrics> #include <QFontMetrics>
#include <QFont> #include <QFont>
#include <QPainter> #include <QPainter>
#include <QDebug>
#include "vimageresourcemanager2.h" #include "vimageresourcemanager2.h"
#include "vtextedit.h" #include "vtextedit.h"
@ -236,6 +235,18 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
bg); 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); auto selections = formatRangeFromSelection(block, p_context.selections);
// Draw the cursor. // Draw the cursor.