40 #include "private/qstroker_p.h"
41 #include "private/qbezier_p.h"
54 : m_path(
path), m_pos(0) { }
56 inline bool hasNext()
const {
return m_pos < m_path->
size(); }
72 inline bool hasNext()
const {
return m_pos >= 0; }
80 if (m_pos == m_path->
size() - 1) {
104 qWarning(
"QSubpathReverseIterator::next: Case %d unhandled", ce.
type);
121 : m_path(
path), m_pos(0), m_curve_index(-1), m_curve_threshold(threshold) { }
123 inline bool hasNext()
const {
return m_curve_index >= 0 || m_pos < m_path->
size(); }
129 if (m_curve_index >= 0) {
135 if (m_curve_index >= m_curve.
size())
155 e.x = m_curve.
at(0).
x();
156 e.y = m_curve.
at(0).
y();
169 qreal m_curve_threshold;
173 bool capFirst,
QLineF *startTangent);
244 if (
matrix.isIdentity()) {
315 if (
matrix.isIdentity()) {
317 for (
int i=1;
i<pointCount; ++
i)
325 for (
int i=1;
i<pointCount; ++
i) {
347 if (!
matrix.isIdentity()) {
349 for (
int i=0;
i<12; ++
i) {
357 for (
int i=0;
i<12;
i+=3) {
367 : m_capStyle(SquareJoin), m_joinStyle(FlatJoin),
368 m_back1X(0), m_back1Y(0),
369 m_back2X(0), m_back2Y(0),
424 QLineF fwStartTangent, bwStartTangent;
426 bool fwclosed =
qt_stroke_side(&fwit,
this,
false, &fwStartTangent);
427 bool bwclosed =
qt_stroke_side(&bwit,
this, !fwclosed, &bwStartTangent);
429 if (!bwclosed && !fwStartTangent.
isNull())
439 #ifdef QPP_STROKE_DEBUG
440 printf(
" -----> joinPoints: around=(%.0f, %.0f), next_p1=(%.0f, %.f) next_p2=(%.0f, %.f)\n",
443 nextLine.
x1(), nextLine.
y1(), nextLine.
x2(), nextLine.
y2());
447 #if !defined (QFIXED_26_6) && !defined (Q_FIXED_32_32)
462 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
477 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
523 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
530 qreal l1_on_x = adapted_angle_on_x(prevLine);
531 qreal l2_on_x = adapted_angle_on_x(nextLine);
533 qreal sweepLength =
qAbs(l2_on_x - l1_on_x);
543 l1_on_x + 90, -sweepLength,
544 curves, &point_count);
550 for (
int i=0;
i<point_count;
i+=3) {
578 prevLine.
x2(), prevLine.
y2());
602 QLineF shortCut(prevLine.
p2(), nextLine.
p1());
619 Q_ASSERT(!
"QStroker::joinPoints(), bad join style...");
638 const int MAX_OFFSET = 16;
639 QBezier offsetCurves[MAX_OFFSET];
647 #ifdef QPP_STROKE_DEBUG
648 qDebug(
" -> (side) [%.2f, %.2f], startPos=%d",
659 while (
it->hasNext()) {
664 #ifdef QPP_STROKE_DEBUG
665 qDebug(
"\n ---> (side) lineto [%.2f, %.2f]",
e.x,
e.y);
672 line.translate(normal.
dx(), normal.
dy());
680 *startTangent =
line;
693 }
else if (
e.isCurveTo()) {
697 #ifdef QPP_STROKE_DEBUG
698 qDebug(
"\n ---> (side) cubicTo [%.2f, %.2f]",
716 tangent.
translate(offsetCurves[0].pt1() - bezier.
pt1());
727 *startTangent = tangent;
752 #ifdef QPP_STROKE_DEBUG
753 qDebug(
"\n ---> (side) closed subpath");
760 #ifdef QPP_STROKE_DEBUG
761 qDebug(
"\n ---> (side) open subpath");
827 printf(
"angle: %f, t: %f\n",
angle,
t);
829 bezierCoefficients(
t,
a,
b,
c,
d);
830 printf(
"cosAngle: %.10f, value: %.10f\n", cosAngle,
a +
b +
c *
QT_PATH_KAPPA);
831 printf(
"sinAngle: %.10f, value: %.10f\n", sinAngle,
b *
QT_PATH_KAPPA +
c +
d);
853 QPointF *curves,
int *point_count)
859 if (qt_is_nan(
rect.x()) || qt_is_nan(
rect.y()) || qt_is_nan(
rect.width()) || qt_is_nan(
rect.height())
860 || qt_is_nan(startAngle) || qt_is_nan(sweepLength)) {
861 qWarning(
"QPainterPath::arcTo: Adding arc where a parameter is NaN, results are undefined");
906 if (sweepLength > 360) sweepLength = 360;
907 else if (sweepLength < -360) sweepLength = -360;
910 if (startAngle == 0.0) {
911 if (sweepLength == 360.0) {
912 for (
int i = 11;
i >= 0; --
i)
913 curves[(*point_count)++] =
points[
i];
915 }
else if (sweepLength == -360.0) {
916 for (
int i = 1;
i <= 12; ++
i)
917 curves[(*point_count)++] =
points[
i];
923 int endSegment = int(
qFloor((startAngle + sweepLength) / 90));
926 qreal endT = (startAngle + sweepLength - endSegment * 90) / 90;
928 int delta = sweepLength > 0 ? 1 : -1;
952 const int end = endSegment + delta;
957 const int j = 3 * quadrant;
965 const int quadrant = 3 - ((
i % 4) + 4) % 4;
966 const int j = 3 * quadrant;
979 if (
i == endSegment && splitAtEnd)
980 b =
b.bezierOnInterval(startT, endT);
981 else if (splitAtStart)
982 b =
b.bezierOnInterval(startT, 1);
983 }
else if (
i == endSegment && splitAtEnd) {
984 b =
b.bezierOnInterval(0, endT);
988 curves[(*point_count)++] =
b.pt2();
989 curves[(*point_count)++] =
b.pt3();
990 curves[(*point_count)++] =
b.pt4();
994 curves[*(point_count)-1] = endPoint;
1018 : m_stroker(stroker), m_dashOffset(0), m_stroke_width(1), m_miter_limit(1)
1047 pattern << dash << space << dot << space;
1050 pattern << dash << space << dot << space << dot << space;
1061 return ((
p1.x > tl.
x ||
p2.x > tl.
x) && (
p1.x < br.
x ||
p2.x < br.
x)
1062 && (
p1.y > tl.
y ||
p2.y > tl.
y) && (
p1.y < br.
y ||
p2.y < br.
y));
1068 if (!lineRectIntersectsRect(
p1,
p2, tl, br))
1080 u.x = tl.
x -
p1.x;
u.y = br.
y -
p1.y;
1081 v.x = br.
x -
p1.x;
v.y = tl.
y -
p1.y;
1084 u.x = tl.
x -
p1.x;
u.y = tl.
y -
p1.y;
1085 v.x = br.
x -
p1.x;
v.y = br.
y -
p1.y;
1087 #if defined(QFIXED_IS_26_6) || defined(QFIXED_IS_16_16)
1090 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0);
1091 #elif defined(QFIXED_IS_32_32)
1097 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0);
1112 qreal longestLength = 0;
1113 qreal sumLength = 0;
1116 sumLength += dashes[
i];
1117 if (dashes[
i] > longestLength)
1118 longestLength = dashes[
i];
1136 doffset = std::fmod(doffset, sumLength);
1138 doffset += sumLength;
1140 while (doffset >= dashes[idash]) {
1141 doffset -= dashes[idash];
1167 bool hasMoveTo =
false;
1168 while (
it.hasNext()) {
1180 estop = estart + elen;
1185 bool clipIt = clipping && !lineIntersectsRect(prev,
e, clip_tl, clip_br);
1188 if (skipDashing || clipIt) {
1190 elen -= std::floor(elen * invSumLength) * sumLength;
1193 qreal dpos =
pos + dashes[idash] - doffset - estart;
1198 doffset = dashes[idash] - (dpos - elen);
1202 pos = --maxDashes > 0 ? dpos + estart : estop;
1226 bool has_offset = doffset > 0;
1227 bool evenDash = (idash & 1) == 0;
1228 qreal dpos =
pos + dashes[idash] - doffset - estart;
1233 doffset = dashes[idash] - (dpos - elen);
1239 pos = dpos + estart;
1251 || lineRectIntersectsRect(move_to_pos, line_to_pos, clip_tl, clip_br))
1257 if (!has_offset || !hasMoveTo) {
1266 move_to_pos = line_to_pos;
small capitals from c petite p scientific f u
small capitals from c petite p scientific i
[1]
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)
The QLineF class provides a two-dimensional vector using floating point precision.
constexpr QPointF p1() const
constexpr qreal x1() const
constexpr bool isNull() const
constexpr qreal y2() const
void translate(const QPointF &p)
constexpr qreal dx() const
constexpr qreal dy() const
qreal angleTo(const QLineF &l) const
IntersectionType intersects(const QLineF &l, QPointF *intersectionPoint=nullptr) const
constexpr qreal x2() const
constexpr QPointF p2() const
constexpr QPointF pointAt(qreal t) const
void setLength(qreal len)
constexpr qreal y1() const
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
bool qFuzzyCompare(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
The QPainterPath::Element class specifies the position and type of a subpath.
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
The QPointF class defines a point in the plane using floating point precision.
constexpr qreal x() const noexcept
constexpr static qreal dotProduct(const QPointF &p1, const QPointF &p2)
constexpr qreal y() const noexcept
The QPolygonF class provides a list of points using floating point precision. \inmodule QtGui.
The QRectF class defines a finite rectangle in the plane using floating point precision.
constexpr bool isEmpty() const noexcept
constexpr qreal bottom() const noexcept
constexpr qreal left() const noexcept
constexpr qreal top() const noexcept
constexpr qreal right() const noexcept
qfixed strokeWidth() const
void emitLineTo(qfixed x, qfixed y)
static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode)
void processCurrentSubpath() override
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)
virtual void begin(void *customData)
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)
void strokePath(const QPainterPath &path, void *data, const QTransform &matrix)
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)
void emitLineTo(qfixed x, qfixed y)
void emitMoveTo(qfixed x, qfixed y)
qfixed curveThreshold() const
void lineTo(qfixed x, qfixed y)
virtual void processCurrentSubpath()=0
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)
QT_BEGIN_NAMESPACE bool done
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
QT_END_INCLUDE_NAMESPACE typedef double qreal
constexpr float qDegreesToRadians(float degrees)
GLenum GLuint GLenum GLsizei length
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 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
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)
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)
#define qt_fixed_to_real(fixed)
#define qt_real_to_fixed(real)
QT_BEGIN_NAMESPACE typedef qreal qfixed
QPainterPath::ElementType type