00001
00002
00003
00004
00005
00006
00007
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 }