42 #include "private/qstroker_p.h" 43 #include "private/qbezier_p.h" 44 #include "private/qmath_p.h" 107 qWarning(
"QSubpathReverseIterator::next: Case %d unhandled", ce.
type);
124 :
m_path(path),
m_pos(0), m_curve_index(-1), m_curve_threshold(threshold) { }
132 if (m_curve_index >= 0) {
138 if (m_curve_index >= m_curve.size())
158 e.
x = m_curve.at(0).x();
159 e.
y = m_curve.at(0).y();
176 bool capFirst,
QLineF *startTangent);
251 for (
int i=0; i<count; ++i) {
274 for (
int i=0; i<count; ++i) {
323 for (
int i=1; i<pointCount; ++i)
329 QPointF start = points[0] * matrix;
331 for (
int i=1; i<pointCount; ++i) {
332 QPointF pt = points[i] * matrix;
354 start = start * matrix;
355 for (
int i=0; i<12; ++i) {
356 pts[i] = pts[i] * matrix;
363 for (
int i=0; i<12; i+=3) {
373 : m_capStyle(SquareJoin), m_joinStyle(FlatJoin),
374 m_back1X(0), m_back1Y(0),
375 m_back2X(0), m_back2Y(0)
429 QLineF fwStartTangent, bwStartTangent;
431 bool fwclosed =
qt_stroke_side(&fwit,
this,
false, &fwStartTangent);
432 bool bwclosed =
qt_stroke_side(&bwit,
this, !fwclosed, &bwStartTangent);
444 #ifdef QPP_STROKE_DEBUG 445 printf(
" -----> joinPoints: around=(%.0f, %.0f), next_p1=(%.0f, %.f) next_p2=(%.0f, %.f)\n",
448 nextLine.
x1(), nextLine.
y1(), nextLine.
x2(), nextLine.
y2());
452 #if !defined (QFIXED_26_6) && !defined (Q_FIXED_32_32) 467 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
488 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
530 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
540 qreal sweepLength =
qAbs(l2_on_x - l1_on_x);
550 l1_on_x + 90, -sweepLength,
551 curves, &point_count);
557 for (
int i=0; i<point_count; i+=3) {
581 prevLine.
x2(), prevLine.
y2());
593 l2 =
QLineF(l2.x1(), l2.y1(), l2.x1()-l2.dx(), l2.y1()-l2.dy());
605 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
622 Q_ASSERT(!
"QStroker::joinPoints(), bad join style...");
641 const int MAX_OFFSET = 16;
642 QBezier offsetCurves[MAX_OFFSET];
650 #ifdef QPP_STROKE_DEBUG 651 qDebug(
" -> (side) [%.2f, %.2f], startPos=%d",
662 while (it->hasNext()) {
667 #ifdef QPP_STROKE_DEBUG 668 qDebug(
"\n ---> (side) lineto [%.2f, %.2f]", e.
x, e.
y);
672 if (line.
p1() != line.
p2()) {
683 *startTangent = line;
700 #ifdef QPP_STROKE_DEBUG 701 qDebug(
"\n ---> (side) cubicTo [%.2f, %.2f]",
712 int count = bezier.
shifted(offsetCurves,
720 tangent.
translate(offsetCurves[0].pt1() - bezier.
pt1());
731 *startTangent = tangent;
740 for (
int i=0; i<count; ++i) {
756 #ifdef QPP_STROKE_DEBUG 757 qDebug(
"\n ---> (side) closed subpath");
764 #ifdef QPP_STROKE_DEBUG 765 qDebug(
"\n ---> (side) open subpath");
809 qreal tc = angle / 90;
828 qreal t = 0.5 * (tc + ts);
831 printf(
"angle: %f, t: %f\n", angle, t);
833 bezierCoefficients(t, a, b, c, d);
834 printf(
"cosAngle: %.10f, value: %.10f\n", cosAngle, a + b + c *
QT_PATH_KAPPA);
835 printf(
"sinAngle: %.10f, value: %.10f\n", sinAngle, b * QT_PATH_KAPPA + c + d);
860 QPointF *curves,
int *point_count)
868 qWarning(
"QPainterPath::arcTo: Adding arc where a parameter is NaN, results are undefined");
913 if (sweepLength > 360) sweepLength = 360;
914 else if (sweepLength < -360) sweepLength = -360;
917 if (startAngle == 0.0) {
918 if (sweepLength == 360.0) {
919 for (
int i = 11; i >= 0; --i)
920 curves[(*point_count)++] = points[i];
922 }
else if (sweepLength == -360.0) {
923 for (
int i = 1; i <= 12; ++i)
924 curves[(*point_count)++] = points[i];
929 int startSegment = int(
qFloor(startAngle / 90));
930 int endSegment = int(
qFloor((startAngle + sweepLength) / 90));
932 qreal startT = (startAngle - startSegment * 90) / 90;
933 qreal endT = (startAngle + sweepLength - endSegment * 90) / 90;
935 int delta = sweepLength > 0 ? 1 : -1;
944 startSegment += delta;
959 const int end = endSegment + delta;
962 if (startSegment == end) {
963 const int quadrant = 3 - ((startSegment % 4) + 4) % 4;
964 const int j = 3 * quadrant;
965 return delta > 0 ? points[j + 3] : points[j];
971 for (
int i = startSegment; i !=
end; i += delta) {
972 const int quadrant = 3 - ((i % 4) + 4) % 4;
973 const int j = 3 * quadrant;
982 if (startSegment == endSegment &&
qFuzzyCompare(startT, endT))
985 if (i == startSegment) {
986 if (i == endSegment && splitAtEnd)
988 else if (splitAtStart)
990 }
else if (i == endSegment && splitAtEnd) {
995 curves[(*point_count)++] = b.
pt2();
996 curves[(*point_count)++] = b.
pt3();
997 curves[(*point_count)++] = b.
pt4();
1001 curves[*(point_count)-1] = endPoint;
1025 : m_stroker(stroker), m_dashOffset(0), m_stroke_width(1), m_miter_limit(1)
1044 pattern << dash << space;
1047 pattern << dot << space;
1050 pattern << dash << space << dot << space;
1053 pattern << dash << space << dot << space << dot << space;
1064 return ((p1.
x > tl.
x || p2.
x > tl.
x) && (p1.
x < br.
x || p2.
x < br.
x)
1065 && (p1.
y > tl.
y || p2.
y > tl.
y) && (p1.
y < br.
y || p2.
y < br.
y));
1073 if (p1.
x == p2.
x || p1.
y == p2.
y)
1083 u.
x = tl.
x - p1.
x; u.
y = br.
y - p1.
y;
1084 v.
x = br.
x - p1.
x; v.
y = tl.
y - p1.
y;
1087 u.
x = tl.
x - p1.
x; u.
y = tl.
y - p1.
y;
1088 v.
x = br.
x - p1.
x; v.
y = br.
y - p1.
y;
1090 #if defined(QFIXED_IS_26_6) || defined(QFIXED_IS_16_16) 1093 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0);
1094 #elif defined(QFIXED_IS_32_32) 1100 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0);
1115 qreal longestLength = 0;
1116 qreal sumLength = 0;
1117 for (
int i=0; i<dashCount; ++i) {
1119 sumLength += dashes[i];
1120 if (dashes[i] > longestLength)
1121 longestLength = dashes[i];
1131 dashCount = dashCount & -2;
1139 doffset -=
qFloor(doffset * invSumLength) * sumLength;
1141 while (doffset >= dashes[idash]) {
1142 doffset -= dashes[idash];
1143 if (++idash >= dashCount)
1168 bool hasMoveTo =
false;
1177 elen = cline.length();
1179 estop = estart + elen;
1181 bool done = pos >= estop;
1187 elen -=
qFloor(elen * invSumLength) * sumLength;
1190 qreal dpos = pos + dashes[idash] - doffset - estart;
1195 doffset = dashes[idash] - (dpos - elen);
1199 pos = dpos + estart;
1200 done = pos >= estop;
1201 if (++idash >= dashCount)
1215 bool has_offset = doffset > 0;
1216 bool evenDash = (idash & 1) == 0;
1217 qreal dpos = pos + dashes[idash] - doffset - estart;
1222 doffset = dashes[idash] - (dpos - elen);
1227 p2 = cline.pointAt(dpos/elen);
1228 pos = dpos + estart;
1229 done = pos >= estop;
1230 if (++idash >= dashCount)
1246 if (!has_offset || !hasMoveTo) {
1255 move_to_pos = line_to_pos;
ElementType type
the type of element
The QPainterPath::Element class specifies the position and type of a subpath.
qfixed strokeWidth() const
bool isEmpty() const
Returns true if either there are no elements in this path, or if the only element is a MoveToElement;...
QDataBuffer< Element > m_elements
qreal y() const
Returns the y-coordinate of the rectangle's top edge.
qreal right() const
Returns the x-coordinate of the rectangle's right edge.
#define qt_real_to_fixed(real)
QLineF startTangent() const
QDashStroker(QStroker *stroker)
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
#define QT_END_NAMESPACE
This macro expands to.
QPainterPath::ElementType type
const QDataBuffer< QStrokerOps::Element > * m_path
qreal length() const
Returns the length of the line.
void lineTo(qfixed x, qfixed y)
#define it(className, varName)
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle)
void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey)
qreal x2() const
Returns the x-coordinate of the line's end point.
void emitLineTo(qfixed x, qfixed y)
static LineJoinMode joinModeForCap(Qt::PenCapStyle)
QPointF p1() const
Returns the line's start point.
qreal y2() const
Returns the y-coordinate of the line's end point.
The QPointF class defines a point in the plane using floating point precision.
LineJoinMode capStyleMode() const
qreal left() const
Returns the x-coordinate of the rectangle's left edge.
QStrokerOps::Element next()
static bool lineIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br)
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.
static bool qt_is_nan(double d)
static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode)
static Q_DECL_CONSTEXPR bool qFuzzyCompare(double p1, double p2)
IntersectType intersect(const QLineF &l, QPointF *intersectionPoint) const
Returns a value indicating whether or not this line intersects with the given line.
static Qt::PenCapStyle capForJoinMode(LineJoinMode mode)
long ASN1_INTEGER_get ASN1_INTEGER * a
qreal dy() const
Returns the vertical component of the line's vector.
virtual void processCurrentSubpath()
qreal y
the y coordinate of the element's position.
Q_DECL_CONSTEXPR T qAbs(const T &t)
void setCurveThresholdFromTransform(const QTransform &transform)
const QPainterPath::Element & elementAt(int i) const
Returns the element at the given index in the painter path.
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
void setCubicToHook(qStrokerCubicToHook cubicToHook)
void cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey)
virtual void processCurrentSubpath()=0
qreal x() const
Returns the x-coordinate of this point.
void emitMoveTo(qfixed x, qfixed y)
int shifted(QBezier *curveSegments, int maxSegmets, qreal offset, float threshold) const
The QLineF class provides a two-dimensional vector using floating point precision.
QSubpathFlatIterator(const QDataBuffer< QStrokerOps::Element > *path, qreal threshold)
Q_CORE_EXPORT void qDebug(const char *,...)
virtual void processCurrentSubpath()
This function is called to stroke the currently built up subpath.
static void qdashstroker_moveTo(qfixed x, qfixed y, void *data)
static QBezier fromPoints(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
QSubpathBackwardIterator(const QDataBuffer< QStrokerOps::Element > *path)
qreal qt_t_for_arc_angle(qreal angle)
void emitMoveTo(qfixed x, qfixed y)
void translate(const QPointF &p)
Translates this line by the given offset.
QBezier bezierOnInterval(qreal t0, qreal t1) const
#define QT_BEGIN_NAMESPACE
This macro expands to.
The QRectF class defines a rectangle in the plane using floating point precision. ...
void strokePath(const QPainterPath &path, void *data, const QTransform &matrix)
Convenience function that decomposes path into begin(), moveTo(), lineTo(), curevTo() and end() calls...
static void qdashstroker_lineTo(qfixed x, qfixed y, void *data)
bool qt_stroke_side(Iterator *it, QStroker *stroker, bool capFirst, QLineF *startTangent)
qreal height() const
Returns the height of the rectangle.
static qreal adapted_angle_on_x(const QLineF &line)
IntersectType
Describes the intersection between two lines.
void strokeEllipse(const QRectF &ellipse, void *data, const QTransform &matrix)
Convenience function for stroking an ellipse with bounding rect rect.
qreal y1() const
Returns the y-coordinate of the line's start point.
QVector< qfixed > m_dashPattern
The QPolygonF class provides a vector of points using floating point precision.
Q_CORE_EXPORT void qWarning(const char *,...)
qreal angle() const
Returns the angle of the line in degrees.
static const char * data(const QByteArray &arr)
const QDataBuffer< QStrokerOps::Element > * m_path
LineJoinMode joinStyleMode() const
void setLength(qreal len)
Sets the length of the line to the given length.
qreal width() const
Returns the width of the rectangle.
virtual void end()
Finishes the stroke.
qreal dx() const
Returns the horizontal component of the line's vector.
qfixed miterLimit() const
qfixed curveThreshold() const
virtual void begin(void *customData)
Prepares the stroker.
void qSwap(T &value1, T &value2)
const T & at(int i) const
Returns the item at index position i in the vector.
static bool lineRectIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br)
void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join)
#define qt_fixed_to_real(fixed)
Q_GUI_EXPORT void qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length, QPointF *startPoint, QPointF *endPoint)
qreal angle(const QPointF &p1, const QPointF &p2)
static void qdashstroker_cubicTo(qfixed, qfixed, qfixed, qfixed, qfixed, qfixed, void *)
qreal x() const
Returns the x-coordinate of the rectangle's left edge.
QPointF p2() const
Returns the line's end point.
qreal x
the x coordinate of the element's position.
qreal y() const
Returns the y-coordinate of this point.
const QDataBuffer< QStrokerOps::Element > * m_path
qreal top() const
Returns the y-coordinate of the rectangle's top edge.
QLineF normalVector() const
Returns a line that is perpendicular to this line with the same starting point and length...
static Q_DECL_CONSTEXPR bool qFuzzyIsNull(double d)
void setLineToHook(qStrokerLineToHook lineToHook)
QSubpathForwardIterator(const QDataBuffer< QStrokerOps::Element > *path)
void moveTo(qfixed x, qfixed y)
int elementCount() const
Returns the number of path elements in the painter path.
qreal bottom() const
Returns the y-coordinate of the rectangle's bottom edge.
QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength, QPointF *curves, int *point_count)
Creates a number of curves for a given arc definition.
void setMoveToHook(qStrokerMoveToHook moveToHook)
Qt::PenJoinStyle joinStyle() const
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
qreal x1() const
Returns the x-coordinate of the line's start point.
QStrokerOps::Element next()
static qreal dot(const QPointF &a, const QPointF &b)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
int size() const
Returns the number of items in the vector.
void emitLineTo(qfixed x, qfixed y)
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
static QVector< qfixed > patternForStyle(Qt::PenStyle style)
QStrokerOps::Element next()