inline static QImage colorBlot(const QColor &color, int blotVariation, QSize *size, const QSize &requestedSize) { QSvgRenderer *renderer = designRenderer(); const static QString elementIdBase = QStringLiteral("colorblot"); const static int variationsCnt = variationsCount(renderer, elementIdBase); const int actualVariation = (blotVariation % variationsCnt) + 1; const QString elementId = elementIdBase + QLatin1Char('_') + QString::number(actualVariation); const QString maskElementId = elementId + QStringLiteral("_mask"); const QString highlightElementId = elementId + QStringLiteral("_highlight"); const QRectF backgroundRect = renderer->boundsOnElement(idPrefix + elementId); QSize resultSize = backgroundRect.size().toSize(); if (size) *size = resultSize; resultSize.scale(requestedSize, Qt::KeepAspectRatio); const qreal scaleFactor = resultSize.width() / backgroundRect.width(); QTransform transform = QTransform::fromScale(scaleFactor, scaleFactor); transform.translate(-backgroundRect.topLeft().x(), -backgroundRect.topLeft().y()); QImage result(resultSize, QImage::Format_ARGB32); if (result.isNull()) qDebug() << Q_FUNC_INFO << "clock image is NULL! Variation:" << blotVariation; result.fill(0); QPainter p(&result); p.setTransform(transform); renderer->render(&p, idPrefix + maskElementId, renderer->boundsOnElement(idPrefix + maskElementId)); p.save(); p.setCompositionMode(QPainter::CompositionMode_SourceIn); p.fillRect(backgroundRect, color); p.restore(); renderer->render(&p, idPrefix + highlightElementId, renderer->boundsOnElement(idPrefix + highlightElementId)); return result; }
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; }
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; }
QRectF minigis::svgRect(QSvgRenderer &render, const QString &cls, const QPointF &p, const qreal &svgSize) { QSizeF element = render.boundsOnElement(cls).size(); // типовой размер if (element.width() > element.height()) element = QSizeF(SVGsize, qreal(element.height() / element.width()) * SVGsize); else element = QSizeF(qreal(element.width() / element.height()) * SVGsize, SVGsize); QRectF rgn( p, element * svgSize ); return rgn; }
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 notes(const QStringList ¬es, QSize *size, const QSize &requestedSize) { QSvgRenderer *renderer = notesRenderer(); static const QString clefId = QStringLiteral("clef"); static const QRectF clefRect = renderer->boundsOnElement(idPrefix + clefId); static const QString staffLinesId = QStringLiteral("stafflines"); static const QRectF staffLinesOriginalRect = renderer->boundsOnElement(idPrefix + staffLinesId); static const qreal clefRightY = clefRect.right() - staffLinesOriginalRect.left(); static const qreal linesSpacePerNote = clefRect.width() * 1.75; const qreal linesSpaceForNotes = notes.count() * linesSpacePerNote; QRectF imageRect = staffLinesOriginalRect; imageRect.setWidth(clefRightY + linesSpaceForNotes); QSize resultSize = imageRect.size().toSize(); if (size) *size = resultSize; resultSize.scale(requestedSize, Qt::KeepAspectRatio); QImage result(resultSize, QImage::Format_ARGB32); if (result.isNull()) qDebug() << Q_FUNC_INFO << "notes image is NULL! Notes:" << notes; result.fill(Qt::transparent); QPainter p(&result); const qreal scaleFactor = resultSize.width() / imageRect.width(); p.scale(scaleFactor, scaleFactor); p.translate(-imageRect.topLeft()); renderer->render(&p, idPrefix + staffLinesId, imageRect); renderer->render(&p, idPrefix + clefId, clefRect); int currentNoteIndex = 0; foreach(const QString ¤tNote, notes) { const QString trimmedNote = currentNote.trimmed(); const QString note = trimmedNote.at(0).toLower(); const QString noteID = QStringLiteral("note_") + note; QRectF noteRect = renderer->boundsOnElement(idPrefix + noteID); const qreal noteCenterX = clefRightY + (currentNoteIndex + 0.125) * linesSpacePerNote + noteRect.width(); currentNoteIndex++; const qreal noteXTranslate = noteCenterX - noteRect.center().x(); noteRect.translate(noteXTranslate, 0); renderer->render(&p, idPrefix + noteID, noteRect); if (trimmedNote.length() > 1) { static const QString sharpId = QStringLiteral("sharp"); static const QString flatId = QStringLiteral("flat"); static const QRectF noteCHeadRect = renderer->boundsOnElement(idPrefix + QStringLiteral("note_c_head")); const bool sharp = trimmedNote.endsWith(QStringLiteral("sharp")); const QString ¬eSign = sharp ? sharpId : flatId; const QRectF noteHeadRect = renderer->boundsOnElement(idPrefix + QStringLiteral("note_") + note + QStringLiteral("_head")); const QRectF signRect = renderer->boundsOnElement(idPrefix + noteSign) .translated(noteXTranslate, 0) .translated(noteHeadRect.topLeft() - noteCHeadRect.topLeft()); renderer->render(&p, idPrefix + noteSign, signRect); } } return result; }
const QImage gradientImage(DesignElementType type) { QSvgRenderer *renderer = designRenderer(); const QString gradientId = idPrefix + (type == DesignElementTypeButton ? buttonString : frameString) + QStringLiteral("gradient"); Q_ASSERT(renderer->boundsOnElement(gradientId).size().toSize() == QSize(256, 1)); QImage result(256, 1, QImage::Format_ARGB32); result.fill(0); QPainter p(&result); renderer->render(&p, gradientId, result.rect()); #if 0 // for debugging p.fillRect(0, 0, 16, 1, Qt::red); p.fillRect(120, 0, 16, 1, Qt::green); p.fillRect(240, 0, 16, 1, Qt::blue); #endif return result; }
inline static QImage renderedLessonIcon(const QString &iconId, int buttonVariation, QSize *size, const QSize &requestedSize) { QImage result(requestedSize, QImage::Format_ARGB32); result.fill(Qt::transparent); QPainter p(&result); QSvgRenderer *renderer = lessonIconsRenderer(); const QRectF iconRectOriginal = renderer->boundsOnElement(idPrefix + iconId); QSizeF iconSize = iconRectOriginal.size(); iconSize.scale(requestedSize, Qt::KeepAspectRatio); QRectF iconRect(QPointF(), iconSize); if (requestedSize.height() > requestedSize.width()) iconRect.moveBottom(requestedSize.height()); else iconRect.moveTop((requestedSize.height() - iconSize.height()) / 2); renderer->render(&p, idPrefix + iconId, iconRect); const QImage button = renderedDesignElement(DesignElementTypeButton, buttonVariation, size, requestedSize); p.drawImage(QPointF(), button); 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; }
int heightOf(const QString & element, int value = 0) const { if (!svg->elementExists(element)) return value; return svg->boundsOnElement(element).height(); }
{ foreach( const KCardTheme & theme, m_themes ) { { QMutexLocker l( &m_haltMutex ); if ( m_haltFlag ) return; } QImage img( d->previewSize, QImage::Format_ARGB32 ); img.fill( Qt::transparent ); QPainter p( &img ); QSvgRenderer renderer( theme.graphicsFilePath() ); QSizeF size = renderer.boundsOnElement(QStringLiteral("back")).size(); size.scale( 1.5 * d->baseCardSize.width(), d->baseCardSize.height(), Qt::KeepAspectRatio ); qreal yPos = ( d->previewSize.height() - size.height() ) / 2; qreal spacingWidth = d->baseCardSize.width() * ( d->previewSize.width() - d->previewLayout.size() * size.width() ) / ( d->previewSize.width() - d->previewLayout.size() * d->baseCardSize.width() ); qreal xPos = 0; foreach ( const QList<QString> & pile, d->previewLayout ) { foreach ( const QString & card, pile ) { renderer.render( &p, card, QRectF( QPointF( xPos, yPos ), size ) ); xPos += 0.3 * spacingWidth; }
/** 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; } }
{ foreach( const KCardTheme & theme, m_themes ) { { QMutexLocker l( &m_haltMutex ); if ( m_haltFlag ) return; } QImage img( d->previewSize, QImage::Format_ARGB32 ); img.fill( Qt::transparent ); QPainter p( &img ); QSvgRenderer renderer( theme.graphicsFilePath() ); QSizeF size = renderer.boundsOnElement("back").size(); size.scale( 1.5 * d->baseCardSize.width(), d->baseCardSize.height(), Qt::KeepAspectRatio ); qreal yPos = ( d->previewSize.height() - size.height() ) / 2; qreal spacingWidth = d->baseCardSize.width() * ( d->previewSize.width() - d->previewLayout.size() * size.width() ) / ( d->previewSize.width() - d->previewLayout.size() * d->baseCardSize.width() ); qreal xPos = 0; foreach ( const QList<QString> & pile, d->previewLayout ) { foreach ( const QString & card, pile ) { renderer.render( &p, card, QRectF( QPointF( xPos, yPos ), size ) ); xPos += 0.3 * spacingWidth; }
ConfigAHRSWidget::ConfigAHRSWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_ahrs = new Ui_AHRSWidget(); m_ahrs->setupUi(this); // Initialization of the Paper plane widget m_ahrs->sixPointsHelp->setScene(new QGraphicsScene(this)); paperplane = new QGraphicsSvgItem(); paperplane->setSharedRenderer(new QSvgRenderer()); paperplane->renderer()->load(QString(":/configgadget/images/paper-plane.svg")); paperplane->setElementId("plane-horizontal"); m_ahrs->sixPointsHelp->scene()->addItem(paperplane); m_ahrs->sixPointsHelp->setSceneRect(paperplane->boundingRect()); // Initialization of the AHRS bargraph graph m_ahrs->ahrsBargraph->setScene(new QGraphicsScene(this)); QSvgRenderer *renderer = new QSvgRenderer(); ahrsbargraph = new QGraphicsSvgItem(); renderer->load(QString(":/configgadget/images/ahrs-calib.svg")); ahrsbargraph->setSharedRenderer(renderer); ahrsbargraph->setElementId("background"); ahrsbargraph->setObjectName("background"); m_ahrs->ahrsBargraph->scene()->addItem(ahrsbargraph); m_ahrs->ahrsBargraph->setSceneRect(ahrsbargraph->boundingRect()); // Initialize the 9 bargraph values: QMatrix lineMatrix = renderer->matrixForElement("accel_x"); QRectF rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_x")); qreal startX = rect.x(); qreal startY = rect.y()+ rect.height(); // maxBarHeight will be used for scaling it later. maxBarHeight = rect.height(); // Then once we have the initial location, we can put it // into a QGraphicsSvgItem which we will display at the same // place: we do this so that the heading scale can be clipped to // the compass dial region. accel_x = new QGraphicsSvgItem(); accel_x->setSharedRenderer(renderer); accel_x->setElementId("accel_x"); m_ahrs->ahrsBargraph->scene()->addItem(accel_x); accel_x->setPos(startX, startY); accel_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("accel_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_y")); startX = rect.x(); startY = rect.y()+ rect.height(); accel_y = new QGraphicsSvgItem(); accel_y->setSharedRenderer(renderer); accel_y->setElementId("accel_y"); m_ahrs->ahrsBargraph->scene()->addItem(accel_y); accel_y->setPos(startX,startY); accel_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("accel_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_z")); startX = rect.x(); startY = rect.y()+ rect.height(); accel_z = new QGraphicsSvgItem(); accel_z->setSharedRenderer(renderer); accel_z->setElementId("accel_z"); m_ahrs->ahrsBargraph->scene()->addItem(accel_z); accel_z->setPos(startX,startY); accel_z->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_x"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_x")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_x = new QGraphicsSvgItem(); gyro_x->setSharedRenderer(renderer); gyro_x->setElementId("gyro_x"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_x); gyro_x->setPos(startX,startY); gyro_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_y")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_y = new QGraphicsSvgItem(); gyro_y->setSharedRenderer(renderer); gyro_y->setElementId("gyro_y"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_y); gyro_y->setPos(startX,startY); gyro_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_z")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_z = new QGraphicsSvgItem(); gyro_z->setSharedRenderer(renderer); gyro_z->setElementId("gyro_z"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_z); gyro_z->setPos(startX,startY); gyro_z->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_x"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_x")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_x = new QGraphicsSvgItem(); mag_x->setSharedRenderer(renderer); mag_x->setElementId("mag_x"); m_ahrs->ahrsBargraph->scene()->addItem(mag_x); mag_x->setPos(startX,startY); mag_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_y")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_y = new QGraphicsSvgItem(); mag_y->setSharedRenderer(renderer); mag_y->setElementId("mag_y"); m_ahrs->ahrsBargraph->scene()->addItem(mag_y); mag_y->setPos(startX,startY); mag_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_z")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_z = new QGraphicsSvgItem(); mag_z->setSharedRenderer(renderer); mag_z->setElementId("mag_z"); m_ahrs->ahrsBargraph->scene()->addItem(mag_z); mag_z->setPos(startX,startY); mag_z->setTransform(QTransform::fromScale(1,0),true); position = -1; // Fill the dropdown menus: UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings"))); UAVObjectField *field = obj->getField(QString("Algorithm")); m_ahrs->algorithm->addItems(field->getOptions()); // Register for Home Location state changes obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("HomeLocation"))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this , SLOT(enableHomeLocSave(UAVObject*))); // Connect the signals connect(m_ahrs->ahrsCalibStart, SIGNAL(clicked()), this, SLOT(launchAHRSCalibration())); connect(m_ahrs->ahrsSettingsRequest, SIGNAL(clicked()), this, SLOT(ahrsSettingsRequest())); /* connect(m_ahrs->algorithm, SIGNAL(currentIndexChanged(int)), this, SLOT(ahrsSettingsSave())); connect(m_ahrs->indoorFlight, SIGNAL(stateChanged(int)), this, SLOT(homeLocationSave())); connect(m_ahrs->homeLocation, SIGNAL(clicked()), this, SLOT(homeLocationSaveSD())); */ connect(m_ahrs->ahrsSettingsSaveRAM, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveRAM())); connect(m_ahrs->ahrsSettingsSaveSD, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveSD())); connect(m_ahrs->sixPointsStart, SIGNAL(clicked()), this, SLOT(sixPointCalibrationMode())); connect(m_ahrs->sixPointsSave, SIGNAL(clicked()), this, SLOT(savePositionData())); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(ahrsSettingsRequest())); }
/** 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; } }
int widthOf(const QString & element, int value = 0) const { if (!svg->elementExists(element)) return value; return svg->boundsOnElement(element).width(); }