mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Support patterns with negative intensity.
This commit is contained in:
parent
5383ae3d96
commit
662966ba31
7 changed files with 109 additions and 42 deletions
|
@ -279,7 +279,7 @@ bool ServiceCheck::checkRippleStartPosition(QPoint position) const {
|
|||
});
|
||||
}
|
||||
|
||||
AdminLog::OwnedItem GenerateTextItem(
|
||||
[[nodiscard]] AdminLog::OwnedItem GenerateTextItem(
|
||||
not_null<HistoryView::ElementDelegate*> delegate,
|
||||
not_null<History*> history,
|
||||
const QString &text,
|
||||
|
@ -308,7 +308,7 @@ AdminLog::OwnedItem GenerateTextItem(
|
|||
return AdminLog::OwnedItem(delegate, item);
|
||||
}
|
||||
|
||||
QImage PrepareScaledNonPattern(
|
||||
[[nodiscard]] QImage PrepareScaledNonPattern(
|
||||
const QImage &image,
|
||||
Images::Option blur) {
|
||||
const auto size = st::boxWideWidth;
|
||||
|
@ -331,7 +331,7 @@ QImage PrepareScaledNonPattern(
|
|||
size);
|
||||
}
|
||||
|
||||
QImage PrepareScaledFromFull(
|
||||
[[nodiscard]] QImage PrepareScaledFromFull(
|
||||
const QImage &image,
|
||||
bool isPattern,
|
||||
const std::vector<QColor> &background,
|
||||
|
@ -350,6 +350,12 @@ QImage PrepareScaledFromFull(
|
|||
QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage BlackImage(QSize size) {
|
||||
auto result = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
||||
result.fill(Qt::black);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BackgroundPreviewBox::BackgroundPreviewBox(
|
||||
|
@ -385,10 +391,14 @@ void BackgroundPreviewBox::generateBackground() {
|
|||
if (_paper.backgroundColors().empty()) {
|
||||
return;
|
||||
}
|
||||
_generated = Ui::PixmapFromImage(Data::GenerateWallPaper(
|
||||
QSize(st::boxWideWidth, st::boxWideWidth) * cIntRetinaFactor(),
|
||||
_paper.backgroundColors(),
|
||||
_paper.gradientRotation()));
|
||||
const auto size = QSize(st::boxWideWidth, st::boxWideWidth)
|
||||
* cIntRetinaFactor();
|
||||
_generated = Ui::PixmapFromImage((_paper.patternOpacity() >= 0.)
|
||||
? Data::GenerateWallPaper(
|
||||
size,
|
||||
_paper.backgroundColors(),
|
||||
_paper.gradientRotation())
|
||||
: BlackImage(size));
|
||||
_generated.setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ WallPaper WallPaper::withUrlParams(
|
|||
if (const auto string = params.value("intensity"); !string.isEmpty()) {
|
||||
auto ok = false;
|
||||
const auto intensity = string.toInt(&ok);
|
||||
if (ok && base::in_range(intensity, 0, 101)) {
|
||||
if (ok && base::in_range(intensity, -100, 101)) {
|
||||
result._intensity = intensity;
|
||||
}
|
||||
}
|
||||
|
@ -604,7 +604,7 @@ std::optional<WallPaper> WallPaper::FromSerialized(
|
|||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
return std::nullopt;
|
||||
} else if (intensity < 0 || intensity > 100) {
|
||||
} else if (intensity < -100 || intensity > 100) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto result = WallPaper(id);
|
||||
|
@ -710,18 +710,27 @@ QImage GenerateWallPaper(
|
|||
auto result = bg.empty()
|
||||
? Images::GenerateGradient(size, { DefaultBackgroundColor() })
|
||||
: Images::GenerateGradient(size, bg, gradientRotation);
|
||||
if (bg.size() > 1) {
|
||||
if (bg.size() > 1 && (!drawPattern || patternOpacity >= 0.)) {
|
||||
result = Images::DitherImage(std::move(result));
|
||||
}
|
||||
if (drawPattern) {
|
||||
auto p = QPainter(&result);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(patternOpacity);
|
||||
if (patternOpacity >= 0.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(patternOpacity);
|
||||
} else {
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
}
|
||||
drawPattern(p);
|
||||
p.end();
|
||||
if (patternOpacity < 0. && patternOpacity > -1.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
p.setOpacity(1. + patternOpacity);
|
||||
p.fillRect(QRect{ QPoint(), size }, Qt::black);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return std::move(result).convertToFormat(
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
|
||||
QImage PreparePatternImage(
|
||||
|
|
|
@ -553,7 +553,10 @@ void BackgroundRow::radialAnimationCallback(crl::time now) {
|
|||
void BackgroundRow::updateImage() {
|
||||
const auto size = st::settingsBackgroundThumb;
|
||||
const auto fullsize = size * cIntRetinaFactor();
|
||||
QImage back(fullsize, fullsize, QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
// We use Format_RGB32 so that DestinationIn shows black, not transparent.
|
||||
// Then we'll convert to Format_ARGB32_Premultiplied for round corners.
|
||||
auto back = QImage(fullsize, fullsize, QImage::Format_RGB32);
|
||||
back.setDevicePixelRatio(cRetinaFactor());
|
||||
{
|
||||
Painter p(&back);
|
||||
|
@ -568,8 +571,13 @@ void BackgroundRow::updateImage() {
|
|||
if (!gradient.isNull()) {
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.drawImage(QRect(0, 0, size, size), gradient);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(patternOpacity);
|
||||
if (patternOpacity >= 0.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(patternOpacity);
|
||||
} else {
|
||||
p.setCompositionMode(
|
||||
QPainter::CompositionMode_DestinationIn);
|
||||
}
|
||||
}
|
||||
const auto &prepared = background->prepared();
|
||||
if (!prepared.isNull()) {
|
||||
|
@ -587,8 +595,18 @@ void BackgroundRow::updateImage() {
|
|||
prepared,
|
||||
QRect(sx, sy, s, s));
|
||||
}
|
||||
if (!gradient.isNull()
|
||||
&& !prepared.isNull()
|
||||
&& patternOpacity < 0.
|
||||
&& patternOpacity > -1.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
p.setOpacity(patternOpacity);
|
||||
p.fillRect(QRect(0, 0, size, size), Qt::black);
|
||||
}
|
||||
}
|
||||
}
|
||||
back = std::move(back).convertToFormat(
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
Images::prepareRound(back, ImageRoundRadius::Small);
|
||||
_background = Ui::PixmapFromImage(std::move(back));
|
||||
_background.setDevicePixelRatio(cRetinaFactor());
|
||||
|
|
|
@ -140,7 +140,7 @@ void SectionWidget::PaintBackground(
|
|||
};
|
||||
const auto hasNow = !state.now.pixmap.isNull();
|
||||
const auto goodNow = hasNow && (state.now.area == fill);
|
||||
const auto useCache = goodNow || (hasNow && !gradient.isNull());
|
||||
const auto useCache = goodNow || !gradient.isNull();
|
||||
if (useCache) {
|
||||
if (state.shown < 1. && !gradient.isNull()) {
|
||||
paintCache(state.was);
|
||||
|
@ -156,22 +156,11 @@ void SectionWidget::PaintBackground(
|
|||
const auto rects = Window::Theme::ComputeBackgroundRects(
|
||||
fill,
|
||||
prepared.size());
|
||||
if (!gradient.isNull()) {
|
||||
p.drawImage(rects.to, gradient);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(patternOpacity);
|
||||
}
|
||||
auto to = rects.to;
|
||||
to.moveTop(to.top() + fromy);
|
||||
p.drawImage(to, prepared, rects.from);
|
||||
return;
|
||||
}
|
||||
if (!gradient.isNull()) {
|
||||
const auto hq = PainterHighQualityEnabler(p);
|
||||
p.drawImage(QRect(QPoint(0, fromy), fill), gradient);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(patternOpacity);
|
||||
}
|
||||
if (!prepared.isNull()) {
|
||||
const auto &tiled = background->preparedForTiled();
|
||||
auto left = clip.left();
|
||||
|
|
|
@ -73,8 +73,9 @@ std::optional<QColor> CalculateImageMonoColor(const QImage &image) {
|
|||
}
|
||||
|
||||
[[nodiscard]] bool GoodImageFormatAndSize(const QImage &image) {
|
||||
return (image.format() == QImage::Format_ARGB32_Premultiplied)
|
||||
&& !image.size().isEmpty();
|
||||
return !image.size().isEmpty()
|
||||
&& (image.format() == QImage::Format_ARGB32_Premultiplied
|
||||
|| image.format() == QImage::Format_RGB32);
|
||||
}
|
||||
|
||||
QByteArray readThemeContent(const QString &path) {
|
||||
|
@ -901,9 +902,19 @@ QImage ChatBackground::createCurrentImage() const {
|
|||
result.setDevicePixelRatio(1.);
|
||||
{
|
||||
auto p = QPainter(&result);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(paper().patternOpacity());
|
||||
const auto patternOpacity = paper().patternOpacity();
|
||||
if (patternOpacity >= 0.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(patternOpacity);
|
||||
} else {
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
}
|
||||
p.drawImage(QRect(QPoint(), _prepared.size()), _prepared);
|
||||
if (patternOpacity < 0. && patternOpacity > -1.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
p.setOpacity(1. + patternOpacity);
|
||||
p.fillRect(QRect(QPoint(), _prepared.size()), Qt::black);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1439,7 +1450,8 @@ QString EditingPalettePath() {
|
|||
}
|
||||
|
||||
QColor CountAverageColor(const QImage &image) {
|
||||
Expects(image.format() == QImage::Format_ARGB32_Premultiplied);
|
||||
Expects(image.format() == QImage::Format_ARGB32_Premultiplied
|
||||
|| image.format() == QImage::Format_RGB32);
|
||||
|
||||
uint64 components[3] = { 0 };
|
||||
const auto w = image.width();
|
||||
|
|
|
@ -97,8 +97,13 @@ constexpr auto kBackgroundFadeDuration = crl::time(200);
|
|||
if (!request.prepared.isNull()) {
|
||||
QPainter p(&result);
|
||||
if (!gradient.isNull()) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(request.patternOpacity);
|
||||
if (request.patternOpacity >= 0.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(request.patternOpacity);
|
||||
} else {
|
||||
p.setCompositionMode(
|
||||
QPainter::CompositionMode_DestinationIn);
|
||||
}
|
||||
}
|
||||
const auto &tiled = request.preparedForTiled;
|
||||
const auto w = tiled.width() / cRetinaFactor();
|
||||
|
@ -112,9 +117,17 @@ constexpr auto kBackgroundFadeDuration = crl::time(200);
|
|||
p.drawImage(QPointF(i * w, j * h), tiled);
|
||||
}
|
||||
}
|
||||
if (!gradient.isNull()
|
||||
&& request.patternOpacity < 0.
|
||||
&& request.patternOpacity > -1.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
p.setOpacity(1. + request.patternOpacity);
|
||||
p.fillRect(QRect(QPoint(), request.area), Qt::black);
|
||||
}
|
||||
}
|
||||
return {
|
||||
.image = std::move(result),
|
||||
.image = std::move(result).convertToFormat(
|
||||
QImage::Format_ARGB32_Premultiplied),
|
||||
.gradient = gradient,
|
||||
.area = request.area,
|
||||
};
|
||||
|
@ -136,13 +149,23 @@ constexpr auto kBackgroundFadeDuration = crl::time(200);
|
|||
result.setDevicePixelRatio(cRetinaFactor());
|
||||
if (!gradient.isNull()) {
|
||||
QPainter p(&result);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(request.patternOpacity);
|
||||
if (request.patternOpacity >= 0.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||
p.setOpacity(request.patternOpacity);
|
||||
} else {
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
}
|
||||
p.drawImage(QRect(QPoint(), rects.to.size()), image);
|
||||
if (request.patternOpacity < 0. && request.patternOpacity > -1.) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
p.setOpacity(1. + request.patternOpacity);
|
||||
p.fillRect(QRect(QPoint(), rects.to.size()), Qt::black);
|
||||
}
|
||||
}
|
||||
image = QImage();
|
||||
return {
|
||||
.image = std::move(result),
|
||||
.image = std::move(result).convertToFormat(
|
||||
QImage::Format_ARGB32_Premultiplied),
|
||||
.gradient = gradient,
|
||||
.area = request.area,
|
||||
.x = rects.to.x(),
|
||||
|
@ -1424,7 +1447,13 @@ void SessionController::openDocument(
|
|||
|
||||
const BackgroundState &SessionController::backgroundState(QSize area) {
|
||||
_backgroundState.shown = _backgroundFade.value(1.);
|
||||
if (_backgroundState.now.area != area) {
|
||||
if (_backgroundState.now.pixmap.isNull()
|
||||
&& !Window::Theme::Background()->gradientForFill().isNull()) {
|
||||
// We don't support direct painting of patterned gradients.
|
||||
// So we need to sync-generate cache image here.
|
||||
setCachedBackground(CacheBackground(currentCacheRequest(area)));
|
||||
_cacheBackgroundTimer.cancel();
|
||||
} else if (_backgroundState.now.area != area) {
|
||||
if (_willCacheForArea != area
|
||||
|| (!_cacheBackgroundTimer.isActive()
|
||||
&& !_backgroundCachingRequest)) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 669767855a197976183684d25b2753899ee95e5c
|
||||
Subproject commit 6b320a99da1d1a4430c8168998f62e1e5ec919ab
|
Loading…
Add table
Reference in a new issue