r21615 by jghali - #14362: Inkscape SVG freezes Scribus

scribus-commit scribus-commit at lists.scribus.net
Thu Dec 8 23:54:07 UTC 2016


Author: jghali
Date: Thu Dec  8 23:54:07 2016
New Revision: 21615

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=21615
Log:
#14362: Inkscape SVG freezes Scribus 

Modified:
    branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.cpp
    branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.h
    branches/Version14x/Scribus/scribus/scclocale.cpp
    branches/Version14x/Scribus/scribus/scclocale.h

Modified: branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21615&path=/branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.cpp	(original)
+++ branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.cpp	Thu Dec  8 23:54:07 2016
@@ -1332,6 +1332,39 @@
 	return LElements;
 }
 
+// The code of this function has been borrowed from Qt SVG module
+// and adapted for Scribus
+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;
@@ -1831,57 +1864,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)
 	{
 		QMatrix 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")
-		{
-			if(params.count() == 2)
-				result.translate(ScCLocale::toDoubleC(params[0]), ScCLocale::toDoubleC(params[1]));
+				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(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.translate(params[0], 0);
+		}
+		else if (subtransform[0] == "scale")
+		{
+			if (params.count() == 2)
+				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.setMatrix(sx, p1, p2, sy, p4, p5);
 			}
 		}

Modified: branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21615&path=/branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.h
==============================================================================
--- branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.h	(original)
+++ branches/Version14x/Scribus/scribus/plugins/import/svg/svgplugin.h	Thu Dec  8 23:54:07 2016
@@ -279,6 +279,9 @@
 		int blendMode;
 	};
 	QMap<QString, filterSpec> filters;
+
+protected:
+	QVector<double> parseNumbersList(const QString& numbersStr);
 };
 
 #endif

