Пример #1
0
bool SvgRenderer::load(const QString &filename)
{
    if (renderer.load(filename) && renderer.isValid())
        return true;

    return false;
}
Пример #2
0
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;
      }
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
      }
Пример #12
0
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" ) );
    }
  }

}
Пример #13
0
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 );
  }
}
Пример #15
0
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;
      }
Пример #16
0
/**
  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;
    }
}