Use Ui::GenerateBackgroundImage for preview in Settings.

This commit is contained in:
John Preston 2021-09-27 20:14:46 +04:00
parent ab0d2bf9c6
commit b1ba9a42c6

View file

@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/chat/attach/attach_extensions.h" #include "ui/chat/attach/attach_extensions.h"
#include "ui/chat/chat_theme.h"
#include "ui/layers/generic_box.h" #include "ui/layers/generic_box.h"
#include "ui/effects/radial_animation.h" #include "ui/effects/radial_animation.h"
#include "ui/style/style_palette_colorizer.h" #include "ui/style/style_palette_colorizer.h"
@ -556,61 +557,61 @@ void BackgroundRow::updateImage() {
const auto size = st::settingsBackgroundThumb; const auto size = st::settingsBackgroundThumb;
const auto fullsize = size * cIntRetinaFactor(); const auto fullsize = size * cIntRetinaFactor();
// We use Format_RGB32 so that DestinationIn shows black, not transparent. const auto &background = *Window::Theme::Background();
// Then we'll convert to Format_ARGB32_Premultiplied for round corners. const auto &paper = background.paper();
auto back = QImage(fullsize, fullsize, QImage::Format_RGB32); const auto &prepared = background.prepared();
back.setDevicePixelRatio(cRetinaFactor()); const auto preparePattern = [&] {
{ const auto paintPattern = [&](QPainter &p, bool inverted) {
Painter p(&back); if (prepared.isNull()) {
PainterHighQualityEnabler hq(p); return;
const auto background = Window::Theme::Background();
if (const auto color = background->colorForFill()) {
p.fillRect(0, 0, size, size, *color);
} else {
const auto gradient = background->gradientForFill();
const auto patternOpacity = background->paper().patternOpacity();
if (!gradient.isNull()) {
auto hq = PainterHighQualityEnabler(p);
p.drawImage(QRect(0, 0, size, size), gradient);
if (patternOpacity >= 0.) {
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
p.setOpacity(patternOpacity);
} else {
p.setCompositionMode(
QPainter::CompositionMode_DestinationIn);
}
} }
const auto &prepared = background->prepared(); const auto w = prepared.width();
if (!prepared.isNull()) { const auto h = prepared.height();
const auto pattern = background->paper().isPattern(); const auto s = [&] {
const auto w = prepared.width(); const auto scaledw = w * st::windowMinHeight / h;
const auto h = prepared.height(); const auto result = (w * size) / scaledw;
const auto use = [&] { return std::min({ result, w, h });
if (!pattern) { }();
return std::min(w, h); auto small = prepared.copy((w - s) / 2, (h - s) / 2, s, s);
} if (inverted) {
const auto scaledw = w * st::windowMinHeight / h; small = Ui::InvertPatternImage(std::move(small));
const auto result = (w * size) / scaledw;
return std::min({ result, w, h });
}();
p.drawImage(
QRect(0, 0, size, size),
prepared,
QRect((w - use) / 2, (h - use) / 2, use, use));
}
if (!gradient.isNull()
&& !prepared.isNull()
&& patternOpacity < 0.
&& patternOpacity > -1.) {
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
p.setOpacity(1. + patternOpacity);
p.fillRect(QRect(0, 0, size, size), Qt::black);
} }
p.drawImage(QRect(0, 0, size, size), small);
};
return Ui::GenerateBackgroundImage(
{ fullsize, fullsize },
paper.backgroundColors(),
paper.gradientRotation(),
paper.patternOpacity(),
paintPattern);
};
const auto prepareNormal = [&] {
auto result = QImage(
QSize{ fullsize, fullsize },
QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor());
if (const auto color = background.colorForFill()) {
result.fill(*color);
return result;
} else if (prepared.isNull()) {
result.fill(Qt::transparent);
return result;
} }
} Painter p(&result);
back = std::move(back).convertToFormat( PainterHighQualityEnabler hq(p);
QImage::Format_ARGB32_Premultiplied); const auto w = prepared.width();
const auto h = prepared.height();
const auto s = std::min(w, h);
p.drawImage(
QRect(0, 0, size, size),
prepared,
QRect((w - s) / 2, (h - s) / 2, s, s));
p.end();
return result;
};
auto back = (paper.isPattern() || !background.gradientForFill().isNull())
? preparePattern()
: prepareNormal();
Images::prepareRound(back, ImageRoundRadius::Small); Images::prepareRound(back, ImageRoundRadius::Small);
_background = Ui::PixmapFromImage(std::move(back)); _background = Ui::PixmapFromImage(std::move(back));
_background.setDevicePixelRatio(cRetinaFactor()); _background.setDevicePixelRatio(cRetinaFactor());