Use quote instead of paragraph for quotes.
This commit is contained in:
parent
48012d7f4a
commit
9eb9fcf043
9 changed files with 275 additions and 240 deletions
|
|
@ -19,7 +19,7 @@ TextPalette {
|
|||
linkAlwaysActive: bool;
|
||||
}
|
||||
|
||||
ParagraphStyle {
|
||||
QuoteStyle {
|
||||
padding: margins;
|
||||
verticalSkip: pixels;
|
||||
header: pixels;
|
||||
|
|
@ -35,8 +35,8 @@ TextStyle {
|
|||
font: font;
|
||||
linkUnderline: int;
|
||||
lineHeight: pixels;
|
||||
blockquote: ParagraphStyle;
|
||||
pre: ParagraphStyle;
|
||||
blockquote: QuoteStyle;
|
||||
pre: QuoteStyle;
|
||||
}
|
||||
|
||||
kLinkUnderlineNever: 0;
|
||||
|
|
@ -65,14 +65,14 @@ defaultTextPalette: TextPalette {
|
|||
selectSpoilerFg: msgInDateFgSelected;
|
||||
selectOverlay: msgSelectOverlay;
|
||||
}
|
||||
defaultParagraphStyle: ParagraphStyle {
|
||||
defaultQuoteStyle: QuoteStyle {
|
||||
}
|
||||
defaultTextStyle: TextStyle {
|
||||
font: normalFont;
|
||||
linkUnderline: kLinkUnderlineActive;
|
||||
lineHeight: 0px;
|
||||
blockquote: defaultParagraphStyle;
|
||||
pre: defaultParagraphStyle;
|
||||
blockquote: defaultQuoteStyle;
|
||||
pre: defaultQuoteStyle;
|
||||
}
|
||||
semiboldTextStyle: TextStyle(defaultTextStyle) {
|
||||
font: semiboldFont;
|
||||
|
|
|
|||
179
ui/text/text.cpp
179
ui/text/text.cpp
|
|
@ -185,9 +185,9 @@ GeometryDescriptor SimpleGeometry(
|
|||
}
|
||||
};
|
||||
|
||||
void ValidateBlockPaintCache(
|
||||
BlockPaintCache &cache,
|
||||
const style::ParagraphStyle &st) {
|
||||
void ValidateQuotePaintCache(
|
||||
QuotePaintCache &cache,
|
||||
const style::QuoteStyle &st) {
|
||||
const auto icon = st.icon.empty() ? nullptr : &st.icon;
|
||||
if (!cache.corners.isNull()
|
||||
&& cache.bgCached == cache.bg
|
||||
|
|
@ -248,11 +248,11 @@ void ValidateBlockPaintCache(
|
|||
cache.corners = std::move(image);
|
||||
}
|
||||
|
||||
void FillBlockPaint(
|
||||
void FillQuotePaint(
|
||||
QPainter &p,
|
||||
QRect rect,
|
||||
const BlockPaintCache &cache,
|
||||
const style::ParagraphStyle &st,
|
||||
const QuotePaintCache &cache,
|
||||
const style::QuoteStyle &st,
|
||||
SkipBlockPaintParts parts) {
|
||||
const auto &image = cache.corners;
|
||||
const auto ratio = int(image.devicePixelRatio());
|
||||
|
|
@ -431,18 +431,18 @@ void String::recountNaturalSize(
|
|||
}
|
||||
};
|
||||
|
||||
auto pindex = paragraphIndex(nullptr);
|
||||
auto paragraph = paragraphByIndex(pindex);
|
||||
auto ppadding = paragraphPadding(paragraph);
|
||||
auto pminwidth = paragraphMinWidth(paragraph);
|
||||
auto pmaxwidth = QFixed(pminwidth);
|
||||
auto poldheight = 0;
|
||||
auto qindex = quoteIndex(nullptr);
|
||||
auto quote = quoteByIndex(qindex);
|
||||
auto qpadding = quotePadding(quote);
|
||||
auto qminwidth = quoteMinWidth(quote);
|
||||
auto qmaxwidth = QFixed(qminwidth);
|
||||
auto qoldheight = 0;
|
||||
|
||||
_maxWidth = 0;
|
||||
_minHeight = ppadding.top();
|
||||
_minHeight = qpadding.top();
|
||||
auto lineHeight = 0;
|
||||
auto maxWidth = QFixed();
|
||||
auto width = QFixed(pminwidth);
|
||||
auto width = QFixed(qminwidth);
|
||||
auto last_rBearing = QFixed();
|
||||
auto last_rPadding = QFixed();
|
||||
for (auto &block : _blocks) {
|
||||
|
|
@ -453,21 +453,24 @@ void String::recountNaturalSize(
|
|||
if (!lineHeight) {
|
||||
lineHeight = blockHeight;
|
||||
}
|
||||
const auto index = paragraphIndex(b);
|
||||
if (pindex != index) {
|
||||
_minHeight += ppadding.bottom();
|
||||
if (paragraph) {
|
||||
paragraph->maxWidth = pmaxwidth.ceil().toInt();
|
||||
paragraph->minHeight = _minHeight - poldheight;
|
||||
accumulate_max(maxWidth, width);
|
||||
accumulate_max(qmaxwidth, width);
|
||||
|
||||
const auto index = quoteIndex(b);
|
||||
if (qindex != index) {
|
||||
_minHeight += qpadding.bottom();
|
||||
if (quote) {
|
||||
quote->maxWidth = qmaxwidth.ceil().toInt();
|
||||
quote->minHeight = _minHeight - qoldheight;
|
||||
}
|
||||
poldheight = _minHeight;
|
||||
pindex = index;
|
||||
paragraph = paragraphByIndex(pindex);
|
||||
ppadding = paragraphPadding(paragraph);
|
||||
pminwidth = paragraphMinWidth(paragraph);
|
||||
pmaxwidth = pminwidth;
|
||||
_minHeight += ppadding.top();
|
||||
ppadding.setTop(0);
|
||||
qoldheight = _minHeight;
|
||||
qindex = index;
|
||||
quote = quoteByIndex(qindex);
|
||||
qpadding = quotePadding(quote);
|
||||
qminwidth = quoteMinWidth(quote);
|
||||
qmaxwidth = qminwidth;
|
||||
_minHeight += qpadding.top();
|
||||
qpadding.setTop(0);
|
||||
}
|
||||
if (initial) {
|
||||
computeParagraphDirection(b->position());
|
||||
|
|
@ -480,9 +483,7 @@ void String::recountNaturalSize(
|
|||
last_rBearing = 0;// b->f_rbearing(); (0 for newline)
|
||||
last_rPadding = 0;// b->f_rpadding(); (0 for newline)
|
||||
|
||||
accumulate_max(maxWidth, width);
|
||||
accumulate_max(pmaxwidth, width);
|
||||
width = pminwidth;
|
||||
width = qminwidth;
|
||||
// + (b->f_width() - last_rBearing); (0 for newline)
|
||||
continue;
|
||||
}
|
||||
|
|
@ -497,7 +498,7 @@ void String::recountNaturalSize(
|
|||
// for all the blocks to fit on their line we check each block, even the
|
||||
// intermediate one with a large negative right bearing.
|
||||
accumulate_max(maxWidth, width);
|
||||
accumulate_max(pmaxwidth, width);
|
||||
accumulate_max(qmaxwidth, width);
|
||||
|
||||
width += last_rBearing + (last_rPadding + b->f_width() - b__f_rbearing);
|
||||
lineHeight = qMax(lineHeight, blockHeight);
|
||||
|
|
@ -513,17 +514,17 @@ void String::recountNaturalSize(
|
|||
if (!lineHeight) {
|
||||
lineHeight = CountBlockHeight(_blocks.back().get(), _st);
|
||||
}
|
||||
_minHeight += ppadding.top() + lineHeight + ppadding.bottom();
|
||||
_minHeight += qpadding.top() + lineHeight + qpadding.bottom();
|
||||
accumulate_max(maxWidth, width);
|
||||
accumulate_max(pmaxwidth, width);
|
||||
accumulate_max(qmaxwidth, width);
|
||||
}
|
||||
_maxWidth = maxWidth.ceil().toInt();
|
||||
if (paragraph) {
|
||||
paragraph->maxWidth = pmaxwidth.ceil().toInt();
|
||||
paragraph->minHeight = _minHeight - poldheight;
|
||||
_endsWithParagraphDetails = true;
|
||||
if (quote) {
|
||||
quote->maxWidth = qmaxwidth.ceil().toInt();
|
||||
quote->minHeight = _minHeight - qoldheight;
|
||||
_endsWithQuote = true;
|
||||
} else {
|
||||
_endsWithParagraphDetails = false;
|
||||
_endsWithQuote = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -674,7 +675,7 @@ bool String::updateSkipBlock(int width, int height) {
|
|||
}
|
||||
_text.resize(block->position());
|
||||
_blocks.pop_back();
|
||||
} else if (_endsWithParagraphDetails) {
|
||||
} else if (_endsWithQuote) {
|
||||
_text.push_back(QChar::LineFeed);
|
||||
_blocks.push_back(Block::Newline(
|
||||
_st->font,
|
||||
|
|
@ -764,10 +765,10 @@ void String::enumerateLines(
|
|||
Callback callback) const {
|
||||
const auto width = QFixed(std::max(w, _minResizeWidth));
|
||||
|
||||
auto pindex = paragraphIndex(nullptr);
|
||||
auto paragraph = paragraphByIndex(pindex);
|
||||
auto ppadding = paragraphPadding(paragraph);
|
||||
auto widthLeft = width - ppadding.left() - ppadding.right();
|
||||
auto qindex = quoteIndex(nullptr);
|
||||
auto quote = quoteByIndex(qindex);
|
||||
auto qpadding = quotePadding(quote);
|
||||
auto widthLeft = width - qpadding.left() - qpadding.right();
|
||||
auto lineHeight = 0;
|
||||
auto last_rBearing = QFixed();
|
||||
auto last_rPadding = QFixed();
|
||||
|
|
@ -780,15 +781,15 @@ void String::enumerateLines(
|
|||
if (!lineHeight) {
|
||||
lineHeight = blockHeight;
|
||||
}
|
||||
lineHeight += ppadding.top();
|
||||
const auto index = paragraphIndex(b.get());
|
||||
if (pindex != index) {
|
||||
lineHeight += ppadding.bottom();
|
||||
pindex = index;
|
||||
paragraph = paragraphByIndex(pindex);
|
||||
ppadding = paragraphPadding(paragraph);
|
||||
lineHeight += qpadding.top();
|
||||
const auto index = quoteIndex(b.get());
|
||||
if (qindex != index) {
|
||||
lineHeight += qpadding.bottom();
|
||||
qindex = index;
|
||||
quote = quoteByIndex(qindex);
|
||||
qpadding = quotePadding(quote);
|
||||
} else {
|
||||
ppadding.setTop(0);
|
||||
qpadding.setTop(0);
|
||||
}
|
||||
|
||||
callback(width - widthLeft, lineHeight);
|
||||
|
|
@ -796,7 +797,7 @@ void String::enumerateLines(
|
|||
lineHeight = 0;
|
||||
last_rBearing = 0;// b->f_rbearing(); (0 for newline)
|
||||
last_rPadding = 0;// b->f_rpadding(); (0 for newline)
|
||||
widthLeft = width - ppadding.left() - ppadding.right();
|
||||
widthLeft = width - qpadding.left() - qpadding.right();
|
||||
// - (b->f_width() - last_rBearing); (0 for newline)
|
||||
|
||||
longWordLine = true;
|
||||
|
|
@ -858,15 +859,15 @@ void String::enumerateLines(
|
|||
j_width = (j->f_width() >= 0) ? j->f_width() : -j->f_width();
|
||||
}
|
||||
|
||||
callback(width - widthLeft, lineHeight + ppadding.top());
|
||||
ppadding.setTop(0);
|
||||
callback(width - widthLeft, lineHeight + qpadding.top());
|
||||
qpadding.setTop(0);
|
||||
|
||||
lineHeight = qMax(0, blockHeight);
|
||||
last_rBearing = j->f_rbearing();
|
||||
last_rPadding = j->f_rpadding();
|
||||
widthLeft = width
|
||||
- ppadding.left()
|
||||
- ppadding.right()
|
||||
- qpadding.left()
|
||||
- qpadding.right()
|
||||
- (j_width - last_rBearing);
|
||||
|
||||
longWordLine = !wordEndsHere;
|
||||
|
|
@ -877,15 +878,15 @@ void String::enumerateLines(
|
|||
continue;
|
||||
}
|
||||
|
||||
callback(width - widthLeft, lineHeight + ppadding.top());
|
||||
ppadding.setTop(0);
|
||||
callback(width - widthLeft, lineHeight + qpadding.top());
|
||||
qpadding.setTop(0);
|
||||
|
||||
lineHeight = qMax(0, blockHeight);
|
||||
last_rBearing = b__f_rbearing;
|
||||
last_rPadding = b->f_rpadding();
|
||||
widthLeft = width
|
||||
- ppadding.left()
|
||||
- ppadding.right()
|
||||
- qpadding.left()
|
||||
- qpadding.right()
|
||||
- (b->f_width() - last_rBearing);
|
||||
|
||||
longWordLine = true;
|
||||
|
|
@ -894,7 +895,7 @@ void String::enumerateLines(
|
|||
if (widthLeft < width) {
|
||||
callback(
|
||||
width - widthLeft,
|
||||
lineHeight + ppadding.top() + ppadding.bottom());
|
||||
lineHeight + qpadding.top() + qpadding.bottom());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1096,60 +1097,60 @@ uint16 String::countBlockLength(
|
|||
return countBlockEnd(i, e) - (*i)->position();
|
||||
}
|
||||
|
||||
ParagraphDetails *String::paragraphByIndex(int index) const {
|
||||
QuoteDetails *String::quoteByIndex(int index) const {
|
||||
Expects(!index
|
||||
|| (_extended && index <= _extended->paragraphs.size()));
|
||||
|| (_extended && index <= _extended->quotes.size()));
|
||||
|
||||
return index ? &_extended->paragraphs[index - 1] : nullptr;
|
||||
return index ? &_extended->quotes[index - 1] : nullptr;
|
||||
}
|
||||
|
||||
int String::paragraphIndex(const AbstractBlock *block) const {
|
||||
int String::quoteIndex(const AbstractBlock *block) const {
|
||||
Expects(!block || block->type() == TextBlockType::Newline);
|
||||
|
||||
return block
|
||||
? static_cast<const NewlineBlock*>(block)->paragraphIndex()
|
||||
: _startParagraphIndex;
|
||||
? static_cast<const NewlineBlock*>(block)->quoteIndex()
|
||||
: _startQuoteIndex;
|
||||
}
|
||||
|
||||
const style::ParagraphStyle &String::paragraphStyle(
|
||||
not_null<ParagraphDetails*> info) const {
|
||||
return info->pre ? _st->pre : _st->blockquote;
|
||||
const style::QuoteStyle &String::quoteStyle(
|
||||
not_null<QuoteDetails*> quote) const {
|
||||
return quote->pre ? _st->pre : _st->blockquote;
|
||||
}
|
||||
|
||||
QMargins String::paragraphPadding(ParagraphDetails *info) const {
|
||||
if (!info) {
|
||||
QMargins String::quotePadding(QuoteDetails *quote) const {
|
||||
if (!quote) {
|
||||
return {};
|
||||
}
|
||||
const auto &st = paragraphStyle(info);
|
||||
const auto &st = quoteStyle(quote);
|
||||
const auto skip = st.verticalSkip;
|
||||
const auto top = st.header;
|
||||
return st.padding + QMargins(0, top + skip, 0, skip);
|
||||
}
|
||||
|
||||
int String::paragraphMinWidth(ParagraphDetails *info) const {
|
||||
if (!info) {
|
||||
int String::quoteMinWidth(QuoteDetails *quote) const {
|
||||
if (!quote) {
|
||||
return 0;
|
||||
}
|
||||
const auto ppadding = paragraphPadding(info);
|
||||
const auto &pheader = paragraphHeaderText(info);
|
||||
const auto pst = info ? ¶graphStyle(info) : nullptr;
|
||||
return ppadding.left()
|
||||
+ (pheader.isEmpty() ? 0 : _st->font->monospace()->width(pheader))
|
||||
const auto qpadding = quotePadding(quote);
|
||||
const auto &qheader = quoteHeaderText(quote);
|
||||
const auto qst = quote ? "eStyle(quote) : nullptr;
|
||||
return qpadding.left()
|
||||
+ (qheader.isEmpty() ? 0 : _st->font->monospace()->width(qheader))
|
||||
+ std::max(
|
||||
ppadding.right(),
|
||||
((pst && !pst->icon.empty())
|
||||
? (pst->iconPosition.x() + pst->icon.width())
|
||||
qpadding.right(),
|
||||
((qst && !qst->icon.empty())
|
||||
? (qst->iconPosition.x() + qst->icon.width())
|
||||
: 0));
|
||||
}
|
||||
|
||||
const QString &String::paragraphHeaderText(ParagraphDetails *info) const {
|
||||
const QString &String::quoteHeaderText(QuoteDetails *quote) const {
|
||||
static const auto kEmptyHeader = QString();
|
||||
static const auto kDefaultHeader = u"code"_q;
|
||||
return (!info || !info->pre)
|
||||
return (!quote || !quote->pre)
|
||||
? kEmptyHeader
|
||||
: info->language.isEmpty()
|
||||
: quote->language.isEmpty()
|
||||
? kDefaultHeader
|
||||
: info->language;
|
||||
: quote->language;
|
||||
}
|
||||
|
||||
template <
|
||||
|
|
@ -1478,7 +1479,7 @@ void String::clear() {
|
|||
_blocks.clear();
|
||||
_extended = nullptr;
|
||||
_maxWidth = _minHeight = 0;
|
||||
_startParagraphIndex = 0;
|
||||
_startQuoteIndex = 0;
|
||||
_startParagraphLTR = false;
|
||||
_startParagraphRTL = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ enum class type : uchar;
|
|||
namespace style {
|
||||
struct TextStyle;
|
||||
struct TextPalette;
|
||||
struct ParagraphStyle;
|
||||
struct QuoteStyle;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
|
|
@ -81,7 +81,7 @@ class AbstractBlock;
|
|||
struct IsolatedEmoji;
|
||||
struct OnlyCustomEmoji;
|
||||
struct SpoilerData;
|
||||
struct ParagraphDetails;
|
||||
struct QuoteDetails;
|
||||
struct ExtendedData;
|
||||
|
||||
struct Modification {
|
||||
|
|
@ -165,7 +165,7 @@ struct GeometryDescriptor {
|
|||
bool elisionOneLine,
|
||||
bool elisionBreakEverywhere);
|
||||
|
||||
struct BlockPaintCache {
|
||||
struct QuotePaintCache {
|
||||
QImage corners;
|
||||
QColor headerCached;
|
||||
QColor bgCached;
|
||||
|
|
@ -178,19 +178,19 @@ struct BlockPaintCache {
|
|||
QColor icon;
|
||||
};
|
||||
|
||||
void ValidateBlockPaintCache(
|
||||
BlockPaintCache &cache,
|
||||
const style::ParagraphStyle &st);
|
||||
void ValidateQuotePaintCache(
|
||||
QuotePaintCache &cache,
|
||||
const style::QuoteStyle &st);
|
||||
|
||||
struct SkipBlockPaintParts {
|
||||
bool skipTop : 1 = false;
|
||||
bool skipBottom : 1 = false;
|
||||
};
|
||||
void FillBlockPaint(
|
||||
void FillQuotePaint(
|
||||
QPainter &p,
|
||||
QRect rect,
|
||||
const BlockPaintCache &cache,
|
||||
const style::ParagraphStyle &st,
|
||||
const QuotePaintCache &cache,
|
||||
const style::QuoteStyle &st,
|
||||
SkipBlockPaintParts parts = {});
|
||||
|
||||
struct PaintContext {
|
||||
|
|
@ -202,8 +202,8 @@ struct PaintContext {
|
|||
QRect clip;
|
||||
|
||||
const style::TextPalette *palette = nullptr;
|
||||
BlockPaintCache *pre = nullptr;
|
||||
BlockPaintCache *blockquote = nullptr;
|
||||
QuotePaintCache *pre = nullptr;
|
||||
QuotePaintCache *blockquote = nullptr;
|
||||
std::span<SpecialColor> colors;
|
||||
SpoilerMessCache *spoiler = nullptr;
|
||||
crl::time now = 0;
|
||||
|
|
@ -375,16 +375,15 @@ private:
|
|||
[[nodiscard]] uint16 countBlockLength(
|
||||
const TextBlocks::const_iterator &i,
|
||||
const TextBlocks::const_iterator &e) const;
|
||||
[[nodiscard]] ParagraphDetails *paragraphByIndex(int index) const;
|
||||
[[nodiscard]] const style::ParagraphStyle ¶graphStyle(
|
||||
not_null<ParagraphDetails*> info) const;
|
||||
[[nodiscard]] QMargins paragraphPadding(ParagraphDetails *info) const;
|
||||
[[nodiscard]] int paragraphMinWidth(ParagraphDetails *info) const;
|
||||
[[nodiscard]] const QString ¶graphHeaderText(
|
||||
ParagraphDetails *info) const;
|
||||
[[nodiscard]] QuoteDetails *quoteByIndex(int index) const;
|
||||
[[nodiscard]] const style::QuoteStyle "eStyle(
|
||||
not_null<QuoteDetails*> quote) const;
|
||||
[[nodiscard]] QMargins quotePadding(QuoteDetails *quote) const;
|
||||
[[nodiscard]] int quoteMinWidth(QuoteDetails *quote) const;
|
||||
[[nodiscard]] const QString "eHeaderText(QuoteDetails *quote) const;
|
||||
|
||||
// block must be either nullptr or a pointer to a NewlineBlock.
|
||||
[[nodiscard]] int paragraphIndex(const AbstractBlock *block) const;
|
||||
[[nodiscard]] int quoteIndex(const AbstractBlock *block) const;
|
||||
|
||||
// Template method for originalText(), originalTextWithEntities().
|
||||
template <
|
||||
|
|
@ -425,7 +424,7 @@ private:
|
|||
int _minResizeWidth = 0;
|
||||
int _maxWidth = 0;
|
||||
int _minHeight = 0;
|
||||
uint16 _startParagraphIndex = 0;
|
||||
uint16 _startQuoteIndex = 0;
|
||||
bool _startParagraphLTR : 1 = false;
|
||||
bool _startParagraphRTL : 1 = false;
|
||||
bool _hasCustomEmoji : 1 = false;
|
||||
|
|
@ -433,7 +432,7 @@ private:
|
|||
bool _isOnlyCustomEmoji : 1 = false;
|
||||
bool _hasNotEmojiAndSpaces : 1 = false;
|
||||
bool _skipBlockAddedNewline : 1 = false;
|
||||
bool _endsWithParagraphDetails : 1 = false;
|
||||
bool _endsWithQuote : 1 = false;
|
||||
|
||||
friend class Parser;
|
||||
friend class Renderer;
|
||||
|
|
|
|||
|
|
@ -107,15 +107,15 @@ public:
|
|||
uint16 linkIndex,
|
||||
uint16 colorIndex);
|
||||
|
||||
[[nodiscard]] uint16 paragraphIndex() const {
|
||||
return _paragraphIndex;
|
||||
[[nodiscard]] uint16 quoteIndex() const {
|
||||
return _quoteIndex;
|
||||
}
|
||||
[[nodiscard]] Qt::LayoutDirection paragraphDirection() const {
|
||||
return UnpackParagraphDirection(_paragraphLTR, _paragraphRTL);
|
||||
}
|
||||
|
||||
private:
|
||||
uint16 _paragraphIndex = 0;
|
||||
uint16 _quoteIndex = 0;
|
||||
bool _paragraphLTR : 1 = false;
|
||||
bool _paragraphRTL : 1 = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ struct SpoilerData {
|
|||
bool revealed = false;
|
||||
};
|
||||
|
||||
struct ParagraphDetails {
|
||||
struct QuoteDetails {
|
||||
QString language;
|
||||
ClickHandlerPtr copy;
|
||||
int copyWidth = 0;
|
||||
|
|
@ -56,7 +56,7 @@ struct ParagraphDetails {
|
|||
|
||||
struct ExtendedData {
|
||||
std::vector<ClickHandlerPtr> links;
|
||||
std::vector<ParagraphDetails> paragraphs;
|
||||
std::vector<QuoteDetails> quotes;
|
||||
std::unique_ptr<SpoilerData> spoiler;
|
||||
std::vector<Modification> modifications;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ void Parser::createBlock(int32 skipBack) {
|
|||
} else if (newline) {
|
||||
push(&Block::Newline);
|
||||
auto &newline = _t->_blocks.back().unsafe<NewlineBlock>();
|
||||
newline._paragraphIndex = _paragraphIndex;
|
||||
newline._quoteIndex = _quoteIndex;
|
||||
} else {
|
||||
push(&Block::Text, _t->_minResizeWidth);
|
||||
}
|
||||
|
|
@ -233,7 +233,7 @@ void Parser::createNewlineBlock(bool fromOriginalText) {
|
|||
createBlock();
|
||||
}
|
||||
|
||||
void Parser::ensureAtNewline(ParagraphDetails details) {
|
||||
void Parser::ensureAtNewline(QuoteDetails quote) {
|
||||
createBlock();
|
||||
const auto lastType = _t->_blocks.empty()
|
||||
? TextBlockType::Newline
|
||||
|
|
@ -243,15 +243,15 @@ void Parser::ensureAtNewline(ParagraphDetails details) {
|
|||
createNewlineBlock(false);
|
||||
_customEmojiData = base::take(saved);
|
||||
}
|
||||
auto ¶graphs = _t->ensureExtended()->paragraphs;
|
||||
paragraphs.push_back(std::move(details));
|
||||
const auto index = _paragraphIndex = int(paragraphs.size());
|
||||
auto "es = _t->ensureExtended()->quotes;
|
||||
quotes.push_back(std::move(quote));
|
||||
const auto index = _quoteIndex = int(quotes.size());
|
||||
if (_t->_blocks.empty()) {
|
||||
_t->_startParagraphIndex = index;
|
||||
_t->_startQuoteIndex = index;
|
||||
} else {
|
||||
auto &last = _t->_blocks.back();
|
||||
Assert(last->type() == TextBlockType::Newline);
|
||||
last.unsafe<NewlineBlock>()._paragraphIndex = index;
|
||||
last.unsafe<NewlineBlock>()._quoteIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,14 +274,14 @@ void Parser::finishEntities() {
|
|||
if ((*flags)
|
||||
& (TextBlockFlag::Pre
|
||||
| TextBlockFlag::Blockquote)) {
|
||||
_paragraphIndex = 0;
|
||||
_quoteIndex = 0;
|
||||
if (lastType != TextBlockType::Newline) {
|
||||
_newlineAwaited = true;
|
||||
} else if (_t->_blocks.empty()) {
|
||||
_t->_startParagraphIndex = 0;
|
||||
_t->_startQuoteIndex = 0;
|
||||
} else {
|
||||
auto &last = _t->_blocks.back();
|
||||
last.unsafe<NewlineBlock>()._paragraphIndex = 0;
|
||||
last.unsafe<NewlineBlock>()._quoteIndex = 0;
|
||||
}
|
||||
}
|
||||
if (IsMono(*flags)) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace Ui::Text {
|
||||
|
||||
struct ParagraphDetails;
|
||||
struct QuoteDetails;
|
||||
|
||||
class Parser {
|
||||
public:
|
||||
|
|
@ -60,7 +60,7 @@ private:
|
|||
void blockCreated();
|
||||
void createBlock(int32 skipBack = 0);
|
||||
void createNewlineBlock(bool fromOriginalText);
|
||||
void ensureAtNewline(ParagraphDetails details);
|
||||
void ensureAtNewline(QuoteDetails quote);
|
||||
|
||||
// Returns true if at least one entity was parsed in the current position.
|
||||
bool checkEntities();
|
||||
|
|
@ -115,7 +115,7 @@ private:
|
|||
uint16 _linkIndex = 0;
|
||||
uint16 _colorIndex = 0;
|
||||
uint16 _monoIndex = 0;
|
||||
uint16 _paragraphIndex = 0;
|
||||
uint16 _quoteIndex = 0;
|
||||
EmojiPtr _emoji = nullptr; // current emoji, if current word is an emoji, or zero
|
||||
int32 _blockStart = 0; // offset in result, from which current parsed block is started
|
||||
int32 _diacritics = 0; // diacritic chars skipped without good char
|
||||
|
|
|
|||
|
|
@ -179,8 +179,8 @@ void Renderer::draw(QPainter &p, const PaintContext &context) {
|
|||
? _originalPen
|
||||
: _palette->selectFg->p;
|
||||
|
||||
_x = context.position.x();
|
||||
_y = context.position.y();
|
||||
_x = _startLeft = context.position.x();
|
||||
_y = _startTop = context.position.y();
|
||||
_yFrom = context.clip.isNull() ? 0 : context.clip.y();
|
||||
_yTo = context.clip.isNull()
|
||||
? -1
|
||||
|
|
@ -206,8 +206,8 @@ void Renderer::draw(QPainter &p, const PaintContext &context) {
|
|||
? (1. - _spoiler->revealAnimation.value(
|
||||
_spoiler->revealed ? 1. : 0.))
|
||||
: 0.;
|
||||
_preBlockCache = context.pre;
|
||||
_blockquoteBlockCache = context.blockquote;
|
||||
_quotePreCache = context.pre;
|
||||
_quoteBlockquoteCache = context.blockquote;
|
||||
enumerate();
|
||||
}
|
||||
|
||||
|
|
@ -227,13 +227,10 @@ void Renderer::enumerate() {
|
|||
}
|
||||
}
|
||||
|
||||
_startLeft = _x.toInt();
|
||||
_startTop = _y;
|
||||
|
||||
if ((*_t->_blocks.cbegin())->type() != TextBlockType::Newline) {
|
||||
initNextParagraph(
|
||||
_t->_blocks.cbegin(),
|
||||
_t->_startParagraphIndex,
|
||||
_t->_startQuoteIndex,
|
||||
UnpackParagraphDirection(
|
||||
_t->_startParagraphLTR,
|
||||
_t->_startParagraphRTL));
|
||||
|
|
@ -262,9 +259,9 @@ void Renderer::enumerate() {
|
|||
if (!_lineHeight) {
|
||||
_lineHeight = blockHeight;
|
||||
}
|
||||
const auto pindex = static_cast<const NewlineBlock*>(b)->paragraphIndex();
|
||||
const auto changed = (_pindex != pindex);
|
||||
fillParagraphBg(changed ? _ppadding.bottom() : 0);
|
||||
const auto qindex = static_cast<const NewlineBlock*>(b)->quoteIndex();
|
||||
const auto changed = (_quoteIndex != qindex);
|
||||
fillParagraphBg(changed ? _quotePadding.bottom() : 0);
|
||||
if (!drawLine((*i)->position(), i, e)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -277,7 +274,7 @@ void Renderer::enumerate() {
|
|||
|
||||
initNextParagraph(
|
||||
i + 1,
|
||||
pindex,
|
||||
qindex,
|
||||
static_cast<const NewlineBlock*>(b)->paragraphDirection());
|
||||
|
||||
longWordLine = true;
|
||||
|
|
@ -395,7 +392,7 @@ void Renderer::enumerate() {
|
|||
continue;
|
||||
}
|
||||
if (_lineStart < _t->_text.size()) {
|
||||
fillParagraphBg(_ppadding.bottom());
|
||||
fillParagraphBg(_quotePadding.bottom());
|
||||
if (!drawLine(_t->_text.size(), e, e)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -407,30 +404,31 @@ void Renderer::enumerate() {
|
|||
}
|
||||
|
||||
void Renderer::fillParagraphBg(int paddingBottom) {
|
||||
const auto cache = (!_p || !_paragraph)
|
||||
const auto cache = (!_p || !_quote)
|
||||
? nullptr
|
||||
: _paragraph->pre
|
||||
? _preBlockCache
|
||||
: _paragraph->blockquote
|
||||
? _blockquoteBlockCache
|
||||
: _quote->pre
|
||||
? _quotePreCache
|
||||
: _quote->blockquote
|
||||
? _quoteBlockquoteCache
|
||||
: nullptr;
|
||||
if (cache) {
|
||||
const auto &st = _t->paragraphStyle(_paragraph);
|
||||
auto &valid = _paragraph->pre
|
||||
? _preBlockCacheValid
|
||||
: _blockquoteBlockCacheValid;
|
||||
const auto &st = _t->quoteStyle(_quote);
|
||||
auto &valid = _quote->pre
|
||||
? _quotePreValid
|
||||
: _quoteBlockquoteValid;
|
||||
if (!valid) {
|
||||
valid = true;
|
||||
ValidateBlockPaintCache(*cache, st);
|
||||
ValidateQuotePaintCache(*cache, st);
|
||||
}
|
||||
const auto skip = st.verticalSkip;
|
||||
const auto isTop = (_y != _blockLineTop);
|
||||
const auto isTop = (_y != _quoteLineTop);
|
||||
const auto isBottom = (paddingBottom != 0);
|
||||
const auto top = _blockLineTop + (isTop ? skip : 0);
|
||||
const auto left = _startLeft + _quoteShift;
|
||||
const auto top = _quoteLineTop + (isTop ? skip : 0);
|
||||
const auto fill = _y + _lineHeight + paddingBottom - top
|
||||
- (isBottom ? skip : 0);
|
||||
const auto rect = QRect(_startLeft, top, _startLineWidth, fill);
|
||||
FillBlockPaint(*_p, rect, *cache, st, {
|
||||
const auto rect = QRect(left, top, _startLineWidth, fill);
|
||||
FillQuotePaint(*_p, rect, *cache, st, {
|
||||
.skipTop = !isTop,
|
||||
.skipBottom = !isBottom,
|
||||
});
|
||||
|
|
@ -442,10 +440,10 @@ void Renderer::fillParagraphBg(int paddingBottom) {
|
|||
const auto baseline = position + QPoint(0, font->ascent);
|
||||
_p->setFont(font);
|
||||
_p->setPen(_palette->monoFg->p);
|
||||
_p->drawText(baseline, _t->paragraphHeaderText(_paragraph));
|
||||
_p->drawText(baseline, _t->quoteHeaderText(_quote));
|
||||
}
|
||||
}
|
||||
_blockLineTop = _y + _lineHeight + paddingBottom;
|
||||
_quoteLineTop = _y + _lineHeight + paddingBottom;
|
||||
}
|
||||
|
||||
StateResult Renderer::getState(
|
||||
|
|
@ -484,27 +482,28 @@ void Renderer::initNextParagraph(
|
|||
String::TextBlocks::const_iterator i,
|
||||
int16 paragraphIndex,
|
||||
Qt::LayoutDirection direction) {
|
||||
_parDirection = (direction == Qt::LayoutDirectionAuto)
|
||||
_paragraphDirection = (direction == Qt::LayoutDirectionAuto)
|
||||
? style::LayoutDirection()
|
||||
: direction;
|
||||
_parStartBlock = i;
|
||||
_paragraphStartBlock = i;
|
||||
_paragraphWidthRemaining = 0;
|
||||
if (_pindex != paragraphIndex) {
|
||||
_y += _ppadding.bottom();
|
||||
_pindex = paragraphIndex;
|
||||
_paragraph = _t->paragraphByIndex(paragraphIndex);
|
||||
_ppadding = _t->paragraphPadding(_paragraph);
|
||||
_blockLineTop = _y;
|
||||
_y += _ppadding.top();
|
||||
_ppadding.setTop(0);
|
||||
if (_quoteIndex != paragraphIndex) {
|
||||
_y += _quotePadding.bottom();
|
||||
_quoteIndex = paragraphIndex;
|
||||
_quote = _t->quoteByIndex(paragraphIndex);
|
||||
_quotePadding = _t->quotePadding(_quote);
|
||||
_quoteLineTop = _y;
|
||||
_y += _quotePadding.top();
|
||||
_quotePadding.setTop(0);
|
||||
_quoteDirection = _paragraphDirection;
|
||||
}
|
||||
const auto e = _t->_blocks.cend();
|
||||
if (i == e) {
|
||||
_lineStart = _parStart = _t->_text.size();
|
||||
_lineStart = _paragraphStart = _t->_text.size();
|
||||
_lineStartBlock = _t->_blocks.size();
|
||||
_parLength = 0;
|
||||
_paragraphLength = 0;
|
||||
} else {
|
||||
_lineStart = _parStart = (*i)->position();
|
||||
_lineStart = _paragraphStart = (*i)->position();
|
||||
_lineStartBlock = i - _t->_blocks.cbegin();
|
||||
|
||||
auto last_rPadding = QFixed(0);
|
||||
|
|
@ -520,10 +519,13 @@ void Renderer::initNextParagraph(
|
|||
- rBearing;
|
||||
last_rBearing = rBearing;
|
||||
}
|
||||
_parLength = ((i == e) ? _t->_text.size() : (*i)->position()) - _parStart;
|
||||
_paragraphLength = ((i == e)
|
||||
? _t->_text.size()
|
||||
: (*i)->position())
|
||||
- _paragraphStart;
|
||||
}
|
||||
_parAnalysis.resize(0);
|
||||
_paragraphWidthRemaining += _ppadding.left() + _ppadding.right();
|
||||
_paragraphAnalysis.resize(0);
|
||||
_paragraphWidthRemaining += _quotePadding.left() + _quotePadding.right();
|
||||
initNextLine();
|
||||
}
|
||||
|
||||
|
|
@ -533,31 +535,48 @@ void Renderer::initNextLine() {
|
|||
.top = (_y - _startTop),
|
||||
.width = _paragraphWidthRemaining.ceil().toInt(),
|
||||
});
|
||||
_blockLineTop += _startTop + line.top - _y;
|
||||
_x = _startLeft + line.left + _ppadding.left();
|
||||
_quoteLineTop += _startTop + line.top - _y;
|
||||
_x = _startLeft + line.left + _quotePadding.left();
|
||||
_y = _startTop + line.top;
|
||||
_startLineWidth = line.width;
|
||||
_lineWidth = _startLineWidth - _ppadding.left() - _ppadding.right();
|
||||
_quoteShift = 0;
|
||||
if (_quote && _quote->maxWidth < _startLineWidth) {
|
||||
const auto delta = _startLineWidth - _quote->maxWidth;
|
||||
_startLineWidth = _quote->maxWidth;
|
||||
|
||||
if (_align & Qt::AlignHCenter) {
|
||||
_quoteShift = delta / 2;
|
||||
} else if (((_align & Qt::AlignLeft)
|
||||
&& (_quoteDirection == Qt::RightToLeft))
|
||||
|| ((_align & Qt::AlignRight)
|
||||
&& (_quoteDirection == Qt::LeftToRight))) {
|
||||
_quoteShift = delta;
|
||||
}
|
||||
_x += _quoteShift;
|
||||
}
|
||||
_lineWidth = _startLineWidth
|
||||
- _quotePadding.left()
|
||||
- _quotePadding.right();
|
||||
_wLeft = _lineWidth;
|
||||
_elidedLine = line.elided;
|
||||
}
|
||||
|
||||
void Renderer::initParagraphBidi() {
|
||||
if (!_parLength || !_parAnalysis.isEmpty()) {
|
||||
if (!_paragraphLength || !_paragraphAnalysis.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String::TextBlocks::const_iterator i = _parStartBlock, e = _t->_blocks.cend(), n = i + 1;
|
||||
String::TextBlocks::const_iterator i = _paragraphStartBlock, e = _t->_blocks.cend(), n = i + 1;
|
||||
|
||||
bool ignore = false;
|
||||
bool rtl = (_parDirection == Qt::RightToLeft);
|
||||
bool rtl = (_paragraphDirection == Qt::RightToLeft);
|
||||
if (!ignore && !rtl) {
|
||||
ignore = true;
|
||||
const ushort *start = reinterpret_cast<const ushort*>(_str) + _parStart;
|
||||
const ushort *start = reinterpret_cast<const ushort*>(_str) + _paragraphStart;
|
||||
const ushort *curr = start;
|
||||
const ushort *end = start + _parLength;
|
||||
const ushort *end = start + _paragraphLength;
|
||||
while (curr < end) {
|
||||
while (n != e && (*n)->position() <= _parStart + (curr - start)) {
|
||||
while (n != e && (*n)->position() <= _paragraphStart + (curr - start)) {
|
||||
i = n;
|
||||
++n;
|
||||
}
|
||||
|
|
@ -572,21 +591,21 @@ void Renderer::initParagraphBidi() {
|
|||
}
|
||||
}
|
||||
|
||||
_parAnalysis.resize(_parLength);
|
||||
QScriptAnalysis *analysis = _parAnalysis.data();
|
||||
_paragraphAnalysis.resize(_paragraphLength);
|
||||
QScriptAnalysis *analysis = _paragraphAnalysis.data();
|
||||
|
||||
BidiControl control(rtl);
|
||||
|
||||
_parHasBidi = false;
|
||||
_paragraphHasBidi = false;
|
||||
if (ignore) {
|
||||
memset(analysis, 0, _parLength * sizeof(QScriptAnalysis));
|
||||
memset(analysis, 0, _paragraphLength * sizeof(QScriptAnalysis));
|
||||
if (rtl) {
|
||||
for (int i = 0; i < _parLength; ++i)
|
||||
for (int i = 0; i < _paragraphLength; ++i)
|
||||
analysis[i].bidiLevel = 1;
|
||||
_parHasBidi = true;
|
||||
_paragraphHasBidi = true;
|
||||
}
|
||||
} else {
|
||||
_parHasBidi = eBidiItemize(analysis, control);
|
||||
_paragraphHasBidi = eBidiItemize(analysis, control);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -651,14 +670,17 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato
|
|||
auto x = _x;
|
||||
if (_align & Qt::AlignHCenter) {
|
||||
x += (_wLeft / 2).toInt();
|
||||
} else if (((_align & Qt::AlignLeft) && _parDirection == Qt::RightToLeft) || ((_align & Qt::AlignRight) && _parDirection == Qt::LeftToRight)) {
|
||||
} else if (((_align & Qt::AlignLeft)
|
||||
&& (_paragraphDirection == Qt::RightToLeft))
|
||||
|| ((_align & Qt::AlignRight)
|
||||
&& (_paragraphDirection == Qt::LeftToRight))) {
|
||||
x += _wLeft;
|
||||
}
|
||||
|
||||
if (!_p) {
|
||||
if (_lookupX < x) {
|
||||
if (_lookupSymbol) {
|
||||
if (_parDirection == Qt::RightToLeft) {
|
||||
if (_paragraphDirection == Qt::RightToLeft) {
|
||||
_lookupResult.symbol = (_lineEnd > _lineStart) ? (_lineEnd - 1) : _lineStart;
|
||||
_lookupResult.afterSymbol = (_lineEnd > _lineStart) ? true : false;
|
||||
// _lookupResult.uponSymbol = ((_lookupX >= _x) && (_lineEnd < _t->_text.size()) && (!_endBlock || _endBlock->type() != TextBlockType::Skip)) ? true : false;
|
||||
|
|
@ -674,7 +696,7 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato
|
|||
_lookupResult.uponSymbol = false;
|
||||
return false;
|
||||
} else if (_lookupX >= x + (_lineWidth - _wLeft)) {
|
||||
if (_parDirection == Qt::RightToLeft) {
|
||||
if (_paragraphDirection == Qt::RightToLeft) {
|
||||
_lookupResult.symbol = _lineStart;
|
||||
_lookupResult.afterSymbol = false;
|
||||
// _lookupResult.uponSymbol = ((_lookupX < _x + _w) && (_lineStart > 0)) ? true : false;
|
||||
|
|
@ -700,14 +722,14 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato
|
|||
&& (_selection.from <= trimmedLineEnd)
|
||||
&& (!_endBlock || _endBlock->type() != TextBlockType::Skip);
|
||||
|
||||
if ((selectFromStart && _parDirection == Qt::LeftToRight)
|
||||
|| (selectTillEnd && _parDirection == Qt::RightToLeft)) {
|
||||
if ((selectFromStart && _paragraphDirection == Qt::LeftToRight)
|
||||
|| (selectTillEnd && _paragraphDirection == Qt::RightToLeft)) {
|
||||
if (x > _x) {
|
||||
fillSelectRange({ _x, x });
|
||||
}
|
||||
}
|
||||
if ((selectTillEnd && _parDirection == Qt::LeftToRight)
|
||||
|| (selectFromStart && _parDirection == Qt::RightToLeft)) {
|
||||
if ((selectTillEnd && _paragraphDirection == Qt::LeftToRight)
|
||||
|| (selectFromStart && _paragraphDirection == Qt::RightToLeft)) {
|
||||
if (x < _x + _wLeft) {
|
||||
fillSelectRange({ x + _lineWidth - _wLeft, _x + _lineWidth });
|
||||
}
|
||||
|
|
@ -723,7 +745,7 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato
|
|||
|
||||
_f = _t->_st->font;
|
||||
QStackTextEngine engine(lineText, _f->f);
|
||||
engine.option.setTextDirection(_parDirection);
|
||||
engine.option.setTextDirection(_paragraphDirection);
|
||||
_e = &engine;
|
||||
|
||||
eItemize();
|
||||
|
|
@ -813,7 +835,7 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato
|
|||
}
|
||||
if (_lookupSymbol) {
|
||||
if (_type == TextBlockType::Skip) {
|
||||
if (_parDirection == Qt::RightToLeft) {
|
||||
if (_paragraphDirection == Qt::RightToLeft) {
|
||||
_lookupResult.symbol = _lineStart;
|
||||
_lookupResult.afterSymbol = false;
|
||||
} else {
|
||||
|
|
@ -1291,19 +1313,25 @@ void Renderer::elideSaveBlock(int32 blockIndex, const AbstractBlock *&_endBlock,
|
|||
}
|
||||
|
||||
void Renderer::setElideBidi(int32 elideStart, int32 elideLen) {
|
||||
int32 newParLength = elideStart + elideLen - _parStart;
|
||||
if (newParLength > _parAnalysis.size()) {
|
||||
_parAnalysis.resize(newParLength);
|
||||
int32 newParLength = elideStart + elideLen - _paragraphStart;
|
||||
if (newParLength > _paragraphAnalysis.size()) {
|
||||
_paragraphAnalysis.resize(newParLength);
|
||||
}
|
||||
for (int32 i = elideLen; i > 0; --i) {
|
||||
_parAnalysis[newParLength - i].bidiLevel = (_parDirection == Qt::RightToLeft) ? 1 : 0;
|
||||
_paragraphAnalysis[newParLength - i].bidiLevel
|
||||
= (_paragraphDirection == Qt::RightToLeft) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::prepareElidedLine(QString &lineText, int32 lineStart, int32 &lineLength, const AbstractBlock *&_endBlock, int repeat) {
|
||||
void Renderer::prepareElidedLine(
|
||||
QString &lineText,
|
||||
int32 lineStart,
|
||||
int32 &lineLength,
|
||||
const AbstractBlock *&_endBlock,
|
||||
int repeat) {
|
||||
_f = _t->_st->font;
|
||||
QStackTextEngine engine(lineText, _f->f);
|
||||
engine.option.setTextDirection(_parDirection);
|
||||
engine.option.setTextDirection(_paragraphDirection);
|
||||
_e = &engine;
|
||||
|
||||
eItemize();
|
||||
|
|
@ -1318,7 +1346,10 @@ void Renderer::prepareElidedLine(QString &lineText, int32 lineStart, int32 &line
|
|||
eShapeLine(line);
|
||||
|
||||
auto elideWidth = _f->elidew;
|
||||
_wLeft = _lineWidth - _ppadding.left() - _ppadding.right() - elideWidth;
|
||||
_wLeft = _lineWidth
|
||||
- _quotePadding.left()
|
||||
- _quotePadding.right()
|
||||
- elideWidth;
|
||||
|
||||
int firstItem = engine.findItem(line.from), lastItem = engine.findItem(line.from + line.length - 1);
|
||||
int nItems = (firstItem >= 0 && lastItem >= firstItem) ? (lastItem - firstItem + 1) : 0, i;
|
||||
|
|
@ -1518,8 +1549,8 @@ void Renderer::eItemize() {
|
|||
auto currentBlock = _t->_blocks[blockIndex].get();
|
||||
auto nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||
|
||||
_e->layoutData->hasBidi = _parHasBidi;
|
||||
auto analysis = _parAnalysis.data() + (_localFrom - _parStart);
|
||||
_e->layoutData->hasBidi = _paragraphHasBidi;
|
||||
auto analysis = _paragraphAnalysis.data() + (_localFrom - _paragraphStart);
|
||||
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
|
|
@ -1568,7 +1599,7 @@ void Renderer::eItemize() {
|
|||
|
||||
{
|
||||
auto i_string = &_e->layoutData->string;
|
||||
auto i_analysis = _parAnalysis.data() + (_localFrom - _parStart);
|
||||
auto i_analysis = _paragraphAnalysis.data() + (_localFrom - _paragraphStart);
|
||||
auto i_items = &_e->layoutData->items;
|
||||
|
||||
blockIndex = _lineStartBlock;
|
||||
|
|
@ -1623,18 +1654,18 @@ QChar::Direction Renderer::eSkipBoundryNeutrals(
|
|||
|
||||
QChar::Direction dir = control.basicDirection();
|
||||
int level = sor > 0 ? analysis[sor - 1].bidiLevel : control.level;
|
||||
while (sor <= _parLength) {
|
||||
while (i != _parStartBlock && (*i)->position() > _parStart + sor) {
|
||||
while (sor <= _paragraphLength) {
|
||||
while (i != _paragraphStartBlock && (*i)->position() > _paragraphStart + sor) {
|
||||
n = i;
|
||||
--i;
|
||||
}
|
||||
while (n != e && (*n)->position() <= _parStart + sor) {
|
||||
while (n != e && (*n)->position() <= _paragraphStart + sor) {
|
||||
i = n;
|
||||
++n;
|
||||
}
|
||||
|
||||
TextBlockType _itype = (*i)->type();
|
||||
if (eor == _parLength)
|
||||
if (eor == _paragraphLength)
|
||||
dir = control.basicDirection();
|
||||
else if (_itype == TextBlockType::Emoji
|
||||
|| _itype == TextBlockType::CustomEmoji)
|
||||
|
|
@ -1662,16 +1693,16 @@ bool Renderer::eBidiItemize(QScriptAnalysis *analysis, BidiControl &control) {
|
|||
int sor = 0;
|
||||
int eor = -1;
|
||||
|
||||
const ushort *unicode = reinterpret_cast<const ushort*>(_t->_text.unicode()) + _parStart;
|
||||
const ushort *unicode = reinterpret_cast<const ushort*>(_t->_text.unicode()) + _paragraphStart;
|
||||
int current = 0;
|
||||
|
||||
QChar::Direction dir = rightToLeft ? QChar::DirR : QChar::DirL;
|
||||
BidiStatus status;
|
||||
|
||||
String::TextBlocks::const_iterator i = _parStartBlock, e = _t->_blocks.cend(), n = i + 1;
|
||||
String::TextBlocks::const_iterator i = _paragraphStartBlock, e = _t->_blocks.cend(), n = i + 1;
|
||||
|
||||
QChar::Direction sdir;
|
||||
TextBlockType _stype = (*_parStartBlock)->type();
|
||||
TextBlockType _stype = (*_paragraphStartBlock)->type();
|
||||
if (_stype == TextBlockType::Emoji || _stype == TextBlockType::CustomEmoji)
|
||||
sdir = QChar::DirCS;
|
||||
else if (_stype == TextBlockType::Skip)
|
||||
|
|
@ -1688,15 +1719,15 @@ bool Renderer::eBidiItemize(QScriptAnalysis *analysis, BidiControl &control) {
|
|||
status.last = status.lastStrong;
|
||||
status.dir = sdir;
|
||||
|
||||
while (current <= _parLength) {
|
||||
while (n != e && (*n)->position() <= _parStart + current) {
|
||||
while (current <= _paragraphLength) {
|
||||
while (n != e && (*n)->position() <= _paragraphStart + current) {
|
||||
i = n;
|
||||
++n;
|
||||
}
|
||||
|
||||
QChar::Direction dirCurrent;
|
||||
TextBlockType _itype = (*i)->type();
|
||||
if (current == (int)_parLength)
|
||||
if (current == (int)_paragraphLength)
|
||||
dirCurrent = control.basicDirection();
|
||||
else if (_itype == TextBlockType::Emoji
|
||||
|| _itype == TextBlockType::CustomEmoji)
|
||||
|
|
@ -2020,7 +2051,7 @@ bool Renderer::eBidiItemize(QScriptAnalysis *analysis, BidiControl &control) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (current >= (int)_parLength) break;
|
||||
if (current >= (int)_paragraphLength) break;
|
||||
|
||||
// set status.last as needed.
|
||||
switch (dirCurrent) {
|
||||
|
|
|
|||
|
|
@ -151,20 +151,25 @@ private:
|
|||
int _indexOfElidedBlock = -1; // For spoilers.
|
||||
|
||||
// current paragraph data
|
||||
String::TextBlocks::const_iterator _parStartBlock;
|
||||
Qt::LayoutDirection _parDirection = Qt::LayoutDirectionAuto;
|
||||
int _parStart = 0;
|
||||
int _parLength = 0;
|
||||
bool _parHasBidi = false;
|
||||
QVarLengthArray<QScriptAnalysis, 4096> _parAnalysis;
|
||||
ParagraphDetails *_paragraph = nullptr;
|
||||
int _pindex = 0;
|
||||
QMargins _ppadding;
|
||||
int _blockLineTop = 0;
|
||||
BlockPaintCache *_preBlockCache = nullptr;
|
||||
BlockPaintCache *_blockquoteBlockCache = nullptr;
|
||||
bool _preBlockCacheValid = false;
|
||||
bool _blockquoteBlockCacheValid = false;
|
||||
String::TextBlocks::const_iterator _paragraphStartBlock;
|
||||
Qt::LayoutDirection _paragraphDirection = Qt::LayoutDirectionAuto;
|
||||
int _paragraphStart = 0;
|
||||
int _paragraphLength = 0;
|
||||
bool _paragraphHasBidi = false;
|
||||
QVarLengthArray<QScriptAnalysis, 4096> _paragraphAnalysis;
|
||||
QFixed _paragraphWidthRemaining = 0;
|
||||
|
||||
// current quote data
|
||||
QuoteDetails *_quote = nullptr;
|
||||
Qt::LayoutDirection _quoteDirection = Qt::LayoutDirectionAuto;
|
||||
int _quoteShift = 0;
|
||||
int _quoteIndex = 0;
|
||||
QMargins _quotePadding;
|
||||
int _quoteLineTop = 0;
|
||||
QuotePaintCache *_quotePreCache = nullptr;
|
||||
QuotePaintCache *_quoteBlockquoteCache = nullptr;
|
||||
bool _quotePreValid = false;
|
||||
bool _quoteBlockquoteValid = false;
|
||||
|
||||
// current line data
|
||||
QTextEngine *_e = nullptr;
|
||||
|
|
@ -189,7 +194,6 @@ private:
|
|||
int _localFrom = 0;
|
||||
int _lineStartBlock = 0;
|
||||
QFixed _lineWidth = 0;
|
||||
QFixed _paragraphWidthRemaining = 0;
|
||||
|
||||
// link and symbol resolve
|
||||
QFixed _lookupX = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue