Skip to content
Snippets Groups Projects
qwt_plot_svgitem.cpp 4.87 KiB
Newer Older
  • Learn to ignore specific revisions
  • pixhawk's avatar
    pixhawk committed
    /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
     * Qwt Widget Library
     * Copyright (C) 1997   Josef Wilgen
     * Copyright (C) 2002   Uwe Rathmann
     *
     * This library is free software; you can redistribute it and/or
     * modify it under the terms of the Qwt License, Version 1.0
     *****************************************************************************/
    
    
    Bryant's avatar
    Bryant committed
    #include "qwt_plot_svgitem.h"
    #include "qwt_scale_map.h"
    #include "qwt_painter.h"
    
    pixhawk's avatar
    pixhawk committed
    #include <qpainter.h>
    #include <qsvgrenderer.h>
    
    class QwtPlotSvgItem::PrivateData
    {
    public:
    
    Bryant's avatar
    Bryant committed
        PrivateData()
        {
    
    pixhawk's avatar
    pixhawk committed
        }
    
    
    Bryant's avatar
    Bryant committed
        QRectF boundingRect;
    
    pixhawk's avatar
    pixhawk committed
        QSvgRenderer renderer;
    };
    
    /*!
       \brief Constructor
    
    pixhawk's avatar
    pixhawk committed
       Sets the following item attributes:
       - QwtPlotItem::AutoScale: true
       - QwtPlotItem::Legend:    false
    
       \param title Title
    */
    
    Bryant's avatar
    Bryant committed
    QwtPlotSvgItem::QwtPlotSvgItem( const QString& title ):
        QwtPlotItem( QwtText( title ) )
    
    pixhawk's avatar
    pixhawk committed
    {
        init();
    }
    
    /*!
       \brief Constructor
    
    pixhawk's avatar
    pixhawk committed
       Sets the following item attributes:
       - QwtPlotItem::AutoScale: true
       - QwtPlotItem::Legend:    false
    
       \param title Title
    */
    
    Bryant's avatar
    Bryant committed
    QwtPlotSvgItem::QwtPlotSvgItem( const QwtText& title ):
        QwtPlotItem( title )
    
    pixhawk's avatar
    pixhawk committed
    {
        init();
    }
    
    //! Destructor
    QwtPlotSvgItem::~QwtPlotSvgItem()
    {
        delete d_data;
    }
    
    void QwtPlotSvgItem::init()
    {
        d_data = new PrivateData();
    
    Bryant's avatar
    Bryant committed
        d_data->boundingRect = QwtPlotItem::boundingRect();
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        setItemAttribute( QwtPlotItem::AutoScale, true );
        setItemAttribute( QwtPlotItem::Legend, false );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        setZ( 8.0 );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    //! \return QwtPlotItem::Rtti_PlotSVG
    int QwtPlotSvgItem::rtti() const
    {
        return QwtPlotItem::Rtti_PlotSVG;
    }
    
    /*!
       Load a SVG file
    
       \param rect Bounding rectangle
       \param fileName SVG file name
    
       \return true, if the SVG file could be loaded
    */
    
    Bryant's avatar
    Bryant committed
    bool QwtPlotSvgItem::loadFile( const QRectF &rect,
        const QString &fileName )
    
    pixhawk's avatar
    pixhawk committed
    {
        d_data->boundingRect = rect;
    
    Bryant's avatar
    Bryant committed
        const bool ok = d_data->renderer.load( fileName );
    
        legendChanged();
    
    pixhawk's avatar
    pixhawk committed
        itemChanged();
    
    Bryant's avatar
    Bryant committed
    
    
    pixhawk's avatar
    pixhawk committed
        return ok;
    }
    
    /*!
    
       Load SVG data
    
    pixhawk's avatar
    pixhawk committed
    
       \param rect Bounding rectangle
       \param data in SVG format
    
       \return true, if the SVG data could be loaded
    */
    
    Bryant's avatar
    Bryant committed
    bool QwtPlotSvgItem::loadData( const QRectF &rect,
        const QByteArray &data )
    
    pixhawk's avatar
    pixhawk committed
    {
        d_data->boundingRect = rect;
    
    Bryant's avatar
    Bryant committed
        const bool ok = d_data->renderer.load( data );
    
        legendChanged();
    
    pixhawk's avatar
    pixhawk committed
        itemChanged();
    
    Bryant's avatar
    Bryant committed
    
    
    pixhawk's avatar
    pixhawk committed
        return ok;
    }
    
    
    Bryant's avatar
    Bryant committed
    //! Bounding rectangle of the item
    QRectF QwtPlotSvgItem::boundingRect() const
    
    pixhawk's avatar
    pixhawk committed
    {
        return d_data->boundingRect;
    }
    
    //! \return Renderer used to render the SVG data
    const QSvgRenderer &QwtPlotSvgItem::renderer() const
    {
        return d_data->renderer;
    }
    
    //! \return Renderer used to render the SVG data
    QSvgRenderer &QwtPlotSvgItem::renderer()
    {
        return d_data->renderer;
    }
    
    /*!
      Draw the SVG item
    
      \param painter Painter
      \param xMap X-Scale Map
      \param yMap Y-Scale Map
      \param canvasRect Contents rect of the plot canvas
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotSvgItem::draw( QPainter *painter,
        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
        const QRectF &canvasRect ) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        const QRectF cRect = QwtScaleMap::invTransform(
            xMap, yMap, canvasRect.toRect() );
        const QRectF bRect = boundingRect();
        if ( bRect.isValid() && cRect.isValid() )
        {
            QRectF rect = bRect;
            if ( bRect.contains( cRect ) )
    
    pixhawk's avatar
    pixhawk committed
                rect = cRect;
    
    
    Bryant's avatar
    Bryant committed
            const QRectF r = QwtScaleMap::transform( xMap, yMap, rect );
            render( painter, viewBox( rect ), r );
    
    pixhawk's avatar
    pixhawk committed
        }
    }
    
    /*!
      Render the SVG data
    
      \param painter Painter
    
    Bryant's avatar
    Bryant committed
      \param viewBox View Box, see QSvgRenderer::viewBox()
      \param rect Target rectangle on the paint device
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotSvgItem::render( QPainter *painter,
        const QRectF &viewBox, const QRectF &rect ) const
    
    pixhawk's avatar
    pixhawk committed
    {
        if ( !viewBox.isValid() )
            return;
    
    
    Bryant's avatar
    Bryant committed
        QRectF r = rect;
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        if ( QwtPainter::roundingAlignment( painter ) )
        {
            r.setLeft ( qRound( r.left() ) );
            r.setRight ( qRound( r.right() ) );
            r.setTop ( qRound( r.top() ) );
            r.setBottom ( qRound( r.bottom() ) );
        }
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        d_data->renderer.setViewBox( viewBox );
        d_data->renderer.render( painter, r );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      Calculate the view box from rect and boundingRect().
    
    pixhawk's avatar
    pixhawk committed
    
      \param rect Rectangle in scale coordinates
    
    Bryant's avatar
    Bryant committed
      \return View box, see QSvgRenderer::viewBox()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    QRectF QwtPlotSvgItem::viewBox( const QRectF &rect ) const
    
    pixhawk's avatar
    pixhawk committed
    {
        const QSize sz = d_data->renderer.defaultSize();
    
    Bryant's avatar
    Bryant committed
        const QRectF br = boundingRect();
    
    pixhawk's avatar
    pixhawk committed
    
        if ( !rect.isValid() || !br.isValid() || sz.isNull() )
    
    Bryant's avatar
    Bryant committed
            return QRectF();
    
    pixhawk's avatar
    pixhawk committed
    
        QwtScaleMap xMap;
    
    Bryant's avatar
    Bryant committed
        xMap.setScaleInterval( br.left(), br.right() );
        xMap.setPaintInterval( 0, sz.width() );
    
    pixhawk's avatar
    pixhawk committed
    
        QwtScaleMap yMap;
    
    Bryant's avatar
    Bryant committed
        yMap.setScaleInterval( br.top(), br.bottom() );
        yMap.setPaintInterval( sz.height(), 0 );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        const double x1 = xMap.transform( rect.left() );
        const double x2 = xMap.transform( rect.right() );
        const double y1 = yMap.transform( rect.bottom() );
        const double y2 = yMap.transform( rect.top() );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        return QRectF( x1, y1, x2 - x1, y2 - y1 );
    
    pixhawk's avatar
    pixhawk committed
    }