Allow requesting exact icon instances, ignoring dpr.

This commit is contained in:
John Preston 2024-01-03 22:11:57 +04:00
parent 99e36f9ac6
commit 7fef09421c
2 changed files with 46 additions and 21 deletions

View file

@ -29,16 +29,18 @@ base::flat_set<IconData*> iconData;
[[nodiscard]] QImage CreateIconMask( [[nodiscard]] QImage CreateIconMask(
not_null<const IconMask*> mask, not_null<const IconMask*> mask,
int scale) { int scale,
bool ignoreDpr = false) {
const auto ratio = ignoreDpr ? 1 : DevicePixelRatio();
auto maskImage = QImage::fromData(mask->data(), mask->size(), "PNG"); auto maskImage = QImage::fromData(mask->data(), mask->size(), "PNG");
maskImage.setDevicePixelRatio(DevicePixelRatio()); maskImage.setDevicePixelRatio(ratio);
Assert(!maskImage.isNull()); Assert(!maskImage.isNull());
// images are layouted like this: // images are laid out like this:
// 100x 200x // 100x 200x
// 300x // 300x
const auto factor = DevicePixelRatio(); const auto realscale = scale * ratio;
const auto realscale = scale * factor;
const auto width = maskImage.width() / 3; const auto width = maskImage.width() / 3;
const auto height = maskImage.height() / 5; const auto height = maskImage.height() / 5;
const auto one = QRect(0, 0, width, height); const auto one = QRect(0, 0, width, height);
@ -54,8 +56,8 @@ base::flat_set<IconData*> iconData;
return maskImage.copy( return maskImage.copy(
(realscale > 200) ? three : two (realscale > 200) ? three : two
).scaled( ).scaled(
ConvertScale(width, scale) * factor, ConvertScale(width, scale) * ratio,
ConvertScale(height, scale) * factor, ConvertScale(height, scale) * ratio,
Qt::IgnoreAspectRatio, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation); Qt::SmoothTransformation);
} }
@ -71,7 +73,10 @@ base::flat_set<IconData*> iconData;
).first->second; ).first->second;
} }
QSize readGeneratedSize(const IconMask *mask, int scale) { [[nodiscard]] QSize readGeneratedSize(
const IconMask *mask,
int scale,
bool ignoreDpr = false) {
auto data = mask->data(); auto data = mask->data();
auto size = mask->size(); auto size = mask->size();
@ -239,10 +244,15 @@ void MonoIcon::fill(
} }
} }
QImage MonoIcon::instance(QColor colorOverride, int scale) const { QImage MonoIcon::instance(
QColor colorOverride,
int scale,
bool ignoreDpr) const {
if (scale == kScaleAuto) { if (scale == kScaleAuto) {
ensureLoaded(); ensureLoaded();
auto result = QImage(size() * DevicePixelRatio(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(
size() * DevicePixelRatio(),
QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(DevicePixelRatio()); result.setDevicePixelRatio(DevicePixelRatio());
if (_pixmap.isNull()) { if (_pixmap.isNull()) {
result.fill(colorOverride); result.fill(colorOverride);
@ -251,16 +261,19 @@ QImage MonoIcon::instance(QColor colorOverride, int scale) const {
} }
return result; return result;
} }
auto size = readGeneratedSize(_mask, scale); const auto ratio = ignoreDpr ? 1 : DevicePixelRatio();
auto size = readGeneratedSize(_mask, scale, ignoreDpr);
if (!size.isEmpty()) { if (!size.isEmpty()) {
auto result = QImage(size * DevicePixelRatio(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(
result.setDevicePixelRatio(DevicePixelRatio()); size * ratio,
QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(ratio);
result.fill(colorOverride); result.fill(colorOverride);
return result; return result;
} }
auto mask = CreateIconMask(_mask, scale); auto mask = CreateIconMask(_mask, scale, ignoreDpr);
auto result = QImage(mask.size(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(mask.size(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(DevicePixelRatio()); result.setDevicePixelRatio(ratio);
colorizeImage(mask, colorOverride, &result); colorizeImage(mask, colorOverride, &result);
return result; return result;
} }
@ -340,12 +353,15 @@ void IconData::fill(QPainter &p, const QRect &rect, QColor colorOverride) const
} }
} }
QImage IconData::instance(QColor colorOverride, int scale) const { QImage IconData::instance(
QColor colorOverride,
int scale,
bool ignoreDpr) const {
Expects(_parts.size() == 1); Expects(_parts.size() == 1);
auto &part = _parts[0]; auto &part = _parts[0];
Assert(part.offset() == QPoint(0, 0)); Assert(part.offset() == QPoint(0, 0));
return part.instance(colorOverride, scale); return part.instance(colorOverride, scale, ignoreDpr);
} }
int IconData::width() const { int IconData::width() const {

View file

@ -62,7 +62,10 @@ public:
void paint(QPainter &p, const QPoint &pos, int outerw, const style::palette &paletteOverride) const; void paint(QPainter &p, const QPoint &pos, int outerw, const style::palette &paletteOverride) const;
void fill(QPainter &p, const QRect &rect, const style::palette &paletteOverride) const; void fill(QPainter &p, const QRect &rect, const style::palette &paletteOverride) const;
QImage instance(QColor colorOverride, int scale) const; [[nodiscard]] QImage instance(
QColor colorOverride,
int scale,
bool ignoreDpr) const;
~MonoIcon() { ~MonoIcon() {
} }
@ -123,7 +126,10 @@ public:
} }
void fill(QPainter &p, const QRect &rect, const style::palette &paletteOverride) const; void fill(QPainter &p, const QRect &rect, const style::palette &paletteOverride) const;
QImage instance(QColor colorOverride, int scale) const; [[nodiscard]] QImage instance(
QColor colorOverride,
int scale,
bool ignoreDpr) const;
int width() const; int width() const;
int height() const; int height() const;
@ -218,8 +224,11 @@ public:
return _data->fill(p, rect, colorOverride); return _data->fill(p, rect, colorOverride);
} }
QImage instance(QColor colorOverride, int scale = kScaleAuto) const { [[nodiscard]] QImage instance(
return _data->instance(colorOverride, scale); QColor colorOverride,
int scale = kScaleAuto,
bool ignoreDpr = false) const {
return _data->instance(colorOverride, scale, ignoreDpr);
} }
class Proxy { class Proxy {