Skip to content

Commit

Permalink
Add Images::EllipseMask method to the interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-preston committed Oct 3, 2022
1 parent cec09b0 commit 2c2a788
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 18 deletions.
5 changes: 1 addition & 4 deletions ui/effects/spoiler_mess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,7 @@ void FillSpoilerRect(
const SpoilerMessFrame &frame,
QImage &cornerCache,
QPoint originShift) {
constexpr auto kTopLeft = 0;
constexpr auto kTopRight = 1;
constexpr auto kBottomLeft = 2;
constexpr auto kBottomRight = 3;
using namespace Images;

if ((!mask.p[kTopLeft] || mask.p[kTopLeft]->isNull())
&& (!mask.p[kTopRight] || mask.p[kTopRight]->isNull())
Expand Down
36 changes: 22 additions & 14 deletions ui/image/image_prepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ TG_FORCE_INLINE uint64 BlurGetColors(const uchar *p) {
+ ((uint64)p[3] << 48);
}

const QImage &CircleMask(QSize size) {
const QImage &EllipseMaskCached(QSize size) {
const auto key = (uint64(uint32(size.width())) << 32)
| uint64(uint32(size.height()));

Expand All @@ -64,17 +64,7 @@ const QImage &CircleMask(QSize size) {
}
lock.unlock();

auto mask = QImage(
size,
QImage::Format_ARGB32_Premultiplied);
mask.fill(Qt::transparent);
{
QPainter p(&mask);
PainterHighQualityEnabler hq(p);
p.setBrush(Qt::white);
p.setPen(Qt::NoPen);
p.drawEllipse(QRect(QPoint(), size));
}
auto mask = EllipseMask(size);

lock.relock();
return Masks.emplace(key, std::move(mask)).first->second;
Expand Down Expand Up @@ -345,6 +335,24 @@ std::array<QImage, 4> CornersMask(int radius) {
return PrepareCornersMask(radius);
}

QImage EllipseMask(QSize size) {
const auto ratio = style::DevicePixelRatio();

size *= ratio;
auto result = QImage(size, QImage::Format_ARGB32_Premultiplied);
result.fill(Qt::transparent);

QPainter p(&result);
PainterHighQualityEnabler hq(p);
p.setBrush(Qt::white);
p.setPen(Qt::NoPen);
p.drawEllipse(QRect(QPoint(), size));
p.end();

result.setDevicePixelRatio(ratio);
return result;
}

std::array<QImage, 4> PrepareCorners(
int radius,
const style::color &color) {
Expand Down Expand Up @@ -987,7 +995,7 @@ QImage Circle(QImage &&image, QRect target) {
Expects(!image.isNull());

if (target.isNull()) {
target = QRect(QPoint(), image.size());
target = QRect(QPoint( ), image.size());
} else {
Assert(QRect(QPoint(), image.size()).contains(target));
}
Expand All @@ -1001,7 +1009,7 @@ QImage Circle(QImage &&image, QRect target) {
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.drawImage(
QRectF(target.topLeft() / ratio, target.size() / ratio),
CircleMask(target.size()));
EllipseMaskCached(target.size()));
p.end();

return std::move(image);
Expand Down
27 changes: 27 additions & 0 deletions ui/image/image_prepare.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ namespace Images {
int bottomAlpha,
QColor color = QColor(0, 0, 0));

inline constexpr auto kTopLeft = 0;
inline constexpr auto kTopRight = 1;
inline constexpr auto kBottomLeft = 2;
inline constexpr auto kBottomRight = 3;

struct CornersMaskRef {
CornersMaskRef() = default;
explicit CornersMaskRef(gsl::span<const QImage, 4> masks)
Expand All @@ -61,7 +66,27 @@ struct CornersMaskRef {
: p{ masks[0], masks[1], masks[2], masks[3] } {
}

[[nodiscard]] bool empty() const {
return !p[0] && !p[1] && !p[2] && !p[3];
}

std::array<const QImage*, 4> p{};

friend inline constexpr std::strong_ordering operator<=>(
CornersMaskRef a,
CornersMaskRef b) noexcept {
for (auto i = 0; i != 4; ++i) {
if (a.p[i] < b.p[i]) {
return std::strong_ordering::less;
} else if (a.p[i] > b.p[i]) {
return std::strong_ordering::greater;
}
}
return std::strong_ordering::equal;
}
friend inline constexpr bool operator==(
CornersMaskRef a,
CornersMaskRef b) noexcept = default;
};

[[nodiscard]] const std::array<QImage, 4> &CornersMask(
Expand All @@ -71,6 +96,8 @@ struct CornersMaskRef {
const style::color &color);

[[nodiscard]] std::array<QImage, 4> CornersMask(int radius);
[[nodiscard]] QImage EllipseMask(QSize size);

[[nodiscard]] std::array<QImage, 4> PrepareCorners(
int radius,
const style::color &color);
Expand Down

0 comments on commit 2c2a788

Please sign in to comment.