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 <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();
}
}
}

View File

@ -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,

View File

@ -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.

View File

@ -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),

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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.