# qwt_plot_svgitem.cpp

    00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
    00002  * Qwt Widget Library
    00003  * Copyright (C) 1997   Josef Wilgen
    00004  * Copyright (C) 2002   Uwe Rathmann
    00005  *
    00006  * This library is free software; you can redistribute it and/or
    00007  * modify it under the terms of the Qwt License, Version 1.0
    00008  *****************************************************************************/
    00009
    00010 #include <qglobal.h>
    00011
    00012 #include <qpainter.h>
    00013 #if QT_VERSION >= 0x040100
    00014 #include <qsvgrenderer.h>
    00015 #else
    00016 #include <qbuffer.h>
    00017 #include <qpicture.h>
    00018 #endif
    00019 #if QT_VERSION < 0x040000
    00020 #include <qpaintdevicemetrics.h>
    00021 #endif
    00022 #include <qwt_scale_map.h>
    00023 #include <qwt_legend.h>
    00024 #include <qwt_legend_item.h>
    00025 #include "qwt_plot_svgitem.h"
    00026
    00027 class QwtPlotSvgItem::PrivateData
    00028 {
    00029 public:
    00030     PrivateData()
    00031     {
    00032     }
    00033
    00034     QwtDoubleRect boundingRect;
    00035 #if QT_VERSION >= 0x040100
    00036     QSvgRenderer renderer;
    00037 #else
    00038     QPicture picture;
    00039 #endif
    00040 };
    00041
    00051 QwtPlotSvgItem::QwtPlotSvgItem(const QString& title):
    00052     QwtPlotItem(QwtText(title))
    00053 {
    00054     init();
    00055 }
    00056
    00066 QwtPlotSvgItem::QwtPlotSvgItem(const QwtText& title):
    00067     QwtPlotItem(title)
    00068 {
    00069     init();
    00070 }
    00071
    00073 QwtPlotSvgItem::~QwtPlotSvgItem()
    00074 {
    00075     delete d_data;
    00076 }
    00077
    00078 void QwtPlotSvgItem::init()
    00079 {
    00080     d_data = new PrivateData();
    00081
    00082     setItemAttribute(QwtPlotItem::AutoScale, true);
    00083     setItemAttribute(QwtPlotItem::Legend, false);
    00084
    00085     setZ(8.0);
    00086 }
    00087
    00089 int QwtPlotSvgItem::rtti() const
    00090 {
    00091     return QwtPlotItem::Rtti_PlotSVG;
    00092 }
    00093
    00102 bool QwtPlotSvgItem::loadFile(const QwtDoubleRect &rect,
    00103     const QString &fileName)
    00104 {
    00105     d_data->boundingRect = rect;
    00106 #if QT_VERSION >= 0x040100
    00107     const bool ok = d_data->renderer.load(fileName);
    00108 #else
    00109     const bool ok = d_data->picture.load(fileName, "svg");
    00110 #endif
    00111     itemChanged();
    00112     return ok;
    00113 }
    00114
    00123 bool QwtPlotSvgItem::loadData(const QwtDoubleRect &rect,
    00124     const QByteArray &data)
    00125 {
    00126     d_data->boundingRect = rect;
    00127 #if QT_VERSION >= 0x040100
    00128     const bool ok = d_data->renderer.load(data);
    00129 #else
    00130 #if QT_VERSION >= 0x040000
    00131     QBuffer buffer(&(QByteArray&)data);
    00132 #else
    00133     QBuffer buffer(data);
    00134 #endif
    00135     const bool ok = d_data->picture.load(&buffer, "svg");
    00136 #endif
    00137     itemChanged();
    00138     return ok;
    00139 }
    00140
    00142 QwtDoubleRect QwtPlotSvgItem::boundingRect() const
    00143 {
    00144     return d_data->boundingRect;
    00145 }
    00146
    00147 #if QT_VERSION >= 0x040100
    00148
    00150 const QSvgRenderer &QwtPlotSvgItem::renderer() const
    00151 {
    00152     return d_data->renderer;
    00153 }
    00154
    00156 QSvgRenderer &QwtPlotSvgItem::renderer()
    00157 {
    00158     return d_data->renderer;
    00159 }
    00160 #endif
    00161
    00170 void QwtPlotSvgItem::draw(QPainter *painter,
    00171     const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    00172     const QRect &canvasRect) const
    00173 {
    00174     const QwtDoubleRect cRect = invTransform(xMap, yMap, canvasRect);
    00175     const QwtDoubleRect bRect = boundingRect();
    00176     if ( bRect.isValid() && cRect.isValid() )
    00177     {
    00178         QwtDoubleRect rect = bRect;
    00179         if ( bRect.contains(cRect) )
    00180             rect = cRect;
    00181
    00182         render(painter, viewBox(rect),
    00183             transform(xMap, yMap, rect) );
    00184     }
    00185 }
    00186
    00194 void QwtPlotSvgItem::render(QPainter *painter,
    00195         const QwtDoubleRect &viewBox, const QRect &rect) const
    00196 {
    00197     if ( !viewBox.isValid() )
    00198         return;
    00199
    00200 #if QT_VERSION >= 0x040200
    00201     d_data->renderer.setViewBox(viewBox);
    00202     d_data->renderer.render(painter, rect);
    00203     return;
    00204 #else
    00205
    00206 #if QT_VERSION >= 0x040100
    00207     const QSize paintSize(painter->window().width(),
    00208         painter->window().height());
    00209     if ( !paintSize.isValid() )
    00210         return;
    00211
    00212     const double xRatio = paintSize.width() / viewBox.width();
    00213     const double yRatio = paintSize.height() / viewBox.height();
    00214
    00215     const double dx = rect.left() / xRatio + 1.0;
    00216     const double dy = rect.top() / yRatio + 1.0;
    00217
    00218     const double mx = double(rect.width()) / paintSize.width();
    00219     const double my = double(rect.height()) / paintSize.height();
    00220
    00221     painter->save();
    00222
    00223     painter->translate(dx, dy);
    00224     painter->scale(mx, my);
    00225
    00226     d_data->renderer.setViewBox(viewBox.toRect());
    00227     d_data->renderer.render(painter);
    00228
    00229     painter->restore();
    00230 #else
    00231     const double mx = rect.width() / viewBox.width();
    00232     const double my = rect.height() / viewBox.height();
    00233     const double dx = rect.x() - mx * viewBox.x();
    00234     const double dy = rect.y() - my * viewBox.y();
    00235
    00236     painter->save();
    00237
    00238     painter->translate(dx, dy);
    00239     painter->scale(mx, my);
    00240
    00241     d_data->picture.play(painter);
    00242
    00243     painter->restore();
    00244 #endif // < 0x040100
    00245 #endif // < 0x040200
    00246 }
    00247
    00254 QwtDoubleRect QwtPlotSvgItem::viewBox(const QwtDoubleRect &rect) const
    00255 {
    00256 #if QT_VERSION >= 0x040100
    00257     const QSize sz = d_data->renderer.defaultSize();
    00258 #else
    00259 #if QT_VERSION > 0x040000
    00260     const QSize sz(d_data->picture.width(),
    00261         d_data->picture.height());
    00262 #else
    00263     QPaintDeviceMetrics metrics(&d_data->picture);
    00264     const QSize sz(metrics.width(), metrics.height());
    00265 #endif
    00266 #endif
    00267     const QwtDoubleRect br = boundingRect();
    00268
    00269     if ( !rect.isValid() || !br.isValid() || sz.isNull() )
    00270         return QwtDoubleRect();
    00271
    00272     QwtScaleMap xMap;
    00273     xMap.setScaleInterval(br.left(), br.right());
    00274     xMap.setPaintInterval(0, sz.width());
    00275
    00276     QwtScaleMap yMap;
    00277     yMap.setScaleInterval(br.top(), br.bottom());
    00278     yMap.setPaintInterval(sz.height(), 0);
    00279
    00280     const double x1 = xMap.xTransform(rect.left());
    00281     const double x2 = xMap.xTransform(rect.right());
    00282     const double y1 = yMap.xTransform(rect.bottom());
    00283     const double y2 = yMap.xTransform(rect.top());
    00284
    00285     return QwtDoubleRect(x1, y1, x2 - x1, y2 - y1);
    00286 }