Store replyPreview in unique_ptr<Image>.

This commit is contained in:
John Preston 2018-11-09 19:03:38 +04:00
parent 147079ce2a
commit 2b95b96fa3
8 changed files with 69 additions and 69 deletions

View File

@ -593,11 +593,7 @@ void DocumentData::unload() {
sticker()->img = ImagePtr();
}
}
if (!replyPreview->isNull()) {
// Should be std::unique_ptr<Image>.
delete replyPreview.get();
replyPreview = ImagePtr();
}
_replyPreview = nullptr;
if (!_data.isEmpty()) {
ActiveCache().decrement(_data.size());
_data.clear();
@ -1037,8 +1033,8 @@ bool DocumentData::isStickerSetInstalled() const {
return false;
}
ImagePtr DocumentData::makeReplyPreview(Data::FileOrigin origin) {
if (replyPreview->isNull() && !thumb->isNull()) {
Image *DocumentData::getReplyPreview(Data::FileOrigin origin) {
if (!_replyPreview->isNull() && !thumb->isNull()) {
if (thumb->loaded()) {
int w = thumb->width(), h = thumb->height();
if (w <= 0) w = 1;
@ -1048,12 +1044,15 @@ ImagePtr DocumentData::makeReplyPreview(Data::FileOrigin origin) {
auto options = Images::Option::Smooth | (isVideoMessage() ? Images::Option::Circled : Images::Option::None) | Images::Option::TransparentBackground;
auto outerSize = st::msgReplyBarSize.height();
auto image = thumb->pixNoCache(origin, thumbSize.width(), thumbSize.height(), options, outerSize, outerSize);
replyPreview = Images::Create(image.toImage(), "PNG");
_replyPreview = std::make_unique<Image>(
std::make_unique<Images::ImageSource>(
image.toImage(),
"PNG"));
} else {
thumb->load(origin);
}
}
return replyPreview;
return _replyPreview.get();
}
StickerData *DocumentData::sticker() const {

View File

@ -126,7 +126,7 @@ public:
void performActionOnLoad();
void unload();
ImagePtr makeReplyPreview(Data::FileOrigin origin);
Image *getReplyPreview(Data::FileOrigin origin);
StickerData *sticker() const;
void checkSticker();
@ -206,7 +206,7 @@ public:
DocumentType type = FileDocument;
QSize dimensions;
int32 date = 0;
ImagePtr thumb, replyPreview;
ImagePtr thumb;
int32 size = 0;
FileStatus status = FileReady;
@ -231,6 +231,7 @@ private:
WebFileLocation _urlLocation;
std::unique_ptr<Image> _goodThumbnail;
std::unique_ptr<Image> _replyPreview;
not_null<AuthSession*> _session;

View File

@ -175,8 +175,8 @@ bool Media::hasReplyPreview() const {
return false;
}
ImagePtr Media::replyPreview() const {
return ImagePtr();
Image *Media::replyPreview() const {
return nullptr;
}
bool Media::allowsForward() const {
@ -270,8 +270,8 @@ bool MediaPhoto::hasReplyPreview() const {
return !_photo->thumb->isNull();
}
ImagePtr MediaPhoto::replyPreview() const {
return _photo->makeReplyPreview(parent()->fullId());
Image *MediaPhoto::replyPreview() const {
return _photo->getReplyPreview(parent()->fullId());
}
QString MediaPhoto::notificationText() const {
@ -508,8 +508,8 @@ bool MediaFile::hasReplyPreview() const {
return !_document->thumb->isNull();
}
ImagePtr MediaFile::replyPreview() const {
return _document->makeReplyPreview(parent()->fullId());
Image *MediaFile::replyPreview() const {
return _document->getReplyPreview(parent()->fullId());
}
QString MediaFile::chatsListText() const {
@ -982,13 +982,13 @@ bool MediaWebPage::hasReplyPreview() const {
return false;
}
ImagePtr MediaWebPage::replyPreview() const {
Image *MediaWebPage::replyPreview() const {
if (const auto document = MediaWebPage::document()) {
return document->makeReplyPreview(parent()->fullId());
return document->getReplyPreview(parent()->fullId());
} else if (const auto photo = MediaWebPage::photo()) {
return photo->makeReplyPreview(parent()->fullId());
return photo->getReplyPreview(parent()->fullId());
}
return ImagePtr();
return nullptr;
}
QString MediaWebPage::chatsListText() const {
@ -1045,13 +1045,13 @@ bool MediaGame::hasReplyPreview() const {
return false;
}
ImagePtr MediaGame::replyPreview() const {
Image *MediaGame::replyPreview() const {
if (const auto document = _game->document) {
return document->makeReplyPreview(parent()->fullId());
return document->getReplyPreview(parent()->fullId());
} else if (const auto photo = _game->photo) {
return photo->makeReplyPreview(parent()->fullId());
return photo->getReplyPreview(parent()->fullId());
}
return ImagePtr();
return nullptr;
}
QString MediaGame::notificationText() const {
@ -1145,11 +1145,11 @@ bool MediaInvoice::hasReplyPreview() const {
return false;
}
ImagePtr MediaInvoice::replyPreview() const {
Image *MediaInvoice::replyPreview() const {
if (const auto photo = _invoice.photo) {
return photo->makeReplyPreview(parent()->fullId());
return photo->getReplyPreview(parent()->fullId());
}
return ImagePtr();
return nullptr;
}
QString MediaInvoice::notificationText() const {

View File

@ -85,7 +85,7 @@ public:
virtual Storage::SharedMediaTypesMask sharedMediaTypes() const;
virtual bool canBeGrouped() const;
virtual bool hasReplyPreview() const;
virtual ImagePtr replyPreview() const;
virtual Image *replyPreview() const;
// Returns text with link-start and link-end commands for service-color highlighting.
// Example: "[link1-start]You:[link1-end] [link1-start]Photo,[link1-end] caption text"
virtual QString chatsListText() const;
@ -138,7 +138,7 @@ public:
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
bool canBeGrouped() const override;
bool hasReplyPreview() const override;
ImagePtr replyPreview() const override;
Image *replyPreview() const override;
QString chatsListText() const override;
QString notificationText() const override;
QString pinnedTextSubstring() const override;
@ -174,7 +174,7 @@ public:
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
bool canBeGrouped() const override;
bool hasReplyPreview() const override;
ImagePtr replyPreview() const override;
Image *replyPreview() const override;
QString chatsListText() const override;
QString notificationText() const override;
QString pinnedTextSubstring() const override;
@ -300,7 +300,7 @@ public:
WebPageData *webpage() const override;
bool hasReplyPreview() const override;
ImagePtr replyPreview() const override;
Image *replyPreview() const override;
QString chatsListText() const override;
QString notificationText() const override;
QString pinnedTextSubstring() const override;
@ -329,7 +329,7 @@ public:
GameData *game() const override;
bool hasReplyPreview() const override;
ImagePtr replyPreview() const override;
Image *replyPreview() const override;
QString notificationText() const override;
QString pinnedTextSubstring() const override;
TextWithEntities clipboardText() const override;
@ -365,7 +365,7 @@ public:
const Invoice *invoice() const override;
bool hasReplyPreview() const override;
ImagePtr replyPreview() const override;
Image *replyPreview() const override;
QString notificationText() const override;
QString pinnedTextSubstring() const override;
TextWithEntities clipboardText() const override;

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "mainwidget.h"
#include "history/history_media_types.h"
#include "auth_session.h"
@ -108,42 +109,39 @@ void PhotoData::unload() {
//thumb->unload();
medium->unload();
full->unload();
if (!replyPreview->isNull()) {
// Should be std::unique_ptr<Image>.
delete replyPreview.get();
replyPreview = ImagePtr();
}
_replyPreview = nullptr;
}
ImagePtr PhotoData::makeReplyPreview(Data::FileOrigin origin) {
if (replyPreview->isNull() && !thumb->isNull()) {
Image *PhotoData::getReplyPreview(Data::FileOrigin origin) {
if (!_replyPreview && !thumb->isNull()) {
const auto previewFromImage = [&](const ImagePtr &image) {
if (!image->loaded()) {
image->load(origin);
return ImagePtr();
return std::unique_ptr<Image>();
}
int w = image->width(), h = image->height();
if (w <= 0) w = 1;
if (h <= 0) h = 1;
return Images::Create(
return std::make_unique<Image>(
std::make_unique<Images::ImageSource>(
(w > h
? image->pix(
origin,
w * st::msgReplyBarSize.height() / h,
st::msgReplyBarSize.height())
: image->pix(origin, st::msgReplyBarSize.height())
).toImage(),
"PNG");
).toImage(),
"PNG"));
};
if (thumb->isDelayedStorageImage()
&& !full->isNull()
&& !full->isDelayedStorageImage()) {
replyPreview = previewFromImage(full);
_replyPreview = previewFromImage(full);
} else {
replyPreview = previewFromImage(thumb);
_replyPreview = previewFromImage(thumb);
}
}
return replyPreview;
return _replyPreview.get();
}
MTPInputPhoto PhotoData::mtpInput() const {

View File

@ -39,7 +39,7 @@ public:
bool waitingForAlbum() const;
void unload();
ImagePtr makeReplyPreview(Data::FileOrigin origin);
Image *getReplyPreview(Data::FileOrigin origin);
MTPInputPhoto mtpInput() const;
@ -53,7 +53,7 @@ public:
uint64 access = 0;
QByteArray fileReference;
TimeId date = 0;
ImagePtr thumb, replyPreview;
ImagePtr thumb;
ImagePtr medium;
ImagePtr full;
@ -62,6 +62,9 @@ public:
std::unique_ptr<Data::UploadState> uploadingData;
private:
std::unique_ptr<Image> _replyPreview;
};
class PhotoClickHandler : public FileClickHandler {

View File

@ -258,12 +258,11 @@ void HistoryMessageReply::paint(
auto previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
if (hasPreview) {
const auto replyPreview = replyToMsg->media()->replyPreview();
if (!replyPreview->isNull()) {
if (const auto image = replyToMsg->media()->replyPreview()) {
auto to = rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x);
auto previewWidth = replyPreview->width() / cIntRetinaFactor();
auto previewHeight = replyPreview->height() / cIntRetinaFactor();
auto preview = replyPreview->pixSingle(replyToMsg->fullId(), previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, RectPart::AllCorners, selected ? &st::msgStickerOverlay : nullptr);
auto previewWidth = image->width() / cIntRetinaFactor();
auto previewHeight = image->height() / cIntRetinaFactor();
auto preview = image->pixSingle(replyToMsg->fullId(), previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, RectPart::AllCorners, selected ? &st::msgStickerOverlay : nullptr);
p.drawPixmap(to.x(), to.y(), preview);
}
}

View File

@ -6641,10 +6641,9 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
if (!drawWebPagePreview) {
if (drawMsgText) {
if (drawMsgText->media() && drawMsgText->media()->hasReplyPreview()) {
auto replyPreview = drawMsgText->media()->replyPreview();
if (!replyPreview->isNull()) {
if (const auto image = drawMsgText->media()->replyPreview()) {
auto to = QRect(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(drawMsgText->fullId(), replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
p.drawPixmap(to.x(), to.y(), image->pixSingle(drawMsgText->fullId(), image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
}
replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
}
@ -6675,8 +6674,8 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|| firstItem->serviceMsg();
const auto preview = (_toForward.size() < 2 && firstMedia && firstMedia->hasReplyPreview())
? firstMedia->replyPreview()
: ImagePtr();
if (!preview->isNull()) {
: nullptr;
if (preview) {
auto to = QRect(forwardLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
if (preview->width() == preview->height()) {
p.drawPixmap(to.x(), to.y(), preview->pix(firstItem->fullId()));
@ -6698,14 +6697,16 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
auto previewLeft = st::historyReplySkip + st::webPageLeft;
p.fillRect(st::historyReplySkip, backy + st::msgReplyPadding.top(), st::webPageBar, st::msgReplyBarSize.height(), st::msgInReplyBarColor);
if ((_previewData->photo && !_previewData->photo->thumb->isNull()) || (_previewData->document && !_previewData->document->thumb->isNull())) {
auto replyPreview = _previewData->photo ? _previewData->photo->makeReplyPreview(Data::FileOrigin()) : _previewData->document->makeReplyPreview(Data::FileOrigin());
if (!replyPreview->isNull()) {
const auto preview = _previewData->photo
? _previewData->photo->getReplyPreview(Data::FileOrigin())
: _previewData->document->getReplyPreview(Data::FileOrigin());
if (preview) {
auto to = QRect(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
if (replyPreview->width() == replyPreview->height()) {
p.drawPixmap(to.x(), to.y(), replyPreview->pix(Data::FileOrigin()));
if (preview->width() == preview->height()) {
p.drawPixmap(to.x(), to.y(), preview->pix(Data::FileOrigin()));
} else {
auto from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width());
p.drawPixmap(to, replyPreview->pix(Data::FileOrigin()), from);
auto from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width());
p.drawPixmap(to, preview->pix(Data::FileOrigin()), from);
}
}
previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
@ -6807,10 +6808,9 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
if (_pinnedBar->msg) {
if (_pinnedBar->msg->media() && _pinnedBar->msg->media()->hasReplyPreview()) {
ImagePtr replyPreview = _pinnedBar->msg->media()->replyPreview();
if (!replyPreview->isNull()) {
if (const auto image = _pinnedBar->msg->media()->replyPreview()) {
QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(_pinnedBar->msg->fullId(), replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
p.drawPixmap(to.x(), to.y(), image->pixSingle(_pinnedBar->msg->fullId(), image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
}
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
}