4#include "private/qstroker_p.h"
5#include "private/qbezier_p.h"
18 : m_path(
path), m_pos(0) { }
20 inline bool hasNext()
const {
return m_pos < m_path->
size(); }
36 inline bool hasNext()
const {
return m_pos >= 0; }
44 if (m_pos == m_path->
size() - 1) {
68 qWarning(
"QSubpathReverseIterator::next: Case %d unhandled", ce.
type);
85 : m_path(
path), m_pos(0), m_curve_index(-1), m_curve_threshold(threshold) { }
87 inline bool hasNext()
const {
return m_curve_index >= 0 || m_pos < m_path->
size(); }
93 if (m_curve_index >= 0) {
99 if (m_curve_index >= m_curve.
size())
119 e.x = m_curve.
at(0).
x();
120 e.y = m_curve.
at(0).
y();
133 qreal m_curve_threshold;
137 bool capFirst,
QLineF *startTangent);
208 if (
matrix.isIdentity()) {
279 if (
matrix.isIdentity()) {
281 for (
int i=1;
i<pointCount; ++
i)
289 for (
int i=1;
i<pointCount; ++
i) {
311 if (!
matrix.isIdentity()) {
313 for (
int i=0;
i<12; ++
i) {
321 for (
int i=0;
i<12;
i+=3) {
331 : m_capStyle(SquareJoin), m_joinStyle(FlatJoin),
332 m_back1X(0), m_back1Y(0),
333 m_back2X(0), m_back2Y(0),
388 QLineF fwStartTangent, bwStartTangent;
390 bool fwclosed =
qt_stroke_side(&fwit,
this,
false, &fwStartTangent);
391 bool bwclosed =
qt_stroke_side(&bwit,
this, !fwclosed, &bwStartTangent);
393 if (!bwclosed && !fwStartTangent.
isNull())
403#ifdef QPP_STROKE_DEBUG
404 printf(
" -----> joinPoints: around=(%.0f, %.0f), next_p1=(%.0f, %.f) next_p2=(%.0f, %.f)\n",
407 nextLine.
x1(), nextLine.
y1(), nextLine.
x2(), nextLine.
y2());
411#if !defined (QFIXED_26_6) && !defined (Q_FIXED_32_32)
426 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
441 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
487 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
497 qreal sweepLength =
qAbs(l2_on_x - l1_on_x);
507 l1_on_x + 90, -sweepLength,
508 curves, &point_count);
514 for (
int i=0;
i<point_count;
i+=3) {
542 prevLine.
x2(), prevLine.
y2());
566 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
583 Q_ASSERT(!
"QStroker::joinPoints(), bad join style...");
602 const int MAX_OFFSET = 16;
603 QBezier offsetCurves[MAX_OFFSET];
611#ifdef QPP_STROKE_DEBUG
612 qDebug(
" -> (side) [%.2f, %.2f], startPos=%d",
623 while (
it->hasNext()) {
628#ifdef QPP_STROKE_DEBUG
629 qDebug(
"\n ---> (side) lineto [%.2f, %.2f]",
e.x,
e.y);
636 line.translate(normal.
dx(), normal.
dy());
644 *startTangent =
line;
657 }
else if (
e.isCurveTo()) {
661#ifdef QPP_STROKE_DEBUG
662 qDebug(
"\n ---> (side) cubicTo [%.2f, %.2f]",
680 tangent.
translate(offsetCurves[0].pt1() - bezier.
pt1());
691 *startTangent = tangent;
716#ifdef QPP_STROKE_DEBUG
717 qDebug(
"\n ---> (side) closed subpath");
724#ifdef QPP_STROKE_DEBUG
725 qDebug(
"\n ---> (side) open subpath");
791 printf(
"angle: %f, t: %f\n",
angle,
t);
793 bezierCoefficients(
t,
a,
b,
c,
d);
794 printf(
"cosAngle: %.10f, value: %.10f\n", cosAngle,
a +
b +
c *
QT_PATH_KAPPA);
795 printf(
"sinAngle: %.10f, value: %.10f\n", sinAngle,
b *
QT_PATH_KAPPA +
c +
d);
817 QPointF *curves,
int *point_count)
825 qWarning(
"QPainterPath::arcTo: Adding arc where a parameter is NaN, results are undefined");
870 if (sweepLength > 360) sweepLength = 360;
871 else if (sweepLength < -360) sweepLength = -360;
874 if (startAngle == 0.0) {
875 if (sweepLength == 360.0) {
876 for (
int i = 11;
i >= 0; --
i)
877 curves[(*point_count)++] =
points[
i];
879 }
else if (sweepLength == -360.0) {
880 for (
int i = 1;
i <= 12; ++
i)
881 curves[(*point_count)++] =
points[
i];
887 int endSegment = int(
qFloor((startAngle + sweepLength) / 90));
890 qreal endT = (startAngle + sweepLength - endSegment * 90) / 90;
892 int delta = sweepLength > 0 ? 1 : -1;
916 const int end = endSegment + delta;
921 const int j = 3 * quadrant;
929 const int quadrant = 3 - ((
i % 4) + 4) % 4;
930 const int j = 3 * quadrant;
943 if (
i == endSegment && splitAtEnd)
944 b =
b.bezierOnInterval(startT, endT);
945 else if (splitAtStart)
946 b =
b.bezierOnInterval(startT, 1);
947 }
else if (
i == endSegment && splitAtEnd) {
948 b =
b.bezierOnInterval(0, endT);
952 curves[(*point_count)++] =
b.pt2();
953 curves[(*point_count)++] =
b.pt3();
954 curves[(*point_count)++] =
b.pt4();
958 curves[*(point_count)-1] = endPoint;
982 : m_stroker(stroker), m_dashOffset(0), m_stroke_width(1), m_miter_limit(1)
1025 return ((
p1.x > tl.
x ||
p2.x > tl.
x) && (
p1.x < br.
x ||
p2.x < br.
x)
1026 && (
p1.y > tl.
y ||
p2.y > tl.
y) && (
p1.y < br.
y ||
p2.y < br.
y));
1044 u.
x = tl.
x -
p1.x; u.
y = br.
y -
p1.y;
1045 v.x = br.
x -
p1.x;
v.y = tl.
y -
p1.y;
1048 u.
x = tl.
x -
p1.x; u.
y = tl.
y -
p1.y;
1049 v.x = br.
x -
p1.x;
v.y = br.
y -
p1.y;
1051#if defined(QFIXED_IS_26_6) || defined(QFIXED_IS_16_16)
1054 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0);
1055#elif defined(QFIXED_IS_32_32)
1061 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0);
1076 qreal longestLength = 0;
1077 qreal sumLength = 0;
1080 sumLength += dashes[
i];
1081 if (dashes[
i] > longestLength)
1082 longestLength = dashes[
i];
1100 doffset = std::fmod(doffset, sumLength);
1102 doffset += sumLength;
1104 while (doffset >= dashes[idash]) {
1105 doffset -= dashes[idash];
1131 bool hasMoveTo =
false;
1132 while (
it.hasNext()) {
1144 estop = estart + elen;
1152 if (skipDashing || clipIt) {
1154 elen -= std::floor(elen * invSumLength) * sumLength;
1157 qreal dpos =
pos + dashes[idash] - doffset - estart;
1162 doffset = dashes[idash] - (dpos - elen);
1166 pos = --maxDashes > 0 ? dpos + estart : estop;
1190 bool has_offset = doffset > 0;
1191 bool evenDash = (idash & 1) == 0;
1192 qreal dpos =
pos + dashes[idash] - doffset - estart;
1197 doffset = dashes[idash] - (dpos - elen);
1203 pos = dpos + estart;
1221 if (!has_offset || !hasMoveTo) {
1230 move_to_pos = line_to_pos;
static QBezier fromPoints(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
QPolygonF toPolygon(qreal bezier_flattening_threshold=0.5) const
QLineF startTangent() const
int shifted(QBezier *curveSegments, int maxSegmets, qreal offset, float threshold) const
void processCurrentSubpath() override
QDashStroker(QStroker *stroker)
QList< qfixed > m_dashPattern
static int repetitionLimit()
static QList< qfixed > patternForStyle(Qt::PenStyle style)
constexpr QPointF p1() const
Returns the line's start point.
constexpr qreal x1() const
Returns the x-coordinate of the line's start point.
constexpr bool isNull() const
Returns true if the line does not have distinct start and end points; otherwise returns false.
constexpr qreal y2() const
Returns the y-coordinate of the line's end point.
void translate(const QPointF &p)
Translates this line by the given offset.
constexpr qreal dx() const
Returns the horizontal component of the line's vector.
constexpr qreal dy() const
Returns the vertical component of the line's vector.
qreal angleTo(const QLineF &l) const
qreal length() const
Returns the length of the line.
IntersectionType
\typealias QLineF::IntersectType
IntersectionType intersects(const QLineF &l, QPointF *intersectionPoint=nullptr) const
constexpr qreal x2() const
Returns the x-coordinate of the line's end point.
constexpr QPointF p2() const
Returns the line's end point.
constexpr QPointF pointAt(qreal t) const
Returns the point at the position specified by finite parameter t.
void setLength(qreal len)
Sets the length of the line to the given finite length.
constexpr qreal y1() const
Returns the y-coordinate of the line's start point.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
static constexpr qreal dotProduct(const QPointF &p1, const QPointF &p2)
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
The QPolygonF class provides a list of points using floating point precision.
\inmodule QtCore\reentrant
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
virtual void begin(void *customData)
Prepares the stroker.
void setCubicToHook(qStrokerCubicToHook cubicToHook)
void moveTo(qfixed x, qfixed y)
void setMoveToHook(qStrokerMoveToHook moveToHook)
void setCurveThresholdFromTransform(const QTransform &transform)
void strokeEllipse(const QRectF &ellipse, void *data, const QTransform &matrix)
Convenience function for stroking an ellipse with bounding rect rect.
void strokePath(const QPainterPath &path, void *data, const QTransform &matrix)
Convenience function that decomposes path into begin(), moveTo(), lineTo(), curevTo() and end() calls...
void setLineToHook(qStrokerLineToHook lineToHook)
QDataBuffer< Element > m_elements
void cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey)
void strokePolygon(const QPointF *points, int pointCount, bool implicit_close, void *data, const QTransform &matrix)
Convenience function for stroking a polygon of the pointCount first points in points.
void emitLineTo(qfixed x, qfixed y)
virtual void end()
Finishes the stroke.
void emitMoveTo(qfixed x, qfixed y)
qfixed curveThreshold() const
void lineTo(qfixed x, qfixed y)
virtual void processCurrentSubpath()=0
qfixed strokeWidth() const
void emitLineTo(qfixed x, qfixed y)
static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode)
void processCurrentSubpath() override
This function is called to stroke the currently built up subpath.
static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle)
LineJoinMode capStyleMode() const
qfixed miterLimit() const
void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join)
Qt::PenJoinStyle joinStyle() const
void emitMoveTo(qfixed x, qfixed y)
LineJoinMode joinStyleMode() const
static LineJoinMode joinModeForCap(Qt::PenCapStyle)
static Qt::PenCapStyle capForJoinMode(LineJoinMode mode)
void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey)
QStrokerOps::Element next()
QSubpathBackwardIterator(const QDataBuffer< QStrokerOps::Element > *path)
QSubpathFlatIterator(const QDataBuffer< QStrokerOps::Element > *path, qreal threshold)
QStrokerOps::Element next()
QStrokerOps::Element next()
QSubpathForwardIterator(const QDataBuffer< QStrokerOps::Element > *path)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
constexpr float qDegreesToRadians(float degrees)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
static Q_DECL_CONST_FUNCTION bool qt_is_nan(double d)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLfloat GLfloat GLfloat GLfloat h
GLfixed GLfixed GLint GLint GLfixed points
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
GLsizei const GLchar *const * path
static qreal dot(const QPointF &a, const QPointF &b)
static void qdashstroker_moveTo(qfixed x, qfixed y, void *data)
Q_GUI_EXPORT void qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length, QPointF *startPoint, QPointF *endPoint)
qreal qt_t_for_arc_angle(qreal angle)
static void qdashstroker_cubicTo(qfixed, qfixed, qfixed, qfixed, qfixed, qfixed, void *)
static bool lineIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br)
static qreal adapted_angle_on_x(const QLineF &line)
bool qt_stroke_side(Iterator *it, QStroker *stroker, bool capFirst, QLineF *startTangent)
QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength, QPointF *curves, int *point_count)
static void qdashstroker_lineTo(qfixed x, qfixed y, void *data)
static bool lineRectIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br)
QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength, QPointF *controlPoints, int *point_count)
#define qt_fixed_to_real(fixed)
#define qt_real_to_fixed(real)
QT_BEGIN_NAMESPACE typedef qreal qfixed
QPainterPath::ElementType type