r23456 by jghali - #14467: 1.5.x slows down immensely (with high CPU usage) when opening 1.4.6 file

scribus-commit scribus-commit at lists.scribus.net
Tue Feb 4 20:26:16 UTC 2020


Author: jghali
Date: Tue Feb  4 20:26:16 2020
New Revision: 23456

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=23456
Log:
#14467: 1.5.x slows down immensely (with high CPU usage) when opening 1.4.6 file

Modified:
    trunk/Scribus/scribus/pageitem_textframe.cpp
    trunk/Scribus/scribus/text/sctext_shared.cpp
    trunk/Scribus/scribus/text/sctext_shared.h
    trunk/Scribus/scribus/text/storytext.cpp
    trunk/Scribus/scribus/text/storytext.h

Modified: trunk/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23456&path=/trunk/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.cpp	(original)
+++ trunk/Scribus/scribus/pageitem_textframe.cpp	Tue Feb  4 20:26:16 2020
@@ -1364,6 +1364,13 @@
 			}
 			m_availableRegion = matrix.map(m_availableRegion);
 		}
+		
+		// update Bullet & number list if any.
+		if (itemText.hasTextMarks() || itemText.hasBulletOrNum() ||  itemText.marksCountChanged())
+		{
+			updateBulletsNum();
+			itemText.resetMarksCountChanged();
+		}
 
 		ITextContext* context = this;
 		//TextShaper textShaper(this, itemText, firstInFrame());
@@ -1372,7 +1379,7 @@
 		QList<GlyphCluster> glyphClusters; // = textShaper.shape();
 		// std::sort(glyphClusters.begin(), glyphClusters.end(), logicalGlyphRunComp);
 
-		LineControl current(m_width, m_height, m_textDistanceMargins, lineCorr, m_Doc, context,columnWidth(), m_columnGap);
+		LineControl current(m_width, m_height, m_textDistanceMargins, lineCorr, m_Doc, context, columnWidth(), m_columnGap);
 		current.nextColumn(textLayout);
 
 		lastLineY = m_textDistanceMargins.top();
@@ -1405,8 +1412,6 @@
 			desc = -itemText.defaultStyle().charStyle().font().descent(itemText.defaultStyle().charStyle().fontSize() / 10.0);
 			current.yPos = itemText.defaultStyle().lineSpacing() + m_textDistanceMargins.top() + lineCorr - desc;
 		}
-		// update Bullet & number list if any.
-		updateBulletsNum();
 
 		current.startLine(0);
 

Modified: trunk/Scribus/scribus/text/sctext_shared.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23456&path=/trunk/Scribus/scribus/text/sctext_shared.cpp
==============================================================================
--- trunk/Scribus/scribus/text/sctext_shared.cpp	(original)
+++ trunk/Scribus/scribus/text/sctext_shared.cpp	Tue Feb  4 20:26:16 2020
@@ -18,7 +18,7 @@
 
 ScText_Shared::ScText_Shared(const StyleContext* pstyles) :
 	pstyleContext(nullptr),
