diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 0ee90f56e7..8c94729e0d 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -593,11 +593,7 @@ void DocumentData::unload() { sticker()->img = ImagePtr(); } } - if (!replyPreview->isNull()) { - // Should be std::unique_ptr. - 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( + std::make_unique( + image.toImage(), + "PNG")); } else { thumb->load(origin); } } - return replyPreview; + return _replyPreview.get(); } StickerData *DocumentData::sticker() const { diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index 66c5b57c4f..5faf50ede7 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -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 _goodThumbnail; + std::unique_ptr _replyPreview; not_null _session; diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index c7ffebe1bc..53782fc0c4 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -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 { diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index e91a00f62b..3bd027908b 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -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; diff --git a/Telegram/SourceFiles/data/data_photo.cpp b/Telegram/SourceFiles/data/data_photo.cpp index ff3b6ac096..77b575a1d9 100644 --- a/Telegram/SourceFiles/data/data_photo.cpp +++ b/Telegram/SourceFiles/data/data_photo.cpp @@ -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. - 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(); } int w = image->width(), h = image->height(); if (w <= 0) w = 1; if (h <= 0) h = 1; - return Images::Create( + return std::make_unique( + std::make_unique( (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 { diff --git a/Telegram/SourceFiles/data/data_photo.h b/Telegram/SourceFiles/data/data_photo.h index 9dd2a1c710..43be5700fc 100644 --- a/Telegram/SourceFiles/data/data_photo.h +++ b/Telegram/SourceFiles/data/data_photo.h @@ -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 uploadingData; +private: + std::unique_ptr _replyPreview; + }; class PhotoClickHandler : public FileClickHandler { diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index ad2c269362..bd38a55d4e 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -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); } } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c0e3a8f907..142c577ee3 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -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(); }