View Issue Details

IDProjectCategoryView StatusLast Update
0010968ScribusTypographypublic2012-08-02 19:51
Reportermecirt Assigned Tojghali  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionfixed 
Product Version1.5.0svn 
Fixed in Version1.5.0svn 
Summary0010968: Text copy/paste is slow (patch attached)
DescriptionText copy/paste causes the XML parser DFA to be rebuilt each time, which is a very expensive operation. The attached patch remedies this issue.
TagsNo tags attached.
Patch

Activities

mecirt

2012-07-28 20:07

reporter  

paste-speedup.patch (5,928 bytes)   
commit 053cf913879403867824e2751e04c16a53fe83bd
Author: Tomas Mecir <mecirt@gmail.com>
Date:   Fri Jul 27 19:15:29 2012 +0200

    Make text copy/paste significantly faster by only initialising the parser once.

diff --git a/Scribus/scribus/desaxe/actions.h b/Scribus/scribus/desaxe/actions.h
index e66d716..6c38374 100644
--- a/Scribus/scribus/desaxe/actions.h
+++ b/Scribus/scribus/desaxe/actions.h
@@ -34,6 +34,7 @@ protected:
                                                
 	virtual void end(const Xml_string&)             {}
 	virtual void chars(const Xml_string&)           {}
+	virtual void reset()                            {}
 
 	Digester* dig;
 private:
@@ -88,6 +89,11 @@ public:
 		return *this;
 	}
 
