Fix spoiler rounding.
This commit is contained in:
parent
541c8d258b
commit
9da4e1e731
1 changed files with 58 additions and 44 deletions
100
ui/text/text.cpp
100
ui/text/text.cpp
|
|
@ -1765,33 +1765,23 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_background.color) {
|
const auto hasSpoiler = _background.color &&
|
||||||
const auto from = currentBlock->from();
|
(_background.inFront || _background.startMs);
|
||||||
const auto to = (nextBlock ? nextBlock->from() : _t->_text.size());
|
if (hasSpoiler) {
|
||||||
if (_localFrom + si.position < to) {
|
|
||||||
auto chFrom = _str + currentBlock->from();
|
|
||||||
auto chTo = chFrom + ((nextBlock ? nextBlock->from() : _t->_text.size()) - currentBlock->from());
|
|
||||||
if (_localFrom + si.position >= from) { // could be without space
|
|
||||||
if (chTo == chFrom || (chTo - 1)->unicode() != QChar::Space || to >= (chTo - _str)) {
|
|
||||||
fillSpoiler = { x, si.width };
|
fillSpoiler = { x, si.width };
|
||||||
} else { // or with space
|
|
||||||
fillSpoiler = { glyphX, currentBlock->f_width() };
|
|
||||||
}
|
}
|
||||||
} else if (chTo > chFrom && (chTo - 1)->unicode() == QChar::Space && (chTo - 1 - _str) >= from) {
|
const auto spoilerOpacity = hasSpoiler
|
||||||
if (rtl) { // rtl space only
|
? fillSpoilerOpacity()
|
||||||
fillSpoiler = { x, glyphX - x };
|
: 0.;
|
||||||
} else { // ltr space only
|
|
||||||
fillSpoiler = { x + currentBlock->f_width(), si.width - currentBlock->f_width() };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const auto hasSpoiler = fillSpoiler.width != QFixed();
|
|
||||||
const auto hasSelect = fillSelect.to != QFixed();
|
const auto hasSelect = fillSelect.to != QFixed();
|
||||||
if (hasSelect) {
|
if (hasSelect) {
|
||||||
fillSelectRange(fillSelect.from, fillSelect.to);
|
fillSelectRange(fillSelect.from, fillSelect.to);
|
||||||
}
|
}
|
||||||
if (!_background.inFront) {
|
const auto opacity = _p->opacity();
|
||||||
|
if (spoilerOpacity < 1.) {
|
||||||
|
if (hasSpoiler) {
|
||||||
|
_p->setOpacity(opacity * (1. - spoilerOpacity));
|
||||||
|
}
|
||||||
Emoji::Draw(
|
Emoji::Draw(
|
||||||
*_p,
|
*_p,
|
||||||
static_cast<const EmojiBlock*>(currentBlock)->_emoji,
|
static_cast<const EmojiBlock*>(currentBlock)->_emoji,
|
||||||
|
|
@ -1799,14 +1789,14 @@ private:
|
||||||
(glyphX + st::emojiPadding).toInt(),
|
(glyphX + st::emojiPadding).toInt(),
|
||||||
_y + _yDelta + emojiY);
|
_y + _yDelta + emojiY);
|
||||||
}
|
}
|
||||||
if ((hasSpoiler && _background.inFront)
|
if (hasSpoiler) {
|
||||||
|| _background.startMs) {
|
_p->setOpacity(opacity * spoilerOpacity);
|
||||||
const auto opacity = _p->opacity();
|
fillSpoilerRange(
|
||||||
const auto fillOpacity = fillSpoilerOpacity();
|
fillSpoiler.from,
|
||||||
if (fillOpacity != opacity) {
|
fillSpoiler.width,
|
||||||
_p->setOpacity(fillOpacity);
|
blockIndex,
|
||||||
}
|
currentBlock->from(),
|
||||||
fillSpoilerRange(fillSpoiler.from, fillSpoiler.width, blockIndex);
|
(nextBlock ? nextBlock->from() : _t->_text.size()));
|
||||||
_p->setOpacity(opacity);
|
_p->setOpacity(opacity);
|
||||||
}
|
}
|
||||||
// } else if (_p && currentBlock->type() == TextBlockSkip) { // debug
|
// } else if (_p && currentBlock->type() == TextBlockSkip) { // debug
|
||||||
|
|
@ -1944,7 +1934,15 @@ private:
|
||||||
selectedRect = QRect(selX.toInt(), _y + _yDelta, (selX + selWidth).toInt() - selX.toInt(), _fontHeight);
|
selectedRect = QRect(selX.toInt(), _y + _yDelta, (selX + selWidth).toInt() - selX.toInt(), _fontHeight);
|
||||||
fillSelectRange(selX, selX + selWidth);
|
fillSelectRange(selX, selX + selWidth);
|
||||||
}
|
}
|
||||||
if (!_background.inFront || _background.startMs) {
|
const auto hasSpoiler = (_background.inFront || _background.startMs);
|
||||||
|
const auto spoilerOpacity = hasSpoiler
|
||||||
|
? fillSpoilerOpacity()
|
||||||
|
: 0.;
|
||||||
|
const auto opacity = _p->opacity();
|
||||||
|
if (spoilerOpacity < 1.) {
|
||||||
|
if (hasSpoiler) {
|
||||||
|
_p->setOpacity(opacity * (1. - spoilerOpacity));
|
||||||
|
}
|
||||||
if (Q_UNLIKELY(hasSelected)) {
|
if (Q_UNLIKELY(hasSelected)) {
|
||||||
if (Q_UNLIKELY(hasNotSelected)) {
|
if (Q_UNLIKELY(hasNotSelected)) {
|
||||||
auto clippingEnabled = _p->hasClipping();
|
auto clippingEnabled = _p->hasClipping();
|
||||||
|
|
@ -1971,13 +1969,14 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_background.inFront || _background.startMs) {
|
if (hasSpoiler) {
|
||||||
const auto opacity = _p->opacity();
|
_p->setOpacity(opacity * spoilerOpacity);
|
||||||
const auto fillOpacity = fillSpoilerOpacity();
|
fillSpoilerRange(
|
||||||
if (fillOpacity != opacity) {
|
x,
|
||||||
_p->setOpacity(fillOpacity);
|
itemWidth,
|
||||||
}
|
blockIndex,
|
||||||
fillSpoilerRange(x, itemWidth, blockIndex);
|
_localFrom + itemStart,
|
||||||
|
_localFrom + itemEnd);
|
||||||
_p->setOpacity(opacity);
|
_p->setOpacity(opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2007,7 +2006,12 @@ private:
|
||||||
return (1. - std::min(progress, 1.));
|
return (1. - std::min(progress, 1.));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillSpoilerRange(QFixed x, QFixed width, int currentBlockIndex) {
|
void fillSpoilerRange(
|
||||||
|
QFixed x,
|
||||||
|
QFixed width,
|
||||||
|
int currentBlockIndex,
|
||||||
|
int positionFrom,
|
||||||
|
int positionTill) {
|
||||||
if (!_background.color) {
|
if (!_background.color) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2019,10 +2023,11 @@ private:
|
||||||
: _t->_spoilerShownCache;
|
: _t->_spoilerShownCache;
|
||||||
const auto cornerWidth = cache.corners[0].width()
|
const auto cornerWidth = cache.corners[0].width()
|
||||||
/ style::DevicePixelRatio();
|
/ style::DevicePixelRatio();
|
||||||
|
const auto useWidth = (x + width).toInt() - x.toInt();
|
||||||
const auto rect = QRect(
|
const auto rect = QRect(
|
||||||
x.toInt(),
|
x.toInt(),
|
||||||
_y + _yDelta,
|
_y + _yDelta,
|
||||||
std::max(width.toInt() - elideOffset, cornerWidth * 2),
|
std::max(useWidth - elideOffset, cornerWidth * 2),
|
||||||
_fontHeight);
|
_fontHeight);
|
||||||
if (!rect.isValid()) {
|
if (!rect.isValid()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -2030,12 +2035,21 @@ private:
|
||||||
|
|
||||||
const auto parts = [&] {
|
const auto parts = [&] {
|
||||||
const auto blockIndex = currentBlockIndex - 1;
|
const auto blockIndex = currentBlockIndex - 1;
|
||||||
const auto now = _t->_blocks[blockIndex]->spoilerIndex();
|
const auto block = _t->_blocks[blockIndex].get();
|
||||||
const auto was = (blockIndex > 0)
|
const auto nextBlock = (blockIndex + 1 < _t->_blocks.size())
|
||||||
|
? _t->_blocks[blockIndex + 1].get()
|
||||||
|
: nullptr;
|
||||||
|
const auto blockEnd = nextBlock ? nextBlock->from() : _t->_text.size();
|
||||||
|
const auto now = block->spoilerIndex();
|
||||||
|
const auto was = (positionFrom > block->from())
|
||||||
|
? now
|
||||||
|
: (blockIndex > 0)
|
||||||
? _t->_blocks[blockIndex - 1]->spoilerIndex()
|
? _t->_blocks[blockIndex - 1]->spoilerIndex()
|
||||||
: 0;
|
: 0;
|
||||||
const auto will = (blockIndex < _t->_blocks.size() - 1)
|
const auto will = (positionTill < blockEnd)
|
||||||
? _t->_blocks[blockIndex + 1]->spoilerIndex()
|
? now
|
||||||
|
: nextBlock
|
||||||
|
? nextBlock->spoilerIndex()
|
||||||
: 0;
|
: 0;
|
||||||
return RectPart::None
|
return RectPart::None
|
||||||
| ((now != was) ? (RectPart::FullLeft) : RectPart::None)
|
| ((now != was) ? (RectPart::FullLeft) : RectPart::None)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue