diff --git a/Telegram/SourceFiles/api/api_chat_invite.cpp b/Telegram/SourceFiles/api/api_chat_invite.cpp index 90a5a5175..dc3e557bc 100644 --- a/Telegram/SourceFiles/api/api_chat_invite.cpp +++ b/Telegram/SourceFiles/api/api_chat_invite.cpp @@ -252,12 +252,13 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) { if (_photo) { if (const auto image = _photo->image(Data::PhotoSize::Small)) { + const auto size = st::confirmInvitePhotoSize; p.drawPixmap( - (width() - st::confirmInvitePhotoSize) / 2, + (width() - size) / 2, st::confirmInvitePhotoTop, - image->pixCircled( - st::confirmInvitePhotoSize, - st::confirmInvitePhotoSize)); + image->pix( + { size, size }, + { .options = Images::Option::RoundCircle })); } } else if (_photoEmpty) { _photoEmpty->paint( diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp index 448828f0a..f527483fc 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp @@ -321,15 +321,11 @@ bool ServiceCheck::checkRippleStartPosition(QPoint position) const { const auto takeHeight = (width > height) ? size : (height * size / width); - return Images::prepare( - image, - takeWidth * cIntRetinaFactor(), - takeHeight * cIntRetinaFactor(), - Images::Option::Smooth - | Images::Option::TransparentBackground - | blur, - size, - size); + const auto ratio = style::DevicePixelRatio(); + return Images::Prepare(image, QSize(takeWidth, takeHeight) * ratio, { + .options = Images::Option::TransparentBackground | blur, + .outer = { size, size }, + }); } [[nodiscard]] QImage PrepareScaledFromFull( @@ -667,7 +663,7 @@ void BackgroundPreviewBox::setScaledFromThumb() { _paper.backgroundColors(), _paper.gradientRotation(), _paper.patternOpacity(), - _paper.document() ? Images::Option::Blurred : Images::Option(0)); + _paper.document() ? Images::Option::Blur : Images::Option()); auto blurred = (_paper.document() || _paper.isPattern()) ? QImage() : PrepareScaledNonPattern( diff --git a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp index d57bca339..9077837bf 100644 --- a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp @@ -183,11 +183,10 @@ void PeerShortInfoCover::paint(QPainter &p) { _widget->size() * style::DevicePixelRatio(), QImage::Format_ARGB32_Premultiplied); image.fill(Qt::black); - Images::prepareRound( - image, + _userpicImage = Images::Round( + std::move(image), ImageRoundRadius::Small, RectPart::TopLeft | RectPart::TopRight); - _userpicImage = std::move(image); } paintCoverImage(p, frame.isNull() ? _userpicImage : frame); @@ -229,8 +228,8 @@ void PeerShortInfoCover::paintCoverImage(QPainter &p, const QImage &image) { image, QRect(0, from * factor, roundedWidth * factor, rounded * factor)); q.end(); - Images::prepareRound( - _roundedTopImage, + _roundedTopImage = Images::Round( + std::move(_roundedTopImage), ImageRoundRadius::Small, RectPart::TopLeft | RectPart::TopRight); p.drawImage( @@ -244,9 +243,8 @@ void PeerShortInfoCover::paintBars(QPainter &p) { const auto factor = style::DevicePixelRatio(); if (_shadowTop.isNull()) { _shadowTop = Images::GenerateShadow(height, kShadowMaxAlpha, 0); - _shadowTop = _shadowTop.scaled(QSize(_st.size, height) * factor); - Images::prepareRound( - _shadowTop, + _shadowTop = Images::Round( + _shadowTop.scaled(QSize(_st.size, height) * factor), ImageRoundRadius::Small, RectPart::TopLeft | RectPart::TopRight); } @@ -771,8 +769,8 @@ int PeerShortInfoBox::fillRoundedTopHeight() { void PeerShortInfoBox::refreshRoundedTopImage(const QColor &color) { _roundedTopColor = color; _roundedTop.fill(color); - Images::prepareRound( - _roundedTop, + _roundedTop = Images::Round( + std::move(_roundedTop), ImageRoundRadius::Small, RectPart::TopLeft | RectPart::TopRight); } diff --git a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp index 93c0bcb8c..e996b72bd 100644 --- a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp @@ -51,19 +51,15 @@ void GenerateImage( bool blurred = false) { using namespace Images; const auto size = st::shortInfoWidth; - const auto factor = style::DevicePixelRatio(); - const auto options = Option::Smooth - | Option::RoundedSmall - | Option::RoundedTopLeft - | Option::RoundedTopRight - | (blurred ? Option::Blurred : Option()); - state->current.photo = Images::prepare( + const auto ratio = style::DevicePixelRatio(); + const auto options = Option::RoundSmall + | Option::RoundSkipBottomLeft + | Option::RoundSkipBottomRight + | (blurred ? Option::Blur : Option()); + state->current.photo = Images::Prepare( std::move(image), - size * factor, - size * factor, - options, - size, - size); + QSize(size, size) * ratio, + { .options = options, .outer = { size, size } }); } void GenerateImage( diff --git a/Telegram/SourceFiles/calls/calls_userpic.cpp b/Telegram/SourceFiles/calls/calls_userpic.cpp index 7b31a8c15..d6cc76f47 100644 --- a/Telegram/SourceFiles/calls/calls_userpic.cpp +++ b/Telegram/SourceFiles/calls/calls_userpic.cpp @@ -165,8 +165,12 @@ void Userpic::refreshPhoto() { void Userpic::createCache(Image *image) { const auto size = this->size(); const auto real = size * cIntRetinaFactor(); - auto options = Images::Option::Smooth | Images::Option::Circled; - // _useTransparency ? (Images::Option::RoundedLarge | Images::Option::RoundedTopLeft | Images::Option::RoundedTopRight | Images::Option::Smooth) : Images::Option::None; + auto options = Images::Option() | Images::Option::RoundCircle; + //_useTransparency + // ? (Images::Option::RoundLarge + // | Images::Option::RoundSkipBottomLeft + // | Images::Option::RoundSkipBottomRight) + // : Images::Option::None; if (image) { auto width = image->width(); auto height = image->height(); @@ -178,14 +182,16 @@ void Userpic::createCache(Image *image) { width = real; } _userPhoto = image->pixNoCache( - width, - height, - options, - size, - size); + { width, height }, + { + .options = Images::Option::RoundCircle, + .outer = { size, size }, + }); _userPhoto.setDevicePixelRatio(cRetinaFactor()); } else { - auto filled = QImage(QSize(real, real), QImage::Format_ARGB32_Premultiplied); + auto filled = QImage( + QSize(real, real), + QImage::Format_ARGB32_Premultiplied); filled.setDevicePixelRatio(cRetinaFactor()); filled.fill(Qt::transparent); { @@ -195,7 +201,10 @@ void Userpic::createCache(Image *image) { _peer->name ).paint(p, 0, 0, size, size); } - //Images::prepareRound(filled, ImageRoundRadius::Large, RectPart::TopLeft | RectPart::TopRight); + //_userPhoto = Images::PixmapFast(Images::Round( + // std::move(filled), + // ImageRoundRadius::Large, + // RectPart::TopLeft | RectPart::TopRight)); _userPhoto = Images::PixmapFast(std::move(filled)); } diff --git a/Telegram/SourceFiles/calls/calls_video_bubble.cpp b/Telegram/SourceFiles/calls/calls_video_bubble.cpp index 7432f7557..c5d55a827 100644 --- a/Telegram/SourceFiles/calls/calls_video_bubble.cpp +++ b/Telegram/SourceFiles/calls/calls_video_bubble.cpp @@ -169,12 +169,12 @@ void VideoBubble::prepareFrame() { for (; from != till; from += fromPerLine, to += toPerLine) { memcpy(to, from, lineSize); } - Images::prepareRound( - _frame, + _frame = Images::Round( + std::move(_frame), ImageRoundRadius::Large, RectPart::AllCorners, - QRect(QPoint(), size)); - _frame = std::move(_frame).mirrored(true, false); + QRect(QPoint(), size) + ).mirrored(true, false); } void VideoBubble::setState(Webrtc::VideoState state) { diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index bceb5a770..f0516d5d6 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -1966,12 +1966,7 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section, const auto pixmap = !sticker.savedFrame.isNull() ? sticker.savedFrame : image - ? image->pixSingle( - w, - h, - w, - h, - ImageRoundRadius::None) + ? image->pixSingle(w, h, { .outer = { w, h } }) : QPixmap(); if (!pixmap.isNull()) { p.drawPixmapLeft(ppos, width(), pixmap); diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index fd569fbe4..39c09b48d 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -128,9 +128,9 @@ using ItemPreviewImage = HistoryView::ItemPreviewImage; Images::CornersMask(pxRadius)).first->second; } } - Images::prepareRound(square, *cache.lastUsed); + square = Images::Round(std::move(square), *cache.lastUsed); } else { - Images::prepareRound(square, radius); + square = Images::Round(std::move(square), radius); } square.setDevicePixelRatio(factor); return square; diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index a6c462183..ba42dc7fc 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -320,7 +320,11 @@ void PeerData::paintUserpic( int y, int size) const { if (const auto userpic = currentUserpic(view)) { - p.drawPixmap(x, y, userpic->pixCircled(size, size)); + const auto circled = Images::Option::RoundCircle; + p.drawPixmap( + x, + y, + userpic->pix(size, size, { .options = circled })); } else { ensureEmptyUserpic()->paint(p, x, y, x + size + x, size); } @@ -380,10 +384,14 @@ QPixmap PeerData::genUserpic( std::shared_ptr &view, int size) const { if (const auto userpic = currentUserpic(view)) { - return userpic->pixCircled(size, size); + const auto circle = Images::Option::RoundCircle; + return userpic->pix(size, size, { .options = circle }); } - auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); - result.setDevicePixelRatio(cRetinaFactor()); + const auto ratio = style::DevicePixelRatio(); + auto result = QImage( + QSize(size, size) * ratio, + QImage::Format_ARGB32_Premultiplied); + result.setDevicePixelRatio(ratio); result.fill(Qt::transparent); { Painter p(&result); @@ -404,15 +412,13 @@ QImage PeerData::generateUserpicImage( ImageRoundRadius radius) const { if (const auto userpic = currentUserpic(view)) { const auto options = (radius == ImageRoundRadius::Ellipse) - ? (Images::Option::RoundedAll | Images::Option::Circled) + ? Images::Option::RoundCircle : (radius == ImageRoundRadius::None) - ? Images::Options() - : (Images::Option::RoundedAll | Images::Option::RoundedSmall); + ? Images::Option() + : Images::Option::RoundSmall; return userpic->pixNoCache( - size, - size, - Images::Option::Smooth | options - ).toImage(); + { size, size }, + { .options = options }).toImage(); } auto result = QImage( QSize(size, size), diff --git a/Telegram/SourceFiles/data/data_photo.cpp b/Telegram/SourceFiles/data/data_photo.cpp index 153456d52..5ff525799 100644 --- a/Telegram/SourceFiles/data/data_photo.cpp +++ b/Telegram/SourceFiles/data/data_photo.cpp @@ -36,7 +36,7 @@ using Data::kPhotoSizeCount; const Data::CloudFile &file) { return (v::is(file.location.file().data) && image.format() == QImage::Format_ARGB32) - ? Images::prepareOpaque(std::move(image)) + ? Images::Opaque(std::move(image)) : image; } diff --git a/Telegram/SourceFiles/data/data_reply_preview.cpp b/Telegram/SourceFiles/data/data_reply_preview.cpp index cc4cd1082..732cdb84d 100644 --- a/Telegram/SourceFiles/data/data_reply_preview.cpp +++ b/Telegram/SourceFiles/data/data_reply_preview.cpp @@ -41,18 +41,13 @@ void ReplyPreview::prepare(not_null image, Images::Options options) { st::msgReplyBarSize.height(), h * st::msgReplyBarSize.height() / w); thumbSize *= cIntRetinaFactor(); - const auto prepareOptions = Images::Option::Smooth - | Images::Option::TransparentBackground - | options; + options |= Images::Option::TransparentBackground; auto outerSize = st::msgReplyBarSize.height(); auto bitmap = image->pixNoCache( - thumbSize.width(), - thumbSize.height(), - prepareOptions, - outerSize, - outerSize); + thumbSize, + { .options = options, .outer = { outerSize, outerSize } }); _image = std::make_unique(bitmap.toImage()); - _good = ((options & Images::Option::Blurred) == 0); + _good = ((options & Images::Option::Blur) == 0); } Image *ReplyPreview::image( @@ -69,13 +64,13 @@ Image *ReplyPreview::image( } const auto thumbnail = _documentMedia->thumbnail(); const auto option = _document->isVideoMessage() - ? Images::Option::Circled + ? Images::Option::RoundCircle : Images::Option::None; if (thumbnail) { prepare(thumbnail, option); } else if (!_image) { if (const auto image = _documentMedia->thumbnailInline()) { - prepare(image, option | Images::Option::Blurred); + prepare(image, option | Images::Option::Blur); } } if (_good || !_document->hasThumbnail()) { @@ -102,7 +97,7 @@ Image *ReplyPreview::image( prepare(large, Images::Option(0)); } else if (!_image) { if (const auto blurred = _photoMedia->thumbnailInline()) { - prepare(blurred, Images::Option::Blurred); + prepare(blurred, Images::Option::Blur); } } if (_good) { diff --git a/Telegram/SourceFiles/editor/photo_editor_content.cpp b/Telegram/SourceFiles/editor/photo_editor_content.cpp index da24431cf..bfff43b5c 100644 --- a/Telegram/SourceFiles/editor/photo_editor_content.cpp +++ b/Telegram/SourceFiles/editor/photo_editor_content.cpp @@ -90,9 +90,7 @@ PhotoEditorContent::PhotoEditorContent( p.setTransform(_imageMatrix); - p.drawPixmap( - _imageRect, - _photo->pix(_imageRect.width(), _imageRect.height())); + p.drawPixmap(_imageRect, _photo->pix(_imageRect.size())); }, lifetime()); setupDragArea(); diff --git a/Telegram/SourceFiles/editor/photo_editor_controls.cpp b/Telegram/SourceFiles/editor/photo_editor_controls.cpp index da7bc28b9..18dc356c4 100644 --- a/Telegram/SourceFiles/editor/photo_editor_controls.cpp +++ b/Telegram/SourceFiles/editor/photo_editor_controls.cpp @@ -90,12 +90,10 @@ QImage EdgeButton::rounded(std::optional color) const { result.setDevicePixelRatio(cIntRetinaFactor()); result.fill(color.value_or(Qt::white)); - using Option = Images::Option; - const auto options = Option::Smooth - | Option::RoundedLarge - | (_left ? Option::RoundedTopLeft : Option::RoundedTopRight) - | (_left ? Option::RoundedBottomLeft : Option::RoundedBottomRight); - return Images::prepare(std::move(result), 0, 0, options, 0, 0); + const auto parts = RectPart::None + | (_left ? RectPart::TopLeft : RectPart::TopRight) + | (_left ? RectPart::BottomLeft : RectPart::BottomRight); + return Images::Round(std::move(result), ImageRoundRadius::Large, parts); } QImage EdgeButton::prepareRippleMask() const { @@ -151,10 +149,9 @@ ButtonBar::ButtonBar( result.setDevicePixelRatio(cIntRetinaFactor()); result.fill(bg->c); - const auto options = Images::Option::Smooth - | Images::Option::RoundedLarge - | Images::Option::RoundedAll; - _roundedBg = Images::prepare(std::move(result), 0, 0, options, 0, 0); + _roundedBg = Images::Round( + std::move(result), + ImageRoundRadius::Large); }, lifetime()); paintRequest( diff --git a/Telegram/SourceFiles/editor/scene/scene_item_sticker.cpp b/Telegram/SourceFiles/editor/scene/scene_item_sticker.cpp index 1075db0a7..741d41060 100644 --- a/Telegram/SourceFiles/editor/scene/scene_item_sticker.cpp +++ b/Telegram/SourceFiles/editor/scene/scene_item_sticker.cpp @@ -59,11 +59,9 @@ ItemSticker::ItemSticker( if (!sticker) { return false; } - auto pixmap = sticker->pixNoCache( - sticker->width() * cIntRetinaFactor(), - sticker->height() * cIntRetinaFactor(), - Images::Option::Smooth); - pixmap.setDevicePixelRatio(cRetinaFactor()); + const auto ratio = style::DevicePixelRatio(); + auto pixmap = sticker->pixNoCache(sticker->size() * ratio); + pixmap.setDevicePixelRatio(ratio); updatePixmap(std::move(pixmap)); return true; }; diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index c377f0b09..3fdb3971a 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -342,16 +342,15 @@ void HistoryMessageReply::paint( if (hasPreview) { if (const auto image = replyToMsg->media()->replyPreview()) { auto to = style::rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x); - auto previewWidth = image->width() / cIntRetinaFactor(); - auto previewHeight = image->height() / cIntRetinaFactor(); - auto preview = image->pixSingle( - previewWidth, - previewHeight, - to.width(), - to.height(), - ImageRoundRadius::Small, - RectPart::AllCorners, - context.selected() ? &st->msgStickerOverlay() : nullptr); + const auto preview = image->pixSingle( + image->size() / style::DevicePixelRatio(), + { + .colored = (context.selected() + ? &st->msgStickerOverlay() + : nullptr), + .options = Images::Option::RoundSmall, + .outer = to.size(), + }); p.drawPixmap(to.x(), to.y(), preview); } } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index de040bef7..af41bc64f 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -7139,7 +7139,12 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { if (drawMsgText->media() && drawMsgText->media()->hasReplyPreview()) { 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(), image->pixSingle(image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); + p.drawPixmap(to.x(), to.y(), image->pixSingle( + image->size() / style::DevicePixelRatio(), + { + .options = Images::Option::RoundSmall, + .outer = to.size(), + })); } replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); } diff --git a/Telegram/SourceFiles/history/view/history_view_react_button.cpp b/Telegram/SourceFiles/history/view/history_view_react_button.cpp index d6ea41727..4cac9dc91 100644 --- a/Telegram/SourceFiles/history/view/history_view_react_button.cpp +++ b/Telegram/SourceFiles/history/view/history_view_react_button.cpp @@ -1144,8 +1144,7 @@ Manager::OverlayImage Manager::validateOverlayShadow( p.end(); } - _overlayShadowScaled = Images::prepareBlur( - std::move(_overlayShadowScaled)); + _overlayShadowScaled = Images::Blur(std::move(_overlayShadowScaled)); auto q = Painter(result.cache); if (result.cache != &_overlayShadowScaled) { @@ -1436,7 +1435,7 @@ QRect Manager::validateShadow( } p.drawRoundedRect(big.translated(0, shift), radius, radius); p.end(); - _shadowBuffer = Images::prepareBlur(std::move(_shadowBuffer)); + _shadowBuffer = Images::Blur(std::move(_shadowBuffer)); auto q = QPainter(&_cacheParts); q.setCompositionMode(QPainter::CompositionMode_Source); diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 72bb56a40..85fe95ba7 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -356,13 +356,18 @@ void Document::draw( const auto inner = QRect(rthumb.x() + (rthumb.width() - innerSize) / 2, rthumb.y() + (rthumb.height() - innerSize) / 2, innerSize, innerSize); const auto radialOpacity = radial ? _animation->radial.opacity() : 1.; if (thumbed) { - auto inWebPage = (_parent->media() != this); - auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large; + const auto inWebPage = (_parent->media() != this); + const auto args = Images::PrepareArgs{ + .options = (inWebPage + ? Images::Option::RoundSmall + : Images::Option::RoundLarge), + .outer = QSize(st.thumbSize, st.thumbSize), + }; QPixmap thumb; if (const auto normal = _dataMedia->thumbnail()) { - thumb = normal->pixSingle(thumbed->_thumbw, 0, st.thumbSize, st.thumbSize, roundRadius); + thumb = normal->pixSingle(thumbed->_thumbw, args); } else if (const auto blurred = _dataMedia->thumbnailInline()) { - thumb = blurred->pixBlurredSingle(thumbed->_thumbw, 0, st.thumbSize, st.thumbSize, roundRadius); + thumb = blurred->pixSingle(thumbed->_thumbw, args.blurred()); } p.drawPixmap(rthumb.topLeft(), thumb); if (context.selected()) { @@ -1090,32 +1095,27 @@ bool DrawThumbnailAsSongCover( return false; } - QPixmap cover; - - const auto ow = rect.width(); - const auto oh = rect.height(); - const auto r = ImageRoundRadius::Ellipse; - const auto c = RectPart::AllCorners; - const auto aspectRatio = Qt::KeepAspectRatioByExpanding; - - const auto scaled = [&](not_null image) -> std::pair { - const auto size = image->size().scaled(ow, oh, aspectRatio); - return { size.width(), size.height() }; + auto cover = QPixmap(); + const auto scaled = [&](not_null image) { + const auto aspectRatio = Qt::KeepAspectRatioByExpanding; + return image->size().scaled(rect.size(), aspectRatio); + }; + const auto args = Images::PrepareArgs{ + .colored = &colored, + .options = Images::Option::RoundCircle, + .outer = rect.size(), }; - if (const auto normal = dataMedia->thumbnail()) { - const auto &[w, h] = scaled(normal); - cover = normal->pixSingle(w, h, ow, oh, r, c, &colored); + cover = normal->pixSingle(scaled(normal), args); } else if (const auto blurred = dataMedia->thumbnailInline()) { - const auto &[w, h] = scaled(blurred); - cover = blurred->pixBlurredSingle(w, h, ow, oh, r, c, &colored); + cover = blurred->pixSingle(scaled(blurred), args.blurred()); } else { return false; } if (selected) { - auto selectedCover = Images::prepareColored( - p.textPalette().selectOverlay, - cover.toImage()); + auto selectedCover = Images::Colored( + cover.toImage(), + p.textPalette().selectOverlay); cover = QPixmap::fromImage( std::move(selectedCover), Qt::ColorOnly); diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index 9c827b373..bfdc2795d 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -439,24 +439,28 @@ void Gif::draw(Painter &p, const PaintContext &context) const { } } else { ensureDataMediaCreated(); + const auto size = QSize(_thumbw, _thumbh); + const auto args = Images::PrepareArgs{ + .options = Images::RoundOptions(roundRadius, roundCorners), + .outer = QSize(usew, painth), + }; if (const auto good = _dataMedia->goodThumbnail()) { - p.drawPixmap(rthumb.topLeft(), good->pixSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); + p.drawPixmap(rthumb.topLeft(), good->pixSingle(size, args)); } else { const auto normal = _dataMedia->thumbnail(); if (normal) { - if (normal->width() >= kUseNonBlurredThreshold - || normal->height() >= kUseNonBlurredThreshold) { - p.drawPixmap(rthumb.topLeft(), normal->pixSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); - } else { - p.drawPixmap(rthumb.topLeft(), normal->pixBlurredSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); - } + const auto blurred = (normal->width() < kUseNonBlurredThreshold) + || (normal->height() < kUseNonBlurredThreshold); + p.drawPixmap( + rthumb.topLeft(), + normal->pixSingle(size, blurred ? args.blurred() : args)); } else { _data->loadThumbnail(_realParent->fullId()); validateVideoThumbnail(); if (_videoThumbnailFrame) { - p.drawPixmap(rthumb.topLeft(), _videoThumbnailFrame->pixSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); + p.drawPixmap(rthumb.topLeft(), _videoThumbnailFrame->pixSingle(size, args)); } else if (const auto blurred = _dataMedia->thumbnailInline()) { - p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); + p.drawPixmap(rthumb.topLeft(), blurred->pixSingle(size, args.blurred())); } else if (!isRound) { const auto roundTop = (roundCorners & RectPart::TopLeft); const auto roundBottom = (roundCorners & RectPart::BottomLeft); @@ -1291,13 +1295,15 @@ void Gif::validateGroupedCache( const auto loadLevel = good ? 3 : thumb ? 2 : image ? 1 : 0; const auto width = geometry.width(); const auto height = geometry.height(); - const auto options = Option::Smooth - | Option::RoundedLarge - | (blur ? Option::Blurred : Option(0)) - | ((corners & RectPart::TopLeft) ? Option::RoundedTopLeft : Option::None) - | ((corners & RectPart::TopRight) ? Option::RoundedTopRight : Option::None) - | ((corners & RectPart::BottomLeft) ? Option::RoundedBottomLeft : Option::None) - | ((corners & RectPart::BottomRight) ? Option::RoundedBottomRight : Option::None); + const auto corner = [&](RectPart part, Option skip) { + return !(corners & part) ? skip : Option(); + }; + const auto options = Option::RoundLarge + | (blur ? Option::Blur : Option(0)) + | corner(RectPart::TopLeft, Option::RoundSkipTopLeft) + | corner(RectPart::TopRight, Option::RoundSkipTopRight) + | corner(RectPart::BottomLeft, Option::RoundSkipBottomLeft) + | corner(RectPart::BottomRight, Option::RoundSkipBottomRight); const auto key = (uint64(width) << 48) | (uint64(height) << 32) | (uint64(options) << 16) @@ -1312,16 +1318,12 @@ void Gif::validateGroupedCache( const auto pixSize = Ui::GetImageScaleSizeForGeometry( { originalWidth, originalHeight }, { width, height }); - const auto pixWidth = pixSize.width() * cIntRetinaFactor(); - const auto pixHeight = pixSize.height() * cIntRetinaFactor(); + const auto ratio = style::DevicePixelRatio(); *cacheKey = key; *cache = (image ? image : Image::BlankMedia().get())->pixNoCache( - pixWidth, - pixHeight, - options, - width, - height); + pixSize * ratio, + { .options = options, .outer = { width, height } }); } void Gif::setStatusSize(int newSize) const { diff --git a/Telegram/SourceFiles/history/view/media/history_view_large_emoji.cpp b/Telegram/SourceFiles/history/view/media/history_view_large_emoji.cpp index 941af50ee..ebce8d94b 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_large_emoji.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_large_emoji.cpp @@ -77,17 +77,15 @@ void LargeEmoji::draw( const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline; const auto size = EmojiImage::Size() / cIntRetinaFactor(); for (const auto &image : images) { - const auto w = size.width(); if (const auto &prepared = image->image) { - const auto h = size.height(); - const auto pixmap = context.selected() - ? prepared->pixColored(context.st->msgStickerOverlay(), w, h) - : prepared->pix(w, h); - p.drawPixmap(x, y, pixmap); + const auto colored = context.selected() + ? &context.st->msgStickerOverlay() + : nullptr; + p.drawPixmap(x, y, prepared->pix(size, { .colored = colored })); } else if (image->load) { image->load(); } - x += w + skip; + x += size.width() + skip; } } diff --git a/Telegram/SourceFiles/history/view/media/history_view_location.cpp b/Telegram/SourceFiles/history/view/media/history_view_location.cpp index d42a25699..07ab77145 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_location.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_location.cpp @@ -194,8 +194,12 @@ void Location::draw(Painter &p, const PaintContext &context) const { auto rthumb = QRect(paintx, painty, paintw, painth); ensureMediaCreated(); if (const auto thumbnail = _media->image()) { - const auto &pix = thumbnail->pixSingle(paintw, painth, paintw, painth, roundRadius, roundCorners); - p.drawPixmap(rthumb.topLeft(), pix); + p.drawPixmap(rthumb.topLeft(), thumbnail->pixSingle( + rthumb.size(), + { + .options = Images::RoundOptions(roundRadius, roundCorners), + .outer = rthumb.size(), + })); } else { Ui::FillComplexLocationRect(p, st, rthumb, roundRadius, roundCorners); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp index 166c99644..30d1555a9 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp @@ -265,21 +265,28 @@ void Photo::draw(Painter &p, const PaintContext &context) const { } else { Ui::FillRoundShadow(p, 0, 0, paintw, painth, sti->msgShadow, sti->msgShadowCorners); } - auto inWebPage = (_parent->media() != this); - auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large; - auto roundCorners = inWebPage ? RectPart::AllCorners : ((isBubbleTop() ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None) + const auto inWebPage = (_parent->media() != this); + const auto roundRadius = inWebPage + ? ImageRoundRadius::Small + : ImageRoundRadius::Large; + const auto roundCorners = inWebPage ? RectPart::AllCorners : ((isBubbleTop() ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None) | ((isRoundedInBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None)); const auto pix = [&] { + const auto size = QSize(_pixw, _pixh); + const auto args = Images::PrepareArgs{ + .options = Images::RoundOptions(roundRadius, roundCorners), + .outer = QSize(paintw, painth), + }; if (const auto large = _dataMedia->image(PhotoSize::Large)) { - return large->pixSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners); + return large->pixSingle(size, args); } else if (const auto thumbnail = _dataMedia->image( PhotoSize::Thumbnail)) { - return thumbnail->pixBlurredSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners); + return thumbnail->pixSingle(size, args.blurred()); } else if (const auto small = _dataMedia->image( PhotoSize::Small)) { - return small->pixBlurredSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners); + return small->pixSingle(size, args.blurred()); } else if (const auto blurred = _dataMedia->thumbnailInline()) { - return blurred->pixBlurredSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners); + return blurred->pixSingle(size, args.blurred()); } else { return QPixmap(); } @@ -389,16 +396,20 @@ void Photo::paintUserpicFrame( return; } const auto pix = [&] { + const auto size = QSize(_pixw, _pixh); + const auto args = Images::PrepareArgs{ + .options = Images::Option::RoundCircle, + }; if (const auto large = _dataMedia->image(PhotoSize::Large)) { - return large->pixCircled(_pixw, _pixh); + return large->pix(size, args); } else if (const auto thumbnail = _dataMedia->image( PhotoSize::Thumbnail)) { - return thumbnail->pixBlurredCircled(_pixw, _pixh); + return thumbnail->pix(size, args.blurred()); } else if (const auto small = _dataMedia->image( PhotoSize::Small)) { - return small->pixBlurredCircled(_pixw, _pixh); + return small->pix(size, args.blurred()); } else if (const auto blurred = _dataMedia->thumbnailInline()) { - return blurred->pixBlurredCircled(_pixw, _pixh); + return blurred->pix(size, args.blurred()); } else { return QPixmap(); } @@ -652,13 +663,15 @@ void Photo::validateGroupedCache( : 0; const auto width = geometry.width(); const auto height = geometry.height(); - const auto options = Option::Smooth - | Option::RoundedLarge - | (loaded ? Option::None : Option::Blurred) - | ((corners & RectPart::TopLeft) ? Option::RoundedTopLeft : Option::None) - | ((corners & RectPart::TopRight) ? Option::RoundedTopRight : Option::None) - | ((corners & RectPart::BottomLeft) ? Option::RoundedBottomLeft : Option::None) - | ((corners & RectPart::BottomRight) ? Option::RoundedBottomRight : Option::None); + const auto corner = [&](RectPart part, Option skip) { + return !(corners & part) ? skip : Option(); + }; + const auto options = Option::RoundLarge + | (loaded ? Option() : Option::Blur) + | corner(RectPart::TopLeft, Option::RoundSkipTopLeft) + | corner(RectPart::TopRight, Option::RoundSkipTopRight) + | corner(RectPart::BottomLeft, Option::RoundSkipBottomLeft) + | corner(RectPart::BottomRight, Option::RoundSkipBottomRight); const auto key = (uint64(width) << 48) | (uint64(height) << 32) | (uint64(options) << 16) @@ -672,8 +685,7 @@ void Photo::validateGroupedCache( const auto pixSize = Ui::GetImageScaleSizeForGeometry( { originalWidth, originalHeight }, { width, height }); - const auto pixWidth = pixSize.width() * cIntRetinaFactor(); - const auto pixHeight = pixSize.height() * cIntRetinaFactor(); + const auto ratio = style::DevicePixelRatio(); const auto image = _dataMedia->image(PhotoSize::Large) ? _dataMedia->image(PhotoSize::Large) : _dataMedia->image(PhotoSize::Thumbnail) @@ -685,7 +697,9 @@ void Photo::validateGroupedCache( : Image::BlankMedia().get(); *cacheKey = key; - *cache = image->pixNoCache(pixWidth, pixHeight, options, width, height); + *cache = image->pixNoCache( + pixSize * ratio, + { .options = options, .outer = { width, height } }); } bool Photo::createStreamingObjects() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp index 1241a59d7..6b30f333d 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp @@ -173,7 +173,9 @@ void Sticker::paintLottie( ? frame.image : _lastDiceFrame; const auto prepared = (!_lastDiceFrame.isNull() && context.selected()) - ? Images::prepareColored(context.st->msgStickerOverlay()->c, image) + ? Images::Colored( + base::duplicate(image), + context.st->msgStickerOverlay()->c) : image; const auto size = prepared.size() / cIntRetinaFactor(); p.drawImage( @@ -252,27 +254,25 @@ void Sticker::paintPath( QPixmap Sticker::paintedPixmap(const PaintContext &context) const { const auto w = _size.width(); const auto h = _size.height(); - const auto &c = context.st->msgStickerOverlay(); + const auto colored = context.selected() + ? &context.st->msgStickerOverlay() + : nullptr; const auto good = _dataMedia->goodThumbnail(); if (const auto image = _dataMedia->getStickerLarge()) { - return context.selected() - ? image->pixColored(c, w, h) - : image->pix(w, h); + return image->pix(_size, { .colored = colored }); // // Inline thumbnails can't have alpha channel. // //} else if (const auto blurred = _data->thumbnailInline()) { - // return context.selected() - // ? blurred->pixBlurredColored(c, w, h) - // : blurred->pixBlurred(w, h); + // return blurred->pix( + // _size, + // { .colored = colored, .options = Images::Option::Blur }); } else if (good) { - return context.selected() - ? good->pixColored(c, w, h) - : good->pix(w, h); + return good->pix(_size, { .colored = colored }); } else if (const auto thumbnail = _dataMedia->thumbnail()) { - return context.selected() - ? thumbnail->pixBlurredColored(c, w, h) - : thumbnail->pixBlurred(w, h); + return thumbnail->pix( + _size, + { .colored = colored, .options = Images::Option::Blur }); } return QPixmap(); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp index a6649b8a6..1c9d8e461 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp @@ -292,8 +292,7 @@ void ThemeDocument::prepareThumbnailFrom( const auto isTheme = _data->isTheme(); const auto isPattern = _data->isPatternWallPaper(); - auto options = Images::Option::Smooth - | (good >= 0 ? Images::Option(0) : Images::Option::Blurred) + auto options = (good >= 0 ? Images::Option(0) : Images::Option::Blur) | (isPattern ? Images::Option::TransparentBackground : Images::Option(0)); @@ -304,20 +303,18 @@ void ThemeDocument::prepareThumbnailFrom( if (!tw || !th) { tw = th = 1; } - original = Images::prepare( + const auto ratio = style::DevicePixelRatio(); + original = Images::Prepare( std::move(original), - _pixw * cIntRetinaFactor(), - ((_pixw * th) / tw) * cIntRetinaFactor(), - options, - _pixw, - _pixh); + QSize(_pixw, (_pixw * th) / tw) * ratio, + { .options = options, .outer = { _pixw, _pixh } }); if (isPattern) { original = Ui::PreparePatternImage( std::move(original), _background, _gradientRotation, _patternOpacity); - original.setDevicePixelRatio(cRetinaFactor()); + original.setDevicePixelRatio(ratio); } _thumbnail = Ui::PixmapFromImage(std::move(original)); _thumbnailGood = good; diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index 486af7747..2cbb84f0a 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -508,14 +508,19 @@ void WebPage::draw(Painter &p, const PaintContext &context) const { pixh = qRound(pixh * coef); pixw = qRound(pixw * coef); } + const auto size = QSize(pixw, pixh); + const auto args = Images::PrepareArgs{ + .options = Images::Option::RoundSmall, + .outer = { pw, ph }, + }; if (const auto thumbnail = _photoMedia->image( Data::PhotoSize::Thumbnail)) { - pix = thumbnail->pixSingle(pixw, pixh, pw, ph, ImageRoundRadius::Small); + pix = thumbnail->pixSingle(size, args); } else if (const auto small = _photoMedia->image( Data::PhotoSize::Small)) { - pix = small->pixBlurredSingle(pixw, pixh, pw, ph, ImageRoundRadius::Small); + pix = small->pixSingle(size, args.blurred()); } else if (const auto blurred = _photoMedia->thumbnailInline()) { - pix = blurred->pixBlurredSingle(pixw, pixh, pw, ph, ImageRoundRadius::Small); + pix = blurred->pixSingle(size, args.blurred()); } p.drawPixmapLeft(padding.left() + paintw - pw, tshift, width(), pix); if (context.selected()) { diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp index fe73c81dd..b16c9c2c1 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp @@ -319,13 +319,12 @@ void Gif::validateThumbnail( } _thumbGood = good; _thumb = image->pixNoCache( - frame.width() * cIntRetinaFactor(), - frame.height() * cIntRetinaFactor(), - (Images::Option::Smooth - | (good ? Images::Option::None : Images::Option::Blurred) - | Images::Option::TransparentBackground), - size.width(), - size.height()); + frame * style::DevicePixelRatio(), + { + .options = (Images::Option::TransparentBackground + | (good ? Images::Option() : Images::Option::Blur)), + .outer = size, + }); } void Gif::prepareThumbnail(QSize size, QSize frame) const { @@ -563,9 +562,7 @@ void Sticker::prepareThumbnail() const { if (const auto sticker = _dataMedia->getStickerSmall()) { if (!_lottie && !_thumbLoaded) { const auto thumbSize = getThumbSize(); - _thumb = sticker->pix( - thumbSize.width(), - thumbSize.height()); + _thumb = sticker->pix(thumbSize); _thumbLoaded = true; } } @@ -662,13 +659,12 @@ void Photo::validateThumbnail( } const auto origin = fileOrigin(); _thumb = image->pixNoCache( - frame.width() * cIntRetinaFactor(), - frame.height() * cIntRetinaFactor(), - (Images::Option::Smooth - | (good ? Images::Option(0) : Images::Option::Blurred) - | Images::Option::TransparentBackground), - size.width(), - size.height()); + frame * style::DevicePixelRatio(), + { + .options = (Images::Option::TransparentBackground + | (good ? Images::Option() : Images::Option::Blur)), + .outer = size, + }); _thumbGood = good; } @@ -823,11 +819,11 @@ void Video::prepareThumbnail(QSize size) const { } } _thumb = thumb->pixNoCache( - w * cIntRetinaFactor(), - h * cIntRetinaFactor(), - Images::Option::Smooth | Images::Option::TransparentBackground, - width, - height); + QSize(w, h) * style::DevicePixelRatio(), + { + .options = Images::Option::TransparentBackground, + .outer = size, + }); } } @@ -1162,11 +1158,11 @@ void Contact::prepareThumbnail(int width, int height) const { } } _thumb = thumb->pixNoCache( - w * cIntRetinaFactor(), - h * cIntRetinaFactor(), - Images::Option::Smooth | Images::Option::TransparentBackground, - width, - height); + QSize(w, h) * style::DevicePixelRatio(), + { + .options = Images::Option::TransparentBackground, + .outer = { width, height }, + }); } Article::Article( @@ -1320,11 +1316,11 @@ void Article::prepareThumbnail(int width, int height) const { } } _thumb = thumb->pixNoCache( - w * cIntRetinaFactor(), - h * cIntRetinaFactor(), - Images::Option::Smooth | Images::Option::TransparentBackground, - width, - height); + QSize(w, h) * style::DevicePixelRatio(), + { + .options = Images::Option::TransparentBackground, + .outer = { width, height }, + }); } Game::Game(not_null context, not_null result) @@ -1539,13 +1535,12 @@ void Game::validateThumbnail(Image *image, QSize size, bool good) const { } _thumbGood = good; _thumb = image->pixNoCache( - w * cIntRetinaFactor(), - h * cIntRetinaFactor(), - (Images::Option::Smooth - | (good ? Images::Option::None : Images::Option::Blurred) - | Images::Option::TransparentBackground), - size.width(), - size.height()); + QSize(w, h) * style::DevicePixelRatio(), + { + .options = (Images::Option::TransparentBackground + | (good ? Images::Option() : Images::Option::Blur)), + .outer = size, + }); } bool Game::isRadialAnimation() const { diff --git a/Telegram/SourceFiles/media/clip/media_clip_reader.cpp b/Telegram/SourceFiles/media/clip/media_clip_reader.cpp index 83a5268cb..a36758720 100644 --- a/Telegram/SourceFiles/media/clip/media_clip_reader.cpp +++ b/Telegram/SourceFiles/media/clip/media_clip_reader.cpp @@ -79,7 +79,10 @@ QImage PrepareFrameImage(const FrameRequest &request, const QImage &original, bo } } if (needRounding) { - Images::prepareRound(cache, request.radius, request.corners); + cache = Images::Round( + std::move(cache), + request.radius, + request.corners); } return cache; } diff --git a/Telegram/SourceFiles/media/player/media_player_float.cpp b/Telegram/SourceFiles/media/player/media_player_float.cpp index e1899950f..4929b2eff 100644 --- a/Telegram/SourceFiles/media/player/media_player_float.cpp +++ b/Telegram/SourceFiles/media/player/media_player_float.cpp @@ -173,7 +173,7 @@ void Float::prepareShadow() { auto extend = 2 * st::lineWidth; p.drawEllipse(getInnerRect().marginsAdded(QMargins(extend, extend, extend, extend))); } - _shadow = Ui::PixmapFromImage(Images::prepareBlur(std::move(shadow))); + _shadow = Ui::PixmapFromImage(Images::Blur(std::move(shadow))); } QRect Float::getInnerRect() const { diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_utility.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_utility.cpp index 6a65b7769..951f66a8a 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_utility.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_utility.cpp @@ -283,7 +283,10 @@ void ApplyFrameRounding(QImage &storage, const FrameRequest &request) { || (request.radius == ImageRoundRadius::None)) { return; } - Images::prepareRound(storage, request.radius, request.corners); + storage = Images::Round( + std::move(storage), + request.radius, + request.corners); } QImage PrepareByRequest( diff --git a/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp b/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp index 9f097dbb1..4755bf071 100644 --- a/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp +++ b/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp @@ -300,10 +300,7 @@ void GroupThumbs::Thumb::validateImage() { Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } else { - _full = _image->pixNoCache( - pixSize.width() * cIntRetinaFactor(), - pixSize.height() * cIntRetinaFactor(), - Images::Option::Smooth); + _full = _image->pixNoCache(pixSize * style::DevicePixelRatio()); } _fullWidth = std::min( wantedPixSize().width(), diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 683ddc00c..148e4c356 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -147,9 +147,9 @@ QWidget *PipDelegate::pipParentWidget() { } [[nodiscard]] Images::Options VideoThumbOptions(DocumentData *document) { - const auto result = Images::Option::Smooth | Images::Option::Blurred; + const auto result = Images::Option::Blur; return (document && document->isVideoMessage()) - ? (result | Images::Option::Circled) + ? (result | Images::Option::RoundCircle) : result; } @@ -2453,9 +2453,9 @@ void OverlayWidget::displayDocument( if (const auto image = _documentMedia->getStickerLarge()) { setStaticContent(image->original()); } else if (const auto thumbnail = _documentMedia->thumbnail()) { - setStaticContent(thumbnail->pixBlurred( - _document->dimensions.width(), - _document->dimensions.height() + setStaticContent(thumbnail->pix( + _document->dimensions, + { .options = Images::Option::Blur } ).toImage()); } } else { @@ -2712,10 +2712,8 @@ void OverlayWidget::initStreamingThumbnail() { } else if (size.isEmpty()) { return; } - const auto w = size.width(); - const auto h = size.height(); const auto options = VideoThumbOptions(_document); - const auto goodOptions = (options & ~Images::Option::Blurred); + const auto goodOptions = (options & ~Images::Option::Blur); setStaticContent((good ? good : thumbnail @@ -2723,11 +2721,11 @@ void OverlayWidget::initStreamingThumbnail() { : blurred ? blurred : Image::BlankMedia().get())->pixNoCache( - w, - h, - good ? goodOptions : options, - w / cIntRetinaFactor(), - h / cIntRetinaFactor() + size, + { + .options = good ? goodOptions : options, + .outer = size / style::DevicePixelRatio(), + } ).toImage()); } @@ -3271,10 +3269,8 @@ void OverlayWidget::validatePhotoImage(Image *image, bool blurred) { const auto use = flipSizeByRotation({ _width, _height }) * cIntRetinaFactor(); setStaticContent(image->pixNoCache( - use.width(), - use.height(), - Images::Option::Smooth - | (blurred ? Images::Option::Blurred : Images::Option(0)) + use, + { .options = (blurred ? Images::Option::Blur : Images::Option()) } ).toImage()); _blurred = blurred; } diff --git a/Telegram/SourceFiles/media/view/media_view_pip.cpp b/Telegram/SourceFiles/media/view/media_view_pip.cpp index 4c407d94e..ea0534490 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip.cpp +++ b/Telegram/SourceFiles/media/view/media_view_pip.cpp @@ -1660,7 +1660,7 @@ QImage Pip::staticContent() const { ? blurred : Image::BlankMedia().get())->original(); if (!good) { - _preparedCoverStorage = Images::prepareBlur( + _preparedCoverStorage = Images::Blur( std::move(_preparedCoverStorage)); } } diff --git a/Telegram/SourceFiles/media/view/media_view_pip_raster.cpp b/Telegram/SourceFiles/media/view/media_view_pip_raster.cpp index 9dc52aca7..bc858a787 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip_raster.cpp +++ b/Telegram/SourceFiles/media/view/media_view_pip_raster.cpp @@ -175,27 +175,18 @@ QImage Pip::RendererSW::staticContentByRequest( // request, // std::move(_preparedCoverStorage)); using Option = Images::Option; - const auto options = Option::Smooth - | Option::RoundedLarge - | ((request.corners & RectPart::TopLeft) - ? Option::RoundedTopLeft - : Option(0)) - | ((request.corners & RectPart::TopRight) - ? Option::RoundedTopRight - : Option(0)) - | ((request.corners & RectPart::BottomRight) - ? Option::RoundedBottomRight - : Option(0)) - | ((request.corners & RectPart::BottomLeft) - ? Option::RoundedBottomLeft - : Option(0)); - _preparedStaticContent = Images::prepare( + const auto corner = [&](RectPart part, Option skip) { + return !(request.corners & part) ? skip : Option(); + }; + const auto options = Option::RoundLarge + | corner(RectPart::TopLeft, Option::RoundSkipTopLeft) + | corner(RectPart::TopRight, Option::RoundSkipTopRight) + | corner(RectPart::BottomLeft, Option::RoundSkipBottomLeft) + | corner(RectPart::BottomRight, Option::RoundSkipBottomRight); + _preparedStaticContent = Images::Prepare( image, - request.resize.width(), - request.resize.height(), - options, - request.outer.width(), - request.outer.height()); + request.resize, + { .options = options, .outer = request.outer }); return _preparedStaticContent; } diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index b87e0edaf..f87611eff 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -358,7 +358,7 @@ void Photo::setPixFrom(not_null image) { const auto size = _width * cIntRetinaFactor(); auto img = image->original(); if (!_goodLoaded) { - img = Images::prepareBlur(std::move(img)); + img = Images::Blur(std::move(img)); } if (img.width() == img.height()) { if (img.width() != size) { @@ -457,7 +457,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const ? good->original() : thumbnail ? thumbnail->original() - : Images::prepareBlur(blurred->original()); + : Images::Blur(blurred->original()); if (img.width() == img.height()) { if (img.width() != size) { img = img.scaled(size, size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); @@ -691,9 +691,11 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const p.setPen(Qt::NoPen); if (thumbnail || blurred) { - const auto thumb = thumbnail - ? thumbnail->pixCircled(inner.width(), inner.height()) - : blurred->pixBlurredCircled(inner.width(), inner.height()); + const auto options = Images::Option::RoundCircle + | (blurred ? Images::Option::Blur : Images::Option()); + const auto thumb = (thumbnail ? thumbnail : blurred)->pix( + inner.size(), + { .options = options }); p.drawPixmap(inner.topLeft(), thumb); } else if (_data->hasThumbnail()) { PainterHighQualityEnabler hq(p); @@ -1101,12 +1103,18 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con if (thumbnail || blurred) { if (_thumb.isNull() || (thumbnail && !_thumbLoaded)) { _thumbLoaded = (thumbnail != nullptr); - auto options = Images::Option::Smooth - | (_thumbLoaded - ? Images::Option::None - : Images::Option::Blurred); + const auto options = _thumbLoaded + ? Images::Option() + : Images::Option::Blur; const auto image = thumbnail ? thumbnail : blurred; - _thumb = image->pixNoCache(_thumbw * cIntRetinaFactor(), 0, options, _st.fileThumbSize, _st.fileThumbSize); + _thumb = image->pixNoCache( + _thumbw * style::DevicePixelRatio(), + { + .options = options, + .outer = QSize( + _st.fileThumbSize, + _st.fileThumbSize), + }); } p.drawPixmap(rthumb.topLeft(), _thumb); } else { @@ -1668,20 +1676,26 @@ void Link::validateThumbnail() { if (!_thumbnail.isNull() && !_thumbnailBlurred) { return; } + const auto size = QSize(_pixw, _pixh); + const auto outer = QSize(st::linksPhotoSize, st::linksPhotoSize); if (_page && _page->photo) { using Data::PhotoSize; ensurePhotoMediaCreated(); + const auto args = Images::PrepareArgs{ + .options = Images::Option::RoundSmall, + .outer = outer, + }; if (const auto thumbnail = _photoMedia->image(PhotoSize::Thumbnail)) { - _thumbnail = thumbnail->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); + _thumbnail = thumbnail->pixSingle(size, args); _thumbnailBlurred = false; } else if (const auto large = _photoMedia->image(PhotoSize::Large)) { - _thumbnail = large->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); + _thumbnail = large->pixSingle(size, args); _thumbnailBlurred = false; } else if (const auto small = _photoMedia->image(PhotoSize::Small)) { - _thumbnail = small->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); + _thumbnail = small->pixSingle(size, args); _thumbnailBlurred = false; } else if (const auto blurred = _photoMedia->thumbnailInline()) { - _thumbnail = blurred->pixBlurredSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); + _thumbnail = blurred->pixSingle(size, args.blurred()); return; } else { return; @@ -1690,14 +1704,17 @@ void Link::validateThumbnail() { delegate()->unregisterHeavyItem(this); } else if (_page && _page->document && _page->document->hasThumbnail()) { ensureDocumentMediaCreated(); - const auto roundRadius = _page->document->isVideoMessage() - ? ImageRoundRadius::Ellipse - : ImageRoundRadius::Small; + const auto args = Images::PrepareArgs{ + .options = (_page->document->isVideoMessage() + ? Images::Option::RoundCircle + : Images::Option::RoundSmall), + .outer = outer, + }; if (const auto thumbnail = _documentMedia->thumbnail()) { - _thumbnail = thumbnail->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius); + _thumbnail = thumbnail->pixSingle(size, args); _thumbnailBlurred = false; } else if (const auto blurred = _documentMedia->thumbnailInline()) { - _thumbnail = blurred->pixBlurredSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius); + _thumbnail = blurred->pixSingle(size, args.blurred()); return; } else { return; @@ -1930,12 +1947,11 @@ void Gif::validateThumbnail( } _thumbGood = good; _thumb = image->pixNoCache( - frame.width() * cIntRetinaFactor(), - frame.height() * cIntRetinaFactor(), - (Images::Option::Smooth - | (good ? Images::Option::None : Images::Option::Blurred)), - size.width(), - size.height()); + frame * style::DevicePixelRatio(), + { + .options = (good ? Images::Option() : Images::Option::Blur), + .outer = size, + }); } void Gif::prepareThumbnail(QSize size, QSize frame) { diff --git a/Telegram/SourceFiles/payments/payments_form.cpp b/Telegram/SourceFiles/payments/payments_form.cpp index d3669f296..7bd866915 100644 --- a/Telegram/SourceFiles/payments/payments_form.cpp +++ b/Telegram/SourceFiles/payments/payments_form.cpp @@ -239,10 +239,10 @@ QImage Form::prepareThumbnail( not_null image, bool blurred) const { auto result = image->original().scaled( - st::paymentsThumbnailSize * cIntRetinaFactor(), + st::paymentsThumbnailSize * style::DevicePixelRatio(), Qt::KeepAspectRatio, Qt::SmoothTransformation); - Images::prepareRound(result, ImageRoundRadius::Large); + result = Images::Round(std::move(result), ImageRoundRadius::Large); result.setDevicePixelRatio(cRetinaFactor()); return result; } diff --git a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm index ad42f4fbc..899b549c6 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm +++ b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm @@ -106,11 +106,8 @@ struct PickerScrubberItem { const auto size = sticker->size() .scaled(kCircleDiameter, kCircleDiameter, Qt::KeepAspectRatio); image = sticker->pixSingle( - size.width(), - size.height(), - kCircleDiameter, - kCircleDiameter, - ImageRoundRadius::None).toImage(); + size, + { .outer = { kCircleDiameter, kCircleDiameter } }).toImage(); } bool isStickerLoaded() const { diff --git a/Telegram/SourceFiles/platform/mac/window_title_mac.mm b/Telegram/SourceFiles/platform/mac/window_title_mac.mm index c8002c05c..bbcfc5c25 100644 --- a/Telegram/SourceFiles/platform/mac/window_title_mac.mm +++ b/Telegram/SourceFiles/platform/mac/window_title_mac.mm @@ -127,8 +127,13 @@ void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRe corners[1] = roundMask.copy(retinaRadius, 0, retinaRadius, retinaRadius); corners[2] = roundMask.copy(0, retinaRadius, retinaRadius, retinaRadius); corners[3] = roundMask.copy(retinaRadius, retinaRadius, retinaRadius, retinaRadius); - auto rounded = preview.copy(inner.x() * retina, inner.y() * retina, inner.width() * retina, inner.height() * retina); - Images::prepareRound(rounded, corners); + auto rounded = Images::Round( + preview.copy( + inner.x() * retina, + inner.y() * retina, + inner.width() * retina, + inner.height() * retina), + corners); rounded.setDevicePixelRatio(cRetinaFactor()); preview.fill(st::themePreviewBg->c); diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index 7e98193d2..3449782ca 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -446,8 +446,9 @@ void BackgroundRow::paintEvent(QPaintEvent *e) { if (!backThumb) { p.drawPixmap(0, 0, _background); } else { - const auto &pix = backThumb->pixBlurred( - st::settingsBackgroundThumb); + const auto &pix = backThumb->pix( + st::settingsBackgroundThumb, + { .options = Images::Option::Blur }); const auto factor = cIntRetinaFactor(); p.drawPixmap( 0, @@ -612,8 +613,8 @@ void BackgroundRow::updateImage() { auto back = (paper.isPattern() || !background.gradientForFill().isNull()) ? preparePattern() : prepareNormal(); - Images::prepareRound(back, ImageRoundRadius::Small); - _background = Ui::PixmapFromImage(std::move(back)); + _background = Ui::PixmapFromImage( + Images::Round(std::move(back), ImageRoundRadius::Small)); _background.setDevicePixelRatio(cRetinaFactor()); rtlupdate(radialRect()); diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index 6f5784c0b..e3dfe5d3c 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -724,7 +724,7 @@ void FileLoadTask::process(Args &&args) { &_information->media)) { fullimage = base::take(image->data); if (!Core::IsMimeSticker(filemime)) { - fullimage = Images::prepareOpaque(std::move(fullimage)); + fullimage = Images::Opaque(std::move(fullimage)); } isAnimation = image->animated; } @@ -743,7 +743,7 @@ void FileLoadTask::process(Args &&args) { const auto mimeType = Core::MimeTypeForData(_content); filemime = mimeType.name(); if (!Core::IsMimeSticker(filemime)) { - fullimage = Images::prepareOpaque(std::move(fullimage)); + fullimage = Images::Opaque(std::move(fullimage)); } if (filemime == "image/jpeg") { filename = filedialogDefaultName(qsl("photo"), qsl(".jpg"), QString(), true); @@ -784,7 +784,7 @@ void FileLoadTask::process(Args &&args) { } filesize = _content.size(); } - fullimage = Images::prepareOpaque(std::move(fullimage)); + fullimage = Images::Opaque(std::move(fullimage)); } } _result->filesize = (int32)qMin(filesize, qint64(INT_MAX)); diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp index 8fa41cfac..7893d7ad7 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp +++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp @@ -304,7 +304,8 @@ void PrepareDetails(PreparedFile &file, int previewWidth) { } else if (const auto video = std::get_if