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

📄 qstroker.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                if (first) {                    QPointF pt = offsetCurves[0].pt1();                    if (capFirst) {                        stroker->joinPoints(prev.x, prev.y,                                            tangent,                                            stroker->capStyleMode());                    } else {                        stroker->emitMoveTo(qt_real_to_fixed(pt.x()),                                            qt_real_to_fixed(pt.y()));                    }                    *startTangent = tangent;                    first = false;                } else {                    stroker->joinPoints(prev.x, prev.y,                                        tangent,                                        stroker->joinStyleMode());                }                // Add these beziers                for (int i=0; i<count; ++i) {                    QPointF cp1 = offsetCurves[i].pt2();                    QPointF cp2 = offsetCurves[i].pt3();                    QPointF ep = offsetCurves[i].pt4();                    stroker->emitCubicTo(qt_real_to_fixed(cp1.x()), qt_real_to_fixed(cp1.y()),                                         qt_real_to_fixed(cp2.x()), qt_real_to_fixed(cp2.y()),                                         qt_real_to_fixed(ep.x()), qt_real_to_fixed(ep.y()));                }            }            prev = ep;        }    }    if (start == prev) {        // closed subpath, join first and last point#ifdef QPP_STROKE_DEBUG        qDebug("\n ---> (side) closed subpath");#endif        stroker->joinPoints(prev.x, prev.y, *startTangent, stroker->joinStyleMode());        return true;    } else {#ifdef QPP_STROKE_DEBUG        qDebug("\n ---> (side) open subpath");#endif        return false;    }}/*!    \internal    Creates a number of curves for a given arc definition. The arc is    defined an arc along the ellipses that fits into \a rect starting    at \a startAngle and an arc length of \a sweepLength.    The function has three out parameters. The return value is the    starting point of the arc. The \a curves array represents the list    of cubicTo elements up to a maximum of \a point_count. There are of course    3 points pr curve.*/QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength,                       QPointF *curves, int *point_count){    Q_ASSERT(point_count);    Q_ASSERT(curves);#ifndef QT_NO_DEBUG    if (qt_is_nan(rect.x()) || qt_is_nan(rect.y()) || qt_is_nan(rect.width()) || qt_is_nan(rect.height())        || qt_is_nan(startAngle) || qt_is_nan(sweepLength))        qWarning("QPainterPath::arcTo: Adding arc where a parameter is NaN, results are undefined");#endif    *point_count = 0;    if (rect.isNull()) {        return QPointF();    }    if (sweepLength > 360) sweepLength = 360;    else if (sweepLength < -360) sweepLength = -360;    // Special case fast path    if (startAngle == 0.0 && sweepLength == 360.0) {        qreal x = rect.x();        qreal y = rect.y();        qreal w = rect.width();        qreal w2 = rect.width() / 2;        qreal w2k = w2 * QT_PATH_KAPPA;        qreal h = rect.height();        qreal h2 = rect.height() / 2;        qreal h2k = h2 * QT_PATH_KAPPA;        // 0 -> 270 degrees        curves[(*point_count)++] = QPointF(x + w, y + h2 + h2k);        curves[(*point_count)++] = QPointF(x + w2 + w2k, y + h);        curves[(*point_count)++] = QPointF(x + w2, y + h);        // 270 -> 180 degrees        curves[(*point_count)++] = QPointF(x + w2 - w2k, y + h);        curves[(*point_count)++] = QPointF(x, y + h2 + h2k);        curves[(*point_count)++] = QPointF(x, y + h2);        // 180 -> 90 degrees        curves[(*point_count)++] = QPointF(x, y + h2 - h2k);        curves[(*point_count)++] = QPointF(x + w2 - w2k, y);        curves[(*point_count)++] = QPointF(x + w2, y);        // 90 -> 0 degrees        curves[(*point_count)++] = QPointF(x + w2 + w2k, y);        curves[(*point_count)++] = QPointF(x + w, y + h2 - h2k);        curves[(*point_count)++] = QPointF(x + w, y + h2);        return QPointF(x + w, y + h2);    }#define ANGLE(t) ((t) * 2 * Q_PI / 360.0)#define SIGN(t) (t > 0 ? 1 : -1)    qreal a = rect.width() / 2.0;    qreal b = rect.height() / 2.0;    qreal absSweepLength = (sweepLength < 0 ? -sweepLength : sweepLength);    int iterations = qCeil((absSweepLength) / qreal(90.0));    QPointF first_point;    if (iterations == 0) {        first_point = rect.center() + QPointF(a * qCos(ANGLE(startAngle)),                                              -b * qSin(ANGLE(startAngle)));    } else {        qreal clength = sweepLength / iterations;        qreal cosangle1, sinangle1, cosangle2, sinangle2;        for (int i=0; i<iterations; ++i) {            qreal cangle = startAngle + i * clength;            cosangle1 = qCos(ANGLE(cangle));            sinangle1 = qSin(ANGLE(cangle));            cosangle2 = qCos(ANGLE(cangle + clength));            sinangle2 = qSin(ANGLE(cangle + clength));            // Find the start and end point of the curve.            QPointF startPoint = rect.center() + QPointF(a * cosangle1, -b * sinangle1);            QPointF endPoint = rect.center() + QPointF(a * cosangle2, -b * sinangle2);            // The derived at the start and end point.            qreal sdx = -a * sinangle1;            qreal sdy = -b * cosangle1;            qreal edx = -a * sinangle2;            qreal edy = -b * cosangle2;            // Creating the tangent lines. We need to reverse their direction if the            // sweep is negative (clockwise)            QLineF controlLine1(startPoint, startPoint + SIGN(sweepLength) * QPointF(sdx, sdy));            QLineF controlLine2(endPoint, endPoint - SIGN(sweepLength) * QPointF(edx, edy));            // We need to scale down the control lines to match that of the current sweeplength.            // qAbs because we only want to scale, not change direction.            qreal kappa = QT_PATH_KAPPA * qAbs(clength) / 90.0;            // Adjust their length to fit the magic KAPPA length.            controlLine1.setLength(controlLine1.length() * kappa);            controlLine2.setLength(controlLine2.length() * kappa);            curves[(*point_count)++] = controlLine1.p2();            curves[(*point_count)++] = controlLine2.p2();            curves[(*point_count)++] = endPoint;            if (i == 0)                first_point = startPoint;        }    }    return first_point;}/******************************************************************************* * QDashStroker members */QDashStroker::QDashStroker(QStroker *stroker)    : m_stroker(stroker), m_dashOffset(0){}QVector<qfixed> QDashStroker::patternForStyle(Qt::PenStyle style){    const qfixed space = 2;    const qfixed dot = 1;    const qfixed dash = 4;    QVector<qfixed> pattern;    switch (style) {    case Qt::DashLine:        pattern << dash << space;        break;    case Qt::DotLine:        pattern << dot << space;        break;    case Qt::DashDotLine:        pattern << dash << space << dot << space;        break;    case Qt::DashDotDotLine:        pattern << dash << space << dot << space << dot << space;        break;    default:        break;    }    return pattern;}void QDashStroker::processCurrentSubpath(){    int dashCount = qMin(m_dashPattern.size(), 32);    qfixed dashes[32];    qreal sumLength = 0;    for (int i=0; i<dashCount; ++i) {        dashes[i] = qMax(m_dashPattern.at(i), qreal(0)) * m_stroker->strokeWidth();        sumLength += dashes[i];    }    if (qFuzzyCompare(sumLength, qreal(0)))        return;    Q_ASSERT(dashCount > 0);    dashCount = (dashCount / 2) * 2; // Round down to even number    int idash = 0; // Index to current dash    qreal pos = 0; // The position on the curve, 0 <= pos <= path.length    qreal elen = 0; // element length    qreal doffset = m_dashOffset * m_stroker->strokeWidth();    // make sure doffset is in range [0..sumLength)    doffset -= qFloor(doffset / sumLength) * sumLength;    while (doffset >= dashes[idash]) {        doffset -= dashes[idash];        idash = (idash + 1) % dashCount;    }    qreal estart = 0; // The elements starting position    qreal estop = 0; // The element stop position    QLineF cline;    QPainterPath dashPath;    QSubpathFlatIterator it(&m_elements);    qfixed2d prev = it.next();    bool clipping = !m_clip_rect.isEmpty();    qfixed2d move_to_pos = prev;    qfixed2d line_to_pos;    // Pad to avoid clipping the borders of thick pens.    qfixed padding = qMax(m_stroker->strokeWidth(), m_stroker->miterLimit());    qfixed2d clip_tl = { qt_real_to_fixed(m_clip_rect.left()) - padding,                         qt_real_to_fixed(m_clip_rect.top()) - padding };    qfixed2d clip_br = { qt_real_to_fixed(m_clip_rect.right()) + padding ,                         qt_real_to_fixed(m_clip_rect.bottom()) + padding };    bool hasMoveTo = false;    while (it.hasNext()) {        QStrokerOps::Element e = it.next();        Q_ASSERT(e.isLineTo());        cline = QLineF(qt_fixed_to_real(prev.x),                       qt_fixed_to_real(prev.y),                       qt_fixed_to_real(e.x),                       qt_fixed_to_real(e.y));        elen = cline.length();        estop = estart + elen;        // Dash away...        while (pos < estop) {            QPointF p2;            int idash_incr = 0;            bool has_offset = doffset > 0;            qreal dpos = pos + dashes[idash] - doffset - estart;            Q_ASSERT(dpos >= 0);            if (dpos > elen) { // dash extends this line                doffset = dashes[idash] - (dpos - elen); // subtract the part already used                pos = estop; // move pos to next path element                p2 = cline.p2();            } else { // Dash is on this line                p2 = cline.pointAt(dpos/elen);                pos = dpos + estart;                idash_incr = 1;                doffset = 0; // full segment so no offset on next.            }            if (idash % 2 == 0) {                line_to_pos.x = qt_real_to_fixed(p2.x());                line_to_pos.y = qt_real_to_fixed(p2.y());                // If we have an offset, we're continuing a dash                // from a previous element and should only                // continue the current dash, without starting a                // new subpath.                if (!has_offset || !hasMoveTo) {                    m_stroker->moveTo(move_to_pos.x, move_to_pos.y);                    hasMoveTo = true;                }                if (!clipping                    // if move_to is inside...                    || (move_to_pos.x > clip_tl.x && move_to_pos.x < clip_br.x                     && move_to_pos.y > clip_tl.y && move_to_pos.y < clip_br.y)                    // Or if line_to is inside...                    || (line_to_pos.x > clip_tl.x && line_to_pos.x < clip_br.x                     && line_to_pos.y > clip_tl.y && line_to_pos.y < clip_br.y))                {                    m_stroker->lineTo(line_to_pos.x, line_to_pos.y);                }            } else {                move_to_pos.x = qt_real_to_fixed(p2.x());                move_to_pos.y = qt_real_to_fixed(p2.y());            }            idash = (idash + idash_incr) % dashCount;        }        // Shuffle to the next cycle...        estart = estop;        prev = e;    }}

⌨️ 快捷键说明

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