diff --git a/plugins/platformtheme/theme.cpp b/plugins/platformtheme/theme.cpp index 3302ac477e5fddac622a74fb9e1c900642766d05..35830f8fa6b096936871556731ce823352a24771 100644 --- a/plugins/platformtheme/theme.cpp +++ b/plugins/platformtheme/theme.cpp @@ -38,6 +38,7 @@ #include "plugins/platformtheme/themed-icon-engine.h" #define THEMED_SVG_ICON_PREFIX "ksvg-" +#define THEMED_RSVG_ICON_PREFIX "krsvg-" namespace Kiran { @@ -66,10 +67,17 @@ QPlatformDialogHelper* Theme::createPlatformDialogHelper(QPlatformTheme::DialogT QIconEngine* Theme::createIconEngine(const QString& iconName) const { - // 针对特定图标前缀的svg,跟随主题变化, 目前只支持单色图标 - if (iconName.startsWith(THEMED_SVG_ICON_PREFIX) && ThemedIconEngine::isValid(iconName)) + if (ThemedIconEngine::isValid(iconName)) { - return new ThemedIconEngine(iconName); + // 针对特定图标前缀的svg,跟随主题变化 + if (iconName.startsWith(THEMED_SVG_ICON_PREFIX)) + { + return new ThemedIconEngine(iconName, ThemedIconEngine::SVG_CONVERT_COMPOSITION); + } + else if (iconName.startsWith(THEMED_RSVG_ICON_PREFIX)) + { + return new ThemedIconEngine(iconName, ThemedIconEngine::SVG_CONVERT_INVERT_PIXELS); + } } return QGenericUnixTheme::createIconEngine(iconName); } diff --git a/plugins/platformtheme/themed-icon-engine.cpp b/plugins/platformtheme/themed-icon-engine.cpp index c22f4c45295c8bed17239aaa1ceb6a1ec9c0a5b1..4d61344956a4715de4babe4d38d2971f34802457 100644 --- a/plugins/platformtheme/themed-icon-engine.cpp +++ b/plugins/platformtheme/themed-icon-engine.cpp @@ -27,14 +27,14 @@ namespace Kiran { namespace Platformtheme { -ThemedIconEngine::ThemedIconEngine(const QString &themeSvgIconName) +ThemedIconEngine::ThemedIconEngine(const QString &themeSvgIconName, const SvgConvertType type) : QIconEngine(), - m_iconName(themeSvgIconName) + m_iconName(themeSvgIconName), + m_svgConvertType(type) { m_settingsMonitor = Kiran::Platformtheme::AppearanceMonitor::instance(); - QObject::connect(m_settingsMonitor, &Kiran::Platformtheme::AppearanceMonitor::gtkThemeChanged, [this](){ - changeSvgIconColor(); - }); + QObject::connect(m_settingsMonitor, &Kiran::Platformtheme::AppearanceMonitor::gtkThemeChanged, [this]() + { changeSvgIconColor(); }); } ThemedIconEngine::~ThemedIconEngine() = default; @@ -76,7 +76,9 @@ QPixmap ThemedIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::Sta } QSvgRenderer renderer(m_svgIconPath); - auto actualSize = renderer.defaultSize(); + // 设置为图标大小,防止原图像过大导致经img反转像素后图片过大 + auto actualSize = size; + QImage img(actualSize, QImage::Format_ARGB32_Premultiplied); img.fill(0x00000000); @@ -86,9 +88,19 @@ QPixmap ThemedIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::Sta // Selected 状态下保持本色 if (mode != QIcon::Selected) { - m_svgColor = Kiran::Theme::Palette::getDefault()->getBaseColors().baseForeground; - p.setCompositionMode(QPainter::CompositionMode_SourceIn); - p.fillRect(QRect(0, 0, actualSize.width(), actualSize.height()), m_svgColor); + if (m_svgConvertType == SvgConvertType::SVG_CONVERT_COMPOSITION) + { + m_svgColor = Kiran::Theme::Palette::getDefault()->getBaseColors().baseForeground; + p.setCompositionMode(QPainter::CompositionMode_SourceIn); + p.fillRect(QRect(0, 0, actualSize.width(), actualSize.height()), m_svgColor); + } + else if (m_svgConvertType == SvgConvertType::SVG_CONVERT_INVERT_PIXELS) + { + if (!m_settingsMonitor->gtkTheme().contains("dark")) + { + img.invertPixels(QImage::InvertRgb); + } + } } p.end(); @@ -110,7 +122,7 @@ void ThemedIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode m pixmapSize *= painter->device()->devicePixelRatioF(); } - painter->drawPixmap(rect, pixmap(pixmapSize,mode,state)); + painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); } QIconEngine *ThemedIconEngine::clone() const @@ -180,13 +192,13 @@ void ThemedIconEngine::virtual_hook(int id, void *data) break; case QIconEngine::IsNullHook: { - *reinterpret_cast(data) = m_svgIconPath.isEmpty(); + *reinterpret_cast(data) = m_svgIconPath.isEmpty(); } break; default: QIconEngine::virtual_hook(id, data); } -} +} void ThemedIconEngine::changeSvgIconColor() { @@ -195,7 +207,7 @@ void ThemedIconEngine::changeSvgIconColor() // 通知所有窗口重绘制 QEvent update(QEvent::UpdateRequest); - for (QWindow* window : qGuiApp->allWindows()) + for (QWindow *window : qGuiApp->allWindows()) { if (window->type() == Qt::Desktop) continue; diff --git a/plugins/platformtheme/themed-icon-engine.h b/plugins/platformtheme/themed-icon-engine.h index 6ac5d49012966741b1ae4bd469c1540bb6cb1776..0c1a735ef69d565c0db133be53415f9d6ca3b6e8 100644 --- a/plugins/platformtheme/themed-icon-engine.h +++ b/plugins/platformtheme/themed-icon-engine.h @@ -14,10 +14,10 @@ #pragma once #include -#include +#include #include +#include #include -#include #include "lib/theme/palette.h" #include "plugins/platformtheme/appearance-monitor.h" @@ -25,13 +25,20 @@ namespace Kiran { namespace Platformtheme { -class ThemedIconEngine:public QIconEngine +class ThemedIconEngine : public QIconEngine { public: - explicit ThemedIconEngine(const QString& themeSvgIconName); + enum SvgConvertType + { + SVG_CONVERT_COMPOSITION, /** < 合成模式 */ + SVG_CONVERT_INVERT_PIXELS /** < 像素反转 */ + }; + +public: + explicit ThemedIconEngine(const QString &themeSvgIconName, const SvgConvertType type); ~ThemedIconEngine() override; - static bool isValid(const QString& themeSvgIconName); + static bool isValid(const QString &themeSvgIconName); QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) override; QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override; void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override; @@ -39,10 +46,10 @@ public: private: QByteArray pixmapCacheKey(const QSize &size, QIcon::Mode mode, QIcon::State state); - static QStringList getScalableSvgIconFromTheme(const QString& iconName); + static QStringList getScalableSvgIconFromTheme(const QString &iconName); void ensureLoaded(); - void virtual_hook(int id, void *data) override; - + void virtual_hook(int id, void *data) override; + private slots: void changeSvgIconColor(); @@ -54,7 +61,9 @@ private: QMap m_pixmapCache; uint m_iconLoaderThemeKey = 0; - Platformtheme::AppearanceMonitor* m_settingsMonitor; + Platformtheme::AppearanceMonitor *m_settingsMonitor; + + SvgConvertType m_svgConvertType; }; } // namespace Platformtheme } // namespace Kiran