mirror of https://github.com/procxx/kepka.git
Fix crash in EditCaptionBox.
This commit is contained in:
parent
771a51224e
commit
7c1704e68b
|
@ -115,6 +115,9 @@ EditCaptionBox::EditCaptionBox(
|
||||||
_refreshThumbnail();
|
_refreshThumbnail();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!image) {
|
||||||
|
image = Image::BlankMedia();
|
||||||
|
}
|
||||||
int32 maxW = 0, maxH = 0;
|
int32 maxW = 0, maxH = 0;
|
||||||
if (_animated) {
|
if (_animated) {
|
||||||
int32 limitW = st::sendMediaPreviewSize;
|
int32 limitW = st::sendMediaPreviewSize;
|
||||||
|
@ -201,7 +204,9 @@ EditCaptionBox::EditCaptionBox(
|
||||||
? _thumbnailImage->loaded()
|
? _thumbnailImage->loaded()
|
||||||
: true;
|
: true;
|
||||||
subscribe(Auth().downloaderTaskFinished(), [=] {
|
subscribe(Auth().downloaderTaskFinished(), [=] {
|
||||||
if (!_thumbnailImageLoaded && _thumbnailImage->loaded()) {
|
if (!_thumbnailImageLoaded
|
||||||
|
&& _thumbnailImage
|
||||||
|
&& _thumbnailImage->loaded()) {
|
||||||
_thumbnailImageLoaded = true;
|
_thumbnailImageLoaded = true;
|
||||||
_refreshThumbnail();
|
_refreshThumbnail();
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -347,12 +347,22 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, TimeM
|
||||||
if (good) {
|
if (good) {
|
||||||
good->load({});
|
good->load({});
|
||||||
}
|
}
|
||||||
if (const auto normal = _data->thumbnail()) {
|
const auto normal = _data->thumbnail();
|
||||||
if (normal->loaded()) {
|
if (normal && normal->loaded()) {
|
||||||
p.drawPixmap(rthumb.topLeft(), normal->pixSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
|
p.drawPixmap(rthumb.topLeft(), normal->pixSingle(_realParent->fullId(), _thumbw, _thumbh, paintw, painth, roundRadius, roundCorners));
|
||||||
} else if (const auto blurred = _data->thumbnailInline()) {
|
} else if (const auto blurred = _data->thumbnailInline()) {
|
||||||
p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
|
p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, paintw, painth, roundRadius, roundCorners));
|
||||||
}
|
} else if (!isRound) {
|
||||||
|
const auto roundTop = (roundCorners & RectPart::TopLeft);
|
||||||
|
const auto roundBottom = (roundCorners & RectPart::BottomLeft);
|
||||||
|
const auto margin = inWebPage
|
||||||
|
? st::buttonRadius
|
||||||
|
: st::historyMessageRadius;
|
||||||
|
const auto parts = roundCorners
|
||||||
|
| RectPart::NoTopBottom
|
||||||
|
| (roundTop ? RectPart::Top : RectPart::None)
|
||||||
|
| (roundBottom ? RectPart::Bottom : RectPart::None);
|
||||||
|
App::roundRect(p, rthumb.marginsAdded({ 0, roundTop ? 0 : margin, 0, roundBottom ? 0 : margin }), st::imageBg, roundRadius, parts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -528,7 +528,7 @@ void HistoryPhoto::validateGroupedCache(
|
||||||
? _data->thumbnailSmall().get()
|
? _data->thumbnailSmall().get()
|
||||||
: _data->thumbnailInline()
|
: _data->thumbnailInline()
|
||||||
? _data->thumbnailInline()
|
? _data->thumbnailInline()
|
||||||
: Image::Blank().get();
|
: Image::BlankMedia().get();
|
||||||
|
|
||||||
*cacheKey = key;
|
*cacheKey = key;
|
||||||
*cache = image->pixNoCache(_realParent->fullId(), pixWidth, pixHeight, options, width, height);
|
*cache = image->pixNoCache(_realParent->fullId(), pixWidth, pixHeight, options, width, height);
|
||||||
|
|
|
@ -183,11 +183,22 @@ void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, Tim
|
||||||
if (good) {
|
if (good) {
|
||||||
good->load({});
|
good->load({});
|
||||||
}
|
}
|
||||||
if (const auto normal = _data->thumbnail()) {
|
const auto normal = _data->thumbnail();
|
||||||
const auto use = (normal->loaded() || !_data->thumbnailInline())
|
if (normal && normal->loaded()) {
|
||||||
? normal
|
p.drawPixmap(rthumb.topLeft(), normal->pixSingle(_realParent->fullId(), _thumbw, _thumbh, paintw, painth, roundRadius, roundCorners));
|
||||||
: _data->thumbnailInline();
|
} else if (const auto blurred = _data->thumbnailInline()) {
|
||||||
p.drawPixmap(rthumb.topLeft(), use->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, paintw, painth, roundRadius, roundCorners));
|
p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, paintw, painth, roundRadius, roundCorners));
|
||||||
|
} else {
|
||||||
|
const auto roundTop = (roundCorners & RectPart::TopLeft);
|
||||||
|
const auto roundBottom = (roundCorners & RectPart::BottomLeft);
|
||||||
|
const auto margin = inWebPage
|
||||||
|
? st::buttonRadius
|
||||||
|
: st::historyMessageRadius;
|
||||||
|
const auto parts = roundCorners
|
||||||
|
| RectPart::NoTopBottom
|
||||||
|
| (roundTop ? RectPart::Top : RectPart::None)
|
||||||
|
| (roundBottom ? RectPart::Bottom : RectPart::None);
|
||||||
|
App::roundRect(p, rthumb.marginsAdded({ 0, roundTop ? 0 : margin, 0, roundBottom ? 0 : margin }), st::imageBg, roundRadius, parts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (selected) {
|
if (selected) {
|
||||||
|
@ -496,7 +507,13 @@ void HistoryVideo::validateGroupedCache(
|
||||||
const auto pixHeight = pixSize.height() * cIntRetinaFactor();
|
const auto pixHeight = pixSize.height() * cIntRetinaFactor();
|
||||||
|
|
||||||
*cacheKey = key;
|
*cacheKey = key;
|
||||||
*cache = (image ? image : Image::Blank().get())->pixNoCache(_realParent->fullId(), pixWidth, pixHeight, options, width, height);
|
*cache = (image ? image : Image::BlankMedia().get())->pixNoCache(
|
||||||
|
_realParent->fullId(),
|
||||||
|
pixWidth,
|
||||||
|
pixHeight,
|
||||||
|
options,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryVideo::setStatusSize(int newSize) const {
|
void HistoryVideo::setStatusSize(int newSize) const {
|
||||||
|
|
|
@ -1810,12 +1810,12 @@ void OverlayWidget::initAnimation() {
|
||||||
auto h = _doc->dimensions.height();
|
auto h = _doc->dimensions.height();
|
||||||
_current = (_doc->hasThumbnail()
|
_current = (_doc->hasThumbnail()
|
||||||
? _doc->thumbnail()
|
? _doc->thumbnail()
|
||||||
: Image::Blank().get())->pixNoCache(fileOrigin(), w, h, VideoThumbOptions(_doc), w / cIntRetinaFactor(), h / cIntRetinaFactor());
|
: Image::Empty().get())->pixNoCache(fileOrigin(), w, h, VideoThumbOptions(_doc), w / cIntRetinaFactor(), h / cIntRetinaFactor());
|
||||||
_current.setDevicePixelRatio(cRetinaFactor());
|
_current.setDevicePixelRatio(cRetinaFactor());
|
||||||
} else if (_doc->hasThumbnail()) {
|
} else if (_doc->hasThumbnail()) {
|
||||||
_current = _doc->thumbnail()->pixNoCache(fileOrigin(), _doc->thumbnail()->width(), _doc->thumbnail()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
_current = _doc->thumbnail()->pixNoCache(fileOrigin(), _doc->thumbnail()->width(), _doc->thumbnail()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
||||||
} else {
|
} else {
|
||||||
_current = Image::Blank().get()->pixNoCache({}, Image::Blank()->width(), Image::Blank()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
_current = Image::Empty()->pixNoCache({}, Image::Empty()->width(), Image::Empty()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1830,12 +1830,12 @@ void OverlayWidget::createClipReader() {
|
||||||
int h = _doc->dimensions.height();
|
int h = _doc->dimensions.height();
|
||||||
_current = (_doc->hasThumbnail()
|
_current = (_doc->hasThumbnail()
|
||||||
? _doc->thumbnail()
|
? _doc->thumbnail()
|
||||||
: Image::Blank().get())->pixNoCache(fileOrigin(), w, h, VideoThumbOptions(_doc), w / cIntRetinaFactor(), h / cIntRetinaFactor());
|
: Image::Empty().get())->pixNoCache(fileOrigin(), w, h, VideoThumbOptions(_doc), w / cIntRetinaFactor(), h / cIntRetinaFactor());
|
||||||
_current.setDevicePixelRatio(cRetinaFactor());
|
_current.setDevicePixelRatio(cRetinaFactor());
|
||||||
} else if (_doc->hasThumbnail()) {
|
} else if (_doc->hasThumbnail()) {
|
||||||
_current = _doc->thumbnail()->pixNoCache(fileOrigin(), _doc->thumbnail()->width(), _doc->thumbnail()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
_current = _doc->thumbnail()->pixNoCache(fileOrigin(), _doc->thumbnail()->width(), _doc->thumbnail()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
||||||
} else {
|
} else {
|
||||||
_current = Image::Blank()->pixNoCache({}, Image::Blank()->width(), Image::Blank()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
_current = Image::Empty()->pixNoCache({}, Image::Empty()->width(), Image::Empty()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
||||||
}
|
}
|
||||||
auto mode = (_doc->isVideoFile() || _doc->isVideoMessage())
|
auto mode = (_doc->isVideoFile() || _doc->isVideoMessage())
|
||||||
? Media::Clip::Reader::Mode::Video
|
? Media::Clip::Reader::Mode::Video
|
||||||
|
@ -2100,7 +2100,7 @@ void OverlayWidget::validatePhotoCurrentImage() {
|
||||||
validatePhotoImage(_photo->thumbnailInline(), true);
|
validatePhotoImage(_photo->thumbnailInline(), true);
|
||||||
if (_current.isNull()) {
|
if (_current.isNull()) {
|
||||||
_photo->loadThumbnailSmall(fileOrigin());
|
_photo->loadThumbnailSmall(fileOrigin());
|
||||||
validatePhotoImage(Image::Blank().get(), true);
|
validatePhotoImage(Image::Empty(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ int64 ComputeUsage(const QImage &image) {
|
||||||
return ComputeUsage(image.size());
|
return ComputeUsage(image.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::MediaActiveCache<const Image> &ActiveCache() {
|
[[nodiscard]] Core::MediaActiveCache<const Image> &ActiveCache() {
|
||||||
static auto Instance = Core::MediaActiveCache<const Image>(
|
static auto Instance = Core::MediaActiveCache<const Image>(
|
||||||
kMemoryForCache,
|
kMemoryForCache,
|
||||||
[](const Image *image) { image->unload(); });
|
[](const Image *image) { image->unload(); });
|
||||||
|
@ -85,7 +85,7 @@ void ClearAll() {
|
||||||
ImagePtr Create(const QString &file, QByteArray format) {
|
ImagePtr Create(const QString &file, QByteArray format) {
|
||||||
if (file.startsWith(qstr("http://"), Qt::CaseInsensitive)
|
if (file.startsWith(qstr("http://"), Qt::CaseInsensitive)
|
||||||
|| file.startsWith(qstr("https://"), Qt::CaseInsensitive)) {
|
|| file.startsWith(qstr("https://"), Qt::CaseInsensitive)) {
|
||||||
const auto key = file;
|
const auto &key = file;
|
||||||
auto i = WebUrlImages.constFind(key);
|
auto i = WebUrlImages.constFind(key);
|
||||||
if (i == WebUrlImages.cend()) {
|
if (i == WebUrlImages.cend()) {
|
||||||
i = WebUrlImages.insert(
|
i = WebUrlImages.insert(
|
||||||
|
@ -208,7 +208,7 @@ QSize getImageSize(const QVector<MTPDocumentAttribute> &attributes) {
|
||||||
ImagePtr Create(const MTPDwebDocument &document) {
|
ImagePtr Create(const MTPDwebDocument &document) {
|
||||||
const auto size = getImageSize(document.vattributes.v);
|
const auto size = getImageSize(document.vattributes.v);
|
||||||
if (size.isEmpty()) {
|
if (size.isEmpty()) {
|
||||||
return Image::Blank();
|
return ImagePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't use size from WebDocument, because it is not reliable.
|
// We don't use size from WebDocument, because it is not reliable.
|
||||||
|
@ -227,7 +227,7 @@ ImagePtr Create(const MTPDwebDocument &document) {
|
||||||
ImagePtr Create(const MTPDwebDocumentNoProxy &document) {
|
ImagePtr Create(const MTPDwebDocumentNoProxy &document) {
|
||||||
const auto size = getImageSize(document.vattributes.v);
|
const auto size = getImageSize(document.vattributes.v);
|
||||||
if (size.isEmpty()) {
|
if (size.isEmpty()) {
|
||||||
return Image::Blank();
|
return ImagePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Create(qs(document.vurl), size.width(), size.height());
|
return Create(qs(document.vurl), size.width(), size.height());
|
||||||
|
@ -236,7 +236,7 @@ ImagePtr Create(const MTPDwebDocumentNoProxy &document) {
|
||||||
ImagePtr Create(const MTPDwebDocument &document, QSize box) {
|
ImagePtr Create(const MTPDwebDocument &document, QSize box) {
|
||||||
//const auto size = getImageSize(document.vattributes.v);
|
//const auto size = getImageSize(document.vattributes.v);
|
||||||
//if (size.isEmpty()) {
|
//if (size.isEmpty()) {
|
||||||
// return Image::Blank();
|
// return ImagePtr();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// We don't use size from WebDocument, because it is not reliable.
|
// We don't use size from WebDocument, because it is not reliable.
|
||||||
|
@ -254,7 +254,7 @@ ImagePtr Create(const MTPDwebDocument &document, QSize box) {
|
||||||
ImagePtr Create(const MTPDwebDocumentNoProxy &document, QSize box) {
|
ImagePtr Create(const MTPDwebDocumentNoProxy &document, QSize box) {
|
||||||
//const auto size = getImageSize(document.vattributes.v);
|
//const auto size = getImageSize(document.vattributes.v);
|
||||||
//if (size.isEmpty()) {
|
//if (size.isEmpty()) {
|
||||||
// return Image::Blank();
|
// return ImagePtr();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
return Create(qs(document.vurl), box);
|
return Create(qs(document.vurl), box);
|
||||||
|
@ -337,8 +337,8 @@ void Image::replaceSource(std::unique_ptr<Source> &&source) {
|
||||||
_source = std::move(source);
|
_source = std::move(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagePtr Image::Blank() {
|
not_null<Image*> Image::Empty() {
|
||||||
static const auto blankImage = [] {
|
static auto result = [] {
|
||||||
const auto factor = cIntRetinaFactor();
|
const auto factor = cIntRetinaFactor();
|
||||||
auto data = QImage(
|
auto data = QImage(
|
||||||
factor,
|
factor,
|
||||||
|
@ -346,15 +346,27 @@ ImagePtr Image::Blank() {
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
data.fill(Qt::transparent);
|
data.fill(Qt::transparent);
|
||||||
data.setDevicePixelRatio(cRetinaFactor());
|
data.setDevicePixelRatio(cRetinaFactor());
|
||||||
return Create(
|
return Image(std::make_unique<ImageSource>(std::move(data), "GIF"));
|
||||||
std::move(data),
|
|
||||||
"GIF");
|
|
||||||
}();
|
}();
|
||||||
return blankImage;
|
return &result;
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<Image*> Image::BlankMedia() {
|
||||||
|
static auto result = [] {
|
||||||
|
const auto factor = cIntRetinaFactor();
|
||||||
|
auto data = QImage(
|
||||||
|
factor,
|
||||||
|
factor,
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
data.fill(Qt::black);
|
||||||
|
data.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
return Image(std::make_unique<ImageSource>(std::move(data), "GIF"));
|
||||||
|
}();
|
||||||
|
return &result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Image::isNull() const {
|
bool Image::isNull() const {
|
||||||
return (this == Blank().get());
|
return (this == Empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &Image::pix(
|
const QPixmap &Image::pix(
|
||||||
|
@ -655,7 +667,7 @@ QPixmap Image::pixNoCache(
|
||||||
if (h <= 0 && height() > 0) {
|
if (h <= 0 && height() > 0) {
|
||||||
h = qRound(width() * w / float64(height()));
|
h = qRound(width() * w / float64(height()));
|
||||||
}
|
}
|
||||||
return Blank()->pixNoCache(origin, w, h, options, outerw, outerh);
|
return Empty()->pixNoCache(origin, w, h, options, outerw, outerh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNull() && outerw > 0 && outerh > 0) {
|
if (isNull() && outerw > 0 && outerh > 0) {
|
||||||
|
@ -713,7 +725,7 @@ QPixmap Image::pixColoredNoCache(
|
||||||
checkSource();
|
checkSource();
|
||||||
|
|
||||||
if (_data.isNull()) {
|
if (_data.isNull()) {
|
||||||
return Blank()->pix(origin);
|
return Empty()->pix(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto img = _data;
|
auto img = _data;
|
||||||
|
@ -737,7 +749,7 @@ QPixmap Image::pixBlurredColoredNoCache(
|
||||||
checkSource();
|
checkSource();
|
||||||
|
|
||||||
if (_data.isNull()) {
|
if (_data.isNull()) {
|
||||||
return Blank()->pix(origin);
|
return Empty()->pix(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto img = prepareBlur(_data);
|
auto img = prepareBlur(_data);
|
||||||
|
@ -828,6 +840,8 @@ void Image::invalidateSizeCache() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::~Image() {
|
Image::~Image() {
|
||||||
|
if (this != Empty() && this != BlankMedia()) {
|
||||||
unload();
|
unload();
|
||||||
ActiveCache().remove(this);
|
ActiveCache().remove(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,8 @@ public:
|
||||||
|
|
||||||
void replaceSource(std::unique_ptr<Images::Source> &&source);
|
void replaceSource(std::unique_ptr<Images::Source> &&source);
|
||||||
|
|
||||||
static ImagePtr Blank();
|
static not_null<Image*> Empty(); // 1x1 transparent
|
||||||
|
static not_null<Image*> BlankMedia(); // 1x1 black
|
||||||
|
|
||||||
QImage original() const;
|
QImage original() const;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "platform/platform_specific.h"
|
#include "platform/platform_specific.h"
|
||||||
|
|
||||||
ImagePtr::ImagePtr() : _data(Image::Blank().get()) {
|
ImagePtr::ImagePtr() : _data(Image::Empty()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagePtr::ImagePtr(not_null<Image*> data) : _data(data) {
|
ImagePtr::ImagePtr(not_null<Image*> data) : _data(data) {
|
||||||
|
|
Loading…
Reference in New Issue