r21616 by jghali - #14362 related: fix sometime incorrect parsing of svg transform causing incorrect svg import
scribus-commit
scribus-commit at lists.scribus.net
Thu Dec 8 23:56:12 UTC 2016
Author: jghali
Date: Thu Dec 8 23:56:12 2016
New Revision: 21616
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=21616
Log:
#14362 related: fix sometime incorrect parsing of svg transform causing incorrect svg import
Modified:
trunk/Scribus/scribus/plugins/import/svg/svgplugin.cpp
trunk/Scribus/scribus/plugins/import/svg/svgplugin.h
trunk/Scribus/scribus/scclocale.cpp
trunk/Scribus/scribus/scclocale.h
Modified: trunk/Scribus/scribus/plugins/import/svg/svgplugin.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21616&path=/trunk/Scribus/scribus/plugins/import/svg/svgplugin.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/import/svg/svgplugin.cpp (original)
+++ trunk/Scribus/scribus/plugins/import/svg/svgplugin.cpp Thu Dec 8 23:56:12 2016
@@ -1647,6 +1647,37 @@
return LElements;
}
+QVector<double> SVGPlug::parseNumbersList(const QString& numbersStr)
+{
+ QVector<double> numbers;
+ if (numbersStr.isEmpty())
+ return numbers;
+ numbers.reserve(8);
+
+ const QChar* str = numbersStr.data();
+
+ while (str->isSpace())
+ ++str;
+ while (ScCLocale::isDigit(str->unicode()) ||
+ *str == QLatin1Char('-') || *str == QLatin1Char('+') ||
+ *str == QLatin1Char('.'))
+ {
+
+ numbers.append(ScCLocale::toDoubleC(str));
+
+ while (str->isSpace())
+ ++str;
+ if (*str == QLatin1Char(','))
+ ++str;
+
+ //eat the rest of space
+ while (str->isSpace())
+ ++str;
+ }
+
+ return numbers;
+}
+
QList<PageItem*> SVGPlug::parsePath(const QDomElement &e)
{
FPointArray pArray;
@@ -2160,57 +2191,56 @@
QStringList subtransforms = trans.split(')', QString::SkipEmptyParts);
QStringList::ConstIterator it = subtransforms.begin();
QStringList::ConstIterator end = subtransforms.end();
- for(; it != end; ++it)
+ for (; it != end; ++it)
{
QTransform result;
QStringList subtransform = it->split('(', QString::SkipEmptyParts);
subtransform[0] = subtransform[0].trimmed().toLower();
subtransform[1] = subtransform[1].simplified();
- QRegExp reg("[,( ]");
- QStringList params = subtransform[1].split(reg, QString::SkipEmptyParts);
- if(subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
+ QVector<double> params = parseNumbersList(subtransform[1]);
+ if (subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
- if(subtransform[0] == "rotate")
- {
- if(params.count() == 3)
- {
- double x = ScCLocale::toDoubleC(params[1]);
- double y = ScCLocale::toDoubleC(params[2]);
+ if (subtransform[0] == "rotate")
+ {
+ if (params.count() == 3)
+ {
+ double x = params[1];
+ double y = params[2];
result.translate(x, y);
- result.rotate(ScCLocale::toDoubleC(params[0]));
+ result.rotate(params[0]);
result.translate(-x, -y);
}
else
- result.rotate(ScCLocale::toDoubleC(params[0]));
- }
- else if(subtransform[0] == "translate")
+ result.rotate(params[0]);
+ }
+ else if (subtransform[0] == "translate")
+ {
+ if (params.count() == 2)
+ result.translate(params[0], params[1]);
+ else // Spec : if only one param given, assume 2nd param to be 0
+ result.translate(params[0], 0);
+ }
+ else if (subtransform[0] == "scale")
{
if(params.count() == 2)
- result.translate(ScCLocale::toDoubleC(params[0]), ScCLocale::toDoubleC(params[1]));
- else // Spec : if only one param given, assume 2nd param to be 0
- result.translate(ScCLocale::toDoubleC(params[0]), 0);
- }
- else if(subtransform[0] == "scale")
- {
- if(params.count() == 2)
- result.scale(ScCLocale::toDoubleC(params[0]), ScCLocale::toDoubleC(params[1]));
+ result.scale(params[0], params[1]);
else // Spec : if only one param given, assume uniform scaling
- result.scale(ScCLocale::toDoubleC(params[0]), ScCLocale::toDoubleC(params[0]));
- }
- else if(subtransform[0] == "skewx")
- result.shear(tan(ScCLocale::toDoubleC(params[0]) * 0.01745329251994329576), 0.0F);
- else if(subtransform[0] == "skewy")
- result.shear(0.0F, tan(ScCLocale::toDoubleC(params[0]) * 0.01745329251994329576));
- else if(subtransform[0] == "matrix")
- {
- if(params.count() >= 6)
- {
- double sx = ScCLocale::toDoubleC(params[0]);
- double sy = ScCLocale::toDoubleC(params[3]);
- double p1 = ScCLocale::toDoubleC(params[1]);
- double p2 = ScCLocale::toDoubleC(params[2]);
- double p4 = ScCLocale::toDoubleC(params[4]);
- double p5 = ScCLocale::toDoubleC(params[5]);
+ result.scale(params[0], params[0]);
+ }
+ else if (subtransform[0] == "skewx")
+ result.shear(tan(params[0] * 0.01745329251994329576), 0.0F);
+ else if (subtransform[0] == "skewy")
+ result.shear(0.0F, tan(params[0] * 0.01745329251994329576));
+ else if (subtransform[0] == "matrix")
+ {
+ if (params.count() >= 6)
+ {
+ double sx = params[0];
+ double sy = params[3];
+ double p1 = params[1];
+ double p2 = params[2];
+ double p4 = params[4];
+ double p5 = params[5];
result = QTransform(sx, p1, p2, sy, p4, p5);
}
}
Modified: trunk/Scribus/scribus/plugins/import/svg/svgplugin.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21616&path=/trunk/Scribus/scribus/plugins/import/svg/svgplugin.h
==============================================================================
--- trunk/Scribus/scribus/plugins/import/svg/svgplugin.h (original)
+++ trunk/Scribus/scribus/plugins/import/svg/svgplugin.h Thu Dec 8 23:56:12 2016
@@ -334,6 +334,9 @@
QMap<QString, filterSpec> filters;
QMap<QString, markerDesc> markers;
QList<PageItem*> Elements;
+
+protected:
+ QVector<double> parseNumbersList(const QString& numbersStr);
};
#endif
Modified: trunk/Scribus/scribus/scclocale.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21616&path=/trunk/Scribus/scribus/scclocale.cpp
==============================================================================
--- trunk/Scribus/scribus/scclocale.cpp (original)
+++ trunk/Scribus/scribus/scclocale.cpp Thu Dec 8 23:56:12 2016
@@ -13,6 +13,8 @@
#include "scclocale.h"
#include <cstdlib>
+
+#include <QByteArray>
#include <QDebug>
ScCLocale * ScCLocale::m_instance = 0;
@@ -49,6 +51,84 @@
Q_ASSERT(m_instance);
}
return m_instance;
+}
+
+// The code of this function has been borrowed
+// from Qt SVG module
+double ScCLocale::toDoubleC(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';
+
+ double 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 = ((double) ival) / ((double) div);
+ } else {
+ val = ival;
+ }
+ if (neg)
+ val = -val;
+ } else {
+ val = QByteArray::fromRawData(temp, pos).toDouble();
+ }
+ return val;
}
double ScCLocale::toDoubleC(const QString & str, bool * ok)
Modified: trunk/Scribus/scribus/scclocale.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21616&path=/trunk/Scribus/scribus/scclocale.h
==============================================================================
--- trunk/Scribus/scribus/scclocale.h (original)
+++ trunk/Scribus/scribus/scclocale.h Thu Dec 8 23:56:12 2016
@@ -48,6 +48,8 @@
static ScCLocale * that();
public:
+ static inline bool isDigit(ushort ch);
+ static double toDoubleC(const QChar *&str);
static double toDoubleC(const QString& str, bool * ok = 0);
static double toDoubleC(const QString& str, double defValue);
static float toFloatC(const QString& str, bool * ok = 0);
@@ -57,6 +59,13 @@
};
+// The code of this function has been borrowed from Qt SVG module
+inline bool ScCLocale::isDigit(ushort ch)
+{
+ static quint16 magic = 0x3ff;
+ return ((ch >> 4) == 3) && (magic >> (ch & 15));
+}
+
#endif // SCCLOCALE_H
More information about the scribus-commit
mailing list