⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qpainterpath.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            }            return;        }        // split curve and try again...        QBezier first_half, second_half;        bezier.split(&first_half, &second_half);        qt_painterpath_isect_curve(first_half, pt, winding);        qt_painterpath_isect_curve(second_half, pt, winding);    }}/*!    \fn bool QPainterPath::contains(const QPointF &point) const    Returns true if the given \a point is inside the path, otherwise    returns false.    \sa intersects()*/bool QPainterPath::contains(const QPointF &pt) const{    if (isEmpty())        return false;    QPainterPathData *d = d_func();    int winding_number = 0;    QPointF last_pt;    QPointF last_start;    for (int i=0; i<d->elements.size(); ++i) {        const Element &e = d->elements.at(i);        switch (e.type) {        case MoveToElement:            if (i > 0) // implicitly close all paths.                qt_painterpath_isect_line(last_pt, last_start, pt, &winding_number);            last_start = last_pt = e;            break;        case LineToElement:            qt_painterpath_isect_line(last_pt, e, pt, &winding_number);            last_pt = e;            break;        case CurveToElement:            {                const QPainterPath::Element &cp2 = d->elements.at(++i);                const QPainterPath::Element &ep = d->elements.at(++i);                qt_painterpath_isect_curve(QBezier::fromPoints(last_pt, e, cp2, ep),                                           pt, &winding_number);                last_pt = ep;            }            break;        default:            break;        }    }    // implicitly close last subpath    if (last_pt != last_start)        qt_painterpath_isect_line(last_pt, last_start, pt, &winding_number);    return (d->fillRule == Qt::WindingFill            ? (winding_number != 0)            : ((winding_number % 2) != 0));}static bool qt_painterpath_isect_line_rect(qreal x1, qreal y1, qreal x2, qreal y2,                                           const QRectF &rect){    qreal left = rect.left();    qreal right = rect.right();    qreal top = rect.top();    qreal bottom = rect.bottom();    enum { Left, Right, Top, Bottom };    // clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html    int p1 = ((x1 < left) << Left)             | ((x1 > right) << Right)             | ((y1 < top) << Top)             | ((y1 > bottom) << Bottom);    int p2 = ((x2 < left) << Left)             | ((x2 > right) << Right)             | ((y2 < top) << Top)             | ((y2 > bottom) << Bottom);    if (p1 & p2)        // completely inside        return false;    if (p1 | p2) {        qreal dx = x2 - x1;        qreal dy = y2 - y1;        // clip x coordinates        if (x1 < left) {            y1 += dy/dx * (left - x1);            x1 = left;        } else if (x1 > right) {            y1 -= dy/dx * (x1 - right);            x1 = right;        }        if (x2 < left) {            y2 += dy/dx * (left - x2);            x2 = left;        } else if (x2 > right) {            y2 -= dy/dx * (x2 - right);            x2 = right;        }        p1 = ((y1 < top) << Top)             | ((y1 > bottom) << Bottom);        p2 = ((y2 < top) << Top)             | ((y2 > bottom) << Bottom);        if (p1 & p2)            return false;        // clip y coordinates        if (y1 < top) {            x1 += dx/dy * (top - y1);            y1 = top;        } else if (y1 > bottom) {            x1 -= dx/dy * (y1 - bottom);            y1 = bottom;        }        if (y2 < top) {            x2 += dx/dy * (top - y2);            y2 = top;        } else if (y2 > bottom) {            x2 -= dx/dy * (y2 - bottom);            y2 = bottom;        }        p1 = ((x1 < left) << Left)             | ((x1 > right) << Right);        p2 = ((x2 < left) << Left)             | ((x2 > right) << Right);        if (p1 & p2)            return false;        return true;    }    return false;}static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1, qreal x2){    QRectF bounds = bezier.bounds();    if (y >= bounds.top() && y < bounds.bottom()        && bounds.right() >= x1 && bounds.left() < x2) {        const qreal lower_bound = .01;        if (bounds.width() < lower_bound && bounds.height() < lower_bound)            return true;        QBezier first_half, second_half;        bezier.split(&first_half, &second_half);        if (qt_isect_curve_horizontal(first_half, y, x1, x2)            || qt_isect_curve_horizontal(second_half, y, x1, x2))            return true;    }    return false;}static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qreal y2){    QRectF bounds = bezier.bounds();    if (x >= bounds.left() && x < bounds.right()        && bounds.bottom() >= y1 && bounds.top() < y2) {        const qreal lower_bound = .01;        if (bounds.width() < lower_bound && bounds.height() < lower_bound)            return true;        QBezier first_half, second_half;        bezier.split(&first_half, &second_half);        if (qt_isect_curve_vertical(first_half, x, y1, y2)            || qt_isect_curve_vertical(second_half, x, y1, y2))            return true;    }     return false;}/*    Returns true if any lines or curves cross the four edges in of rect*/static bool qt_painterpath_check_crossing(const QPainterPath *path, const QRectF &rect){    QPointF last_pt;    QPointF last_start;    for (int i=0; i<path->elementCount(); ++i) {        const QPainterPath::Element &e = path->elementAt(i);        switch (e.type) {        case QPainterPath::MoveToElement:            if (i > 0                && qFuzzyCompare(last_pt.x(), last_start.y())                && qFuzzyCompare(last_pt.y(), last_start.y())                && qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(),                                                  last_start.x(), last_start.y(), rect))                return true;            last_start = last_pt = e;            break;        case QPainterPath::LineToElement:            if (qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(), e.x, e.y, rect))                return true;            last_pt = e;            break;        case QPainterPath::CurveToElement:            {                QPointF cp2 = path->elementAt(++i);                QPointF ep = path->elementAt(++i);                QBezier bezier = QBezier::fromPoints(last_pt, e, cp2, ep);                if (qt_isect_curve_horizontal(bezier, rect.top(), rect.left(), rect.right())                    || qt_isect_curve_horizontal(bezier, rect.bottom(), rect.left(), rect.right())                    || qt_isect_curve_vertical(bezier, rect.left(), rect.top(), rect.bottom())                    || qt_isect_curve_vertical(bezier, rect.right(), rect.top(), rect.bottom()))                    return true;                last_pt = ep;            }            break;        default:            break;        }    }    // implicitly close last subpath    if (last_pt != last_start        && qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(),                                          last_start.x(), last_start.y(), rect))        return true;    return false;}/*!    \fn bool QPainterPath::intersects(const QRectF &rectangle) const    Returns true if any point in the given \a rectangle intersects the    path; otherwise returns false.    There is an intersection if any of the lines making up the    rectangle crosses a part of the path or if any part of the    rectangle overlaps with any area enclosed by the path. This    function respects the current fillRule to determine what is    considered inside the path.    \sa contains()*/bool QPainterPath::intersects(const QRectF &rect) const{    if (isEmpty() || !controlPointRect().intersects(rect))        return false;    // If any path element cross the rect its bound to be an intersection    if (qt_painterpath_check_crossing(this, rect))        return true;    if (contains(rect.center()))        return true;    Q_D(QPainterPath);    // Check if the rectangle surounds any subpath...    for (int i=0; i<d->elements.size(); ++i) {        const Element &e = d->elements.at(i);        if (e.type == QPainterPath::MoveToElement && rect.contains(e))            return true;    }    return false;}/*!    \fn bool QPainterPath::contains(const QRectF &rectangle) const    \overload    Returns true if the given \a rectangle is inside the path,    otherwise returns false.*/bool QPainterPath::contains(const QRectF &rect) const{    Q_D(QPainterPath);    // the path is empty or the control point rect doesn't completely    // cover the rectangle we abort stratight away.    if (isEmpty() || !controlPointRect().contains(rect))        return false;    // if there are intersections, chances are that the rect is not    // contained, except if we have winding rule, in which case it    // still might.    if (qt_painterpath_check_crossing(this, rect)) {        if (fillRule() == Qt::OddEvenFill) {            return false;        } else {            // Do some wague sampling in the winding case. This is not            // precise but it should mostly be good enough.            if (!contains(rect.topLeft()) ||                !contains(rect.topRight()) ||                !contains(rect.bottomRight()) ||                !contains(rect.bottomLeft()))                return false;        }    }    // If there exists a point inside that is not part of the path its    // because: rectangle lies completely outside path or a subpath    // excludes parts of the rectangle. Both cases mean that the rect    // is not contained    if (!contains(rect.center()))        return false;    // If there are any subpaths inside this rectangle we need to    // check if they are still contained as a result of the fill    // rule. This can only be the case for WindingFill though. For    // OddEvenFill the rect will never be contained if it surrounds a    // subpath. (the case where two subpaths are completely identical    // can be argued but we choose to neglect it).    for (int i=0; i<d->elements.size(); ++i) {        const Element &e = d->elements.at(i);        if (e.type == QPainterPath::MoveToElement && rect.contains(e)) {            if (fillRule() == Qt::OddEvenFill)                return false;            bool stop = false;            for (; !stop && i<d->elements.size(); ++i) {                const Element &el = d->elements.at(i);                switch (el.type) {                case MoveToElement:                    stop = true;                    break;                case LineToElement:                    if (!contains(el))                        return false;                    break;                case CurveToElement:                    if (!contains(d->elements.at(i+2)))                        return false;                    i += 2;                    break;                default:                    break;                }            }            // compensate for the last ++i in the inner for            --i;        }    }    return true;}/*!    Returns true if this painterpath is equal to the given \a path.    Note that comparing paths may involve a per element comparison    which can be slow for complex paths.    \sa operator!=()*/bool QPainterPath::operator==(const QPainterPath &path) const{    QPainterPathData *d = reinterpret_cast<QPainterPathData *>(d_func());    if (path.d_func() == d)        return true;    else if (!d || !path.d_func())        return false;    bool equal = d->fillRule == path.d_func()->fillRule && d->elements.size() == path.d_func()->elements.size();    for (int i = 0; i < d->elements.size() && equal; ++i)        equal = d->elements.at(i) == path.d_func()->elements.at(i);    return equal;}/*!    Returns true if this painter path differs from the given \a path.    Note that comparing paths may involve a per element comparison    which can be slow for complex paths.    \sa operator==()*/bool QPainterPath::operator!=(const QPainterPath &path) const{    return !(*this==path);}#ifndef QT_NO_DATASTREAM/*!    \fn QDataStream &operator<<(QDataStream &stream, const QPainterPath &path)    \relates QPainterPath    Writes the given painter \a path to the given \a stream, and    returns a reference to the \a stream.    \sa {Format of the QDataStream Operators}*/QDataStream &operator<<(QDataStream &s, const QPainterPath &p){    if (p.isEmpty()) {        s << 0;        return s;    }    s << p.elementCount();    for (int i=0; i < p.d_func()->elements.size(); ++i) {        const QPainterPath::Element &e = p.d_func()->elements.at(i);        s << int(e.type);        s << double(e.x) << double(e.y);    }    s << p.d_func()->cStart;    s << int(p.d_func()->fillRule);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -