File indexing completed on 2024-04-28 15:15:36
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2006-2009 Torsten Rahn <tackat@kde.org> 0004 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org> 0005 // 0006 0007 0008 #include "ClipPainter.h" 0009 0010 #include <cmath> 0011 0012 #include "MarbleDebug.h" 0013 0014 0015 namespace Marble 0016 { 0017 0018 class ClipPainterPrivate 0019 { 0020 public: 0021 explicit ClipPainterPrivate( ClipPainter * parent ); 0022 0023 ClipPainter * q; 0024 0025 // true if clipping is on. 0026 bool m_doClip; 0027 0028 // The limits 0029 qreal m_left; 0030 qreal m_right; 0031 qreal m_top; 0032 qreal m_bottom; 0033 0034 // Used in the paint process of vectors.. 0035 int m_currentSector; 0036 int m_previousSector; 0037 0038 // int m_debugNodeCount; 0039 0040 QPointF m_currentPoint; 0041 QPointF m_previousPoint; 0042 0043 inline int sector( const QPointF & point ) const; 0044 0045 inline QPointF clipTop( qreal m, const QPointF & point ) const; 0046 inline QPointF clipLeft( qreal m, const QPointF & point ) const; 0047 inline QPointF clipBottom( qreal m, const QPointF & point ) const; 0048 inline QPointF clipRight( qreal m, const QPointF & point ) const; 0049 0050 inline void initClipRect(); 0051 0052 inline void clipPolyObject ( const QPolygonF & sourcePolygon, 0053 QVector<QPolygonF> & clippedPolyObjects, 0054 bool isClosed ); 0055 0056 inline void clipMultiple( QPolygonF & clippedPolyObject, 0057 QVector<QPolygonF> & clippedPolyObjects, 0058 bool isClosed ); 0059 inline void clipOnce( QPolygonF & clippedPolyObject, 0060 QVector<QPolygonF> & clippedPolyObjects, 0061 bool isClosed ); 0062 inline void clipOnceCorner( QPolygonF & clippedPolyObject, 0063 QVector<QPolygonF> & clippedPolyObjects, 0064 const QPointF& corner, 0065 const QPointF& point, 0066 bool isClosed ) const; 0067 inline void clipOnceEdge( QPolygonF & clippedPolyObject, 0068 QVector<QPolygonF> & clippedPolyObjects, 0069 const QPointF& point, 0070 bool isClosed ) const; 0071 0072 0073 void labelPosition(const QPolygonF &polygon, QVector<QPointF> &labelNodes, 0074 LabelPositionFlags labelPositionFlags) const; 0075 0076 bool pointAllowsLabel(const QPointF &point) const; 0077 QPointF interpolateLabelPoint(const QPointF &previousPoint, 0078 const QPointF ¤tPoint, 0079 LabelPositionFlags labelPositionFlags) const; 0080 0081 static inline qreal _m( const QPointF & start, const QPointF & end ); 0082 0083 void debugDrawNodes( const QPolygonF & ); 0084 0085 qreal m_labelAreaMargin; 0086 0087 int m_debugPenBatchColor; 0088 int m_debugBrushBatchColor; 0089 int m_debugPolygonsLevel; 0090 bool m_debugBatchRender; 0091 }; 0092 0093 } 0094 0095 using namespace Marble; 0096 0097 // #define MARBLE_DEBUG 0098 0099 ClipPainter::ClipPainter(QPaintDevice * pd, bool clip) 0100 : QPainter( pd ), d( new ClipPainterPrivate( this ) ) 0101 { 0102 d->initClipRect(); 0103 0104 // m_debugNodeCount = 0; 0105 d->m_doClip = clip; 0106 } 0107 0108 0109 ClipPainter::ClipPainter() 0110 : d( new ClipPainterPrivate( this ) ) 0111 { 0112 } 0113 0114 0115 ClipPainter::~ClipPainter() 0116 { 0117 delete d; 0118 } 0119 0120 0121 void ClipPainter::setScreenClip(bool enable) 0122 { 0123 d->m_doClip = enable; 0124 } 0125 0126 0127 bool ClipPainter::hasScreenClip() const 0128 { 0129 return d->m_doClip; 0130 } 0131 0132 0133 void ClipPainter::drawPolygon ( const QPolygonF & polygon, 0134 Qt::FillRule fillRule ) 0135 { 0136 if ( d->m_doClip ) { 0137 d->initClipRect(); 0138 QVector<QPolygonF> clippedPolyObjects; 0139 0140 d->clipPolyObject( polygon, clippedPolyObjects, true ); 0141 0142 for( const QPolygonF & clippedPolyObject: clippedPolyObjects ) { 0143 if ( clippedPolyObject.size() > 2 ) { 0144 // mDebug() << "Size: " << clippedPolyObject.size(); 0145 if (d->m_debugPolygonsLevel) { 0146 QBrush brush = QPainter::brush(); 0147 QBrush originalBrush = brush; 0148 QColor color = brush.color(); 0149 color.setAlpha(color.alpha()*0.75); 0150 brush.setColor(color); 0151 QPainter::setBrush(brush); 0152 0153 QPainter::drawPolygon ( clippedPolyObject, fillRule ); 0154 0155 QPainter::setBrush(originalBrush); 0156 0157 d->debugDrawNodes( clippedPolyObject ); 0158 } 0159 else { 0160 QPainter::drawPolygon ( clippedPolyObject, fillRule ); 0161 } 0162 } 0163 } 0164 } 0165 else { 0166 if (d->m_debugPolygonsLevel) { 0167 QBrush brush = QPainter::brush(); 0168 QBrush originalBrush = brush; 0169 QColor color = brush.color(); 0170 color.setAlpha(color.alpha()*0.75); 0171 brush.setColor(color); 0172 QPainter::setBrush(brush); 0173 0174 QPainter::drawPolygon ( polygon, fillRule ); 0175 0176 QPainter::setBrush(originalBrush); 0177 0178 d->debugDrawNodes( polygon ); 0179 } 0180 else { 0181 QPainter::drawPolygon ( polygon, fillRule ); 0182 } 0183 } 0184 } 0185 0186 void ClipPainter::drawPolyline( const QPolygonF & polygon ) 0187 { 0188 if ( d->m_doClip ) { 0189 d->initClipRect(); 0190 QVector<QPolygonF> clippedPolyObjects; 0191 0192 d->clipPolyObject( polygon, clippedPolyObjects, false ); 0193 0194 for( const QPolygonF & clippedPolyObject: clippedPolyObjects ) { 0195 if ( clippedPolyObject.size() > 1 ) { 0196 if (d->m_debugPolygonsLevel) { 0197 QPen pen = QPainter::pen(); 0198 QPen originalPen = pen; 0199 QColor color = pen.color(); 0200 color.setAlpha(color.alpha()*0.75); 0201 pen.setColor(color); 0202 QPainter::setPen(pen); 0203 0204 QPainter::drawPolyline ( clippedPolyObject ); 0205 0206 QPainter::setPen(originalPen); 0207 0208 d->debugDrawNodes( clippedPolyObject ); 0209 } 0210 else { 0211 QPainter::drawPolyline ( clippedPolyObject ); 0212 } 0213 } 0214 } 0215 } 0216 else { 0217 if (d->m_debugPolygonsLevel) { 0218 QPen pen = QPainter::pen(); 0219 QPen originalPen = pen; 0220 QColor color = pen.color(); 0221 color.setAlpha(color.alpha()*0.75); 0222 pen.setColor(color); 0223 QPainter::setPen(pen); 0224 0225 QPainter::drawPolyline ( polygon ); 0226 0227 QPainter::setPen(originalPen); 0228 0229 d->debugDrawNodes( polygon ); 0230 } 0231 else { 0232 QPainter::drawPolyline ( polygon ); 0233 } 0234 } 0235 } 0236 0237 void ClipPainter::drawPolyline(const QPolygonF & polygon, QVector<QPointF>& labelNodes, 0238 LabelPositionFlags positionFlags) 0239 { 0240 if ( d->m_doClip ) { 0241 d->initClipRect(); 0242 QVector<QPolygonF> clippedPolyObjects; 0243 0244 d->clipPolyObject( polygon, clippedPolyObjects, false ); 0245 0246 for( const QPolygonF & clippedPolyObject: clippedPolyObjects ) { 0247 if (d->m_debugPolygonsLevel) { 0248 QPen pen = QPainter::pen(); 0249 QPen originalPen = pen; 0250 QColor color = pen.color(); 0251 color.setAlpha(color.alpha()*0.75); 0252 pen.setColor(color); 0253 QPainter::setPen(pen); 0254 0255 QPainter::drawPolyline ( clippedPolyObject ); 0256 0257 QPainter::setPen(originalPen); 0258 0259 d->debugDrawNodes( clippedPolyObject ); 0260 } 0261 else { 0262 QPainter::drawPolyline ( clippedPolyObject ); 0263 } 0264 } 0265 } 0266 else { 0267 if (d->m_debugPolygonsLevel) { 0268 QPen pen = QPainter::pen(); 0269 QPen originalPen = pen; 0270 QColor color = pen.color(); 0271 color.setAlpha(color.alpha()*0.75); 0272 pen.setColor(color); 0273 QPainter::setPen(pen); 0274 0275 QPainter::drawPolyline ( polygon ); 0276 0277 QPainter::setPen(originalPen); 0278 0279 d->debugDrawNodes( polygon ); 0280 } 0281 else { 0282 QPainter::drawPolyline ( polygon ); 0283 } 0284 0285 d->labelPosition( polygon, labelNodes, positionFlags ); 0286 } 0287 } 0288 0289 void ClipPainter::labelPosition(const QPolygonF &polygon, QVector<QPointF> &labelNodes, 0290 LabelPositionFlags labelPositionFlags) const 0291 { 0292 d->labelPosition(polygon, labelNodes, labelPositionFlags); 0293 } 0294 0295 void ClipPainter::setPen(const QColor &color) { 0296 if (d->m_debugBatchRender) { 0297 qDebug(); 0298 } 0299 setPen(QPen(color)); 0300 } 0301 0302 void ClipPainter::setPen(Qt::PenStyle style) { 0303 if (d->m_debugBatchRender) { 0304 qDebug(); 0305 } 0306 setPen(QPen(style)); 0307 } 0308 0309 void ClipPainter::setPen(const QPen & pen) { 0310 if (d->m_debugBatchRender) { 0311 qDebug(); 0312 if (pen != QPainter::pen()) { 0313 qDebug() << "--" << pen.color() << QPainter::pen().color() ; 0314 QPen newPen = pen; 0315 newPen.setColor((Qt::GlobalColor)(d->m_debugPenBatchColor+4)); 0316 QPainter::setPen(newPen); 0317 d->m_debugPenBatchColor++; 0318 d->m_debugPenBatchColor %= 14; 0319 } 0320 else { 0321 qDebug() << "++"; 0322 QPainter::setPen(pen); 0323 } 0324 } 0325 else { 0326 QPainter::setPen(pen); 0327 } 0328 } 0329 0330 void ClipPainter::setBrush(const QBrush & brush) { 0331 if (d->m_debugBatchRender) { 0332 qDebug(); 0333 if (brush != QPainter::brush()) { 0334 qDebug() << "--" << brush.color() << QPainter::brush().color() ; 0335 QBrush batchColor(QColor((Qt::GlobalColor)(d->m_debugBrushBatchColor))); 0336 QPainter::setBrush(batchColor); 0337 d->m_debugBrushBatchColor++; 0338 d->m_debugBrushBatchColor %= 20; 0339 } 0340 else { 0341 qDebug() << "++"; 0342 QPainter::setBrush(brush); 0343 } 0344 } 0345 else { 0346 QPainter::setBrush(brush); 0347 } 0348 } 0349 0350 void ClipPainterPrivate::labelPosition(const QPolygonF &polygon, QVector<QPointF> &labelNodes, 0351 LabelPositionFlags labelPositionFlags) const 0352 { 0353 if ( labelPositionFlags.testFlag( LineCenter ) ) { 0354 // The Label at the center of the polyline: 0355 if ( polygon.size() > 0 ) { 0356 const int labelPosition = polygon.size() / 2; // implied: 0 <= labelPosition < polygon.size() 0357 labelNodes << polygon.at( labelPosition ); 0358 } 0359 } 0360 0361 if ( polygon.size() > 0 && labelPositionFlags.testFlag( LineStart ) ) { 0362 if ( pointAllowsLabel( polygon.first() ) ) { 0363 labelNodes << polygon.first(); 0364 } 0365 0366 // The Label at the start of the polyline: 0367 for ( int it = 1; it < polygon.size(); ++it ) { 0368 const bool currentAllowsLabel = pointAllowsLabel(polygon.at(it)); 0369 0370 if ( currentAllowsLabel ) { 0371 // As polygon.size() > 0 it's ensured that it-1 exists. 0372 QPointF node = interpolateLabelPoint( polygon.at( it -1 ), polygon.at( it ), 0373 labelPositionFlags ); 0374 if ( node != QPointF( -1.0, -1.0 ) ) { 0375 labelNodes << node; 0376 } 0377 break; 0378 } 0379 } 0380 } 0381 0382 if ( polygon.size() > 1 && labelPositionFlags.testFlag( LineEnd ) ) { 0383 if ( pointAllowsLabel( polygon.at( polygon.size() - 1 ) ) ) { 0384 labelNodes << polygon.at( polygon.size() - 1 ); 0385 } 0386 0387 // The Label at the end of the polyline: 0388 for ( int it = polygon.size() - 2; it > 0; --it ) { 0389 const bool currentAllowsLabel = pointAllowsLabel(polygon.at(it)); 0390 0391 if ( currentAllowsLabel ) { 0392 QPointF node = interpolateLabelPoint( polygon.at( it + 1 ), polygon.at( it ), 0393 labelPositionFlags ); 0394 if ( node != QPointF( -1.0, -1.0 ) ) { 0395 labelNodes << node; 0396 } 0397 break; 0398 } 0399 } 0400 } 0401 } 0402 0403 bool ClipPainterPrivate::pointAllowsLabel(const QPointF &point) const 0404 { 0405 return point.x() > m_labelAreaMargin && point.x() < q->viewport().width() - m_labelAreaMargin 0406 && point.y() > m_labelAreaMargin && point.y() < q->viewport().height() - m_labelAreaMargin; 0407 } 0408 0409 QPointF ClipPainterPrivate::interpolateLabelPoint(const QPointF &previousPoint, 0410 const QPointF ¤tPoint, 0411 LabelPositionFlags labelPositionFlags) const 0412 { 0413 qreal m = _m( previousPoint, currentPoint ); 0414 if ( previousPoint.x() <= m_labelAreaMargin ) { 0415 if ( labelPositionFlags.testFlag( IgnoreXMargin ) ) { 0416 return QPointF( -1.0, -1.0 ); 0417 } 0418 return QPointF( m_labelAreaMargin, 0419 previousPoint.y() + ( m_labelAreaMargin - previousPoint.x() ) * m ); 0420 } 0421 else if ( previousPoint.x() >= q->viewport().width() - m_labelAreaMargin ) { 0422 if ( labelPositionFlags.testFlag( IgnoreXMargin ) ) { 0423 return QPointF( -1.0, -1.0 ); 0424 } 0425 return QPointF( q->viewport().width() - m_labelAreaMargin, 0426 previousPoint.y() - 0427 ( previousPoint.x() - q->viewport().width() + m_labelAreaMargin ) * m ); 0428 } 0429 0430 if ( previousPoint.y() <= m_labelAreaMargin ) { 0431 if ( labelPositionFlags.testFlag( IgnoreYMargin ) ) { 0432 return QPointF( -1.0, -1.0 ); 0433 } 0434 return QPointF( previousPoint.x() + ( m_labelAreaMargin - previousPoint.y() ) / m, 0435 m_labelAreaMargin ); 0436 } 0437 else if ( previousPoint.y() >= q->viewport().height() - m_labelAreaMargin ) { 0438 if ( labelPositionFlags.testFlag( IgnoreYMargin ) ) { 0439 return QPointF( -1.0, -1.0 ); 0440 } 0441 return QPointF( previousPoint.x() - 0442 ( previousPoint.y() - q->viewport().height() + m_labelAreaMargin ) / m, 0443 q->viewport().height() - m_labelAreaMargin ); 0444 } 0445 0446 // mDebug() << "Previous and current node position are allowed!"; 0447 0448 return QPointF( -1.0, -1.0 ); 0449 } 0450 0451 ClipPainterPrivate::ClipPainterPrivate( ClipPainter * parent ) 0452 : m_doClip( true ), 0453 m_left(0.0), 0454 m_right(0.0), 0455 m_top(0.0), 0456 m_bottom(0.0), 0457 m_currentSector(4), 0458 m_previousSector(4), 0459 m_currentPoint(QPointF()), 0460 m_previousPoint(QPointF()), 0461 m_labelAreaMargin(10.0), 0462 m_debugPenBatchColor(0), 0463 m_debugBrushBatchColor(0), 0464 m_debugPolygonsLevel(0), 0465 m_debugBatchRender(false) 0466 { 0467 q = parent; 0468 } 0469 0470 void ClipPainterPrivate::initClipRect () 0471 { 0472 qreal penHalfWidth = q->pen().widthF() / 2.0 + 1.0; 0473 0474 m_left = -penHalfWidth; 0475 m_right = (qreal)(q->device()->width()) + penHalfWidth; 0476 m_top = -penHalfWidth; 0477 m_bottom = (qreal)(q->device()->height()) + penHalfWidth; 0478 } 0479 0480 qreal ClipPainterPrivate::_m( const QPointF & start, const QPointF & end ) 0481 { 0482 qreal divisor = end.x() - start.x(); 0483 if ( std::fabs( divisor ) < 0.000001 ) { 0484 // this is in screencoordinates so the difference 0485 // between 0, 0.000001 and -0.000001 isn't visible at all 0486 divisor = 0.000001; 0487 } 0488 0489 return ( end.y() - start.y() ) 0490 / divisor; 0491 } 0492 0493 0494 QPointF ClipPainterPrivate::clipTop( qreal m, const QPointF & point ) const 0495 { 0496 return QPointF( ( m_top - point.y() ) / m + point.x(), m_top ); 0497 } 0498 0499 QPointF ClipPainterPrivate::clipLeft( qreal m, const QPointF & point ) const 0500 { 0501 return QPointF( m_left, ( m_left - point.x() ) * m + point.y() ); 0502 } 0503 0504 QPointF ClipPainterPrivate::clipBottom( qreal m, const QPointF & point ) const 0505 { 0506 return QPointF( ( m_bottom - point.y() ) / m + point.x(), m_bottom ); 0507 } 0508 0509 QPointF ClipPainterPrivate::clipRight( qreal m, const QPointF & point ) const 0510 { 0511 return QPointF( m_right, ( m_right - point.x() ) * m + point.y() ); 0512 } 0513 0514 int ClipPainterPrivate::sector( const QPointF & point ) const 0515 { 0516 // If we think of the image borders as (infinitely long) parallel 0517 // lines then the plane is divided into 9 sectors. Each of these 0518 // sections is identified by a unique keynumber (currentSector): 0519 // 0520 // 0 | 1 | 2 0521 // --+---+-- 0522 // 3 | 4 | 5 <- sector number "4" represents the onscreen sector / viewport 0523 // --+---+-- 0524 // 6 | 7 | 8 0525 // 0526 0527 // Figure out the section of the current point. 0528 int xSector = 1; 0529 if ( point.x() < m_left ) 0530 xSector = 0; 0531 else if ( point.x() > m_right ) 0532 xSector = 2; 0533 0534 int ySector = 3; 0535 if ( point.y() < m_top ) 0536 ySector = 0; 0537 else if ( point.y() > m_bottom ) 0538 ySector = 6; 0539 0540 // By adding xSector and ySector we get a 0541 // sector number of the values shown in the ASCII-art graph above. 0542 return ySector + xSector; 0543 0544 } 0545 0546 void ClipPainterPrivate::clipPolyObject ( const QPolygonF & polygon, 0547 QVector<QPolygonF> & clippedPolyObjects, 0548 bool isClosed ) 0549 { 0550 // mDebug() << "ClipPainter enabled." ; 0551 0552 // Only create a new polyObject as soon as we know for sure that 0553 // the current point is on the screen. 0554 QPolygonF clippedPolyObject = QPolygonF(); 0555 0556 const QVector<QPointF>::const_iterator itStartPoint = polygon.constBegin(); 0557 const QVector<QPointF>::const_iterator itEndPoint = polygon.constEnd(); 0558 QVector<QPointF>::const_iterator itPoint = itStartPoint; 0559 0560 // We use a while loop to be able to cover linestrings as well as linear rings: 0561 // Linear rings require to tessellate the path from the last node to the first node 0562 // which isn't really convenient to achieve with a for loop ... 0563 0564 bool processingLastNode = false; 0565 0566 while ( itPoint != itEndPoint ) { 0567 m_currentPoint = (*itPoint); 0568 // mDebug() << "m_currentPoint.x()" << m_currentPoint.x() << "m_currentPOint.y()" << m_currentPoint.y(); 0569 0570 // Figure out the sector of the current point. 0571 m_currentSector = sector( m_currentPoint ); 0572 0573 // Initialize the variables related to the previous point. 0574 if ( itPoint == itStartPoint && processingLastNode == false ) { 0575 if ( isClosed ) { 0576 m_previousPoint = polygon.last(); 0577 0578 // Figure out the sector of the previous point. 0579 m_previousSector = sector( m_previousPoint ); 0580 } 0581 else { 0582 m_previousSector = m_currentSector; 0583 } 0584 } 0585 0586 // If the current point reaches a new sector, take care of clipping. 0587 if ( m_currentSector != m_previousSector ) { 0588 if ( m_currentSector == 4 || m_previousSector == 4 ) { 0589 // In this case the current or the previous point is visible on the 0590 // screen but not both. Hence we only need to clip once and require 0591 // only one interpolation for both cases. 0592 0593 clipOnce( clippedPolyObject, clippedPolyObjects, isClosed ); 0594 } 0595 else { 0596 // This case mostly deals with lines that reach from one 0597 // sector that is located off screen to another one that 0598 // is located off screen. In this situation the line 0599 // can get clipped once, twice, or not at all. 0600 clipMultiple( clippedPolyObject, clippedPolyObjects, isClosed ); 0601 } 0602 0603 m_previousSector = m_currentSector; 0604 } 0605 0606 // If the current point is onscreen, just add it to our final polygon. 0607 if ( m_currentSector == 4 ) { 0608 0609 clippedPolyObject << m_currentPoint; 0610 #ifdef MARBLE_DEBUG 0611 ++(m_debugNodeCount); 0612 #endif 0613 } 0614 0615 m_previousPoint = m_currentPoint; 0616 0617 // Now let's handle the case where we have a (closed) polygon and where the 0618 // last point of the polyline is outside the viewport and the start point 0619 // is inside the viewport. This needs special treatment 0620 if ( processingLastNode ) { 0621 break; 0622 } 0623 ++itPoint; 0624 0625 if ( itPoint == itEndPoint && isClosed ) { 0626 itPoint = itStartPoint; 0627 processingLastNode = true; 0628 } 0629 } 0630 0631 // Only add the pointer if there's node data available. 0632 if ( !clippedPolyObject.isEmpty() ) { 0633 clippedPolyObjects << clippedPolyObject; 0634 } 0635 } 0636 0637 0638 void ClipPainterPrivate::clipMultiple( QPolygonF & clippedPolyObject, 0639 QVector<QPolygonF> & clippedPolyObjects, 0640 bool isClosed ) 0641 { 0642 Q_UNUSED( clippedPolyObjects ) 0643 Q_UNUSED( isClosed ) 0644 0645 // Take care of adding nodes in the image corners if the iterator 0646 // traverses off screen sections. 0647 0648 qreal m = _m( m_previousPoint, m_currentPoint ); 0649 0650 switch ( m_currentSector ) { 0651 case 0: 0652 if ( m_previousSector == 5 ) { 0653 QPointF pointRight = clipRight( m, m_previousPoint ); 0654 QPointF pointTop = clipTop( m, m_currentPoint ); 0655 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0656 0657 if ( pointRight.y() > m_top ) { 0658 clippedPolyObject << pointRight; 0659 } else { 0660 clippedPolyObject << QPointF( m_right, m_top ); 0661 } 0662 if ( pointTop.x() >= m_left && pointTop.x() < m_right ) 0663 clippedPolyObject << pointTop; 0664 if ( pointLeft.y() > m_top ) 0665 clippedPolyObject << pointLeft; 0666 } 0667 else if ( m_previousSector == 7 ) { 0668 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0669 QPointF pointTop = clipTop( m, m_currentPoint ); 0670 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0671 0672 if ( pointBottom.x() > m_left ) { 0673 clippedPolyObject << pointBottom; 0674 } else { 0675 clippedPolyObject << QPointF( m_left, m_bottom ); 0676 } 0677 if ( pointLeft.y() >= m_top && pointLeft.y() < m_bottom ) 0678 clippedPolyObject << pointLeft; 0679 if ( pointTop.x() > m_left ) 0680 clippedPolyObject << pointTop; 0681 } 0682 else if ( m_previousSector == 8 ) { 0683 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0684 QPointF pointRight = clipRight( m, m_previousPoint ); 0685 QPointF pointTop = clipTop( m, m_currentPoint ); 0686 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0687 0688 if ( pointBottom.x() > m_left && pointBottom.x() < m_right ) 0689 clippedPolyObject << pointBottom; 0690 if ( pointRight.y() > m_top && pointRight.y() < m_bottom ) 0691 clippedPolyObject << pointRight; 0692 if ( pointTop.x() > m_left && pointTop.x() < m_right ) 0693 clippedPolyObject << pointTop; 0694 if ( pointLeft.y() > m_top && pointLeft.y() < m_bottom ) 0695 clippedPolyObject << pointLeft; 0696 0697 if ( pointBottom.x() <= m_left && pointLeft.y() >= m_bottom ) 0698 clippedPolyObject << QPointF( m_left, m_bottom ); 0699 if ( pointTop.x() >= m_right && pointRight.y() <= m_top ) 0700 clippedPolyObject << QPointF( m_right, m_top ); 0701 } 0702 0703 clippedPolyObject << QPointF( m_left, m_top ); 0704 break; 0705 0706 case 1: 0707 if ( m_previousSector == 3 ) { 0708 QPointF pointLeft = clipLeft( m, m_previousPoint ); 0709 QPointF pointTop = clipTop( m, m_currentPoint ); 0710 0711 if ( pointLeft.y() > m_top ) { 0712 clippedPolyObject << pointLeft; 0713 } else { 0714 clippedPolyObject << QPointF( m_left, m_top ); 0715 } 0716 if ( pointTop.x() > m_left ) 0717 clippedPolyObject << pointTop; 0718 } 0719 else if ( m_previousSector == 5 ) { 0720 QPointF pointRight = clipRight( m, m_previousPoint ); 0721 QPointF pointTop = clipTop( m, m_currentPoint ); 0722 0723 if ( pointRight.y() > m_top ) { 0724 clippedPolyObject << pointRight; 0725 } else { 0726 clippedPolyObject << QPointF( m_right, m_top ); 0727 } 0728 if ( pointTop.x() < m_right ) 0729 clippedPolyObject << pointTop; 0730 } 0731 else if ( m_previousSector == 6 ) { 0732 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0733 QPointF pointLeft = clipLeft( m, m_previousPoint ); 0734 QPointF pointTop = clipTop( m, m_currentPoint ); 0735 0736 if ( pointBottom.x() > m_left ) 0737 clippedPolyObject << pointBottom; 0738 if ( pointLeft.y() > m_top && pointLeft.y() <= m_bottom ) 0739 clippedPolyObject << pointLeft; 0740 if ( pointTop.x() > m_left ) { 0741 clippedPolyObject << pointTop; 0742 } else { 0743 clippedPolyObject << QPointF( m_left, m_top ); 0744 } 0745 } 0746 else if ( m_previousSector == 7 ) { 0747 clippedPolyObject << clipBottom( m, m_previousPoint ); 0748 clippedPolyObject << clipTop( m, m_currentPoint ); 0749 } 0750 else if ( m_previousSector == 8 ) { 0751 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0752 QPointF pointRight = clipRight( m, m_previousPoint ); 0753 QPointF pointTop = clipTop( m, m_currentPoint ); 0754 0755 if ( pointBottom.x() < m_right ) 0756 clippedPolyObject << pointBottom; 0757 if ( pointRight.y() > m_top && pointRight.y() <= m_bottom ) 0758 clippedPolyObject << pointRight; 0759 if ( pointTop.x() < m_right ) { 0760 clippedPolyObject << pointTop; 0761 } else { 0762 clippedPolyObject << QPointF( m_right, m_top ); 0763 } 0764 } 0765 break; 0766 0767 case 2: 0768 if ( m_previousSector == 3 ) { 0769 QPointF pointLeft = clipLeft( m, m_previousPoint ); 0770 QPointF pointTop = clipTop( m, m_currentPoint ); 0771 QPointF pointRight = clipRight( m, m_currentPoint ); 0772 0773 if ( pointLeft.y() > m_top ) { 0774 clippedPolyObject << pointLeft; 0775 } else { 0776 clippedPolyObject << QPointF( m_left, m_top ); 0777 } 0778 if ( pointTop.x() > m_left && pointTop.x() <= m_right ) 0779 clippedPolyObject << pointTop; 0780 if ( pointRight.y() > m_top ) 0781 clippedPolyObject << pointRight; 0782 } 0783 else if ( m_previousSector == 7 ) { 0784 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0785 QPointF pointTop = clipTop( m, m_currentPoint ); 0786 QPointF pointRight = clipRight( m, m_currentPoint ); 0787 0788 if ( pointBottom.x() < m_right ) { 0789 clippedPolyObject << pointBottom; 0790 } else { 0791 clippedPolyObject << QPointF( m_right, m_bottom ); 0792 } 0793 if ( pointRight.y() >= m_top && pointRight.y() < m_bottom ) 0794 clippedPolyObject << pointRight; 0795 if ( pointTop.x() < m_right ) 0796 clippedPolyObject << pointTop; 0797 } 0798 else if ( m_previousSector == 6 ) { 0799 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0800 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0801 QPointF pointTop = clipTop( m, m_currentPoint ); 0802 QPointF pointRight = clipRight( m, m_previousPoint ); 0803 0804 if ( pointBottom.x() > m_left && pointBottom.x() < m_right ) 0805 clippedPolyObject << pointBottom; 0806 if ( pointLeft.y() > m_top && pointLeft.y() < m_bottom ) 0807 clippedPolyObject << pointLeft; 0808 if ( pointTop.x() > m_left && pointTop.x() < m_right ) 0809 clippedPolyObject << pointTop; 0810 if ( pointRight.y() > m_top && pointRight.y() < m_bottom ) 0811 clippedPolyObject << pointRight; 0812 0813 if ( pointBottom.x() >= m_right && pointRight.y() >= m_bottom ) 0814 clippedPolyObject << QPointF( m_right, m_bottom ); 0815 if ( pointTop.x() <= m_left && pointLeft.y() <= m_top ) 0816 clippedPolyObject << QPointF( m_left, m_top ); 0817 } 0818 0819 clippedPolyObject << QPointF( m_right, m_top ); 0820 break; 0821 0822 case 3: 0823 if ( m_previousSector == 7 ) { 0824 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0825 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0826 0827 if ( pointBottom.x() > m_left ) 0828 clippedPolyObject << pointBottom; 0829 if ( pointLeft.y() < m_bottom ) { 0830 clippedPolyObject << pointLeft; 0831 } else { 0832 clippedPolyObject << QPointF( m_left, m_bottom ); 0833 } 0834 } 0835 else if ( m_previousSector == 1 ) { 0836 QPointF pointTop = clipTop( m, m_previousPoint ); 0837 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0838 0839 if ( pointTop.x() > m_left ) 0840 clippedPolyObject << pointTop; 0841 if ( pointLeft.y() > m_top ) { 0842 clippedPolyObject << pointLeft; 0843 } else { 0844 clippedPolyObject << QPointF( m_left, m_top ); 0845 } 0846 } 0847 else if ( m_previousSector == 8 ) { 0848 QPointF pointRight = clipRight( m, m_previousPoint ); 0849 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0850 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0851 0852 if ( pointRight.y() < m_bottom ) 0853 clippedPolyObject << pointRight; 0854 if ( pointBottom.x() > m_left && pointBottom.x() <= m_right ) 0855 clippedPolyObject << pointBottom; 0856 if ( pointLeft.y() < m_bottom ) { 0857 clippedPolyObject << pointLeft; 0858 } else { 0859 clippedPolyObject << QPointF( m_left, m_bottom ); 0860 } 0861 } 0862 else if ( m_previousSector == 5 ) { 0863 clippedPolyObject << clipRight( m, m_previousPoint ); 0864 clippedPolyObject << clipLeft( m, m_currentPoint ); 0865 } 0866 else if ( m_previousSector == 2 ) { 0867 QPointF pointRight = clipRight( m, m_previousPoint ); 0868 QPointF pointTop = clipTop( m, m_previousPoint ); 0869 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0870 0871 if ( pointRight.y() > m_top ) 0872 clippedPolyObject << pointRight; 0873 if ( pointTop.x() > m_left && pointTop.x() <= m_right ) 0874 clippedPolyObject << pointTop; 0875 if ( pointLeft.y() > m_top ) { 0876 clippedPolyObject << pointLeft; 0877 } else { 0878 clippedPolyObject << QPointF( m_left, m_top ); 0879 } 0880 } 0881 break; 0882 0883 case 5: 0884 if ( m_previousSector == 7 ) { 0885 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0886 QPointF pointRight = clipRight( m, m_currentPoint ); 0887 0888 if ( pointBottom.x() < m_right ) 0889 clippedPolyObject << pointBottom; 0890 if ( pointRight.y() < m_bottom ) { 0891 clippedPolyObject << pointRight; 0892 } else { 0893 clippedPolyObject << QPointF( m_right, m_bottom ); 0894 } 0895 } 0896 else if ( m_previousSector == 1 ) { 0897 QPointF pointTop = clipTop( m, m_previousPoint ); 0898 QPointF pointRight = clipRight( m, m_currentPoint ); 0899 0900 if ( pointTop.x() < m_right ) 0901 clippedPolyObject << pointTop; 0902 if ( pointRight.y() > m_top ) { 0903 clippedPolyObject << pointRight; 0904 } else { 0905 clippedPolyObject << QPointF( m_right, m_top ); 0906 } 0907 } 0908 else if ( m_previousSector == 6 ) { 0909 QPointF pointLeft = clipLeft( m, m_previousPoint ); 0910 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0911 QPointF pointRight = clipRight( m, m_currentPoint ); 0912 0913 if ( pointLeft.y() < m_bottom ) 0914 clippedPolyObject << pointLeft; 0915 if ( pointBottom.x() >= m_left && pointBottom.x() < m_right ) 0916 clippedPolyObject << pointBottom; 0917 if ( pointRight.y() < m_bottom ) { 0918 clippedPolyObject << pointRight; 0919 } else { 0920 clippedPolyObject << QPointF( m_right, m_bottom ); 0921 } 0922 } 0923 else if ( m_previousSector == 3 ) { 0924 clippedPolyObject << clipLeft( m, m_previousPoint ); 0925 clippedPolyObject << clipRight( m, m_currentPoint ); 0926 } 0927 else if ( m_previousSector == 0 ) { 0928 QPointF pointLeft = clipLeft( m, m_previousPoint ); 0929 QPointF pointTop = clipTop( m, m_previousPoint ); 0930 QPointF pointRight = clipRight( m, m_currentPoint ); 0931 0932 if ( pointLeft.y() > m_top ) 0933 clippedPolyObject << pointLeft; 0934 if ( pointTop.x() >= m_left && pointTop.x() < m_right ) 0935 clippedPolyObject << pointTop; 0936 if ( pointRight.y() > m_top ) { 0937 clippedPolyObject << pointRight; 0938 } else { 0939 clippedPolyObject << QPointF( m_right, m_top ); 0940 } 0941 } 0942 break; 0943 0944 case 6: 0945 if ( m_previousSector == 5 ) { 0946 QPointF pointRight = clipRight( m, m_previousPoint ); 0947 QPointF pointBottom = clipBottom( m, m_currentPoint ); 0948 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0949 0950 if ( pointRight.y() < m_bottom ) { 0951 clippedPolyObject << pointRight; 0952 } else { 0953 clippedPolyObject << QPointF( m_right, m_bottom ); 0954 } 0955 if ( pointBottom.x() >= m_left && pointBottom.x() < m_right ) 0956 clippedPolyObject << pointBottom; 0957 if ( pointLeft.y() < m_bottom ) 0958 clippedPolyObject << pointLeft; 0959 } 0960 else if ( m_previousSector == 1 ) { 0961 QPointF pointTop = clipTop( m, m_previousPoint ); 0962 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0963 QPointF pointBottom = clipBottom( m, m_currentPoint ); 0964 0965 if ( pointTop.x() > m_left ) { 0966 clippedPolyObject << pointTop; 0967 } else { 0968 clippedPolyObject << QPointF( m_left, m_top ); 0969 } 0970 if ( pointLeft.y() > m_top && pointLeft.y() <= m_bottom ) 0971 clippedPolyObject << pointLeft; 0972 if ( pointBottom.x() > m_left ) 0973 clippedPolyObject << pointBottom; 0974 } 0975 else if ( m_previousSector == 2 ) { 0976 QPointF pointTop = clipTop( m, m_currentPoint ); 0977 QPointF pointRight = clipRight( m, m_previousPoint ); 0978 QPointF pointBottom = clipBottom( m, m_previousPoint ); 0979 QPointF pointLeft = clipLeft( m, m_currentPoint ); 0980 0981 if ( pointTop.x() > m_left && pointTop.x() < m_right ) 0982 clippedPolyObject << pointTop; 0983 if ( pointRight.y() > m_top && pointRight.y() < m_bottom ) 0984 clippedPolyObject << pointRight; 0985 if ( pointBottom.x() > m_left && pointBottom.x() < m_right ) 0986 clippedPolyObject << pointBottom; 0987 if ( pointLeft.y() > m_top && pointLeft.y() < m_bottom ) 0988 clippedPolyObject << pointLeft; 0989 0990 if ( pointBottom.x() >= m_right && pointRight.y() >= m_bottom ) 0991 clippedPolyObject << QPointF( m_right, m_bottom ); 0992 if ( pointTop.x() <= m_left && pointLeft.y() <= m_top ) 0993 clippedPolyObject << QPointF( m_left, m_top ); 0994 } 0995 0996 clippedPolyObject << QPointF( m_left, m_bottom ); 0997 break; 0998 0999 case 7: 1000 if ( m_previousSector == 3 ) { 1001 QPointF pointLeft = clipLeft( m, m_previousPoint ); 1002 QPointF pointBottom = clipBottom( m, m_currentPoint ); 1003 1004 if ( pointLeft.y() < m_bottom ) { 1005 clippedPolyObject << pointLeft; 1006 } else { 1007 clippedPolyObject << QPointF( m_left, m_bottom ); 1008 } 1009 if ( pointBottom.x() > m_left ) 1010 clippedPolyObject << pointBottom; 1011 } 1012 else if ( m_previousSector == 5 ) { 1013 QPointF pointRight = clipRight( m, m_previousPoint ); 1014 QPointF pointBottom = clipBottom( m, m_currentPoint ); 1015 1016 if ( pointRight.y() < m_bottom ) { 1017 clippedPolyObject << pointRight; 1018 } else { 1019 clippedPolyObject << QPointF( m_right, m_bottom ); 1020 } 1021 if ( pointBottom.x() < m_right ) 1022 clippedPolyObject << pointBottom; 1023 } 1024 else if ( m_previousSector == 0 ) { 1025 QPointF pointTop = clipTop( m, m_previousPoint ); 1026 QPointF pointLeft = clipLeft( m, m_previousPoint ); 1027 QPointF pointBottom = clipBottom( m, m_currentPoint ); 1028 1029 if ( pointTop.x() > m_left ) 1030 clippedPolyObject << pointTop; 1031 if ( pointLeft.y() >= m_top && pointLeft.y() < m_bottom ) 1032 clippedPolyObject << pointLeft; 1033 if ( pointBottom.x() > m_left ) { 1034 clippedPolyObject << pointBottom; 1035 } else { 1036 clippedPolyObject << QPointF( m_left, m_bottom ); 1037 } 1038 } 1039 else if ( m_previousSector == 1 ) { 1040 clippedPolyObject << clipTop( m, m_previousPoint ); 1041 clippedPolyObject << clipBottom( m, m_currentPoint ); 1042 } 1043 else if ( m_previousSector == 2 ) { 1044 QPointF pointTop = clipTop( m, m_previousPoint ); 1045 QPointF pointRight = clipRight( m, m_previousPoint ); 1046 QPointF pointBottom = clipBottom( m, m_currentPoint ); 1047 1048 if ( pointTop.x() < m_right ) 1049 clippedPolyObject << pointTop; 1050 if ( pointRight.y() >= m_top && pointRight.y() < m_bottom ) 1051 clippedPolyObject << pointRight; 1052 if ( pointBottom.x() < m_right ) { 1053 clippedPolyObject << pointBottom; 1054 } else { 1055 clippedPolyObject << QPointF( m_right, m_bottom ); 1056 } 1057 } 1058 break; 1059 1060 case 8: 1061 if ( m_previousSector == 3 ) { 1062 QPointF pointLeft = clipLeft( m, m_previousPoint ); 1063 QPointF pointBottom = clipBottom( m, m_currentPoint ); 1064 QPointF pointRight = clipRight( m, m_currentPoint ); 1065 1066 if ( pointLeft.y() < m_bottom ) { 1067 clippedPolyObject << pointLeft; 1068 } else { 1069 clippedPolyObject << QPointF( m_left, m_bottom ); 1070 } 1071 if ( pointBottom.x() > m_left && pointBottom.x() <= m_right ) 1072 clippedPolyObject << pointBottom; 1073 if ( pointRight.y() < m_bottom ) 1074 clippedPolyObject << pointRight; 1075 } 1076 else if ( m_previousSector == 1 ) { 1077 QPointF pointTop = clipTop( m, m_previousPoint ); 1078 QPointF pointRight = clipRight( m, m_currentPoint ); 1079 QPointF pointBottom = clipBottom( m, m_currentPoint ); 1080 1081 if ( pointTop.x() < m_right ) { 1082 clippedPolyObject << pointTop; 1083 } else { 1084 clippedPolyObject << QPointF( m_right, m_top ); 1085 } 1086 if ( pointRight.y() > m_top && pointRight.y() <= m_bottom ) 1087 clippedPolyObject << pointRight; 1088 if ( pointBottom.x() < m_right ) 1089 clippedPolyObject << pointBottom; 1090 } 1091 else if ( m_previousSector == 0 ) { 1092 QPointF pointTop = clipTop( m, m_currentPoint ); 1093 QPointF pointLeft = clipLeft( m, m_currentPoint ); 1094 QPointF pointBottom = clipBottom( m, m_previousPoint ); 1095 QPointF pointRight = clipRight( m, m_previousPoint ); 1096 1097 if ( pointTop.x() > m_left && pointTop.x() < m_right ) 1098 clippedPolyObject << pointTop; 1099 if ( pointLeft.y() > m_top && pointLeft.y() < m_bottom ) 1100 clippedPolyObject << pointLeft; 1101 if ( pointBottom.x() > m_left && pointBottom.x() < m_right ) 1102 clippedPolyObject << pointBottom; 1103 if ( pointRight.y() > m_top && pointRight.y() < m_bottom ) 1104 clippedPolyObject << pointRight; 1105 1106 if ( pointBottom.x() <= m_left && pointLeft.y() >= m_bottom ) 1107 clippedPolyObject << QPointF( m_left, m_bottom ); 1108 if ( pointTop.x() >= m_right && pointRight.y() <= m_top ) 1109 clippedPolyObject << QPointF( m_right, m_top ); 1110 } 1111 1112 clippedPolyObject << QPointF( m_right, m_bottom ); 1113 break; 1114 1115 default: 1116 break; 1117 } 1118 } 1119 1120 void ClipPainterPrivate::clipOnceCorner( QPolygonF & clippedPolyObject, 1121 QVector<QPolygonF> & clippedPolyObjects, 1122 const QPointF& corner, 1123 const QPointF& point, 1124 bool isClosed ) const 1125 { 1126 Q_UNUSED( clippedPolyObjects ) 1127 Q_UNUSED( isClosed ) 1128 1129 if ( m_currentSector == 4) { 1130 // Appearing 1131 clippedPolyObject << corner; 1132 clippedPolyObject << point; 1133 } else { 1134 // Disappearing 1135 clippedPolyObject << point; 1136 clippedPolyObject << corner; 1137 } 1138 } 1139 1140 void ClipPainterPrivate::clipOnceEdge( QPolygonF & clippedPolyObject, 1141 QVector<QPolygonF> & clippedPolyObjects, 1142 const QPointF& point, 1143 bool isClosed ) const 1144 { 1145 if ( m_currentSector == 4) { 1146 // Appearing 1147 if ( !isClosed ) { 1148 clippedPolyObject = QPolygonF(); 1149 } 1150 clippedPolyObject << point; 1151 } 1152 else { 1153 // Disappearing 1154 clippedPolyObject << point; 1155 if ( !isClosed ) { 1156 clippedPolyObjects << clippedPolyObject; 1157 } 1158 } 1159 } 1160 1161 void ClipPainterPrivate::clipOnce( QPolygonF & clippedPolyObject, 1162 QVector<QPolygonF> & clippedPolyObjects, 1163 bool isClosed ) 1164 { 1165 // Interpolate border points (linear interpolation) 1166 QPointF point; 1167 1168 // Calculating the slope. 1169 qreal m = _m( m_previousPoint, m_currentPoint ); 1170 1171 // Calculate in which sector the end of the line is located that is off screen 1172 int offscreenpos = ( m_currentSector == 4 ) ? m_previousSector : m_currentSector; 1173 1174 // "Rise over run" for all possible situations . 1175 switch ( offscreenpos ) { 1176 case 0: // topleft 1177 point = clipTop( m, m_previousPoint ); 1178 if ( point.x() < m_left ) { 1179 point = clipLeft( m, point ); 1180 } 1181 clipOnceCorner( clippedPolyObject, clippedPolyObjects, QPointF( m_left, m_top ), point, isClosed ); 1182 break; 1183 case 1: // top 1184 point = clipTop( m, m_previousPoint ); 1185 clipOnceEdge( clippedPolyObject, clippedPolyObjects, point, isClosed ); 1186 break; 1187 case 2: // topright 1188 point = clipTop( m, m_previousPoint ); 1189 if ( point.x() > m_right ) { 1190 point = clipRight( m, point ); 1191 } 1192 clipOnceCorner( clippedPolyObject, clippedPolyObjects, QPointF( m_right, m_top ), point, isClosed ); 1193 break; 1194 case 3: // left 1195 point = clipLeft( m, m_previousPoint ); 1196 clipOnceEdge( clippedPolyObject, clippedPolyObjects, point, isClosed ); 1197 break; 1198 case 5: // right 1199 point = clipRight( m, m_previousPoint ); 1200 clipOnceEdge( clippedPolyObject, clippedPolyObjects, point, isClosed ); 1201 break; 1202 case 6: // bottomleft 1203 point = clipBottom( m, m_previousPoint ); 1204 if ( point.x() < m_left ) { 1205 point = clipLeft( m, point ); 1206 } 1207 clipOnceCorner( clippedPolyObject, clippedPolyObjects, QPointF( m_left, m_bottom ), point, isClosed ); 1208 break; 1209 case 7: // bottom 1210 point = clipBottom( m, m_previousPoint ); 1211 clipOnceEdge( clippedPolyObject, clippedPolyObjects, point, isClosed ); 1212 break; 1213 case 8: // bottomright 1214 point = clipBottom( m, m_previousPoint ); 1215 if ( point.x() > m_right ) { 1216 point = clipRight( m, point ); 1217 } 1218 clipOnceCorner( clippedPolyObject, clippedPolyObjects, QPointF( m_right, m_bottom ), point, isClosed ); 1219 break; 1220 default: 1221 break; 1222 } 1223 1224 } 1225 1226 void ClipPainter::setDebugPolygonsLevel( int level ) { 1227 d->m_debugPolygonsLevel = level; 1228 } 1229 1230 void ClipPainter::setDebugBatchRender( bool enabled ) { 1231 d->m_debugBatchRender = enabled; 1232 } 1233 1234 1235 void ClipPainterPrivate::debugDrawNodes( const QPolygonF & polygon ) 1236 { 1237 1238 q->save(); 1239 q->setRenderHint( QPainter::Antialiasing, false ); 1240 1241 q->setPen( Qt::red ); 1242 q->setBrush(QBrush("#40FF0000")); 1243 1244 const QVector<QPointF>::const_iterator itStartPoint = polygon.constBegin(); 1245 const QVector<QPointF>::const_iterator itEndPoint = polygon.constEnd(); 1246 QVector<QPointF>::const_iterator itPoint = itStartPoint; 1247 1248 int i = 0; 1249 1250 for (; itPoint != itEndPoint; ++itPoint ) { 1251 1252 ++i; 1253 1254 if ( itPoint == itStartPoint || itPoint == itStartPoint + 1 || itPoint == itStartPoint + 2 ) { 1255 q->setPen( Qt::darkGreen ); 1256 q->setBrush(QBrush("#4000FF00")); 1257 if ( itPoint == itStartPoint ) { 1258 q->drawRect( itPoint->x() - 6.0, itPoint->y() - 6.0 , 12.0, 12.0 ); 1259 } 1260 else if ( itPoint == itStartPoint + 1 ) { 1261 q->drawRect( itPoint->x() - 4.0, itPoint->y() - 4.0 , 8.0, 8.0 ); 1262 } 1263 else { 1264 q->drawRect( itPoint->x() - 2.0, itPoint->y() - 2.0 , 4.0, 4.0 ); 1265 } 1266 q->setPen( Qt::red ); 1267 q->setBrush(QBrush("#40FF0000")); 1268 } 1269 else if ( itPoint == itEndPoint - 1 || itPoint == itEndPoint - 2 || itPoint == itEndPoint - 3 ) { 1270 q->setPen( Qt::blue ); 1271 q->setBrush(QBrush("#400000FF")); 1272 if ( itPoint == itEndPoint - 3 ) { 1273 q->drawRect( itPoint->x() - 6.0, itPoint->y() - 6.0 , 12.0, 12.0 ); 1274 } 1275 else if ( itPoint == itEndPoint - 2 ) { 1276 q->drawRect( itPoint->x() - 4.0, itPoint->y() - 4.0 , 8.0, 8.0 ); 1277 } 1278 else { 1279 q->drawRect( itPoint->x() - 2.0, itPoint->y() - 2.0 , 4.0, 4.0 ); 1280 } 1281 q->setPen( Qt::red ); 1282 q->setBrush(QBrush("#400000FF")); 1283 } 1284 else { 1285 q->drawRect( itPoint->x() - 4, itPoint->y() - 4 , 8.0, 8.0 ); 1286 } 1287 if (m_debugPolygonsLevel == 2) { 1288 q->setFont(QFont(QStringLiteral("Sans Serif"), 7)); 1289 q->setPen("black"); 1290 q->setBrush(Qt::transparent); 1291 q->drawText(itPoint->x() + 6.0, itPoint->y() + (15 - (i * 5) % 30) , QString::number(i)); 1292 } 1293 } 1294 q->restore(); 1295 }