iconutils.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include "iconutils.h"
  2. #include <QRegExp>
  3. #include <QFileInfo>
  4. #include <QPixmap>
  5. #include <QPainter>
  6. #include <QDebug>
  7. #include "fileutils.h"
  8. using namespace vnotex;
  9. QString IconUtils::s_defaultIconForeground;
  10. QString IconUtils::s_defaultIconDisabledForeground;
  11. QIcon IconUtils::fetchIcon(const QString &p_iconFile,
  12. const QVector<OverriddenColor> &p_overriddenColors,
  13. qreal p_angle)
  14. {
  15. const auto suffix = QFileInfo(p_iconFile).suffix().toLower().toStdString();
  16. if (p_overriddenColors.isEmpty() || suffix != "svg") {
  17. return QIcon(p_iconFile);
  18. }
  19. auto content = FileUtils::readTextFile(p_iconFile);
  20. if (content.isEmpty()) {
  21. return QIcon();
  22. }
  23. QIcon icon;
  24. for (const auto &color : p_overriddenColors) {
  25. auto overriddenContent = replaceForegroundOfIcon(content, color.m_foreground);
  26. auto data = overriddenContent.toLocal8Bit();
  27. QPixmap pixmap;
  28. pixmap.loadFromData(data, suffix.c_str());
  29. if (p_angle > 0) {
  30. pixmap = pixmap.transformed(QTransform().rotate(p_angle));
  31. }
  32. icon.addPixmap(pixmap, color.m_mode, color.m_state);
  33. }
  34. return icon;
  35. }
  36. QIcon IconUtils::fetchIcon(const QString &p_iconFile, const QString &p_overriddenForeground)
  37. {
  38. QVector<OverriddenColor> colors;
  39. if (!p_overriddenForeground.isEmpty()) {
  40. colors.push_back(OverriddenColor(p_overriddenForeground, QIcon::Normal, QIcon::Off));
  41. }
  42. return fetchIcon(p_iconFile, colors);
  43. }
  44. QString IconUtils::replaceForegroundOfIcon(const QString &p_iconContent, const QString &p_foreground)
  45. {
  46. if (p_foreground.isEmpty()) {
  47. return p_iconContent;
  48. }
  49. // Negative lookahead to avoid fill="none".
  50. QRegExp styleRe(R"((\s|"|;)(fill|stroke)(:|(="))(?!none)[^;"]*)");
  51. if (p_iconContent.indexOf(styleRe) > -1) {
  52. auto newContent(p_iconContent);
  53. newContent.replace(styleRe, QString("\\1\\2\\3%1").arg(p_foreground));
  54. return newContent;
  55. }
  56. return p_iconContent;
  57. }
  58. QIcon IconUtils::fetchIcon(const QString &p_iconFile)
  59. {
  60. return fetchIcon(p_iconFile, s_defaultIconForeground);
  61. }
  62. void IconUtils::setDefaultIconForeground(const QString &p_fg, const QString &p_disabledFg)
  63. {
  64. s_defaultIconForeground = p_fg;
  65. s_defaultIconDisabledForeground = p_disabledFg;
  66. }
  67. QIcon IconUtils::fetchIconWithDisabledState(const QString &p_iconFile)
  68. {
  69. QVector<OverriddenColor> colors;
  70. colors.push_back(OverriddenColor(s_defaultIconForeground, QIcon::Normal, QIcon::Off));
  71. colors.push_back(OverriddenColor(s_defaultIconDisabledForeground, QIcon::Disabled, QIcon::Off));
  72. return fetchIcon(p_iconFile, colors);
  73. }
  74. QIcon IconUtils::drawTextIcon(const QString &p_text,
  75. const QString &p_fg,
  76. const QString &p_border)
  77. {
  78. const int wid = 64;
  79. QPixmap pixmap(wid, wid);
  80. pixmap.fill(Qt::transparent);
  81. QPainter painter(&pixmap);
  82. painter.setRenderHint(QPainter::Antialiasing);
  83. auto pen = painter.pen();
  84. pen.setColor(p_border);
  85. pen.setWidth(3);
  86. painter.setPen(pen);
  87. painter.drawRoundedRect(4, 4, wid - 8, wid - 8, 8, 8);
  88. if (!p_text.isEmpty()) {
  89. pen.setColor(p_fg);
  90. painter.setPen(pen);
  91. auto font = painter.font();
  92. font.setPointSize(36);
  93. painter.setFont(font);
  94. auto requriedRect = painter.boundingRect(4, 4, wid - 8, wid - 8,
  95. Qt::AlignCenter,
  96. p_text);
  97. painter.drawText(requriedRect, p_text);
  98. }
  99. QIcon icon;
  100. icon.addPixmap(pixmap);
  101. return icon;
  102. }