mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Use std::unique_ptrs for ITextBlocks.
This commit is contained in:
parent
8550099110
commit
8d43bdb084
3 changed files with 97 additions and 99 deletions
|
@ -178,13 +178,13 @@ public:
|
||||||
}
|
}
|
||||||
lastSkipped = false;
|
lastSkipped = false;
|
||||||
if (emoji) {
|
if (emoji) {
|
||||||
_t->_blocks.push_back(new EmojiBlock(_t->_st->font, _t->_text, blockStart, len, flags, lnkIndex, emoji));
|
_t->_blocks.push_back(std::make_unique<EmojiBlock>(_t->_st->font, _t->_text, blockStart, len, flags, lnkIndex, emoji));
|
||||||
emoji = 0;
|
emoji = 0;
|
||||||
lastSkipped = true;
|
lastSkipped = true;
|
||||||
} else if (newline) {
|
} else if (newline) {
|
||||||
_t->_blocks.push_back(new NewlineBlock(_t->_st->font, _t->_text, blockStart, len, flags, lnkIndex));
|
_t->_blocks.push_back(std::make_unique<NewlineBlock>(_t->_st->font, _t->_text, blockStart, len, flags, lnkIndex));
|
||||||
} else {
|
} else {
|
||||||
_t->_blocks.push_back(new TextBlock(_t->_st->font, _t->_text, _t->_minResizeWidth, blockStart, len, flags, lnkIndex));
|
_t->_blocks.push_back(std::make_unique<TextBlock>(_t->_st->font, _t->_text, _t->_minResizeWidth, blockStart, len, flags, lnkIndex));
|
||||||
}
|
}
|
||||||
blockStart += len;
|
blockStart += len;
|
||||||
blockCreated();
|
blockCreated();
|
||||||
|
@ -194,7 +194,7 @@ public:
|
||||||
void createSkipBlock(int32 w, int32 h) {
|
void createSkipBlock(int32 w, int32 h) {
|
||||||
createBlock();
|
createBlock();
|
||||||
_t->_text.push_back('_');
|
_t->_text.push_back('_');
|
||||||
_t->_blocks.push_back(new SkipBlock(_t->_st->font, _t->_text, blockStart++, w, h, lnkIndex));
|
_t->_blocks.push_back(std::make_unique<SkipBlock>(_t->_st->font, _t->_text, blockStart++, w, h, lnkIndex));
|
||||||
blockCreated();
|
blockCreated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ public:
|
||||||
} else if (type == EntityInTextPre) {
|
} else if (type == EntityInTextPre) {
|
||||||
startFlags = TextBlockFPre;
|
startFlags = TextBlockFPre;
|
||||||
createBlock();
|
createBlock();
|
||||||
if (!_t->_blocks.isEmpty() && _t->_blocks.back()->type() != TextBlockTNewline) {
|
if (!_t->_blocks.empty() && _t->_blocks.back()->type() != TextBlockTNewline) {
|
||||||
createNewlineBlock();
|
createNewlineBlock();
|
||||||
}
|
}
|
||||||
} else if (type == EntityInTextUrl
|
} else if (type == EntityInTextUrl
|
||||||
|
@ -587,7 +587,7 @@ public:
|
||||||
|
|
||||||
_t->_links.resize(maxLnkIndex);
|
_t->_links.resize(maxLnkIndex);
|
||||||
for (auto i = _t->_blocks.cbegin(), e = _t->_blocks.cend(); i != e; ++i) {
|
for (auto i = _t->_blocks.cbegin(), e = _t->_blocks.cend(); i != e; ++i) {
|
||||||
auto b = *i;
|
auto b = i->get();
|
||||||
if (b->lnkIndex() > 0x8000) {
|
if (b->lnkIndex() > 0x8000) {
|
||||||
lnkIndex = maxLnkIndex + (b->lnkIndex() - 0x8000);
|
lnkIndex = maxLnkIndex + (b->lnkIndex() - 0x8000);
|
||||||
if (_t->_links.size() < lnkIndex) {
|
if (_t->_links.size() < lnkIndex) {
|
||||||
|
@ -635,7 +635,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_t->_links.squeeze();
|
_t->_links.squeeze();
|
||||||
_t->_blocks.squeeze();
|
_t->_blocks.shrink_to_fit();
|
||||||
_t->_text.squeeze();
|
_t->_text.squeeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,8 +823,8 @@ public:
|
||||||
_wLeft = _w = w;
|
_wLeft = _w = w;
|
||||||
if (_elideLast) {
|
if (_elideLast) {
|
||||||
_yToElide = _yTo;
|
_yToElide = _yTo;
|
||||||
if (_elideRemoveFromEnd > 0 && !_t->_blocks.isEmpty()) {
|
if (_elideRemoveFromEnd > 0 && !_t->_blocks.empty()) {
|
||||||
int firstBlockHeight = countBlockHeight(_t->_blocks.front(), _t->_st);
|
int firstBlockHeight = countBlockHeight(_t->_blocks.front().get(), _t->_st);
|
||||||
if (_y + firstBlockHeight >= _yToElide) {
|
if (_y + firstBlockHeight >= _yToElide) {
|
||||||
_wLeft -= _elideRemoveFromEnd;
|
_wLeft -= _elideRemoveFromEnd;
|
||||||
}
|
}
|
||||||
|
@ -860,7 +860,7 @@ public:
|
||||||
bool longWordLine = true;
|
bool longWordLine = true;
|
||||||
auto e = _t->_blocks.cend();
|
auto e = _t->_blocks.cend();
|
||||||
for (auto i = _t->_blocks.cbegin(); i != e; ++i, ++blockIndex) {
|
for (auto i = _t->_blocks.cbegin(); i != e; ++i, ++blockIndex) {
|
||||||
auto b = *i;
|
auto b = i->get();
|
||||||
auto _btype = b->type();
|
auto _btype = b->type();
|
||||||
auto blockHeight = countBlockHeight(b, _t->_st);
|
auto blockHeight = countBlockHeight(b, _t->_st);
|
||||||
|
|
||||||
|
@ -1139,7 +1139,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto _endBlock = (_endBlockIter == _end) ? nullptr : (*_endBlockIter);
|
auto _endBlock = (_endBlockIter == _end) ? nullptr : _endBlockIter->get();
|
||||||
auto elidedLine = _elideLast && (_y + _lineHeight >= _yToElide);
|
auto elidedLine = _elideLast && (_y + _lineHeight >= _yToElide);
|
||||||
if (elidedLine) {
|
if (elidedLine) {
|
||||||
// If we decided to draw the last line elided only because of the skip block
|
// If we decided to draw the last line elided only because of the skip block
|
||||||
|
@ -1154,8 +1154,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
auto blockIndex = _lineStartBlock;
|
auto blockIndex = _lineStartBlock;
|
||||||
auto currentBlock = _t->_blocks[blockIndex];
|
auto currentBlock = _t->_blocks[blockIndex].get();
|
||||||
auto nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : nullptr;
|
auto nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
|
|
||||||
int32 delta = (currentBlock->from() < _lineStart ? qMin(_lineStart - currentBlock->from(), 2) : 0);
|
int32 delta = (currentBlock->from() < _lineStart ? qMin(_lineStart - currentBlock->from(), 2) : 0);
|
||||||
_localFrom = _lineStart - delta;
|
_localFrom = _lineStart - delta;
|
||||||
|
@ -1254,12 +1254,12 @@ private:
|
||||||
QVarLengthArray<int> visualOrder(nItems);
|
QVarLengthArray<int> visualOrder(nItems);
|
||||||
QVarLengthArray<uchar> levels(nItems);
|
QVarLengthArray<uchar> levels(nItems);
|
||||||
for (int i = 0; i < nItems; ++i) {
|
for (int i = 0; i < nItems; ++i) {
|
||||||
QScriptItem &si(engine.layoutData->items[firstItem + i]);
|
auto &si = engine.layoutData->items[firstItem + i];
|
||||||
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
}
|
}
|
||||||
TextBlockType _type = currentBlock->type();
|
auto _type = currentBlock->type();
|
||||||
if (_type == TextBlockTSkip) {
|
if (_type == TextBlockTSkip) {
|
||||||
levels[i] = si.analysis.bidiLevel = 0;
|
levels[i] = si.analysis.bidiLevel = 0;
|
||||||
skipIndex = i;
|
skipIndex = i;
|
||||||
|
@ -1282,8 +1282,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
blockIndex = _lineStartBlock;
|
blockIndex = _lineStartBlock;
|
||||||
currentBlock = _t->_blocks[blockIndex];
|
currentBlock = _t->_blocks[blockIndex].get();
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
|
|
||||||
int32 textY = _y + _yDelta + _t->_st->font->ascent, emojiY = (_t->_st->font->height - st::emojiSize) / 2;
|
int32 textY = _y + _yDelta + _t->_st->font->ascent, emojiY = (_t->_st->font->height - st::emojiSize) / 2;
|
||||||
|
|
||||||
|
@ -1295,12 +1295,12 @@ private:
|
||||||
|
|
||||||
while (blockIndex > _lineStartBlock + 1 && _t->_blocks[blockIndex - 1]->from() > _localFrom + si.position) {
|
while (blockIndex > _lineStartBlock + 1 && _t->_blocks[blockIndex - 1]->from() > _localFrom + si.position) {
|
||||||
nextBlock = currentBlock;
|
nextBlock = currentBlock;
|
||||||
currentBlock = _t->_blocks[--blockIndex - 1];
|
currentBlock = _t->_blocks[--blockIndex - 1].get();
|
||||||
applyBlockProperties(currentBlock);
|
applyBlockProperties(currentBlock);
|
||||||
}
|
}
|
||||||
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
applyBlockProperties(currentBlock);
|
applyBlockProperties(currentBlock);
|
||||||
}
|
}
|
||||||
if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
|
if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
|
||||||
|
@ -1551,10 +1551,11 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
_elideSavedIndex = blockIndex;
|
_elideSavedIndex = blockIndex;
|
||||||
_elideSavedBlock = _t->_blocks[blockIndex];
|
auto mutableText = const_cast<Text*>(_t);
|
||||||
const_cast<Text*>(_t)->_blocks[blockIndex] = new TextBlock(_t->_st->font, _t->_text, QFIXED_MAX, elideStart, 0, _elideSavedBlock->flags(), _elideSavedBlock->lnkIndex());
|
_elideSavedBlock = std::move(mutableText->_blocks[blockIndex]);
|
||||||
|
mutableText->_blocks[blockIndex] = std::make_unique<TextBlock>(_t->_st->font, _t->_text, QFIXED_MAX, elideStart, 0, _elideSavedBlock->flags(), _elideSavedBlock->lnkIndex());
|
||||||
_blocksSize = blockIndex + 1;
|
_blocksSize = blockIndex + 1;
|
||||||
_endBlock = (blockIndex + 1 < _t->_blocks.size() ? _t->_blocks[blockIndex + 1] : 0);
|
_endBlock = (blockIndex + 1 < _t->_blocks.size() ? _t->_blocks[blockIndex + 1].get() : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setElideBidi(int32 elideStart, int32 elideLen) {
|
void setElideBidi(int32 elideStart, int32 elideLen) {
|
||||||
|
@ -1577,9 +1578,9 @@ private:
|
||||||
|
|
||||||
eItemize();
|
eItemize();
|
||||||
|
|
||||||
int blockIndex = _lineStartBlock;
|
auto blockIndex = _lineStartBlock;
|
||||||
ITextBlock *currentBlock = _t->_blocks[blockIndex];
|
auto currentBlock = _t->_blocks[blockIndex].get();
|
||||||
ITextBlock *nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
auto nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
|
|
||||||
QScriptLine line;
|
QScriptLine line;
|
||||||
line.from = lineStart;
|
line.from = lineStart;
|
||||||
|
@ -1596,7 +1597,7 @@ private:
|
||||||
QScriptItem &si(engine.layoutData->items[firstItem + i]);
|
QScriptItem &si(engine.layoutData->items[firstItem + i]);
|
||||||
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
}
|
}
|
||||||
TextBlockType _type = currentBlock->type();
|
TextBlockType _type = currentBlock->type();
|
||||||
if (si.analysis.flags == QScriptAnalysis::Object) {
|
if (si.analysis.flags == QScriptAnalysis::Object) {
|
||||||
|
@ -1667,7 +1668,7 @@ private:
|
||||||
lineLength += _Elide.size();
|
lineLength += _Elide.size();
|
||||||
|
|
||||||
if (!repeat) {
|
if (!repeat) {
|
||||||
for (; blockIndex < _blocksSize && _t->_blocks[blockIndex] != _endBlock && _t->_blocks[blockIndex]->from() < elideStart; ++blockIndex) {
|
for (; blockIndex < _blocksSize && _t->_blocks[blockIndex].get() != _endBlock && _t->_blocks[blockIndex]->from() < elideStart; ++blockIndex) {
|
||||||
}
|
}
|
||||||
if (blockIndex < _blocksSize) {
|
if (blockIndex < _blocksSize) {
|
||||||
elideSaveBlock(blockIndex, _endBlock, elideStart, elideWidth);
|
elideSaveBlock(blockIndex, _endBlock, elideStart, elideWidth);
|
||||||
|
@ -1677,9 +1678,7 @@ private:
|
||||||
|
|
||||||
void restoreAfterElided() {
|
void restoreAfterElided() {
|
||||||
if (_elideSavedBlock) {
|
if (_elideSavedBlock) {
|
||||||
delete _t->_blocks[_elideSavedIndex];
|
const_cast<Text*>(_t)->_blocks[_elideSavedIndex] = std::move(_elideSavedBlock);
|
||||||
const_cast<Text*>(_t)->_blocks[_elideSavedIndex] = _elideSavedBlock;
|
|
||||||
_elideSavedBlock = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1695,15 +1694,15 @@ private:
|
||||||
auto end = _e->findItem(line.from + line.length - 1, item);
|
auto end = _e->findItem(line.from + line.length - 1, item);
|
||||||
#endif // OS_MAC_OLD
|
#endif // OS_MAC_OLD
|
||||||
|
|
||||||
int blockIndex = _lineStartBlock;
|
auto blockIndex = _lineStartBlock;
|
||||||
ITextBlock *currentBlock = _t->_blocks[blockIndex];
|
auto currentBlock = _t->_blocks[blockIndex].get();
|
||||||
ITextBlock *nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
auto nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
eSetFont(currentBlock);
|
eSetFont(currentBlock);
|
||||||
for (; item <= end; ++item) {
|
for (; item <= end; ++item) {
|
||||||
QScriptItem &si = _e->layoutData->items[item];
|
QScriptItem &si = _e->layoutData->items[item];
|
||||||
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
eSetFont(currentBlock);
|
eSetFont(currentBlock);
|
||||||
}
|
}
|
||||||
_e->shape(item);
|
_e->shape(item);
|
||||||
|
@ -1773,12 +1772,12 @@ private:
|
||||||
|
|
||||||
const ushort *string = reinterpret_cast<const ushort*>(_e->layoutData->string.unicode());
|
const ushort *string = reinterpret_cast<const ushort*>(_e->layoutData->string.unicode());
|
||||||
|
|
||||||
int blockIndex = _lineStartBlock;
|
auto blockIndex = _lineStartBlock;
|
||||||
ITextBlock *currentBlock = _t->_blocks[blockIndex];
|
auto currentBlock = _t->_blocks[blockIndex].get();
|
||||||
ITextBlock *nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
auto nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
|
|
||||||
_e->layoutData->hasBidi = _parHasBidi;
|
_e->layoutData->hasBidi = _parHasBidi;
|
||||||
QScriptAnalysis *analysis = _parAnalysis.data() + (_localFrom - _parStart);
|
auto analysis = _parAnalysis.data() + (_localFrom - _parStart);
|
||||||
|
|
||||||
{
|
{
|
||||||
QVarLengthArray<uchar> scripts(length);
|
QVarLengthArray<uchar> scripts(length);
|
||||||
|
@ -1788,17 +1787,17 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
blockIndex = _lineStartBlock;
|
blockIndex = _lineStartBlock;
|
||||||
currentBlock = _t->_blocks[blockIndex];
|
currentBlock = _t->_blocks[blockIndex].get();
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
|
|
||||||
const ushort *start = string;
|
auto start = string;
|
||||||
const ushort *end = start + length;
|
auto end = start + length;
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
while (nextBlock && nextBlock->from() <= _localFrom + (start - string)) {
|
while (nextBlock && nextBlock->from() <= _localFrom + (start - string)) {
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
}
|
}
|
||||||
TextBlockType _type = currentBlock->type();
|
auto _type = currentBlock->type();
|
||||||
if (_type == TextBlockTEmoji || _type == TextBlockTSkip) {
|
if (_type == TextBlockTEmoji || _type == TextBlockTSkip) {
|
||||||
analysis->script = QChar::Script_Common;
|
analysis->script = QChar::Script_Common;
|
||||||
analysis->flags = QScriptAnalysis::Object;
|
analysis->flags = QScriptAnalysis::Object;
|
||||||
|
@ -1811,22 +1810,24 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const QString *i_string = &_e->layoutData->string;
|
auto i_string = &_e->layoutData->string;
|
||||||
const QScriptAnalysis *i_analysis = _parAnalysis.data() + (_localFrom - _parStart);
|
auto i_analysis = _parAnalysis.data() + (_localFrom - _parStart);
|
||||||
QScriptItemArray *i_items = &_e->layoutData->items;
|
auto i_items = &_e->layoutData->items;
|
||||||
|
|
||||||
blockIndex = _lineStartBlock;
|
blockIndex = _lineStartBlock;
|
||||||
currentBlock = _t->_blocks[blockIndex];
|
currentBlock = _t->_blocks[blockIndex].get();
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
ITextBlock *startBlock = currentBlock;
|
auto startBlock = currentBlock;
|
||||||
|
|
||||||
if (!length)
|
if (!length) {
|
||||||
return;
|
return;
|
||||||
int start = 0, end = start + length;
|
}
|
||||||
|
auto start = 0;
|
||||||
|
auto end = start + length;
|
||||||
for (int i = start + 1; i < end; ++i) {
|
for (int i = start + 1; i < end; ++i) {
|
||||||
while (nextBlock && nextBlock->from() <= _localFrom + i) {
|
while (nextBlock && nextBlock->from() <= _localFrom + i) {
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex].get() : nullptr;
|
||||||
}
|
}
|
||||||
// According to the unicode spec we should be treating characters in the Common script
|
// According to the unicode spec we should be treating characters in the Common script
|
||||||
// (punctuation, spaces, etc) as being the same script as the surrounding text for the
|
// (punctuation, spaces, etc) as being the same script as the surrounding text for the
|
||||||
|
@ -2359,7 +2360,7 @@ private:
|
||||||
// elided hack support
|
// elided hack support
|
||||||
int _blocksSize = 0;
|
int _blocksSize = 0;
|
||||||
int _elideSavedIndex = 0;
|
int _elideSavedIndex = 0;
|
||||||
ITextBlock *_elideSavedBlock = nullptr;
|
std::unique_ptr<ITextBlock> _elideSavedBlock;
|
||||||
|
|
||||||
int _lineStart = 0;
|
int _lineStart = 0;
|
||||||
int _localFrom = 0;
|
int _localFrom = 0;
|
||||||
|
@ -2406,11 +2407,11 @@ Text::Text(const Text &other)
|
||||||
, _minHeight(other._minHeight)
|
, _minHeight(other._minHeight)
|
||||||
, _text(other._text)
|
, _text(other._text)
|
||||||
, _st(other._st)
|
, _st(other._st)
|
||||||
, _blocks(other._blocks.size())
|
|
||||||
, _links(other._links)
|
, _links(other._links)
|
||||||
, _startDir(other._startDir) {
|
, _startDir(other._startDir) {
|
||||||
for (int32 i = 0, l = _blocks.size(); i < l; ++i) {
|
_blocks.reserve(other._blocks.size());
|
||||||
_blocks[i] = other._blocks.at(i)->clone();
|
for (auto &block : other._blocks) {
|
||||||
|
_blocks.push_back(block->clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2420,7 +2421,7 @@ Text::Text(Text &&other)
|
||||||
, _minHeight(other._minHeight)
|
, _minHeight(other._minHeight)
|
||||||
, _text(other._text)
|
, _text(other._text)
|
||||||
, _st(other._st)
|
, _st(other._st)
|
||||||
, _blocks(other._blocks)
|
, _blocks(std::move(other._blocks))
|
||||||
, _links(other._links)
|
, _links(other._links)
|
||||||
, _startDir(other._startDir) {
|
, _startDir(other._startDir) {
|
||||||
other.clearFields();
|
other.clearFields();
|
||||||
|
@ -2447,7 +2448,7 @@ Text &Text::operator=(Text &&other) {
|
||||||
_minHeight = other._minHeight;
|
_minHeight = other._minHeight;
|
||||||
_text = other._text;
|
_text = other._text;
|
||||||
_st = other._st;
|
_st = other._st;
|
||||||
_blocks = other._blocks;
|
_blocks = std::move(other._blocks);
|
||||||
_links = other._links;
|
_links = other._links;
|
||||||
_startDir = other._startDir;
|
_startDir = other._startDir;
|
||||||
other.clearFields();
|
other.clearFields();
|
||||||
|
@ -2471,7 +2472,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
|
||||||
int32 result = 0, lastNewlineStart = 0;
|
int32 result = 0, lastNewlineStart = 0;
|
||||||
QFixed _width = 0, last_rBearing = 0, last_rPadding = 0;
|
QFixed _width = 0, last_rBearing = 0, last_rPadding = 0;
|
||||||
for (auto i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) {
|
for (auto i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) {
|
||||||
auto b = *i;
|
auto b = i->get();
|
||||||
auto _btype = b->type();
|
auto _btype = b->type();
|
||||||
auto blockHeight = countBlockHeight(b, _st);
|
auto blockHeight = countBlockHeight(b, _st);
|
||||||
if (_btype == TextBlockTNewline) {
|
if (_btype == TextBlockTNewline) {
|
||||||
|
@ -2530,7 +2531,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_width > 0) {
|
if (_width > 0) {
|
||||||
if (!lineHeight) lineHeight = countBlockHeight(_blocks.back(), _st);
|
if (!lineHeight) lineHeight = countBlockHeight(_blocks.back().get(), _st);
|
||||||
_minHeight += lineHeight;
|
_minHeight += lineHeight;
|
||||||
accumulate_max(_maxWidth, _width);
|
accumulate_max(_maxWidth, _width);
|
||||||
}
|
}
|
||||||
|
@ -2659,23 +2660,23 @@ bool Text::hasLinks() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Text::hasSkipBlock() const {
|
bool Text::hasSkipBlock() const {
|
||||||
return _blocks.isEmpty() ? false : _blocks.back()->type() == TextBlockTSkip;
|
return _blocks.empty() ? false : _blocks.back()->type() == TextBlockTSkip;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::setSkipBlock(int32 width, int32 height) {
|
void Text::setSkipBlock(int32 width, int32 height) {
|
||||||
if (!_blocks.isEmpty() && _blocks.back()->type() == TextBlockTSkip) {
|
if (!_blocks.empty() && _blocks.back()->type() == TextBlockTSkip) {
|
||||||
SkipBlock *block = static_cast<SkipBlock*>(_blocks.back());
|
auto block = static_cast<SkipBlock*>(_blocks.back().get());
|
||||||
if (block->width() == width && block->height() == height) return;
|
if (block->width() == width && block->height() == height) return;
|
||||||
_text.resize(block->from());
|
_text.resize(block->from());
|
||||||
_blocks.pop_back();
|
_blocks.pop_back();
|
||||||
}
|
}
|
||||||
_text.push_back('_');
|
_text.push_back('_');
|
||||||
_blocks.push_back(new SkipBlock(_st->font, _text, _text.size() - 1, width, height, 0));
|
_blocks.push_back(std::make_unique<SkipBlock>(_st->font, _text, _text.size() - 1, width, height, 0));
|
||||||
recountNaturalSize(false);
|
recountNaturalSize(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::removeSkipBlock() {
|
void Text::removeSkipBlock() {
|
||||||
if (!_blocks.isEmpty() && _blocks.back()->type() == TextBlockTSkip) {
|
if (!_blocks.empty() && _blocks.back()->type() == TextBlockTSkip) {
|
||||||
_text.resize(_blocks.back()->from());
|
_text.resize(_blocks.back()->from());
|
||||||
_blocks.pop_back();
|
_blocks.pop_back();
|
||||||
recountNaturalSize(false);
|
recountNaturalSize(false);
|
||||||
|
@ -2721,9 +2722,9 @@ void Text::enumerateLines(int w, Callback callback) const {
|
||||||
int lineHeight = 0;
|
int lineHeight = 0;
|
||||||
QFixed widthLeft = width, last_rBearing = 0, last_rPadding = 0;
|
QFixed widthLeft = width, last_rBearing = 0, last_rPadding = 0;
|
||||||
bool longWordLine = true;
|
bool longWordLine = true;
|
||||||
for_const (auto b, _blocks) {
|
for (auto &b : _blocks) {
|
||||||
auto _btype = b->type();
|
auto _btype = b->type();
|
||||||
int blockHeight = countBlockHeight(b, _st);
|
int blockHeight = countBlockHeight(b.get(), _st);
|
||||||
|
|
||||||
if (_btype == TextBlockTNewline) {
|
if (_btype == TextBlockTNewline) {
|
||||||
if (!lineHeight) lineHeight = blockHeight;
|
if (!lineHeight) lineHeight = blockHeight;
|
||||||
|
@ -2751,7 +2752,7 @@ void Text::enumerateLines(int w, Callback callback) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_btype == TextBlockTText) {
|
if (_btype == TextBlockTText) {
|
||||||
auto t = static_cast<TextBlock*>(b);
|
auto t = static_cast<TextBlock*>(b.get());
|
||||||
if (t->_words.isEmpty()) { // no words in this block, spaces only => layout this block in the same line
|
if (t->_words.isEmpty()) { // no words in this block, spaces only => layout this block in the same line
|
||||||
last_rPadding += b->f_rpadding();
|
last_rPadding += b->f_rpadding();
|
||||||
|
|
||||||
|
@ -3027,9 +3028,6 @@ QString Text::originalText(TextSelection selection, ExpandLinksMode mode) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::clear() {
|
void Text::clear() {
|
||||||
for (TextBlocks::iterator i = _blocks.begin(), e = _blocks.end(); i != e; ++i) {
|
|
||||||
delete *i;
|
|
||||||
}
|
|
||||||
clearFields();
|
clearFields();
|
||||||
_text.clear();
|
_text.clear();
|
||||||
}
|
}
|
||||||
|
@ -3041,6 +3039,8 @@ void Text::clearFields() {
|
||||||
_startDir = Qt::LayoutDirectionAuto;
|
_startDir = Qt::LayoutDirectionAuto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text::~Text() = default;
|
||||||
|
|
||||||
void emojiDraw(QPainter &p, EmojiPtr e, int x, int y) {
|
void emojiDraw(QPainter &p, EmojiPtr e, int x, int y) {
|
||||||
auto size = Ui::Emoji::Size();
|
auto size = Ui::Emoji::Size();
|
||||||
p.drawPixmap(QPoint(x, y), App::emoji(), QRect(e->x() * size, e->y() * size, size, size));
|
p.drawPixmap(QPoint(x, y), App::emoji(), QRect(e->x() * size, e->y() * size, size, size));
|
||||||
|
|
|
@ -199,12 +199,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
~Text() {
|
~Text();
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using TextBlocks = QVector<ITextBlock*>;
|
using TextBlocks = std::vector<std::unique_ptr<ITextBlock>>;
|
||||||
using TextLinks = QVector<ClickHandlerPtr>;
|
using TextLinks = QVector<ClickHandlerPtr>;
|
||||||
|
|
||||||
uint16 countBlockEnd(const TextBlocks::const_iterator &i, const TextBlocks::const_iterator &e) const;
|
uint16 countBlockEnd(const TextBlocks::const_iterator &i, const TextBlocks::const_iterator &e) const;
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
return (_flags & 0xFF);
|
return (_flags & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ITextBlock *clone() const = 0;
|
virtual std::unique_ptr<ITextBlock> clone() const = 0;
|
||||||
virtual ~ITextBlock() {
|
virtual ~ITextBlock() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,19 +99,19 @@ protected:
|
||||||
|
|
||||||
class NewlineBlock : public ITextBlock {
|
class NewlineBlock : public ITextBlock {
|
||||||
public:
|
public:
|
||||||
Qt::LayoutDirection nextDirection() const {
|
|
||||||
return _nextDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
ITextBlock *clone() const {
|
|
||||||
return new NewlineBlock(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
NewlineBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : ITextBlock(font, str, from, length, flags, lnkIndex), _nextDir(Qt::LayoutDirectionAuto) {
|
NewlineBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : ITextBlock(font, str, from, length, flags, lnkIndex), _nextDir(Qt::LayoutDirectionAuto) {
|
||||||
_flags |= ((TextBlockTNewline & 0x0F) << 8);
|
_flags |= ((TextBlockTNewline & 0x0F) << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::LayoutDirection nextDirection() const {
|
||||||
|
return _nextDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ITextBlock> clone() const override {
|
||||||
|
return std::make_unique<NewlineBlock>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
Qt::LayoutDirection _nextDir;
|
Qt::LayoutDirection _nextDir;
|
||||||
|
|
||||||
friend class Text;
|
friend class Text;
|
||||||
|
@ -155,13 +155,13 @@ private:
|
||||||
|
|
||||||
class TextBlock : public ITextBlock {
|
class TextBlock : public ITextBlock {
|
||||||
public:
|
public:
|
||||||
ITextBlock *clone() const {
|
TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex);
|
||||||
return new TextBlock(*this);
|
|
||||||
|
std::unique_ptr<ITextBlock> clone() const override {
|
||||||
|
return std::make_unique<TextBlock>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex);
|
|
||||||
|
|
||||||
friend class ITextBlock;
|
friend class ITextBlock;
|
||||||
QFixed real_f_rbearing() const {
|
QFixed real_f_rbearing() const {
|
||||||
return _words.isEmpty() ? 0 : _words.back().f_rbearing();
|
return _words.isEmpty() ? 0 : _words.back().f_rbearing();
|
||||||
|
@ -180,13 +180,13 @@ private:
|
||||||
|
|
||||||
class EmojiBlock : public ITextBlock {
|
class EmojiBlock : public ITextBlock {
|
||||||
public:
|
public:
|
||||||
ITextBlock *clone() const {
|
EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, EmojiPtr emoji);
|
||||||
return new EmojiBlock(*this);
|
|
||||||
|
std::unique_ptr<ITextBlock> clone() const {
|
||||||
|
return std::make_unique<EmojiBlock>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, EmojiPtr emoji);
|
|
||||||
|
|
||||||
EmojiPtr emoji = nullptr;
|
EmojiPtr emoji = nullptr;
|
||||||
|
|
||||||
friend class Text;
|
friend class Text;
|
||||||
|
@ -198,17 +198,17 @@ private:
|
||||||
|
|
||||||
class SkipBlock : public ITextBlock {
|
class SkipBlock : public ITextBlock {
|
||||||
public:
|
public:
|
||||||
|
SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex);
|
||||||
|
|
||||||
int32 height() const {
|
int32 height() const {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITextBlock *clone() const {
|
std::unique_ptr<ITextBlock> clone() const override {
|
||||||
return new SkipBlock(*this);
|
return std::make_unique<SkipBlock>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex);
|
|
||||||
|
|
||||||
int32 _height;
|
int32 _height;
|
||||||
|
|
||||||
friend class Text;
|
friend class Text;
|
||||||
|
|
Loading…
Add table
Reference in a new issue