From 3752e158e43a7aa8ca7641017de1abca01270fc6 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 9 Nov 2022 12:33:57 +0400 Subject: [PATCH] Fix spoilers with multi-item elision blocks. --- ui/text/text_renderer.cpp | 30 +++++++++++++++++------------- ui/text/text_renderer.h | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/ui/text/text_renderer.cpp b/ui/text/text_renderer.cpp index 6c2b824..2ad871c 100644 --- a/ui/text/text_renderer.cpp +++ b/ui/text/text_renderer.cpp @@ -708,9 +708,10 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato applyBlockProperties(currentBlock); for (int i = 0; i < nItems; ++i) { - int item = firstItem + visualOrder[i]; - const QScriptItem &si = engine.layoutData->items.at(item); - bool rtl = (si.analysis.bidiLevel % 2); + const auto item = firstItem + visualOrder[i]; + const auto isLastItem = (item == lastItem); + const auto &si = engine.layoutData->items.at(item); + const auto rtl = (si.analysis.bidiLevel % 2); while (blockIndex > _lineStartBlock + 1 && _t->_blocks[blockIndex - 1]->from() > _localFrom + si.position) { nextBlock = currentBlock; @@ -842,7 +843,10 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato } } if (hasSpoiler) { - pushSpoilerRange(fillSpoiler, fillSelect, blockIndex); + // Elided item should be a text item + // with '...' at the end, so this should not be it. + const auto isElidedItem = false; + pushSpoilerRange(fillSpoiler, fillSelect, isElidedItem); } //} else if (_p && currentBlock->type() == TextBlockSkip) { // debug // _p->fillRect(QRect(x.toInt(), _y, currentBlock->width(), static_cast(currentBlock)->height()), QColor(0, 0, 0, 32)); @@ -986,12 +990,12 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato const auto hasSpoiler = _background.spoiler && (_spoilerOpacity > 0.); const auto opacity = _p->opacity(); - const auto isElidedBlock = !rtl - && (_indexOfElidedBlock == blockIndex); + const auto isElidedItem = (_indexOfElidedBlock == blockIndex) + && isLastItem; const auto complexClipping = hasSpoiler - && isElidedBlock + && isElidedItem && (_spoilerOpacity == 1.); - if (!hasSpoiler || (_spoilerOpacity < 1.) || isElidedBlock) { + if (!hasSpoiler || (_spoilerOpacity < 1.) || isElidedItem) { const auto complexClippingEnabled = complexClipping && _p->hasClipping(); const auto complexClippingRegion = complexClipping @@ -1008,7 +1012,7 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato elided, _y + 2 * _lineHeight), Qt::IntersectClip); - } else if (hasSpoiler && !isElidedBlock) { + } else if (hasSpoiler && !isElidedItem) { _p->setOpacity(opacity * (1. - _spoilerOpacity)); } if (Q_UNLIKELY(hasSelected)) { @@ -1060,13 +1064,13 @@ bool Renderer::drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterato } else { _p->setClipping(false); } - } else if (hasSpoiler && !isElidedBlock) { + } else if (hasSpoiler && !isElidedItem) { _p->setOpacity(opacity); } } if (hasSpoiler) { - pushSpoilerRange(itemRange, fillSelect, blockIndex); + pushSpoilerRange(itemRange, fillSelect, isElidedItem); } } @@ -1088,11 +1092,11 @@ void Renderer::fillSelectRange(FixedRange range) { void Renderer::pushSpoilerRange( FixedRange range, FixedRange selected, - int currentBlockIndex) { + bool isElidedItem) { if (!_background.spoiler || !_spoiler) { return; } - const auto elided = (_indexOfElidedBlock == currentBlockIndex) + const auto elided = isElidedItem ? (_elideRemoveFromEnd + _f->elidew) : 0; range.till -= elided; diff --git a/ui/text/text_renderer.h b/ui/text/text_renderer.h index 544ee55..aa41bb5 100644 --- a/ui/text/text_renderer.h +++ b/ui/text/text_renderer.h @@ -62,7 +62,7 @@ private: void pushSpoilerRange( FixedRange range, FixedRange selected, - int currentBlockIndex); + bool isElidedItem); void fillSpoilerRects(); void fillSpoilerRects( QVarLengthArray &rects,