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_symbol.h"
|
---|
11 | #include "qwt_painter.h"
|
---|
12 | #include "qwt_graphic.h"
|
---|
13 | #include <qapplication.h>
|
---|
14 | #include <qpainter.h>
|
---|
15 | #include <qpainterpath.h>
|
---|
16 | #include <qpixmap.h>
|
---|
17 | #include <qpaintengine.h>
|
---|
18 | #include <qmath.h>
|
---|
19 | #ifndef QWT_NO_SVG
|
---|
20 | #include <qsvgrenderer.h>
|
---|
21 | #endif
|
---|
22 |
|
---|
23 | namespace QwtTriangle
|
---|
24 | {
|
---|
25 | enum Type
|
---|
26 | {
|
---|
27 | Left,
|
---|
28 | Right,
|
---|
29 | Up,
|
---|
30 | Down
|
---|
31 | };
|
---|
32 | }
|
---|
33 |
|
---|
34 | static QwtGraphic qwtPathGraphic( const QPainterPath &path,
|
---|
35 | const QPen &pen, const QBrush& brush )
|
---|
36 | {
|
---|
37 | QwtGraphic graphic;
|
---|
38 | graphic.setRenderHint( QwtGraphic::RenderPensUnscaled );
|
---|
39 |
|
---|
40 | QPainter painter( &graphic );
|
---|
41 | painter.setPen( pen );
|
---|
42 | painter.setBrush( brush );
|
---|
43 | painter.drawPath( path );
|
---|
44 | painter.end();
|
---|
45 |
|
---|
46 | return graphic;
|
---|
47 | }
|
---|
48 |
|
---|
49 | static inline QRectF qwtScaledBoundingRect(
|
---|
50 | const QwtGraphic &graphic, const QSizeF size )
|
---|
51 | {
|
---|
52 | QSizeF scaledSize = size;
|
---|
53 | if ( scaledSize.isEmpty() )
|
---|
54 | scaledSize = graphic.defaultSize();
|
---|
55 |
|
---|
56 | const QSizeF sz = graphic.controlPointRect().size();
|
---|
57 |
|
---|
58 | double sx = 1.0;
|
---|
59 | if ( sz.width() > 0.0 )
|
---|
60 | sx = scaledSize.width() / sz.width();
|
---|
61 |
|
---|
62 | double sy = 1.0;
|
---|
63 | if ( sz.height() > 0.0 )
|
---|
64 | sy = scaledSize.height() / sz.height();
|
---|
65 |
|
---|
66 | return graphic.scaledBoundingRect( sx, sy );
|
---|
67 | }
|
---|
68 |
|
---|
69 | static inline void qwtDrawPixmapSymbols( QPainter *painter,
|
---|
70 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
71 | {
|
---|
72 | QSize size = symbol.size();
|
---|
73 | if ( size.isEmpty() )
|
---|
74 | size = symbol.pixmap().size();
|
---|
75 |
|
---|
76 | const QTransform transform = painter->transform();
|
---|
77 | if ( transform.isScaling() )
|
---|
78 | {
|
---|
79 | const QRect r( 0, 0, size.width(), size.height() );
|
---|
80 | size = transform.mapRect( r ).size();
|
---|
81 | }
|
---|
82 |
|
---|
83 | QPixmap pm = symbol.pixmap();
|
---|
84 | if ( pm.size() != size )
|
---|
85 | pm = pm.scaled( size );
|
---|
86 |
|
---|
87 | QPointF pinPoint( 0.5 * size.width(), 0.5 * size.height() );
|
---|
88 | if ( symbol.isPinPointEnabled() )
|
---|
89 | pinPoint = symbol.pinPoint();
|
---|
90 |
|
---|
91 | painter->resetTransform();
|
---|
92 |
|
---|
93 | for ( int i = 0; i < numPoints; i++ )
|
---|
94 | {
|
---|
95 | const QPointF pos = transform.map( points[i] ) - pinPoint;
|
---|
96 |
|
---|
97 | QwtPainter::drawPixmap( painter,
|
---|
98 | QRect( pos.toPoint(), pm.size() ), pm );
|
---|
99 | }
|
---|
100 | }
|
---|
101 |
|
---|
102 | #ifndef QWT_NO_SVG
|
---|
103 |
|
---|
104 | static inline void qwtDrawSvgSymbols( QPainter *painter,
|
---|
105 | const QPointF *points, int numPoints,
|
---|
106 | QSvgRenderer *renderer, const QwtSymbol &symbol )
|
---|
107 | {
|
---|
108 | if ( renderer == NULL || !renderer->isValid() )
|
---|
109 | return;
|
---|
110 |
|
---|
111 | const QRectF viewBox = renderer->viewBoxF();
|
---|
112 | if ( viewBox.isEmpty() )
|
---|
113 | return;
|
---|
114 |
|
---|
115 | QSizeF sz = symbol.size();
|
---|
116 | if ( !sz.isValid() )
|
---|
117 | sz = viewBox.size();
|
---|
118 |
|
---|
119 | const double sx = sz.width() / viewBox.width();
|
---|
120 | const double sy = sz.height() / viewBox.height();
|
---|
121 |
|
---|
122 | QPointF pinPoint = viewBox.center();
|
---|
123 | if ( symbol.isPinPointEnabled() )
|
---|
124 | pinPoint = symbol.pinPoint();
|
---|
125 |
|
---|
126 | const double dx = sx * ( pinPoint.x() - viewBox.left() );
|
---|
127 | const double dy = sy * ( pinPoint.y() - viewBox.top() );
|
---|
128 |
|
---|
129 | for ( int i = 0; i < numPoints; i++ )
|
---|
130 | {
|
---|
131 | const double x = points[i].x() - dx;
|
---|
132 | const double y = points[i].y() - dy;
|
---|
133 |
|
---|
134 | renderer->render( painter,
|
---|
135 | QRectF( x, y, sz.width(), sz.height() ) );
|
---|
136 | }
|
---|
137 | }
|
---|
138 |
|
---|
139 | #endif
|
---|
140 |
|
---|
141 | static inline void qwtDrawGraphicSymbols( QPainter *painter,
|
---|
142 | const QPointF *points, int numPoints, const QwtGraphic &graphic,
|
---|
143 | const QwtSymbol &symbol )
|
---|
144 | {
|
---|
145 | const QRectF pointRect = graphic.controlPointRect();
|
---|
146 | if ( pointRect.isEmpty() )
|
---|
147 | return;
|
---|
148 |
|
---|
149 | double sx = 1.0;
|
---|
150 | double sy = 1.0;
|
---|
151 |
|
---|
152 | const QSize sz = symbol.size();
|
---|
153 | if ( sz.isValid() )
|
---|
154 | {
|
---|
155 | sx = sz.width() / pointRect.width();
|
---|
156 | sy = sz.height() / pointRect.height();
|
---|
157 | }
|
---|
158 |
|
---|
159 | QPointF pinPoint = pointRect.center();
|
---|
160 | if ( symbol.isPinPointEnabled() )
|
---|
161 | pinPoint = symbol.pinPoint();
|
---|
162 |
|
---|
163 | const QTransform transform = painter->transform();
|
---|
164 |
|
---|
165 | for ( int i = 0; i < numPoints; i++ )
|
---|
166 | {
|
---|
167 | QTransform tr = transform;
|
---|
168 | tr.translate( points[i].x(), points[i].y() );
|
---|
169 | tr.scale( sx, sy );
|
---|
170 | tr.translate( -pinPoint.x(), -pinPoint.y() );
|
---|
171 |
|
---|
172 | painter->setTransform( tr );
|
---|
173 |
|
---|
174 | graphic.render( painter );
|
---|
175 | }
|
---|
176 |
|
---|
177 | painter->setTransform( transform );
|
---|
178 | }
|
---|
179 |
|
---|
180 | static inline void qwtDrawEllipseSymbols( QPainter *painter,
|
---|
181 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
182 | {
|
---|
183 | painter->setBrush( symbol.brush() );
|
---|
184 | painter->setPen( symbol.pen() );
|
---|
185 |
|
---|
186 | const QSize size = symbol.size();
|
---|
187 |
|
---|
188 | if ( QwtPainter::roundingAlignment( painter ) )
|
---|
189 | {
|
---|
190 | const int sw = size.width();
|
---|
191 | const int sh = size.height();
|
---|
192 | const int sw2 = size.width() / 2;
|
---|
193 | const int sh2 = size.height() / 2;
|
---|
194 |
|
---|
195 | for ( int i = 0; i < numPoints; i++ )
|
---|
196 | {
|
---|
197 | const int x = qRound( points[i].x() );
|
---|
198 | const int y = qRound( points[i].y() );
|
---|
199 |
|
---|
200 | const QRectF r( x - sw2, y - sh2, sw, sh );
|
---|
201 | QwtPainter::drawEllipse( painter, r );
|
---|
202 | }
|
---|
203 | }
|
---|
204 | else
|
---|
205 | {
|
---|
206 | const double sw = size.width();
|
---|
207 | const double sh = size.height();
|
---|
208 | const double sw2 = 0.5 * size.width();
|
---|
209 | const double sh2 = 0.5 * size.height();
|
---|
210 |
|
---|
211 | for ( int i = 0; i < numPoints; i++ )
|
---|
212 | {
|
---|
213 | const double x = points[i].x();
|
---|
214 | const double y = points[i].y();
|
---|
215 |
|
---|
216 | const QRectF r( x - sw2, y - sh2, sw, sh );
|
---|
217 | QwtPainter::drawEllipse( painter, r );
|
---|
218 | }
|
---|
219 | }
|
---|
220 | }
|
---|
221 |
|
---|
222 | static inline void qwtDrawRectSymbols( QPainter *painter,
|
---|
223 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
224 | {
|
---|
225 | const QSize size = symbol.size();
|
---|
226 |
|
---|
227 | QPen pen = symbol.pen();
|
---|
228 | pen.setJoinStyle( Qt::MiterJoin );
|
---|
229 | painter->setPen( pen );
|
---|
230 | painter->setBrush( symbol.brush() );
|
---|
231 | painter->setRenderHint( QPainter::Antialiasing, false );
|
---|
232 |
|
---|
233 | if ( QwtPainter::roundingAlignment( painter ) )
|
---|
234 | {
|
---|
235 | const int sw = size.width();
|
---|
236 | const int sh = size.height();
|
---|
237 | const int sw2 = size.width() / 2;
|
---|
238 | const int sh2 = size.height() / 2;
|
---|
239 |
|
---|
240 | for ( int i = 0; i < numPoints; i++ )
|
---|
241 | {
|
---|
242 | const int x = qRound( points[i].x() );
|
---|
243 | const int y = qRound( points[i].y() );
|
---|
244 |
|
---|
245 | const QRect r( x - sw2, y - sh2, sw, sh );
|
---|
246 | QwtPainter::drawRect( painter, r );
|
---|
247 | }
|
---|
248 | }
|
---|
249 | else
|
---|
250 | {
|
---|
251 | const double sw = size.width();
|
---|
252 | const double sh = size.height();
|
---|
253 | const double sw2 = 0.5 * size.width();
|
---|
254 | const double sh2 = 0.5 * size.height();
|
---|
255 |
|
---|
256 | for ( int i = 0; i < numPoints; i++ )
|
---|
257 | {
|
---|
258 | const double x = points[i].x();
|
---|
259 | const double y = points[i].y();
|
---|
260 |
|
---|
261 | const QRectF r( x - sw2, y - sh2, sw, sh );
|
---|
262 | QwtPainter::drawRect( painter, r );
|
---|
263 | }
|
---|
264 | }
|
---|
265 | }
|
---|
266 |
|
---|
267 | static inline void qwtDrawDiamondSymbols( QPainter *painter,
|
---|
268 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
269 | {
|
---|
270 | const QSize size = symbol.size();
|
---|
271 |
|
---|
272 | QPen pen = symbol.pen();
|
---|
273 | pen.setJoinStyle( Qt::MiterJoin );
|
---|
274 | painter->setPen( pen );
|
---|
275 | painter->setBrush( symbol.brush() );
|
---|
276 |
|
---|
277 | if ( QwtPainter::roundingAlignment( painter ) )
|
---|
278 | {
|
---|
279 | for ( int i = 0; i < numPoints; i++ )
|
---|
280 | {
|
---|
281 | const int x = qRound( points[i].x() );
|
---|
282 | const int y = qRound( points[i].y() );
|
---|
283 |
|
---|
284 | const int x1 = x - size.width() / 2;
|
---|
285 | const int y1 = y - size.height() / 2;
|
---|
286 | const int x2 = x1 + size.width();
|
---|
287 | const int y2 = y1 + size.height();
|
---|
288 |
|
---|
289 | QPolygonF polygon;
|
---|
290 | polygon += QPointF( x, y1 );
|
---|
291 | polygon += QPointF( x1, y );
|
---|
292 | polygon += QPointF( x, y2 );
|
---|
293 | polygon += QPointF( x2, y );
|
---|
294 |
|
---|
295 | QwtPainter::drawPolygon( painter, polygon );
|
---|
296 | }
|
---|
297 | }
|
---|
298 | else
|
---|
299 | {
|
---|
300 | for ( int i = 0; i < numPoints; i++ )
|
---|
301 | {
|
---|
302 | const QPointF &pos = points[i];
|
---|
303 |
|
---|
304 | const double x1 = pos.x() - 0.5 * size.width();
|
---|
305 | const double y1 = pos.y() - 0.5 * size.height();
|
---|
306 | const double x2 = x1 + size.width();
|
---|
307 | const double y2 = y1 + size.height();
|
---|
308 |
|
---|
309 | QPolygonF polygon;
|
---|
310 | polygon += QPointF( pos.x(), y1 );
|
---|
311 | polygon += QPointF( x2, pos.y() );
|
---|
312 | polygon += QPointF( pos.x(), y2 );
|
---|
313 | polygon += QPointF( x1, pos.y() );
|
---|
314 |
|
---|
315 | QwtPainter::drawPolygon( painter, polygon );
|
---|
316 | }
|
---|
317 | }
|
---|
318 | }
|
---|
319 |
|
---|
320 | static inline void qwtDrawTriangleSymbols(
|
---|
321 | QPainter *painter, QwtTriangle::Type type,
|
---|
322 | const QPointF *points, int numPoints,
|
---|
323 | const QwtSymbol &symbol )
|
---|
324 | {
|
---|
325 | const QSize size = symbol.size();
|
---|
326 |
|
---|
327 | QPen pen = symbol.pen();
|
---|
328 | pen.setJoinStyle( Qt::MiterJoin );
|
---|
329 | painter->setPen( pen );
|
---|
330 |
|
---|
331 | painter->setBrush( symbol.brush() );
|
---|
332 |
|
---|
333 | const bool doAlign = QwtPainter::roundingAlignment( painter );
|
---|
334 |
|
---|
335 | double sw2 = 0.5 * size.width();
|
---|
336 | double sh2 = 0.5 * size.height();
|
---|
337 |
|
---|
338 | if ( doAlign )
|
---|
339 | {
|
---|
340 | sw2 = qFloor( sw2 );
|
---|
341 | sh2 = qFloor( sh2 );
|
---|
342 | }
|
---|
343 |
|
---|
344 | QPolygonF triangle( 3 );
|
---|
345 | QPointF *trianglePoints = triangle.data();
|
---|
346 |
|
---|
347 | for ( int i = 0; i < numPoints; i++ )
|
---|
348 | {
|
---|
349 | const QPointF &pos = points[i];
|
---|
350 |
|
---|
351 | double x = pos.x();
|
---|
352 | double y = pos.y();
|
---|
353 |
|
---|
354 | if ( doAlign )
|
---|
355 | {
|
---|
356 | x = qRound( x );
|
---|
357 | y = qRound( y );
|
---|
358 | }
|
---|
359 |
|
---|
360 | const double x1 = x - sw2;
|
---|
361 | const double x2 = x1 + size.width();
|
---|
362 | const double y1 = y - sh2;
|
---|
363 | const double y2 = y1 + size.height();
|
---|
364 |
|
---|
365 | switch ( type )
|
---|
366 | {
|
---|
367 | case QwtTriangle::Left:
|
---|
368 | {
|
---|
369 | trianglePoints[0].rx() = x2;
|
---|
370 | trianglePoints[0].ry() = y1;
|
---|
371 |
|
---|
372 | trianglePoints[1].rx() = x1;
|
---|
373 | trianglePoints[1].ry() = y;
|
---|
374 |
|
---|
375 | trianglePoints[2].rx() = x2;
|
---|
376 | trianglePoints[2].ry() = y2;
|
---|
377 |
|
---|
378 | break;
|
---|
379 | }
|
---|
380 | case QwtTriangle::Right:
|
---|
381 | {
|
---|
382 | trianglePoints[0].rx() = x1;
|
---|
383 | trianglePoints[0].ry() = y1;
|
---|
384 |
|
---|
385 | trianglePoints[1].rx() = x2;
|
---|
386 | trianglePoints[1].ry() = y;
|
---|
387 |
|
---|
388 | trianglePoints[2].rx() = x1;
|
---|
389 | trianglePoints[2].ry() = y2;
|
---|
390 |
|
---|
391 | break;
|
---|
392 | }
|
---|
393 | case QwtTriangle::Up:
|
---|
394 | {
|
---|
395 | trianglePoints[0].rx() = x1;
|
---|
396 | trianglePoints[0].ry() = y2;
|
---|
397 |
|
---|
398 | trianglePoints[1].rx() = x;
|
---|
399 | trianglePoints[1].ry() = y1;
|
---|
400 |
|
---|
401 | trianglePoints[2].rx() = x2;
|
---|
402 | trianglePoints[2].ry() = y2;
|
---|
403 |
|
---|
404 | break;
|
---|
405 | }
|
---|
406 | case QwtTriangle::Down:
|
---|
407 | {
|
---|
408 | trianglePoints[0].rx() = x1;
|
---|
409 | trianglePoints[0].ry() = y1;
|
---|
410 |
|
---|
411 | trianglePoints[1].rx() = x;
|
---|
412 | trianglePoints[1].ry() = y2;
|
---|
413 |
|
---|
414 | trianglePoints[2].rx() = x2;
|
---|
415 | trianglePoints[2].ry() = y1;
|
---|
416 |
|
---|
417 | break;
|
---|
418 | }
|
---|
419 | }
|
---|
420 | QwtPainter::drawPolygon( painter, triangle );
|
---|
421 | }
|
---|
422 | }
|
---|
423 |
|
---|
424 | static inline void qwtDrawLineSymbols(
|
---|
425 | QPainter *painter, int orientations,
|
---|
426 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
427 | {
|
---|
428 | const QSize size = symbol.size();
|
---|
429 |
|
---|
430 | int off = 0;
|
---|
431 |
|
---|
432 | QPen pen = symbol.pen();
|
---|
433 | if ( pen.width() > 1 )
|
---|
434 | {
|
---|
435 | pen.setCapStyle( Qt::FlatCap );
|
---|
436 | off = 1;
|
---|
437 | }
|
---|
438 |
|
---|
439 | painter->setPen( pen );
|
---|
440 | painter->setRenderHint( QPainter::Antialiasing, false );
|
---|
441 |
|
---|
442 | if ( QwtPainter::roundingAlignment( painter ) )
|
---|
443 | {
|
---|
444 | const int sw = qFloor( size.width() );
|
---|
445 | const int sh = qFloor( size.height() );
|
---|
446 | const int sw2 = size.width() / 2;
|
---|
447 | const int sh2 = size.height() / 2;
|
---|
448 |
|
---|
449 | for ( int i = 0; i < numPoints; i++ )
|
---|
450 | {
|
---|
451 | if ( orientations & Qt::Horizontal )
|
---|
452 | {
|
---|
453 | const int x = qRound( points[i].x() ) - sw2;
|
---|
454 | const int y = qRound( points[i].y() );
|
---|
455 |
|
---|
456 | QwtPainter::drawLine( painter, x, y, x + sw + off, y );
|
---|
457 | }
|
---|
458 | if ( orientations & Qt::Vertical )
|
---|
459 | {
|
---|
460 | const int x = qRound( points[i].x() );
|
---|
461 | const int y = qRound( points[i].y() ) - sh2;
|
---|
462 |
|
---|
463 | QwtPainter::drawLine( painter, x, y, x, y + sh + off );
|
---|
464 | }
|
---|
465 | }
|
---|
466 | }
|
---|
467 | else
|
---|
468 | {
|
---|
469 | const double sw = size.width();
|
---|
470 | const double sh = size.height();
|
---|
471 | const double sw2 = 0.5 * size.width();
|
---|
472 | const double sh2 = 0.5 * size.height();
|
---|
473 |
|
---|
474 | for ( int i = 0; i < numPoints; i++ )
|
---|
475 | {
|
---|
476 | if ( orientations & Qt::Horizontal )
|
---|
477 | {
|
---|
478 | const double x = points[i].x() - sw2;
|
---|
479 | const double y = points[i].y();
|
---|
480 |
|
---|
481 | QwtPainter::drawLine( painter, x, y, x + sw, y );
|
---|
482 | }
|
---|
483 | if ( orientations & Qt::Vertical )
|
---|
484 | {
|
---|
485 | const double y = points[i].y() - sh2;
|
---|
486 | const double x = points[i].x();
|
---|
487 |
|
---|
488 | QwtPainter::drawLine( painter, x, y, x, y + sh );
|
---|
489 | }
|
---|
490 | }
|
---|
491 | }
|
---|
492 | }
|
---|
493 |
|
---|
494 | static inline void qwtDrawXCrossSymbols( QPainter *painter,
|
---|
495 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
496 | {
|
---|
497 | const QSize size = symbol.size();
|
---|
498 | int off = 0;
|
---|
499 |
|
---|
500 | QPen pen = symbol.pen();
|
---|
501 | if ( pen.width() > 1 )
|
---|
502 | {
|
---|
503 | pen.setCapStyle( Qt::FlatCap );
|
---|
504 | off = 1;
|
---|
505 | }
|
---|
506 | painter->setPen( pen );
|
---|
507 |
|
---|
508 |
|
---|
509 | if ( QwtPainter::roundingAlignment( painter ) )
|
---|
510 | {
|
---|
511 | const int sw = size.width();
|
---|
512 | const int sh = size.height();
|
---|
513 | const int sw2 = size.width() / 2;
|
---|
514 | const int sh2 = size.height() / 2;
|
---|
515 |
|
---|
516 | for ( int i = 0; i < numPoints; i++ )
|
---|
517 | {
|
---|
518 | const QPointF &pos = points[i];
|
---|
519 |
|
---|
520 | const int x = qRound( pos.x() );
|
---|
521 | const int y = qRound( pos.y() );
|
---|
522 |
|
---|
523 | const int x1 = x - sw2;
|
---|
524 | const int x2 = x1 + sw + off;
|
---|
525 | const int y1 = y - sh2;
|
---|
526 | const int y2 = y1 + sh + off;
|
---|
527 |
|
---|
528 | QwtPainter::drawLine( painter, x1, y1, x2, y2 );
|
---|
529 | QwtPainter::drawLine( painter, x2, y1, x1, y2 );
|
---|
530 | }
|
---|
531 | }
|
---|
532 | else
|
---|
533 | {
|
---|
534 | const double sw = size.width();
|
---|
535 | const double sh = size.height();
|
---|
536 | const double sw2 = 0.5 * size.width();
|
---|
537 | const double sh2 = 0.5 * size.height();
|
---|
538 |
|
---|
539 | for ( int i = 0; i < numPoints; i++ )
|
---|
540 | {
|
---|
541 | const QPointF &pos = points[i];
|
---|
542 |
|
---|
543 | const double x1 = pos.x() - sw2;
|
---|
544 | const double x2 = x1 + sw;
|
---|
545 | const double y1 = pos.y() - sh2;
|
---|
546 | const double y2 = y1 + sh;
|
---|
547 |
|
---|
548 | QwtPainter::drawLine( painter, x1, y1, x2, y2 );
|
---|
549 | QwtPainter::drawLine( painter, x1, y2, x2, y1 );
|
---|
550 | }
|
---|
551 | }
|
---|
552 | }
|
---|
553 |
|
---|
554 | static inline void qwtDrawStar1Symbols( QPainter *painter,
|
---|
555 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
556 | {
|
---|
557 | const QSize size = symbol.size();
|
---|
558 | painter->setPen( symbol.pen() );
|
---|
559 |
|
---|
560 | if ( QwtPainter::roundingAlignment( painter ) )
|
---|
561 | {
|
---|
562 | QRect r( 0, 0, size.width(), size.height() );
|
---|
563 |
|
---|
564 | for ( int i = 0; i < numPoints; i++ )
|
---|
565 | {
|
---|
566 | r.moveCenter( points[i].toPoint() );
|
---|
567 |
|
---|
568 | const double sqrt1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
|
---|
569 |
|
---|
570 | const double d1 = r.width() / 2.0 * ( 1.0 - sqrt1_2 );
|
---|
571 |
|
---|
572 | QwtPainter::drawLine( painter,
|
---|
573 | qRound( r.left() + d1 ), qRound( r.top() + d1 ),
|
---|
574 | qRound( r.right() - d1 ), qRound( r.bottom() - d1 ) );
|
---|
575 | QwtPainter::drawLine( painter,
|
---|
576 | qRound( r.left() + d1 ), qRound( r.bottom() - d1 ),
|
---|
577 | qRound( r .right() - d1), qRound( r.top() + d1 ) );
|
---|
578 |
|
---|
579 | const QPoint c = r.center();
|
---|
580 |
|
---|
581 | QwtPainter::drawLine( painter,
|
---|
582 | c.x(), r.top(), c.x(), r.bottom() );
|
---|
583 | QwtPainter::drawLine( painter,
|
---|
584 | r.left(), c.y(), r.right(), c.y() );
|
---|
585 | }
|
---|
586 | }
|
---|
587 | else
|
---|
588 | {
|
---|
589 | QRectF r( 0, 0, size.width(), size.height() );
|
---|
590 |
|
---|
591 | for ( int i = 0; i < numPoints; i++ )
|
---|
592 | {
|
---|
593 | r.moveCenter( points[i] );
|
---|
594 |
|
---|
595 | const double sqrt1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
|
---|
596 |
|
---|
597 | const QPointF c = r.center();
|
---|
598 | const double d1 = r.width() / 2.0 * ( 1.0 - sqrt1_2 );
|
---|
599 |
|
---|
600 | QwtPainter::drawLine( painter,
|
---|
601 | r.left() + d1, r.top() + d1,
|
---|
602 | r.right() - d1, r.bottom() - d1 );
|
---|
603 | QwtPainter::drawLine( painter,
|
---|
604 | r.left() + d1, r.bottom() - d1,
|
---|
605 | r.right() - d1, r.top() + d1 );
|
---|
606 | QwtPainter::drawLine( painter,
|
---|
607 | c.x(), r.top(),
|
---|
608 | c.x(), r.bottom() );
|
---|
609 | QwtPainter::drawLine( painter,
|
---|
610 | r.left(), c.y(),
|
---|
611 | r.right(), c.y() );
|
---|
612 | }
|
---|
613 | }
|
---|
614 | }
|
---|
615 |
|
---|
616 | static inline void qwtDrawStar2Symbols( QPainter *painter,
|
---|
617 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
618 | {
|
---|
619 | QPen pen = symbol.pen();
|
---|
620 | if ( pen.width() > 1 )
|
---|
621 | pen.setCapStyle( Qt::FlatCap );
|
---|
622 | pen.setJoinStyle( Qt::MiterJoin );
|
---|
623 | painter->setPen( pen );
|
---|
624 |
|
---|
625 | painter->setBrush( symbol.brush() );
|
---|
626 |
|
---|
627 | const double cos30 = 0.866025; // cos(30°)
|
---|
628 |
|
---|
629 | const double dy = 0.25 * symbol.size().height();
|
---|
630 | const double dx = 0.5 * symbol.size().width() * cos30 / 3.0;
|
---|
631 |
|
---|
632 | QPolygonF star( 12 );
|
---|
633 | QPointF *starPoints = star.data();
|
---|
634 |
|
---|
635 | const bool doAlign = QwtPainter::roundingAlignment( painter );
|
---|
636 |
|
---|
637 | for ( int i = 0; i < numPoints; i++ )
|
---|
638 | {
|
---|
639 | double x = points[i].x();
|
---|
640 | double y = points[i].y();
|
---|
641 | if ( doAlign )
|
---|
642 | {
|
---|
643 | x = qRound( x );
|
---|
644 | y = qRound( y );
|
---|
645 | }
|
---|
646 |
|
---|
647 | double x1 = x - 3 * dx;
|
---|
648 | double y1 = y - 2 * dy;
|
---|
649 | if ( doAlign )
|
---|
650 | {
|
---|
651 | x1 = qRound( x - 3 * dx );
|
---|
652 | y1 = qRound( y - 2 * dy );
|
---|
653 | }
|
---|
654 |
|
---|
655 | const double x2 = x1 + 1 * dx;
|
---|
656 | const double x3 = x1 + 2 * dx;
|
---|
657 | const double x4 = x1 + 3 * dx;
|
---|
658 | const double x5 = x1 + 4 * dx;
|
---|
659 | const double x6 = x1 + 5 * dx;
|
---|
660 | const double x7 = x1 + 6 * dx;
|
---|
661 |
|
---|
662 | const double y2 = y1 + 1 * dy;
|
---|
663 | const double y3 = y1 + 2 * dy;
|
---|
664 | const double y4 = y1 + 3 * dy;
|
---|
665 | const double y5 = y1 + 4 * dy;
|
---|
666 |
|
---|
667 | starPoints[0].rx() = x4;
|
---|
668 | starPoints[0].ry() = y1;
|
---|
669 |
|
---|
670 | starPoints[1].rx() = x5;
|
---|
671 | starPoints[1].ry() = y2;
|
---|
672 |
|
---|
673 | starPoints[2].rx() = x7;
|
---|
674 | starPoints[2].ry() = y2;
|
---|
675 |
|
---|
676 | starPoints[3].rx() = x6;
|
---|
677 | starPoints[3].ry() = y3;
|
---|
678 |
|
---|
679 | starPoints[4].rx() = x7;
|
---|
680 | starPoints[4].ry() = y4;
|
---|
681 |
|
---|
682 | starPoints[5].rx() = x5;
|
---|
683 | starPoints[5].ry() = y4;
|
---|
684 |
|
---|
685 | starPoints[6].rx() = x4;
|
---|
686 | starPoints[6].ry() = y5;
|
---|
687 |
|
---|
688 | starPoints[7].rx() = x3;
|
---|
689 | starPoints[7].ry() = y4;
|
---|
690 |
|
---|
691 | starPoints[8].rx() = x1;
|
---|
692 | starPoints[8].ry() = y4;
|
---|
693 |
|
---|
694 | starPoints[9].rx() = x2;
|
---|
695 | starPoints[9].ry() = y3;
|
---|
696 |
|
---|
697 | starPoints[10].rx() = x1;
|
---|
698 | starPoints[10].ry() = y2;
|
---|
699 |
|
---|
700 | starPoints[11].rx() = x3;
|
---|
701 | starPoints[11].ry() = y2;
|
---|
702 |
|
---|
703 | QwtPainter::drawPolygon( painter, star );
|
---|
704 | }
|
---|
705 | }
|
---|
706 |
|
---|
707 | static inline void qwtDrawHexagonSymbols( QPainter *painter,
|
---|
708 | const QPointF *points, int numPoints, const QwtSymbol &symbol )
|
---|
709 | {
|
---|
710 | painter->setBrush( symbol.brush() );
|
---|
711 | painter->setPen( symbol.pen() );
|
---|
712 |
|
---|
713 | const double cos30 = 0.866025; // cos(30°)
|
---|
714 | const double dx = 0.5 * ( symbol.size().width() - cos30 );
|
---|
715 |
|
---|
716 | const double dy = 0.25 * symbol.size().height();
|
---|
717 |
|
---|
718 | QPolygonF hexaPolygon( 6 );
|
---|
719 | QPointF *hexaPoints = hexaPolygon.data();
|
---|
720 |
|
---|
721 | const bool doAlign = QwtPainter::roundingAlignment( painter );
|
---|
722 |
|
---|
723 | for ( int i = 0; i < numPoints; i++ )
|
---|
724 | {
|
---|
725 | double x = points[i].x();
|
---|
726 | double y = points[i].y();
|
---|
727 | if ( doAlign )
|
---|
728 | {
|
---|
729 | x = qRound( x );
|
---|
730 | y = qRound( y );
|
---|
731 | }
|
---|
732 |
|
---|
733 | double x1 = x - dx;
|
---|
734 | double y1 = y - 2 * dy;
|
---|
735 | if ( doAlign )
|
---|
736 | {
|
---|
737 | x1 = qCeil( x1 );
|
---|
738 | y1 = qCeil( y1 );
|
---|
739 | }
|
---|
740 |
|
---|
741 | const double x2 = x1 + 1 * dx;
|
---|
742 | const double x3 = x1 + 2 * dx;
|
---|
743 |
|
---|
744 | const double y2 = y1 + 1 * dy;
|
---|
745 | const double y3 = y1 + 3 * dy;
|
---|
746 | const double y4 = y1 + 4 * dy;
|
---|
747 |
|
---|
748 | hexaPoints[0].rx() = x2;
|
---|
749 | hexaPoints[0].ry() = y1;
|
---|
750 |
|
---|
751 | hexaPoints[1].rx() = x3;
|
---|
752 | hexaPoints[1].ry() = y2;
|
---|
753 |
|
---|
754 | hexaPoints[2].rx() = x3;
|
---|
755 | hexaPoints[2].ry() = y3;
|
---|
756 |
|
---|
757 | hexaPoints[3].rx() = x2;
|
---|
758 | hexaPoints[3].ry() = y4;
|
---|
759 |
|
---|
760 | hexaPoints[4].rx() = x1;
|
---|
761 | hexaPoints[4].ry() = y3;
|
---|
762 |
|
---|
763 | hexaPoints[5].rx() = x1;
|
---|
764 | hexaPoints[5].ry() = y2;
|
---|
765 |
|
---|
766 | QwtPainter::drawPolygon( painter, hexaPolygon );
|
---|
767 | }
|
---|
768 | }
|
---|
769 |
|
---|
770 | class QwtSymbol::PrivateData
|
---|
771 | {
|
---|
772 | public:
|
---|
773 | PrivateData( QwtSymbol::Style st, const QBrush &br,
|
---|
774 | const QPen &pn, const QSize &sz ):
|
---|
775 | style( st ),
|
---|
776 | size( sz ),
|
---|
777 | brush( br ),
|
---|
778 | pen( pn ),
|
---|
779 | isPinPointEnabled( false )
|
---|
780 | {
|
---|
781 | cache.policy = QwtSymbol::AutoCache;
|
---|
782 | #ifndef QWT_NO_SVG
|
---|
783 | svg.renderer = NULL;
|
---|
784 | #endif
|
---|
785 | }
|
---|
786 |
|
---|
787 | ~PrivateData()
|
---|
788 | {
|
---|
789 | #ifndef QWT_NO_SVG
|
---|
790 | delete svg.renderer;
|
---|
791 | #endif
|
---|
792 | }
|
---|
793 |
|
---|
794 | Style style;
|
---|
795 | QSize size;
|
---|
796 | QBrush brush;
|
---|
797 | QPen pen;
|
---|
798 |
|
---|
799 | bool isPinPointEnabled;
|
---|
800 | QPointF pinPoint;
|
---|
801 |
|
---|
802 | struct Path
|
---|
803 | {
|
---|
804 | QPainterPath path;
|
---|
805 | QwtGraphic graphic;
|
---|
806 |
|
---|
807 | } path;
|
---|
808 |
|
---|
809 | struct Pixmap
|
---|
810 | {
|
---|
811 | QPixmap pixmap;
|
---|
812 |
|
---|
813 | } pixmap;
|
---|
814 |
|
---|
815 | struct Graphic
|
---|
816 | {
|
---|
817 | QwtGraphic graphic;
|
---|
818 |
|
---|
819 | } graphic;
|
---|
820 |
|
---|
821 | #ifndef QWT_NO_SVG
|
---|
822 | struct SVG
|
---|
823 | {
|
---|
824 | QSvgRenderer *renderer;
|
---|
825 | } svg;
|
---|
826 | #endif
|
---|
827 |
|
---|
828 | struct PaintCache
|
---|
829 | {
|
---|
830 | QwtSymbol::CachePolicy policy;
|
---|
831 | QPixmap pixmap;
|
---|
832 |
|
---|
833 | } cache;
|
---|
834 | };
|
---|
835 |
|
---|
836 | /*!
|
---|
837 | Default Constructor
|
---|
838 | \param style Symbol Style
|
---|
839 |
|
---|
840 | The symbol is constructed with gray interior,
|
---|
841 | black outline with zero width, no size and style 'NoSymbol'.
|
---|
842 | */
|
---|
843 | QwtSymbol::QwtSymbol( Style style )
|
---|
844 | {
|
---|
845 | d_data = new PrivateData( style, QBrush( Qt::gray ),
|
---|
846 | QPen( Qt::black, 0 ), QSize() );
|
---|
847 | }
|
---|
848 |
|
---|
849 | /*!
|
---|
850 | \brief Constructor
|
---|
851 | \param style Symbol Style
|
---|
852 | \param brush brush to fill the interior
|
---|
853 | \param pen outline pen
|
---|
854 | \param size size
|
---|
855 |
|
---|
856 | \sa setStyle(), setBrush(), setPen(), setSize()
|
---|
857 | */
|
---|
858 | QwtSymbol::QwtSymbol( QwtSymbol::Style style, const QBrush &brush,
|
---|
859 | const QPen &pen, const QSize &size )
|
---|
860 | {
|
---|
861 | d_data = new PrivateData( style, brush, pen, size );
|
---|
862 | }
|
---|
863 |
|
---|
864 | /*!
|
---|
865 | \brief Constructor
|
---|
866 |
|
---|
867 | The symbol gets initialized by a painter path. The style is
|
---|
868 | set to QwtSymbol::Path, the size is set to empty ( the path
|
---|
869 | is displayed unscaled ).
|
---|
870 |
|
---|
871 | \param path painter path
|
---|
872 | \param brush brush to fill the interior
|
---|
873 | \param pen outline pen
|
---|
874 |
|
---|
875 | \sa setPath(), setBrush(), setPen(), setSize()
|
---|
876 | */
|
---|
877 |
|
---|
878 | QwtSymbol::QwtSymbol( const QPainterPath &path,
|
---|
879 | const QBrush &brush, const QPen &pen )
|
---|
880 | {
|
---|
881 | d_data = new PrivateData( QwtSymbol::Path, brush, pen, QSize() );
|
---|
882 | setPath( path );
|
---|
883 | }
|
---|
884 |
|
---|
885 | //! Destructor
|
---|
886 | QwtSymbol::~QwtSymbol()
|
---|
887 | {
|
---|
888 | delete d_data;
|
---|
889 | }
|
---|
890 |
|
---|
891 | /*!
|
---|
892 | Change the cache policy
|
---|
893 |
|
---|
894 | The default policy is AutoCache
|
---|
895 |
|
---|
896 | \param policy Cache policy
|
---|
897 | \sa CachePolicy, cachePolicy()
|
---|
898 | */
|
---|
899 | void QwtSymbol::setCachePolicy(
|
---|
900 | QwtSymbol::CachePolicy policy )
|
---|
901 | {
|
---|
902 | if ( d_data->cache.policy != policy )
|
---|
903 | {
|
---|
904 | d_data->cache.policy = policy;
|
---|
905 | invalidateCache();
|
---|
906 | }
|
---|
907 | }
|
---|
908 |
|
---|
909 | /*!
|
---|
910 | \return Cache policy
|
---|
911 | \sa CachePolicy, setCachePolicy()
|
---|
912 | */
|
---|
913 | QwtSymbol::CachePolicy QwtSymbol::cachePolicy() const
|
---|
914 | {
|
---|
915 | return d_data->cache.policy;
|
---|
916 | }
|
---|
917 |
|
---|
918 | /*!
|
---|
919 | \brief Set a painter path as symbol
|
---|
920 |
|
---|
921 | The symbol is represented by a painter path, where the
|
---|
922 | origin ( 0, 0 ) of the path coordinate system is mapped to
|
---|
923 | the position of the symbol.
|
---|
924 |
|
---|
925 | When the symbol has valid size the painter path gets scaled
|
---|
926 | to fit into the size. Otherwise the symbol size depends on
|
---|
927 | the bounding rectangle of the path.
|
---|
928 |
|
---|
929 | The following code defines a symbol drawing an arrow:
|
---|
930 |
|
---|
931 | \verbatim
|
---|
932 | #include <qwt_symbol.h>
|
---|
933 |
|
---|
934 | QwtSymbol *symbol = new QwtSymbol();
|
---|
935 |
|
---|
936 | QPen pen( Qt::black, 2 );
|
---|
937 | pen.setJoinStyle( Qt::MiterJoin );
|
---|
938 |
|
---|
939 | symbol->setPen( pen );
|
---|
940 | symbol->setBrush( Qt::red );
|
---|
941 |
|
---|
942 | QPainterPath path;
|
---|
943 | path.moveTo( 0, 8 );
|
---|
944 | path.lineTo( 0, 5 );
|
---|
945 | path.lineTo( -3, 5 );
|
---|
946 | path.lineTo( 0, 0 );
|
---|
947 | path.lineTo( 3, 5 );
|
---|
948 | path.lineTo( 0, 5 );
|
---|
949 |
|
---|
950 | QTransform transform;
|
---|
951 | transform.rotate( -30.0 );
|
---|
952 | path = transform.map( path );
|
---|
953 |
|
---|
954 | symbol->setPath( path );
|
---|
955 | symbol->setPinPoint( QPointF( 0.0, 0.0 ) );
|
---|
956 |
|
---|
957 | setSize( 10, 14 );
|
---|
958 | \endverbatim
|
---|
959 |
|
---|
960 | \param path Painter path
|
---|
961 |
|
---|
962 | \note The style is implicitely set to QwtSymbol::Path.
|
---|
963 | \sa path(), setSize()
|
---|
964 | */
|
---|
965 | void QwtSymbol::setPath( const QPainterPath &path )
|
---|
966 | {
|
---|
967 | d_data->style = QwtSymbol::Path;
|
---|
968 | d_data->path.path = path;
|
---|
969 | d_data->path.graphic.reset();
|
---|
970 | }
|
---|
971 |
|
---|
972 | /*!
|
---|
973 | \return Painter path for displaying the symbol
|
---|
974 | \sa setPath()
|
---|
975 | */
|
---|
976 | const QPainterPath &QwtSymbol::path() const
|
---|
977 | {
|
---|
978 | return d_data->path.path;
|
---|
979 | }
|
---|
980 |
|
---|
981 | /*!
|
---|
982 | Set a pixmap as symbol
|
---|
983 |
|
---|
984 | \param pixmap Pixmap
|
---|
985 |
|
---|
986 | \sa pixmap(), setGraphic()
|
---|
987 |
|
---|
988 | \note the style() is set to QwtSymbol::Pixmap
|
---|
989 | \note brush() and pen() have no effect
|
---|
990 | */
|
---|
991 | void QwtSymbol::setPixmap( const QPixmap &pixmap )
|
---|
992 | {
|
---|
993 | d_data->style = QwtSymbol::Pixmap;
|
---|
994 | d_data->pixmap.pixmap = pixmap;
|
---|
995 | }
|
---|
996 |
|
---|
997 | /*!
|
---|
998 | \return Assigned pixmap
|
---|
999 | \sa setPixmap()
|
---|
1000 | */
|
---|
1001 | const QPixmap &QwtSymbol::pixmap() const
|
---|
1002 | {
|
---|
1003 | return d_data->pixmap.pixmap;
|
---|
1004 | }
|
---|
1005 |
|
---|
1006 | /*!
|
---|
1007 | Set a graphic as symbol
|
---|
1008 |
|
---|
1009 | \param graphic Graphic
|
---|
1010 |
|
---|
1011 | \sa graphic(), setPixmap()
|
---|
1012 |
|
---|
1013 | \note the style() is set to QwtSymbol::Graphic
|
---|
1014 | \note brush() and pen() have no effect
|
---|
1015 | */
|
---|
1016 | void QwtSymbol::setGraphic( const QwtGraphic &graphic )
|
---|
1017 | {
|
---|
1018 | d_data->style = QwtSymbol::Graphic;
|
---|
1019 | d_data->graphic.graphic = graphic;
|
---|
1020 | }
|
---|
1021 |
|
---|
1022 | /*!
|
---|
1023 | \return Assigned graphic
|
---|
1024 | \sa setGraphic()
|
---|
1025 | */
|
---|
1026 | const QwtGraphic &QwtSymbol::graphic() const
|
---|
1027 | {
|
---|
1028 | return d_data->graphic.graphic;
|
---|
1029 | }
|
---|
1030 |
|
---|
1031 | #ifndef QWT_NO_SVG
|
---|
1032 |
|
---|
1033 | /*!
|
---|
1034 | Set a SVG icon as symbol
|
---|
1035 |
|
---|
1036 | \param svgDocument SVG icon
|
---|
1037 |
|
---|
1038 | \sa setGraphic(), setPixmap()
|
---|
1039 |
|
---|
1040 | \note the style() is set to QwtSymbol::SvgDocument
|
---|
1041 | \note brush() and pen() have no effect
|
---|
1042 | */
|
---|
1043 | void QwtSymbol::setSvgDocument( const QByteArray &svgDocument )
|
---|
1044 | {
|
---|
1045 | d_data->style = QwtSymbol::SvgDocument;
|
---|
1046 | if ( d_data->svg.renderer == NULL )
|
---|
1047 | d_data->svg.renderer = new QSvgRenderer();
|
---|
1048 |
|
---|
1049 | d_data->svg.renderer->load( svgDocument );
|
---|
1050 | }
|
---|
1051 |
|
---|
1052 | #endif
|
---|
1053 |
|
---|
1054 | /*!
|
---|
1055 | \brief Specify the symbol's size
|
---|
1056 |
|
---|
1057 | If the 'h' parameter is left out or less than 0,
|
---|
1058 | and the 'w' parameter is greater than or equal to 0,
|
---|
1059 | the symbol size will be set to (w,w).
|
---|
1060 |
|
---|
1061 | \param width Width
|
---|
1062 | \param height Height (defaults to -1)
|
---|
1063 |
|
---|
1064 | \sa size()
|
---|
1065 | */
|
---|
1066 | void QwtSymbol::setSize( int width, int height )
|
---|
1067 | {
|
---|
1068 | if ( ( width >= 0 ) && ( height < 0 ) )
|
---|
1069 | height = width;
|
---|
1070 |
|
---|
1071 | setSize( QSize( width, height ) );
|
---|
1072 | }
|
---|
1073 |
|
---|
1074 | /*!
|
---|
1075 | Set the symbol's size
|
---|
1076 | \param size Size
|
---|
1077 |
|
---|
1078 | \sa size()
|
---|
1079 | */
|
---|
1080 | void QwtSymbol::setSize( const QSize &size )
|
---|
1081 | {
|
---|
1082 | if ( size.isValid() && size != d_data->size )
|
---|
1083 | {
|
---|
1084 | d_data->size = size;
|
---|
1085 | invalidateCache();
|
---|
1086 | }
|
---|
1087 | }
|
---|
1088 |
|
---|
1089 | /*!
|
---|
1090 | \return Size
|
---|
1091 | \sa setSize()
|
---|
1092 | */
|
---|
1093 | const QSize& QwtSymbol::size() const
|
---|
1094 | {
|
---|
1095 | return d_data->size;
|
---|
1096 | }
|
---|
1097 |
|
---|
1098 | /*!
|
---|
1099 | \brief Assign a brush
|
---|
1100 |
|
---|
1101 | The brush is used to draw the interior of the symbol.
|
---|
1102 | \param brush Brush
|
---|
1103 |
|
---|
1104 | \sa brush()
|
---|
1105 | */
|
---|
1106 | void QwtSymbol::setBrush( const QBrush &brush )
|
---|
1107 | {
|
---|
1108 | if ( brush != d_data->brush )
|
---|
1109 | {
|
---|
1110 | d_data->brush = brush;
|
---|
1111 | invalidateCache();
|
---|
1112 |
|
---|
1113 | if ( d_data->style == QwtSymbol::Path )
|
---|
1114 | d_data->path.graphic.reset();
|
---|
1115 | }
|
---|
1116 | }
|
---|
1117 |
|
---|
1118 | /*!
|
---|
1119 | \return Brush
|
---|
1120 | \sa setBrush()
|
---|
1121 | */
|
---|
1122 | const QBrush& QwtSymbol::brush() const
|
---|
1123 | {
|
---|
1124 | return d_data->brush;
|
---|
1125 | }
|
---|
1126 |
|
---|
1127 | /*!
|
---|
1128 | Build and assign a pen
|
---|
1129 |
|
---|
1130 | In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 )
|
---|
1131 | what makes it non cosmetic ( see QPen::isCosmetic() ).
|
---|
1132 | This method has been introduced to hide this incompatibility.
|
---|
1133 |
|
---|
1134 | \param color Pen color
|
---|
1135 | \param width Pen width
|
---|
1136 | \param style Pen style
|
---|
1137 |
|
---|
1138 | \sa pen(), brush()
|
---|
1139 | */
|
---|
1140 | void QwtSymbol::setPen( const QColor &color,
|
---|
1141 | qreal width, Qt::PenStyle style )
|
---|
1142 | {
|
---|
1143 | setPen( QPen( color, width, style ) );
|
---|
1144 | }
|
---|
1145 |
|
---|
1146 | /*!
|
---|
1147 | Assign a pen
|
---|
1148 |
|
---|
1149 | The pen is used to draw the symbol's outline.
|
---|
1150 |
|
---|
1151 | \param pen Pen
|
---|
1152 | \sa pen(), setBrush()
|
---|
1153 | */
|
---|
1154 | void QwtSymbol::setPen( const QPen &pen )
|
---|
1155 | {
|
---|
1156 | if ( pen != d_data->pen )
|
---|
1157 | {
|
---|
1158 | d_data->pen = pen;
|
---|
1159 | invalidateCache();
|
---|
1160 |
|
---|
1161 | if ( d_data->style == QwtSymbol::Path )
|
---|
1162 | d_data->path.graphic.reset();
|
---|
1163 | }
|
---|
1164 | }
|
---|
1165 |
|
---|
1166 | /*!
|
---|
1167 | \return Pen
|
---|
1168 | \sa setPen(), brush()
|
---|
1169 | */
|
---|
1170 | const QPen& QwtSymbol::pen() const
|
---|
1171 | {
|
---|
1172 | return d_data->pen;
|
---|
1173 | }
|
---|
1174 |
|
---|
1175 | /*!
|
---|
1176 | \brief Set the color of the symbol
|
---|
1177 |
|
---|
1178 | Change the color of the brush for symbol types with a filled area.
|
---|
1179 | For all other symbol types the color will be assigned to the pen.
|
---|
1180 |
|
---|
1181 | \param color Color
|
---|
1182 |
|
---|
1183 | \sa setBrush(), setPen(), brush(), pen()
|
---|
1184 | */
|
---|
1185 | void QwtSymbol::setColor( const QColor &color )
|
---|
1186 | {
|
---|
1187 | switch ( d_data->style )
|
---|
1188 | {
|
---|
1189 | case QwtSymbol::Ellipse:
|
---|
1190 | case QwtSymbol::Rect:
|
---|
1191 | case QwtSymbol::Diamond:
|
---|
1192 | case QwtSymbol::Triangle:
|
---|
1193 | case QwtSymbol::UTriangle:
|
---|
1194 | case QwtSymbol::DTriangle:
|
---|
1195 | case QwtSymbol::RTriangle:
|
---|
1196 | case QwtSymbol::LTriangle:
|
---|
1197 | case QwtSymbol::Star2:
|
---|
1198 | case QwtSymbol::Hexagon:
|
---|
1199 | {
|
---|
1200 | if ( d_data->brush.color() != color )
|
---|
1201 | {
|
---|
1202 | d_data->brush.setColor( color );
|
---|
1203 | invalidateCache();
|
---|
1204 | }
|
---|
1205 | break;
|
---|
1206 | }
|
---|
1207 | case QwtSymbol::Cross:
|
---|
1208 | case QwtSymbol::XCross:
|
---|
1209 | case QwtSymbol::HLine:
|
---|
1210 | case QwtSymbol::VLine:
|
---|
1211 | case QwtSymbol::Star1:
|
---|
1212 | {
|
---|
1213 | if ( d_data->pen.color() != color )
|
---|
1214 | {
|
---|
1215 | d_data->pen.setColor( color );
|
---|
1216 | invalidateCache();
|
---|
1217 | }
|
---|
1218 | break;
|
---|
1219 | }
|
---|
1220 | default:
|
---|
1221 | {
|
---|
1222 | if ( d_data->brush.color() != color ||
|
---|
1223 | d_data->pen.color() != color )
|
---|
1224 | {
|
---|
1225 | invalidateCache();
|
---|
1226 | }
|
---|
1227 |
|
---|
1228 | d_data->brush.setColor( color );
|
---|
1229 | d_data->pen.setColor( color );
|
---|
1230 | }
|
---|
1231 | }
|
---|
1232 | }
|
---|
1233 |
|
---|
1234 | /*!
|
---|
1235 | \brief Set and enable a pin point
|
---|
1236 |
|
---|
1237 | The position of a complex symbol is not always aligned to its center
|
---|
1238 | ( f.e an arrow, where the peak points to a position ). The pin point
|
---|
1239 | defines the position inside of a Pixmap, Graphic, SvgDocument
|
---|
1240 | or PainterPath symbol where the represented point has to
|
---|
1241 | be aligned to.
|
---|
1242 |
|
---|
1243 | \param pos Position
|
---|
1244 | \param enable En/Disable the pin point alignment
|
---|
1245 |
|
---|
1246 | \sa pinPoint(), setPinPointEnabled()
|
---|
1247 | */
|
---|
1248 | void QwtSymbol::setPinPoint( const QPointF &pos, bool enable )
|
---|
1249 | {
|
---|
1250 | if ( d_data->pinPoint != pos )
|
---|
1251 | {
|
---|
1252 | d_data->pinPoint = pos;
|
---|
1253 | if ( d_data->isPinPointEnabled )
|
---|
1254 | {
|
---|
1255 | invalidateCache();
|
---|
1256 | }
|
---|
1257 | }
|
---|
1258 |
|
---|
1259 | setPinPointEnabled( enable );
|
---|
1260 | }
|
---|
1261 |
|
---|
1262 | /*!
|
---|
1263 | \return Pin point
|
---|
1264 | \sa setPinPoint(), setPinPointEnabled()
|
---|
1265 | */
|
---|
1266 | QPointF QwtSymbol::pinPoint() const
|
---|
1267 | {
|
---|
1268 | return d_data->pinPoint;
|
---|
1269 | }
|
---|
1270 |
|
---|
1271 | /*!
|
---|
1272 | En/Disable the pin point alignment
|
---|
1273 |
|
---|
1274 | \param on Enabled, when on is true
|
---|
1275 | \sa setPinPoint(), isPinPointEnabled()
|
---|
1276 | */
|
---|
1277 | void QwtSymbol::setPinPointEnabled( bool on )
|
---|
1278 | {
|
---|
1279 | if ( d_data->isPinPointEnabled != on )
|
---|
1280 | {
|
---|
1281 | d_data->isPinPointEnabled = on;
|
---|
1282 | invalidateCache();
|
---|
1283 | }
|
---|
1284 | }
|
---|
1285 |
|
---|
1286 | /*!
|
---|
1287 | \return True, when the pin point translation is enabled
|
---|
1288 | \sa setPinPoint(), setPinPointEnabled()
|
---|
1289 | */
|
---|
1290 | bool QwtSymbol::isPinPointEnabled() const
|
---|
1291 | {
|
---|
1292 | return d_data->isPinPointEnabled;
|
---|
1293 | }
|
---|
1294 |
|
---|
1295 | /*!
|
---|
1296 | Render an array of symbols
|
---|
1297 |
|
---|
1298 | Painting several symbols is more effective than drawing symbols
|
---|
1299 | one by one, as a couple of layout calculations and setting of pen/brush
|
---|
1300 | can be done once for the complete array.
|
---|
1301 |
|
---|
1302 | \param painter Painter
|
---|
1303 | \param points Array of points
|
---|
1304 | \param numPoints Number of points
|
---|
1305 | */
|
---|
1306 | void QwtSymbol::drawSymbols( QPainter *painter,
|
---|
1307 | const QPointF *points, int numPoints ) const
|
---|
1308 | {
|
---|
1309 | if ( numPoints <= 0 )
|
---|
1310 | return;
|
---|
1311 |
|
---|
1312 | bool useCache = false;
|
---|
1313 |
|
---|
1314 | // Don't use the pixmap, when the paint device
|
---|
1315 | // could generate scalable vectors
|
---|
1316 |
|
---|
1317 | if ( QwtPainter::roundingAlignment( painter ) &&
|
---|
1318 | !painter->transform().isScaling() )
|
---|
1319 | {
|
---|
1320 | if ( d_data->cache.policy == QwtSymbol::Cache )
|
---|
1321 | {
|
---|
1322 | useCache = true;
|
---|
1323 | }
|
---|
1324 | else if ( d_data->cache.policy == QwtSymbol::AutoCache )
|
---|
1325 | {
|
---|
1326 | if ( painter->paintEngine()->type() == QPaintEngine::Raster )
|
---|
1327 | {
|
---|
1328 | useCache = true;
|
---|
1329 | }
|
---|
1330 | else
|
---|
1331 | {
|
---|
1332 | switch( d_data->style )
|
---|
1333 | {
|
---|
1334 | case QwtSymbol::XCross:
|
---|
1335 | case QwtSymbol::HLine:
|
---|
1336 | case QwtSymbol::VLine:
|
---|
1337 | case QwtSymbol::Cross:
|
---|
1338 | break;
|
---|
1339 |
|
---|
1340 | case QwtSymbol::Pixmap:
|
---|
1341 | {
|
---|
1342 | if ( !d_data->size.isEmpty() &&
|
---|
1343 | d_data->size != d_data->pixmap.pixmap.size() )
|
---|
1344 | {
|
---|
1345 | useCache = true;
|
---|
1346 | }
|
---|
1347 | break;
|
---|
1348 | }
|
---|
1349 | default:
|
---|
1350 | useCache = true;
|
---|
1351 | }
|
---|
1352 | }
|
---|
1353 | }
|
---|
1354 | }
|
---|
1355 |
|
---|
1356 | if ( useCache )
|
---|
1357 | {
|
---|
1358 | const QRect br = boundingRect();
|
---|
1359 |
|
---|
1360 | const QRect rect( 0, 0, br.width(), br.height() );
|
---|
1361 |
|
---|
1362 | if ( d_data->cache.pixmap.isNull() )
|
---|
1363 | {
|
---|
1364 | d_data->cache.pixmap = QwtPainter::backingStore( NULL, br.size() );
|
---|
1365 | d_data->cache.pixmap.fill( Qt::transparent );
|
---|
1366 |
|
---|
1367 | QPainter p( &d_data->cache.pixmap );
|
---|
1368 | p.setRenderHints( painter->renderHints() );
|
---|
1369 | p.translate( -br.topLeft() );
|
---|
1370 |
|
---|
1371 | const QPointF pos;
|
---|
1372 | renderSymbols( &p, &pos, 1 );
|
---|
1373 | }
|
---|
1374 |
|
---|
1375 | const int dx = br.left();
|
---|
1376 | const int dy = br.top();
|
---|
1377 |
|
---|
1378 | for ( int i = 0; i < numPoints; i++ )
|
---|
1379 | {
|
---|
1380 | const int left = qRound( points[i].x() ) + dx;
|
---|
1381 | const int top = qRound( points[i].y() ) + dy;
|
---|
1382 |
|
---|
1383 | painter->drawPixmap( left, top, d_data->cache.pixmap );
|
---|
1384 | }
|
---|
1385 | }
|
---|
1386 | else
|
---|
1387 | {
|
---|
1388 | painter->save();
|
---|
1389 | renderSymbols( painter, points, numPoints );
|
---|
1390 | painter->restore();
|
---|
1391 | }
|
---|
1392 | }
|
---|
1393 |
|
---|
1394 | /*!
|
---|
1395 | \brief Draw the symbol into a rectangle
|
---|
1396 |
|
---|
1397 | The symbol is painted centered and scaled into the target rectangle.
|
---|
1398 | It is always painted uncached and the pin point is ignored.
|
---|
1399 |
|
---|
1400 | This method is primarily intended for drawing a symbol to
|
---|
1401 | the legend.
|
---|
1402 |
|
---|
1403 | \param painter Painter
|
---|
1404 | \param rect Target rectangle for the symbol
|
---|
1405 | */
|
---|
1406 | void QwtSymbol::drawSymbol( QPainter *painter, const QRectF &rect ) const
|
---|
1407 | {
|
---|
1408 | if ( d_data->style == QwtSymbol::NoSymbol )
|
---|
1409 | return;
|
---|
1410 |
|
---|
1411 | if ( d_data->style == QwtSymbol::Graphic )
|
---|
1412 | {
|
---|
1413 | d_data->graphic.graphic.render(
|
---|
1414 | painter, rect, Qt::KeepAspectRatio );
|
---|
1415 | }
|
---|
1416 | else if ( d_data->style == QwtSymbol::Path )
|
---|
1417 | {
|
---|
1418 | if ( d_data->path.graphic.isNull() )
|
---|
1419 | {
|
---|
1420 | d_data->path.graphic = qwtPathGraphic(
|
---|
1421 | d_data->path.path, d_data->pen, d_data->brush );
|
---|
1422 | }
|
---|
1423 |
|
---|
1424 | d_data->path.graphic.render(
|
---|
1425 | painter, rect, Qt::KeepAspectRatio );
|
---|
1426 | return;
|
---|
1427 | }
|
---|
1428 | else if ( d_data->style == QwtSymbol::SvgDocument )
|
---|
1429 | {
|
---|
1430 | #ifndef QWT_NO_SVG
|
---|
1431 | if ( d_data->svg.renderer )
|
---|
1432 | {
|
---|
1433 | QRectF scaledRect;
|
---|
1434 |
|
---|
1435 | QSizeF sz = d_data->svg.renderer->viewBoxF().size();
|
---|
1436 | if ( !sz.isEmpty() )
|
---|
1437 | {
|
---|
1438 | sz.scale( rect.size(), Qt::KeepAspectRatio );
|
---|
1439 | scaledRect.setSize( sz );
|
---|
1440 | scaledRect.moveCenter( rect.center() );
|
---|
1441 | }
|
---|
1442 | else
|
---|
1443 | {
|
---|
1444 | scaledRect = rect;
|
---|
1445 | }
|
---|
1446 |
|
---|
1447 | d_data->svg.renderer->render(
|
---|
1448 | painter, scaledRect );
|
---|
1449 | }
|
---|
1450 | #endif
|
---|
1451 | }
|
---|
1452 | else
|
---|
1453 | {
|
---|
1454 | const QRect br = boundingRect();
|
---|
1455 |
|
---|
1456 | // scale the symbol size to fit into rect.
|
---|
1457 |
|
---|
1458 | const double ratio = qMin( rect.width() / br.width(),
|
---|
1459 | rect.height() / br.height() );
|
---|
1460 |
|
---|
1461 | painter->save();
|
---|
1462 |
|
---|
1463 | painter->translate( rect.center() );
|
---|
1464 | painter->scale( ratio, ratio );
|
---|
1465 |
|
---|
1466 | const bool isPinPointEnabled = d_data->isPinPointEnabled;
|
---|
1467 | d_data->isPinPointEnabled = false;
|
---|
1468 |
|
---|
1469 | const QPointF pos;
|
---|
1470 | renderSymbols( painter, &pos, 1 );
|
---|
1471 |
|
---|
1472 | d_data->isPinPointEnabled = isPinPointEnabled;
|
---|
1473 |
|
---|
1474 | painter->restore();
|
---|
1475 | }
|
---|
1476 | }
|
---|
1477 |
|
---|
1478 | /*!
|
---|
1479 | Render the symbol to series of points
|
---|
1480 |
|
---|
1481 | \param painter Qt painter
|
---|
1482 | \param points Positions of the symbols
|
---|
1483 | \param numPoints Number of points
|
---|
1484 | */
|
---|
1485 | void QwtSymbol::renderSymbols( QPainter *painter,
|
---|
1486 | const QPointF *points, int numPoints ) const
|
---|
1487 | {
|
---|
1488 | switch ( d_data->style )
|
---|
1489 | {
|
---|
1490 | case QwtSymbol::Ellipse:
|
---|
1491 | {
|
---|
1492 | qwtDrawEllipseSymbols( painter, points, numPoints, *this );
|
---|
1493 | break;
|
---|
1494 | }
|
---|
1495 | case QwtSymbol::Rect:
|
---|
1496 | {
|
---|
1497 | qwtDrawRectSymbols( painter, points, numPoints, *this );
|
---|
1498 | break;
|
---|
1499 | }
|
---|
1500 | case QwtSymbol::Diamond:
|
---|
1501 | {
|
---|
1502 | qwtDrawDiamondSymbols( painter, points, numPoints, *this );
|
---|
1503 | break;
|
---|
1504 | }
|
---|
1505 | case QwtSymbol::Cross:
|
---|
1506 | {
|
---|
1507 | qwtDrawLineSymbols( painter, Qt::Horizontal | Qt::Vertical,
|
---|
1508 | points, numPoints, *this );
|
---|
1509 | break;
|
---|
1510 | }
|
---|
1511 | case QwtSymbol::XCross:
|
---|
1512 | {
|
---|
1513 | qwtDrawXCrossSymbols( painter, points, numPoints, *this );
|
---|
1514 | break;
|
---|
1515 | }
|
---|
1516 | case QwtSymbol::Triangle:
|
---|
1517 | case QwtSymbol::UTriangle:
|
---|
1518 | {
|
---|
1519 | qwtDrawTriangleSymbols( painter, QwtTriangle::Up,
|
---|
1520 | points, numPoints, *this );
|
---|
1521 | break;
|
---|
1522 | }
|
---|
1523 | case QwtSymbol::DTriangle:
|
---|
1524 | {
|
---|
1525 | qwtDrawTriangleSymbols( painter, QwtTriangle::Down,
|
---|
1526 | points, numPoints, *this );
|
---|
1527 | break;
|
---|
1528 | }
|
---|
1529 | case QwtSymbol::RTriangle:
|
---|
1530 | {
|
---|
1531 | qwtDrawTriangleSymbols( painter, QwtTriangle::Right,
|
---|
1532 | points, numPoints, *this );
|
---|
1533 | break;
|
---|
1534 | }
|
---|
1535 | case QwtSymbol::LTriangle:
|
---|
1536 | {
|
---|
1537 | qwtDrawTriangleSymbols( painter, QwtTriangle::Left,
|
---|
1538 | points, numPoints, *this );
|
---|
1539 | break;
|
---|
1540 | }
|
---|
1541 | case QwtSymbol::HLine:
|
---|
1542 | {
|
---|
1543 | qwtDrawLineSymbols( painter, Qt::Horizontal,
|
---|
1544 | points, numPoints, *this );
|
---|
1545 | break;
|
---|
1546 | }
|
---|
1547 | case QwtSymbol::VLine:
|
---|
1548 | {
|
---|
1549 | qwtDrawLineSymbols( painter, Qt::Vertical,
|
---|
1550 | points, numPoints, *this );
|
---|
1551 | break;
|
---|
1552 | }
|
---|
1553 | case QwtSymbol::Star1:
|
---|
1554 | {
|
---|
1555 | qwtDrawStar1Symbols( painter, points, numPoints, *this );
|
---|
1556 | break;
|
---|
1557 | }
|
---|
1558 | case QwtSymbol::Star2:
|
---|
1559 | {
|
---|
1560 | qwtDrawStar2Symbols( painter, points, numPoints, *this );
|
---|
1561 | break;
|
---|
1562 | }
|
---|
1563 | case QwtSymbol::Hexagon:
|
---|
1564 | {
|
---|
1565 | qwtDrawHexagonSymbols( painter, points, numPoints, *this );
|
---|
1566 | break;
|
---|
1567 | }
|
---|
1568 | case QwtSymbol::Path:
|
---|
1569 | {
|
---|
1570 | if ( d_data->path.graphic.isNull() )
|
---|
1571 | {
|
---|
1572 | d_data->path.graphic = qwtPathGraphic( d_data->path.path,
|
---|
1573 | d_data->pen, d_data->brush );
|
---|
1574 | }
|
---|
1575 |
|
---|
1576 | qwtDrawGraphicSymbols( painter, points, numPoints,
|
---|
1577 | d_data->path.graphic, *this );
|
---|
1578 | break;
|
---|
1579 | }
|
---|
1580 | case QwtSymbol::Pixmap:
|
---|
1581 | {
|
---|
1582 | qwtDrawPixmapSymbols( painter, points, numPoints, *this );
|
---|
1583 | break;
|
---|
1584 | }
|
---|
1585 | case QwtSymbol::Graphic:
|
---|
1586 | {
|
---|
1587 | qwtDrawGraphicSymbols( painter, points, numPoints,
|
---|
1588 | d_data->graphic.graphic, *this );
|
---|
1589 | break;
|
---|
1590 | }
|
---|
1591 | case QwtSymbol::SvgDocument:
|
---|
1592 | {
|
---|
1593 | #ifndef QWT_NO_SVG
|
---|
1594 | qwtDrawSvgSymbols( painter, points, numPoints,
|
---|
1595 | d_data->svg.renderer, *this );
|
---|
1596 | #endif
|
---|
1597 | break;
|
---|
1598 | }
|
---|
1599 | default:;
|
---|
1600 | }
|
---|
1601 | }
|
---|
1602 |
|
---|
1603 | /*!
|
---|
1604 | Calculate the bounding rectangle for a symbol
|
---|
1605 | at position (0,0).
|
---|
1606 |
|
---|
1607 | \return Bounding rectangle
|
---|
1608 | */
|
---|
1609 | QRect QwtSymbol::boundingRect() const
|
---|
1610 | {
|
---|
1611 | QRectF rect;
|
---|
1612 |
|
---|
1613 | bool pinPointTranslation = false;
|
---|
1614 |
|
---|
1615 | switch ( d_data->style )
|
---|
1616 | {
|
---|
1617 | case QwtSymbol::Ellipse:
|
---|
1618 | case QwtSymbol::Rect:
|
---|
1619 | case QwtSymbol::Hexagon:
|
---|
1620 | {
|
---|
1621 | qreal pw = 0.0;
|
---|
1622 | if ( d_data->pen.style() != Qt::NoPen )
|
---|
1623 | pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) );
|
---|
1624 |
|
---|
1625 | rect.setSize( d_data->size + QSizeF( pw, pw ) );
|
---|
1626 | rect.moveCenter( QPointF( 0.0, 0.0 ) );
|
---|
1627 |
|
---|
1628 | break;
|
---|
1629 | }
|
---|
1630 | case QwtSymbol::XCross:
|
---|
1631 | case QwtSymbol::Diamond:
|
---|
1632 | case QwtSymbol::Triangle:
|
---|
1633 | case QwtSymbol::UTriangle:
|
---|
1634 | case QwtSymbol::DTriangle:
|
---|
1635 | case QwtSymbol::RTriangle:
|
---|
1636 | case QwtSymbol::LTriangle:
|
---|
1637 | case QwtSymbol::Star1:
|
---|
1638 | case QwtSymbol::Star2:
|
---|
1639 | {
|
---|
1640 | qreal pw = 0.0;
|
---|
1641 | if ( d_data->pen.style() != Qt::NoPen )
|
---|
1642 | pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) );
|
---|
1643 |
|
---|
1644 | rect.setSize( d_data->size + QSizeF( 2 * pw, 2 * pw ) );
|
---|
1645 | rect.moveCenter( QPointF( 0.0, 0.0 ) );
|
---|
1646 | break;
|
---|
1647 | }
|
---|
1648 | case QwtSymbol::Path:
|
---|
1649 | {
|
---|
1650 | if ( d_data->path.graphic.isNull() )
|
---|
1651 | {
|
---|
1652 | d_data->path.graphic = qwtPathGraphic(
|
---|
1653 | d_data->path.path, d_data->pen, d_data->brush );
|
---|
1654 | }
|
---|
1655 |
|
---|
1656 | rect = qwtScaledBoundingRect(
|
---|
1657 | d_data->path.graphic, d_data->size );
|
---|
1658 | pinPointTranslation = true;
|
---|
1659 |
|
---|
1660 | break;
|
---|
1661 | }
|
---|
1662 | case QwtSymbol::Pixmap:
|
---|
1663 | {
|
---|
1664 | if ( d_data->size.isEmpty() )
|
---|
1665 | rect.setSize( d_data->pixmap.pixmap.size() );
|
---|
1666 | else
|
---|
1667 | rect.setSize( d_data->size );
|
---|
1668 |
|
---|
1669 | pinPointTranslation = true;
|
---|
1670 |
|
---|
1671 | break;
|
---|
1672 | }
|
---|
1673 | case QwtSymbol::Graphic:
|
---|
1674 | {
|
---|
1675 | rect = qwtScaledBoundingRect(
|
---|
1676 | d_data->graphic.graphic, d_data->size );
|
---|
1677 | pinPointTranslation = true;
|
---|
1678 |
|
---|
1679 | break;
|
---|
1680 | }
|
---|
1681 | #ifndef QWT_NO_SVG
|
---|
1682 | case QwtSymbol::SvgDocument:
|
---|
1683 | {
|
---|
1684 | if ( d_data->svg.renderer )
|
---|
1685 | rect = d_data->svg.renderer->viewBoxF();
|
---|
1686 |
|
---|
1687 | if ( d_data->size.isValid() && !rect.isEmpty() )
|
---|
1688 | {
|
---|
1689 | QSizeF sz = rect.size();
|
---|
1690 |
|
---|
1691 | const double sx = d_data->size.width() / sz.width();
|
---|
1692 | const double sy = d_data->size.height() / sz.height();
|
---|
1693 |
|
---|
1694 | QTransform transform;
|
---|
1695 | transform.scale( sx, sy );
|
---|
1696 |
|
---|
1697 | rect = transform.mapRect( rect );
|
---|
1698 | }
|
---|
1699 | pinPointTranslation = true;
|
---|
1700 | break;
|
---|
1701 | }
|
---|
1702 | #endif
|
---|
1703 | default:
|
---|
1704 | {
|
---|
1705 | rect.setSize( d_data->size );
|
---|
1706 | rect.moveCenter( QPointF( 0.0, 0.0 ) );
|
---|
1707 | }
|
---|
1708 | }
|
---|
1709 |
|
---|
1710 | if ( pinPointTranslation )
|
---|
1711 | {
|
---|
1712 | QPointF pinPoint( 0.0, 0.0 );
|
---|
1713 | if ( d_data->isPinPointEnabled )
|
---|
1714 | pinPoint = rect.center() - d_data->pinPoint;
|
---|
1715 |
|
---|
1716 | rect.moveCenter( pinPoint );
|
---|
1717 | }
|
---|
1718 |
|
---|
1719 | QRect r;
|
---|
1720 | r.setLeft( qFloor( rect.left() ) );
|
---|
1721 | r.setTop( qFloor( rect.top() ) );
|
---|
1722 | r.setRight( qCeil( rect.right() ) );
|
---|
1723 | r.setBottom( qCeil( rect.bottom() ) );
|
---|
1724 |
|
---|
1725 | if ( d_data->style != QwtSymbol::Pixmap )
|
---|
1726 | r.adjust( -1, -1, 1, 1 ); // for antialiasing
|
---|
1727 |
|
---|
1728 | return r;
|
---|
1729 | }
|
---|
1730 |
|
---|
1731 | /*!
|
---|
1732 | Invalidate the cached symbol pixmap
|
---|
1733 |
|
---|
1734 | The symbol invalidates its cache, whenever an attribute is changed
|
---|
1735 | that has an effect ob how to display a symbol. In case of derived
|
---|
1736 | classes with individual styles ( >= QwtSymbol::UserStyle ) it
|
---|
1737 | might be necessary to call invalidateCache() for attributes
|
---|
1738 | that are relevant for this style.
|
---|
1739 |
|
---|
1740 | \sa CachePolicy, setCachePolicy(), drawSymbols()
|
---|
1741 | */
|
---|
1742 | void QwtSymbol::invalidateCache()
|
---|
1743 | {
|
---|
1744 | if ( !d_data->cache.pixmap.isNull() )
|
---|
1745 | d_data->cache.pixmap = QPixmap();
|
---|
1746 | }
|
---|
1747 |
|
---|
1748 | /*!
|
---|
1749 | Specify the symbol style
|
---|
1750 |
|
---|
1751 | \param style Style
|
---|
1752 | \sa style()
|
---|
1753 | */
|
---|
1754 | void QwtSymbol::setStyle( QwtSymbol::Style style )
|
---|
1755 | {
|
---|
1756 | if ( d_data->style != style )
|
---|
1757 | {
|
---|
1758 | d_data->style = style;
|
---|
1759 | invalidateCache();
|
---|
1760 | }
|
---|
1761 | }
|
---|
1762 |
|
---|
1763 | /*!
|
---|
1764 | \return Current symbol style
|
---|
1765 | \sa setStyle()
|
---|
1766 | */
|
---|
1767 | QwtSymbol::Style QwtSymbol::style() const
|
---|
1768 | {
|
---|
1769 | return d_data->style;
|
---|
1770 | }
|
---|