mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Support new rounding for GIFs / videos.
This commit is contained in:
parent
b2302d35fe
commit
8268e9f872
17 changed files with 170 additions and 193 deletions
|
@ -626,19 +626,24 @@ struct VideoPreviewDocument {
|
|||
};
|
||||
|
||||
check();
|
||||
const auto corners = alignToBottom
|
||||
? (RectPart::TopLeft | RectPart::TopRight)
|
||||
: (RectPart::BottomLeft | RectPart::BottomRight);
|
||||
const auto ready = state->instance.player().ready()
|
||||
&& !state->instance.player().videoSize().isEmpty();
|
||||
const auto size = QSize(width, height) * style::DevicePixelRatio();
|
||||
|
||||
using namespace Images;
|
||||
auto rounding = CornersMaskRef(
|
||||
Images::CornersMask(ImageRoundRadius::Large));
|
||||
if (alignToBottom) {
|
||||
rounding.p[kBottomLeft] = rounding.p[kBottomRight] = nullptr;
|
||||
} else {
|
||||
rounding.p[kTopLeft] = rounding.p[kTopRight] = nullptr;
|
||||
}
|
||||
const auto frame = !ready
|
||||
? state->blurred
|
||||
: state->instance.frame({
|
||||
.resize = size,
|
||||
.outer = size,
|
||||
.radius = ImageRoundRadius::Large,
|
||||
.corners = corners,
|
||||
.rounding = rounding,
|
||||
});
|
||||
paintFrame(QColor(0, 0, 0, 128), 12.);
|
||||
p.drawImage(QRect(left, top, width, height), frame);
|
||||
|
|
|
@ -274,6 +274,32 @@ QSize Gif::videoSize() const {
|
|||
}
|
||||
}
|
||||
|
||||
void Gif::validateRoundingMask(QSize size) const {
|
||||
if (_roundingMask.size() != size) {
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
_roundingMask = Images::EllipseMask(size / ratio);
|
||||
}
|
||||
}
|
||||
|
||||
Images::CornersMaskRef Gif::prepareRoundingRef(
|
||||
std::optional<Ui::BubbleRounding> rounding) const {
|
||||
using namespace Ui;
|
||||
using namespace Images;
|
||||
if (!rounding) {
|
||||
return CornersMaskRef(CachedCornersMasks(CachedCornerRadius::Small));
|
||||
}
|
||||
auto result = CornersMaskRef();
|
||||
for (auto i = 0; i != 4; ++i) {
|
||||
const auto corner = (*rounding)[i];
|
||||
result.p[i] = (corner == BubbleCornerRounding::Large)
|
||||
? &CachedCornersMasks(CachedCornerRadius::BubbleLarge)[i]
|
||||
: (corner == BubbleCornerRounding::Small)
|
||||
? &CachedCornersMasks(CachedCornerRadius::BubbleSmall)[i]
|
||||
: nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Gif::downloadInCorner() const {
|
||||
return _data->isVideoFile()
|
||||
&& (_data->loading() || !autoplayEnabled())
|
||||
|
@ -349,6 +375,9 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
const auto radial = isRadialAnimation()
|
||||
|| (streamedForWaiting && streamedForWaiting->waitingShown());
|
||||
|
||||
const auto rounding = inWebPage
|
||||
? std::optional<Ui::BubbleRounding>()
|
||||
: adjustedBubbleRoundingWithCaption(_caption);
|
||||
if (bubble) {
|
||||
if (!_caption.isEmpty()) {
|
||||
painth -= st::mediaCaptionSkip + _caption.countHeight(captionw);
|
||||
|
@ -356,9 +385,6 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
painth -= st::msgPadding.bottom();
|
||||
}
|
||||
}
|
||||
} else if (!unwrapped) {
|
||||
// #TODO rounding
|
||||
Ui::FillRoundShadow(p, 0, 0, paintw, height(), sti->msgShadow, sti->msgShadowCornersSmall);
|
||||
}
|
||||
|
||||
auto usex = 0, usew = paintw;
|
||||
|
@ -381,42 +407,30 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
|
||||
QRect rthumb(style::rtlrect(usex + paintx, painty, usew, painth, width()));
|
||||
|
||||
const auto roundRadius = isRound
|
||||
? ImageRoundRadius::Ellipse
|
||||
: unwrapped
|
||||
? ImageRoundRadius::None
|
||||
: inWebPage
|
||||
? ImageRoundRadius::Small
|
||||
: ImageRoundRadius::Large;
|
||||
const auto roundCorners = isRound
|
||||
? RectPart::AllCorners
|
||||
: unwrapped
|
||||
? RectPart::None
|
||||
: inWebPage
|
||||
? RectPart::AllCorners
|
||||
: ((isBubbleTop()
|
||||
? (RectPart::TopLeft | RectPart::TopRight)
|
||||
: RectPart::None)
|
||||
| ((isRoundedInBubbleBottom() && _caption.isEmpty())
|
||||
? (RectPart::BottomLeft | RectPart::BottomRight)
|
||||
: RectPart::None));
|
||||
if (!bubble && !unwrapped) {
|
||||
Assert(rounding.has_value());
|
||||
fillImageShadow(p, rthumb, *rounding, context);
|
||||
}
|
||||
|
||||
const auto skipDrawingContent = context.skipDrawingParts
|
||||
== PaintContext::SkipDrawingParts::Content;
|
||||
if (streamed && !skipDrawingContent) {
|
||||
auto paused = context.paused;
|
||||
auto request = ::Media::Streaming::FrameRequest{
|
||||
.outer = QSize(usew, painth) * cIntRetinaFactor(),
|
||||
.blurredBackground = true,
|
||||
};
|
||||
if (isRound) {
|
||||
if (activeRoundStreamed()) {
|
||||
paused = false;
|
||||
} else {
|
||||
displayMute = true;
|
||||
}
|
||||
validateRoundingMask(request.outer);
|
||||
request.mask = _roundingMask;
|
||||
} else {
|
||||
request.rounding = prepareRoundingRef(rounding);
|
||||
}
|
||||
auto request = ::Media::Streaming::FrameRequest{
|
||||
.outer = QSize(usew, painth) * cIntRetinaFactor(),
|
||||
.radius = roundRadius,
|
||||
.corners = roundCorners,
|
||||
.blurredBackground = true,
|
||||
};
|
||||
if (!activeRoundPlaying && activeOwnPlaying->instance.playerLocked()) {
|
||||
if (activeOwnPlaying->frozenFrame.isNull()) {
|
||||
activeOwnPlaying->frozenRequest = request;
|
||||
|
@ -465,12 +479,16 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
}
|
||||
} else if (!skipDrawingContent) {
|
||||
ensureDataMediaCreated();
|
||||
validateThumbCache({ usew, painth }, roundRadius, roundCorners);
|
||||
validateThumbCache({ usew, painth }, isRound, rounding);
|
||||
p.drawImage(rthumb, _thumbCache);
|
||||
}
|
||||
|
||||
if (context.selected()) {
|
||||
Ui::FillComplexOverlayRect(p, st, rthumb, roundRadius, roundCorners);
|
||||
if (isRound) {
|
||||
Ui::FillComplexEllipse(p, st, rthumb);
|
||||
} else {
|
||||
fillImageOverlay(p, rthumb, rounding, context);
|
||||
}
|
||||
}
|
||||
|
||||
if (radial
|
||||
|
@ -691,10 +709,8 @@ void Gif::validateVideoThumbnail() const {
|
|||
|
||||
void Gif::validateThumbCache(
|
||||
QSize outer,
|
||||
ImageRoundRadius radius,
|
||||
RectParts corners) const {
|
||||
const auto intRadius = static_cast<int>(radius);
|
||||
const auto intCorners = static_cast<int>(corners);
|
||||
bool isEllipse,
|
||||
std::optional<Ui::BubbleRounding> rounding) const {
|
||||
const auto good = _dataMedia->goodThumbnail();
|
||||
const auto normal = good ? good : _dataMedia->thumbnail();
|
||||
if (!normal) {
|
||||
|
@ -708,24 +724,18 @@ void Gif::validateThumbCache(
|
|||
&& (normal->height() < kUseNonBlurredThreshold))
|
||||
: !videothumb;
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto shouldBeBlurred = blurred ? 1 : 0;
|
||||
if (_thumbCache.size() == (outer * ratio)
|
||||
&& _thumbCacheRoundRadius == intRadius
|
||||
&& _thumbCacheRoundCorners == intCorners
|
||||
&& _thumbCacheBlurred == shouldBeBlurred) {
|
||||
&& _thumbCacheRounding == rounding
|
||||
&& _thumbCacheBlurred == blurred
|
||||
&& _thumbIsEllipse == isEllipse) {
|
||||
return;
|
||||
}
|
||||
_thumbCache = prepareThumbCache(outer, radius, corners);
|
||||
_thumbCacheRoundRadius = intRadius;
|
||||
_thumbCacheRoundCorners = intCorners;
|
||||
_thumbCacheBlurred = shouldBeBlurred;
|
||||
}
|
||||
|
||||
QImage Gif::prepareThumbCache(
|
||||
QSize outer,
|
||||
ImageRoundRadius radius,
|
||||
RectParts corners) const {
|
||||
return Images::Round(prepareThumbCache(outer), radius, corners);
|
||||
auto cache = prepareThumbCache(outer);
|
||||
_thumbCache = isEllipse
|
||||
? Images::Circle(std::move(cache))
|
||||
: Images::Round(std::move(cache), MediaRoundingMask(rounding));
|
||||
_thumbCacheRounding = rounding;
|
||||
_thumbCacheBlurred = blurred;
|
||||
}
|
||||
|
||||
QImage Gif::prepareThumbCache(QSize outer) const {
|
||||
|
@ -1071,8 +1081,8 @@ void Gif::drawGrouped(
|
|||
auto request = ::Media::Streaming::FrameRequest{
|
||||
.resize = pixSize * cIntRetinaFactor(),
|
||||
.outer = geometry.size() * cIntRetinaFactor(),
|
||||
.radius = roundRadius,
|
||||
.corners = corners,
|
||||
//.radius = roundRadius, // #TODO rounding
|
||||
//.corners = corners,
|
||||
};
|
||||
if (activeOwnPlaying->instance.playerLocked()) {
|
||||
if (activeOwnPlaying->frozenFrame.isNull()) {
|
||||
|
@ -1104,10 +1114,11 @@ void Gif::drawGrouped(
|
|||
: highlightOpacity;
|
||||
if (overlayOpacity > 0.) {
|
||||
p.setOpacity(overlayOpacity);
|
||||
Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
if (!context.selected()) {
|
||||
Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
}
|
||||
// #TODO rounding
|
||||
//Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
//if (!context.selected()) {
|
||||
// Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
//}
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
|
|
|
@ -163,12 +163,8 @@ private:
|
|||
|
||||
void validateThumbCache(
|
||||
QSize outer,
|
||||
ImageRoundRadius radius,
|
||||
RectParts corners) const;
|
||||
[[nodiscard]] QImage prepareThumbCache(
|
||||
QSize outer,
|
||||
ImageRoundRadius radius,
|
||||
RectParts corners) const;
|
||||
bool isEllipse,
|
||||
std::optional<Ui::BubbleRounding> rounding) const;
|
||||
[[nodiscard]] QImage prepareThumbCache(QSize outer) const;
|
||||
|
||||
void validateGroupedCache(
|
||||
|
@ -180,6 +176,10 @@ private:
|
|||
void updateStatusText() const;
|
||||
[[nodiscard]] QSize sizeForAspectRatio() const;
|
||||
|
||||
void validateRoundingMask(QSize size) const;
|
||||
[[nodiscard]] Images::CornersMaskRef prepareRoundingRef(
|
||||
std::optional<Ui::BubbleRounding> rounding) const;
|
||||
|
||||
[[nodiscard]] bool downloadInCorner() const;
|
||||
void drawCornerStatus(
|
||||
Painter &p,
|
||||
|
@ -197,9 +197,10 @@ private:
|
|||
mutable std::unique_ptr<Image> _videoThumbnailFrame;
|
||||
QString _downloadSize;
|
||||
mutable QImage _thumbCache;
|
||||
mutable int _thumbCacheRoundRadius : 4 = 0;
|
||||
mutable int _thumbCacheRoundCorners : 12 = 0;
|
||||
mutable int _thumbCacheBlurred : 1 = 0;
|
||||
mutable QImage _roundingMask;
|
||||
mutable std::optional<Ui::BubbleRounding> _thumbCacheRounding;
|
||||
mutable bool _thumbCacheBlurred = false;
|
||||
mutable bool _thumbIsEllipse = false;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ struct ColorReplacements;
|
|||
namespace Ui {
|
||||
struct BubbleSelectionInterval;
|
||||
struct ChatPaintContext;
|
||||
struct CornersMaskRef;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Images {
|
||||
|
|
|
@ -44,6 +44,7 @@ using Data::PhotoSize;
|
|||
struct Photo::Streamed {
|
||||
explicit Streamed(std::shared_ptr<::Media::Streaming::Document> shared);
|
||||
::Media::Streaming::Instance instance;
|
||||
QImage roundingMask;
|
||||
QImage frozenFrame;
|
||||
};
|
||||
|
||||
|
@ -410,7 +411,10 @@ void Photo::paintUserpicFrame(
|
|||
auto request = ::Media::Streaming::FrameRequest();
|
||||
request.outer = size * cIntRetinaFactor();
|
||||
request.resize = size * cIntRetinaFactor();
|
||||
request.radius = ImageRoundRadius::Ellipse;
|
||||
if (_streamed->roundingMask.size() != request.outer) {
|
||||
_streamed->roundingMask = Images::EllipseMask(size);
|
||||
}
|
||||
request.mask = _streamed->roundingMask;
|
||||
if (_streamed->instance.playerLocked()) {
|
||||
if (_streamed->frozenFrame.isNull()) {
|
||||
_streamed->frozenFrame = _streamed->instance.frame(request);
|
||||
|
@ -569,10 +573,11 @@ void Photo::drawGrouped(
|
|||
if (overlayOpacity > 0.) {
|
||||
p.setOpacity(overlayOpacity);
|
||||
const auto roundRadius = ImageRoundRadius::Large;
|
||||
Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
if (!context.selected()) {
|
||||
Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
}
|
||||
// #TODO rounding
|
||||
//Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
//if (!context.selected()) {
|
||||
// Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
//}
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
|
|
|
@ -244,7 +244,10 @@ bool Float::fillFrame() {
|
|||
if (const auto streamed = getStreamed()) {
|
||||
auto request = Streaming::FrameRequest::NonStrict();
|
||||
request.outer = request.resize = _frame.size();
|
||||
request.radius = ImageRoundRadius::Ellipse;
|
||||
if (_roundingMask.size() != request.outer) {
|
||||
_roundingMask = Images::EllipseMask(frameInner().size());
|
||||
}
|
||||
request.mask = _roundingMask;
|
||||
auto frame = streamed->frame(request);
|
||||
if (!frame.isNull()) {
|
||||
_frame.fill(Qt::transparent);
|
||||
|
|
|
@ -96,6 +96,7 @@ private:
|
|||
float64 _opacity = 1.;
|
||||
|
||||
QPixmap _shadow;
|
||||
QImage _roundingMask;
|
||||
QImage _frame;
|
||||
bool _down = false;
|
||||
QPoint _downPoint;
|
||||
|
|
|
@ -8,10 +8,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "data/data_audio_msg_id.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/rect_part.h"
|
||||
|
||||
enum class ImageRoundRadius;
|
||||
|
||||
namespace Media {
|
||||
|
||||
inline constexpr auto kTimeUnknown = std::numeric_limits<crl::time>::min();
|
||||
|
@ -120,8 +119,8 @@ enum class Error {
|
|||
struct FrameRequest {
|
||||
QSize resize;
|
||||
QSize outer;
|
||||
ImageRoundRadius radius = ImageRoundRadius();
|
||||
RectParts corners = RectPart::AllCorners;
|
||||
Images::CornersMaskRef rounding;
|
||||
QImage mask;
|
||||
QColor colored = QColor(0, 0, 0, 0);
|
||||
bool blurredBackground = false;
|
||||
bool requireARGB32 = true;
|
||||
|
@ -141,8 +140,8 @@ struct FrameRequest {
|
|||
[[nodiscard]] bool operator==(const FrameRequest &other) const {
|
||||
return (resize == other.resize)
|
||||
&& (outer == other.outer)
|
||||
&& (radius == other.radius)
|
||||
&& (corners == other.corners)
|
||||
&& (rounding == other.rounding)
|
||||
&& (mask.constBits() == other.mask.constBits())
|
||||
&& (colored == other.colored)
|
||||
&& (keepAlpha == other.keepAlpha)
|
||||
&& (requireARGB32 == other.requireARGB32)
|
||||
|
|
|
@ -101,8 +101,7 @@ bool GoodForRequest(
|
|||
return true;
|
||||
} else if (rotation != 0) {
|
||||
return false;
|
||||
} else if ((request.radius != ImageRoundRadius::None)
|
||||
&& ((request.corners & RectPart::AllCorners) != 0)) {
|
||||
} else if (!request.rounding.empty() || !request.mask.isNull()) {
|
||||
return false;
|
||||
}
|
||||
const auto size = request.blurredBackground
|
||||
|
@ -348,14 +347,15 @@ void PaintFrameContent(
|
|||
}
|
||||
|
||||
void ApplyFrameRounding(QImage &storage, const FrameRequest &request) {
|
||||
if (!(request.corners & RectPart::AllCorners)
|
||||
|| (request.radius == ImageRoundRadius::None)) {
|
||||
return;
|
||||
if (!request.mask.isNull()) {
|
||||
auto p = QPainter(&storage);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
p.drawImage(
|
||||
QRect(QPoint(), storage.size() / storage.devicePixelRatio()),
|
||||
request.mask);
|
||||
} else if (!request.rounding.empty()) {
|
||||
storage = Images::Round(std::move(storage), request.rounding);
|
||||
}
|
||||
storage = Images::Round(
|
||||
std::move(storage),
|
||||
request.radius,
|
||||
request.corners);
|
||||
}
|
||||
|
||||
ExpandDecision DecideFrameResize(
|
||||
|
|
|
@ -21,45 +21,43 @@ namespace {
|
|||
if (!rotation) {
|
||||
return request;
|
||||
}
|
||||
const auto unrotatedCorner = [&](RectPart corner) {
|
||||
if (!(request.corners & corner)) {
|
||||
return RectPart(0);
|
||||
}
|
||||
switch (corner) {
|
||||
case RectPart::TopLeft:
|
||||
const auto unrotatedCorner = [&](int index) {
|
||||
using namespace Images;
|
||||
switch (index) {
|
||||
case kTopLeft:
|
||||
return (rotation == 90)
|
||||
? RectPart::BottomLeft
|
||||
? kBottomLeft
|
||||
: (rotation == 180)
|
||||
? RectPart::BottomRight
|
||||
: RectPart::TopRight;
|
||||
case RectPart::TopRight:
|
||||
? kBottomRight
|
||||
: kTopRight;
|
||||
case kTopRight:
|
||||
return (rotation == 90)
|
||||
? RectPart::TopLeft
|
||||
? kTopLeft
|
||||
: (rotation == 180)
|
||||
? RectPart::BottomLeft
|
||||
: RectPart::BottomRight;
|
||||
case RectPart::BottomRight:
|
||||
? kBottomLeft
|
||||
: kBottomRight;
|
||||
case kBottomRight:
|
||||
return (rotation == 90)
|
||||
? RectPart::TopRight
|
||||
? kTopRight
|
||||
: (rotation == 180)
|
||||
? RectPart::TopLeft
|
||||
: RectPart::BottomLeft;
|
||||
case RectPart::BottomLeft:
|
||||
? kTopLeft
|
||||
: kBottomLeft;
|
||||
case kBottomLeft:
|
||||
return (rotation == 90)
|
||||
? RectPart::BottomRight
|
||||
? kBottomRight
|
||||
: (rotation == 180)
|
||||
? RectPart::TopRight
|
||||
: RectPart::TopLeft;
|
||||
? kTopRight
|
||||
: kTopLeft;
|
||||
}
|
||||
Unexpected("Corner in rotateCorner.");
|
||||
};
|
||||
auto result = request;
|
||||
result.outer = FlipSizeByRotation(request.outer, rotation);
|
||||
result.resize = FlipSizeByRotation(request.resize, rotation);
|
||||
result.corners = unrotatedCorner(RectPart::TopLeft)
|
||||
| unrotatedCorner(RectPart::TopRight)
|
||||
| unrotatedCorner(RectPart::BottomRight)
|
||||
| unrotatedCorner(RectPart::BottomLeft);
|
||||
auto rounding = result.rounding;
|
||||
for (auto i = 0; i != 4; ++i) {
|
||||
result.rounding.p[unrotatedCorner(i)] = rounding.p[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -137,23 +135,23 @@ void Pip::RendererSW::paintButton(
|
|||
|
||||
Pip::FrameRequest Pip::RendererSW::frameRequest(
|
||||
ContentGeometry geometry) const {
|
||||
using namespace Images;
|
||||
auto result = FrameRequest();
|
||||
result.outer = geometry.inner.size() * style::DevicePixelRatio();
|
||||
result.resize = result.outer;
|
||||
result.corners = RectPart(0)
|
||||
| ((geometry.attached & (RectPart::Left | RectPart::Top))
|
||||
? RectPart(0)
|
||||
: RectPart::TopLeft)
|
||||
| ((geometry.attached & (RectPart::Top | RectPart::Right))
|
||||
? RectPart(0)
|
||||
: RectPart::TopRight)
|
||||
| ((geometry.attached & (RectPart::Right | RectPart::Bottom))
|
||||
? RectPart(0)
|
||||
: RectPart::BottomRight)
|
||||
| ((geometry.attached & (RectPart::Bottom | RectPart::Left))
|
||||
? RectPart(0)
|
||||
: RectPart::BottomLeft);
|
||||
result.radius = ImageRoundRadius::Large;
|
||||
result.rounding = CornersMaskRef(CornersMask(ImageRoundRadius::Large));
|
||||
if (geometry.attached & (RectPart::Top | RectPart::Left)) {
|
||||
result.rounding.p[kTopLeft] = nullptr;
|
||||
}
|
||||
if (geometry.attached & (RectPart::Top | RectPart::Right)) {
|
||||
result.rounding.p[kTopRight] = nullptr;
|
||||
}
|
||||
if (geometry.attached & (RectPart::Bottom | RectPart::Left)) {
|
||||
result.rounding.p[kBottomLeft] = nullptr;
|
||||
}
|
||||
if (geometry.attached & (RectPart::Bottom | RectPart::Right)) {
|
||||
result.rounding.p[kBottomRight] = nullptr;
|
||||
}
|
||||
return UnrotateRequest(result, geometry.rotation);
|
||||
}
|
||||
|
||||
|
@ -175,19 +173,11 @@ QImage Pip::RendererSW::staticContentByRequest(
|
|||
// _instance.info().video.rotation,
|
||||
// request,
|
||||
// std::move(_preparedCoverStorage));
|
||||
using Option = Images::Option;
|
||||
const auto corner = [&](RectPart part, Option skip) {
|
||||
return !(request.corners & part) ? skip : Option();
|
||||
};
|
||||
const auto options = Option::RoundLarge
|
||||
| corner(RectPart::TopLeft, Option::RoundSkipTopLeft)
|
||||
| corner(RectPart::TopRight, Option::RoundSkipTopRight)
|
||||
| corner(RectPart::BottomLeft, Option::RoundSkipBottomLeft)
|
||||
| corner(RectPart::BottomRight, Option::RoundSkipBottomRight);
|
||||
_preparedStaticContent = Images::Prepare(
|
||||
_preparedStaticContent = Images::Round(Images::Prepare(
|
||||
image,
|
||||
request.resize,
|
||||
{ .options = options, .outer = request.outer });
|
||||
{ .outer = request.outer }), request.rounding);
|
||||
|
||||
return _preparedStaticContent;
|
||||
}
|
||||
|
||||
|
|
|
@ -161,10 +161,6 @@ void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color
|
|||
FillRoundRect(p, x, y, w, h, bg, Corners[index], shadow, parts);
|
||||
}
|
||||
|
||||
void FillRoundShadow(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, CachedRoundCorners index) {
|
||||
FillRoundShadow(p, x, y, w, h, shadow, Corners[index]);
|
||||
}
|
||||
|
||||
void FillRoundShadow(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, const CornersPixmaps &corners) {
|
||||
constexpr auto kLeft = 2;
|
||||
constexpr auto kRight = 3;
|
||||
|
|
|
@ -40,10 +40,6 @@ void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color
|
|||
inline void FillRoundRect(QPainter &p, const QRect &rect, style::color bg, CachedRoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
|
||||
FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
|
||||
}
|
||||
void FillRoundShadow(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, CachedRoundCorners index);
|
||||
inline void FillRoundShadow(QPainter &p, const QRect &rect, style::color shadow, CachedRoundCorners index) {
|
||||
FillRoundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index);
|
||||
}
|
||||
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
|
||||
inline void FillRoundRect(QPainter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
|
||||
FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
|
||||
|
|
|
@ -693,10 +693,7 @@ void FillComplexOverlayRect(
|
|||
QRect rect,
|
||||
const style::color &color,
|
||||
const CornersPixmaps &corners) {
|
||||
constexpr auto kTopLeft = 0;
|
||||
constexpr auto kTopRight = 1;
|
||||
constexpr auto kBottomLeft = 2;
|
||||
constexpr auto kBottomRight = 3;
|
||||
using namespace Images;
|
||||
|
||||
const auto pix = corners.p;
|
||||
const auto fillRect = [&](QRect rect) {
|
||||
|
@ -795,36 +792,14 @@ void FillComplexOverlayRect(
|
|||
}
|
||||
}
|
||||
|
||||
void FillComplexOverlayRect(
|
||||
void FillComplexEllipse(
|
||||
QPainter &p,
|
||||
not_null<const ChatStyle*> st,
|
||||
QRect rect,
|
||||
ImageRoundRadius radius,
|
||||
RectParts roundCorners) {
|
||||
const auto bg = st->msgSelectOverlay();
|
||||
if (radius == ImageRoundRadius::Ellipse) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(bg);
|
||||
p.drawEllipse(rect);
|
||||
} else {
|
||||
// #TODO rounding
|
||||
//const auto &corners = (radius == ImageRoundRadius::Small)
|
||||
// ? st->msgSelectOverlayCornersSmall()
|
||||
// : st->msgSelectOverlayCornersLarge();
|
||||
//RectWithCorners(p, rect, bg, corners, roundCorners);
|
||||
}
|
||||
}
|
||||
|
||||
void FillComplexLocationRect(
|
||||
QPainter &p,
|
||||
not_null<const ChatStyle*> st,
|
||||
QRect rect,
|
||||
ImageRoundRadius radius,
|
||||
RectParts roundCorners) {
|
||||
const auto stm = &st->messageStyle(false, false);
|
||||
// #TODO rounding
|
||||
RectWithCorners(p, rect, stm->msgBg, stm->msgBgCornersSmall, roundCorners);
|
||||
QRect rect) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st->msgSelectOverlay());
|
||||
p.drawEllipse(rect);
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -360,17 +360,9 @@ void FillComplexOverlayRect(
|
|||
const style::color &color,
|
||||
const CornersPixmaps &corners);
|
||||
|
||||
void FillComplexOverlayRect(
|
||||
void FillComplexEllipse(
|
||||
QPainter &p,
|
||||
not_null<const ChatStyle*> st,
|
||||
QRect rect,
|
||||
ImageRoundRadius radius,
|
||||
RectParts roundCorners);
|
||||
void FillComplexLocationRect(
|
||||
QPainter &p,
|
||||
not_null<const ChatStyle*> st,
|
||||
QRect rect,
|
||||
ImageRoundRadius radius,
|
||||
RectParts roundCorners);
|
||||
QRect rect);
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -478,7 +478,10 @@ void UserpicButton::paintUserpicFrame(Painter &p, QPoint photoPosition) {
|
|||
auto size = QSize{ _st.photoSize, _st.photoSize };
|
||||
request.outer = size * cIntRetinaFactor();
|
||||
request.resize = size * cIntRetinaFactor();
|
||||
request.radius = ImageRoundRadius::Ellipse;
|
||||
if (_ellipseMask.size() != request.outer) {
|
||||
_ellipseMask = Images::EllipseMask(size);
|
||||
}
|
||||
request.mask = _ellipseMask;
|
||||
p.drawImage(QRect(photoPosition, size), _streamed->frame(request));
|
||||
if (!paused) {
|
||||
_streamed->markFrameShown();
|
||||
|
|
|
@ -170,6 +170,7 @@ private:
|
|||
InMemoryKey _userpicUniqueKey;
|
||||
Ui::Animations::Simple _a_appearance;
|
||||
QImage _result;
|
||||
QImage _ellipseMask;
|
||||
std::unique_ptr<Media::Streaming::Instance> _streamed;
|
||||
PhotoData *_streamedPhoto = nullptr;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit cec09b0260ba19639bf9abc7df373569aa1509e7
|
||||
Subproject commit 2c2a7887e644dff7130d764c5a7b04aaa0463056
|
Loading…
Add table
Reference in a new issue