7#include "ClipPainter.h" 
   11#include "MarbleDebug.h" 
   16class ClipPainterPrivate
 
   19    explicit ClipPainterPrivate(ClipPainter *parent);
 
   38    QPointF m_currentPoint;
 
   39    QPointF m_previousPoint;
 
   41    inline int sector(
const QPointF &point) 
const;
 
   43    inline QPointF clipTop(qreal m, 
const QPointF &point) 
const;
 
   44    inline QPointF clipLeft(qreal m, 
const QPointF &point) 
const;
 
   45    inline QPointF clipBottom(qreal m, 
const QPointF &point) 
const;
 
   46    inline QPointF clipRight(qreal m, 
const QPointF &point) 
const;
 
   48    inline void initClipRect();
 
   50    inline void clipPolyObject(
const QPolygonF &sourcePolygon, QList<QPolygonF> &clippedPolyObjects, 
bool isClosed);
 
   52    inline void clipMultiple(QPolygonF &clippedPolyObject, QList<QPolygonF> &clippedPolyObjects, 
bool isClosed);
 
   53    inline void clipOnce(QPolygonF &clippedPolyObject, QList<QPolygonF> &clippedPolyObjects, 
bool isClosed);
 
   55    clipOnceCorner(QPolygonF &clippedPolyObject, QList<QPolygonF> &clippedPolyObjects, 
const QPointF &corner, 
const QPointF &point, 
bool isClosed) 
const;
 
   56    inline void clipOnceEdge(QPolygonF &clippedPolyObject, QList<QPolygonF> &clippedPolyObjects, 
const QPointF &point, 
bool isClosed) 
const;
 
   58    void labelPosition(
const QPolygonF &polygon, QList<QPointF> &labelNodes, LabelPositionFlags labelPositionFlags) 
const;
 
   60    bool pointAllowsLabel(
const QPointF &point) 
const;
 
   61    QPointF interpolateLabelPoint(
const QPointF &previousPoint, 
const QPointF ¤tPoint, LabelPositionFlags labelPositionFlags) 
const;
 
   63    static inline qreal _m(
const QPointF &
start, 
const QPointF &end);
 
   65    void debugDrawNodes(
const QPolygonF &);
 
   67    qreal m_labelAreaMargin;
 
   69    int m_debugPenBatchColor;
 
   70    int m_debugBrushBatchColor;
 
   71    int m_debugPolygonsLevel;
 
   72    bool m_debugBatchRender;
 
   83    , d(new ClipPainterPrivate(this))
 
   91ClipPainter::ClipPainter()
 
   92    : d(new ClipPainterPrivate(this))
 
   96ClipPainter::~ClipPainter()
 
  101void ClipPainter::setScreenClip(
bool enable)
 
  103    d->m_doClip = enable;
 
  106bool ClipPainter::hasScreenClip()
 const 
  111void ClipPainter::drawPolygon(
const QPolygonF &polygon, 
Qt::FillRule fillRule)
 
  115        QList<QPolygonF> clippedPolyObjects;
 
  117        d->clipPolyObject(polygon, clippedPolyObjects, 
true);
 
  119        for (
const QPolygonF &clippedPolyObject : clippedPolyObjects) {
 
  120            if (clippedPolyObject.size() > 2) {
 
  122                if (d->m_debugPolygonsLevel) {
 
  124                    QBrush originalBrush = 
brush;
 
  125                    QColor color = 
brush.color();
 
  127                    brush.setColor(color);
 
  134                    d->debugDrawNodes(clippedPolyObject);
 
  141        if (d->m_debugPolygonsLevel) {
 
  143            QBrush originalBrush = 
brush;
 
  144            QColor color = 
brush.color();
 
  146            brush.setColor(color);
 
  153            d->debugDrawNodes(polygon);
 
  160void ClipPainter::drawPolyline(
const QPolygonF &polygon)
 
  164        QList<QPolygonF> clippedPolyObjects;
 
  166        d->clipPolyObject(polygon, clippedPolyObjects, 
false);
 
  168        for (
const QPolygonF &clippedPolyObject : clippedPolyObjects) {
 
  169            if (clippedPolyObject.size() > 1) {
 
  170                if (d->m_debugPolygonsLevel) {
 
  172                    QPen originalPen = 
pen;
 
  173                    QColor color = 
pen.color();
 
  182                    d->debugDrawNodes(clippedPolyObject);
 
  189        if (d->m_debugPolygonsLevel) {
 
  191            QPen originalPen = 
pen;
 
  192            QColor color = 
pen.color();
 
  201            d->debugDrawNodes(polygon);
 
  208void ClipPainter::drawPolyline(
const QPolygonF &polygon, QList<QPointF> &labelNodes, LabelPositionFlags positionFlags)
 
  212        QList<QPolygonF> clippedPolyObjects;
 
  214        d->clipPolyObject(polygon, clippedPolyObjects, 
false);
 
  216        for (
const QPolygonF &clippedPolyObject : clippedPolyObjects) {
 
  217            if (d->m_debugPolygonsLevel) {
 
  219                QPen originalPen = 
pen;
 
  220                QColor color = 
pen.color();
 
  229                d->debugDrawNodes(clippedPolyObject);
 
  235        if (d->m_debugPolygonsLevel) {
 
  237            QPen originalPen = 
pen;
 
  238            QColor color = 
pen.color();
 
  247            d->debugDrawNodes(polygon);
 
  252        d->labelPosition(polygon, labelNodes, positionFlags);
 
  256void ClipPainter::labelPosition(
const QPolygonF &polygon, QList<QPointF> &labelNodes, LabelPositionFlags labelPositionFlags)
 const 
  258    d->labelPosition(polygon, labelNodes, labelPositionFlags);
 
  261void ClipPainter::setPen(
const QColor &color)
 
  263    if (d->m_debugBatchRender) {
 
  271    if (d->m_debugBatchRender) {
 
  277void ClipPainter::setPen(
const QPen &pen)
 
  279    if (d->m_debugBatchRender) {
 
  286            d->m_debugPenBatchColor++;
 
  287            d->m_debugPenBatchColor %= 14;
 
  297void ClipPainter::setBrush(
const QBrush &brush)
 
  299    if (d->m_debugBatchRender) {
 
  303            QBrush batchColor(QColor((
Qt::GlobalColor)(d->m_debugBrushBatchColor)));
 
  305            d->m_debugBrushBatchColor++;
 
  306            d->m_debugBrushBatchColor %= 20;
 
  316void ClipPainterPrivate::labelPosition(
const QPolygonF &polygon, QList<QPointF> &labelNodes, LabelPositionFlags labelPositionFlags)
 const 
  318    if (labelPositionFlags.
testFlag(LineCenter)) {
 
  321            const int labelPosition = polygon.
size() / 2; 
 
  322            labelNodes << polygon.
at(labelPosition);
 
  327        if (pointAllowsLabel(polygon.
first())) {
 
  328            labelNodes << polygon.
first();
 
  332        for (
int it = 1; it < polygon.
size(); ++it) {
 
  333            const bool currentAllowsLabel = pointAllowsLabel(polygon.
at(it));
 
  335            if (currentAllowsLabel) {
 
  337                QPointF node = interpolateLabelPoint(polygon.
at(it - 1), polygon.
at(it), labelPositionFlags);
 
  338                if (node != QPointF(-1.0, -1.0)) {
 
  346    if (polygon.
size() > 1 && labelPositionFlags.
testFlag(LineEnd)) {
 
  347        if (pointAllowsLabel(polygon.
at(polygon.
size() - 1))) {
 
  348            labelNodes << polygon.
at(polygon.
size() - 1);
 
  352        for (
int it = polygon.
size() - 2; it > 0; --it) {
 
  353            const bool currentAllowsLabel = pointAllowsLabel(polygon.
at(it));
 
  355            if (currentAllowsLabel) {
 
  356                QPointF node = interpolateLabelPoint(polygon.
at(it + 1), polygon.
at(it), labelPositionFlags);
 
  357                if (node != QPointF(-1.0, -1.0)) {
 
  366bool ClipPainterPrivate::pointAllowsLabel(
const QPointF &point)
 const 
  368    return point.
x() > m_labelAreaMargin && point.
x() < q->viewport().width() - m_labelAreaMargin && point.
y() > m_labelAreaMargin
 
  369        && point.
y() < q->viewport().height() - m_labelAreaMargin;
 
  372QPointF ClipPainterPrivate::interpolateLabelPoint(
const QPointF &previousPoint, 
const QPointF ¤tPoint, LabelPositionFlags labelPositionFlags)
 const 
  374    qreal m = _m(previousPoint, currentPoint);
 
  375    if (previousPoint.
x() <= m_labelAreaMargin) {
 
  376        if (labelPositionFlags.
testFlag(IgnoreXMargin)) {
 
  379        return {m_labelAreaMargin, previousPoint.
y() + (m_labelAreaMargin - previousPoint.
x()) * m};
 
  380    } 
else if (previousPoint.
x() >= q->viewport().width() - m_labelAreaMargin) {
 
  381        if (labelPositionFlags.
testFlag(IgnoreXMargin)) {
 
  384        return {q->viewport().width() - m_labelAreaMargin, previousPoint.
y() - (previousPoint.
x() - q->viewport().width() + m_labelAreaMargin) * m};
 
  387    if (previousPoint.
y() <= m_labelAreaMargin) {
 
  388        if (labelPositionFlags.
testFlag(IgnoreYMargin)) {
 
  391        return {previousPoint.
x() + (m_labelAreaMargin - previousPoint.
y()) / m, m_labelAreaMargin};
 
  392    } 
else if (previousPoint.
y() >= q->viewport().height() - m_labelAreaMargin) {
 
  393        if (labelPositionFlags.
testFlag(IgnoreYMargin)) {
 
  396        return {previousPoint.
x() - (previousPoint.
y() - q->viewport().height() + m_labelAreaMargin) / m, q->viewport().height() - m_labelAreaMargin};
 
  404ClipPainterPrivate::ClipPainterPrivate(ClipPainter *parent)
 
  411    , m_previousSector(4)
 
  412    , m_currentPoint(QPointF())
 
  413    , m_previousPoint(QPointF())
 
  414    , m_labelAreaMargin(10.0)
 
  415    , m_debugPenBatchColor(0)
 
  416    , m_debugBrushBatchColor(0)
 
  417    , m_debugPolygonsLevel(0)
 
  418    , m_debugBatchRender(false)
 
  423void ClipPainterPrivate::initClipRect()
 
  425    qreal penHalfWidth = q->
pen().
widthF() / 2.0 + 1.0;
 
  427    m_left = -penHalfWidth;
 
  428    m_right = (qreal)(q->device()->width()) + penHalfWidth;
 
  429    m_top = -penHalfWidth;
 
  430    m_bottom = (qreal)(q->device()->height()) + penHalfWidth;
 
  433qreal ClipPainterPrivate::_m(
const QPointF &
start, 
const QPointF &end)
 
  435    qreal divisor = 
end.x() - 
start.x();
 
  436    if (std::fabs(divisor) < 0.000001) {
 
  442    return (
end.y() - 
start.y()) / divisor;
 
  445QPointF ClipPainterPrivate::clipTop(qreal m, 
const QPointF &point)
 const 
  447    return {(m_top - point.
y()) / m + point.
x(), m_top};
 
  450QPointF ClipPainterPrivate::clipLeft(qreal m, 
const QPointF &point)
 const 
  452    return {m_left, (m_left - point.
x()) * m + point.
y()};
 
  455QPointF ClipPainterPrivate::clipBottom(qreal m, 
const QPointF &point)
 const 
  457    return {(m_bottom - point.
y()) / m + point.
x(), m_bottom};
 
  460QPointF ClipPainterPrivate::clipRight(qreal m, 
const QPointF &point)
 const 
  462    return {m_right, (m_right - point.
x()) * m + point.
y()};
 
  465int ClipPainterPrivate::sector(
const QPointF &point)
 const 
  480    if (point.
x() < m_left)
 
  482    else if (point.
x() > m_right)
 
  486    if (point.
y() < m_top)
 
  488    else if (point.
y() > m_bottom)
 
  493    return ySector + xSector;
 
  496void ClipPainterPrivate::clipPolyObject(
const QPolygonF &polygon, QList<QPolygonF> &clippedPolyObjects, 
bool isClosed)
 
  502    QPolygonF clippedPolyObject = QPolygonF();
 
  504    const QList<QPointF>::const_iterator itStartPoint = polygon.
constBegin();
 
  505    const QList<QPointF>::const_iterator itEndPoint = polygon.
constEnd();
 
  506    QList<QPointF>::const_iterator itPoint = itStartPoint;
 
  512    bool processingLastNode = 
false;
 
  514    while (itPoint != itEndPoint) {
 
  515        m_currentPoint = (*itPoint);
 
  519        m_currentSector = sector(m_currentPoint);
 
  522        if (itPoint == itStartPoint && processingLastNode == 
false) {
 
  524                m_previousPoint = polygon.
last();
 
  527                m_previousSector = sector(m_previousPoint);
 
  529                m_previousSector = m_currentSector;
 
  534        if (m_currentSector != m_previousSector) {
 
  535            if (m_currentSector == 4 || m_previousSector == 4) {
 
  540                clipOnce(clippedPolyObject, clippedPolyObjects, isClosed);
 
  546                clipMultiple(clippedPolyObject, clippedPolyObjects, isClosed);
 
  549            m_previousSector = m_currentSector;
 
  553        if (m_currentSector == 4) {
 
  554            clippedPolyObject << m_currentPoint;
 
  556            ++(m_debugNodeCount);
 
  560        m_previousPoint = m_currentPoint;
 
  565        if (processingLastNode) {
 
  570        if (itPoint == itEndPoint && isClosed) {
 
  571            itPoint = itStartPoint;
 
  572            processingLastNode = 
true;
 
  577    if (!clippedPolyObject.
isEmpty()) {
 
  578        clippedPolyObjects << clippedPolyObject;
 
  582void ClipPainterPrivate::clipMultiple(QPolygonF &clippedPolyObject, QList<QPolygonF> &clippedPolyObjects, 
bool isClosed)
 
  584    Q_UNUSED(clippedPolyObjects)
 
  590    qreal m = _m(m_previousPoint, m_currentPoint);
 
  592    switch (m_currentSector) {
 
  594        if (m_previousSector == 5) {
 
  595            QPointF pointRight = clipRight(m, m_previousPoint);
 
  596            QPointF pointTop = clipTop(m, m_currentPoint);
 
  597            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  599            if (pointRight.
y() > m_top) {
 
  600                clippedPolyObject << pointRight;
 
  602                clippedPolyObject << QPointF(m_right, m_top);
 
  604            if (pointTop.
x() >= m_left && pointTop.
x() < m_right)
 
  605                clippedPolyObject << pointTop;
 
  606            if (pointLeft.
y() > m_top)
 
  607                clippedPolyObject << pointLeft;
 
  608        } 
else if (m_previousSector == 7) {
 
  609            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  610            QPointF pointTop = clipTop(m, m_currentPoint);
 
  611            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  613            if (pointBottom.
x() > m_left) {
 
  614                clippedPolyObject << pointBottom;
 
  616                clippedPolyObject << QPointF(m_left, m_bottom);
 
  618            if (pointLeft.
y() >= m_top && pointLeft.
y() < m_bottom)
 
  619                clippedPolyObject << pointLeft;
 
  620            if (pointTop.
x() > m_left)
 
  621                clippedPolyObject << pointTop;
 
  622        } 
else if (m_previousSector == 8) {
 
  623            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  624            QPointF pointRight = clipRight(m, m_previousPoint);
 
  625            QPointF pointTop = clipTop(m, m_currentPoint);
 
  626            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  628            if (pointBottom.
x() > m_left && pointBottom.
x() < m_right)
 
  629                clippedPolyObject << pointBottom;
 
  630            if (pointRight.
y() > m_top && pointRight.
y() < m_bottom)
 
  631                clippedPolyObject << pointRight;
 
  632            if (pointTop.
x() > m_left && pointTop.
x() < m_right)
 
  633                clippedPolyObject << pointTop;
 
  634            if (pointLeft.
y() > m_top && pointLeft.
y() < m_bottom)
 
  635                clippedPolyObject << pointLeft;
 
  637            if (pointBottom.x() <= m_left && pointLeft.y() >= m_bottom)
 
  638                clippedPolyObject << QPointF(m_left, m_bottom);
 
  639            if (pointTop.x() >= m_right && pointRight.y() <= m_top)
 
  640                clippedPolyObject << QPointF(m_right, m_top);
 
  643        clippedPolyObject << QPointF(m_left, m_top);
 
  647        if (m_previousSector == 3) {
 
  648            QPointF pointLeft = clipLeft(m, m_previousPoint);
 
  649            QPointF pointTop = clipTop(m, m_currentPoint);
 
  651            if (pointLeft.
y() > m_top) {
 
  652                clippedPolyObject << pointLeft;
 
  654                clippedPolyObject << QPointF(m_left, m_top);
 
  656            if (pointTop.
x() > m_left)
 
  657                clippedPolyObject << pointTop;
 
  658        } 
else if (m_previousSector == 5) {
 
  659            QPointF pointRight = clipRight(m, m_previousPoint);
 
  660            QPointF pointTop = clipTop(m, m_currentPoint);
 
  662            if (pointRight.
y() > m_top) {
 
  663                clippedPolyObject << pointRight;
 
  665                clippedPolyObject << QPointF(m_right, m_top);
 
  667            if (pointTop.
x() < m_right)
 
  668                clippedPolyObject << pointTop;
 
  669        } 
else if (m_previousSector == 6) {
 
  670            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  671            QPointF pointLeft = clipLeft(m, m_previousPoint);
 
  672            QPointF pointTop = clipTop(m, m_currentPoint);
 
  674            if (pointBottom.
x() > m_left)
 
  675                clippedPolyObject << pointBottom;
 
  676            if (pointLeft.
y() > m_top && pointLeft.
y() <= m_bottom)
 
  677                clippedPolyObject << pointLeft;
 
  678            if (pointTop.
x() > m_left) {
 
  679                clippedPolyObject << pointTop;
 
  681                clippedPolyObject << QPointF(m_left, m_top);
 
  683        } 
else if (m_previousSector == 7) {
 
  684            clippedPolyObject << clipBottom(m, m_previousPoint);
 
  685            clippedPolyObject << clipTop(m, m_currentPoint);
 
  686        } 
else if (m_previousSector == 8) {
 
  687            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  688            QPointF pointRight = clipRight(m, m_previousPoint);
 
  689            QPointF pointTop = clipTop(m, m_currentPoint);
 
  691            if (pointBottom.
x() < m_right)
 
  692                clippedPolyObject << pointBottom;
 
  693            if (pointRight.
y() > m_top && pointRight.
y() <= m_bottom)
 
  694                clippedPolyObject << pointRight;
 
  695            if (pointTop.
x() < m_right) {
 
  696                clippedPolyObject << pointTop;
 
  698                clippedPolyObject << QPointF(m_right, m_top);
 
  704        if (m_previousSector == 3) {
 
  705            QPointF pointLeft = clipLeft(m, m_previousPoint);
 
  706            QPointF pointTop = clipTop(m, m_currentPoint);
 
  707            QPointF pointRight = clipRight(m, m_currentPoint);
 
  709            if (pointLeft.
y() > m_top) {
 
  710                clippedPolyObject << pointLeft;
 
  712                clippedPolyObject << QPointF(m_left, m_top);
 
  714            if (pointTop.
x() > m_left && pointTop.
x() <= m_right)
 
  715                clippedPolyObject << pointTop;
 
  716            if (pointRight.
y() > m_top)
 
  717                clippedPolyObject << pointRight;
 
  718        } 
else if (m_previousSector == 7) {
 
  719            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  720            QPointF pointTop = clipTop(m, m_currentPoint);
 
  721            QPointF pointRight = clipRight(m, m_currentPoint);
 
  723            if (pointBottom.
x() < m_right) {
 
  724                clippedPolyObject << pointBottom;
 
  726                clippedPolyObject << QPointF(m_right, m_bottom);
 
  728            if (pointRight.
y() >= m_top && pointRight.
y() < m_bottom)
 
  729                clippedPolyObject << pointRight;
 
  730            if (pointTop.
x() < m_right)
 
  731                clippedPolyObject << pointTop;
 
  732        } 
else if (m_previousSector == 6) {
 
  733            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  734            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  735            QPointF pointTop = clipTop(m, m_currentPoint);
 
  736            QPointF pointRight = clipRight(m, m_previousPoint);
 
  738            if (pointBottom.
x() > m_left && pointBottom.
x() < m_right)
 
  739                clippedPolyObject << pointBottom;
 
  740            if (pointLeft.
y() > m_top && pointLeft.
y() < m_bottom)
 
  741                clippedPolyObject << pointLeft;
 
  742            if (pointTop.
x() > m_left && pointTop.
x() < m_right)
 
  743                clippedPolyObject << pointTop;
 
  744            if (pointRight.
y() > m_top && pointRight.
y() < m_bottom)
 
  745                clippedPolyObject << pointRight;
 
  747            if (pointBottom.x() >= m_right && pointRight.y() >= m_bottom)
 
  748                clippedPolyObject << QPointF(m_right, m_bottom);
 
  749            if (pointTop.x() <= m_left && pointLeft.y() <= m_top)
 
  750                clippedPolyObject << QPointF(m_left, m_top);
 
  753        clippedPolyObject << QPointF(m_right, m_top);
 
  757        if (m_previousSector == 7) {
 
  758            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  759            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  761            if (pointBottom.
x() > m_left)
 
  762                clippedPolyObject << pointBottom;
 
  763            if (pointLeft.
y() < m_bottom) {
 
  764                clippedPolyObject << pointLeft;
 
  766                clippedPolyObject << QPointF(m_left, m_bottom);
 
  768        } 
else if (m_previousSector == 1) {
 
  769            QPointF pointTop = clipTop(m, m_previousPoint);
 
  770            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  772            if (pointTop.
x() > m_left)
 
  773                clippedPolyObject << pointTop;
 
  774            if (pointLeft.
y() > m_top) {
 
  775                clippedPolyObject << pointLeft;
 
  777                clippedPolyObject << QPointF(m_left, m_top);
 
  779        } 
else if (m_previousSector == 8) {
 
  780            QPointF pointRight = clipRight(m, m_previousPoint);
 
  781            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  782            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  784            if (pointRight.
y() < m_bottom)
 
  785                clippedPolyObject << pointRight;
 
  786            if (pointBottom.
x() > m_left && pointBottom.
x() <= m_right)
 
  787                clippedPolyObject << pointBottom;
 
  788            if (pointLeft.
y() < m_bottom) {
 
  789                clippedPolyObject << pointLeft;
 
  791                clippedPolyObject << QPointF(m_left, m_bottom);
 
  793        } 
else if (m_previousSector == 5) {
 
  794            clippedPolyObject << clipRight(m, m_previousPoint);
 
  795            clippedPolyObject << clipLeft(m, m_currentPoint);
 
  796        } 
else if (m_previousSector == 2) {
 
  797            QPointF pointRight = clipRight(m, m_previousPoint);
 
  798            QPointF pointTop = clipTop(m, m_previousPoint);
 
  799            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  801            if (pointRight.
y() > m_top)
 
  802                clippedPolyObject << pointRight;
 
  803            if (pointTop.
x() > m_left && pointTop.
x() <= m_right)
 
  804                clippedPolyObject << pointTop;
 
  805            if (pointLeft.
y() > m_top) {
 
  806                clippedPolyObject << pointLeft;
 
  808                clippedPolyObject << QPointF(m_left, m_top);
 
  814        if (m_previousSector == 7) {
 
  815            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  816            QPointF pointRight = clipRight(m, m_currentPoint);
 
  818            if (pointBottom.
x() < m_right)
 
  819                clippedPolyObject << pointBottom;
 
  820            if (pointRight.
y() < m_bottom) {
 
  821                clippedPolyObject << pointRight;
 
  823                clippedPolyObject << QPointF(m_right, m_bottom);
 
  825        } 
else if (m_previousSector == 1) {
 
  826            QPointF pointTop = clipTop(m, m_previousPoint);
 
  827            QPointF pointRight = clipRight(m, m_currentPoint);
 
  829            if (pointTop.
x() < m_right)
 
  830                clippedPolyObject << pointTop;
 
  831            if (pointRight.
y() > m_top) {
 
  832                clippedPolyObject << pointRight;
 
  834                clippedPolyObject << QPointF(m_right, m_top);
 
  836        } 
else if (m_previousSector == 6) {
 
  837            QPointF pointLeft = clipLeft(m, m_previousPoint);
 
  838            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  839            QPointF pointRight = clipRight(m, m_currentPoint);
 
  841            if (pointLeft.
y() < m_bottom)
 
  842                clippedPolyObject << pointLeft;
 
  843            if (pointBottom.
x() >= m_left && pointBottom.
x() < m_right)
 
  844                clippedPolyObject << pointBottom;
 
  845            if (pointRight.
y() < m_bottom) {
 
  846                clippedPolyObject << pointRight;
 
  848                clippedPolyObject << QPointF(m_right, m_bottom);
 
  850        } 
else if (m_previousSector == 3) {
 
  851            clippedPolyObject << clipLeft(m, m_previousPoint);
 
  852            clippedPolyObject << clipRight(m, m_currentPoint);
 
  853        } 
else if (m_previousSector == 0) {
 
  854            QPointF pointLeft = clipLeft(m, m_previousPoint);
 
  855            QPointF pointTop = clipTop(m, m_previousPoint);
 
  856            QPointF pointRight = clipRight(m, m_currentPoint);
 
  858            if (pointLeft.
y() > m_top)
 
  859                clippedPolyObject << pointLeft;
 
  860            if (pointTop.
x() >= m_left && pointTop.
x() < m_right)
 
  861                clippedPolyObject << pointTop;
 
  862            if (pointRight.
y() > m_top) {
 
  863                clippedPolyObject << pointRight;
 
  865                clippedPolyObject << QPointF(m_right, m_top);
 
  871        if (m_previousSector == 5) {
 
  872            QPointF pointRight = clipRight(m, m_previousPoint);
 
  873            QPointF pointBottom = clipBottom(m, m_currentPoint);
 
  874            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  876            if (pointRight.
y() < m_bottom) {
 
  877                clippedPolyObject << pointRight;
 
  879                clippedPolyObject << QPointF(m_right, m_bottom);
 
  881            if (pointBottom.
x() >= m_left && pointBottom.
x() < m_right)
 
  882                clippedPolyObject << pointBottom;
 
  883            if (pointLeft.
y() < m_bottom)
 
  884                clippedPolyObject << pointLeft;
 
  885        } 
else if (m_previousSector == 1) {
 
  886            QPointF pointTop = clipTop(m, m_previousPoint);
 
  887            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  888            QPointF pointBottom = clipBottom(m, m_currentPoint);
 
  890            if (pointTop.
x() > m_left) {
 
  891                clippedPolyObject << pointTop;
 
  893                clippedPolyObject << QPointF(m_left, m_top);
 
  895            if (pointLeft.
y() > m_top && pointLeft.
y() <= m_bottom)
 
  896                clippedPolyObject << pointLeft;
 
  897            if (pointBottom.
x() > m_left)
 
  898                clippedPolyObject << pointBottom;
 
  899        } 
else if (m_previousSector == 2) {
 
  900            QPointF pointTop = clipTop(m, m_currentPoint);
 
  901            QPointF pointRight = clipRight(m, m_previousPoint);
 
  902            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
  903            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
  905            if (pointTop.
x() > m_left && pointTop.
x() < m_right)
 
  906                clippedPolyObject << pointTop;
 
  907            if (pointRight.
y() > m_top && pointRight.
y() < m_bottom)
 
  908                clippedPolyObject << pointRight;
 
  909            if (pointBottom.
x() > m_left && pointBottom.
x() < m_right)
 
  910                clippedPolyObject << pointBottom;
 
  911            if (pointLeft.
y() > m_top && pointLeft.
y() < m_bottom)
 
  912                clippedPolyObject << pointLeft;
 
  914            if (pointBottom.x() >= m_right && pointRight.y() >= m_bottom)
 
  915                clippedPolyObject << QPointF(m_right, m_bottom);
 
  916            if (pointTop.x() <= m_left && pointLeft.y() <= m_top)
 
  917                clippedPolyObject << QPointF(m_left, m_top);
 
  920        clippedPolyObject << QPointF(m_left, m_bottom);
 
  924        if (m_previousSector == 3) {
 
  925            QPointF pointLeft = clipLeft(m, m_previousPoint);
 
  926            QPointF pointBottom = clipBottom(m, m_currentPoint);
 
  928            if (pointLeft.
y() < m_bottom) {
 
  929                clippedPolyObject << pointLeft;
 
  931                clippedPolyObject << QPointF(m_left, m_bottom);
 
  933            if (pointBottom.
x() > m_left)
 
  934                clippedPolyObject << pointBottom;
 
  935        } 
else if (m_previousSector == 5) {
 
  936            QPointF pointRight = clipRight(m, m_previousPoint);
 
  937            QPointF pointBottom = clipBottom(m, m_currentPoint);
 
  939            if (pointRight.
y() < m_bottom) {
 
  940                clippedPolyObject << pointRight;
 
  942                clippedPolyObject << QPointF(m_right, m_bottom);
 
  944            if (pointBottom.
x() < m_right)
 
  945                clippedPolyObject << pointBottom;
 
  946        } 
else if (m_previousSector == 0) {
 
  947            QPointF pointTop = clipTop(m, m_previousPoint);
 
  948            QPointF pointLeft = clipLeft(m, m_previousPoint);
 
  949            QPointF pointBottom = clipBottom(m, m_currentPoint);
 
  951            if (pointTop.
x() > m_left)
 
  952                clippedPolyObject << pointTop;
 
  953            if (pointLeft.
y() >= m_top && pointLeft.
y() < m_bottom)
 
  954                clippedPolyObject << pointLeft;
 
  955            if (pointBottom.
x() > m_left) {
 
  956                clippedPolyObject << pointBottom;
 
  958                clippedPolyObject << QPointF(m_left, m_bottom);
 
  960        } 
else if (m_previousSector == 1) {
 
  961            clippedPolyObject << clipTop(m, m_previousPoint);
 
  962            clippedPolyObject << clipBottom(m, m_currentPoint);
 
  963        } 
else if (m_previousSector == 2) {
 
  964            QPointF pointTop = clipTop(m, m_previousPoint);
 
  965            QPointF pointRight = clipRight(m, m_previousPoint);
 
  966            QPointF pointBottom = clipBottom(m, m_currentPoint);
 
  968            if (pointTop.
x() < m_right)
 
  969                clippedPolyObject << pointTop;
 
  970            if (pointRight.
y() >= m_top && pointRight.
y() < m_bottom)
 
  971                clippedPolyObject << pointRight;
 
  972            if (pointBottom.
x() < m_right) {
 
  973                clippedPolyObject << pointBottom;
 
  975                clippedPolyObject << QPointF(m_right, m_bottom);
 
  981        if (m_previousSector == 3) {
 
  982            QPointF pointLeft = clipLeft(m, m_previousPoint);
 
  983            QPointF pointBottom = clipBottom(m, m_currentPoint);
 
  984            QPointF pointRight = clipRight(m, m_currentPoint);
 
  986            if (pointLeft.
y() < m_bottom) {
 
  987                clippedPolyObject << pointLeft;
 
  989                clippedPolyObject << QPointF(m_left, m_bottom);
 
  991            if (pointBottom.
x() > m_left && pointBottom.
x() <= m_right)
 
  992                clippedPolyObject << pointBottom;
 
  993            if (pointRight.
y() < m_bottom)
 
  994                clippedPolyObject << pointRight;
 
  995        } 
else if (m_previousSector == 1) {
 
  996            QPointF pointTop = clipTop(m, m_previousPoint);
 
  997            QPointF pointRight = clipRight(m, m_currentPoint);
 
  998            QPointF pointBottom = clipBottom(m, m_currentPoint);
 
 1000            if (pointTop.
x() < m_right) {
 
 1001                clippedPolyObject << pointTop;
 
 1003                clippedPolyObject << QPointF(m_right, m_top);
 
 1005            if (pointRight.
y() > m_top && pointRight.
y() <= m_bottom)
 
 1006                clippedPolyObject << pointRight;
 
 1007            if (pointBottom.
x() < m_right)
 
 1008                clippedPolyObject << pointBottom;
 
 1009        } 
else if (m_previousSector == 0) {
 
 1010            QPointF pointTop = clipTop(m, m_currentPoint);
 
 1011            QPointF pointLeft = clipLeft(m, m_currentPoint);
 
 1012            QPointF pointBottom = clipBottom(m, m_previousPoint);
 
 1013            QPointF pointRight = clipRight(m, m_previousPoint);
 
 1015            if (pointTop.
x() > m_left && pointTop.
x() < m_right)
 
 1016                clippedPolyObject << pointTop;
 
 1017            if (pointLeft.
y() > m_top && pointLeft.
y() < m_bottom)
 
 1018                clippedPolyObject << pointLeft;
 
 1019            if (pointBottom.
x() > m_left && pointBottom.
x() < m_right)
 
 1020                clippedPolyObject << pointBottom;
 
 1021            if (pointRight.
y() > m_top && pointRight.
y() < m_bottom)
 
 1022                clippedPolyObject << pointRight;
 
 1024            if (pointBottom.x() <= m_left && pointLeft.y() >= m_bottom)
 
 1025                clippedPolyObject << QPointF(m_left, m_bottom);
 
 1026            if (pointTop.x() >= m_right && pointRight.y() <= m_top)
 
 1027                clippedPolyObject << QPointF(m_right, m_top);
 
 1030        clippedPolyObject << QPointF(m_right, m_bottom);
 
 1038void ClipPainterPrivate::clipOnceCorner(QPolygonF &clippedPolyObject,
 
 1039                                        QList<QPolygonF> &clippedPolyObjects,
 
 1040                                        const QPointF &corner,
 
 1041                                        const QPointF &point,
 
 1042                                        bool isClosed)
 const 
 1044    Q_UNUSED(clippedPolyObjects)
 
 1047    if (m_currentSector == 4) {
 
 1049        clippedPolyObject << corner;
 
 1050        clippedPolyObject << point;
 
 1053        clippedPolyObject << point;
 
 1054        clippedPolyObject << corner;
 
 1058void ClipPainterPrivate::clipOnceEdge(QPolygonF &clippedPolyObject, QList<QPolygonF> &clippedPolyObjects, 
const QPointF &point, 
bool isClosed)
 const 
 1060    if (m_currentSector == 4) {
 
 1063            clippedPolyObject = QPolygonF();
 
 1065        clippedPolyObject << point;
 
 1068        clippedPolyObject << point;
 
 1070            clippedPolyObjects << clippedPolyObject;
 
 1075void ClipPainterPrivate::clipOnce(QPolygonF &clippedPolyObject, QList<QPolygonF> &clippedPolyObjects, 
bool isClosed)
 
 1081    qreal m = _m(m_previousPoint, m_currentPoint);
 
 1084    int offscreenpos = (m_currentSector == 4) ? m_previousSector : m_currentSector;
 
 1087    switch (offscreenpos) {
 
 1089        point = clipTop(m, m_previousPoint);
 
 1090        if (point.
x() < m_left) {
 
 1091            point = clipLeft(m, point);
 
 1093        clipOnceCorner(clippedPolyObject, clippedPolyObjects, QPointF(m_left, m_top), point, isClosed);
 
 1096        point = clipTop(m, m_previousPoint);
 
 1097        clipOnceEdge(clippedPolyObject, clippedPolyObjects, point, isClosed);
 
 1100        point = clipTop(m, m_previousPoint);
 
 1101        if (point.
x() > m_right) {
 
 1102            point = clipRight(m, point);
 
 1104        clipOnceCorner(clippedPolyObject, clippedPolyObjects, QPointF(m_right, m_top), point, isClosed);
 
 1107        point = clipLeft(m, m_previousPoint);
 
 1108        clipOnceEdge(clippedPolyObject, clippedPolyObjects, point, isClosed);
 
 1111        point = clipRight(m, m_previousPoint);
 
 1112        clipOnceEdge(clippedPolyObject, clippedPolyObjects, point, isClosed);
 
 1115        point = clipBottom(m, m_previousPoint);
 
 1116        if (point.
x() < m_left) {
 
 1117            point = clipLeft(m, point);
 
 1119        clipOnceCorner(clippedPolyObject, clippedPolyObjects, QPointF(m_left, m_bottom), point, isClosed);
 
 1122        point = clipBottom(m, m_previousPoint);
 
 1123        clipOnceEdge(clippedPolyObject, clippedPolyObjects, point, isClosed);
 
 1126        point = clipBottom(m, m_previousPoint);
 
 1127        if (point.
x() > m_right) {
 
 1128            point = clipRight(m, point);
 
 1130        clipOnceCorner(clippedPolyObject, clippedPolyObjects, QPointF(m_right, m_bottom), point, isClosed);
 
 1137void ClipPainter::setDebugPolygonsLevel(
int level)
 
 1139    d->m_debugPolygonsLevel = 
level;
 
 1142void ClipPainter::setDebugBatchRender(
bool enabled)
 
 1144    d->m_debugBatchRender = enabled;
 
 1147void ClipPainterPrivate::debugDrawNodes(
const QPolygonF &polygon)
 
 1153    q->setBrush(QBrush(
"#40FF0000"));
 
 1155    const QList<QPointF>::const_iterator itStartPoint = polygon.
constBegin();
 
 1156    const QList<QPointF>::const_iterator itEndPoint = polygon.
constEnd();
 
 1157    QList<QPointF>::const_iterator itPoint = itStartPoint;
 
 1161    for (; itPoint != itEndPoint; ++itPoint) {
 
 1164        if (itPoint == itStartPoint || itPoint == itStartPoint + 1 || itPoint == itStartPoint + 2) {
 
 1166            q->setBrush(QBrush(
"#4000FF00"));
 
 1167            if (itPoint == itStartPoint) {
 
 1168                q->drawRect(itPoint->x() - 6.0, itPoint->y() - 6.0, 12.0, 12.0);
 
 1169            } 
else if (itPoint == itStartPoint + 1) {
 
 1170                q->drawRect(itPoint->x() - 4.0, itPoint->y() - 4.0, 8.0, 8.0);
 
 1172                q->drawRect(itPoint->x() - 2.0, itPoint->y() - 2.0, 4.0, 4.0);
 
 1175            q->setBrush(QBrush(
"#40FF0000"));
 
 1176        } 
else if (itPoint == itEndPoint - 1 || itPoint == itEndPoint - 2 || itPoint == itEndPoint - 3) {
 
 1178            q->setBrush(QBrush(
"#400000FF"));
 
 1179            if (itPoint == itEndPoint - 3) {
 
 1180                q->drawRect(itPoint->x() - 6.0, itPoint->y() - 6.0, 12.0, 12.0);
 
 1181            } 
else if (itPoint == itEndPoint - 2) {
 
 1182                q->drawRect(itPoint->x() - 4.0, itPoint->y() - 4.0, 8.0, 8.0);
 
 1184                q->drawRect(itPoint->x() - 2.0, itPoint->y() - 2.0, 4.0, 4.0);
 
 1187            q->setBrush(QBrush(
"#400000FF"));
 
 1189            q->drawRect(itPoint->x() - 4, itPoint->y() - 4, 8.0, 8.0);
 
 1191        if (m_debugPolygonsLevel == 2) {
 
 1192            q->setFont(QFont(QStringLiteral(
"Sans Serif"), 7));
 
 1195            q->drawText(itPoint->x() + 6.0, itPoint->y() + (15 - (i * 5) % 30), 
QString::number(i));
 
Q_SCRIPTABLE Q_NOREPLY void start()
 
QStringView level(QStringView ifopt)
 
const QList< QKeySequence > & end()
 
Binds a QML item to a specific geodetic location in screen coordinates.
 
const QColor & color() const const
 
bool testFlag(Enum flag) const const
 
const_reference at(qsizetype i) const const
 
const_iterator constBegin() const const
 
const_iterator constEnd() const const
 
bool isEmpty() const const
 
qsizetype size() const const
 
const QBrush & brush() const const
 
void drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule)
 
void drawPolyline(const QPoint *points, int pointCount)
 
const QPen & pen() const const
 
void setBrush(Qt::BrushStyle style)
 
void setPen(Qt::PenStyle style)
 
QColor color() const const
 
void setColor(const QColor &color)
 
qreal widthF() const const
 
QString number(double n, char format, int precision)