-	refs(1), len(0), cursorPosition(0)
+	refs(1), len(0), cursorPosition(0), marksCount(0), marksCountChanged(false)
 {
 	pstyleContext.setDefaultStyle( & defaultStyle );
 	defaultStyle.setContext( pstyles );
@@ -33,7 +33,7 @@
 	defaultStyle(other.defaultStyle), 
 	pstyleContext(other.pstyleContext),
 	refs(1), len(0), cursorPosition(other.cursorPosition),
-	trailingStyle(other.trailingStyle)
+	trailingStyle(other.trailingStyle), marksCount(other.marksCount), marksCountChanged(other.marksCountChanged)
 {
 	pstyleContext.setDefaultStyle( &defaultStyle );
 	trailingStyle.setContext( &pstyleContext );
@@ -41,14 +41,16 @@
 
 	QListIterator<ScText*> it( other );
 	ScText* elem;
-	while ( it.hasNext() ) {
+	while ( it.hasNext() )
+	{
 		elem = it.next();
 		ScText* elem2 = new ScText(*elem);
 		append(elem2);
-		if (elem2->parstyle) {
+		if (elem2->parstyle)
+		{
 			elem2->parstyle->setContext( & pstyleContext);
 //				elem2->parstyle->charStyle().setContext( defaultStyle.charStyleContext() );
-			replaceCharStyleContextInParagraph(count()-1, elem2->parstyle->charStyleContext());
+			replaceCharStyleContextInParagraph(count() - 1, elem2->parstyle->charStyleContext());
 		}
 	}
 	len = count();
@@ -62,6 +64,9 @@
 		delete this->takeFirst(); 
 	QList<ScText*>::clear();
 	cursorPosition = 0;
+	if (marksCount > 0)
+		marksCountChanged = true;
+	marksCount = 0;
 }
 
 ScText_Shared& ScText_Shared::operator= (const ScText_Shared& other) 
@@ -78,11 +83,13 @@
 		clear();
 		QListIterator<ScText*> it( other );
 		ScText* elem;
-		while ( it.hasNext() ) {
+		while ( it.hasNext() )
+		{
 			elem = it.next();
 			ScText* elem2 = new ScText(*elem);
 			append(elem2);
-			if (elem2->parstyle) {
+			if (elem2->parstyle)
+			{
 				elem2->parstyle->setContext( & pstyleContext );
 //					qDebug() << QString("StoryText::copy: * %1 align=%2").arg(elem2->parstyle->parent())
 //						   .arg(elem2->parstyle->alignment())
@@ -93,6 +100,8 @@
 		}
 		len = count();
 		cursorPosition = other.cursorPosition;
+		marksCount = other.marksCount;
+		marksCountChanged = other.marksCountChanged;
 		pstyleContext.invalidate();
 //			qDebug() << QString("StoryText::copy: %1 align=%2 %3").arg(trailingStyle.parentStyle()->name())
 //				   .arg(trailingStyle.alignment()).arg((uint)trailingStyle.context());
@@ -132,7 +141,8 @@
 	// assert that all chars point to the following parstyle
 	QListIterator<ScText*> it( *this );
 	const StyleContext* lastContext = nullptr;
-	while ( it.hasNext() ) {
+	while ( it.hasNext() )
+	{
 		ScText* elem = it.next();
 		assert( elem );
 		if ( elem->ch.isNull() ) 

Modified: trunk/Scribus/scribus/text/sctext_shared.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23456&path=/trunk/Scribus/scribus/text/sctext_shared.h
==============================================================================
--- trunk/Scribus/scribus/text/sctext_shared.h	(original)
+++ trunk/Scribus/scribus/text/sctext_shared.h	Tue Feb  4 20:26:16 2020
@@ -28,6 +28,8 @@
 	uint refs;
 	uint len;
 	uint cursorPosition;
+	uint marksCount;
+	bool marksCountChanged;
 	ParagraphStyle trailingStyle;
 	CharStyle orphanedCharStyle;
 

Modified: trunk/Scribus/scribus/text/storytext.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23456&path=/trunk/Scribus/scribus/text/storytext.cpp
==============================================================================
--- trunk/Scribus/scribus/text/storytext.cpp	(original)
+++ trunk/Scribus/scribus/text/storytext.cpp	Tue Feb  4 20:26:16 2020
@@ -104,6 +104,48 @@
 		d->len = 0;
 		delete d;
 	}	
+}
+
+bool StoryText::hasBulletOrNum() const
+{
+	if (!d)
+		return false;
+
+	bool lastWasPARSEP = true;
+	for (int i = 0; i < length(); ++i)
+	{
+		lastWasPARSEP = (d->at(i)->ch == SpecialChars::PARSEP);
+		if (!lastWasPARSEP)
+			continue;
+		const ParagraphStyle& paraStyle = paragraphStyle(i);
+		if (paraStyle.hasBullet() || paraStyle.hasNum())
+			return true;
+	}
+
+	const ParagraphStyle& trailingStyle = d->trailingStyle;
+	if (trailingStyle.hasBullet() || trailingStyle.hasNum())
+		return true;
+
+	return false;
+}
+
+bool StoryText::hasTextMarks() const
+{
+	if (d)
+		return (d->marksCount > 0);
+	return false;
+}
+
+bool StoryText::marksCountChanged() const
+{
+	if (d)
+		return d->marksCountChanged;
+	return false;
+}
+
+void StoryText::resetMarksCountChanged()
+{
+	d->marksCountChanged = false;
 }
 
 void StoryText::setDoc(ScribusDoc *docin)
@@ -471,6 +513,11 @@
 			insertChars(pos, SpecialChars::OBJECT);
 			item(pos)->embedded = other.item(i)->embedded;
 			item(pos)->mark = other.item(i)->mark;
+			if (item(pos)->mark)
+			{
+				d->marksCount++;
+				d->marksCountChanged = true;
+			}
 			applyCharStyle(pos, 1, other.charStyle(i));
 			cstyleStart = i+1;
 			pos += 1;
@@ -555,6 +602,8 @@
 	if (pos + static_cast<int>(len) > length())
 		len = length() - pos;
 
+	uint oldMarksCount = d->marksCount;
+
 	if ((pos == 0) && (len > 0) && (static_cast<int>(len) == length()))
 	{
 		int lastChar = length() - 1;
@@ -565,8 +614,10 @@
 	for (int i = pos + static_cast<int>(len) - 1; i >= pos; --i)
 	{
 		ScText *it = d->at(i);
-		if ((it->ch == SpecialChars::PARSEP))
+		if (it->ch == SpecialChars::PARSEP)
 			removeParSep(i);
+		if ((it->ch == SpecialChars::OBJECT) && (it->mark != nullptr))
+			d->marksCount--;
 		d->takeAt(i);
 		d->len--;
 		delete it;
@@ -580,6 +631,9 @@
 			d->cursorPosition -= 1;
 	}
 
+	if (oldMarksCount != d->marksCount)
+		d->marksCountChanged = true;
+
 	d->len = d->count();
 	d->cursorPosition = qMin(d->cursorPosition, d->len);
 	if (m_selFirst > m_selLast)
@@ -731,12 +785,19 @@
 	ScText* item = d->at(pos);
 	if (item->ch == ch)
 		return;
-	
-	if (d->at(pos)->ch == SpecialChars::PARSEP)
+
+	uint oldMarksCount = d->marksCount;
+	
+	if (item->ch == SpecialChars::PARSEP)
 		removeParSep(pos);
+	if ((item->ch == SpecialChars::OBJECT) && (item->mark != nullptr))
+		d->marksCount--;
 	item->ch = ch;
 	if (d->at(pos)->ch == SpecialChars::PARSEP)
 		insertParSep(pos);
+
+	if (oldMarksCount != d->marksCount)
+		d->marksCountChanged = true;
 	
 	invalidate(pos, pos + 1);
 }
@@ -846,15 +907,20 @@
 	m_doc->FrameItems[ob]->OwnPage = -1; // #10379: OwnPage is not meaningful for inline object
 }
 
-void StoryText::insertMark(Mark* Mark, int pos)
-{
-	if (Mark == nullptr)
+void StoryText::insertMark(Mark* mark, int pos)
+{
+	if (mark == nullptr)
 		return;
 	if (pos < 0)
 		pos = d->cursorPosition;
 
 	insertChars(pos, SpecialChars::OBJECT, false);
-	const_cast<StoryText *>(this)->d->at(pos)->mark = Mark;
+	d->at(pos)->mark = mark;
+	if (mark)
+	{
+		d->marksCount++;
+		d->marksCountChanged = true;
+	}
 }
 
 void StoryText::replaceObject(int pos, int ob)
@@ -983,9 +1049,9 @@
 
 QString StoryText::sentence(int pos, int &posn)
 {
-	int sentencePos=qMax(0, prevSentence(pos));
+	int sentencePos = qMax(0, prevSentence(pos));
 	posn=sentencePos;
-	int nextSentencePos=qMin(length(), endOfSentence(pos));
+	int nextSentencePos = qMin(length(), endOfSentence(pos));
 	return text(sentencePos, nextSentencePos-sentencePos);
 }
 
@@ -1111,7 +1177,17 @@
 	assert(pos >= 0);
 	assert(pos < length());
 
+	bool hadMarks = (d->marksCount > 0);
+
+	ScText* textItem = this->d->at(pos);
+	if (textItem->mark)
+		this->d->marksCount--;
 	this->d->at(pos)->mark = mrk;
+	if (textItem->mark)
+		this->d->marksCount++;
+
+	// Set marksCountChanged unconditionnaly to force text relayout
+	d->marksCountChanged = true;
 }
 
 

Modified: trunk/Scribus/scribus/text/storytext.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23456&path=/trunk/Scribus/scribus/text/storytext.h
==============================================================================
--- trunk/Scribus/scribus/text/storytext.h	(original)
+++ trunk/Scribus/scribus/text/storytext.h	Tue Feb  4 20:26:16 2020
@@ -78,6 +78,11 @@
 	StoryText(const StoryText & other);
 	StoryText& operator= (const StoryText & other);
 	virtual ~StoryText();
+
+	bool hasBulletOrNum() const;
+	bool hasTextMarks() const;
+	bool marksCountChanged() const;
+	void resetMarksCountChanged();
 	
 	void setDoc(ScribusDoc *docin);
 	
@@ -127,7 +132,7 @@
 	// Insert object at specific position
 	void insertObject(int pos, int obj);
 	// Insert mark at cursor or specific position
-	void insertMark(Mark* Mark, int pos = -1);
+	void insertMark(Mark* mark, int pos = -1);
 	// Replace a character
  	void replaceChar(int pos, QChar ch);
 	// Replace current selection with specified text




More information about the scribus-commit mailing list