 556aa28df6
			
		
	
	
		556aa28df6
		
	
	
	
	
		
			
			The following are commits related to removed variables. apiwrap.cppe050e27: kSaveDraftBeforeQuitTimeout app.cpp113f665: serviceImageCacheSize boxes/auto_download_box.cppa0c6104: checked(Source source, Type type) boxes/background_preview_box.cppb6edf45: resultBytesPerPixelfe21b5a: ms boxes/calendar_box.cppae97704: yearIndex, monthIndex99bb093: ms boxes/connection_box.cppf794d8d: ping boxes/dictionaries_manager.cpp8353867: session boxes/peer_list_box.cpp2ce2a14: grayedWidth boxes/peers/add_participants_box.cpp07e010d: chat, channel boxes/self_destruction_box.cppfe9f02e: count chat_helpers/emoji_suggestions_widget.cppa12bc60: is(QLatin1String string) chat_helpers/field_autocomplete.cpp8c7a35c: atwidth, hashwidth chat_helpers/gifs_list_widget.cppff65734: inlineItems3d846fc: newSelectedd1687ab: kSaveDraftBeforeQuitTimeout chat_helpers/stickers_dice_pack.cppc83e297: kZeroDiceDocumentId chat_helpers/stickers_emoji_pack.cppd298953: length chat_helpers/stickers_list_widget.cppeb75859: index, x core/crash_reports.cpp5940ae6: LaunchedDateTimeStr, LaunchedBinaryName data/data_changes.cpp 3c4e959:clearRealtime data/data_cloud_file.cpp4b354b0: fromCloud, cacheTag data/data_document_media.cpp7db5359: kMaxVideoFrameArea data/data_messages.cpp794e315: wasCount data/data_photo_media.cppe27d2bc: index data/data_wall_paper.cppb6edf45: resultBytesPerPixel data/data_types.cppaa8f62d: kWebDocumentCacheTag, kStorageCacheMask history/admin_log/history_admin_log_inner.cpp794e315: canDelete, canForward history/history_location_manager.cpp60f45ab: kCoordPrecision9f90d3a: kMaxHttpRedirects history/history_message.cppcedf8a6: kPinnedMessageTextLimit history/history_widget.cppb305924: serviceColorefa5fc4: hasForward5e7aa4f: kTabbedSelectorToggleTooltipTimeoutMs, kTabbedSelectorToggleTooltipCount history/view/history_view_context_menu.cppfe1a90b: isVideoLink, isVoiceLink, isAudioLink settings.cppe2f54eb: defaultRecent settings/settings_folders.cppe8bf5bb: kRefreshSuggestedTimeout ui/filter_icon_panel.cppc4a0bc1: kDelayedHideTimeoutMs window/themes/window_theme_preview.cppef927c8: mutedCounter ----- Modified variables boxes/stickers_box.cpp554eb3a: _rows[pressedIndex] -> set data/data_notify_settings.cpp734c410: muteForSeconds -> muteUntil history/view/history_view_list_widget.cpp07528be: _items[index] -> viewe5f3bed: fromState, tillState history/history.cppcd3c1c6: kStatusShowClientsideRecordVideo -> kStatusShowClientsideRecordVoice storage/download_manager_mtproto.cppae8fb14: _queues[dcId] -> queue storage/localstorage.cpp357caf8: MTP::Environment::Production -> production
		
			
				
	
	
		
			629 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			629 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| This file is part of Telegram Desktop,
 | |
| the official desktop application for the Telegram messaging service.
 | |
| 
 | |
| For license and copyright information please follow this link:
 | |
| https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | |
| */
 | |
| #include "data/data_wall_paper.h"
 | |
| 
 | |
| #include "data/data_document.h"
 | |
| #include "data/data_file_origin.h"
 | |
| #include "data/data_session.h"
 | |
| #include "storage/serialize_common.h"
 | |
| #include "core/application.h"
 | |
