mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add support for SVG patterns in wallpapers.
This commit is contained in:
parent
e8fc874456
commit
6cadf54874
7 changed files with 62 additions and 29 deletions
|
@ -411,7 +411,7 @@ void DocumentData::setattributes(
|
||||||
|
|
||||||
void DocumentData::validateLottieSticker() {
|
void DocumentData::validateLottieSticker() {
|
||||||
if (type == FileDocument
|
if (type == FileDocument
|
||||||
&& _mimeString == qstr("application/x-tgsticker")) {
|
&& hasMimeType(qstr("application/x-tgsticker"))) {
|
||||||
type = StickerDocument;
|
type = StickerDocument;
|
||||||
_additional = std::make_unique<StickerData>();
|
_additional = std::make_unique<StickerData>();
|
||||||
sticker()->animated = true;
|
sticker()->animated = true;
|
||||||
|
@ -442,9 +442,8 @@ bool DocumentData::checkWallPaperProperties() {
|
||||||
|| !dimensions.height()
|
|| !dimensions.height()
|
||||||
|| dimensions.width() > Storage::kMaxWallPaperDimension
|
|| dimensions.width() > Storage::kMaxWallPaperDimension
|
||||||
|| dimensions.height() > Storage::kMaxWallPaperDimension
|
|| dimensions.height() > Storage::kMaxWallPaperDimension
|
||||||
|| size > Storage::kMaxWallPaperInMemory
|
|| size > Storage::kMaxWallPaperInMemory) {
|
||||||
|| mimeString() == qstr("application/x-tgwallpattern")) {
|
return false;
|
||||||
return false; // #TODO themes support svg patterns
|
|
||||||
}
|
}
|
||||||
type = WallPaperDocument;
|
type = WallPaperDocument;
|
||||||
return true;
|
return true;
|
||||||
|
@ -487,9 +486,18 @@ bool DocumentData::isWallPaper() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DocumentData::isPatternWallPaper() const {
|
bool DocumentData::isPatternWallPaper() const {
|
||||||
|
return isWallPaper()
|
||||||
|
&& (isPatternWallPaperPNG() || isPatternWallPaperSVG());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DocumentData::isPatternWallPaperPNG() const {
|
||||||
return isWallPaper() && hasMimeType(qstr("image/png"));
|
return isWallPaper() && hasMimeType(qstr("image/png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DocumentData::isPatternWallPaperSVG() const {
|
||||||
|
return isWallPaper() && hasMimeType(qstr("application/x-tgwallpattern"));
|
||||||
|
}
|
||||||
|
|
||||||
bool DocumentData::hasThumbnail() const {
|
bool DocumentData::hasThumbnail() const {
|
||||||
return _thumbnail.location.valid();
|
return _thumbnail.location.valid();
|
||||||
}
|
}
|
||||||
|
@ -661,9 +669,9 @@ bool DocumentData::saveToCache() const {
|
||||||
&& ((type == StickerDocument)
|
&& ((type == StickerDocument)
|
||||||
|| isAnimation()
|
|| isAnimation()
|
||||||
|| isVoiceMessage()
|
|| isVoiceMessage()
|
||||||
|| (type == WallPaperDocument)
|
|| isWallPaper()
|
||||||
|| isTheme()
|
|| isTheme()
|
||||||
|| (mimeString() == qstr("image/png")
|
|| (hasMimeType(qstr("image/png"))
|
||||||
&& _filename.startsWith("image_")));
|
&& _filename.startsWith("image_")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1233,11 +1241,12 @@ QString DocumentData::mimeString() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DocumentData::hasMimeType(QLatin1String mime) const {
|
bool DocumentData::hasMimeType(QLatin1String mime) const {
|
||||||
return !_mimeString.compare(mime, Qt::CaseInsensitive);
|
return (_mimeString == mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::setMimeString(const QString &mime) {
|
void DocumentData::setMimeString(const QString &mime) {
|
||||||
_mimeString = mime;
|
_mimeString = mime;
|
||||||
|
_mimeString = std::move(_mimeString).toLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaKey DocumentData::mediaKey() const {
|
MediaKey DocumentData::mediaKey() const {
|
||||||
|
@ -1263,7 +1272,7 @@ uint8 DocumentData::cacheTag() const {
|
||||||
return Data::kVideoMessageCacheTag;
|
return Data::kVideoMessageCacheTag;
|
||||||
} else if (isAnimation()) {
|
} else if (isAnimation()) {
|
||||||
return Data::kAnimationCacheTag;
|
return Data::kAnimationCacheTag;
|
||||||
} else if (type == WallPaperDocument) {
|
} else if (isWallPaper()) {
|
||||||
return Data::kImageCacheTag;
|
return Data::kImageCacheTag;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1298,14 +1307,9 @@ bool DocumentData::isGifv() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DocumentData::isTheme() const {
|
bool DocumentData::isTheme() const {
|
||||||
return
|
return hasMimeType(qstr("application/x-tgtheme-tdesktop"))
|
||||||
_mimeString == qstr("application/x-tgtheme-tdesktop")
|
|| _filename.endsWith(qstr(".tdesktop-theme"), Qt::CaseInsensitive)
|
||||||
|| _filename.endsWith(
|
|| _filename.endsWith(qstr(".tdesktop-palette"), Qt::CaseInsensitive);
|
||||||
qstr(".tdesktop-theme"),
|
|
||||||
Qt::CaseInsensitive)
|
|
||||||
|| _filename.endsWith(
|
|
||||||
qstr(".tdesktop-palette"),
|
|
||||||
Qt::CaseInsensitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DocumentData::isSong() const {
|
bool DocumentData::isSong() const {
|
||||||
|
|
|
@ -155,6 +155,8 @@ public:
|
||||||
bool checkWallPaperProperties();
|
bool checkWallPaperProperties();
|
||||||
[[nodiscard]] bool isWallPaper() const;
|
[[nodiscard]] bool isWallPaper() const;
|
||||||
[[nodiscard]] bool isPatternWallPaper() const;
|
[[nodiscard]] bool isPatternWallPaper() const;
|
||||||
|
[[nodiscard]] bool isPatternWallPaperPNG() const;
|
||||||
|
[[nodiscard]] bool isPatternWallPaperSVG() const;
|
||||||
|
|
||||||
[[nodiscard]] bool hasThumbnail() const;
|
[[nodiscard]] bool hasThumbnail() const;
|
||||||
[[nodiscard]] bool thumbnailLoading() const;
|
[[nodiscard]] bool thumbnailLoading() const;
|
||||||
|
|
|
@ -39,6 +39,8 @@ enum class FileType {
|
||||||
Video,
|
Video,
|
||||||
AnimatedSticker,
|
AnimatedSticker,
|
||||||
WallPaper,
|
WallPaper,
|
||||||
|
WallPatternPNG,
|
||||||
|
WallPatternSVG,
|
||||||
Theme,
|
Theme,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,6 +62,15 @@ enum class FileType {
|
||||||
return Lottie::ReadThumbnail(Lottie::ReadContent(data, path));
|
return Lottie::ReadThumbnail(Lottie::ReadContent(data, path));
|
||||||
} else if (type == FileType::Theme) {
|
} else if (type == FileType::Theme) {
|
||||||
return Window::Theme::GeneratePreview(data, path);
|
return Window::Theme::GeneratePreview(data, path);
|
||||||
|
} else if (type == FileType::WallPatternSVG) {
|
||||||
|
return Images::Read({
|
||||||
|
.path = path,
|
||||||
|
.content = std::move(data),
|
||||||
|
.maxSize = QSize(
|
||||||
|
kWallPaperThumbnailLimit,
|
||||||
|
kWallPaperThumbnailLimit),
|
||||||
|
.gzipSvg = true,
|
||||||
|
}).image;
|
||||||
}
|
}
|
||||||
auto buffer = QBuffer(&data);
|
auto buffer = QBuffer(&data);
|
||||||
auto file = QFile(path);
|
auto file = QFile(path);
|
||||||
|
@ -390,7 +401,11 @@ void DocumentMedia::checkStickerLarge(not_null<FileLoader*> loader) {
|
||||||
void DocumentMedia::GenerateGoodThumbnail(
|
void DocumentMedia::GenerateGoodThumbnail(
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
QByteArray data) {
|
QByteArray data) {
|
||||||
const auto type = document->isWallPaper()
|
const auto type = document->isPatternWallPaperSVG()
|
||||||
|
? FileType::WallPatternSVG
|
||||||
|
: document->isPatternWallPaperPNG()
|
||||||
|
? FileType::WallPatternPNG
|
||||||
|
: document->isWallPaper()
|
||||||
? FileType::WallPaper
|
? FileType::WallPaper
|
||||||
: document->isTheme()
|
: document->isTheme()
|
||||||
? FileType::Theme
|
? FileType::Theme
|
||||||
|
@ -415,7 +430,8 @@ void DocumentMedia::GenerateGoodThumbnail(
|
||||||
auto buffer = QBuffer(&bytes);
|
auto buffer = QBuffer(&bytes);
|
||||||
const auto format = (type == FileType::AnimatedSticker)
|
const auto format = (type == FileType::AnimatedSticker)
|
||||||
? "WEBP"
|
? "WEBP"
|
||||||
: (type == FileType::WallPaper && result.hasAlphaChannel())
|
: (type == FileType::WallPatternPNG
|
||||||
|
|| type == FileType::WallPatternSVG)
|
||||||
? "PNG"
|
? "PNG"
|
||||||
: "JPG";
|
: "JPG";
|
||||||
result.save(&buffer, format, kGoodThumbQuality);
|
result.save(&buffer, format, kGoodThumbQuality);
|
||||||
|
|
|
@ -33,6 +33,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Data {
|
namespace Data {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kMaxWallpaperSize = 3072;
|
||||||
|
|
||||||
void LaunchWithWarning(
|
void LaunchWithWarning(
|
||||||
// not_null<Window::Controller*> controller,
|
// not_null<Window::Controller*> controller,
|
||||||
const QString &name,
|
const QString &name,
|
||||||
|
@ -173,27 +175,38 @@ bool IsIpRevealingName(const QString &filepath) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QImage ReadImage(
|
||||||
|
const QString &path,
|
||||||
|
const QByteArray &content,
|
||||||
|
bool gzipSvg) {
|
||||||
|
return Images::Read({
|
||||||
|
.path = path,
|
||||||
|
.content = content,
|
||||||
|
.maxSize = QSize(kMaxWallpaperSize, kMaxWallpaperSize),
|
||||||
|
.gzipSvg = gzipSvg,
|
||||||
|
}).image;
|
||||||
|
}
|
||||||
|
|
||||||
base::binary_guard ReadImageAsync(
|
base::binary_guard ReadImageAsync(
|
||||||
not_null<Data::DocumentMedia*> media,
|
not_null<Data::DocumentMedia*> media,
|
||||||
FnMut<QImage(QImage)> postprocess,
|
FnMut<QImage(QImage)> postprocess,
|
||||||
FnMut<void(QImage&&)> done) {
|
FnMut<void(QImage&&)> done) {
|
||||||
auto result = base::binary_guard();
|
auto result = base::binary_guard();
|
||||||
|
const auto gzipSvg = media->owner()->isPatternWallPaperSVG();
|
||||||
crl::async([
|
crl::async([
|
||||||
|
gzipSvg,
|
||||||
bytes = media->bytes(),
|
bytes = media->bytes(),
|
||||||
path = media->owner()->filepath(),
|
path = media->owner()->filepath(),
|
||||||
postprocess = std::move(postprocess),
|
postprocess = std::move(postprocess),
|
||||||
guard = result.make_guard(),
|
guard = result.make_guard(),
|
||||||
callback = std::move(done)
|
callback = std::move(done)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
auto read = Images::Read({
|
auto image = ReadImage(path, bytes, gzipSvg);
|
||||||
.path = path,
|
|
||||||
.content = bytes,
|
|
||||||
});
|
|
||||||
if (postprocess) {
|
if (postprocess) {
|
||||||
read.image = postprocess(std::move(read.image));
|
image = postprocess(std::move(image));
|
||||||
}
|
}
|
||||||
crl::on_main(std::move(guard), [
|
crl::on_main(std::move(guard), [
|
||||||
image = std::move(read.image),
|
image = std::move(image),
|
||||||
callback = std::move(callback)
|
callback = std::move(callback)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
callback(std::move(image));
|
callback(std::move(image));
|
||||||
|
|
|
@ -35,9 +35,7 @@ DocumentGenericPreview DocumentGenericPreview::Create(
|
||||||
: document->filename())
|
: document->filename())
|
||||||
: tr::lng_message_empty(tr::now)).toLower();
|
: tr::lng_message_empty(tr::now)).toLower();
|
||||||
auto lastDot = name.lastIndexOf('.');
|
auto lastDot = name.lastIndexOf('.');
|
||||||
const auto mime = document
|
const auto mime = document ? document->mimeString() : QString();
|
||||||
? document->mimeString().toLower()
|
|
||||||
: QString();
|
|
||||||
if (name.endsWith(qstr(".doc")) ||
|
if (name.endsWith(qstr(".doc")) ||
|
||||||
name.endsWith(qstr(".docx")) ||
|
name.endsWith(qstr(".docx")) ||
|
||||||
name.endsWith(qstr(".txt")) ||
|
name.endsWith(qstr(".txt")) ||
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2f9bda2cc7b8c94abe34f501b270df8533a7b141
|
Subproject commit 06960b493d58d7c4e642dc38384d5f0db5340f1c
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2bd63281b58d54aa129da78f05f0e6e73e5d63c9
|
Subproject commit dd88f8fa41a06bdf3128276d8084cfa4f087dee7
|
Loading…
Add table
Reference in a new issue