diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index c3ab565296..e8fd3cfa0f 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -411,7 +411,7 @@ void DocumentData::setattributes( void DocumentData::validateLottieSticker() { if (type == FileDocument - && _mimeString == qstr("application/x-tgsticker")) { + && hasMimeType(qstr("application/x-tgsticker"))) { type = StickerDocument; _additional = std::make_unique(); sticker()->animated = true; @@ -442,9 +442,8 @@ bool DocumentData::checkWallPaperProperties() { || !dimensions.height() || dimensions.width() > Storage::kMaxWallPaperDimension || dimensions.height() > Storage::kMaxWallPaperDimension - || size > Storage::kMaxWallPaperInMemory - || mimeString() == qstr("application/x-tgwallpattern")) { - return false; // #TODO themes support svg patterns + || size > Storage::kMaxWallPaperInMemory) { + return false; } type = WallPaperDocument; return true; @@ -487,9 +486,18 @@ bool DocumentData::isWallPaper() const { } bool DocumentData::isPatternWallPaper() const { + return isWallPaper() + && (isPatternWallPaperPNG() || isPatternWallPaperSVG()); +} + +bool DocumentData::isPatternWallPaperPNG() const { return isWallPaper() && hasMimeType(qstr("image/png")); } +bool DocumentData::isPatternWallPaperSVG() const { + return isWallPaper() && hasMimeType(qstr("application/x-tgwallpattern")); +} + bool DocumentData::hasThumbnail() const { return _thumbnail.location.valid(); } @@ -661,9 +669,9 @@ bool DocumentData::saveToCache() const { && ((type == StickerDocument) || isAnimation() || isVoiceMessage() - || (type == WallPaperDocument) + || isWallPaper() || isTheme() - || (mimeString() == qstr("image/png") + || (hasMimeType(qstr("image/png")) && _filename.startsWith("image_"))); } @@ -1233,11 +1241,12 @@ QString DocumentData::mimeString() const { } bool DocumentData::hasMimeType(QLatin1String mime) const { - return !_mimeString.compare(mime, Qt::CaseInsensitive); + return (_mimeString == mime); } void DocumentData::setMimeString(const QString &mime) { _mimeString = mime; + _mimeString = std::move(_mimeString).toLower(); } MediaKey DocumentData::mediaKey() const { @@ -1263,7 +1272,7 @@ uint8 DocumentData::cacheTag() const { return Data::kVideoMessageCacheTag; } else if (isAnimation()) { return Data::kAnimationCacheTag; - } else if (type == WallPaperDocument) { + } else if (isWallPaper()) { return Data::kImageCacheTag; } return 0; @@ -1298,14 +1307,9 @@ bool DocumentData::isGifv() const { } bool DocumentData::isTheme() const { - return - _mimeString == qstr("application/x-tgtheme-tdesktop") - || _filename.endsWith( - qstr(".tdesktop-theme"), - Qt::CaseInsensitive) - || _filename.endsWith( - qstr(".tdesktop-palette"), - Qt::CaseInsensitive); + return hasMimeType(qstr("application/x-tgtheme-tdesktop")) + || _filename.endsWith(qstr(".tdesktop-theme"), Qt::CaseInsensitive) + || _filename.endsWith(qstr(".tdesktop-palette"), Qt::CaseInsensitive); } bool DocumentData::isSong() const { diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index 09d7ec1211..09d1f5b3c9 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -155,6 +155,8 @@ public: bool checkWallPaperProperties(); [[nodiscard]] bool isWallPaper() const; [[nodiscard]] bool isPatternWallPaper() const; + [[nodiscard]] bool isPatternWallPaperPNG() const; + [[nodiscard]] bool isPatternWallPaperSVG() const; [[nodiscard]] bool hasThumbnail() const; [[nodiscard]] bool thumbnailLoading() const; diff --git a/Telegram/SourceFiles/data/data_document_media.cpp b/Telegram/SourceFiles/data/data_document_media.cpp index 736fdb2c10..8e5c63fec2 100644 --- a/Telegram/SourceFiles/data/data_document_media.cpp +++ b/Telegram/SourceFiles/data/data_document_media.cpp @@ -39,6 +39,8 @@ enum class FileType { Video, AnimatedSticker, WallPaper, + WallPatternPNG, + WallPatternSVG, Theme, }; @@ -60,6 +62,15 @@ enum class FileType { return Lottie::ReadThumbnail(Lottie::ReadContent(data, path)); } else if (type == FileType::Theme) { 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 file = QFile(path); @@ -390,7 +401,11 @@ void DocumentMedia::checkStickerLarge(not_null loader) { void DocumentMedia::GenerateGoodThumbnail( not_null document, QByteArray data) { - const auto type = document->isWallPaper() + const auto type = document->isPatternWallPaperSVG() + ? FileType::WallPatternSVG + : document->isPatternWallPaperPNG() + ? FileType::WallPatternPNG + : document->isWallPaper() ? FileType::WallPaper : document->isTheme() ? FileType::Theme @@ -415,7 +430,8 @@ void DocumentMedia::GenerateGoodThumbnail( auto buffer = QBuffer(&bytes); const auto format = (type == FileType::AnimatedSticker) ? "WEBP" - : (type == FileType::WallPaper && result.hasAlphaChannel()) + : (type == FileType::WallPatternPNG + || type == FileType::WallPatternSVG) ? "PNG" : "JPG"; result.save(&buffer, format, kGoodThumbQuality); diff --git a/Telegram/SourceFiles/data/data_document_resolver.cpp b/Telegram/SourceFiles/data/data_document_resolver.cpp index 12aae4be3e..53049a70af 100644 --- a/Telegram/SourceFiles/data/data_document_resolver.cpp +++ b/Telegram/SourceFiles/data/data_document_resolver.cpp @@ -33,6 +33,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Data { namespace { +constexpr auto kMaxWallpaperSize = 3072; + void LaunchWithWarning( // not_null controller, 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( not_null media, FnMut postprocess, FnMut done) { auto result = base::binary_guard(); + const auto gzipSvg = media->owner()->isPatternWallPaperSVG(); crl::async([ + gzipSvg, bytes = media->bytes(), path = media->owner()->filepath(), postprocess = std::move(postprocess), guard = result.make_guard(), callback = std::move(done) ]() mutable { - auto read = Images::Read({ - .path = path, - .content = bytes, - }); + auto image = ReadImage(path, bytes, gzipSvg); if (postprocess) { - read.image = postprocess(std::move(read.image)); + image = postprocess(std::move(image)); } crl::on_main(std::move(guard), [ - image = std::move(read.image), + image = std::move(image), callback = std::move(callback) ]() mutable { callback(std::move(image)); diff --git a/Telegram/SourceFiles/layout/layout_document_generic_preview.cpp b/Telegram/SourceFiles/layout/layout_document_generic_preview.cpp index 2206f10205..11c9615189 100644 --- a/Telegram/SourceFiles/layout/layout_document_generic_preview.cpp +++ b/Telegram/SourceFiles/layout/layout_document_generic_preview.cpp @@ -35,9 +35,7 @@ DocumentGenericPreview DocumentGenericPreview::Create( : document->filename()) : tr::lng_message_empty(tr::now)).toLower(); auto lastDot = name.lastIndexOf('.'); - const auto mime = document - ? document->mimeString().toLower() - : QString(); + const auto mime = document ? document->mimeString() : QString(); if (name.endsWith(qstr(".doc")) || name.endsWith(qstr(".docx")) || name.endsWith(qstr(".txt")) || diff --git a/Telegram/lib_lottie b/Telegram/lib_lottie index 2f9bda2cc7..06960b493d 160000 --- a/Telegram/lib_lottie +++ b/Telegram/lib_lottie @@ -1 +1 @@ -Subproject commit 2f9bda2cc7b8c94abe34f501b270df8533a7b141 +Subproject commit 06960b493d58d7c4e642dc38384d5f0db5340f1c diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 2bd63281b5..dd88f8fa41 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 2bd63281b58d54aa129da78f05f0e6e73e5d63c9 +Subproject commit dd88f8fa41a06bdf3128276d8084cfa4f087dee7