diff options
author | Gunnar Sletta <gunnar.sletta@nokia.com> | 2011-09-12 08:12:58 +0200 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@nokia.com> | 2011-09-12 08:12:58 +0200 |
commit | d77218522eb480c8d528de18049cd7b604cdeb2a (patch) | |
tree | a6433a8e9205a95006eae10b53285a0e3487423d /src/declarative/items/context2d | |
parent | 589c8445e2623ef8e0b8294d7c558a2948b2a5e3 (diff) | |
parent | d5686fa2ac2248d5a31237573fa08697f18f035f (diff) |
Merge branch 'master' into refactor
Conflicts:
examples/declarative/cppextensions/qwidgets/qwidgets.pro
examples/declarative/minehunt/main.cpp
examples/declarative/minehunt/minehunt.pro
src/declarative/items/context2d/qsgcontext2d.cpp
src/declarative/items/qsgflickable.cpp
src/declarative/items/qsgtextedit.cpp
src/declarative/items/qsgtextinput.cpp
src/declarative/particles/qsgangleddirection.cpp
src/declarative/particles/qsgcumulativedirection.cpp
src/declarative/particles/qsgcumulativedirection_p.h
src/declarative/particles/qsgfollowemitter.cpp
src/declarative/particles/qsgmodelparticle.cpp
src/declarative/particles/qsgparticlesystem.cpp
src/qtquick1/util/qdeclarativeview.h
tests/auto/declarative/examples/examples.pro
tests/auto/declarative/qsgfocusscope/tst_qsgfocusscope.cpp
Change-Id: Ib4be2a5e742dee1a399d73da97161736f77448e5
Diffstat (limited to 'src/declarative/items/context2d')
-rw-r--r-- | src/declarative/items/context2d/qsgcontext2d.cpp | 587 |
1 files changed, 4 insertions, 583 deletions
diff --git a/src/declarative/items/context2d/qsgcontext2d.cpp b/src/declarative/items/context2d/qsgcontext2d.cpp index 7a8465a4bc..e5f2eca6b1 100644 --- a/src/declarative/items/context2d/qsgcontext2d.cpp +++ b/src/declarative/items/context2d/qsgcontext2d.cpp @@ -46,6 +46,7 @@ #include <QtGui/qopenglframebufferobject.h> #include <QtCore/qdebug.h> #include "private/qsgcontext_p.h" +#include "private/qdeclarativesvgparser_p.h" #include <QtGui/qguiapplication.h> #include <qdeclarativeinfo.h> @@ -77,6 +78,7 @@ void copy_vector(QVector<T>* dst, const QVector<T>& src) } static bool parsePathDataFast(const QString &dataStr, QPainterPath &path); + #define DEGREES(t) ((t) * 180.0 / Q_PI) #define qClamp(val, min, max) qMin(qMax(val, min), max) @@ -2310,7 +2312,7 @@ void QSGContext2D::setPath(QSGCanvasPath* path) QSGCanvasPath* QSGContext2D::createPath(const QString& pathString) { QPainterPath path; - if (parsePathDataFast(pathString, path)) { + if (QDeclarativeSvgParser::parsePathDataFast(pathString, path)) { return new QSGCanvasPath(path, this); } return 0; @@ -2571,592 +2573,11 @@ bool QSGContext2D::isPointInPath(qreal x, qreal y) const return d->path.contains(QPointF(x, y)); } -//copied from QtSvg (qsvghandler.cpp). -Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); -// '0' is 0x30 and '9' is 0x39 -static inline bool isDigit(ushort ch) -{ - static quint16 magic = 0x3ff; - return ((ch >> 4) == 3) && (magic >> (ch & 15)); -} - -static qreal toDouble(const QChar *&str) -{ - const int maxLen = 255;//technically doubles can go til 308+ but whatever - char temp[maxLen+1]; - int pos = 0; - - if (*str == QLatin1Char('-')) { - temp[pos++] = '-'; - ++str; - } else if (*str == QLatin1Char('+')) { - ++str; - } - while (isDigit(str->unicode()) && pos < maxLen) { - temp[pos++] = str->toLatin1(); - ++str; - } - if (*str == QLatin1Char('.') && pos < maxLen) { - temp[pos++] = '.'; - ++str; - } - while (isDigit(str->unicode()) && pos < maxLen) { - temp[pos++] = str->toLatin1(); - ++str; - } - bool exponent = false; - if ((*str == QLatin1Char('e') || *str == QLatin1Char('E')) && pos < maxLen) { - exponent = true; - temp[pos++] = 'e'; - ++str; - if ((*str == QLatin1Char('-') || *str == QLatin1Char('+')) && pos < maxLen) { - temp[pos++] = str->toLatin1(); - ++str; - } - while (isDigit(str->unicode()) && pos < maxLen) { - temp[pos++] = str->toLatin1(); - ++str; - } - } - - temp[pos] = '\0'; - - qreal val; - if (!exponent && pos < 10) { - int ival = 0; - const char *t = temp; - bool neg = false; - if(*t == '-') { - neg = true; - ++t; - } - while(*t && *t != '.') { - ival *= 10; - ival += (*t) - '0'; - ++t; - } - if(*t == '.') { - ++t; - int div = 1; - while(*t) { - ival *= 10; - ival += (*t) - '0'; - div *= 10; - ++t; - } - val = ((qreal)ival)/((qreal)div); - } else { - val = ival; - } - if (neg) - val = -val; - } else { -#if defined(Q_WS_QWS) && !defined(Q_OS_VXWORKS) - if(sizeof(qreal) == sizeof(float)) - val = strtof(temp, 0); - else -#endif - { - bool ok = false; - val = qstrtod(temp, 0, &ok); - } - } - return val; - -} -static qreal toDouble(const QString &str, bool *ok = NULL) -{ - const QChar *c = str.constData(); - qreal res = toDouble(c); - if (ok) { - *ok = ((*c) == QLatin1Char('\0')); - } - return res; -} - -static qreal toDouble(const QStringRef &str, bool *ok = NULL) -{ - const QChar *c = str.constData(); - qreal res = toDouble(c); - if (ok) { - *ok = (c == (str.constData() + str.length())); - } - return res; -} -static inline void parseNumbersArray(const QChar *&str, QVarLengthArray<qreal, 8> &points) -{ - while (str->isSpace()) - ++str; - while (isDigit(str->unicode()) || - *str == QLatin1Char('-') || *str == QLatin1Char('+') || - *str == QLatin1Char('.')) { - - points.append(toDouble(str)); - - while (str->isSpace()) - ++str; - if (*str == QLatin1Char(',')) - ++str; - - //eat the rest of space - while (str->isSpace()) - ++str; - } -} - -static void pathArcSegment(QPainterPath &path, - qreal xc, qreal yc, - qreal th0, qreal th1, - qreal rx, qreal ry, qreal xAxisRotation) -{ - qreal sinTh, cosTh; - qreal a00, a01, a10, a11; - qreal x1, y1, x2, y2, x3, y3; - qreal t; - qreal thHalf; - - sinTh = qSin(xAxisRotation * (Q_PI / 180.0)); - cosTh = qCos(xAxisRotation * (Q_PI / 180.0)); - - a00 = cosTh * rx; - a01 = -sinTh * ry; - a10 = sinTh * rx; - a11 = cosTh * ry; - - thHalf = 0.5 * (th1 - th0); - t = (8.0 / 3.0) * qSin(thHalf * 0.5) * qSin(thHalf * 0.5) / qSin(thHalf); - x1 = xc + qCos(th0) - t * qSin(th0); - y1 = yc + qSin(th0) + t * qCos(th0); - x3 = xc + qCos(th1); - y3 = yc + qSin(th1); - x2 = x3 + t * qSin(th1); - y2 = y3 - t * qCos(th1); - - path.cubicTo(a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, - a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, - a00 * x3 + a01 * y3, a10 * x3 + a11 * y3); -} - -static void pathArc(QPainterPath &path, - qreal rx, - qreal ry, - qreal x_axis_rotation, - int large_arc_flag, - int sweep_flag, - qreal x, - qreal y, - qreal curx, qreal cury) -{ - qreal sin_th, cos_th; - qreal a00, a01, a10, a11; - qreal x0, y0, x1, y1, xc, yc; - qreal d, sfactor, sfactor_sq; - qreal th0, th1, th_arc; - int i, n_segs; - qreal dx, dy, dx1, dy1, Pr1, Pr2, Px, Py, check; - - rx = qAbs(rx); - ry = qAbs(ry); - - sin_th = qSin(x_axis_rotation * (Q_PI / 180.0)); - cos_th = qCos(x_axis_rotation * (Q_PI / 180.0)); - - dx = (curx - x) / 2.0; - dy = (cury - y) / 2.0; - dx1 = cos_th * dx + sin_th * dy; - dy1 = -sin_th * dx + cos_th * dy; - Pr1 = rx * rx; - Pr2 = ry * ry; - Px = dx1 * dx1; - Py = dy1 * dy1; - /* Spec : check if radii are large enough */ - check = Px / Pr1 + Py / Pr2; - if (check > 1) { - rx = rx * qSqrt(check); - ry = ry * qSqrt(check); - } - - a00 = cos_th / rx; - a01 = sin_th / rx; - a10 = -sin_th / ry; - a11 = cos_th / ry; - x0 = a00 * curx + a01 * cury; - y0 = a10 * curx + a11 * cury; - x1 = a00 * x + a01 * y; - y1 = a10 * x + a11 * y; - /* (x0, y0) is current point in transformed coordinate space. - (x1, y1) is new point in transformed coordinate space. - - The arc fits a unit-radius circle in this space. - */ - d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0); - sfactor_sq = 1.0 / d - 0.25; - if (sfactor_sq < 0) sfactor_sq = 0; - sfactor = qSqrt(sfactor_sq); - if (sweep_flag == large_arc_flag) sfactor = -sfactor; - xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0); - yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0); - /* (xc, yc) is center of the circle. */ - - th0 = qAtan2(y0 - yc, x0 - xc); - th1 = qAtan2(y1 - yc, x1 - xc); - - th_arc = th1 - th0; - if (th_arc < 0 && sweep_flag) - th_arc += 2 * Q_PI; - else if (th_arc > 0 && !sweep_flag) - th_arc -= 2 * Q_PI; - - n_segs = qCeil(qAbs(th_arc / (Q_PI * 0.5 + 0.001))); - - for (i = 0; i < n_segs; i++) { - pathArcSegment(path, xc, yc, - th0 + i * th_arc / n_segs, - th0 + (i + 1) * th_arc / n_segs, - rx, ry, x_axis_rotation); - } -} - - -static bool parsePathDataFast(const QString &dataStr, QPainterPath &path) -{ - qreal x0 = 0, y0 = 0; // starting point - qreal x = 0, y = 0; // current point - char lastMode = 0; - QPointF ctrlPt; - const QChar *str = dataStr.constData(); - const QChar *end = str + dataStr.size(); - - while (str != end) { - while (str->isSpace()) - ++str; - QChar pathElem = *str; - ++str; - QChar endc = *end; - *const_cast<QChar *>(end) = 0; // parseNumbersArray requires 0-termination that QStringRef cannot guarantee - QVarLengthArray<qreal, 8> arg; - parseNumbersArray(str, arg); - *const_cast<QChar *>(end) = endc; - if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z')) - arg.append(0);//dummy - const qreal *num = arg.constData(); - int count = arg.count(); - while (count > 0) { - qreal offsetX = x; // correction offsets - qreal offsetY = y; // for relative commands - switch (pathElem.unicode()) { - case 'm': { - if (count < 2) { - num++; - count--; - break; - } - x = x0 = num[0] + offsetX; - y = y0 = num[1] + offsetY; - num += 2; - count -= 2; - path.moveTo(x0, y0); - - // As per 1.2 spec 8.3.2 The "moveto" commands - // If a 'moveto' is followed by multiple pairs of coordinates without explicit commands, - // the subsequent pairs shall be treated as implicit 'lineto' commands. - pathElem = QLatin1Char('l'); - } - break; - case 'M': { - if (count < 2) { - num++; - count--; - break; - } - x = x0 = num[0]; - y = y0 = num[1]; - num += 2; - count -= 2; - path.moveTo(x0, y0); - - // As per 1.2 spec 8.3.2 The "moveto" commands - // If a 'moveto' is followed by multiple pairs of coordinates without explicit commands, - // the subsequent pairs shall be treated as implicit 'lineto' commands. - pathElem = QLatin1Char('L'); - } - break; - case 'z': - case 'Z': { - x = x0; - y = y0; - count--; // skip dummy - num++; - path.closeSubpath(); - } - break; - case 'l': { - if (count < 2) { - num++; - count--; - break; - } - x = num[0] + offsetX; - y = num[1] + offsetY; - num += 2; - count -= 2; - path.lineTo(x, y); - - } - break; - case 'L': { - if (count < 2) { - num++; - count--; - break; - } - x = num[0]; - y = num[1]; - num += 2; - count -= 2; - path.lineTo(x, y); - } - break; - case 'h': { - x = num[0] + offsetX; - num++; - count--; - path.lineTo(x, y); - } - break; - case 'H': { - x = num[0]; - num++; - count--; - path.lineTo(x, y); - } - break; - case 'v': { - y = num[0] + offsetY; - num++; - count--; - path.lineTo(x, y); - } - break; - case 'V': { - y = num[0]; - num++; - count--; - path.lineTo(x, y); - } - break; - case 'c': { - if (count < 6) { - num += count; - count = 0; - break; - } - QPointF c1(num[0] + offsetX, num[1] + offsetY); - QPointF c2(num[2] + offsetX, num[3] + offsetY); - QPointF e(num[4] + offsetX, num[5] + offsetY); - num += 6; - count -= 6; - path.cubicTo(c1, c2, e); - ctrlPt = c2; - x = e.x(); - y = e.y(); - break; - } - case 'C': { - if (count < 6) { - num += count; - count = 0; - break; - } - QPointF c1(num[0], num[1]); - QPointF c2(num[2], num[3]); - QPointF e(num[4], num[5]); - num += 6; - count -= 6; - path.cubicTo(c1, c2, e); - ctrlPt = c2; - x = e.x(); - y = e.y(); - break; - } - case 's': { - if (count < 4) { - num += count; - count = 0; - break; - } - QPointF c1; - if (lastMode == 'c' || lastMode == 'C' || - lastMode == 's' || lastMode == 'S') - c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y()); - else - c1 = QPointF(x, y); - QPointF c2(num[0] + offsetX, num[1] + offsetY); - QPointF e(num[2] + offsetX, num[3] + offsetY); - num += 4; - count -= 4; - path.cubicTo(c1, c2, e); - ctrlPt = c2; - x = e.x(); - y = e.y(); - break; - } - case 'S': { - if (count < 4) { - num += count; - count = 0; - break; - } - QPointF c1; - if (lastMode == 'c' || lastMode == 'C' || - lastMode == 's' || lastMode == 'S') - c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y()); - else - c1 = QPointF(x, y); - QPointF c2(num[0], num[1]); - QPointF e(num[2], num[3]); - num += 4; - count -= 4; - path.cubicTo(c1, c2, e); - ctrlPt = c2; - x = e.x(); - y = e.y(); - break; - } - case 'q': { - if (count < 4) { - num += count; - count = 0; - break; - } - QPointF c(num[0] + offsetX, num[1] + offsetY); - QPointF e(num[2] + offsetX, num[3] + offsetY); - num += 4; - count -= 4; - path.quadTo(c, e); - ctrlPt = c; - x = e.x(); - y = e.y(); - break; - } - case 'Q': { - if (count < 4) { - num += count; - count = 0; - break; - } - QPointF c(num[0], num[1]); - QPointF e(num[2], num[3]); - num += 4; - count -= 4; - path.quadTo(c, e); - ctrlPt = c; - x = e.x(); - y = e.y(); - break; - } - case 't': { - if (count < 2) { - num += count; - count = 0; - break; - } - QPointF e(num[0] + offsetX, num[1] + offsetY); - num += 2; - count -= 2; - QPointF c; - if (lastMode == 'q' || lastMode == 'Q' || - lastMode == 't' || lastMode == 'T') - c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y()); - else - c = QPointF(x, y); - path.quadTo(c, e); - ctrlPt = c; - x = e.x(); - y = e.y(); - break; - } - case 'T': { - if (count < 2) { - num += count; - count = 0; - break; - } - QPointF e(num[0], num[1]); - num += 2; - count -= 2; - QPointF c; - if (lastMode == 'q' || lastMode == 'Q' || - lastMode == 't' || lastMode == 'T') - c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y()); - else - c = QPointF(x, y); - path.quadTo(c, e); - ctrlPt = c; - x = e.x(); - y = e.y(); - break; - } - case 'a': { - if (count < 7) { - num += count; - count = 0; - break; - } - qreal rx = (*num++); - qreal ry = (*num++); - qreal xAxisRotation = (*num++); - qreal largeArcFlag = (*num++); - qreal sweepFlag = (*num++); - qreal ex = (*num++) + offsetX; - qreal ey = (*num++) + offsetY; - count -= 7; - qreal curx = x; - qreal cury = y; - pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag), - int(sweepFlag), ex, ey, curx, cury); - - x = ex; - y = ey; - } - break; - case 'A': { - if (count < 7) { - num += count; - count = 0; - break; - } - qreal rx = (*num++); - qreal ry = (*num++); - qreal xAxisRotation = (*num++); - qreal largeArcFlag = (*num++); - qreal sweepFlag = (*num++); - qreal ex = (*num++); - qreal ey = (*num++); - count -= 7; - qreal curx = x; - qreal cury = y; - pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag), - int(sweepFlag), ex, ey, curx, cury); - - x = ex; - y = ey; - } - break; - default: - return false; - } - lastMode = pathElem.toLatin1(); - } - } - return true; -} - void QSGContext2D::setPathString(const QString& path) { Q_D(QSGContext2D); d->path = QPainterPath(); - parsePathDataFast(path, d->path); + QDeclarativeSvgParser::parsePathDataFast(path, d->path); } QList<int> QSGContext2D::getImageData(qreal sx, qreal sy, qreal sw, qreal sh) |