diff options
author | Petr Mrázek <peterix@gmail.com> | 2013-03-20 07:59:35 +0100 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2013-03-20 07:59:35 +0100 |
commit | e4806ab08d0293d395c1718ab16d28ba2ae9d0ed (patch) | |
tree | d4a2a79461fb4215f556d9c08f93ba451f862560 /gui/iconcache.cpp | |
parent | 7d7e4034f48b578c87a4651075c2b73dc236181b (diff) | |
download | MultiMC-e4806ab08d0293d395c1718ab16d28ba2ae9d0ed.tar MultiMC-e4806ab08d0293d395c1718ab16d28ba2ae9d0ed.tar.gz MultiMC-e4806ab08d0293d395c1718ab16d28ba2ae9d0ed.tar.lz MultiMC-e4806ab08d0293d395c1718ab16d28ba2ae9d0ed.tar.xz MultiMC-e4806ab08d0293d395c1718ab16d28ba2ae9d0ed.zip |
Add SVG icon rendering/cache
Diffstat (limited to 'gui/iconcache.cpp')
-rw-r--r-- | gui/iconcache.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/gui/iconcache.cpp b/gui/iconcache.cpp new file mode 100644 index 00000000..520a7839 --- /dev/null +++ b/gui/iconcache.cpp @@ -0,0 +1,127 @@ +#include "iconcache.h" +#include <QMap> +#include <QWebView> +#include <QWebFrame> +#include <QEventLoop> +#include <QWebElement> + +IconCache* IconCache::m_Instance = 0; +QMutex IconCache::mutex; +#define MAX_SIZE 1024 + +class Private : public QWebView +{ + Q_OBJECT + +public: + QString name; + QSize size; + QMap<QString, QIcon> icons; + +public: + Private() + { + connect(this, SIGNAL(loadFinished(bool)), this, SLOT(svgLoaded(bool))); + setFixedSize(MAX_SIZE, MAX_SIZE); + + QPalette pal = palette(); + pal.setColor(QPalette::Base, Qt::transparent); + setPalette(pal); + setAttribute(Qt::WA_OpaquePaintEvent, false); + size = QSize(128,128); + } + void renderSVGIcon(QString name); + +signals: + void svgRendered(); + +private slots: + void svgLoaded(bool ok); +}; + +void Private::svgLoaded(bool ok) +{ + if (!ok) + { + emit svgRendered(); + return; + } + // check for SVG root tag + QString root = page()->currentFrame()->documentElement().tagName(); + if (root.compare("svg", Qt::CaseInsensitive) != 0) + { + emit svgRendered(); + return; + } + + // get the size of the svg image, check if it's valid + auto elem = page()->currentFrame()->documentElement(); + double width = elem.attribute("width").toDouble(); + double height = elem.attribute("height").toDouble(); + if (width == 0.0 || height == 0.0 || width == MAX_SIZE || height == MAX_SIZE) + { + emit svgRendered(); + return; + } + + // create the target surface + QSize t = size.isValid() ? size : QSize(width, height); + QImage img(t, QImage::Format_ARGB32_Premultiplied); + img.fill(Qt::transparent); + + // prepare the painter, scale to required size + QPainter p(&img); + if(size.isValid()) + { + p.scale(size.width() / width, size.height() / height); + } + + // the best quality + p.setRenderHint(QPainter::Antialiasing); + p.setRenderHint(QPainter::TextAntialiasing); + p.setRenderHint(QPainter::SmoothPixmapTransform); + + page()->mainFrame()->render(&p,QWebFrame::ContentsLayer); + p.end(); + + icons[name] = QIcon(QPixmap::fromImage(img)); + emit svgRendered(); +} + +void Private::renderSVGIcon ( QString name ) +{ + // use event loop to wait for signal + QEventLoop loop; + this->name = name; + QString prefix = "qrc:/icons/instances/"; + QObject::connect(this, SIGNAL(svgRendered()), &loop, SLOT(quit())); + load(QUrl(prefix + name)); + loop.exec(); +} + +IconCache::IconCache():d(new Private()) +{ +} + +QIcon IconCache::getIcon ( QString name ) +{ + if(name == "default") + name = "infinity"; + { + auto iter = d->icons.find(name); + if(iter != d->icons.end()) + return *iter; + } + d->renderSVGIcon(name); + auto iter = d->icons.find(name); + if(iter != d->icons.end()) + return *iter; + + // Fallback for icons that don't exist. + QString path = ":/icons/instances/infinity"; + //path += name; + d->icons[name] = QIcon(path); + return d->icons[name]; +} + +#include "iconcache.moc"
\ No newline at end of file |