r23160 by jghali - #14921: Text-on-path should be able to wrap around on closed paths

scribus-commit scribus-commit at lists.scribus.net
Sat Aug 24 11:44:56 UTC 2019


Author: jghali
Date: Sat Aug 24 11:44:56 2019
New Revision: 23160

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=23160
Log:
#14921: Text-on-path should be able to wrap around on closed paths

Modified:
    trunk/Scribus/scribus/fpointarray.cpp
    trunk/Scribus/scribus/fpointarray.h
    trunk/Scribus/scribus/pageitem_pathtext.cpp

Modified: trunk/Scribus/scribus/fpointarray.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23160&path=/trunk/Scribus/scribus/fpointarray.cpp
==============================================================================
--- trunk/Scribus/scribus/fpointarray.cpp	(original)
+++ trunk/Scribus/scribus/fpointarray.cpp	Sat Aug 24 11:44:56 2019
@@ -462,6 +462,11 @@
 	delete[]( q );
 }
 
+bool FPointArray::isBezierClosed() const
+{
+	int sz = size();
+	return ((sz >= 4) && (pointQF(0) == pointQF(sz - 2)));
+}
 
 struct SVGState
 {

Modified: trunk/Scribus/scribus/fpointarray.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23160&path=/trunk/Scribus/scribus/fpointarray.h
==============================================================================
--- trunk/Scribus/scribus/fpointarray.h	(original)
+++ trunk/Scribus/scribus/fpointarray.h	Sat Aug 24 11:44:56 2019
@@ -79,6 +79,7 @@
 	double lenPathDist(int seg, double t1, double t2) const;
 	void pointTangentNormalAt( int seg, double t, FPoint* p, FPoint* tn, FPoint* n ) const;
 	void pointDerivativesAt( int seg, double t, FPoint* p, FPoint* d1, FPoint* d2 ) const;
+	bool isBezierClosed() const;
 	void svgInit();
 	void svgMoveTo(double x, double y);
 	void svgLineTo(double x, double y);

Modified: trunk/Scribus/scribus/pageitem_pathtext.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23160&path=/trunk/Scribus/scribus/pageitem_pathtext.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_pathtext.cpp	(original)
+++ trunk/Scribus/scribus/pageitem_pathtext.cpp	Sat Aug 24 11:44:56 2019
@@ -153,15 +153,13 @@
 			}
 		}
 	}
+
 	double totalTextLen = 0.0;
 	double totalCurveLen = 0.0;
 	double extraOffset = 0.0;
-	if (itemText.length() != 0)
-	{
-		CurX += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0;
-	}
-	else
+	if (itemText.length() <= 0)
 		return;
+	CurX += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0;
 
 	textLayout.setStory(&itemText);
 	int spaceCount = 0;
@@ -171,6 +169,10 @@
 	const QList<GlyphCluster> glyphRuns = textShaper.shape(0, itemText.length()).glyphs();
 	if (glyphRuns.isEmpty())
 		return;
+
+	// enable seamless crossing past the endpoint for closed curve
+	bool curveClosed = PoLine.isBezierClosed();
+	bool canWrapAround = curveClosed;
 
 	for (const GlyphCluster& run : glyphRuns)
 	{
@@ -209,7 +211,7 @@
 			extraOffset = (totalCurveLen - m_textDistanceMargins.left() - totalTextLen) / static_cast<double>(itemText.length());
 	}
 	int firstRun = 0;
-	if (totalTextLen + m_textDistanceMargins.left() > totalCurveLen && itemText.paragraphStyle(0).direction() == ParagraphStyle::RTL)
+	if (!curveClosed && (totalTextLen + m_textDistanceMargins.left() > totalCurveLen) && (itemText.paragraphStyle(0).direction() == ParagraphStyle::RTL))
 	{
 		double totalLenDiff = totalTextLen + m_textDistanceMargins.left() - totalCurveLen;
 		while (firstRun < glyphRuns.count())
@@ -221,11 +223,16 @@
 				break;
 		}
 	}
+
+	int currPathIndex = 0;
 	QPainterPath guidePath = PoLine.toQPainterPath(false);
 	QList<QPainterPath> pathList = decomposePath(guidePath);
 	QPainterPath currPath = pathList[0];
-	int currPathIndex = 0;
 	PathLineBox* linebox = new PathLineBox();
+
+	double lastPathPerc = currPath.percentAtLength(CurX);
+	double totalPathPerc = 0.0;
+
 	for (int i = firstRun; i < glyphRuns.length(); i++)
 	{
 		const GlyphCluster &run = glyphRuns.at(i);
@@ -235,16 +242,35 @@
 		double currPerc = currPath.percentAtLength(CurX);
 		if (currPerc >= 0.9999999)
 		{
+			// sticks out to the next segment
 			currPathIndex++;
 			if (currPathIndex == pathList.count())
 			{
-				m_maxChars = run.firstChar();
-				break;
+				if (!curveClosed || !canWrapAround)
+				{
+					m_maxChars = run.firstChar();
+					break;
+				}
+				canWrapAround = false;
+				currPathIndex = 0;
 			}
+			CurX -= currPath.length();
 			currPath = pathList[currPathIndex];
-			CurX = dx;
 			currPerc = currPath.percentAtLength(CurX);
-		}
+			lastPathPerc = 0.0;
+		}
+
+		// Prevent total text length to exceed the length of path
+		totalPathPerc += (currPerc - lastPathPerc);
+		if (lastPathPerc > currPerc)
+			totalPathPerc -= 1.0;
+		if (totalPathPerc >= pathList.count() - 1e-7)
+		{
+			m_maxChars = run.firstChar();
+			break;
+		}
+		lastPathPerc = currPerc;
+
 		double currAngle = currPath.angleAtPercent(currPerc);
 		if (currAngle <= 180.0)
 			currAngle *= -1.0;




More information about the scribus-commit mailing list