r17043 by jghali - #10404: Linked text frames edition has become sluggish

scribus-commit scribus-commit at lists.scribus.net
Tue Nov 29 22:29:55 UTC 2011


Author: jghali
Date: Tue Nov 29 22:29:54 2011
New Revision: 17043

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=17043
Log:
#10404: Linked text frames edition has become sluggish

Modified:
    branches/Version135/Scribus/scribus/pageitem_textframe.cpp
    branches/Version135/Scribus/scribus/util_math.cpp
    branches/Version135/Scribus/scribus/util_math.h

Modified: branches/Version135/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17043&path=/branches/Version135/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- branches/Version135/Scribus/scribus/pageitem_textframe.cpp (original)
+++ branches/Version135/Scribus/scribus/pageitem_textframe.cpp Tue Nov 29 22:29:54 2011
@@ -585,18 +585,16 @@
 		}
 
 		QRect   pt(pt12, pt22);
-		QRegion region;
 
 		double EndX2 = StartX;
 		double Interval = 0.25;
 		do {
 			int xP = static_cast<int>(ceil(EndX2 + morespace));
 			pt.moveTopLeft(QPoint(xP, yAsc));
-			region = QRegion(pt).subtracted(shape);
-			if (!region.isEmpty())
+			if (!regionContainsRect(shape, pt))
 				break;
 			EndX2 += Interval;
-		} while ((EndX2 < maxX) && region.isEmpty());
+		} while ((EndX2 < maxX) && regionContainsRect(shape, pt));
 
 		/*double oldEndX2 = endOfLine_old(shape, pf2, morespace, yAsc, yDesc);
 		if (oldEndX2 != qMin(EndX2, maxX))
@@ -784,8 +782,6 @@
 	double lineCorr;
 };
 
-
-
 /// called when line length is known and line is to be justified
 static void justifyLine(StoryText& itemText, LineSpec& line)
 {
@@ -962,7 +958,7 @@
 
 static double findRealOverflowEnd(const QRegion& shape, QRect pt, double maxX)
 {
-	while (!QRegion(pt).subtracted(shape).isEmpty() && pt.right() < maxX)
+	while (!regionContainsRect(shape, pt) && pt.right() < maxX)
 		pt.translate(1, 0);
 	if (pt.right() >= maxX)
 		return maxX;
@@ -1495,7 +1491,7 @@
 					//check if in indent any overflow occurs
 					while (Xpos <= Xend && Xpos < current.colRight)
 					{
-						if (!QRegion(pt).subtracted(cl).isEmpty())
+						if (!regionContainsRect(cl, pt))
 						{
 							Xpos = current.xPos = realEnd = findRealOverflowEnd(cl, pt, current.colRight);
 							Xend = current.xPos + current.leftIndent;
@@ -1824,7 +1820,7 @@
 					pt2 = QPoint(charEnd, maxYDesc);
 				}
 				pt = QRect(pt1, pt2);
-				if (!QRegion(pt).subtracted(cl).isEmpty())
+				if (!regionContainsRect(cl, pt))
 				{
 					realEnd = findRealOverflowEnd(cl, pt, current.colRight);
 					outs = true;
@@ -1835,7 +1831,7 @@
 						//condition after || is for find overflows in right margin area
 					{
 						pt.translate(static_cast<int>(ceil(style.rightMargin())), 0);
-						if (!QRegion(pt).subtracted(cl).isEmpty())
+						if (!regionContainsRect(cl, pt))
 						{
 							realEnd = findRealOverflowEnd(cl, pt, current.colRight);
 							outs = true;
@@ -1844,7 +1840,7 @@
 				}
 				if (outs)
 				{
-					if (current.itemsInLine ==0)
+					if (current.itemsInLine == 0)
 					{
 						current.line.x = current.xPos = realEnd;
 						a--;

Modified: branches/Version135/Scribus/scribus/util_math.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17043&path=/branches/Version135/Scribus/scribus/util_math.cpp
==============================================================================
--- branches/Version135/Scribus/scribus/util_math.cpp (original)
+++ branches/Version135/Scribus/scribus/util_math.cpp Tue Nov 29 22:29:54 2011
@@ -21,14 +21,14 @@
  *                                                                         *
  ***************************************************************************/
 
+#include <QRegion>
+
 #include "util_math.h"
 #include "scconfig.h"
 #include "fpoint.h"
 #include "fpointarray.h"
 
 using namespace std;
-
-
 
 uint getDouble(const QByteArray in, bool raw)
 {
@@ -178,8 +178,6 @@
 	return ret;
 }
 
-
-
 FPoint projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd)
 {
 	if (lineStart == lineEnd)
@@ -195,6 +193,75 @@
 	return FPoint(lineStart.x() + partOfLine * lineEnd.x(), lineStart.y() + partOfLine * lineEnd.y());
 }
 
