qwt_plot_rasteritem.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 <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 ) // alpha != 0
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 }

Generated on Mon Feb 26 21:22:38 2007 for Qwt User's Guide by  doxygen 1.4.6