diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp index 391272951..d4f836e2b 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp @@ -547,10 +547,6 @@ void BackgroundPreviewBox::paintEvent(QPaintEvent *e) { void BackgroundPreviewBox::paintImage(Painter &p) { Expects(!_scaled.isNull()); - const auto master = _paper.isPattern() - ? std::clamp(_paper.patternIntensity() / 100., 0., 1.) - : 1.; - const auto factor = cIntRetinaFactor(); const auto size = st::boxWideWidth; const auto from = QRect( @@ -567,7 +563,7 @@ void BackgroundPreviewBox::paintImage(Painter &p) { const auto &pixmap = (!_blurred.isNull() && _paper.isBlurred()) ? _blurred : _scaled; - p.setOpacity(master * fade); + p.setOpacity(fade); p.drawPixmap(rect(), pixmap, from); checkBlurAnimationStart(); } diff --git a/Telegram/SourceFiles/data/data_wall_paper.cpp b/Telegram/SourceFiles/data/data_wall_paper.cpp index af2baad93..a71931e4f 100644 --- a/Telegram/SourceFiles/data/data_wall_paper.cpp +++ b/Telegram/SourceFiles/data/data_wall_paper.cpp @@ -55,6 +55,10 @@ constexpr auto kVersion = 1; int(serialized & 0xFFU))); } +[[nodiscard]] QColor DefaultBackgroundColor() { + return QColor(213, 223, 233); +} + [[nodiscard]] std::optional MaybeColorFromSerialized( const tl::conditional &mtp) { return mtp ? MaybeColorFromSerialized(mtp->v) : std::nullopt; @@ -460,7 +464,7 @@ std::optional WallPaper::Create( }); } if (result.isPattern() && result.backgroundColors().empty()) { - return std::nullopt; + result._backgroundColors.push_back(DefaultBackgroundColor()); } return result; } @@ -489,7 +493,7 @@ std::optional WallPaper::Create(const MTPDwallPaperNoFile &data) { }); } if (result.backgroundColors().empty()) { - return std::nullopt; + result._backgroundColors.push_back(DefaultBackgroundColor()); } return result; } @@ -625,7 +629,7 @@ std::optional WallPaper::FromSerialized( result._intensity = intensity; result._rotation = rotation; if (result.isPattern() && result.backgroundColors().empty()) { - return std::nullopt; + result._backgroundColors.push_back(DefaultBackgroundColor()); } return result; } @@ -643,7 +647,7 @@ std::optional WallPaper::FromLegacySerialized( result._backgroundColors.push_back(*color); } if (result.isPattern() && result.backgroundColors().empty()) { - return std::nullopt; + result._backgroundColors.push_back(DefaultBackgroundColor()); } return result; } @@ -755,28 +759,36 @@ bool IsCloudWallPaper(const WallPaper &paper) { } QImage PreparePatternImage( - QImage image, + QSize size, + Fn drawPattern, const std::vector &bg, int rotation, float64 opacity) { - if (image.format() != QImage::Format_ARGB32_Premultiplied) { - image = std::move(image).convertToFormat( - QImage::Format_ARGB32_Premultiplied); - } - - auto result = QImage(image.size(), QImage::Format_ARGB32_Premultiplied); + auto result = QImage(size, QImage::Format_ARGB32_Premultiplied); if (bg.size() < 2) { - result.fill(bg.empty() ? QColor(213, 223, 233) : bg.front()); + result.fill(bg.empty() ? DefaultBackgroundColor() : bg.front()); } else { result = FillDitheredGradient(std::move(result), bg, rotation); } auto p = QPainter(&result); p.setCompositionMode(QPainter::CompositionMode_SoftLight); p.setOpacity(opacity); - p.drawImage(QRect(QPoint(), image.size()), image); + drawPattern(p); p.end(); - image = QImage(); + return result; +} + +QImage PreparePatternImage( + QImage pattern, + const std::vector &bg, + int rotation, + float64 opacity) { + auto result = PreparePatternImage(pattern.size(), [&](QPainter &p) { + p.drawImage(QRect(QPoint(), pattern.size()), pattern); + }, bg, rotation, opacity); + + pattern = QImage(); return result; } diff --git a/Telegram/SourceFiles/data/data_wall_paper.h b/Telegram/SourceFiles/data/data_wall_paper.h index 8c6d93ddc..e4ff66e78 100644 --- a/Telegram/SourceFiles/data/data_wall_paper.h +++ b/Telegram/SourceFiles/data/data_wall_paper.h @@ -123,7 +123,13 @@ private: [[nodiscard]] bool IsCloudWallPaper(const WallPaper &paper); [[nodiscard]] QImage PreparePatternImage( - QImage image, + QSize size, + Fn drawPattern, + const std::vector &bg, + int rotation, + float64 opacity); +[[nodiscard]] QImage PreparePatternImage( + QImage pattern, const std::vector &bg, int rotation, float64 opacity); diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index 3eb496fce..a755be623 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -87,7 +87,6 @@ constexpr auto kMinDiffIntensity = 0.25; [[nodiscard]] bool IsFilledCover() { const auto background = Window::Theme::Background(); - return false; AssertIsDebug(); return background->tile() || background->colorForFill().has_value() || !background->gradientForFill().isNull() @@ -985,12 +984,25 @@ void MainMenu::refreshMenu() { } void MainMenu::refreshBackground() { - const auto fill = QRect(0, 0, width(), st::mainMenuCoverHeight); + const auto fill = QRect(0, 0, st::mainMenuWidth, st::mainMenuCoverHeight); const auto intensityText = IntensityOfColor(st::mainMenuCoverFg->c); - QImage backgroundImage( - st::mainMenuWidth * cIntRetinaFactor(), - st::mainMenuCoverHeight * cIntRetinaFactor(), - QImage::Format_ARGB32_Premultiplied); + const auto background = Window::Theme::Background(); + const auto &paper = background->paper(); + const auto &pixmap = background->pixmap(); + + QRect to, from; + Window::Theme::ComputeBackgroundRects(fill, pixmap.size(), to, from); + + auto backgroundImage = paper.isPattern() + ? Data::PreparePatternImage( + fill.size() * cIntRetinaFactor(), + [&](QPainter &p) { p.drawPixmap(to, pixmap, from); }, + paper.backgroundColors(), + paper.gradientRotation(), + paper.patternOpacity()) + : QImage( + fill.size() * cIntRetinaFactor(), + QImage::Format_ARGB32_Premultiplied); QPainter p(&backgroundImage); const auto drawShadow = [](QPainter &p) { @@ -1005,7 +1017,7 @@ void MainMenu::refreshBackground() { }; // Solid color. - if (const auto color = Window::Theme::Background()->colorForFill()) { + if (const auto color = background->colorForFill()) { const auto intensity = IntensityOfColor(*color); p.fillRect(fill, *color); if (std::abs(intensity - intensityText) < kMinDiffIntensity) { @@ -1016,9 +1028,9 @@ void MainMenu::refreshBackground() { } // Background image. - const auto &pixmap = Window::Theme::Background()->pixmap(); - QRect to, from; - Window::Theme::ComputeBackgroundRects(fill, pixmap.size(), to, from); + if (!paper.isPattern()) { + p.drawPixmap(to, pixmap, from); + } // Cut off the part of the background that is under text. const QRect underText( @@ -1029,8 +1041,6 @@ void MainMenu::refreshBackground() { _controller->session().user()->nameText().toString()), st::normalFont->width(_phoneText)), st::semiboldFont->height * 2); - - p.drawPixmap(to, pixmap, from); if (IsShadowShown(backgroundImage, underText, intensityText)) { drawShadow(p); }