int KGameRenderer::frameCount(const QString& key) const { //ensure that some theme is loaded if (!d->m_currentTheme) { d->_k_setTheme(d->m_provider->currentTheme()); } //look up in in-process cache QHash<QString, int>::const_iterator it = d->m_frameCountCache.constFind(key); if (it != d->m_frameCountCache.constEnd()) { return it.value(); } //look up in shared cache (if SVG is not yet loaded) int count = -1; bool countFound = false; const QString cacheKey = d->m_frameCountPrefix + key; if (d->m_rendererPool.hasAvailableRenderers() && (d->m_strategies & KGameRenderer::UseDiskCache)) { QByteArray buffer; if (d->m_imageCache->find(cacheKey, &buffer)) { count = buffer.toInt(); countFound = true; } } //determine from SVG if (!countFound) { QSvgRenderer* renderer = d->m_rendererPool.allocRenderer(); //look for animated sprite first count = d->m_frameBaseIndex; while (renderer->elementExists(d->spriteFrameKey(key, count, false))) { ++count; } count -= d->m_frameBaseIndex; //look for non-animated sprite instead if (count == 0) { if (!renderer->elementExists(key)) { count = -1; } } d->m_rendererPool.freeRenderer(renderer); //save in shared cache for following requests if (d->m_strategies & KGameRenderer::UseDiskCache) { d->m_imageCache->insert(cacheKey, QByteArray::number(count)); } } d->m_frameCountCache.insert(key, count); return count; }
ElementVariationList elementsWithSizes(const QString &elementBase) { ElementVariationList result; QSvgRenderer *renderer = designRenderer(); ElementVariations element; element.widthToHeightRatio = -1; for (int i = 1; ; i++) { const QString id = elementBase + QLatin1Char('_') + QString::number(i); if (!renderer->elementExists(idPrefix + id)) break; const QSizeF size = renderer->boundsOnElement(idPrefix + id).size(); const qreal widthToHeightRatio = size.width() / size.height(); if (!qFuzzyCompare(widthToHeightRatio, element.widthToHeightRatio)) { if (element.widthToHeightRatio > 0) // Check, is it is the first element result.append(element); element.widthToHeightRatio = widthToHeightRatio; element.elementIds.clear(); } element.elementIds.append(id); } if (!element.elementIds.isEmpty()) result.append(element); qSort(result); return result; }
void B9Edit::importSlicesFromSvg(QString file, double pixelsizemicrons) { int layers = 0; double xsizemm = 0.0; double ysizemm = 0.0; double x = 0; double y = 0; bool inverted = false; QSvgRenderer SvgRender; if(!SvgRender.load(file)) { QMessageBox msgBox; msgBox.setText("Unable to import SVG file."); msgBox.exec(); return; } if(!SvgRender.elementExists("layer0")) { QMessageBox msgBox; msgBox.setText("SVG file does not contain compatible layer information\nUnable to import."); msgBox.exec(); return; } //do a quick search for the word "slic3r:type="contour"" and then the following "style="fill:" //to figure out whether the image is inverted or not. QString buff = ""; QFile searchfile(file); searchfile.open(QIODevice::ReadOnly); QTextStream searchstream(&searchfile); while(buff != "slic3r:type=\"contour\"" && !searchstream.atEnd()) { searchstream >> buff; } if(!searchstream.atEnd())//we must have found it. { while(buff != "style=\"fill:" && !searchstream.atEnd()) { searchstream >> buff; } if(!searchstream.atEnd()) { searchstream >> buff; if(buff == "white\"") { inverted = false; } else { inverted = true; } } else {
QImage SvgElementProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize) { // Resolve URL QUrl url = QUrl(id); if (url.isRelative() && !mBaseUrl.isEmpty()) url = mBaseUrl.resolved(url); if (!url.isValid()) return placeholder(QString("Invalid URL\nBase: %1\nInput: %2").arg(mBaseUrl.toString()).arg(id), requestedSize); // Make a filename from the given URL QString imagepath = QQmlFile::urlToLocalFileOrQrc(url); // Fragment is used to specify SVG element QString elementId = url.fragment(); // Load image QSvgRenderer renderer; if (!renderer.load(imagepath)) { qWarning() << "Unable to load image:" << imagepath; return placeholder(QStringLiteral("Unable to load image:\n") + imagepath, requestedSize); } // Check whether requested element exists if (!elementId.isEmpty() && !renderer.elementExists(elementId)) return placeholder(QStringLiteral("Unable to find element:\n") + elementId + "\nin image:\n" + imagepath, requestedSize); // Get image or element size QSize itemSize = elementId.isEmpty() ? renderer.defaultSize() : renderer.boundsOnElement(elementId).size().toSize(); if (size) *size = itemSize; // Create image QImage image(requestedSize.width() > 0 ? requestedSize.width() : itemSize.width(), requestedSize.height() > 0 ? requestedSize.height() : itemSize.height(), QImage::Format_ARGB32_Premultiplied); image.fill(Qt::transparent); // Paint svg or element QPainter p(&image); if (elementId.isEmpty()) renderer.render(&p); else renderer.render(&p, elementId); return image; }
inline static QImage clock(int hour, int minute, int variation, QSize *size, const QSize &requestedSize) { QSvgRenderer *renderer = clocksRenderer(); const static QString clockBackgroundString = QStringLiteral("background"); const static int variationsCnt = variationsCount(renderer, clockBackgroundString); const int actualVariation = (variation % variationsCnt) + 1; const QString variationNumber = QLatin1Char('_') + QString::number(actualVariation); const QString backgroundElementId = clockBackgroundString + variationNumber; const QRectF backgroundRect = renderer->boundsOnElement(idPrefix + backgroundElementId); QSize resultSize = backgroundRect.size().toSize(); if (size) *size = resultSize; resultSize.scale(requestedSize, Qt::KeepAspectRatio); QImage result(resultSize, QImage::Format_ARGB32); if (result.isNull()) qDebug() << Q_FUNC_INFO << "clock image is NULL! Variation:" << variation; result.fill(Qt::transparent); QPainter p(&result); const qreal scaleFactor = resultSize.width() / backgroundRect.width(); QTransform mainTransform; mainTransform .scale(scaleFactor, scaleFactor) .translate(-backgroundRect.left(), -backgroundRect.top()); p.setTransform(mainTransform); renderer->render(&p, idPrefix + backgroundElementId, backgroundRect); const int minuteRotation = (minute * 6) % 360; renderIndicator(QStringLiteral("minute") + variationNumber, minuteRotation, backgroundRect, scaleFactor, renderer, &p); const int hoursSkew = 6; // Initial position of hour in the SVG is 6 renderIndicator(QStringLiteral("hour") + variationNumber, (((hour + hoursSkew) * 360 + minuteRotation) / 12) % 360, backgroundRect, scaleFactor, renderer, &p); const QString foregroundElementId = QStringLiteral("foreground") + variationNumber; if (renderer->elementExists(idPrefix + foregroundElementId)) { p.setTransform(mainTransform); renderer->render(&p, idPrefix + foregroundElementId, renderer->boundsOnElement(idPrefix + foregroundElementId)); } return result; }
/*! \fn SvgImageProvider::scaledElementBounds(const QString &svgFile, const QString &element) Returns the bound of \a element in logical coordinates, scalled to the default size of svg document (so the bounds of whole doc would be (0,0,1,1) ). */ QRectF SvgImageProvider::scaledElementBounds(const QString &svgFile, const QString &elementName) { QSvgRenderer *renderer = loadRenderer(svgFile); if (!renderer) return QRectF(); if (!renderer->elementExists(elementName)) { qWarning() << "invalid element:" << elementName << "of" << svgFile; return QRectF(); } QRectF elementBounds = renderer->boundsOnElement(elementName); QMatrix matrix = renderer->matrixForElement(elementName); elementBounds = matrix.mapRect(elementBounds); QSize docSize = renderer->defaultSize(); return QRectF(elementBounds.x()/docSize.width(), elementBounds.y()/docSize.height(), elementBounds.width()/docSize.width(), elementBounds.height()/docSize.height()); }
QPixmap loadStamp( const QString& _name, const QSize& size, int iconSize ) { const QString name = _name.toLower(); QSvgRenderer * r = 0; if ( ( r = s_data->svgStamps() ) && r->elementExists( name ) ) { const QRectF stampElemRect = r->boundsOnElement( name ); const QRectF stampRect( size.isValid() ? QRectF( QPointF( 0, 0 ), size ) : stampElemRect ); QPixmap pixmap( stampRect.size().toSize() ); pixmap.fill( Qt::transparent ); QPainter p( &pixmap ); r->render( &p, name ); p.end(); return pixmap; } QPixmap pixmap; const KIconLoader * il = iconLoader(); QString path; const int minSize = iconSize > 0 ? iconSize : qMin( size.width(), size.height() ); pixmap = il->loadIcon( name, KIconLoader::User, minSize, KIconLoader::DefaultState, QStringList(), &path, true ); if ( path.isEmpty() ) pixmap = il->loadIcon( name, KIconLoader::NoGroup, minSize ); return pixmap; }
MonitorWidget::MonitorWidget(QWidget *parent) : QGraphicsView(parent), aspectRatioMode(Qt::KeepAspectRatio) { setMinimumSize(180, 25); QGraphicsScene *scene = new QGraphicsScene(); setScene(scene); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); // no scroll bars setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setBackgroundBrush(QBrush(Utils::StyleHelper::baseColor())); setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); QSvgRenderer *renderer = new QSvgRenderer(); if (renderer->load(QString(":/telemetry/images/tx-rx.svg"))) { // create graph graph = new QGraphicsSvgItem(); graph->setSharedRenderer(renderer); graph->setElementId("background"); graph->setFlags(QGraphicsItem::ItemClipsChildrenToShape | QGraphicsItem::ItemClipsToShape); scene->addItem(graph); int i; // create tx nodes i = 0; while (true) { QString id = QString("tx%0").arg(i); QString bgId = QString("tx_bg%0").arg(i); if (!renderer->elementExists(id) || !renderer->elementExists(bgId)) { break; } QGraphicsSvgItem *item = createSvgItem(graph, bgId); item->setElementId(id); txNodes.append(item); i++; } // create rx nodes i = 0; while (true) { QString id = QString("rx%0").arg(i); QString bgId = QString("rx_bg%0").arg(i); if (!renderer->elementExists(id) || !renderer->elementExists(bgId)) { break; } QGraphicsSvgItem *item = createSvgItem(graph, bgId); item->setElementId(id); rxNodes.append(item); i++; } if (renderer->elementExists("txSpeed")) { txSpeed = createTextItem(graph, "txSpeed", "Helvetica"); txSpeed->setDefaultTextColor(Qt::white); } else { txSpeed = NULL; } if (renderer->elementExists("rxSpeed")) { rxSpeed = createTextItem(graph, "rxSpeed", "Helvetica"); rxSpeed->setDefaultTextColor(Qt::white); } else { rxSpeed = NULL; } // scene->setSceneRect(graph->boundingRect()); } connected = false; setMin(0.0); setMax(1200.0); telemetryUpdated(0.0, 0.0); }
TelemetryMonitorWidget::TelemetryMonitorWidget(QWidget *parent) : QGraphicsView(parent) { setMinimumSize(180,100); setMaximumSize(180,100); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setAlignment(Qt::AlignCenter); setFrameStyle(QFrame::NoFrame); setStyleSheet("background:transparent;"); setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(Qt::FramelessWindowHint); QGraphicsScene *scene = new QGraphicsScene(0,0,180,100, this); QSvgRenderer *renderer = new QSvgRenderer(); if (renderer->load(QString(":/core/images/tx-rx.svg"))) { graph = new QGraphicsSvgItem(); graph->setSharedRenderer(renderer); graph->setElementId("txrxBackground"); QString name; QGraphicsSvgItem* pt; for (int i=0; i<NODE_NUMELEM; i++) { name = QString("tx%0").arg(i); if (renderer->elementExists(name)) { pt = new QGraphicsSvgItem(); pt->setSharedRenderer(renderer); pt->setElementId(name); pt->setParentItem(graph); txNodes.append(pt); } name = QString("rx%0").arg(i); if (renderer->elementExists(name)) { pt = new QGraphicsSvgItem(); pt->setSharedRenderer(renderer); pt->setElementId(name); pt->setParentItem(graph); rxNodes.append(pt); } } scene->addItem(graph); txSpeed = new QGraphicsTextItem(); txSpeed->setDefaultTextColor(Qt::white); txSpeed->setFont(QFont("Helvetica",22,2)); txSpeed->setParentItem(graph); scene->addItem(txSpeed); rxSpeed = new QGraphicsTextItem(); rxSpeed->setDefaultTextColor(Qt::white); rxSpeed->setFont(QFont("Helvetica",22,2)); rxSpeed->setParentItem(graph); scene->addItem(rxSpeed); scene->setSceneRect(graph->boundingRect()); setScene(scene); } connected = false; txValue = 0.0; rxValue = 0.0; setMin(0.0); setMax(1200.0); showTelemetry(); }
/** Supported id format: fileName[!elementName[?parameters]] where parameters may be: vslice=1:2;hslice=2:4 - use the 3rd horizontal slice of total 4 slices, slice numbering starts from 0 borders=1 - 1 pixel wide transparent border requestedSize is related to the whole element size, even if slice is requested. usage: Image { source: "image://svg/pfd.svg!world" } */ QImage SvgImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) { QString svgFile = id; QString element; QString parameters; int separatorPos = id.indexOf('!'); if (separatorPos != -1) { svgFile = id.left(separatorPos); element = id.mid(separatorPos+1); } int parametersPos = element.indexOf('?'); if (parametersPos != -1) { parameters = element.mid(parametersPos+1); element = element.left(parametersPos); } int hSlicesCount = 0; int hSlice = 0; int vSlicesCount = 0; int vSlice = 0; int border = 0; if (!parameters.isEmpty()) { QRegExp hSliceRx("hslice=(\\d+):(\\d+)"); if (hSliceRx.indexIn(parameters) != -1) { hSlice = hSliceRx.cap(1).toInt(); hSlicesCount = hSliceRx.cap(2).toInt(); } QRegExp vSliceRx("vslice=(\\d+):(\\d+)"); if (vSliceRx.indexIn(parameters) != -1) { vSlice = vSliceRx.cap(1).toInt(); vSlicesCount = vSliceRx.cap(2).toInt(); } QRegExp borderRx("border=(\\d+)"); if (borderRx.indexIn(parameters) != -1) { border = borderRx.cap(1).toInt(); } } if (size) *size = QSize(); QSvgRenderer *renderer = loadRenderer(svgFile); if (!renderer) return QImage(); qreal xScale = 1.0; qreal yScale = 1.0; QSize docSize = renderer->defaultSize(); if (!requestedSize.isEmpty()) { if (!element.isEmpty()) { QRectF elementBounds = renderer->boundsOnElement(element); xScale = qreal(requestedSize.width())/elementBounds.width(); yScale = qreal(requestedSize.height())/elementBounds.height(); } else if (!docSize.isEmpty()) { xScale = qreal(requestedSize.width())/docSize.width(); yScale = qreal(requestedSize.height())/docSize.height(); } } //keep the aspect ratio //TODO: how to configure it? as a part of image path? xScale = yScale = qMin(xScale, yScale); if (!element.isEmpty()) { if (!renderer->elementExists(element)) { qWarning() << "invalid element:" << element << "of" << svgFile; return QImage(); } QRectF elementBounds = renderer->boundsOnElement(element); int elementWidth = qRound(elementBounds.width() * xScale); int elementHeigh = qRound(elementBounds.height() * yScale); int w = elementWidth; int h = elementHeigh; int x = 0; int y = 0; if (hSlicesCount > 1) { x = (w*hSlice)/hSlicesCount; w = (w*(hSlice+1))/hSlicesCount - x; } if (vSlicesCount > 1) { y = (h*(vSlice))/vSlicesCount; h = (h*(vSlice+1))/vSlicesCount - y; } QImage img(w+border*2, h+border*2, QImage::Format_ARGB32_Premultiplied); img.fill(0); QPainter p(&img); p.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing | QPainter::SmoothPixmapTransform); p.translate(-x+border,-y+border); renderer->render(&p, element, QRectF(0, 0, elementWidth, elementHeigh)); if (size) *size = QSize(w, h); //img.save(element+parameters+".png"); return img; } else { //render the whole svg file int w = qRound(docSize.width() * xScale); int h = qRound(docSize.height() * yScale); QImage img(w, h, QImage::Format_ARGB32_Premultiplied); img.fill(0); QPainter p(&img); p.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing | QPainter::SmoothPixmapTransform); p.scale(xScale, yScale); renderer->render(&p, QRectF(QPointF(), QSizeF(docSize))); if (size) *size = QSize(w, h); return img; } }
/** requestedSize is realted to the whole svg file, not to specific element */ QImage SvgImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) { QString svgFile = id; QString element; int separatorPos = id.indexOf('!'); if (separatorPos != -1) { svgFile = id.left(separatorPos); element = id.mid(separatorPos+1); } if (size) *size = QSize(); QSvgRenderer *renderer = m_renderers.value(svgFile); if (!renderer) { renderer = new QSvgRenderer(svgFile); QString fn = QUrl::fromLocalFile(m_basePath).resolved(svgFile).toLocalFile(); //convert path to be relative to base if (!renderer->isValid()) renderer->load(fn); if (!renderer->isValid()) { qWarning() << "Failed to load svg file:" << svgFile << fn; return QImage(); } m_renderers.insert(svgFile, renderer); } qreal xScale = 1.0; qreal yScale = 1.0; QSize docSize = renderer->defaultSize(); if (!requestedSize.isEmpty() && !docSize.isEmpty()) { xScale = qreal(requestedSize.width())/docSize.width(); yScale = qreal(requestedSize.height())/docSize.height(); } //keep the aspect ratio //TODO: how to configure it? as a part of image path? xScale = yScale = qMin(xScale, yScale); if (!element.isEmpty()) { if (!renderer->elementExists(element)) { qWarning() << "invalid element:" << element << "of" << svgFile; return QImage(); } QRectF elementBounds = renderer->boundsOnElement(element); int w = qRound(elementBounds.width() * xScale); int h = qRound(elementBounds.height() * yScale); QImage img(w, h, QImage::Format_ARGB32_Premultiplied); img.fill(0); QPainter p(&img); renderer->render(&p, element); if (size) *size = QSize(w, h); return img; } else { //render the whole svg file int w = qRound(docSize.width() * xScale); int h = qRound(docSize.height() * yScale); QImage img(w, h, QImage::Format_ARGB32_Premultiplied); img.fill(0); QPainter p(&img); renderer->render(&p); if (size) *size = QSize(w, h); return img; } }
int heightOf(const QString & element, int value = 0) const { if (!svg->elementExists(element)) return value; return svg->boundsOnElement(element).height(); }
int widthOf(const QString & element, int value = 0) const { if (!svg->elementExists(element)) return value; return svg->boundsOnElement(element).width(); }