qwt_plot_shapeitem.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
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  *****************************************************************************/
9 
10 #include "qwt_plot_shapeitem.h"
11 #include "qwt_scale_map.h"
12 #include "qwt_text.h"
13 #include "qwt_graphic.h"
14 #include "qwt_painter.h"
16 #include "qwt_clipper.h"
17 #include "qwt_math.h"
18 
19 #include <qpainter.h>
20 #include <qpainterpath.h>
21 
22 static QPainterPath qwtTransformPath( const QwtScaleMap &xMap,
23  const QwtScaleMap &yMap, const QPainterPath &path, bool doAlign )
24 {
25  QPainterPath shape;
26  shape.setFillRule( path.fillRule() );
27 
28  for ( int i = 0; i < path.elementCount(); i++ )
29  {
30  const QPainterPath::Element element = path.elementAt( i );
31 
32  double x = xMap.transform( element.x );
33  double y = yMap.transform( element.y );
34 
35  switch( element.type )
36  {
37  case QPainterPath::MoveToElement:
38  {
39  if ( doAlign )
40  {
41  x = qRound( x );
42  y = qRound( y );
43  }
44 
45  shape.moveTo( x, y );
46  break;
47  }
48  case QPainterPath::LineToElement:
49  {
50  if ( doAlign )
51  {
52  x = qRound( x );
53  y = qRound( y );
54  }
55 
56  shape.lineTo( x, y );
57  break;
58  }
59  case QPainterPath::CurveToElement:
60  {
61  const QPainterPath::Element element1 = path.elementAt( ++i );
62  const double x1 = xMap.transform( element1.x );
63  const double y1 = yMap.transform( element1.y );
64 
65  const QPainterPath::Element element2 = path.elementAt( ++i );
66  const double x2 = xMap.transform( element2.x );
67  const double y2 = yMap.transform( element2.y );
68 
69  shape.cubicTo( x, y, x1, y1, x2, y2 );
70  break;
71  }
72  case QPainterPath::CurveToDataElement:
73  {
74  break;
75  }
76  }
77  }
78 
79  return shape;
80 }
81 
82 
84 {
85 public:
88  renderTolerance( 0.0 )
89  {
90  }
91 
94 
96  QRectF boundingRect;
97 
98  QPen pen;
99  QBrush brush;
100  QPainterPath shape;
101 };
102 
113  QwtPlotItem( QwtText( title ) )
114 {
115  init();
116 }
117 
128  QwtPlotItem( title )
129 {
130  init();
131 }
132 
135 {
136  delete d_data;
137 }
138 
140 {
141  d_data = new PrivateData();
143 
146 
147  setZ( 8.0 );
148 }
149 
152 {
154 }
155 
164 {
165  if ( on )
166  d_data->paintAttributes |= attribute;
167  else
168  d_data->paintAttributes &= ~attribute;
169 }
170 
176 {
177  return ( d_data->paintAttributes & attribute );
178 }
179 
187 {
188  if ( mode != d_data->legendMode )
189  {
190  d_data->legendMode = mode;
191  legendChanged();
192  }
193 }
194 
200 {
201  return d_data->legendMode;
202 }
203 
206 {
207  return d_data->boundingRect;
208 }
209 
216 void QwtPlotShapeItem::setRect( const QRectF &rect )
217 {
218  QPainterPath path;
219  path.addRect( rect );
220 
221  setShape( path );
222 }
223 
230 void QwtPlotShapeItem::setPolygon( const QPolygonF &polygon )
231 {
232  QPainterPath shape;
233  shape.addPolygon( polygon );
234 
235  setShape( shape );
236 }
237 
244 void QwtPlotShapeItem::setShape( const QPainterPath &shape )
245 {
246  if ( shape != d_data->shape )
247  {
248  d_data->shape = shape;
249  if ( shape.isEmpty() )
250  {
252  }
253  else
254  {
255  d_data->boundingRect = shape.boundingRect();
256  }
257 
258  itemChanged();
259  }
260 }
261 
266 QPainterPath QwtPlotShapeItem::shape() const
267 {
268  return d_data->shape;
269 }
270 
284 void QwtPlotShapeItem::setPen( const QColor &color, qreal width, Qt::PenStyle style )
285 {
286  setPen( QPen( color, width, style ) );
287 }
288 
297 void QwtPlotShapeItem::setPen( const QPen &pen )
298 {
299  if ( pen != d_data->pen )
300  {
301  d_data->pen = pen;
302  itemChanged();
303  }
304 }
305 
311 {
312  return d_data->pen;
313 }
314 
323 void QwtPlotShapeItem::setBrush( const QBrush &brush )
324 {
325  if ( brush != d_data->brush )
326  {
327  d_data->brush = brush;
328  itemChanged();
329  }
330 }
331 
337 {
338  return d_data->brush;
339 }
340 
357 void QwtPlotShapeItem::setRenderTolerance( double tolerance )
358 {
359  tolerance = qwtMaxF( tolerance, 0.0 );
360 
361  if ( tolerance != d_data->renderTolerance )
362  {
363  d_data->renderTolerance = tolerance;
364  itemChanged();
365  }
366 }
367 
373 {
374  return d_data->renderTolerance;
375 }
376 
385 void QwtPlotShapeItem::draw( QPainter *painter,
386  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
387  const QRectF &canvasRect ) const
388 {
389  if ( d_data->shape.isEmpty() )
390  return;
391 
392  if ( d_data->pen.style() == Qt::NoPen
393  && d_data->brush.style() == Qt::NoBrush )
394  {
395  return;
396  }
397 
398  const QRectF cr = QwtScaleMap::invTransform(
399  xMap, yMap, canvasRect.toRect() );
400 
401  const QRectF &br = d_data->boundingRect;
402 
403  if ( ( br.left() > cr.right() ) || ( br.right() < cr.left() )
404  || ( br.top() > cr.bottom() ) || ( br.bottom() < cr.top() ) )
405  {
406  // outside the visisble area
407  return;
408  }
409 
410  const bool doAlign = QwtPainter::roundingAlignment( painter );
411 
412  QPainterPath path = qwtTransformPath( xMap, yMap,
413  d_data->shape, doAlign );
414 
416  {
417  const qreal pw = QwtPainter::effectivePenWidth( painter->pen() );
418  const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );
419 
420  QPainterPath clippedPath;
421  clippedPath.setFillRule( path.fillRule() );
422 
423  QList<QPolygonF> polygons = path.toSubpathPolygons();
424  for ( int i = 0; i < polygons.size(); i++ )
425  {
426  QwtClipper::clipPolygonF( clipRect, polygons[i], true );
427  clippedPath.addPolygon( polygons[i] );
428 
429  }
430 
431  path = clippedPath;
432  }
433 
434  if ( d_data->renderTolerance > 0.0 )
435  {
437 
438  QPainterPath fittedPath;
439  fittedPath.setFillRule( path.fillRule() );
440 
441  const QList<QPolygonF> polygons = path.toSubpathPolygons();
442  for ( int i = 0; i < polygons.size(); i++ )
443  fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) );
444 
445  path = fittedPath;
446  }
447 
448  painter->setPen( d_data->pen );
449  painter->setBrush( d_data->brush );
450 
451  painter->drawPath( path );
452 }
453 
464  const QSizeF &size ) const
465 {
466  Q_UNUSED( index );
467 
468  QwtGraphic icon;
469  icon.setDefaultSize( size );
470 
471  if ( size.isEmpty() )
472  return icon;
473 
475  {
476  const QRectF &br = d_data->boundingRect;
477 
478  QPainter painter( &icon );
479  painter.setRenderHint( QPainter::Antialiasing,
481 
482  painter.translate( -br.topLeft() );
483 
484  painter.setPen( d_data->pen );
485  painter.setBrush( d_data->brush );
486  painter.drawPath( d_data->shape );
487  }
488  else
489  {
490  QColor iconColor;
491  if ( d_data->brush.style() != Qt::NoBrush )
492  iconColor = d_data->brush.color();
493  else
494  iconColor = d_data->pen.color();
495 
496  icon = defaultIcon( iconColor, size );
497  }
498 
499  return icon;
500 }
501 
virtual void legendChanged()
Display a scaled down version of the shape.
Display a filled rectangle.
void setLegendMode(LegendMode)
QPainterPath shape() const
Enable antialiasing.
QWT_CONSTEXPR float qwtMaxF(float a, float b)
Definition: qwt_math.h:123
bool testPaintAttribute(PaintAttribute) const
LegendMode
Mode how to display the item on the legend.
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
QwtGraphic defaultIcon(const QBrush &, const QSizeF &) const
Return a default icon from a brush.
LegendMode legendMode() const
static qreal effectivePenWidth(const QPen &)
Definition: qwt_painter.h:199
virtual int rtti() const QWT_OVERRIDE
void setDefaultSize(const QSizeF &)
Set a default size.
The item is represented on the legend.
void setPaintAttribute(PaintAttribute, bool on=true)
bool testRenderHint(RenderHint) const
A curve fitter implementing Douglas and Peucker algorithm.
For QwtPlotShapeItem.
static void clipPolygonF(const QRectF &, QPolygonF &, bool closePolygon=false)
virtual void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const QWT_OVERRIDE
A class representing a text.
Definition: qwt_text.h:51
void setZ(double z)
Set the z value.
A paint device for scalable graphics.
Definition: qwt_graphic.h:75
void setRenderTolerance(double)
Set the tolerance for the weeding optimization.
void setRect(const QRectF &)
Set a path built from a rectangle.
void setPolygon(const QPolygonF &)
Set a path built from a polygon.
A scale map.
Definition: qwt_scale_map.h:26
virtual QwtGraphic legendIcon(int index, const QSizeF &) const QWT_OVERRIDE
double invTransform(double p) const
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
virtual void itemChanged()
A plot item, which displays any graphical shape, that can be defined by a QPainterPath.
QwtPlotShapeItem(const QString &title=QString())
Constructor.
QwtPlotShapeItem::PaintAttributes paintAttributes
PrivateData * d_data
QwtPlotShapeItem::LegendMode legendMode
double renderTolerance() const
static QPainterPath qwtTransformPath(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QPainterPath &path, bool doAlign)
Base class for items on the plot canvas.
Definition: qwt_plot_item.h:65
void setItemAttribute(ItemAttribute, bool on=true)
double transform(double s) const
QBrush brush() const
void setShape(const QPainterPath &)
Set the shape to be displayed.
void setBrush(const QBrush &)
virtual QPolygonF fitCurve(const QPolygonF &) const QWT_OVERRIDE
static bool roundingAlignment()
Definition: qwt_painter.h:181
virtual QRectF boundingRect() const QWT_OVERRIDE
Bounding rectangle of the shape.
virtual ~QwtPlotShapeItem()
Destructor.
const QwtText & title() const
virtual QRectF boundingRect() const


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10