qwt_symbol.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  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. #include "qwt_symbol.h"
  10. #include "qwt_painter.h"
  11. #include <qapplication.h>
  12. #include <qpainter.h>
  13. #include <qmath.h>
  14. namespace QwtTriangle
  15. {
  16. enum Type
  17. {
  18. Left,
  19. Right,
  20. Up,
  21. Down
  22. };
  23. }
  24. static inline void qwtDrawEllipseSymbols( QPainter *painter,
  25. const QPointF *points, int numPoints, const QwtSymbol &symbol )
  26. {
  27. painter->setBrush( symbol.brush() );
  28. painter->setPen( symbol.pen() );
  29. const QSize size = symbol.size();
  30. if ( QwtPainter::roundingAlignment( painter ) )
  31. {
  32. const int sw = size.width();
  33. const int sh = size.height();
  34. const int sw2 = size.width() / 2;
  35. const int sh2 = size.height() / 2;
  36. for ( int i = 0; i < numPoints; i++ )
  37. {
  38. const int x = qRound( points[i].x() );
  39. const int y = qRound( points[i].y() );
  40. const QRectF r( x - sw2, y - sh2, sw, sh );
  41. QwtPainter::drawEllipse( painter, r );
  42. }
  43. }
  44. else
  45. {
  46. const double sw = size.width();
  47. const double sh = size.height();
  48. const double sw2 = 0.5 * size.width();
  49. const double sh2 = 0.5 * size.height();
  50. for ( int i = 0; i < numPoints; i++ )
  51. {
  52. const double x = points[i].x();
  53. const double y = points[i].y();
  54. const QRectF r( x - sw2, y - sh2, sw, sh );
  55. QwtPainter::drawEllipse( painter, r );
  56. }
  57. }
  58. }
  59. static inline void qwtDrawRectSymbols( QPainter *painter,
  60. const QPointF *points, int numPoints, const QwtSymbol &symbol )
  61. {
  62. const QSize size = symbol.size();
  63. QPen pen = symbol.pen();
  64. pen.setJoinStyle( Qt::MiterJoin );
  65. painter->setPen( pen );
  66. painter->setBrush( symbol.brush() );
  67. painter->setRenderHint( QPainter::Antialiasing, false );
  68. if ( QwtPainter::roundingAlignment( painter ) )
  69. {
  70. const int sw = size.width();
  71. const int sh = size.height();
  72. const int sw2 = size.width() / 2;
  73. const int sh2 = size.height() / 2;
  74. for ( int i = 0; i < numPoints; i++ )
  75. {
  76. const int x = qRound( points[i].x() );
  77. const int y = qRound( points[i].y() );
  78. const QRect r( x - sw2, y - sh2, sw, sh );
  79. QwtPainter::drawRect( painter, r );
  80. }
  81. }
  82. else
  83. {
  84. const double sw = size.width();
  85. const double sh = size.height();
  86. const double sw2 = 0.5 * size.width();
  87. const double sh2 = 0.5 * size.height();
  88. for ( int i = 0; i < numPoints; i++ )
  89. {
  90. const double x = points[i].x();
  91. const double y = points[i].y();
  92. const QRectF r( x - sw2, y - sh2, sw, sh );
  93. QwtPainter::drawRect( painter, r );
  94. }
  95. }
  96. }
  97. static inline void qwtDrawDiamondSymbols( QPainter *painter,
  98. const QPointF *points, int numPoints, const QwtSymbol &symbol )
  99. {
  100. const QSize size = symbol.size();
  101. QPen pen = symbol.pen();
  102. pen.setJoinStyle( Qt::MiterJoin );
  103. painter->setPen( pen );
  104. painter->setBrush( symbol.brush() );
  105. if ( QwtPainter::roundingAlignment( painter ) )
  106. {
  107. for ( int i = 0; i < numPoints; i++ )
  108. {
  109. const int x = qRound( points[i].x() );
  110. const int y = qRound( points[i].y() );
  111. const int x1 = x - size.width() / 2;
  112. const int y1 = y - size.height() / 2;
  113. const int x2 = x1 + size.width();
  114. const int y2 = y1 + size.height();
  115. QPolygonF polygon;
  116. polygon += QPointF( x, y1 );
  117. polygon += QPointF( x1, y );
  118. polygon += QPointF( x, y2 );
  119. polygon += QPointF( x2, y );
  120. QwtPainter::drawPolygon( painter, polygon );
  121. }
  122. }
  123. else
  124. {
  125. for ( int i = 0; i < numPoints; i++ )
  126. {
  127. const QPointF &pos = points[i];
  128. const double x1 = pos.x() - 0.5 * size.width();
  129. const double y1 = pos.y() - 0.5 * size.height();
  130. const double x2 = x1 + size.width();
  131. const double y2 = y1 + size.height();
  132. QPolygonF polygon;
  133. polygon += QPointF( pos.x(), y1 );
  134. polygon += QPointF( x2, pos.y() );
  135. polygon += QPointF( pos.x(), y2 );
  136. polygon += QPointF( x1, pos.y() );
  137. QwtPainter::drawPolygon( painter, polygon );
  138. }
  139. }
  140. }
  141. static inline void qwtDrawTriangleSymbols(
  142. QPainter *painter, QwtTriangle::Type type,
  143. const QPointF *points, int numPoints,
  144. const QwtSymbol &symbol )
  145. {
  146. const QSize size = symbol.size();
  147. QPen pen = symbol.pen();
  148. pen.setJoinStyle( Qt::MiterJoin );
  149. painter->setPen( pen );
  150. painter->setBrush( symbol.brush() );
  151. const bool doAlign = QwtPainter::roundingAlignment( painter );
  152. double sw2 = 0.5 * size.width();
  153. double sh2 = 0.5 * size.height();
  154. if ( doAlign )
  155. {
  156. sw2 = qFloor( sw2 );
  157. sh2 = qFloor( sh2 );
  158. }
  159. QPolygonF triangle( 3 );
  160. QPointF *trianglePoints = triangle.data();
  161. for ( int i = 0; i < numPoints; i++ )
  162. {
  163. const QPointF &pos = points[i];
  164. double x = pos.x();
  165. double y = pos.y();
  166. if ( doAlign )
  167. {
  168. x = qRound( x );
  169. y = qRound( y );
  170. }
  171. const double x1 = x - sw2;
  172. const double x2 = x1 + size.width();
  173. const double y1 = y - sh2;
  174. const double y2 = y1 + size.height();
  175. switch ( type )
  176. {
  177. case QwtTriangle::Left:
  178. {
  179. trianglePoints[0].rx() = x2;
  180. trianglePoints[0].ry() = y1;
  181. trianglePoints[1].rx() = x1;
  182. trianglePoints[1].ry() = y;
  183. trianglePoints[2].rx() = x2;
  184. trianglePoints[2].ry() = y2;
  185. break;
  186. }
  187. case QwtTriangle::Right:
  188. {
  189. trianglePoints[0].rx() = x1;
  190. trianglePoints[0].ry() = y1;
  191. trianglePoints[1].rx() = x2;
  192. trianglePoints[1].ry() = y;
  193. trianglePoints[2].rx() = x1;
  194. trianglePoints[2].ry() = y2;
  195. break;
  196. }
  197. case QwtTriangle::Up:
  198. {
  199. trianglePoints[0].rx() = x1;
  200. trianglePoints[0].ry() = y2;
  201. trianglePoints[1].rx() = x;
  202. trianglePoints[1].ry() = y1;
  203. trianglePoints[2].rx() = x2;
  204. trianglePoints[2].ry() = y2;
  205. break;
  206. }
  207. case QwtTriangle::Down:
  208. {
  209. trianglePoints[0].rx() = x1;
  210. trianglePoints[0].ry() = y1;
  211. trianglePoints[1].rx() = x;
  212. trianglePoints[1].ry() = y2;
  213. trianglePoints[2].rx() = x2;
  214. trianglePoints[2].ry() = y1;
  215. break;
  216. }
  217. }
  218. QwtPainter::drawPolygon( painter, triangle );
  219. }
  220. }
  221. static inline void qwtDrawLineSymbols(
  222. QPainter *painter, int orientations,
  223. const QPointF *points, int numPoints, const QwtSymbol &symbol )
  224. {
  225. const QSize size = symbol.size();
  226. QPen pen = symbol.pen();
  227. pen.setCapStyle( Qt::FlatCap );
  228. painter->setPen( pen );
  229. painter->setRenderHint( QPainter::Antialiasing, false );
  230. if ( QwtPainter::roundingAlignment( painter ) )
  231. {
  232. const int sw = qFloor( size.width() );
  233. const int sh = qFloor( size.height() );
  234. const int sw2 = size.width() / 2;
  235. const int sh2 = size.height() / 2;
  236. for ( int i = 0; i < numPoints; i++ )
  237. {
  238. if ( orientations & Qt::Horizontal )
  239. {
  240. const int x = qRound( points[i].x() ) - sw2;
  241. const int y = qRound( points[i].y() );
  242. QwtPainter::drawLine( painter, x, y, x + sw, y );
  243. }
  244. if ( orientations & Qt::Vertical )
  245. {
  246. const int x = qRound( points[i].x() );
  247. const int y = qRound( points[i].y() ) - sh2;
  248. QwtPainter::drawLine( painter, x, y, x, y + sh );
  249. }
  250. }
  251. }
  252. else
  253. {
  254. const double sw = size.width();
  255. const double sh = size.height();
  256. const double sw2 = 0.5 * size.width();
  257. const double sh2 = 0.5 * size.height();
  258. for ( int i = 0; i < numPoints; i++ )
  259. {
  260. if ( orientations & Qt::Horizontal )
  261. {
  262. const double x = points[i].x() - sw2;
  263. const double y = points[i].y();
  264. QwtPainter::drawLine( painter, x, y, x + sw, y );
  265. }
  266. if ( orientations & Qt::Vertical )
  267. {
  268. const double y = points[i].y() - sh2;
  269. const double x = points[i].x();
  270. QwtPainter::drawLine( painter, x, y, x, y + sh );
  271. }
  272. }
  273. }
  274. }
  275. static inline void qwtDrawXCrossSymbols( QPainter *painter,
  276. const QPointF *points, int numPoints, const QwtSymbol &symbol )
  277. {
  278. const QSize size = symbol.size();
  279. QPen pen = symbol.pen();
  280. pen.setCapStyle( Qt::FlatCap );
  281. painter->setPen( pen );
  282. if ( QwtPainter::roundingAlignment( painter ) )
  283. {
  284. const int sw = size.width();
  285. const int sh = size.height();
  286. const int sw2 = size.width() / 2;
  287. const int sh2 = size.height() / 2;
  288. for ( int i = 0; i < numPoints; i++ )
  289. {
  290. const QPointF &pos = points[i];
  291. const int x = qRound( pos.x() );
  292. const int y = qRound( pos.y() );
  293. const int x1 = x - sw2;
  294. const int x2 = x1 + sw;
  295. const int y1 = y - sh2;
  296. const int y2 = y1 + sh;
  297. QwtPainter::drawLine( painter, x1, y1, x2, y2 );
  298. QwtPainter::drawLine( painter, x2, y1, x1, y2 );
  299. }
  300. }
  301. else
  302. {
  303. const double sw = size.width();
  304. const double sh = size.height();
  305. const double sw2 = 0.5 * size.width();
  306. const double sh2 = 0.5 * size.height();
  307. for ( int i = 0; i < numPoints; i++ )
  308. {
  309. const QPointF &pos = points[i];
  310. const double x1 = pos.x() - sw2;
  311. const double x2 = x1 + sw;
  312. const double y1 = pos.y() - sh2;
  313. const double y2 = y1 + sh;
  314. QwtPainter::drawLine( painter, x1, y1, x2, y2 );
  315. QwtPainter::drawLine( painter, x1, y2, x2, y1 );
  316. }
  317. }
  318. }
  319. static inline void qwtDrawStar1Symbols( QPainter *painter,
  320. const QPointF *points, int numPoints, const QwtSymbol &symbol )
  321. {
  322. const QSize size = symbol.size();
  323. painter->setPen( symbol.pen() );
  324. if ( QwtPainter::roundingAlignment( painter ) )
  325. {
  326. QRect r( 0, 0, size.width(), size.height() );
  327. for ( int i = 0; i < numPoints; i++ )
  328. {
  329. r.moveCenter( points[i].toPoint() );
  330. const double sqrt1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
  331. const double d1 = r.width() / 2.0 * ( 1.0 - sqrt1_2 );
  332. QwtPainter::drawLine( painter,
  333. qRound( r.left() + d1 ), qRound( r.top() + d1 ),
  334. qRound( r.right() - d1 ), qRound( r.bottom() - d1 ) );
  335. QwtPainter::drawLine( painter,
  336. qRound( r.left() + d1 ), qRound( r.bottom() - d1 ),
  337. qRound( r .right() - d1), qRound( r.top() + d1 ) );
  338. const QPoint c = r.center();
  339. QwtPainter::drawLine( painter,
  340. c.x(), r.top(), c.x(), r.bottom() );
  341. QwtPainter::drawLine( painter,
  342. r.left(), c.y(), r.right(), c.y() );
  343. }
  344. }
  345. else
  346. {
  347. QRectF r( 0, 0, size.width(), size.height() );
  348. for ( int i = 0; i < numPoints; i++ )
  349. {
  350. r.moveCenter( points[i] );
  351. const double sqrt1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
  352. const QPointF c = r.center();
  353. const double d1 = r.width() / 2.0 * ( 1.0 - sqrt1_2 );
  354. QwtPainter::drawLine( painter,
  355. r.left() + d1, r.top() + d1,
  356. r.right() - d1, r.bottom() - d1 );
  357. QwtPainter::drawLine( painter,
  358. r.left() + d1, r.bottom() - d1,
  359. r.right() - d1, r.top() + d1 );
  360. QwtPainter::drawLine( painter,
  361. c.x(), r.top(),
  362. c.x(), r.bottom() );
  363. QwtPainter::drawLine( painter,
  364. r.left(), c.y(),
  365. r.right(), c.y() );
  366. }
  367. }
  368. }
  369. static inline void qwtDrawStar2Symbols( QPainter *painter,
  370. const QPointF *points, int numPoints, const QwtSymbol &symbol )
  371. {
  372. QPen pen = symbol.pen();
  373. pen.setCapStyle( Qt::FlatCap );
  374. pen.setJoinStyle( Qt::MiterJoin );
  375. painter->setPen( pen );
  376. painter->setBrush( symbol.brush() );
  377. const double cos30 = 0.866025; // cos(30°)
  378. const double dy = 0.25 * symbol.size().height();
  379. const double dx = 0.5 * symbol.size().width() * cos30 / 3.0;
  380. QPolygonF star( 12 );
  381. QPointF *starPoints = star.data();
  382. const bool doAlign = QwtPainter::roundingAlignment( painter );
  383. for ( int i = 0; i < numPoints; i++ )
  384. {
  385. double x = points[i].x();
  386. double y = points[i].y();
  387. if ( doAlign )
  388. {
  389. x = qRound( x );
  390. y = qRound( y );
  391. }
  392. double x1 = x - 3 * dx;
  393. double y1 = y - 2 * dy;
  394. if ( doAlign )
  395. {
  396. x1 = qRound( x - 3 * dx );
  397. y1 = qRound( y - 2 * dy );
  398. }
  399. const double x2 = x1 + 1 * dx;
  400. const double x3 = x1 + 2 * dx;
  401. const double x4 = x1 + 3 * dx;
  402. const double x5 = x1 + 4 * dx;
  403. const double x6 = x1 + 5 * dx;
  404. const double x7 = x1 + 6 * dx;
  405. const double y2 = y1 + 1 * dy;
  406. const double y3 = y1 + 2 * dy;
  407. const double y4 = y1 + 3 * dy;
  408. const double y5 = y1 + 4 * dy;
  409. starPoints[0].rx() = x4;
  410. starPoints[0].ry() = y1;
  411. starPoints[1].rx() = x5;
  412. starPoints[1].ry() = y2;
  413. starPoints[2].rx() = x7;
  414. starPoints[2].ry() = y2;
  415. starPoints[3].rx() = x6;
  416. starPoints[3].ry() = y3;
  417. starPoints[4].rx() = x7;
  418. starPoints[4].ry() = y4;
  419. starPoints[5].rx() = x5;
  420. starPoints[5].ry() = y4;
  421. starPoints[6].rx() = x4;
  422. starPoints[6].ry() = y5;
  423. starPoints[7].rx() = x3;
  424. starPoints[7].ry() = y4;
  425. starPoints[8].rx() = x1;
  426. starPoints[8].ry() = y4;
  427. starPoints[9].rx() = x2;
  428. starPoints[9].ry() = y3;
  429. starPoints[10].rx() = x1;
  430. starPoints[10].ry() = y2;
  431. starPoints[11].rx() = x3;
  432. starPoints[11].ry() = y2;
  433. QwtPainter::drawPolygon( painter, star );
  434. }
  435. }
  436. static inline void qwtDrawHexagonSymbols( QPainter *painter,
  437. const QPointF *points, int numPoints, const QwtSymbol &symbol )
  438. {
  439. painter->setBrush( symbol.brush() );
  440. painter->setPen( symbol.pen() );
  441. const double cos30 = 0.866025; // cos(30°)
  442. const double dx = 0.5 * ( symbol.size().width() - cos30 );
  443. const double dy = 0.25 * symbol.size().height();
  444. QPolygonF hexaPolygon( 6 );
  445. QPointF *hexaPoints = hexaPolygon.data();
  446. const bool doAlign = QwtPainter::roundingAlignment( painter );
  447. for ( int i = 0; i < numPoints; i++ )
  448. {
  449. double x = points[i].x();
  450. double y = points[i].y();
  451. if ( doAlign )
  452. {
  453. x = qRound( x );
  454. y = qRound( y );
  455. }
  456. double x1 = x - dx;
  457. double y1 = y - 2 * dy;
  458. if ( doAlign )
  459. {
  460. x1 = qCeil( x1 );
  461. y1 = qCeil( y1 );
  462. }
  463. const double x2 = x1 + 1 * dx;
  464. const double x3 = x1 + 2 * dx;
  465. const double y2 = y1 + 1 * dy;
  466. const double y3 = y1 + 3 * dy;
  467. const double y4 = y1 + 4 * dy;
  468. hexaPoints[0].rx() = x2;
  469. hexaPoints[0].ry() = y1;
  470. hexaPoints[1].rx() = x3;
  471. hexaPoints[1].ry() = y2;
  472. hexaPoints[2].rx() = x3;
  473. hexaPoints[2].ry() = y3;
  474. hexaPoints[3].rx() = x2;
  475. hexaPoints[3].ry() = y4;
  476. hexaPoints[4].rx() = x1;
  477. hexaPoints[4].ry() = y3;
  478. hexaPoints[5].rx() = x1;
  479. hexaPoints[5].ry() = y2;
  480. QwtPainter::drawPolygon( painter, hexaPolygon );
  481. }
  482. }
  483. class QwtSymbol::PrivateData
  484. {
  485. public:
  486. PrivateData( QwtSymbol::Style st, const QBrush &br,
  487. const QPen &pn, const QSize &sz ):
  488. style( st ),
  489. size( sz ),
  490. brush( br ),
  491. pen( pn )
  492. {
  493. }
  494. bool operator==( const PrivateData &other ) const
  495. {
  496. return ( style == other.style )
  497. && ( size == other.size )
  498. && ( brush == other.brush )
  499. && ( pen == other.pen );
  500. }
  501. Style style;
  502. QSize size;
  503. QBrush brush;
  504. QPen pen;
  505. };
  506. /*!
  507. Default Constructor
  508. \param style Symbol Style
  509. The symbol is constructed with gray interior,
  510. black outline with zero width, no size and style 'NoSymbol'.
  511. */
  512. QwtSymbol::QwtSymbol( Style style )
  513. {
  514. d_data = new PrivateData( style, QBrush( Qt::gray ),
  515. QPen( Qt::black ), QSize( 0.0, 0.0 ) );
  516. }
  517. /*!
  518. \brief Constructor
  519. \param style Symbol Style
  520. \param brush brush to fill the interior
  521. \param pen outline pen
  522. \param size size
  523. \sa setStyle(), setBrush(), setPen(), setSize()
  524. */
  525. QwtSymbol::QwtSymbol( QwtSymbol::Style style, const QBrush &brush,
  526. const QPen &pen, const QSize &size )
  527. {
  528. d_data = new PrivateData( style, brush, pen, size );
  529. }
  530. /*!
  531. \brief Copy constructor
  532. \param other Symbol
  533. */
  534. QwtSymbol::QwtSymbol( const QwtSymbol &other )
  535. {
  536. d_data = new PrivateData( other.style(), other.brush(),
  537. other.pen(), other.size() );
  538. };
  539. //! Destructor
  540. QwtSymbol::~QwtSymbol()
  541. {
  542. delete d_data;
  543. }
  544. //! \brief Assignment operator
  545. QwtSymbol &QwtSymbol::operator=( const QwtSymbol &other )
  546. {
  547. *d_data = *other.d_data;
  548. return *this;
  549. }
  550. //! \brief Compare two symbols
  551. bool QwtSymbol::operator==( const QwtSymbol &other ) const
  552. {
  553. return *d_data == *other.d_data;
  554. }
  555. //! \brief Compare two symbols
  556. bool QwtSymbol::operator!=( const QwtSymbol &other ) const
  557. {
  558. return !( *d_data == *other.d_data );
  559. }
  560. /*!
  561. \brief Specify the symbol's size
  562. If the 'h' parameter is left out or less than 0,
  563. and the 'w' parameter is greater than or equal to 0,
  564. the symbol size will be set to (w,w).
  565. \param width Width
  566. \param height Height (defaults to -1)
  567. \sa size()
  568. */
  569. void QwtSymbol::setSize( int width, int height )
  570. {
  571. if ( ( width >= 0 ) && ( height < 0 ) )
  572. height = width;
  573. d_data->size = QSize( width, height );
  574. }
  575. /*!
  576. Set the symbol's size
  577. \param size Size
  578. \sa size()
  579. */
  580. void QwtSymbol::setSize( const QSize &size )
  581. {
  582. if ( size.isValid() )
  583. d_data->size = size;
  584. }
  585. /*!
  586. \return Size
  587. \sa setSize()
  588. */
  589. const QSize& QwtSymbol::size() const
  590. {
  591. return d_data->size;
  592. }
  593. /*!
  594. \brief Assign a brush
  595. The brush is used to draw the interior of the symbol.
  596. \param brush Brush
  597. \sa brush()
  598. */
  599. void QwtSymbol::setBrush( const QBrush &brush )
  600. {
  601. d_data->brush = brush;
  602. }
  603. /*!
  604. \return Brush
  605. \sa setBrush()
  606. */
  607. const QBrush& QwtSymbol::brush() const
  608. {
  609. return d_data->brush;
  610. }
  611. /*!
  612. Assign a pen
  613. The pen is used to draw the symbol's outline.
  614. \param pen Pen
  615. \sa pen(), setBrush()
  616. */
  617. void QwtSymbol::setPen( const QPen &pen )
  618. {
  619. d_data->pen = pen;
  620. }
  621. /*!
  622. \return Pen
  623. \sa setPen(), brush()
  624. */
  625. const QPen& QwtSymbol::pen() const
  626. {
  627. return d_data->pen;
  628. }
  629. /*!
  630. \brief Set the color of the symbol
  631. Change the color of the brush for symbol types with a filled area.
  632. For all other symbol types the color will be assigned to the pen.
  633. \param color Color
  634. \sa setBrush(), setPen(), brush(), pen()
  635. */
  636. void QwtSymbol::setColor( const QColor &color )
  637. {
  638. switch ( d_data->style )
  639. {
  640. case QwtSymbol::Ellipse:
  641. case QwtSymbol::Rect:
  642. case QwtSymbol::Diamond:
  643. case QwtSymbol::Triangle:
  644. case QwtSymbol::UTriangle:
  645. case QwtSymbol::DTriangle:
  646. case QwtSymbol::RTriangle:
  647. case QwtSymbol::LTriangle:
  648. case QwtSymbol::Star2:
  649. case QwtSymbol::Hexagon:
  650. {
  651. d_data->brush.setColor( color );
  652. break;
  653. }
  654. case QwtSymbol::Cross:
  655. case QwtSymbol::XCross:
  656. case QwtSymbol::HLine:
  657. case QwtSymbol::VLine:
  658. case QwtSymbol::Star1:
  659. {
  660. d_data->pen.setColor( color );
  661. break;
  662. }
  663. default:
  664. {
  665. d_data->brush.setColor( color );
  666. d_data->pen.setColor( color );
  667. }
  668. }
  669. }
  670. /*!
  671. Draw an array of symbols
  672. Painting several symbols is more effective than drawing symbols
  673. one by one, as a couple of layout calculations and setting of pen/brush
  674. can be done once for the complete array.
  675. \param painter Painter
  676. \param points Array of points
  677. \param numPoints Number of points
  678. */
  679. void QwtSymbol::drawSymbols( QPainter *painter,
  680. const QPointF *points, int numPoints ) const
  681. {
  682. if ( numPoints <= 0 )
  683. return;
  684. painter->save();
  685. switch ( d_data->style )
  686. {
  687. case QwtSymbol::Ellipse:
  688. {
  689. qwtDrawEllipseSymbols( painter, points, numPoints, *this );
  690. break;
  691. }
  692. case QwtSymbol::Rect:
  693. {
  694. qwtDrawRectSymbols( painter, points, numPoints, *this );
  695. break;
  696. }
  697. case QwtSymbol::Diamond:
  698. {
  699. qwtDrawDiamondSymbols( painter, points, numPoints, *this );
  700. break;
  701. }
  702. case QwtSymbol::Cross:
  703. {
  704. qwtDrawLineSymbols( painter, Qt::Horizontal | Qt::Vertical,
  705. points, numPoints, *this );
  706. break;
  707. }
  708. case QwtSymbol::XCross:
  709. {
  710. qwtDrawXCrossSymbols( painter, points, numPoints, *this );
  711. break;
  712. }
  713. case QwtSymbol::Triangle:
  714. case QwtSymbol::UTriangle:
  715. {
  716. qwtDrawTriangleSymbols( painter, QwtTriangle::Up,
  717. points, numPoints, *this );
  718. break;
  719. }
  720. case QwtSymbol::DTriangle:
  721. {
  722. qwtDrawTriangleSymbols( painter, QwtTriangle::Down,
  723. points, numPoints, *this );
  724. break;
  725. }
  726. case QwtSymbol::RTriangle:
  727. {
  728. qwtDrawTriangleSymbols( painter, QwtTriangle::Right,
  729. points, numPoints, *this );
  730. break;
  731. }
  732. case QwtSymbol::LTriangle:
  733. {
  734. qwtDrawTriangleSymbols( painter, QwtTriangle::Left,
  735. points, numPoints, *this );
  736. break;
  737. }
  738. case QwtSymbol::HLine:
  739. {
  740. qwtDrawLineSymbols( painter, Qt::Horizontal,
  741. points, numPoints, *this );
  742. break;
  743. }
  744. case QwtSymbol::VLine:
  745. {
  746. qwtDrawLineSymbols( painter, Qt::Vertical,
  747. points, numPoints, *this );
  748. break;
  749. }
  750. case QwtSymbol::Star1:
  751. {
  752. qwtDrawStar1Symbols( painter, points, numPoints, *this );
  753. break;
  754. }
  755. case QwtSymbol::Star2:
  756. {
  757. qwtDrawStar2Symbols( painter, points, numPoints, *this );
  758. break;
  759. }
  760. case QwtSymbol::Hexagon:
  761. {
  762. qwtDrawHexagonSymbols( painter, points, numPoints, *this );
  763. break;
  764. }
  765. default:;
  766. }
  767. painter->restore();
  768. }
  769. //! \return Size of the bounding rectangle of a symbol
  770. QSize QwtSymbol::boundingSize() const
  771. {
  772. QSize size;
  773. switch ( d_data->style )
  774. {
  775. case QwtSymbol::Ellipse:
  776. case QwtSymbol::Rect:
  777. case QwtSymbol::Hexagon:
  778. {
  779. qreal pw = 0.0;
  780. if ( d_data->pen.style() != Qt::NoPen )
  781. pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) );
  782. size = d_data->size + QSize( pw, pw );
  783. break;
  784. }
  785. case QwtSymbol::XCross:
  786. case QwtSymbol::Diamond:
  787. case QwtSymbol::Triangle:
  788. case QwtSymbol::UTriangle:
  789. case QwtSymbol::DTriangle:
  790. case QwtSymbol::RTriangle:
  791. case QwtSymbol::LTriangle:
  792. case QwtSymbol::Star1:
  793. case QwtSymbol::Star2:
  794. {
  795. qreal pw = 0.0;
  796. if ( d_data->pen.style() != Qt::NoPen )
  797. pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) );
  798. size = d_data->size + QSize( 2 * pw, 2 * pw );
  799. break;
  800. }
  801. default:
  802. {
  803. size = d_data->size;
  804. }
  805. }
  806. return size + QSize( 1, 1 ); // for antialiasing
  807. }
  808. /*!
  809. Specify the symbol style
  810. \param style Style
  811. \sa style()
  812. */
  813. void QwtSymbol::setStyle( QwtSymbol::Style style )
  814. {
  815. d_data->style = style;
  816. }
  817. /*!
  818. \return Current symbol style
  819. \sa setStyle()
  820. */
  821. QwtSymbol::Style QwtSymbol::style() const
  822. {
  823. return d_data->style;
  824. }