+bool regionContainsRect(const QRegion& shape, QRect rect)
+{
+	/*bool oldResult = QRegion(rect).subtracted(shape).isEmpty();*/
+
+	// Code adapted from Qt RectInRegion (cf. qregion.cpp) to detect
+	// if a specific rect is stricly contained in a specific region
+	const QRect *pbox, *pboxEnd;
+    bool partIn(false), partOut(false);
+
+	QRect *prect = ▭
+	int rx = rect.left();
+	int ry = rect.top();
+   
+	int rectCount = shape.rectCount();
+	QRect boundingRect = shape.boundingRect();
+    if (rectCount == 0 || !boundingRect.contains(rect))
+        return false;
+
+    /* can stop when both partOut and partIn are true, or we reach prect->y2 */
+	const QVector<QRect> rects = shape.rects();
+    pbox = (rectCount == 1) ? &boundingRect : rects.constData();
+    pboxEnd = pbox + rectCount;
+    for (; pbox < pboxEnd; ++pbox) {
+        if (pbox->bottom() < ry)
+           continue;
+
+        if (pbox->top() > ry) {
+           partOut = true;
+           if (partIn || pbox->top() > prect->bottom())
+              break;
+           ry = pbox->top();
+        }
+
+        if (pbox->right() < rx)
+           continue;            /* not far enough over yet */
+
+        if (pbox->left() > rx) {
+           partOut = true;      /* missed part of rectangle to left */
+           if (partIn)
+              break;
+        }
+
+        if (pbox->left() <= prect->right()) {
+            partIn = true;      /* definitely overlap */
+            if (partOut)
+               break;
+        }
+
+        if (pbox->right() >= prect->right()) {
+           ry = pbox->bottom() + 1;     /* finished with this band */
+           if (ry > prect->bottom())
+              break;
+           rx = prect->left();  /* reset x out to left again */
+        } else {
+            /*
+             * Because boxes in a band are maximal width, if the first box
+             * to overlap the rectangle doesn't completely cover it in that
+             * band, the rectangle must be partially out, since some of it
+             * will be uncovered in that band. partIn will have been set true
+             * by now...
+             */
+            break;
+        }
+    }
+	/*bool newResult = partIn ? ((ry <= prect->bottom()) ? false : true) : false;
+	if (oldResult != newResult)
+		int test = 0;*/
+    return partIn ? ((ry <= prect->bottom()) ? false : true) : false;
+}
 
 QPolygon FlattenPath(const FPointArray& ina, QList<uint> &Segs)
 {

Modified: branches/Version135/Scribus/scribus/util_math.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17043&path=/branches/Version135/Scribus/scribus/util_math.h
==============================================================================
--- branches/Version135/Scribus/scribus/util_math.h (original)
+++ branches/Version135/Scribus/scribus/util_math.h Tue Nov 29 22:29:54 2011
@@ -22,20 +22,21 @@
 
 class FPoint;
 class FPointArray;
-
+class QRegion;
 
 /*! \brief Compare double values by pre-multiplying by 10000 and converting to long if possible.
 If premultiplication does not allow to store result in a long value, perform a standard comparison.
 */
 bool SCRIBUS_API compareDouble(double a, double b);
-FPoint SCRIBUS_API getMaxClipF(FPointArray* Clip);
-FPoint SCRIBUS_API getMinClipF(FPointArray* Clip);
-inline double SCRIBUS_API xy2Deg(double x, double y);
-FPoint SCRIBUS_API projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd);
+uint SCRIBUS_API getDouble(const QByteArray in, bool raw);
+FPoint   SCRIBUS_API getMaxClipF(FPointArray* Clip);
+FPoint   SCRIBUS_API getMinClipF(FPointArray* Clip);
+FPoint   SCRIBUS_API projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd);
+bool     SCRIBUS_API regionContainsRect(const QRegion& shape, QRect rect);
 QPolygon SCRIBUS_API FlattenPath(const FPointArray& ina, QList<uint> &Segs);
 QList<QPainterPath> SCRIBUS_API decomposePath(QPainterPath &path);
-QPainterPath SCRIBUS_API RegularPolygon(double w, double h, uint c, bool star, double factor, double rota, double factor2 = 0.0);
-uint SCRIBUS_API getDouble(const QByteArray in, bool raw);
+QPainterPath  SCRIBUS_API RegularPolygon(double w, double h, uint c, bool star, double factor, double rota, double factor2 = 0.0);
+inline double SCRIBUS_API xy2Deg(double x, double y);
 inline double SCRIBUS_API sind(double);
 inline double SCRIBUS_API cosd(double);
 inline double SCRIBUS_API square(double);




More information about the scribus-commit mailing list