diff options
Diffstat (limited to 'src/gui/painting/qpainterpath.cpp')
-rw-r--r-- | src/gui/painting/qpainterpath.cpp | 118 |
1 files changed, 86 insertions, 32 deletions
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index ff133b6..8d3cfab 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -73,6 +73,17 @@ QT_BEGIN_NAMESPACE +struct QPainterPathPrivateDeleter +{ + static inline void cleanup(QPainterPathPrivate *d) + { + // note - we must up-cast to QPainterPathData since QPainterPathPrivate + // has a non-virtual destructor! + if (d && !d->ref.deref()) + delete static_cast<QPainterPathData *>(d); + } +}; + // This value is used to determine the length of control point vectors // when approximating arc segments as curves. The factor is multiplied // with the radius of the circle. @@ -153,7 +164,7 @@ static void qt_debug_path(const QPainterPath &path) /*! \class QPainterPath - \ingroup multimedia + \ingroup painting \ingroup shared \brief The QPainterPath class provides a container for painting operations, @@ -506,10 +517,10 @@ QPainterPath::QPainterPath() \sa operator=() */ QPainterPath::QPainterPath(const QPainterPath &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { - if (d_func()) - d_func()->ref.ref(); + if (d_ptr) + d_ptr->ref.ref(); } /*! @@ -530,9 +541,7 @@ QPainterPath::QPainterPath(const QPointF &startPoint) void QPainterPath::detach_helper() { QPainterPathPrivate *data = new QPainterPathData(*d_func()); - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = data; + d_ptr.reset(data); } /*! @@ -544,9 +553,7 @@ void QPainterPath::ensureData_helper() data->elements.reserve(16); QPainterPath::Element e = { 0, 0, QPainterPath::MoveToElement }; data->elements << e; - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = data; + d_ptr.reset(data); Q_ASSERT(d_ptr != 0); } @@ -563,9 +570,7 @@ QPainterPath &QPainterPath::operator=(const QPainterPath &other) QPainterPathPrivate *data = other.d_func(); if (data) data->ref.ref(); - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = data; + d_ptr.reset(data); } return *this; } @@ -575,8 +580,6 @@ QPainterPath &QPainterPath::operator=(const QPainterPath &other) */ QPainterPath::~QPainterPath() { - if (d_func() && !d_func()->ref.deref()) - delete d_func(); } /*! @@ -1299,10 +1302,10 @@ static QRectF qt_painterpath_bezier_extrema(const QBezier &b) qreal bx = QT_BEZIER_B(b, x); qreal cx = QT_BEZIER_C(b, x); // specialcase quadratic curves to avoid div by zero - if (qFuzzyCompare(ax + 1, 1)) { + if (qFuzzyIsNull(ax)) { // linear curves are covered by initialization. - if (!qFuzzyCompare(bx + 1, 1)) { + if (!qFuzzyIsNull(bx)) { qreal t = -cx / bx; QT_BEZIER_CHECK_T(b, t); } @@ -1329,10 +1332,10 @@ static QRectF qt_painterpath_bezier_extrema(const QBezier &b) qreal cy = QT_BEZIER_C(b, y); // specialcase quadratic curves to avoid div by zero - if (qFuzzyCompare(ay + 1, 1)) { + if (qFuzzyIsNull(ay)) { // linear curves are covered by initialization. - if (!qFuzzyCompare(by + 1, 1)) { + if (!qFuzzyIsNull(by)) { qreal t = -cy / by; QT_BEZIER_CHECK_T(b, t); } @@ -1517,12 +1520,6 @@ QList<QPolygonF> QPainterPath::toSubpathPolygons(const QMatrix &matrix) const return toSubpathPolygons(QTransform(matrix)); } -static inline bool rect_intersects(const QRectF &r1, const QRectF &r2) -{ - return qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) - && qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()); -} - /*! Converts the path into a list of polygons using the QTransform \a matrix, and returns the list. @@ -1575,7 +1572,7 @@ QList<QPolygonF> QPainterPath::toFillPolygons(const QTransform &matrix) const continue; QRectF cbounds = bounds.at(j); for (int i=0; i<count; ++i) { - if (rect_intersects(cbounds, bounds.at(i))) { + if (cbounds.intersects(bounds.at(i))) { isects[j] << i; } } @@ -2000,7 +1997,63 @@ bool QPainterPath::intersects(const QRectF &rect) const return false; } +/*! + Translates all elements in the path by (\a{dx}, \a{dy}). + + \since 4.6 + \sa translated() +*/ +void QPainterPath::translate(qreal dx, qreal dy) +{ + if (!d_ptr || (dx == 0 && dy == 0)) + return; + + int elementsLeft = d_ptr->elements.size(); + if (elementsLeft <= 0) + return; + + detach(); + QPainterPath::Element *element = d_func()->elements.data(); + Q_ASSERT(element); + while (elementsLeft--) { + element->x += dx; + element->y += dy; + ++element; + } +} + +/*! + \fn void QPainterPath::translate(const QPointF &offset) + \overload + \since 4.6 + + Translates all elements in the path by the given \a offset. + + \sa translated() +*/ + +/*! + Returns a copy of the path that is translated by (\a{dx}, \a{dy}). + + \since 4.6 + \sa translate() +*/ +QPainterPath QPainterPath::translated(qreal dx, qreal dy) const +{ + QPainterPath copy(*this); + copy.translate(dx, dy); + return copy; +} + +/*! + \fn QPainterPath QPainterPath::translated(const QPointF &offset) const; + \overload + \since 4.6 + + Returns a copy of the path that is translated by the given \a offset. + \sa translate() +*/ /*! \fn bool QPainterPath::contains(const QRectF &rectangle) const @@ -2310,7 +2363,7 @@ QDataStream &operator>>(QDataStream &s, QPainterPath &p) p.d_func()->dirtyControlBounds = true; return s; } -#endif +#endif // QT_NO_DATASTREAM /******************************************************************************* @@ -2340,7 +2393,7 @@ void qt_path_stroke_cubic_to(qfixed c1x, qfixed c1y, /*! \since 4.1 \class QPainterPathStroker - \ingroup multimedia + \ingroup painting \brief The QPainterPathStroker class is used to generate fillable outlines for a given painter path. @@ -2408,7 +2461,6 @@ QPainterPathStroker::QPainterPathStroker() */ QPainterPathStroker::~QPainterPathStroker() { - delete d_ptr; } @@ -2867,7 +2919,7 @@ qreal QPainterPath::angleAtPercent(qreal t) const return QLineF(0, 0, m1, m2).angle(); } -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) #pragma warning( disable : 4056 4756 ) #endif @@ -3100,7 +3152,7 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd) Set operations on paths will treat the paths as areas. Non-closed paths will be treated as implicitly closed. - \sa intersected(), subtracted(), subtractedInverted() + \sa intersected(), subtracted() */ QPainterPath QPainterPath::united(const QPainterPath &p) const { @@ -3215,6 +3267,8 @@ void QPainterPath::setDirty(bool dirty) { d_func()->dirtyBounds = dirty; d_func()->dirtyControlBounds = dirty; + delete d_func()->pathConverter; + d_func()->pathConverter = 0; } void QPainterPath::computeBoundingRect() const @@ -3292,7 +3346,7 @@ QDebug operator<<(QDebug s, const QPainterPath &p) s.nospace() << "QPainterPath: Element count=" << p.elementCount() << endl; const char *types[] = {"MoveTo", "LineTo", "CurveTo", "CurveToData"}; for (int i=0; i<p.elementCount(); ++i) { - s.nospace() << " -> " << types[p.elementAt(i).type] << "(x=" << p.elementAt(i).x << ", y=" << p.elementAt(i).y << ")" << endl; + s.nospace() << " -> " << types[p.elementAt(i).type] << "(x=" << p.elementAt(i).x << ", y=" << p.elementAt(i).y << ')' << endl; } return s; |