1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3
* Copyright (C) 1997 Josef Wilgen
4
* Copyright (C) 2002 Uwe Rathmann
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the Qwt License, Version 1.0
8
*****************************************************************************/
10
#include <qapplication.h>
11
#include <qdesktopwidget.h>
12
#include <qpaintdevice.h>
14
#include "qwt_legend.h"
15
#include "qwt_legend_item.h"
16
#include "qwt_scale_map.h"
17
#include "qwt_plot_rasteritem.h"
19
class QwtPlotRasterItem::PrivateData
25
cache.policy = QwtPlotRasterItem::NoCache;
32
QwtPlotRasterItem::CachePolicy policy;
39
static QImage toRgba(const QImage& image, int alpha)
41
if ( alpha < 0 || alpha >= 255 )
44
#if QT_VERSION < 0x040000
45
QImage alphaImage(image.size(), 32);
46
alphaImage.setAlphaBuffer(true);
48
QImage alphaImage(image.size(), QImage::Format_ARGB32);
51
const QRgb mask1 = qRgba(0, 0, 0, alpha);
52
const QRgb mask2 = qRgba(255, 255, 255, 0);
53
const QRgb mask3 = qRgba(0, 0, 0, 255);
55
const int w = image.size().width();
56
const int h = image.size().height();
58
if ( image.depth() == 8 )
60
for ( int y = 0; y < h; y++ )
62
QRgb* alphaLine = (QRgb*)alphaImage.scanLine(y);
63
const unsigned char *line = image.scanLine(y);
65
for ( int x = 0; x < w; x++ )
66
*alphaLine++ = (image.color(*line++) & mask2) | mask1;
69
else if ( image.depth() == 32 )
71
for ( int y = 0; y < h; y++ )
73
QRgb* alphaLine = (QRgb*)alphaImage.scanLine(y);
74
const QRgb* line = (const QRgb*) image.scanLine(y);
76
for ( int x = 0; x < w; x++ )
78
const QRgb rgb = *line++;
79
if ( rgb & mask3 ) // alpha != 0
80
*alphaLine++ = (rgb & mask2) | mask1;
91
QwtPlotRasterItem::QwtPlotRasterItem(const QString& title):
92
QwtPlotItem(QwtText(title))
98
QwtPlotRasterItem::QwtPlotRasterItem(const QwtText& title):
105
QwtPlotRasterItem::~QwtPlotRasterItem()
110
void QwtPlotRasterItem::init()
112
d_data = new PrivateData();
114
setItemAttribute(QwtPlotItem::AutoScale, true);
115
setItemAttribute(QwtPlotItem::Legend, false);
121
\brief Set an alpha value for the raster data
123
Often a plot has several types of raster data organized in layers.
124
( f.e a geographical map, with weather statistics ).
125
Using setAlpha() raster items can be stacked easily.
127
The alpha value is a value [0, 255] to
128
control the transparency of the image. 0 represents a fully
129
transparent color, while 255 represents a fully opaque color.
131
\param alpha Alpha value
134
All alpha values of the pixels returned by renderImage() will be set to
135
alpha, beside those with an alpha value of 0 (invalid pixels).
137
The alpha values returned by renderImage() are not changed.
139
The default alpha value is -1.
143
void QwtPlotRasterItem::setAlpha(int alpha)
151
if ( alpha != d_data->alpha )
153
d_data->alpha = alpha;
160
\return Alpha value of the raster item
163
int QwtPlotRasterItem::alpha() const
165
return d_data->alpha;
169
Change the cache policy
171
The default policy is NoCache
173
\param policy Cache policy
174
\sa CachePolicy, cachePolicy()
176
void QwtPlotRasterItem::setCachePolicy(
177
QwtPlotRasterItem::CachePolicy policy)
179
if ( d_data->cache.policy != policy )
181
d_data->cache.policy = policy;
190
\sa CachePolicy, setCachePolicy()
192
QwtPlotRasterItem::CachePolicy QwtPlotRasterItem::cachePolicy() const
194
return d_data->cache.policy;
198
Invalidate the paint cache
201
void QwtPlotRasterItem::invalidateCache()
203
d_data->cache.image = QImage();
204
d_data->cache.rect = QwtDoubleRect();
205
d_data->cache.size = QSize();
209
\brief Returns the recommended raster for a given rect.
211
F.e the raster hint can be used to limit the resolution of
212
the image that is rendered.
214
The default implementation returns an invalid size (QSize()),
217
QSize QwtPlotRasterItem::rasterHint(const QwtDoubleRect &) const
223
\brief Draw the raster data
224
\param painter Painter
225
\param xMap X-Scale Map
226
\param yMap Y-Scale Map
227
\param canvasRect Contents rect of the plot canvas
229
void QwtPlotRasterItem::draw(QPainter *painter,
230
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
231
const QRect &canvasRect) const
233
if ( canvasRect.isEmpty() || d_data->alpha == 0 )
236
QwtDoubleRect area = invTransform(xMap, yMap, canvasRect);
237
if ( boundingRect().isValid() )
238
area &= boundingRect();
240
const QRect paintRect = transform(xMap, yMap, area);
241
if ( !paintRect.isValid() )
247
if ( painter->device()->devType() == QInternal::Printer
248
|| painter->device()->devType() == QInternal::Picture )
253
if ( !doCache || d_data->cache.policy == NoCache )
255
image = renderImage(xMap, yMap, area);
256
if ( d_data->alpha >= 0 && d_data->alpha < 255 )
257
image = toRgba(image, d_data->alpha);
260
else if ( d_data->cache.policy == PaintCache )
262
if ( d_data->cache.image.isNull() || d_data->cache.rect != area
263
|| d_data->cache.size != paintRect.size() )
265
d_data->cache.image = renderImage(xMap, yMap, area);
266
d_data->cache.rect = area;
267
d_data->cache.size = paintRect.size();
270
image = d_data->cache.image;
271
if ( d_data->alpha >= 0 && d_data->alpha < 255 )
272
image = toRgba(image, d_data->alpha);
274
else if ( d_data->cache.policy == ScreenCache )
276
const QSize screenSize =
277
QApplication::desktop()->screenGeometry().size();
279
if ( paintRect.width() > screenSize.width() ||
280
paintRect.height() > screenSize.height() )
282
image = renderImage(xMap, yMap, area);
286
if ( d_data->cache.image.isNull() || d_data->cache.rect != area )
288
QwtScaleMap cacheXMap = xMap;
289
cacheXMap.setPaintInterval( 0, screenSize.width());
291
QwtScaleMap cacheYMap = yMap;
292
cacheYMap.setPaintInterval(screenSize.height(), 0);
294
d_data->cache.image = renderImage(
295
cacheXMap, cacheYMap, area);
296
d_data->cache.rect = area;
297
d_data->cache.size = paintRect.size();
300
image = d_data->cache.image;
302
image = toRgba(image, d_data->alpha);
305
painter->drawImage(paintRect, image);