bool SvgRenderer::load(const QString &filename) { if (renderer.load(filename) && renderer.isValid()) return true; return false; }
QPixmap MIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { QPixmap pm; QString pmckey(d->pmcKey(size, mode, state)); if (QPixmapCache::find(pmckey, pm)) return pm; if (d->addedPixmaps) { pm = d->addedPixmaps->value(d->hashKey(mode, state)); if (!pm.isNull() && pm.size() == size) return pm; } QSvgRenderer renderer; d->loadDataForModeAndState(&renderer, mode, state); if (!renderer.isValid()) return pm; QSize actualSize = renderer.defaultSize(); if (!actualSize.isNull()) actualSize.scale(size, Qt::KeepAspectRatio); QImage img(actualSize, QImage::Format_ARGB32); img.fill(0x00000000); QPainter p(&img); renderer.render(&p); p.end(); pm = QPixmap::fromImage(img); if (!pm.isNull()) QPixmapCache::insert(pmckey, pm); return pm; }
QSvgRenderer *SvgImageProvider::loadRenderer(const QString &svgFile) { QSvgRenderer *renderer = m_renderers.value(svgFile, NULL); if (!renderer) { QString fn = svgFile; if(!QFileInfo::exists(fn)) { //convert path to be relative to base fn = QUrl::fromLocalFile(m_basePath).resolved(svgFile).toLocalFile(); } if(!QFileInfo::exists(fn)) { //it's really missing this time qWarning() << "[SvgImageProvider::loadRenderer]SVG file not found:" << svgFile; return 0; } renderer = new QSvgRenderer(fn); if (!renderer->isValid()) { qWarning() << "[SvgImageProvider::loadRenderer]Failed to load svg file:" << svgFile; delete renderer; return 0; } m_renderers.insert(svgFile, renderer); } return renderer; }
QPixmap SIconPool::loadIcon( const QString &fileName, const QSize &size, Qt::AspectRatioMode mode, const QColor &color) { QPixmap pm; // SVG? Use QSvgRenderer if (fileName.endsWith(".svg")) { QSvgRenderer *renderer = getSvgRenderer(fileName); if (renderer->isValid()) { QSize renderSize = renderer->defaultSize(); // If given size is valid, scale default size to it using the given aspect ratio mode if (size.isValid()) { renderSize.scale(size, mode); // If only one dimension is valid, scale other dimension keeping the aspect ratio } else if (size.height() > 0) { Qt::AspectRatioMode scaleMode = size.height() > renderSize.height() ? Qt::KeepAspectRatioByExpanding : Qt::KeepAspectRatio; renderSize.scale(renderSize.width(), size.height(), scaleMode); } else if (size.width() > 0) { Qt::AspectRatioMode scaleMode = size.width() > renderSize.width() ? Qt::KeepAspectRatioByExpanding : Qt::KeepAspectRatio; renderSize.scale(size.width(), renderSize.height(), scaleMode); } // Otherwise (-1,-1) was given as size, leave renderSize as icon's default size pm = QPixmap(renderSize); pm.fill(QColor(0, 0, 0, 0)); QPainter painter(&pm); renderer->render(&painter, QRectF(QPointF(), renderSize)); } } else { // Otherwise load with QPixmap pm.load(fileName); if (!pm.isNull()) { pm = pm.scaled(size, mode, Qt::SmoothTransformation); } } if (!pm.isNull() && color.isValid()) { // Colorize the icon QPixmap mask = pm.alphaChannel(); pm.fill(color); pm.setAlphaChannel(mask); } #ifdef Q_DEBUG_ICON if (pm.isNull()) { qDebug() << "Fail to load icon: " << filename; } #endif return pm; }
bool QSvgIOHandlerPrivate::load(QIODevice *device) { if (loaded) return true; if (r->load(device->readAll())) { defaultSize = QSize(r->viewBox().width(), r->viewBox().height()); if (currentSize.isEmpty()) currentSize = defaultSize; } loaded = r->isValid(); return loaded; }
QPixmap QSvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { QPixmap pm; QString pmckey(d->pmcKey(size, mode, state)); if (QPixmapCache::find(pmckey, pm)) return pm; if (d->addedPixmaps) { pm = d->addedPixmaps->value(d->hashKey(mode, state)); if (!pm.isNull() && pm.size() == size) return pm; } QSvgRenderer renderer; d->loadDataForModeAndState(&renderer, mode, state); if (!renderer.isValid()) return pm; QSize actualSize = renderer.defaultSize(); if (!actualSize.isNull()) actualSize.scale(size, Qt::KeepAspectRatio); if (actualSize.isEmpty()) return QPixmap(); QImage img(actualSize, QImage::Format_ARGB32_Premultiplied); img.fill(0x00000000); QPainter p(&img); renderer.render(&p); p.end(); pm = QPixmap::fromImage(img); if (qobject_cast<QGuiApplication *>(QCoreApplication::instance())) { const QPixmap generated = QGuiApplicationPrivate::instance()->applyQIconStyleHelper(mode, pm); if (!generated.isNull()) pm = generated; } if (!pm.isNull()) QPixmapCache::insert(pmckey, pm); return pm; }
bool SvgHandler::loadSvg( const QString& name ) { const QString &svgFilename = !m_customTheme ? KStandardDirs::locate( "data", name ) : name; QSvgRenderer *renderer = new QSvgRenderer( The::svgTinter()->tint( svgFilename ) ); if ( !renderer->isValid() ) { debug() << "Bluddy 'ell mateys, aye canna' load ya Ess Vee Gee at " << svgFilename; delete renderer; return false; } QWriteLocker writeLocker( &m_lock ); if( m_renderers[name] ) delete m_renderers[name]; m_renderers[name] = renderer; return true; }
QPixmap QSvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { QPixmap pm; QString pmckey(d->pmcKey(size, mode, state)); if (QPixmapCache::find(pmckey, pm)) return pm; if (d->addedPixmaps) { pm = d->addedPixmaps->value(d->hashKey(mode, state)); if (!pm.isNull() && pm.size() == size) return pm; } QSvgRenderer renderer; d->loadDataForModeAndState(&renderer, mode, state); if (!renderer.isValid()) return pm; QSize actualSize = renderer.defaultSize(); if (!actualSize.isNull()) actualSize.scale(size, Qt::KeepAspectRatio); QImage img(actualSize, QImage::Format_ARGB32_Premultiplied); img.fill(0x00000000); QPainter p(&img); renderer.render(&p); p.end(); pm = QPixmap::fromImage(img); QStyleOption opt(0); opt.palette = QApplication::palette(); QPixmap generated = QApplication::style()->generatedIconPixmap(mode, pm, &opt); if (!generated.isNull()) pm = generated; if (!pm.isNull()) QPixmapCache::insert(pmckey, pm); return pm; }
QSvgRenderer *SvgImageProvider::loadRenderer(const QString &svgFile) { QSvgRenderer *renderer = m_renderers.value(svgFile, NULL); if (!renderer) { QFileInfo fi(svgFile); // if svgFile is relative, make it relative to base QString fn = fi.isRelative() ? QUrl::fromLocalFile(m_basePath).resolved(svgFile).toLocalFile() : svgFile; renderer = new QSvgRenderer(fn); if (!renderer->isValid()) { qWarning() << "Failed to load svg file:" << svgFile << fn; delete renderer; return 0; } m_renderers.insert(svgFile, renderer); } return renderer; }
QSize SIconPool::defaultSize(const QString &fileName) { QSize defSize; // Get the default size from svg renderer or pixmap size if (!fileName.isEmpty()) { // SVG? Use QSvgRenderer if (fileName.endsWith(".svg")) { QSvgRenderer *svgRenderer = getSvgRenderer(fileName); if (svgRenderer->isValid()) { defSize = svgRenderer->defaultSize(); } } else { // Otherwise load with QPixmap QPixmap pixmap; pixmap.load(fileName); defSize = pixmap.size(); } } return defSize; }
QPixmap MIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { QPixmap pm; QString pmckey(d->pmcKey(size, mode, state)); pmckey.prepend("Ms"); if (QPixmapCache::find(pmckey, pm)) return pm; if (d->addedPixmaps) { pm = d->addedPixmaps->value(d->hashKey(mode, state)); if (!pm.isNull() && pm.size() == size) return pm; } QSvgRenderer renderer; d->loadDataForModeAndState(&renderer, mode, state); if (!renderer.isValid()) return pm; QSize actualSize = renderer.defaultSize(); if (!actualSize.isNull()) actualSize.scale(size, Qt::KeepAspectRatio); // Generate an image of the requested size, but render the // the SVG with the correct aspect ratio centered in the image // to prevent scaling issues when setting non square icon size. QImage img(size, QImage::Format_ARGB32); img.fill(0x00000000); QPainter p(&img); renderer.render(&p, getBounds(size, actualSize)); p.end(); pm = QPixmap::fromImage(img); if (!pm.isNull()) QPixmapCache::insert(pmckey, pm); return pm; }
void QgsDecorationNorthArrow::render( const QgsMapSettings &mapSettings, QgsRenderContext &context ) { //Large IF statement controlled by enable checkbox if ( enabled() ) { QSize size( 64, 64 ); QSvgRenderer svg; const QByteArray &svgContent = QgsApplication::svgCache()->svgContent( QStringLiteral( ":/images/north_arrows/default.svg" ), size.width(), mColor, mOutlineColor, 1.0, 1.0 ); svg.load( svgContent ); if ( svg.isValid() ) { double centerXDouble = size.width() / 2.0; double centerYDouble = size.width() / 2.0; //save the current canvas rotation context.painter()->save(); // //work out how to shift the image so that it rotates // properly about its center //(x cos a + y sin a - x, -x sin a + y cos a - y) // // could move this call to somewhere else so that it is only // called when the projection or map extent changes if ( mAutomatic ) { mRotationInt = QgsBearingUtils:: bearingTrueNorth( mapSettings.destinationCrs(), context.extent().center() ); mRotationInt += mapSettings.rotation(); } double myRadiansDouble = mRotationInt * M_PI / 180.0; int xShift = static_cast<int>( ( ( centerXDouble * cos( myRadiansDouble ) ) + ( centerYDouble * sin( myRadiansDouble ) ) ) - centerXDouble ); int yShift = static_cast<int>( ( ( -centerXDouble * sin( myRadiansDouble ) ) + ( centerYDouble * cos( myRadiansDouble ) ) ) - centerYDouble ); // need width/height of paint device int myHeight = context.painter()->device()->height(); int myWidth = context.painter()->device()->width(); //QgsDebugMsg("Rendering north arrow at " + mPlacementLabels.at(mPlacementIndex)); // Set margin according to selected units int myXOffset = 0; int myYOffset = 0; switch ( mMarginUnit ) { case QgsUnitTypes::RenderMillimeters: { int myPixelsInchX = context.painter()->device()->logicalDpiX(); int myPixelsInchY = context.painter()->device()->logicalDpiY(); myXOffset = myPixelsInchX * INCHES_TO_MM * mMarginHorizontal; myYOffset = myPixelsInchY * INCHES_TO_MM * mMarginVertical; break; } case QgsUnitTypes::RenderPixels: myXOffset = mMarginHorizontal - 5; // Minus 5 to shift tight into corner myYOffset = mMarginVertical - 5; break; case QgsUnitTypes::RenderPercentage: myXOffset = ( ( myWidth - size.width() ) / 100. ) * mMarginHorizontal; myYOffset = ( ( myHeight - size.width() ) / 100. ) * mMarginVertical; break; default: // Use default of top left break; } //Determine placement of label from form combo box switch ( mPlacement ) { case BottomLeft: context.painter()->translate( myXOffset, myHeight - myYOffset - size.width() ); break; case TopLeft: context.painter()->translate( myXOffset, myYOffset ); break; case TopRight: context.painter()->translate( myWidth - myXOffset - size.width(), myYOffset ); break; case BottomRight: context.painter()->translate( myWidth - myXOffset - size.width(), myHeight - myYOffset - size.width() ); break; default: { //QgsDebugMsg("Unable to determine where to put north arrow so defaulting to top left"); } } //rotate the canvas by the north arrow rotation amount context.painter()->rotate( mRotationInt ); //Now we can actually do the drawing, and draw a smooth north arrow even when rotated context.painter()->translate( xShift, yShift ); svg.render( context.painter(), QRectF( 0, 0, size.width(), size.height() ) ); //unrotate the canvas again context.painter()->restore(); } else { QFont myQFont( QStringLiteral( "time" ), 12, QFont::Bold ); context.painter()->setFont( myQFont ); context.painter()->setPen( Qt::black ); context.painter()->drawText( 10, 20, tr( "North arrow pixmap not found" ) ); } } }
void QgsDecorationNorthArrow::render( const QgsMapSettings &mapSettings, QgsRenderContext &context ) { if ( !enabled() ) return; double maxLength = mSize * mapSettings.outputDpi() / 25.4; QSvgRenderer svg; const QByteArray &svgContent = QgsApplication::svgCache()->svgContent( svgPath(), maxLength, mColor, mOutlineColor, 1.0, 1.0 ); svg.load( svgContent ); if ( svg.isValid() ) { QSize size( maxLength, maxLength ); QRectF viewBox = svg.viewBoxF(); if ( viewBox.height() > viewBox.width() ) { size.setWidth( maxLength * viewBox.width() / viewBox.height() ); } else { size.setHeight( maxLength * viewBox.height() / viewBox.width() ); } double centerXDouble = size.width() / 2.0; double centerYDouble = size.height() / 2.0; //save the current canvas rotation context.painter()->save(); // //work out how to shift the image so that it rotates // properly about its center //(x cos a + y sin a - x, -x sin a + y cos a - y) // // could move this call to somewhere else so that it is only // called when the projection or map extent changes if ( mAutomatic ) { try { mRotationInt = QgsBearingUtils:: bearingTrueNorth( mapSettings.destinationCrs(), mapSettings.transformContext(), context.extent().center() ); } catch ( QgsException & ) { mRotationInt = 0.0; } mRotationInt += mapSettings.rotation(); } double radiansDouble = mRotationInt * M_PI / 180.0; int xShift = static_cast<int>( ( ( centerXDouble * std::cos( radiansDouble ) ) + ( centerYDouble * std::sin( radiansDouble ) ) ) - centerXDouble ); int yShift = static_cast<int>( ( ( -centerXDouble * std::sin( radiansDouble ) ) + ( centerYDouble * std::cos( radiansDouble ) ) ) - centerYDouble ); // need width/height of paint device int deviceHeight = context.painter()->device()->height(); int deviceWidth = context.painter()->device()->width(); // Set margin according to selected units int xOffset = 0; int yOffset = 0; switch ( mMarginUnit ) { case QgsUnitTypes::RenderMillimeters: { int pixelsInchX = context.painter()->device()->logicalDpiX(); int pixelsInchY = context.painter()->device()->logicalDpiY(); xOffset = pixelsInchX * INCHES_TO_MM * mMarginHorizontal; yOffset = pixelsInchY * INCHES_TO_MM * mMarginVertical; break; } case QgsUnitTypes::RenderPixels: xOffset = mMarginHorizontal - 5; // Minus 5 to shift tight into corner yOffset = mMarginVertical - 5; break; case QgsUnitTypes::RenderPercentage: xOffset = ( ( deviceWidth - size.width() ) / 100. ) * mMarginHorizontal; yOffset = ( ( deviceHeight - size.width() ) / 100. ) * mMarginVertical; break; case QgsUnitTypes::RenderMapUnits: case QgsUnitTypes::RenderPoints: case QgsUnitTypes::RenderInches: case QgsUnitTypes::RenderUnknownUnit: case QgsUnitTypes::RenderMetersInMapUnits: break; } //Determine placement of label from form combo box switch ( mPlacement ) { case BottomLeft: context.painter()->translate( xOffset, deviceHeight - yOffset - maxLength + ( maxLength - size.height() ) / 2 ); break; case TopLeft: context.painter()->translate( xOffset, yOffset ); break; case TopRight: context.painter()->translate( deviceWidth - xOffset - maxLength + ( maxLength - size.width() ) / 2, yOffset ); break; case BottomRight: context.painter()->translate( deviceWidth - xOffset - maxLength + ( maxLength - size.width() ) / 2, deviceHeight - yOffset - maxLength + ( maxLength - size.height() ) / 2 ); break; } //rotate the canvas by the north arrow rotation amount context.painter()->rotate( mRotationInt ); //Now we can actually do the drawing, and draw a smooth north arrow even when rotated context.painter()->translate( xShift, yShift ); svg.render( context.painter(), QRectF( 0, 0, size.width(), size.height() ) ); //unrotate the canvas again context.painter()->restore(); } }
void QgsDecorationNorthArrowDialog::drawNorthArrow() { int rotation = spinAngle->value(); double maxLength = 64; QSvgRenderer svg; const QByteArray &svgContent = QgsApplication::svgCache()->svgContent( mDeco.svgPath(), maxLength, pbnChangeColor->color(), pbnChangeOutlineColor->color(), 1.0, 1.0 ); svg.load( svgContent ); if ( svg.isValid() ) { QSize size( maxLength, maxLength ); QRectF viewBox = svg.viewBoxF(); if ( viewBox.height() > viewBox.width() ) { size.setWidth( maxLength * viewBox.width() / viewBox.height() ); } else { size.setHeight( maxLength * viewBox.height() / viewBox.width() ); } QPixmap myPainterPixmap( maxLength, maxLength ); myPainterPixmap.fill(); QPainter myQPainter; myQPainter.begin( &myPainterPixmap ); myQPainter.setRenderHint( QPainter::SmoothPixmapTransform ); double centerXDouble = size.width() / 2.0; double centerYDouble = size.height() / 2.0; //save the current canvas rotation myQPainter.save(); myQPainter.translate( ( maxLength - size.width() ) / 2, ( maxLength - size.height() ) / 2 ); //rotate the canvas myQPainter.rotate( rotation ); //work out how to shift the image so that it appears in the center of the canvas //(x cos a + y sin a - x, -x sin a + y cos a - y) double myRadiansDouble = ( M_PI / 180 ) * rotation; int xShift = static_cast<int>( ( ( centerXDouble * std::cos( myRadiansDouble ) ) + ( centerYDouble * std::sin( myRadiansDouble ) ) ) - centerXDouble ); int yShift = static_cast<int>( ( ( -centerXDouble * std::sin( myRadiansDouble ) ) + ( centerYDouble * std::cos( myRadiansDouble ) ) ) - centerYDouble ); //draw the pixmap in the proper position myQPainter.translate( xShift, yShift ); svg.render( &myQPainter, QRectF( 0, 0, size.width(), size.height() ) ); //unrotate the canvas again myQPainter.restore(); myQPainter.end(); pixmapLabel->setPixmap( myPainterPixmap ); } else { QPixmap myPainterPixmap( 200, 200 ); myPainterPixmap.fill(); QPainter myQPainter; myQPainter.begin( &myPainterPixmap ); QFont myQFont( QStringLiteral( "time" ), 12, QFont::Bold ); myQPainter.setFont( myQFont ); myQPainter.setPen( Qt::red ); myQPainter.drawText( 10, 20, tr( "Pixmap not found" ) ); myQPainter.end(); pixmapLabel->setPixmap( myPainterPixmap ); } }
QPixmap MIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { QPixmap pm; QString pmckey(d->pmcKey(size, mode, state)); if (QPixmapCache::find(pmckey, pm)) return pm; if (d->addedPixmaps) { pm = d->addedPixmaps->value(d->hashKey(mode, state)); if (!pm.isNull() && pm.size() == size) return pm; } QSvgRenderer renderer; d->loadDataForModeAndState(&renderer, mode, state); if (!renderer.isValid()) return pm; QSize actualSize = renderer.defaultSize(); if (!actualSize.isNull()) actualSize.scale(size, Qt::KeepAspectRatio); QImage img(actualSize, QImage::Format_ARGB32); img.fill(0x00000000); QPainter p(&img); renderer.render(&p); p.end(); bool light = Ms::preferences.globalStyle == Ms::STYLE_LIGHT; int ww = img.width(); if (state == QIcon::On) { if (light) { for (int y = 0; y < img.height(); ++y) { QRgb *scanLine = (QRgb*)img.scanLine(y); for (int x = 0; x < img.width(); ++x) { QRgb pixel = *scanLine; int alpha = qAlpha(pixel); if (alpha < 0) alpha = 0; *scanLine = qRgba(qRed(255-pixel), qGreen(255-pixel), qBlue(255-pixel), alpha); ++scanLine; } } } else { for (int y = 0; y < img.height(); ++y) { quint32* p = (quint32*)img.scanLine(y); for (int x = 0; x < ww; ++x) { if (*p & 0xff000000) { int d = 0xff - (*p & 0xff); int dd = 50; QColor color(QColor::fromRgba(*p)); int r = 70 - d + dd; if (r < 0) r = 0; int g = 130 - d + dd; if (g < 0) g = 0; int b = 180 - d + dd; if (b < 0) b = 0; QColor nc = QColor(r, g, b, color.alpha()); *p = nc.rgba(); } ++p; } } } } else { // change alpha channel int delta = 51; if (mode == QIcon::Disabled) delta = 178; else if (state == QIcon::On) delta = 0; if (light) { for (int y = 0; y < img.height(); ++y) { QRgb *scanLine = (QRgb*)img.scanLine(y); for (int x = 0; x < img.width(); ++x) { QRgb pixel = *scanLine; int alpha = qAlpha(pixel) - delta; if (alpha < 0) alpha = 0; *scanLine = qRgba(qRed(255-pixel), qGreen(255-pixel), qBlue(255-pixel), alpha); ++scanLine; } } } else { for (int y = 0; y < img.height(); ++y) { QRgb *scanLine = (QRgb*)img.scanLine(y); for (int x = 0; x < img.width(); ++x) { QRgb pixel = *scanLine; int alpha = qAlpha(pixel) - delta; if (alpha < 0) alpha = 0; *scanLine = qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), alpha); ++scanLine; } } } } pm = QPixmap::fromImage(img); if (!pm.isNull()) QPixmapCache::insert(pmckey, pm); return pm; }
/** 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; } }