Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_symbol.cpp
- Timestamp:
- May 10, 2017, 3:20:54 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/qwt/qwt_symbol.cpp
r4271 r8127 10 10 #include "qwt_symbol.h" 11 11 #include "qwt_painter.h" 12 #include "qwt_graphic.h" 12 13 #include <qapplication.h> 13 14 #include <qpainter.h> 15 #include <qpainterpath.h> 16 #include <qpixmap.h> 17 #include <qpaintengine.h> 14 18 #include <qmath.h> 19 #ifndef QWT_NO_SVG 20 #include <qsvgrenderer.h> 21 #endif 15 22 16 23 namespace QwtTriangle … … 23 30 Down 24 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 ); 25 178 } 26 179 … … 623 776 size( sz ), 624 777 brush( br ), 625 pen( pn ) 626 { 627 } 628 629 bool operator==( const PrivateData &other ) const 630 { 631 return ( style == other.style ) 632 && ( size == other.size ) 633 && ( brush == other.brush ) 634 && ( pen == other.pen ); 635 } 636 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 } 637 793 638 794 Style style; … … 640 796 QBrush brush; 641 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; 642 834 }; 643 835 … … 652 844 { 653 845 d_data = new PrivateData( style, QBrush( Qt::gray ), 654 QPen( Qt::black ), QSize( 0.0, 0.0) );846 QPen( Qt::black, 0 ), QSize() ); 655 847 } 656 848 … … 671 863 672 864 /*! 673 \brief Copy constructor 674 675 \param other Symbol 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() 676 876 */ 677 QwtSymbol::QwtSymbol( const QwtSymbol &other ) 678 { 679 d_data = new PrivateData( other.style(), other.brush(), 680 other.pen(), other.size() ); 681 }; 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 } 682 884 683 885 //! Destructor … … 687 889 } 688 890 689 //! \brief Assignment operator 690 QwtSymbol &QwtSymbol::operator=( const QwtSymbol &other ) 691 { 692 *d_data = *other.d_data; 693 return *this; 694 } 695 696 //! \brief Compare two symbols 697 bool QwtSymbol::operator==( const QwtSymbol &other ) const 698 { 699 return *d_data == *other.d_data; 700 } 701 702 //! \brief Compare two symbols 703 bool QwtSymbol::operator!=( const QwtSymbol &other ) const 704 { 705 return !( *d_data == *other.d_data ); 706 } 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 707 1053 708 1054 /*! … … 712 1058 and the 'w' parameter is greater than or equal to 0, 713 1059 the symbol size will be set to (w,w). 1060 714 1061 \param width Width 715 1062 \param height Height (defaults to -1) … … 722 1069 height = width; 723 1070 724 d_data->size = QSize( width, height);1071 setSize( QSize( width, height ) ); 725 1072 } 726 1073 … … 733 1080 void QwtSymbol::setSize( const QSize &size ) 734 1081 { 735 if ( size.isValid() ) 1082 if ( size.isValid() && size != d_data->size ) 1083 { 736 1084 d_data->size = size; 1085 invalidateCache(); 1086 } 737 1087 } 738 1088 … … 756 1106 void QwtSymbol::setBrush( const QBrush &brush ) 757 1107 { 758 d_data->brush = brush; 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 } 759 1116 } 760 1117 … … 769 1126 770 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 /*! 771 1147 Assign a pen 772 1148 … … 778 1154 void QwtSymbol::setPen( const QPen &pen ) 779 1155 { 780 d_data->pen = pen; 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 } 781 1164 } 782 1165 … … 815 1198 case QwtSymbol::Hexagon: 816 1199 { 817 d_data->brush.setColor( color ); 1200 if ( d_data->brush.color() != color ) 1201 { 1202 d_data->brush.setColor( color ); 1203 invalidateCache(); 1204 } 818 1205 break; 819 1206 } … … 824 1211 case QwtSymbol::Star1: 825 1212 { 826 d_data->pen.setColor( color ); 1213 if ( d_data->pen.color() != color ) 1214 { 1215 d_data->pen.setColor( color ); 1216 invalidateCache(); 1217 } 827 1218 break; 828 1219 } 829 1220 default: 830 1221 { 1222 if ( d_data->brush.color() != color || 1223 d_data->pen.color() != color ) 1224 { 1225 invalidateCache(); 1226 } 1227 831 1228 d_data->brush.setColor( color ); 832 1229 d_data->pen.setColor( color ); … … 836 1233 837 1234 /*! 838 Draw an array of symbols 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 839 1297 840 1298 Painting several symbols is more effective than drawing symbols … … 852 1310 return; 853 1311 854 painter->save(); 855 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 { 856 1488 switch ( d_data->style ) 857 1489 { … … 934 1566 break; 935 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 } 936 1599 default:; 937 1600 } 938 painter->restore(); 939 } 940 941 //! \return Size of the bounding rectangle of a symbol 942 QSize QwtSymbol::boundingSize() const 943 { 944 QSize size; 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; 945 1614 946 1615 switch ( d_data->style ) … … 954 1623 pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) ); 955 1624 956 size = d_data->size + QSize( pw, pw ); 1625 rect.setSize( d_data->size + QSizeF( pw, pw ) ); 1626 rect.moveCenter( QPointF( 0.0, 0.0 ) ); 957 1627 958 1628 break; … … 972 1642 pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) ); 973 1643 974 size = d_data->size + QSize( 2 * pw, 2 * pw ); 975 break; 976 } 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 977 1703 default: 978 1704 { 979 size = d_data->size; 980 } 981 } 982 983 return size + QSize( 1, 1 ); // for antialiasing 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(); 984 1746 } 985 1747 … … 992 1754 void QwtSymbol::setStyle( QwtSymbol::Style style ) 993 1755 { 994 d_data->style = style; 1756 if ( d_data->style != style ) 1757 { 1758 d_data->style = style; 1759 invalidateCache(); 1760 } 995 1761 } 996 1762
Note:
See TracChangeset
for help on using the changeset viewer.