+	virtual void reset()
+	{
+		body->reset();
+	}
+
 protected:
 	Action(Action_body* body_)
 	{
diff --git a/Scribus/scribus/desaxe/digester.cpp b/Scribus/scribus/desaxe/digester.cpp
index 9b4109e..21d273d 100644
--- a/Scribus/scribus/desaxe/digester.cpp
+++ b/Scribus/scribus/desaxe/digester.cpp
@@ -164,7 +164,7 @@ void Digester::begin(const Xml_string& tag, Xml_attr attr)
 	for(it=rules.begin(); it!=rules.end(); ++it)
 	{
 #ifdef DESAXE_DEBUG
-		std::cerr << "B " << it->first << " " << typeid(it->second).name() << "\n";
+		std::cerr << "B " << it->first.toStdString() << " " << typeid(it->second).name() << "\n";
 #endif
 		const_cast<Action&>(it->second).begin(tag, attr);
 	}
@@ -177,7 +177,7 @@ void Digester::end(const Xml_string& tag)
 	for(it=rules.rbegin(); it!=rules.rend(); ++it)
 	{
 #ifdef DESAXE_DEBUG
-		std::cerr << "E " << it->first << " " << typeid(it->second).name() << "\n";
+		std::cerr << "E " << it->first.toStdString() << " " << typeid(it->second).name() << "\n";
 #endif
 		const_cast<Action&>(it->second).end(tag);
 	}
@@ -191,7 +191,7 @@ void Digester::chars(const Xml_string& text)
 	for(it=rules.begin(); it!=rules.end(); ++it)
 	{
 #ifdef DESAXE_DEBUG
-		std::cerr << "C " << it->first << " " << typeid(it->second).name() << "\n";
+		std::cerr << "C " << it->first.toStdString() << " " << typeid(it->second).name() << "\n";
 #endif
 		const_cast<Action&>(it->second).chars(text);
 	}
@@ -243,6 +243,9 @@ void RuleState::addRule(const Xml_string& pattern, Action action)
 inline
 void RuleState::reset()
 {
+	std::vector<rule_t>::iterator it;
+	for (it = rules.begin(); it != rules.end(); ++it)
+		it->second.reset();
 	stateStack.clear();
 	if (!valid)
 		compileDFA();
diff --git a/Scribus/scribus/scribus.cpp b/Scribus/scribus/scribus.cpp
index 9e5f306..13470d3 100644
--- a/Scribus/scribus/scribus.cpp
+++ b/Scribus/scribus/scribus.cpp
@@ -5090,15 +5090,14 @@ void ScribusMainWindow::slotEditPaste()
 
 			if (ScMimeData::clipboardHasScribusText())
 			{
-				Serializer dig(*doc); // TODO: do we really need a new serializer here?
-				dig.store<ScribusDoc>("<scribusdoc>", doc);
-				StoryText::desaxeRules("/", dig, "SCRIBUSTEXT");
-				dig.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>());
+				Serializer *textSerializer = doc->textSerializer();
+				textSerializer->reset();
+				textSerializer->store<ScribusDoc>("<scribusdoc>", doc);
 
 				QByteArray xml = ScMimeData::clipboardScribusText();
-				dig.parseMemory(xml, xml.length());
+				textSerializer->parseMemory(xml, xml.length());
 
-				StoryText* story = dig.result<StoryText>();
+				StoryText* story = textSerializer->result<StoryText>();
 
 				currItem->itemText.insert(*story);
 
diff --git a/Scribus/scribus/scribusdoc.cpp b/Scribus/scribus/scribusdoc.cpp
index 282e200..1ecca8c 100644
--- a/Scribus/scribus/scribusdoc.cpp
+++ b/Scribus/scribus/scribusdoc.cpp
@@ -200,6 +200,7 @@ ScribusDoc::ScribusDoc() : UndoObject( tr("Document")), Observable<ScribusDoc>(N
 	m_View(0),
 	m_guardedObject(this),
 	m_serializer(NULL),
+	m_tserializer(NULL),
 	is12doc(false),
 	NrItems(0),
 	First(1), Last(0),
@@ -293,6 +294,7 @@ ScribusDoc::ScribusDoc(const QString& docName, int unitindex, const PageSize& pa
 	m_View(0),
 	m_guardedObject(this),
 	m_serializer(NULL),
+	m_tserializer(NULL),
 	is12doc(false),
 	NrItems(0),
 	First(1), Last(0),
@@ -681,6 +683,8 @@ ScribusDoc::~ScribusDoc()
 		delete docHyphenator;
 	if (m_serializer)
 		delete m_serializer;
+	if (m_tserializer)
+		delete m_tserializer;
 	ScCore->fileWatcher->start();
 }
 
@@ -15034,6 +15038,17 @@ Serializer *ScribusDoc::serializer()
 	return m_serializer;
 }
 
+Serializer *ScribusDoc::textSerializer()
+{
+	if (!m_tserializer) {
+		m_tserializer = new Serializer (*this);
+		StoryText::desaxeRules("/", *m_tserializer, "SCRIBUSTEXT");
+		m_tserializer->addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>());
+	}
+	Q_ASSERT(m_tserializer);
+	return m_tserializer;
+}
+
 
 void ScribusDoc::RotMode(const int& val)
 {
diff --git a/Scribus/scribus/scribusdoc.h b/Scribus/scribus/scribusdoc.h
index ad46b78..aa1c876 100644
--- a/Scribus/scribus/scribusdoc.h
+++ b/Scribus/scribus/scribusdoc.h
@@ -1143,6 +1143,8 @@ public:
 	QMap<PageItem*, QString> getDocItemNames(PageItem::ItemType itemType);
 	//! \brief Returns a serializer for this document
 	Serializer *serializer();
+	//! \brief Returns a text serializer for this document, used to paste text chunks
+	Serializer *textSerializer();
 
 	//! \brief Get rotation mode
 	int RotMode() const {return rotMode;}
@@ -1179,7 +1181,7 @@ protected:
 	ScribusMainWindow* m_ScMW;
 	ScribusView* m_View;
 	ScGuardedObject<ScribusDoc> m_guardedObject;
-	Serializer *m_serializer;
+	Serializer *m_serializer, *m_tserializer;
 	QString currentEditedSymbol;
 	int currentEditedIFrame;
 
diff --git a/Scribus/scribus/text/storytext.cpp b/Scribus/scribus/text/storytext.cpp
index 9daf9ce..0a3761c 100644
--- a/Scribus/scribus/text/storytext.cpp
+++ b/Scribus/scribus/text/storytext.cpp
@@ -2091,7 +2091,12 @@ public:
 		if (lastStyle)
 			delete lastStyle;
 	}
-	
+
+	virtual void reset()
+	{
+		numPara = 0;
+	}
+
 	void begin(const Xml_string& tag, Xml_attr attr)
 	{
 		if (tag == "text-content")
paste-speedup.patch (5,928 bytes)   

jghali

2012-07-30 22:16

administrator   ~0028694

Committed! Thanks!

Issue History

Date Modified Username Field Change
2012-07-28 20:07 mecirt New Issue
2012-07-28 20:07 mecirt File Added: paste-speedup.patch
2012-07-30 22:16 jghali Note Added: 0028694
2012-07-30 22:16 jghali Status new => resolved
2012-07-30 22:16 jghali Fixed in Version => 1.5.0svn
2012-07-30 22:16 jghali Resolution open => fixed
2012-07-30 22:16 jghali Assigned To => jghali
2012-08-02 19:51 cbradney Status resolved => closed