24 class ClipPainterPrivate
46 QPointF m_currentPoint;
47 QPointF m_previousPoint;
49 inline int sector(
const QPointF & point )
const;
51 inline QPointF clipTop( qreal m,
const QPointF & point )
const;
52 inline QPointF clipLeft( qreal m,
const QPointF & point )
const;
53 inline QPointF clipBottom( qreal m,
const QPointF & point )
const;
54 inline QPointF clipRight( qreal m,
const QPointF & point )
const;
56 inline void initClipRect();
58 inline void clipPolyObject (
const QPolygonF & sourcePolygon,
59 QVector<QPolygonF> & clippedPolyObjects,
62 inline void clipMultiple( QPolygonF & clippedPolyObject,
63 QVector<QPolygonF> & clippedPolyObjects,
65 inline void clipOnce( QPolygonF & clippedPolyObject,
66 QVector<QPolygonF> & clippedPolyObjects,
68 inline void clipOnceCorner( QPolygonF & clippedPolyObject,
69 QVector<QPolygonF> & clippedPolyObjects,
70 const QPointF& corner,
73 inline void clipOnceEdge( QPolygonF & clippedPolyObject,
74 QVector<QPolygonF> & clippedPolyObjects,
79 void labelPosition(
const QPolygonF & polygon, QVector<QPointF>& labelNodes,
80 LabelPositionFlags labelPositionFlags);
82 bool pointAllowsLabel(
const QPointF& point );
83 QPointF interpolateLabelPoint(
const QPointF& previousPoint,
84 const QPointF& currentPoint,
85 LabelPositionFlags labelPositionFlags );
87 inline qreal _m(
const QPointF & start,
const QPointF & end )
const;
89 #ifdef DEBUG_DRAW_NODES
90 void debugDrawNodes(
const QPolygonF & );
93 qreal m_labelAreaMargin;
98 using namespace Marble;
103 :
QPainter( pd ), d( new ClipPainterPrivate( this ) )
113 : d( new ClipPainterPrivate( this ) )
126 d->m_doClip = enable;
137 Qt::FillRule fillRule )
142 QVector<QPolygonF> clippedPolyObjects;
144 d->clipPolyObject( polygon, clippedPolyObjects,
true );
146 foreach(
const QPolygonF & clippedPolyObject, clippedPolyObjects ) {
147 if ( clippedPolyObject.size() > 2 ) {
149 QPainter::drawPolygon ( clippedPolyObject, fillRule );
151 #ifdef DEBUG_DRAW_NODES
152 d->debugDrawNodes( clippedPolyObject );
158 QPainter::drawPolygon ( polygon, fillRule );
160 #ifdef DEBUG_DRAW_NODES
161 d->debugDrawNodes( polygon );
171 QVector<QPolygonF> clippedPolyObjects;
173 d->clipPolyObject( polygon, clippedPolyObjects,
false );
175 foreach(
const QPolygonF & clippedPolyObject, clippedPolyObjects ) {
176 if ( clippedPolyObject.size() > 1 ) {
178 QPainter::drawPolyline ( clippedPolyObject );
181 #ifdef DEBUG_DRAW_NODES
182 d->debugDrawNodes( clippedPolyObject );
188 QPainter::drawPolyline( polygon );
190 #ifdef DEBUG_DRAW_NODES
191 d->debugDrawNodes( polygon );
197 LabelPositionFlags positionFlags)
203 QVector<QPolygonF> clippedPolyObjects;
205 d->clipPolyObject( polygon, clippedPolyObjects,
false );
207 foreach(
const QPolygonF & clippedPolyObject, clippedPolyObjects ) {
208 if ( clippedPolyObject.size() > 1 ) {
210 QPainter::drawPolyline ( clippedPolyObject );
213 #ifdef DEBUG_DRAW_NODES
214 d->debugDrawNodes( clippedPolyObject );
217 d->labelPosition( clippedPolyObject, labelNodes, positionFlags );
222 QPainter::drawPolyline( polygon );
224 #ifdef DEBUG_DRAW_NODES
225 d->debugDrawNodes( polygon );
228 d->labelPosition( polygon, labelNodes, positionFlags );
232 void ClipPainterPrivate::labelPosition(
const QPolygonF & polygon, QVector<QPointF>& labelNodes,
233 LabelPositionFlags labelPositionFlags)
235 int labelPosition = 0;
237 bool currentAllowsLabel =
false;
239 if ( labelPositionFlags.testFlag(
LineCenter ) ) {
241 labelPosition =
static_cast<int>( polygon.size() / 2.0 );
242 if ( polygon.size() > 0 ) {
243 if ( labelPosition >= polygon.size() ) {
244 labelPosition = polygon.size() - 1;
246 labelNodes << polygon.at( labelPosition );
250 if ( polygon.size() > 0 && labelPositionFlags.testFlag(
LineStart ) ) {
251 if ( pointAllowsLabel( polygon.first() ) ) {
252 labelNodes << polygon.first();
256 for (
int it = 1; it < polygon.size(); ++it ) {
257 currentAllowsLabel = pointAllowsLabel( polygon.at( it ) );
259 if ( currentAllowsLabel ) {
261 QPointF node = interpolateLabelPoint( polygon.at( it -1 ), polygon.at( it ),
262 labelPositionFlags );
263 if ( node != QPointF( -1.0, -1.0 ) ) {
271 if ( polygon.size() > 1 && labelPositionFlags.testFlag(
LineEnd ) ) {
272 if ( pointAllowsLabel( polygon.at( polygon.size() - 1 ) ) ) {
273 labelNodes << polygon.at( polygon.size() - 1 );
277 for (
int it = polygon.size() - 2; it > 0; --it ) {
278 currentAllowsLabel = pointAllowsLabel( polygon.at( it ) );
280 if ( currentAllowsLabel ) {
281 QPointF node = interpolateLabelPoint( polygon.at( it + 1 ), polygon.at( it ),
282 labelPositionFlags );
283 if ( node != QPointF( -1.0, -1.0 ) ) {
292 bool ClipPainterPrivate::pointAllowsLabel(
const QPointF& point )
295 if ( point.x() > m_labelAreaMargin && point.x() < q->viewport().width() - m_labelAreaMargin
296 && point.y() > m_labelAreaMargin && point.y() < q->viewport().height() - m_labelAreaMargin ) {
302 QPointF ClipPainterPrivate::interpolateLabelPoint(
const QPointF& previousPoint,
303 const QPointF& currentPoint,
304 LabelPositionFlags labelPositionFlags )
306 qreal m = _m( previousPoint, currentPoint );
307 if ( previousPoint.x() <= m_labelAreaMargin ) {
309 return QPointF( -1.0, -1.0 );
311 return QPointF( m_labelAreaMargin,
312 previousPoint.y() + ( m_labelAreaMargin - previousPoint.x() ) * m );
314 else if ( previousPoint.x() >= q->viewport().width() - m_labelAreaMargin ) {
316 return QPointF( -1.0, -1.0 );
318 return QPointF( q->viewport().width() - m_labelAreaMargin,
320 ( previousPoint.x() - q->viewport().width() + m_labelAreaMargin ) * m );
323 if ( previousPoint.y() <= m_labelAreaMargin ) {
325 return QPointF( -1.0, -1.0 );
327 return QPointF( previousPoint.x() + ( m_labelAreaMargin - previousPoint.y() ) / m,
330 else if ( previousPoint.y() >= q->viewport().height() - m_labelAreaMargin ) {
332 return QPointF( -1.0, -1.0 );
334 return QPointF( previousPoint.x() -
335 ( previousPoint.y() - q->viewport().height() + m_labelAreaMargin ) / m,
336 q->viewport().height() - m_labelAreaMargin );
341 return QPointF( -1.0, -1.0 );
344 ClipPainterPrivate::ClipPainterPrivate(
ClipPainter * parent )
352 m_currentPoint(QPointF()),
353 m_previousPoint(QPointF()),
354 m_labelAreaMargin(10.0)
359 void ClipPainterPrivate::initClipRect ()
361 qreal penHalfWidth = q->pen().widthF() / 2.0 + 1.0;
363 m_left = -penHalfWidth;
364 m_right = (qreal)(q->device()->width()) + penHalfWidth;
365 m_top = -penHalfWidth;
366 m_bottom = (qreal)(q->device()->height()) + penHalfWidth;
369 qreal ClipPainterPrivate::_m(
const QPointF & start,
const QPointF & end )
const
371 qreal divisor = end.x() - start.x();
372 if ( std::fabs( divisor ) < 0.000001 ) {
378 return ( end.y() - start.y() )
383 QPointF ClipPainterPrivate::clipTop( qreal m,
const QPointF & point )
const
385 return QPointF( ( m_top - point.y() ) / m + point.x(), m_top );
388 QPointF ClipPainterPrivate::clipLeft( qreal m,
const QPointF & point )
const
390 return QPointF( m_left, ( m_left - point.x() ) * m + point.y() );
393 QPointF ClipPainterPrivate::clipBottom( qreal m,
const QPointF & point )
const
395 return QPointF( ( m_bottom - point.y() ) / m + point.x(), m_bottom );
398 QPointF ClipPainterPrivate::clipRight( qreal m,
const QPointF & point )
const
400 return QPointF( m_right, ( m_right - point.x() ) * m + point.y() );
403 int ClipPainterPrivate::sector(
const QPointF & point )
const
418 if ( point.x() < m_left )
420 else if ( point.x() > m_right )
424 if ( point.y() < m_top )
426 else if ( point.y() > m_bottom )
431 return ySector + xSector;
435 void ClipPainterPrivate::clipPolyObject (
const QPolygonF & polygon,
436 QVector<QPolygonF> & clippedPolyObjects,
443 QPolygonF clippedPolyObject = QPolygonF();
445 const QVector<QPointF>::const_iterator itStartPoint = polygon.constBegin();
446 const QVector<QPointF>::const_iterator itEndPoint = polygon.constEnd();
447 QVector<QPointF>::const_iterator itPoint = itStartPoint;
453 bool processingLastNode =
false;
455 while ( itPoint != itEndPoint ) {
456 m_currentPoint = (*itPoint);
460 m_currentSector = sector( m_currentPoint );
463 if ( itPoint == itStartPoint && processingLastNode ==
false ) {
465 m_previousPoint = polygon.last();
468 m_previousSector = sector( m_previousPoint );
471 m_previousSector = m_currentSector;
476 if ( m_currentSector != m_previousSector ) {
477 if ( m_currentSector == 4 || m_previousSector == 4 ) {
482 clipOnce( clippedPolyObject, clippedPolyObjects, isClosed );
489 clipMultiple( clippedPolyObject, clippedPolyObjects, isClosed );
492 m_previousSector = m_currentSector;
496 if ( m_currentSector == 4 ) {
498 clippedPolyObject << m_currentPoint;
500 ++(m_debugNodeCount);
504 m_previousPoint = m_currentPoint;
509 if ( processingLastNode ) {
514 if ( itPoint == itEndPoint && isClosed ) {
515 itPoint = itStartPoint;
516 processingLastNode =
true;
521 if ( !clippedPolyObject.isEmpty() ) {
522 clippedPolyObjects << clippedPolyObject;
527 void ClipPainterPrivate::clipMultiple( QPolygonF & clippedPolyObject,
528 QVector<QPolygonF> & clippedPolyObjects,
531 Q_UNUSED( clippedPolyObjects )
537 qreal m = _m( m_previousPoint, m_currentPoint );
539 switch ( m_currentSector ) {
541 if ( m_previousSector == 5 ) {
542 QPointF pointRight = clipRight( m, m_previousPoint );
543 QPointF pointTop = clipTop( m, m_currentPoint );
544 QPointF pointLeft = clipLeft( m, m_currentPoint );
546 if ( pointRight.y() > m_top ) {
547 clippedPolyObject << pointRight;
549 clippedPolyObject << QPointF( m_right, m_top );
551 if ( pointTop.x() >= m_left && pointTop.x() < m_right )
552 clippedPolyObject << pointTop;
553 if ( pointLeft.y() > m_top )
554 clippedPolyObject << pointLeft;
556 else if ( m_previousSector == 7 ) {
557 QPointF pointBottom = clipBottom( m, m_previousPoint );
558 QPointF pointTop = clipTop( m, m_currentPoint );
559 QPointF pointLeft = clipLeft( m, m_currentPoint );
561 if ( pointBottom.x() > m_left ) {
562 clippedPolyObject << pointBottom;
564 clippedPolyObject << QPointF( m_left, m_bottom );
566 if ( pointLeft.y() >= m_top && pointLeft.y() < m_bottom )
567 clippedPolyObject << pointLeft;
568 if ( pointTop.x() > m_left )
569 clippedPolyObject << pointTop;
571 else if ( m_previousSector == 8 ) {
572 QPointF pointBottom = clipBottom( m, m_previousPoint );
573 QPointF pointRight = clipRight( m, m_previousPoint );
574 QPointF pointTop = clipTop( m, m_currentPoint );
575 QPointF pointLeft = clipLeft( m, m_currentPoint );
577 if ( pointBottom.x() > m_left && pointBottom.x() < m_right )
578 clippedPolyObject << pointBottom;
579 if ( pointRight.y() > m_top && pointRight.y() < m_bottom )
580 clippedPolyObject << pointRight;
581 if ( pointTop.x() > m_left && pointTop.x() < m_right )
582 clippedPolyObject << pointTop;
583 if ( pointLeft.y() > m_top && pointLeft.y() < m_bottom )
584 clippedPolyObject << pointLeft;
586 if ( pointBottom.x() <= m_left && pointLeft.y() >= m_bottom )
587 clippedPolyObject << QPointF( m_left, m_bottom );
588 if ( pointTop.x() >= m_right && pointRight.y() <= m_top )
589 clippedPolyObject << QPointF( m_right, m_top );
592 clippedPolyObject << QPointF( m_left, m_top );
596 if ( m_previousSector == 3 ) {
597 QPointF pointLeft = clipLeft( m, m_previousPoint );
598 QPointF pointTop = clipTop( m, m_currentPoint );
600 if ( pointLeft.y() > m_top ) {
601 clippedPolyObject << pointLeft;
603 clippedPolyObject << QPointF( m_left, m_top );
605 if ( pointTop.x() > m_left )
606 clippedPolyObject << pointTop;
608 else if ( m_previousSector == 5 ) {
609 QPointF pointRight = clipRight( m, m_previousPoint );
610 QPointF pointTop = clipTop( m, m_currentPoint );
612 if ( pointRight.y() > m_top ) {
613 clippedPolyObject << pointRight;
615 clippedPolyObject << QPointF( m_right, m_top );
617 if ( pointTop.x() < m_right )
618 clippedPolyObject << pointTop;
620 else if ( m_previousSector == 6 ) {
621 QPointF pointBottom = clipBottom( m, m_previousPoint );
622 QPointF pointLeft = clipLeft( m, m_previousPoint );
623 QPointF pointTop = clipTop( m, m_currentPoint );
625 if ( pointBottom.x() > m_left )
626 clippedPolyObject << pointBottom;
627 if ( pointLeft.y() > m_top && pointLeft.y() <= m_bottom )
628 clippedPolyObject << pointLeft;
629 if ( pointTop.x() > m_left ) {
630 clippedPolyObject << pointTop;
632 clippedPolyObject << QPointF( m_left, m_top );
635 else if ( m_previousSector == 7 ) {
636 clippedPolyObject << clipBottom( m, m_previousPoint );
637 clippedPolyObject << clipTop( m, m_currentPoint );
639 else if ( m_previousSector == 8 ) {
640 QPointF pointBottom = clipBottom( m, m_previousPoint );
641 QPointF pointRight = clipRight( m, m_previousPoint );
642 QPointF pointTop = clipTop( m, m_currentPoint );
644 if ( pointBottom.x() < m_right )
645 clippedPolyObject << pointBottom;
646 if ( pointRight.y() > m_top && pointRight.y() <= m_bottom )
647 clippedPolyObject << pointRight;
648 if ( pointTop.x() < m_right ) {
649 clippedPolyObject << pointTop;
651 clippedPolyObject << QPointF( m_right, m_top );
657 if ( m_previousSector == 3 ) {
658 QPointF pointLeft = clipLeft( m, m_previousPoint );
659 QPointF pointTop = clipTop( m, m_currentPoint );
660 QPointF pointRight = clipRight( m, m_currentPoint );
662 if ( pointLeft.y() > m_top ) {
663 clippedPolyObject << pointLeft;
665 clippedPolyObject << QPointF( m_left, m_top );
667 if ( pointTop.x() > m_left && pointTop.x() <= m_right )
668 clippedPolyObject << pointTop;
669 if ( pointRight.y() > m_top )
670 clippedPolyObject << pointRight;
672 else if ( m_previousSector == 7 ) {
673 QPointF pointBottom = clipBottom( m, m_previousPoint );
674 QPointF pointTop = clipTop( m, m_currentPoint );
675 QPointF pointRight = clipRight( m, m_currentPoint );
677 if ( pointBottom.x() < m_right ) {
678 clippedPolyObject << pointBottom;
680 clippedPolyObject << QPointF( m_right, m_bottom );
682 if ( pointRight.y() >= m_top && pointRight.y() < m_bottom )
683 clippedPolyObject << pointRight;
684 if ( pointTop.x() < m_right )
685 clippedPolyObject << pointTop;
687 else if ( m_previousSector == 6 ) {
688 QPointF pointBottom = clipBottom( m, m_previousPoint );
689 QPointF pointLeft = clipLeft( m, m_currentPoint );
690 QPointF pointTop = clipTop( m, m_currentPoint );
691 QPointF pointRight = clipRight( m, m_previousPoint );
693 if ( pointBottom.x() > m_left && pointBottom.x() < m_right )
694 clippedPolyObject << pointBottom;
695 if ( pointLeft.y() > m_top && pointLeft.y() < m_bottom )
696 clippedPolyObject << pointLeft;
697 if ( pointTop.x() > m_left && pointTop.x() < m_right )
698 clippedPolyObject << pointTop;
699 if ( pointRight.y() > m_top && pointRight.y() < m_bottom )
700 clippedPolyObject << pointRight;
702 if ( pointBottom.x() >= m_right && pointRight.y() >= m_bottom )
703 clippedPolyObject << QPointF( m_right, m_bottom );
704 if ( pointTop.x() <= m_left && pointLeft.y() <= m_top )
705 clippedPolyObject << QPointF( m_left, m_top );
708 clippedPolyObject << QPointF( m_right, m_top );
712 if ( m_previousSector == 7 ) {
713 QPointF pointBottom = clipBottom( m, m_previousPoint );
714 QPointF pointLeft = clipLeft( m, m_currentPoint );
716 if ( pointBottom.x() > m_left )
717 clippedPolyObject << pointBottom;
718 if ( pointLeft.y() < m_bottom ) {
719 clippedPolyObject << pointLeft;
721 clippedPolyObject << QPointF( m_left, m_bottom );
724 else if ( m_previousSector == 1 ) {
725 QPointF pointTop = clipTop( m, m_previousPoint );
726 QPointF pointLeft = clipLeft( m, m_currentPoint );
728 if ( pointTop.x() > m_left )
729 clippedPolyObject << pointTop;
730 if ( pointLeft.y() > m_top ) {
731 clippedPolyObject << pointLeft;
733 clippedPolyObject << QPointF( m_left, m_top );
736 else if ( m_previousSector == 8 ) {
737 QPointF pointRight = clipRight( m, m_previousPoint );
738 QPointF pointBottom = clipBottom( m, m_previousPoint );
739 QPointF pointLeft = clipLeft( m, m_currentPoint );
741 if ( pointRight.y() < m_bottom )
742 clippedPolyObject << pointRight;
743 if ( pointBottom.x() > m_left && pointBottom.x() <= m_right )
744 clippedPolyObject << pointBottom;
745 if ( pointLeft.y() < m_bottom ) {
746 clippedPolyObject << pointLeft;
748 clippedPolyObject << QPointF( m_left, m_bottom );
751 else if ( m_previousSector == 5 ) {
752 clippedPolyObject << clipRight( m, m_previousPoint );
753 clippedPolyObject << clipLeft( m, m_currentPoint );
755 else if ( m_previousSector == 2 ) {
756 QPointF pointRight = clipRight( m, m_previousPoint );
757 QPointF pointTop = clipTop( m, m_previousPoint );
758 QPointF pointLeft = clipLeft( m, m_currentPoint );
760 if ( pointRight.y() > m_top )
761 clippedPolyObject << pointRight;
762 if ( pointTop.x() > m_left && pointTop.x() <= m_right )
763 clippedPolyObject << pointTop;
764 if ( pointLeft.y() > m_top ) {
765 clippedPolyObject << pointLeft;
767 clippedPolyObject << QPointF( m_left, m_top );
773 if ( m_previousSector == 7 ) {
774 QPointF pointBottom = clipBottom( m, m_previousPoint );
775 QPointF pointRight = clipRight( m, m_currentPoint );
777 if ( pointBottom.x() < m_right )
778 clippedPolyObject << pointBottom;
779 if ( pointRight.y() < m_bottom ) {
780 clippedPolyObject << pointRight;
782 clippedPolyObject << QPointF( m_right, m_bottom );
785 else if ( m_previousSector == 1 ) {
786 QPointF pointTop = clipTop( m, m_previousPoint );
787 QPointF pointRight = clipRight( m, m_currentPoint );
789 if ( pointTop.x() < m_right )
790 clippedPolyObject << pointTop;
791 if ( pointRight.y() > m_top ) {
792 clippedPolyObject << pointRight;
794 clippedPolyObject << QPointF( m_right, m_top );
797 else if ( m_previousSector == 6 ) {
798 QPointF pointLeft = clipLeft( m, m_previousPoint );
799 QPointF pointBottom = clipBottom( m, m_previousPoint );
800 QPointF pointRight = clipRight( m, m_currentPoint );
802 if ( pointLeft.y() < m_bottom )
803 clippedPolyObject << pointLeft;
804 if ( pointBottom.x() >= m_left && pointBottom.x() < m_right )
805 clippedPolyObject << pointBottom;
806 if ( pointRight.y() < m_bottom ) {
807 clippedPolyObject << pointRight;
809 clippedPolyObject << QPointF( m_right, m_bottom );
812 else if ( m_previousSector == 3 ) {
813 clippedPolyObject << clipLeft( m, m_previousPoint );
814 clippedPolyObject << clipRight( m, m_currentPoint );
816 else if ( m_previousSector == 0 ) {
817 QPointF pointLeft = clipLeft( m, m_previousPoint );
818 QPointF pointTop = clipTop( m, m_previousPoint );
819 QPointF pointRight = clipRight( m, m_currentPoint );
821 if ( pointLeft.y() > m_top )
822 clippedPolyObject << pointLeft;
823 if ( pointTop.x() >= m_left && pointTop.x() < m_right )
824 clippedPolyObject << pointTop;
825 if ( pointRight.y() > m_top ) {
826 clippedPolyObject << pointRight;
828 clippedPolyObject << QPointF( m_right, m_top );
834 if ( m_previousSector == 5 ) {
835 QPointF pointRight = clipRight( m, m_previousPoint );
836 QPointF pointBottom = clipBottom( m, m_currentPoint );
837 QPointF pointLeft = clipLeft( m, m_currentPoint );
839 if ( pointRight.y() < m_bottom ) {
840 clippedPolyObject << pointRight;
842 clippedPolyObject << QPointF( m_right, m_bottom );
844 if ( pointBottom.x() >= m_left && pointBottom.x() < m_right )
845 clippedPolyObject << pointBottom;
846 if ( pointLeft.y() < m_bottom )
847 clippedPolyObject << pointLeft;
849 else if ( m_previousSector == 1 ) {
850 QPointF pointTop = clipTop( m, m_previousPoint );
851 QPointF pointLeft = clipLeft( m, m_currentPoint );
852 QPointF pointBottom = clipBottom( m, m_currentPoint );
854 if ( pointTop.x() > m_left ) {
855 clippedPolyObject << pointTop;
857 clippedPolyObject << QPointF( m_left, m_top );
859 if ( pointLeft.y() > m_top && pointLeft.y() <= m_bottom )
860 clippedPolyObject << pointLeft;
861 if ( pointBottom.x() > m_left )
862 clippedPolyObject << pointBottom;
864 else if ( m_previousSector == 2 ) {
865 QPointF pointTop = clipTop( m, m_currentPoint );
866 QPointF pointRight = clipRight( m, m_previousPoint );
867 QPointF pointBottom = clipBottom( m, m_previousPoint );
868 QPointF pointLeft = clipLeft( m, m_currentPoint );
870 if ( pointTop.x() > m_left && pointTop.x() < m_right )
871 clippedPolyObject << pointTop;
872 if ( pointRight.y() > m_top && pointRight.y() < m_bottom )
873 clippedPolyObject << pointRight;
874 if ( pointBottom.x() > m_left && pointBottom.x() < m_right )
875 clippedPolyObject << pointBottom;
876 if ( pointLeft.y() > m_top && pointLeft.y() < m_bottom )
877 clippedPolyObject << pointLeft;
879 if ( pointBottom.x() >= m_right && pointRight.y() >= m_bottom )
880 clippedPolyObject << QPointF( m_right, m_bottom );
881 if ( pointTop.x() <= m_left && pointLeft.y() <= m_top )
882 clippedPolyObject << QPointF( m_left, m_top );
885 clippedPolyObject << QPointF( m_left, m_bottom );
889 if ( m_previousSector == 3 ) {
890 QPointF pointLeft = clipLeft( m, m_previousPoint );
891 QPointF pointBottom = clipBottom( m, m_currentPoint );
893 if ( pointLeft.y() < m_bottom ) {
894 clippedPolyObject << pointLeft;
896 clippedPolyObject << QPointF( m_left, m_bottom );
898 if ( pointBottom.x() > m_left )
899 clippedPolyObject << pointBottom;
901 else if ( m_previousSector == 5 ) {
902 QPointF pointRight = clipRight( m, m_previousPoint );
903 QPointF pointBottom = clipBottom( m, m_currentPoint );
905 if ( pointRight.y() < m_bottom ) {
906 clippedPolyObject << pointRight;
908 clippedPolyObject << QPointF( m_right, m_bottom );
910 if ( pointBottom.x() < m_right )
911 clippedPolyObject << pointBottom;
913 else if ( m_previousSector == 0 ) {
914 QPointF pointTop = clipTop( m, m_previousPoint );
915 QPointF pointLeft = clipLeft( m, m_previousPoint );
916 QPointF pointBottom = clipBottom( m, m_currentPoint );
918 if ( pointTop.x() > m_left )
919 clippedPolyObject << pointTop;
920 if ( pointLeft.y() >= m_top && pointLeft.y() < m_bottom )
921 clippedPolyObject << pointLeft;
922 if ( pointBottom.x() > m_left ) {
923 clippedPolyObject << pointBottom;
925 clippedPolyObject << QPointF( m_left, m_bottom );
928 else if ( m_previousSector == 1 ) {
929 clippedPolyObject << clipTop( m, m_previousPoint );
930 clippedPolyObject << clipBottom( m, m_currentPoint );
932 else if ( m_previousSector == 2 ) {
933 QPointF pointTop = clipTop( m, m_previousPoint );
934 QPointF pointRight = clipRight( m, m_previousPoint );
935 QPointF pointBottom = clipBottom( m, m_currentPoint );
937 if ( pointTop.x() < m_right )
938 clippedPolyObject << pointTop;
939 if ( pointRight.y() >= m_top && pointRight.y() < m_bottom )
940 clippedPolyObject << pointRight;
941 if ( pointBottom.x() < m_right ) {
942 clippedPolyObject << pointBottom;
944 clippedPolyObject << QPointF( m_right, m_bottom );
950 if ( m_previousSector == 3 ) {
951 QPointF pointLeft = clipLeft( m, m_previousPoint );
952 QPointF pointBottom = clipBottom( m, m_currentPoint );
953 QPointF pointRight = clipRight( m, m_currentPoint );
955 if ( pointLeft.y() < m_bottom ) {
956 clippedPolyObject << pointLeft;
958 clippedPolyObject << QPointF( m_left, m_bottom );
960 if ( pointBottom.x() > m_left && pointBottom.x() <= m_right )
961 clippedPolyObject << pointBottom;
962 if ( pointRight.y() < m_bottom )
963 clippedPolyObject << pointRight;
965 else if ( m_previousSector == 1 ) {
966 QPointF pointTop = clipTop( m, m_previousPoint );
967 QPointF pointRight = clipRight( m, m_currentPoint );
968 QPointF pointBottom = clipBottom( m, m_currentPoint );
970 if ( pointTop.x() < m_right ) {
971 clippedPolyObject << pointTop;
973 clippedPolyObject << QPointF( m_right, m_top );
975 if ( pointRight.y() > m_top && pointRight.y() <= m_bottom )
976 clippedPolyObject << pointRight;
977 if ( pointBottom.x() < m_right )
978 clippedPolyObject << pointBottom;
980 else if ( m_previousSector == 0 ) {
981 QPointF pointTop = clipTop( m, m_currentPoint );
982 QPointF pointLeft = clipLeft( m, m_currentPoint );
983 QPointF pointBottom = clipBottom( m, m_previousPoint );
984 QPointF pointRight = clipRight( m, m_previousPoint );
986 if ( pointTop.x() > m_left && pointTop.x() < m_right )
987 clippedPolyObject << pointTop;
988 if ( pointLeft.y() > m_top && pointLeft.y() < m_bottom )
989 clippedPolyObject << pointLeft;
990 if ( pointBottom.x() > m_left && pointBottom.x() < m_right )
991 clippedPolyObject << pointBottom;
992 if ( pointRight.y() > m_top && pointRight.y() < m_bottom )
993 clippedPolyObject << pointRight;
995 if ( pointBottom.x() <= m_left && pointLeft.y() >= m_bottom )
996 clippedPolyObject << QPointF( m_left, m_bottom );
997 if ( pointTop.x() >= m_right && pointRight.y() <= m_top )
998 clippedPolyObject << QPointF( m_right, m_top );
1001 clippedPolyObject << QPointF( m_right, m_bottom );
1009 void ClipPainterPrivate::clipOnceCorner( QPolygonF & clippedPolyObject,
1010 QVector<QPolygonF> & clippedPolyObjects,
1011 const QPointF& corner,
1012 const QPointF& point,
1015 Q_UNUSED( clippedPolyObjects )
1016 Q_UNUSED( isClosed )
1018 if ( m_currentSector == 4) {
1020 clippedPolyObject << corner;
1021 clippedPolyObject << point;
1024 clippedPolyObject << point;
1025 clippedPolyObject << corner;
1029 void ClipPainterPrivate::clipOnceEdge( QPolygonF & clippedPolyObject,
1030 QVector<QPolygonF> & clippedPolyObjects,
1031 const QPointF& point,
1034 if ( m_currentSector == 4) {
1037 clippedPolyObject = QPolygonF();
1039 clippedPolyObject << point;
1043 clippedPolyObject << point;
1045 clippedPolyObjects << clippedPolyObject;
1050 void ClipPainterPrivate::clipOnce( QPolygonF & clippedPolyObject,
1051 QVector<QPolygonF> & clippedPolyObjects,
1058 qreal m = _m( m_previousPoint, m_currentPoint );
1061 int offscreenpos = ( m_currentSector == 4 ) ? m_previousSector : m_currentSector;
1064 switch ( offscreenpos ) {
1066 point = clipTop( m, m_previousPoint );
1067 if ( point.x() < m_left ) {
1068 point = clipLeft( m, point );
1070 clipOnceCorner( clippedPolyObject, clippedPolyObjects, QPointF( m_left, m_top ), point, isClosed );
1073 point = clipTop( m, m_previousPoint );
1074 clipOnceEdge( clippedPolyObject, clippedPolyObjects, point, isClosed );
1077 point = clipTop( m, m_previousPoint );
1078 if ( point.x() > m_right ) {
1079 point = clipRight( m, point );
1081 clipOnceCorner( clippedPolyObject, clippedPolyObjects, QPointF( m_right, m_top ), point, isClosed );
1084 point = clipLeft( m, m_previousPoint );
1085 clipOnceEdge( clippedPolyObject, clippedPolyObjects, point, isClosed );
1088 point = clipRight( m, m_previousPoint );
1089 clipOnceEdge( clippedPolyObject, clippedPolyObjects, point, isClosed );
1092 point = clipBottom( m, m_previousPoint );
1093 if ( point.x() < m_left ) {
1094 point = clipLeft( m, point );
1096 clipOnceCorner( clippedPolyObject, clippedPolyObjects, QPointF( m_left, m_bottom ), point, isClosed );
1099 point = clipBottom( m, m_previousPoint );
1100 clipOnceEdge( clippedPolyObject, clippedPolyObjects, point, isClosed );
1103 point = clipBottom( m, m_previousPoint );
1104 if ( point.x() > m_right ) {
1105 point = clipRight( m, point );
1107 clipOnceCorner( clippedPolyObject, clippedPolyObjects, QPointF( m_right, m_bottom ), point, isClosed );
1115 #ifdef DEBUG_DRAW_NODES
1117 void ClipPainterPrivate::debugDrawNodes(
const QPolygonF & polygon )
1121 q->setRenderHint( QPainter::Antialiasing,
false );
1123 q->setPen( Qt::red );
1124 q->setBrush( Qt::transparent );
1126 const QVector<QPointF>::const_iterator itStartPoint = polygon.constBegin();
1127 const QVector<QPointF>::const_iterator itEndPoint = polygon.constEnd();
1128 QVector<QPointF>::const_iterator itPoint = itStartPoint;
1130 for (; itPoint != itEndPoint; ++itPoint ) {
1132 if ( itPoint == itStartPoint || itPoint == itStartPoint + 1 || itPoint == itStartPoint + 2 ) {
1133 q->setPen( Qt::darkGreen );
1134 if ( itPoint == itStartPoint ) {
1135 q->drawRect( itPoint->x() - 3.0, itPoint->y() - 3.0 , 6.0, 6.0 );
1137 else if ( itPoint == itStartPoint + 1 ) {
1138 q->drawRect( itPoint->x() - 2.0, itPoint->y() - 2.0 , 4.0, 4.0 );
1141 q->drawRect( itPoint->x() - 1.0, itPoint->y() - 1.0 , 2.0, 2.0 );
1143 q->setPen( Qt::red );
1145 else if ( itPoint == itEndPoint - 1 || itPoint == itEndPoint - 2 || itPoint == itEndPoint - 3 ) {
1146 q->setPen( Qt::blue );
1147 if ( itPoint == itEndPoint - 3 ) {
1148 q->drawRect( itPoint->x() - 3.0, itPoint->y() - 3.0 , 6.0, 6.0 );
1150 else if ( itPoint == itEndPoint - 2 ) {
1151 q->drawRect( itPoint->x() - 2.0, itPoint->y() - 2.0 , 4.0, 4.0 );
1154 q->drawRect( itPoint->x() - 1.0, itPoint->y() - 1.0 , 2.0, 2.0 );
1156 q->setPen( Qt::red );
1159 q->drawRect( itPoint->x() - 1.5, itPoint->y() - 1.5 , 3.0, 3.0 );
void drawPolygon(const QPolygonF &, Qt::FillRule fillRule=Qt::OddEvenFill)
void drawPolyline(const QPolygonF &)
void setClipping(bool enable)