qwt_plot_svgitem.cpp 4.87 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2 3 4 5 6 7 8 9
/* -*- 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
10 11 12
#include "qwt_plot_svgitem.h"
#include "qwt_scale_map.h"
#include "qwt_painter.h"
pixhawk's avatar
pixhawk committed
13 14 15 16 17 18
#include <qpainter.h>
#include <qsvgrenderer.h>

class QwtPlotSvgItem::PrivateData
{
public:
Bryant's avatar
Bryant committed
19 20
    PrivateData()
    {
pixhawk's avatar
pixhawk committed
21 22
    }

Bryant's avatar
Bryant committed
23
    QRectF boundingRect;
pixhawk's avatar
pixhawk committed
24 25 26 27 28
    QSvgRenderer renderer;
};

/*!
   \brief Constructor
29

pixhawk's avatar
pixhawk committed
30 31 32 33 34 35
   Sets the following item attributes:
   - QwtPlotItem::AutoScale: true
   - QwtPlotItem::Legend:    false

   \param title Title
*/
Bryant's avatar
Bryant committed
36 37
QwtPlotSvgItem::QwtPlotSvgItem( const QString& title ):
    QwtPlotItem( QwtText( title ) )
pixhawk's avatar
pixhawk committed
38 39 40 41 42 43
{
    init();
}

/*!
   \brief Constructor
44

pixhawk's avatar
pixhawk committed
45 46 47 48 49 50
   Sets the following item attributes:
   - QwtPlotItem::AutoScale: true
   - QwtPlotItem::Legend:    false

   \param title Title
*/
Bryant's avatar
Bryant committed
51 52
QwtPlotSvgItem::QwtPlotSvgItem( const QwtText& title ):
    QwtPlotItem( title )
pixhawk's avatar
pixhawk committed
53 54 55 56 57 58 59 60 61 62 63 64 65
{
    init();
}

//! Destructor
QwtPlotSvgItem::~QwtPlotSvgItem()
{
    delete d_data;
}

void QwtPlotSvgItem::init()
{
    d_data = new PrivateData();
Bryant's avatar
Bryant committed
66
    d_data->boundingRect = QwtPlotItem::boundingRect();
pixhawk's avatar
pixhawk committed
67

Bryant's avatar
Bryant committed
68 69
    setItemAttribute( QwtPlotItem::AutoScale, true );
    setItemAttribute( QwtPlotItem::Legend, false );
pixhawk's avatar
pixhawk committed
70

Bryant's avatar
Bryant committed
71
    setZ( 8.0 );
pixhawk's avatar
pixhawk committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
}

//! \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
88 89
bool QwtPlotSvgItem::loadFile( const QRectF &rect,
    const QString &fileName )
pixhawk's avatar
pixhawk committed
90 91
{
    d_data->boundingRect = rect;
Bryant's avatar
Bryant committed
92 93 94
    const bool ok = d_data->renderer.load( fileName );

    legendChanged();
pixhawk's avatar
pixhawk committed
95
    itemChanged();
Bryant's avatar
Bryant committed
96

pixhawk's avatar
pixhawk committed
97 98 99 100
    return ok;
}

/*!
101
   Load SVG data
pixhawk's avatar
pixhawk committed
102 103 104 105 106 107

   \param rect Bounding rectangle
   \param data in SVG format

   \return true, if the SVG data could be loaded
*/
Bryant's avatar
Bryant committed
108 109
bool QwtPlotSvgItem::loadData( const QRectF &rect,
    const QByteArray &data )
pixhawk's avatar
pixhawk committed
110 111
{
    d_data->boundingRect = rect;
Bryant's avatar
Bryant committed
112 113 114
    const bool ok = d_data->renderer.load( data );

    legendChanged();
pixhawk's avatar
pixhawk committed
115
    itemChanged();
Bryant's avatar
Bryant committed
116

pixhawk's avatar
pixhawk committed
117 118 119
    return ok;
}

Bryant's avatar
Bryant committed
120 121
//! Bounding rectangle of the item
QRectF QwtPlotSvgItem::boundingRect() const
pixhawk's avatar
pixhawk committed
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
{
    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
146 147 148
void QwtPlotSvgItem::draw( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect ) const
pixhawk's avatar
pixhawk committed
149
{
Bryant's avatar
Bryant committed
150 151 152 153 154 155 156
    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
157 158
            rect = cRect;

Bryant's avatar
Bryant committed
159 160
        const QRectF r = QwtScaleMap::transform( xMap, yMap, rect );
        render( painter, viewBox( rect ), r );
pixhawk's avatar
pixhawk committed
161 162 163 164 165 166 167
    }
}

/*!
  Render the SVG data

  \param painter Painter
Bryant's avatar
Bryant committed
168 169
  \param viewBox View Box, see QSvgRenderer::viewBox()
  \param rect Target rectangle on the paint device
pixhawk's avatar
pixhawk committed
170
*/
Bryant's avatar
Bryant committed
171 172
void QwtPlotSvgItem::render( QPainter *painter,
    const QRectF &viewBox, const QRectF &rect ) const
pixhawk's avatar
pixhawk committed
173 174 175 176
{
    if ( !viewBox.isValid() )
        return;

Bryant's avatar
Bryant committed
177
    QRectF r = rect;
pixhawk's avatar
pixhawk committed
178

Bryant's avatar
Bryant committed
179 180 181 182 183 184 185
    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
186

Bryant's avatar
Bryant committed
187 188
    d_data->renderer.setViewBox( viewBox );
    d_data->renderer.render( painter, r );
pixhawk's avatar
pixhawk committed
189 190 191
}

/*!
Bryant's avatar
Bryant committed
192
  Calculate the view box from rect and boundingRect().
pixhawk's avatar
pixhawk committed
193 194

  \param rect Rectangle in scale coordinates
Bryant's avatar
Bryant committed
195
  \return View box, see QSvgRenderer::viewBox()
pixhawk's avatar
pixhawk committed
196
*/
Bryant's avatar
Bryant committed
197
QRectF QwtPlotSvgItem::viewBox( const QRectF &rect ) const
pixhawk's avatar
pixhawk committed
198 199
{
    const QSize sz = d_data->renderer.defaultSize();
Bryant's avatar
Bryant committed
200
    const QRectF br = boundingRect();
pixhawk's avatar
pixhawk committed
201 202

    if ( !rect.isValid() || !br.isValid() || sz.isNull() )
Bryant's avatar
Bryant committed
203
        return QRectF();
pixhawk's avatar
pixhawk committed
204 205

    QwtScaleMap xMap;
Bryant's avatar
Bryant committed
206 207
    xMap.setScaleInterval( br.left(), br.right() );
    xMap.setPaintInterval( 0, sz.width() );
pixhawk's avatar
pixhawk committed
208 209

    QwtScaleMap yMap;
Bryant's avatar
Bryant committed
210 211
    yMap.setScaleInterval( br.top(), br.bottom() );
    yMap.setPaintInterval( sz.height(), 0 );
pixhawk's avatar
pixhawk committed
212

Bryant's avatar
Bryant committed
213 214 215 216
    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
217

Bryant's avatar
Bryant committed
218
    return QRectF( x1, y1, x2 - x1, y2 - y1 );
pixhawk's avatar
pixhawk committed
219
}