Add Images::EllipseMask method to the interface.
This commit is contained in:
parent
cec09b0260
commit
2c2a7887e6
3 changed files with 50 additions and 18 deletions
|
|
@ -505,10 +505,7 @@ void FillSpoilerRect(
|
||||||
const SpoilerMessFrame &frame,
|
const SpoilerMessFrame &frame,
|
||||||
QImage &cornerCache,
|
QImage &cornerCache,
|
||||||
QPoint originShift) {
|
QPoint originShift) {
|
||||||
constexpr auto kTopLeft = 0;
|
using namespace Images;
|
||||||
constexpr auto kTopRight = 1;
|
|
||||||
constexpr auto kBottomLeft = 2;
|
|
||||||
constexpr auto kBottomRight = 3;
|
|
||||||
|
|
||||||
if ((!mask.p[kTopLeft] || mask.p[kTopLeft]->isNull())
|
if ((!mask.p[kTopLeft] || mask.p[kTopLeft]->isNull())
|
||||||
&& (!mask.p[kTopRight] || mask.p[kTopRight]->isNull())
|
&& (!mask.p[kTopRight] || mask.p[kTopRight]->isNull())
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ TG_FORCE_INLINE uint64 BlurGetColors(const uchar *p) {
|
||||||
+ ((uint64)p[3] << 48);
|
+ ((uint64)p[3] << 48);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QImage &CircleMask(QSize size) {
|
const QImage &EllipseMaskCached(QSize size) {
|
||||||
const auto key = (uint64(uint32(size.width())) << 32)
|
const auto key = (uint64(uint32(size.width())) << 32)
|
||||||
| uint64(uint32(size.height()));
|
| uint64(uint32(size.height()));
|
||||||
|
|
||||||
|
|
@ -64,17 +64,7 @@ const QImage &CircleMask(QSize size) {
|
||||||
}
|
}
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
auto mask = QImage(
|
auto mask = EllipseMask(size);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
lock.relock();
|
lock.relock();
|
||||||
return Masks.emplace(key, std::move(mask)).first->second;
|
return Masks.emplace(key, std::move(mask)).first->second;
|
||||||
|
|
@ -345,6 +335,24 @@ std::array<QImage, 4> CornersMask(int radius) {
|
||||||
return PrepareCornersMask(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(
|
std::array<QImage, 4> PrepareCorners(
|
||||||
int radius,
|
int radius,
|
||||||
const style::color &color) {
|
const style::color &color) {
|
||||||
|
|
@ -1001,7 +1009,7 @@ QImage Circle(QImage &&image, QRect target) {
|
||||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||||
p.drawImage(
|
p.drawImage(
|
||||||
QRectF(target.topLeft() / ratio, target.size() / ratio),
|
QRectF(target.topLeft() / ratio, target.size() / ratio),
|
||||||
CircleMask(target.size()));
|
EllipseMaskCached(target.size()));
|
||||||
p.end();
|
p.end();
|
||||||
|
|
||||||
return std::move(image);
|
return std::move(image);
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,11 @@ namespace Images {
|
||||||
int bottomAlpha,
|
int bottomAlpha,
|
||||||
QColor color = QColor(0, 0, 0));
|
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 {
|
struct CornersMaskRef {
|
||||||
CornersMaskRef() = default;
|
CornersMaskRef() = default;
|
||||||
explicit CornersMaskRef(gsl::span<const QImage, 4> masks)
|
explicit CornersMaskRef(gsl::span<const QImage, 4> masks)
|
||||||
|
|
@ -61,7 +66,27 @@ struct CornersMaskRef {
|
||||||
: p{ masks[0], masks[1], masks[2], masks[3] } {
|
: 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{};
|
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(
|
[[nodiscard]] const std::array<QImage, 4> &CornersMask(
|
||||||
|
|
@ -71,6 +96,8 @@ struct CornersMaskRef {
|
||||||
const style::color &color);
|
const style::color &color);
|
||||||
|
|
||||||
[[nodiscard]] std::array<QImage, 4> CornersMask(int radius);
|
[[nodiscard]] std::array<QImage, 4> CornersMask(int radius);
|
||||||
|
[[nodiscard]] QImage EllipseMask(QSize size);
|
||||||
|
|
||||||
[[nodiscard]] std::array<QImage, 4> PrepareCorners(
|
[[nodiscard]] std::array<QImage, 4> PrepareCorners(
|
||||||
int radius,
|
int radius,
|
||||||
const style::color &color);
|
const style::color &color);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue