diff options
Diffstat (limited to 'src/quick/util/qdeclarativesvgparser.cpp')
-rw-r--r-- | src/quick/util/qdeclarativesvgparser.cpp | 614 |
1 files changed, 0 insertions, 614 deletions
diff --git a/src/quick/util/qdeclarativesvgparser.cpp b/src/quick/util/qdeclarativesvgparser.cpp deleted file mode 100644 index 41f12150d6..0000000000 --- a/src/quick/util/qdeclarativesvgparser.cpp +++ /dev/null @@ -1,614 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclaractive module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdeclarativesvgparser_p.h" - -#include <QtCore/qmath.h> -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qstring.h> - -QT_BEGIN_NAMESPACE - -static const double Q_PI = 3.14159265358979323846; // pi - -//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 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); -} - -void QDeclarativeSvgParser::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); - } -} - - -bool QDeclarativeSvgParser::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; -} - -QT_END_NAMESPACE |