00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <qapplication.h>
00011 #include <qdesktopwidget.h>
00012 #include <qpaintdevice.h>
00013 #include <qpainter.h>
00014 #include "qwt_legend.h"
00015 #include "qwt_legend_item.h"
00016 #include "qwt_scale_map.h"
00017 #include "qwt_plot_rasteritem.h"
00018
00019 class QwtPlotRasterItem::PrivateData
00020 {
00021 public:
00022 PrivateData():
00023 alpha(-1)
00024 {
00025 cache.policy = QwtPlotRasterItem::NoCache;
00026 }
00027
00028 int alpha;
00029
00030 struct ImageCache
00031 {
00032 QwtPlotRasterItem::CachePolicy policy;
00033 QwtDoubleRect rect;
00034 QSize size;
00035 QImage image;
00036 } cache;
00037 };
00038
00039 static QImage toRgba(const QImage& image, int alpha)
00040 {
00041 if ( alpha < 0 || alpha >= 255 )
00042 return image;
00043
00044 #if QT_VERSION < 0x040000
00045 QImage alphaImage(image.size(), 32);
00046 alphaImage.setAlphaBuffer(true);
00047 #else
00048 QImage alphaImage(image.size(), QImage::Format_ARGB32);
00049 #endif
00050
00051 const QRgb mask1 = qRgba(0, 0, 0, alpha);
00052 const QRgb mask2 = qRgba(255, 255, 255, 0);
00053 const QRgb mask3 = qRgba(0, 0, 0, 255);
00054
00055 const int w = image.size().width();
00056 const int h = image.size().height();
00057
00058 if ( image.depth() == 8 )
00059 {
00060 for ( int y = 0; y < h; y++ )
00061 {
00062 QRgb* alphaLine = (QRgb*)alphaImage.scanLine(y);
00063 const unsigned char *line = image.scanLine(y);
00064
00065 for ( int x = 0; x < w; x++ )
00066 *alphaLine++ = (image.color(*line++) & mask2) | mask1;
00067 }
00068 }
00069 else if ( image.depth() == 32 )
00070 {
00071 for ( int y = 0; y < h; y++ )
00072 {
00073 QRgb* alphaLine = (QRgb*)alphaImage.scanLine(y);
00074 const QRgb* line = (const QRgb*) image.scanLine(y);
00075
00076 for ( int x = 0; x < w; x++ )
00077 {
00078 const QRgb rgb = *line++;
00079 if ( rgb & mask3 )
00080 *alphaLine++ = (rgb & mask2) | mask1;
00081 else
00082 *alphaLine++ = rgb;
00083 }
00084 }
00085 }
00086
00087 return alphaImage;
00088 }
00089
00091 QwtPlotRasterItem::QwtPlotRasterItem(const QString& title):
00092 QwtPlotItem(QwtText(title))
00093 {
00094 init();
00095 }
00096
00098 QwtPlotRasterItem::QwtPlotRasterItem(const QwtText& title):
00099 QwtPlotItem(title)
00100 {
00101 init();
00102 }
00103
00105 QwtPlotRasterItem::~QwtPlotRasterItem()
00106 {
00107 delete d_data;
00108 }
00109
00110 void QwtPlotRasterItem::init()
00111 {
00112 d_data = new PrivateData();
00113
00114 setItemAttribute(QwtPlotItem::AutoScale, true);
00115 setItemAttribute(QwtPlotItem::Legend, false);
00116
00117 setZ(8.0);
00118 }
00119
00143 void QwtPlotRasterItem::setAlpha(int alpha)
00144 {
00145 if ( alpha < 0 )
00146 alpha = -1;
00147
00148 if ( alpha > 255 )
00149 alpha = 255;
00150
00151 if ( alpha != d_data->alpha )
00152 {
00153 d_data->alpha = alpha;
00154
00155 itemChanged();
00156 }
00157 }
00158
00163 int QwtPlotRasterItem::alpha() const
00164 {
00165 return d_data->alpha;
00166 }
00167
00176 void QwtPlotRasterItem::setCachePolicy(
00177 QwtPlotRasterItem::CachePolicy policy)
00178 {
00179 if ( d_data->cache.policy != policy )
00180 {
00181 d_data->cache.policy = policy;
00182
00183 invalidateCache();
00184 itemChanged();
00185 }
00186 }
00187
00192 QwtPlotRasterItem::CachePolicy QwtPlotRasterItem::cachePolicy() const
00193 {
00194 return d_data->cache.policy;
00195 }
00196
00201 void QwtPlotRasterItem::invalidateCache()
00202 {
00203 d_data->cache.image = QImage();
00204 d_data->cache.rect = QwtDoubleRect();
00205 d_data->cache.size = QSize();
00206 }
00207
00217 QSize QwtPlotRasterItem::rasterHint(const QwtDoubleRect &) const
00218 {
00219 return QSize();
00220 }
00221
00229 void QwtPlotRasterItem::draw(QPainter *painter,
00230 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00231 const QRect &canvasRect) const
00232 {
00233 if ( canvasRect.isEmpty() || d_data->alpha == 0 )
00234 return;
00235
00236 QwtDoubleRect area = invTransform(xMap, yMap, canvasRect);
00237 if ( boundingRect().isValid() )
00238 area &= boundingRect();
00239
00240 const QRect paintRect = transform(xMap, yMap, area);
00241 if ( !paintRect.isValid() )
00242 return;
00243
00244 QImage image;
00245
00246 bool doCache = true;
00247 if ( painter->device()->devType() == QInternal::Printer
00248 || painter->device()->devType() == QInternal::Picture )
00249 {
00250 doCache = false;
00251 }
00252
00253 if ( !doCache || d_data->cache.policy == NoCache )
00254 {
00255 image = renderImage(xMap, yMap, area);
00256 if ( d_data->alpha >= 0 && d_data->alpha < 255 )
00257 image = toRgba(image, d_data->alpha);
00258
00259 }
00260 else if ( d_data->cache.policy == PaintCache )
00261 {
00262 if ( d_data->cache.image.isNull() || d_data->cache.rect != area
00263 || d_data->cache.size != paintRect.size() )
00264 {
00265 d_data->cache.image = renderImage(xMap, yMap, area);
00266 d_data->cache.rect = area;
00267 d_data->cache.size = paintRect.size();
00268 }
00269
00270 image = d_data->cache.image;
00271 if ( d_data->alpha >= 0 && d_data->alpha < 255 )
00272 image = toRgba(image, d_data->alpha);
00273 }
00274 else if ( d_data->cache.policy == ScreenCache )
00275 {
00276 const QSize screenSize =
00277 QApplication::desktop()->screenGeometry().size();
00278
00279 if ( paintRect.width() > screenSize.width() ||
00280 paintRect.height() > screenSize.height() )
00281 {
00282 image = renderImage(xMap, yMap, area);
00283 }
00284 else
00285 {
00286 if ( d_data->cache.image.isNull() || d_data->cache.rect != area )
00287 {
00288 QwtScaleMap cacheXMap = xMap;
00289 cacheXMap.setPaintInterval( 0, screenSize.width());
00290
00291 QwtScaleMap cacheYMap = yMap;
00292 cacheYMap.setPaintInterval(screenSize.height(), 0);
00293
00294 d_data->cache.image = renderImage(
00295 cacheXMap, cacheYMap, area);
00296 d_data->cache.rect = area;
00297 d_data->cache.size = paintRect.size();
00298 }
00299
00300 image = d_data->cache.image;
00301 }
00302 image = toRgba(image, d_data->alpha);
00303 }
00304
00305 painter->drawImage(paintRect, image);
00306 }