Modified: branches/Version14x/Scribus/scribus/scclocale.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21615&path=/branches/Version14x/Scribus/scribus/scclocale.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/scclocale.cpp	(original)
+++ branches/Version14x/Scribus/scribus/scclocale.cpp	Thu Dec  8 23:54:07 2016
@@ -1,126 +1,206 @@
-//
-// C++ Implementation: sclocale
-//
-// Description: 
-//
-//
-// Author: Pierre Marchand <pierremarc at oep-h.com>, (C) 2009
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
-
-#include "scclocale.h"
-
-#include <cstdlib>
-#include <QDebug>
-
-ScCLocale * ScCLocale::m_instance = 0;
-ScCLocale::ScCLocale()
-	:qLocale(QLocale::C)
-{
-	qLocale.setNumberOptions(QLocale::OmitGroupSeparator);
-
-#if defined(Q_WS_WIN)
-	cLocale = _create_locale(LC_ALL, "C");
-#else
-  #if not defined(Q_OS_SOLARIS) and not defined(Q_OS_OPENBSD) and not defined (Q_OS_FREEBSD) and not defined (Q_OS_HAIKU)
-	cLocale = newlocale(LC_ALL_MASK, "C", NULL);
-  #endif
-#endif
-}
-
-ScCLocale::~ScCLocale()
-{
-#if defined(Q_WS_WIN)
-	_free_locale(cLocale);
-#else
-  #if not defined(Q_OS_SOLARIS) and not defined(Q_OS_OPENBSD) and not defined (Q_OS_FREEBSD) and not defined (Q_OS_HAIKU)
-	freelocale(cLocale);
-  #endif
-#endif
-}
-
-ScCLocale * ScCLocale::that()
-{
-	if(!m_instance)
-	{
-		m_instance = new ScCLocale();
-		Q_ASSERT(m_instance);
-	}
-	return m_instance;
-}
-
-double ScCLocale::toDoubleC(const QString & str, bool * ok) 
-{
-	double ret( that()->qLocale.toDouble(str, ok) );
-	return ret;
-}
-
-double ScCLocale::toDoubleC(const QString& str, double defValue)
-{
-	double ret = defValue;
-	if (!str.isEmpty())
-	{
-		bool ok  = false;
-		double d = ScCLocale::toDoubleC(str, &ok);
-		if (ok)
-			ret = d;
-	}
-	return ret;
-}
-
-float ScCLocale::toFloatC(const QString & str, bool * ok) 
-{
-	double ret( that()->qLocale.toFloat(str, ok) );
-	return ret;
-}
-
-float ScCLocale::toFloatC(const QString& str, float defValue)
-{
-	double ret = defValue;
-	if (!str.isEmpty())
-	{
-		bool ok  = false;
-		double d = ScCLocale::toFloatC(str, &ok);
-		if (ok)
-			ret = d;
-	}
-	return ret;
-}
-
-QString ScCLocale::toQStringC(double d, int prec)
-{
-	return that()->qLocale.toString(d, 'f', prec);
-}
-
-double ScCLocale::strtod ( const char * str, char ** endptr )
-{
-	if(NULL == that()->cLocale)
-	{
-		// a sade workaround
-		double result(0.0);
-		setlocale(LC_NUMERIC, "C");
-		result = std::strtod(str, endptr);
-		setlocale(LC_NUMERIC, "");
-		return result;
-	}
-	else
-	{
-#if defined(Q_WS_WIN)
-		return _strtod_l(str, endptr, that()->cLocale);
-#else
-  #if defined(Q_OS_SOLARIS) or defined (Q_OS_OPENBSD) or defined (Q_OS_FREEBSD) or defined (Q_OS_HAIKU)
-		char *oldlocale=setlocale(LC_NUMERIC, NULL);
-		double result(0.0);
-		setlocale(LC_NUMERIC, "C");
-		result = std::strtod(str, endptr);
-		setlocale(LC_NUMERIC, oldlocale);
-		return result;
-  #else
-		return strtod_l(str, endptr, that()->cLocale);
-  #endif
-#endif
-	}
-}
-
+//
+// C++ Implementation: sclocale
+//
+// Description: 
+//
+//
+// Author: Pierre Marchand <pierremarc at oep-h.com>, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "scclocale.h"
+
+#include <cstdlib>
+
+#include <QByteArray>
+#include <QDebug>
+
+ScCLocale * ScCLocale::m_instance = 0;
+ScCLocale::ScCLocale()
+	:qLocale(QLocale::C)
+{
+	qLocale.setNumberOptions(QLocale::OmitGroupSeparator);
+
+#if defined(Q_WS_WIN)
+	cLocale = _create_locale(LC_ALL, "C");
+#else
+  #if not defined(Q_OS_SOLARIS) and not defined(Q_OS_OPENBSD) and not defined (Q_OS_FREEBSD) and not defined (Q_OS_HAIKU)
+	cLocale = newlocale(LC_ALL_MASK, "C", NULL);
+  #endif
+#endif
+}
+
+ScCLocale::~ScCLocale()
+{
+#if defined(Q_WS_WIN)
+	_free_locale(cLocale);
+#else
+  #if not defined(Q_OS_SOLARIS) and not defined(Q_OS_OPENBSD) and not defined (Q_OS_FREEBSD) and not defined (Q_OS_HAIKU)
+	freelocale(cLocale);
+  #endif
+#endif
+}
+
+ScCLocale * ScCLocale::that()
+{
+	if(!m_instance)
+	{
+		m_instance = new ScCLocale();
+		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) 
+{
+	double ret( that()->qLocale.toDouble(str, ok) );
+	return ret;
+}
+
+double ScCLocale::toDoubleC(const QString& str, double defValue)
+{
+	double ret = defValue;
+	if (!str.isEmpty())
+	{
+		bool ok  = false;
+		double d = ScCLocale::toDoubleC(str, &ok);
+		if (ok)
+			ret = d;
+	}
+	return ret;
+}
+
+float ScCLocale::toFloatC(const QString & str, bool * ok) 
+{
+	double ret( that()->qLocale.toFloat(str, ok) );
+	return ret;
+}
+
+float ScCLocale::toFloatC(const QString& str, float defValue)
+{
+	double ret = defValue;
+	if (!str.isEmpty())
+	{
+		bool ok  = false;
+		double d = ScCLocale::toFloatC(str, &ok);
+		if (ok)
+			ret = d;
+	}
+	return ret;
+}
+
+QString ScCLocale::toQStringC(double d, int prec)
+{
+	return that()->qLocale.toString(d, 'f', prec);
+}
+
+double ScCLocale::strtod ( const char * str, char ** endptr )
+{
+	if(NULL == that()->cLocale)
+	{
+		// a sade workaround
+		double result(0.0);
+		setlocale(LC_NUMERIC, "C");
+		result = std::strtod(str, endptr);
+		setlocale(LC_NUMERIC, "");
+		return result;
+	}
+	else
+	{
+#if defined(Q_WS_WIN)
+		return _strtod_l(str, endptr, that()->cLocale);
+#else
+  #if defined(Q_OS_SOLARIS) or defined (Q_OS_OPENBSD) or defined (Q_OS_FREEBSD) or defined (Q_OS_HAIKU)
+		char *oldlocale=setlocale(LC_NUMERIC, NULL);
+		double result(0.0);
+		setlocale(LC_NUMERIC, "C");
+		result = std::strtod(str, endptr);
+		setlocale(LC_NUMERIC, oldlocale);
+		return result;
+  #else
+		return strtod_l(str, endptr, that()->cLocale);
+  #endif
+#endif
+	}
+}
+

Modified: branches/Version14x/Scribus/scribus/scclocale.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21615&path=/branches/Version14x/Scribus/scribus/scclocale.h
==============================================================================
--- branches/Version14x/Scribus/scribus/scclocale.h	(original)
+++ branches/Version14x/Scribus/scribus/scclocale.h	Thu Dec  8 23:54:07 2016
@@ -1,63 +1,72 @@
-//
-// C++ Interface: sclocale
-//
-// Description: 
-//
-//
-// Author: Pierre Marchand <pierremarc at oep-h.com>, (C) 2009
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
-
-#ifndef SCCLOCALE_H
-#define SCCLOCALE_H
-
-#include <QLocale>
-#include <QString>
-
-#include <clocale>
-#if defined(Q_OS_MAC)
-#include <xlocale.h>
-#endif
-
-#if defined(Q_OS_SOLARIS) || defined (Q_OS_OPENBSD) || defined (Q_OS_FREEBSD) || defined (Q_OS_HAIKU)
-#include <locale.h>
-#endif
-
-#if defined(Q_WS_WIN)
-#define XLocaleType _locale_t
-#else
-  #if defined (Q_OS_SOLARIS) || defined (Q_OS_OPENBSD) || defined (Q_OS_FREEBSD) || defined (Q_OS_HAIKU)
-  #define XLocaleType char*   //dummy?
-  #else
-  #define XLocaleType locale_t
-  #endif
-#endif
-
-#include "scribusapi.h"
-
-class SCRIBUS_API ScCLocale
-{
-	ScCLocale();
-	~ScCLocale();
-	QLocale qLocale;
-	XLocaleType cLocale;
-
-	static ScCLocale * m_instance;
-	static ScCLocale * that();
-	
-	public:
-		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);
-		static float toFloatC(const QString& str, float defValue);
-		static QString toQStringC(double d, int prec = 3);
-		static double strtod ( const char * str, char ** endptr );
-		
-};
-
-#endif // SCCLOCALE_H
-
-
-
+//
+// C++ Interface: sclocale
+//
+// Description: 
+//
+//
+// Author: Pierre Marchand <pierremarc at oep-h.com>, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef SCCLOCALE_H
+#define SCCLOCALE_H
+
+#include <QLocale>
+#include <QString>
+
+#include <clocale>
+#if defined(Q_OS_MAC)
+#include <xlocale.h>
+#endif
+
+#if defined(Q_OS_SOLARIS) || defined (Q_OS_OPENBSD) || defined (Q_OS_FREEBSD) || defined (Q_OS_HAIKU)
+#include <locale.h>
+#endif
+
+#if defined(Q_WS_WIN)
+#define XLocaleType _locale_t
+#else
+  #if defined (Q_OS_SOLARIS) || defined (Q_OS_OPENBSD) || defined (Q_OS_FREEBSD) || defined (Q_OS_HAIKU)
+  #define XLocaleType char*   //dummy?
+  #else
+  #define XLocaleType locale_t
+  #endif
+#endif
+
+#include "scribusapi.h"
+
+class SCRIBUS_API ScCLocale
+{
+	ScCLocale();
+	~ScCLocale();
+	QLocale qLocale;
+	XLocaleType cLocale;
+
+	static ScCLocale * m_instance;
+	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);
+		static float toFloatC(const QString& str, float defValue);
+		static QString toQStringC(double d, int prec = 3);
+		static double strtod ( const char * str, char ** endptr );
+		
+};
+
+// 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