| #include "main/main_session.h"
 | |
| 
 | |
| namespace Data {
 | |
| namespace {
 | |
| 
 | |
| constexpr auto FromLegacyBackgroundId(int32 legacyId) -> WallPaperId {
 | |
| 	return uint64(0xFFFFFFFF00000000ULL) | uint64(uint32(legacyId));
 | |
| }
 | |
| 
 | |
| constexpr auto kUninitializedBackground = FromLegacyBackgroundId(-999);
 | |
| constexpr auto kTestingThemeBackground = FromLegacyBackgroundId(-666);
 | |
| constexpr auto kTestingDefaultBackground = FromLegacyBackgroundId(-665);
 | |
| constexpr auto kTestingEditorBackground = FromLegacyBackgroundId(-664);
 | |
| constexpr auto kThemeBackground = FromLegacyBackgroundId(-2);
 | |
| constexpr auto kCustomBackground = FromLegacyBackgroundId(-1);
 | |
| constexpr auto kLegacy1DefaultBackground = FromLegacyBackgroundId(0);
 | |
| constexpr auto kDefaultBackground = 5947530738516623361;
 | |
| constexpr auto kIncorrectDefaultBackground = FromLegacyBackgroundId(105);
 | |
| 
 | |
| quint32 SerializeMaybeColor(std::optional<QColor> color) {
 | |
| 	return color
 | |
| 		? ((quint32(std::clamp(color->red(), 0, 255)) << 16)
 | |
| 			| (quint32(std::clamp(color->green(), 0, 255)) << 8)
 | |
| 			| quint32(std::clamp(color->blue(), 0, 255)))
 | |
| 		: quint32(-1);
 | |
| }
 | |
| 
 | |
| std::optional<QColor> MaybeColorFromSerialized(quint32 serialized) {
 | |
| 	return (serialized == quint32(-1))
 | |
| 		? std::nullopt
 | |
| 		: std::make_optional(QColor(
 | |
| 			int((serialized >> 16) & 0xFFU),
 | |
| 			int((serialized >> 8) & 0xFFU),
 | |
| 			int(serialized & 0xFFU)));
 | |
| }
 | |
| 
 | |
| std::optional<QColor> ColorFromString(const QString &string) {
 | |
| 	if (string.size() != 6) {
 | |
| 		return {};
 | |
| 	} else if (ranges::any_of(string, [](QChar ch) {
 | |
| 		return (ch < 'a' || ch > 'f')
 | |
| 			&& (ch < 'A' || ch > 'F')
 | |
| 			&& (ch < '0' || ch > '9');
 | |
| 	})) {
 | |
| 		return {};
 | |
| 	}
 | |
| 	const auto component = [](const QString &text, int index) {
 | |
| 		const auto decimal = [](QChar hex) {
 | |
| 			const auto code = hex.unicode();
 | |
| 			return (code >= '0' && code <= '9')
 | |
| 				? int(code - '0')
 | |
| 				: (code >= 'a' && code <= 'f')
 | |
| 				? int(code - 'a' + 0x0a)
 | |
| 				: int(code - 'A' + 0x0a);
 | |
| 		};
 | |
| 		index *= 2;
 | |
| 		return decimal(text[index]) * 0x10 + decimal(text[index + 1]);
 | |
| 	};
 | |
| 	return QColor(
 | |
| 		component(string, 0),
 | |
| 		component(string, 1),
 | |
| 		component(string, 2),
 | |
| 		255);
 | |
| }
 | |
| 
 | |
| QString StringFromColor(QColor color) {
 | |
| 	const auto component = [](int value) {
 | |
| 		const auto hex = [](int value) {
 | |
| 			value = std::clamp(value, 0, 15);
 | |
| 			return (value > 9)
 | |
| 				? ('a' + (value - 10))
 | |
| 				: ('0' + value);
 | |
| 		};
 | |
| 		return QString() + hex(value / 16) + hex(value % 16);
 | |
| 	};
 | |
| 	return component(color.red())
 | |
| 		+ component(color.green())
 | |
| 		+ component(color.blue());
 | |
| }
 | |
| 
 | |
| } // namespace
 | |
| 
 | |
| WallPaper::WallPaper(WallPaperId id) : _id(id) {
 | |
| }
 | |
| 
 | |
| void WallPaper::setLocalImageAsThumbnail(std::shared_ptr<Image> image) {
 | |
| 	Expects(IsDefaultWallPaper(*this)
 | |
| 		|| IsLegacy1DefaultWallPaper(*this)
 | |
| 		|| IsCustomWallPaper(*this));
 | |
| 	Expects(_thumbnail == nullptr);
 | |
| 
 | |
| 	_thumbnail = std::move(image);
 | |
| }
 | |
| 
 | |
| WallPaperId WallPaper::id() const {
 | |
| 	return _id;
 | |
| }
 | |
| 
 | |
| std::optional<QColor> WallPaper::backgroundColor() const {
 | |
| 	return _backgroundColor;
 | |
| }
 | |
| 
 | |
| DocumentData *WallPaper::document() const {
 | |
| 	return _document;
 | |
| }
 | |
| 
 | |
| Image *WallPaper::localThumbnail() const {
 | |
| 	return _thumbnail.get();
 | |
| }
 | |
| 
 | |
| bool WallPaper::isPattern() const {
 | |
| 	return _flags & MTPDwallPaper::Flag::f_pattern;
 | |
| }
 | |
| 
 | |
| bool WallPaper::isDefault() const {
 | |
| 	return _flags & MTPDwallPaper::Flag::f_default;
 | |
| }
 | |
| 
 | |
| bool WallPaper::isCreator() const {
 | |
| 	return _flags & MTPDwallPaper::Flag::f_creator;
 | |
| }
 | |
| 
 | |
| bool WallPaper::isDark() const {
 | |
| 	return _flags & MTPDwallPaper::Flag::f_dark;
 | |
| }
 | |
| 
 | |
| bool WallPaper::isLocal() const {
 | |
| 	return !document() && _thumbnail;
 | |
| }
 | |
| 
 | |
| bool WallPaper::isBlurred() const {
 | |
| 	return _settings & MTPDwallPaperSettings::Flag::f_blur;
 | |
| }
 | |
| 
 | |
| int WallPaper::patternIntensity() const {
 | |
| 	return _intensity;
 | |
| }
 | |
| 
 | |
| bool WallPaper::hasShareUrl() const {
 | |
| 	return !_slug.isEmpty();
 | |
| }
 | |
| 
 | |
| QString WallPaper::shareUrl(not_null<Main::Session*> session) const {
 | |
| 	if (!hasShareUrl()) {
 | |
| 		return QString();
 | |
| 	}
 | |
| 	const auto base = session->createInternalLinkFull("bg/" + _slug);
 | |
| 	auto params = QStringList();
 | |
| 	if (isPattern()) {
 | |
| 		if (_backgroundColor) {
 | |
| 			params.push_back("bg_color=" + StringFromColor(*_backgroundColor));
 | |
| 		}
 | |
| 		if (_intensity) {
 | |
| 			params.push_back("intensity=" + QString::number(_intensity));
 | |
| 		}
 | |
| 	}
 | |
| 	auto mode = QStringList();
 | |
| 	if (_settings & MTPDwallPaperSettings::Flag::f_blur) {
 | |
| 		mode.push_back("blur");
 | |
| 	}
 | |
| 	if (_settings & MTPDwallPaperSettings::Flag::f_motion) {
 | |
| 		mode.push_back("motion");
 | |
| 	}
 | |
| 	if (!mode.isEmpty()) {
 | |
| 		params.push_back("mode=" + mode.join('+'));
 | |
| 	}
 | |
| 	return params.isEmpty()
 | |
| 		? base
 | |
| 		: base + '?' + params.join('&');
 | |
| }
 | |
| 
 | |
| void WallPaper::loadDocumentThumbnail() const {
 | |
| 	if (_document) {
 | |
| 		_document->loadThumbnail(fileOrigin());
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void WallPaper::loadDocument() const {
 | |
| 	if (_document) {
 | |
| 		_document->save(fileOrigin(), QString());
 | |
| 	}
 | |
| }
 | |
| 
 | |
| FileOrigin WallPaper::fileOrigin() const {
 | |
| 	return FileOriginWallpaper(_id, _accessHash, _ownerId, _slug);
 | |
| }
 | |
| 
 | |
| UserId WallPaper::ownerId() const {
 | |
| 	return _ownerId;
 | |
| }
 | |
| 
 | |
| MTPInputWallPaper WallPaper::mtpInput(not_null<Main::Session*> session) const {
 | |
| 	return (_ownerId && _ownerId != session->userId() && !_slug.isEmpty())
 | |
| 		? MTP_inputWallPaperSlug(MTP_string(_slug))
 | |
| 		: MTP_inputWallPaper(MTP_long(_id), MTP_long(_accessHash));
 | |
| }
 | |
| 
 | |
| MTPWallPaperSettings WallPaper::mtpSettings() const {
 | |
| 	return MTP_wallPaperSettings(
 | |
| 		MTP_flags(_settings),
 | |
| 		(_backgroundColor
 | |
| 			? MTP_int(SerializeMaybeColor(_backgroundColor))
 | |
| 			: MTP_int(0)),
 | |
| 		MTP_int(0), // second_background_color
 | |
| 		MTP_int(_intensity),
 | |
| 		MTP_int(0) // rotation
 | |
| 	);
 | |
| }
 | |
| 
 | |
| WallPaper WallPaper::withUrlParams(
 | |
| 		const QMap<QString, QString> ¶ms) const {
 | |
| 	using Flag = MTPDwallPaperSettings::Flag;
 | |
| 
 | |
| 	auto result = *this;
 | |
| 	result._settings = Flag(0);
 | |
| 	result._backgroundColor = ColorFromString(_slug);
 | |
| 	result._intensity = kDefaultIntensity;
 | |
| 
 | |
| 	if (auto mode = params.value("mode"); !mode.isEmpty()) {
 | |
| 		const auto list = mode.replace('+', ' ').split(' ');
 | |
| 		for (const auto &change : list) {
 | |
| 			if (change == qstr("blur")) {
 | |
| 				result._settings |= Flag::f_blur;
 | |
| 			} else if (change == qstr("motion")) {
 | |
| 				result._settings |= Flag::f_motion;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	if (const auto color = ColorFromString(params.value("bg_color"))) {
 | |
| 		result._settings |= Flag::f_background_color;
 | |
| 		result._backgroundColor = color;
 | |
| 	}
 | |
| 	if (const auto string = params.value("intensity"); !string.isEmpty()) {
 | |
| 		auto ok = false;
 | |
| 		const auto intensity = string.toInt(&ok);
 | |
| 		if (ok && base::in_range(intensity, 0, 101)) {
 | |
| 			result._settings |= Flag::f_intensity;
 | |
| 			result._intensity = intensity;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| WallPaper WallPaper::withBlurred(bool blurred) const {
 | |
| 	using Flag = MTPDwallPaperSettings::Flag;
 | |
| 
 | |
| 	auto result = *this;
 | |
| 	if (blurred) {
 | |
| 		result._settings |= Flag::f_blur;
 | |
| 	} else {
 | |
| 		result._settings &= ~Flag::f_blur;
 | |
| 	}
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| WallPaper WallPaper::withPatternIntensity(int intensity) const {
 | |
| 	using Flag = MTPDwallPaperSettings::Flag;
 | |
| 
 | |
| 	auto result = *this;
 | |
| 	result._settings |= Flag::f_intensity;
 | |
| 	result._intensity = intensity;
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| WallPaper WallPaper::withBackgroundColor(QColor color) const {
 | |
| 	using Flag = MTPDwallPaperSettings::Flag;
 | |
| 
 | |
| 	auto result = *this;
 | |
| 	result._settings |= Flag::f_background_color;
 | |
| 	result._backgroundColor = color;
 | |
| 	if (ColorFromString(_slug)) {
 | |
| 		result._slug = StringFromColor(color);
 | |
| 	}
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| WallPaper WallPaper::withParamsFrom(const WallPaper &other) const {
 | |
| 	auto result = *this;
 | |
| 	result._settings = other._settings;
 | |
| 	if (other._backgroundColor || !ColorFromString(_slug)) {
 | |
| 		result._backgroundColor = other._backgroundColor;
 | |
| 		if (ColorFromString(_slug)) {
 | |
| 			result._slug = StringFromColor(*result._backgroundColor);
 | |
| 		}
 | |
| 	}
 | |
| 	result._intensity = other._intensity;
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| WallPaper WallPaper::withoutImageData() const {
 | |
| 	auto result = *this;
 | |
| 	result._thumbnail = nullptr;
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| std::optional<WallPaper> WallPaper::Create(
 | |
| 		not_null<Main::Session*> session,
 | |
| 		const MTPWallPaper &data) {
 | |
| 	return data.match([&](const MTPDwallPaper &data) {
 | |
| 		return Create(session, data);
 | |
| 	}, [](const MTPDwallPaperNoFile &data) {
 | |
| 		return std::optional<WallPaper>(); // #TODO themes
 | |
| 	});
 | |
| }
 | |
| 
 | |
| std::optional<WallPaper> WallPaper::Create(
 | |
| 		not_null<Main::Session*> session,
 | |
| 		const MTPDwallPaper &data) {
 | |
| 	using Flag = MTPDwallPaper::Flag;
 | |
| 
 | |
| 	const auto document = session->data().processDocument(
 | |
| 		data.vdocument());
 | |
| 	if (!document->checkWallPaperProperties()) {
 | |
| 		return std::nullopt;
 | |
| 	}
 | |
| 	auto result = WallPaper(data.vid().v);
 | |
| 	result._accessHash = data.vaccess_hash().v;
 | |
| 	result._ownerId = session->userId();
 | |
| 	result._flags = data.vflags().v;
 | |
| 	result._slug = qs(data.vslug());
 | |
| 	result._document = document;
 | |
| 	if (const auto settings = data.vsettings()) {
 | |
| 		const auto isPattern = ((result._flags & Flag::f_pattern) != 0);
 | |
| 		settings->match([&](const MTPDwallPaperSettings &data) {
 | |
| 			using Flag = MTPDwallPaperSettings::Flag;
 | |
| 
 | |
| 			result._settings = data.vflags().v;
 | |
| 			const auto backgroundColor = data.vbackground_color();
 | |
| 			if (isPattern && backgroundColor) {
 | |
| 				result._backgroundColor = MaybeColorFromSerialized(
 | |
| 					backgroundColor->v);
 | |
| 			} else {
 | |
| 				result._settings &= ~Flag::f_background_color;
 | |
| 			}
 | |
| 			const auto intensity = data.vintensity();
 | |
| 			if (isPattern && intensity) {
 | |
| 				result._intensity = intensity->v;
 | |
| 			} else {
 | |
| 				result._settings &= ~Flag::f_intensity;
 | |
| 			}
 | |
| 		});
 | |
| 	}
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| QByteArray WallPaper::serialize() const {
 | |
| 	auto size = sizeof(quint64) // _id
 | |
| 		+ sizeof(quint64) // _accessHash
 | |
| 		+ sizeof(qint32) // _flags
 | |
| 		+ Serialize::stringSize(_slug)
 | |
| 		+ sizeof(qint32) // _settings
 | |
| 		+ sizeof(quint32) // _backgroundColor
 | |
| 		+ sizeof(qint32); // _intensity
 | |
| 
 | |
| 	auto result = QByteArray();
 | |
| 	result.reserve(size);
 | |
| 	{
 | |
| 		auto stream = QDataStream(&result, QIODevice::WriteOnly);
 | |
| 		stream.setVersion(QDataStream::Qt_5_1);
 | |
| 		stream
 | |
| 			<< quint64(_id)
 | |
| 			<< quint64(_accessHash)
 | |
| 			<< qint32(_flags)
 | |
| 			<< _slug
 | |
| 			<< qint32(_settings)
 | |
| 			<< SerializeMaybeColor(_backgroundColor)
 | |
| 			<< qint32(_intensity)
 | |
| 			<< qint32(_ownerId);
 | |
| 	}
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| std::optional<WallPaper> WallPaper::FromSerialized(
 | |
| 		const QByteArray &serialized) {
 | |
| 	if (serialized.isEmpty()) {
 | |
| 		return std::nullopt;
 | |
| 	}
 | |
| 
 | |
| 	auto id = quint64();
 | |
| 	auto accessHash = quint64();
 | |
| 	auto ownerId = qint32();
 | |
| 	auto flags = qint32();
 | |
| 	auto slug = QString();
 | |
| 	auto settings = qint32();
 | |
| 	auto backgroundColor = quint32();
 | |
| 	auto intensity = qint32();
 | |
| 
 | |
| 	auto stream = QDataStream(serialized);
 | |
| 	stream.setVersion(QDataStream::Qt_5_1);
 | |
| 	stream
 | |
| 		>> id
 | |
| 		>> accessHash
 | |
| 		>> flags
 | |
| 		>> slug
 | |
| 		>> settings
 | |
| 		>> backgroundColor
 | |
| 		>> intensity;
 | |
| 	if (!stream.atEnd()) {
 | |
| 		stream >> ownerId;
 | |
| 	}
 | |
| 	if (stream.status() != QDataStream::Ok) {
 | |
| 		return std::nullopt;
 | |
| 	} else if (intensity < 0 || intensity > 100) {
 | |
| 		return std::nullopt;
 | |
| 	}
 | |
| 	auto result = WallPaper(id);
 | |
| 	result._accessHash = accessHash;
 | |
| 	result._ownerId = ownerId;
 | |
| 	result._flags = MTPDwallPaper::Flags::from_raw(flags);
 | |
| 	result._slug = slug;
 | |
| 	result._settings = MTPDwallPaperSettings::Flags::from_raw(settings);
 | |
| 	result._backgroundColor = MaybeColorFromSerialized(backgroundColor);
 | |
| 	result._intensity = intensity;
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| std::optional<WallPaper> WallPaper::FromLegacySerialized(
 | |
| 		quint64 id,
 | |
| 		quint64 accessHash,
 | |
| 		quint32 flags,
 | |
| 		QString slug) {
 | |
| 	auto result = WallPaper(id);
 | |
| 	result._accessHash = accessHash;
 | |
| 	result._flags = MTPDwallPaper::Flags::from_raw(flags);
 | |
| 	result._slug = slug;
 | |
| 	result._backgroundColor = ColorFromString(slug);
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| std::optional<WallPaper> WallPaper::FromLegacyId(qint32 legacyId) {
 | |
| 	auto result = WallPaper(FromLegacyBackgroundId(legacyId));
 | |
| 	if (!IsCustomWallPaper(result)) {
 | |
| 		result._flags = MTPDwallPaper::Flag::f_default;
 | |
| 	}
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| std::optional<WallPaper> WallPaper::FromColorSlug(const QString &slug) {
 | |
| 	if (const auto color = ColorFromString(slug)) {
 | |
| 		auto result = CustomWallPaper();
 | |
| 		result._slug = slug;
 | |
| 		result._backgroundColor = color;
 | |
| 		return result;
 | |
| 	}
 | |
| 	return std::nullopt;
 | |
| }
 | |
| 
 | |
| WallPaper ThemeWallPaper() {
 | |
| 	return WallPaper(kThemeBackground);
 | |
| }
 | |
| 
 | |
| bool IsThemeWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() == kThemeBackground);
 | |
| }
 | |
| 
 | |
| WallPaper CustomWallPaper() {
 | |
| 	return WallPaper(kCustomBackground);
 | |
| }
 | |
| 
 | |
| bool IsCustomWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() == kCustomBackground);
 | |
| }
 | |
| 
 | |
| WallPaper Legacy1DefaultWallPaper() {
 | |
| 	return WallPaper(kLegacy1DefaultBackground);
 | |
| }
 | |
| 
 | |
| bool IsLegacy1DefaultWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() == kLegacy1DefaultBackground);
 | |
| }
 | |
| 
 | |
| WallPaper DefaultWallPaper() {
 | |
| 	return WallPaper(kDefaultBackground);
 | |
| }
 | |
| 
 | |
| bool IsDefaultWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() == kDefaultBackground)
 | |
| 		|| (paper.id() == kIncorrectDefaultBackground);
 | |
| }
 | |
| 
 | |
| bool IsCloudWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() != kIncorrectDefaultBackground)
 | |
| 		&& !IsThemeWallPaper(paper)
 | |
| 		&& !IsCustomWallPaper(paper)
 | |
| 		&& !IsLegacy1DefaultWallPaper(paper)
 | |
| 		&& !details::IsUninitializedWallPaper(paper)
 | |
| 		&& !details::IsTestingThemeWallPaper(paper)
 | |
| 		&& !details::IsTestingDefaultWallPaper(paper)
 | |
| 		&& !details::IsTestingEditorWallPaper(paper);
 | |
| }
 | |
| 
 | |
| QColor PatternColor(QColor background) {
 | |
| 	const auto hue = background.hueF();
 | |
| 	const auto saturation = background.saturationF();
 | |
| 	const auto value = background.valueF();
 | |
| 	return QColor::fromHsvF(
 | |
| 		hue,
 | |
| 		std::min(1.0, saturation + 0.05 + 0.1 * (1. - saturation)),
 | |
| 		(value > 0.5
 | |
| 			? std::max(0., value * 0.65)
 | |
| 			: std::max(0., std::min(1., 1. - value * 0.65))),
 | |
| 		0.4
 | |
| 	).toRgb();
 | |
| }
 | |
| 
 | |
| QImage PreparePatternImage(
 | |
| 		QImage image,
 | |
| 		QColor bg,
 | |
| 		QColor fg,
 | |
| 		int intensity) {
 | |
| 	if (image.format() != QImage::Format_ARGB32_Premultiplied) {
 | |
| 		image = std::move(image).convertToFormat(
 | |
| 			QImage::Format_ARGB32_Premultiplied);
 | |
| 	}
 | |
| 	// Similar to ColorizePattern.
 | |
| 	// But here we set bg to all 'alpha=0' pixels and fg to opaque ones.
 | |
| 
 | |
| 	const auto width = image.width();
 | |
| 	const auto height = image.height();
 | |
| 	const auto alpha = anim::interpolate(
 | |
| 		0,
 | |
| 		255,
 | |
| 		fg.alphaF() * std::clamp(intensity / 100., 0., 1.));
 | |
| 	if (!alpha) {
 | |
| 		image.fill(bg);
 | |
| 		return image;
 | |
| 	}
 | |
| 	fg.setAlpha(255);
 | |
| 	const auto patternBg = anim::shifted(bg);
 | |
| 	const auto patternFg = anim::shifted(fg);
 | |
| 
 | |
| 	constexpr auto resultIntsPerPixel = 1;
 | |
| 	const auto resultIntsPerLine = (image.bytesPerLine() >> 2);
 | |
| 	const auto resultIntsAdded = resultIntsPerLine - width * resultIntsPerPixel;
 | |
| 	auto resultInts = reinterpret_cast<uint32*>(image.bits());
 | |
| 	Assert(resultIntsAdded >= 0);
 | |
| 	Assert(image.depth() == static_cast<int>((resultIntsPerPixel * sizeof(uint32)) << 3));
 | |
| 	Assert(image.bytesPerLine() == (resultIntsPerLine << 2));
 | |
| 
 | |
| 	const auto maskBytesPerPixel = (image.depth() >> 3);
 | |
| 	const auto maskBytesPerLine = image.bytesPerLine();
 | |
| 	const auto maskBytesAdded = maskBytesPerLine - width * maskBytesPerPixel;
 | |
| 
 | |
| 	// We want to read the last byte of four available.
 | |
| 	// This is the difference with style::colorizeImage.
 | |
| 	auto maskBytes = image.constBits() + (maskBytesPerPixel - 1);
 | |
| 	Assert(maskBytesAdded >= 0);
 | |
| 	Assert(image.depth() == (maskBytesPerPixel << 3));
 | |
| 	for (auto y = 0; y != height; ++y) {
 | |
| 		for (auto x = 0; x != width; ++x) {
 | |
| 			const auto maskOpacity = static_cast<anim::ShiftedMultiplier>(
 | |
| 				*maskBytes) + 1;
 | |
| 			const auto fgOpacity = (maskOpacity * alpha) >> 8;
 | |
| 			const auto bgOpacity = 256 - fgOpacity;
 | |
| 			*resultInts = anim::unshifted(
 | |
| 				patternBg * bgOpacity + patternFg * fgOpacity);
 | |
| 			maskBytes += maskBytesPerPixel;
 | |
| 			resultInts += resultIntsPerPixel;
 | |
| 		}
 | |
| 		maskBytes += maskBytesAdded;
 | |
| 		resultInts += resultIntsAdded;
 | |
| 	}
 | |
| 	return image;
 | |
| }
 | |
| 
 | |
| QImage PrepareBlurredBackground(QImage image) {
 | |
| 	constexpr auto kSize = 900;
 | |
| 	constexpr auto kRadius = 24;
 | |
| 	if (image.width() > kSize || image.height() > kSize) {
 | |
| 		image = image.scaled(
 | |
| 			kSize,
 | |
| 			kSize,
 | |
| 			Qt::KeepAspectRatio,
 | |
| 			Qt::SmoothTransformation);
 | |
| 	}
 | |
| 	return Images::BlurLargeImage(image, kRadius);
 | |
| }
 | |
| 
 | |
| namespace details {
 | |
| 
 | |
| WallPaper UninitializedWallPaper() {
 | |
| 	return WallPaper(kUninitializedBackground);
 | |
| }
 | |
| 
 | |
| bool IsUninitializedWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() == kUninitializedBackground);
 | |
| }
 | |
| 
 | |
| WallPaper TestingThemeWallPaper() {
 | |
| 	return WallPaper(kTestingThemeBackground);
 | |
| }
 | |
| 
 | |
| bool IsTestingThemeWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() == kTestingThemeBackground);
 | |
| }
 | |
| 
 | |
| WallPaper TestingDefaultWallPaper() {
 | |
| 	return WallPaper(kTestingDefaultBackground);
 | |
| }
 | |
| 
 | |
| bool IsTestingDefaultWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() == kTestingDefaultBackground);
 | |
| }
 | |
| 
 | |
| WallPaper TestingEditorWallPaper() {
 | |
| 	return WallPaper(kTestingEditorBackground);
 | |
| }
 | |
| 
 | |
| bool IsTestingEditorWallPaper(const WallPaper &paper) {
 | |
| 	return (paper.id() == kTestingEditorBackground);
 | |
| }
 | |
| 
 | |
| } // namespace details
 | |
| } // namespace Data
 |