r15990 by pierremarc - Integration of Fribidi for correct bidi handling. Still bugs at paragraph level.

scribus-commit scribus-commit at lists.scribus.net
Thu Nov 25 20:12:35 CET 2010


Author: pierremarc
Date: Thu Nov 25 19:12:35 2010
New Revision: 15990

URL: http://scribus.info/websvn/listing.php?repname=Scribus&sc=1&rev=15990
Log:
Integration of Fribidi for correct bidi handling. Still bugs at paragraph level.

Added:
    branches/ScribusOIF/scribus/text/scbidi.cpp
    branches/ScribusOIF/scribus/text/scbidi.h
    branches/ScribusOIF/scribus/third_party/fribidi/
    branches/ScribusOIF/scribus/third_party/fribidi/.directory
    branches/ScribusOIF/scribus/third_party/fribidi/CMakeLists.txt
    branches/ScribusOIF/scribus/third_party/fribidi/COPYING
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi.c
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi.h
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_bidi_types.c
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_char_type.c
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_config.h
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_mem.c
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_mem.h
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_mirroring.c
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_tab_char_type_2.i
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_tab_char_type_9.i
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_tab_mirroring.i
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_types.c
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_types.h
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_types.i
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_unicode.h
    branches/ScribusOIF/scribus/third_party/fribidi/fribidi_utils.c
    branches/ScribusOIF/scribus/third_party/fribidi/wcwidth.c
    branches/ScribusOIF/scribus/third_party/fribidi/wcwidth.i
Modified:
    branches/ScribusOIF/scribus/CMakeLists.txt
    branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
    branches/ScribusOIF/scribus/text/CMakeLists.txt
    branches/ScribusOIF/scribus/text/blocklayouter.cpp
    branches/ScribusOIF/scribus/text/boxes.cpp
    branches/ScribusOIF/scribus/text/glyphstore.cpp
    branches/ScribusOIF/scribus/text/glyphstore.h
    branches/ScribusOIF/scribus/text/linelayouter.cpp
    branches/ScribusOIF/scribus/text/shaper.cpp
    branches/ScribusOIF/scribus/text/specialchars.cpp
    branches/ScribusOIF/scribus/third_party/CMakeLists.txt

Modified: branches/ScribusOIF/scribus/CMakeLists.txt
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/CMakeLists.txt
==============================================================================
--- branches/ScribusOIF/scribus/CMakeLists.txt (original)
+++ branches/ScribusOIF/scribus/CMakeLists.txt Thu Nov 25 19:12:35 2010
@@ -894,6 +894,8 @@
 ENDIF (HAVE_BOOST)
 SET(SCRIBUS_WPG_LIB "scribus_wpg_lib")
 SET(SCRIBUS_HARFBUZZ_LIB "scribus_harfbuzz_lib")
+SET(SCRIBUS_FRIBIDI_LIB "scribus_fribidi_lib")
+
 
 SET(SCRIBUS_PGF_LIB "scribus_pgf_lib")
 
@@ -1061,6 +1063,7 @@
   ${SCRIBUS_WPG_LIB}
   ${SCRIBUS_PGF_LIB}
   ${SCRIBUS_HARFBUZZ_LIB}
+  ${SCRIBUS_FRIBIDI_LIB}
 )
 
 IF(HAVE_PODOFO)

Modified: branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface_ttf.cpp (original)
+++ branches/ScribusOIF/scribus/fonts/scface_ttf.cpp Thu Nov 25 19:12:35 2010
@@ -744,7 +744,7 @@
 	const TextStore * story(gs->story());
 	LanguageManager * lm(LanguageManager::instance());
 	QString language(lm->getAbbrevFromLang(story->charStyle(gs->itemTextPosition(item)).language(), false, false));
-	bool isRTL(lm->isRightToLeft(language));
+	bool isRTL(story->charAttributes(gs->itemTextPosition(item)).testFlag(TextFlag_RightToLeft));
 	bool isAuto(story->charStyle(gs->itemTextPosition(item)).autoShape());
 	double fSize(story->charStyle(gs->itemTextPosition(item)).fontSize() /10.0);
 	int itemPos(gs->itemTextPosition(item));

Modified: branches/ScribusOIF/scribus/text/CMakeLists.txt
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/text/CMakeLists.txt
==============================================================================
--- branches/ScribusOIF/scribus/text/CMakeLists.txt (original)
+++ branches/ScribusOIF/scribus/text/CMakeLists.txt Thu Nov 25 19:12:35 2010
@@ -23,6 +23,7 @@
 linelayouter.cpp
 blocklayouter.cpp
 shaper.cpp
+scbidi.cpp
 )
 
 

Modified: branches/ScribusOIF/scribus/text/blocklayouter.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/text/blocklayouter.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/blocklayouter.cpp (original)
+++ branches/ScribusOIF/scribus/text/blocklayouter.cpp Thu Nov 25 19:12:35 2010
@@ -21,6 +21,7 @@
 #include "text/blocklayouter.h"
 #include "text/linelayouter.h"
 #include "scribusdoc.h"
+#include "langmgr.h"
 
 #include "pageitem_textframe.h"
 
@@ -61,6 +62,9 @@
 	const CharStyle charStyle(parStyle.charStyle());
 	const double frameHeight(m_layout->pageItem()->height());
 	bool fitInFrame(true);
+	LanguageManager * lm(LanguageManager::instance());
+	// we need a general direction for the block
+	bool paragraphIsRTL(lm->isRightToLeft(lm->getAbbrevFromLang( story->charStyle(startPos).language() ,false,false)));
 
 	double asc(charStyle.font().ascent() * charStyle.fontSize() / 10.0);
 	double desc(charStyle.font().descent() * charStyle.fontSize() / 10.0);
@@ -94,7 +98,7 @@
 
 
 		qDebug()<<"\t"<<curPos<<lResult.endPos;
-		if(gs->findItem(curPos) == gs->findItem(lResult.endPos))
+		if(gs->findItem(curPos) == gs->findItem(lResult.endPos)) // Case where the's only 1 item for the whole line
 		{
 			GlyphBox * glyphs(new GlyphBox(const_cast<GlyphStore*>(gs),
 						       m_textFrame->doc()->PageColors,
@@ -107,29 +111,171 @@
 			glyphs->setDescent(-desc);
 			line->addBox(glyphs);
 		}
-		else // we need at least as many GlyphBoxes as items
+		else // we need at least as many GlyphBoxes as items --- TODO_OIF make it more compact
 		{
+			// We first build a list of items grouped by items running in the same direction and store cursor position
+			QList<QList<int> > runs;
 			int item(gs->findItem(curPos));
+			bool itemIsRTL(story->charAttributes(gs->itemTextPosition(item)).testFlag(TextFlag_RightToLeft));
 			int c(curPos);
-			int e(gs->itemCharCount(item) + c);
-			GlyphBox * glyphs(new GlyphBox(const_cast<GlyphStore*>(gs),  m_textFrame->doc()->PageColors, item, c, e));
-			glyphs->moveTo(x,y);
-			glyphs->setWidth(lResult.width);
-			glyphs->setAscent(asc);
-			glyphs->setDescent(-desc);
-			line->addBox(glyphs);
+			int e(qMin(int( c + gs->itemCharCount(item)),  lResult.endPos));
+			QList<int> sameDirectionItems;
+			sameDirectionItems << item;
 			while(e < lResult.endPos)
 			{
 				c = e+1;
 				item = gs->findItem(c);
 				e = qMin(int(gs->itemCharCount(item) + c), lResult.endPos);
-				glyphs = new GlyphBox(const_cast<GlyphStore*>(gs),  m_textFrame->doc()->PageColors, item, c, e);
-				glyphs->moveTo(x,y);
-				glyphs->setWidth(lResult.width);
-				glyphs->setAscent(asc);
-				glyphs->setDescent(-desc);
-				line->addBox(glyphs);
-			}
+				if(itemIsRTL != story->charAttributes(gs->itemTextPosition(item)).testFlag(TextFlag_RightToLeft))
+				{
+					runs << sameDirectionItems;
+					sameDirectionItems.clear();
+					itemIsRTL = story->charAttributes(gs->itemTextPosition(item)).testFlag(TextFlag_RightToLeft);
+				}
+				sameDirectionItems << item;
+			}
+			// commit remaining items
+			if(sameDirectionItems.count() > 0)
+			{
+				runs << sameDirectionItems;
+			}
+
+			// debug
+			int runCounter(0);
+			foreach(QList<int> l, runs)
+			{
+				qDebug()<<"R"<<(++runCounter);
+				foreach(int i, l)
+					qDebug()<<"\t"<<gs->itemTextPosition(i) << gs->itemCharCount(i) <<"\n\t"<<story->text(gs->itemTextPosition(i),gs->itemCharCount(i));
+			}
+
+			bool first(true);
+			double cPosX(paragraphIsRTL ? lResult.width  : 0.0);
+			// we fake a previous reverse direction
+			itemIsRTL = !story->charAttributes(gs->itemTextPosition(gs->findItem(curPos))).testFlag(TextFlag_RightToLeft);
+			double iListWidth(0);
+			foreach(const QList<int>& iList, runs)
+			{
+				if(first)
+				{
+					first = false;
+					// cPosX is already setup
+				}
+				else
+				{
+					// at this point itemIsRTL represents the direction of the previous run
+					// and we know that we're in reversed direction and that previous run
+					// positioned the cursor at the end of its box in visual order
+					// + iListWidth represents the width of the previous run
+					if(paragraphIsRTL)
+					{
+						if(itemIsRTL) // current is LTR
+						{
+							foreach(const int& it, iList)
+							{
+								int c(qMax(gs->itemTextPosition(it), curPos));
+								int e(qMin(int(gs->itemCharCount(item) + c),  lResult.endPos));
+								double itemWidth(gs->itemWidth(it, c - gs->itemTextPosition(it), e - c + 1));
+								cPosX -= itemWidth;
+							}
+						} // current is RTL
+						else
+						{
+							cPosX -= iListWidth;
+						}
+					}
+					else
+					{
+						if(itemIsRTL) // current is LTR
+						{
+							foreach(const int& it, iList)
+							{
+								int c(qMax(gs->itemTextPosition(it), curPos));
+								int e(qMin(int(gs->itemCharCount(item) + c),  lResult.endPos));
+								double itemWidth(gs->itemWidth(it, c - gs->itemTextPosition(it), e - c + 1));
+								cPosX -= itemWidth;
+							}
+						} // current is RTL
+						else
+						{
+							cPosX -= iListWidth;
+						}
+					}
+				}
+				iListWidth = 0.0;
+				itemIsRTL = !itemIsRTL;
+				foreach(const int& it, iList)
+				{
+					int c(qMax(gs->itemTextPosition(it), curPos));
+					int e(qMin(int(gs->itemCharCount(it) + c),  lResult.endPos));
+					double itemWidth(gs->itemWidth(it, c - gs->itemTextPosition(it), e - c + 1));
+					iListWidth += itemWidth;
+					GlyphBox * glyphs(new GlyphBox(const_cast<GlyphStore*>(gs),  m_textFrame->doc()->PageColors, it, c, e));
+					qDebug()<<"ADD GLYPHBOX item"<<it<<"startpos"<<c<<"endpos"<<e<<"posx"<<cPosX<<"RTL"<<itemIsRTL<<"iWidth"<<itemWidth;
+					glyphs->setWidth(itemWidth);
+					glyphs->setAscent(asc);
+					glyphs->setDescent(-desc);
+					if(itemIsRTL)
+					{
+						glyphs->moveTo(cPosX - itemWidth, y);
+						cPosX -= itemWidth;
+					}
+					else
+					{
+						glyphs->moveTo(cPosX,y);
+						cPosX += itemWidth;
+					}
+					line->addBox(glyphs);
+				}
+			}
+
+			////
+//			int item(gs->findItem(curPos));
+//			double itemWidth(gs->itemWidth(item));
+//			bool itemIsRTL(story->charAttributes(gs->itemTextPosition(item)).testFlag(TextFlag_RightToLeft));
+//			double cPosX(itemIsRTL ? lResult.width : 0.0);
+//			int c(curPos);
+//			int e(gs->itemCharCount(item) + c);
+//			GlyphBox * glyphs(new GlyphBox(const_cast<GlyphStore*>(gs),  m_textFrame->doc()->PageColors, item, c, e));
+//			if(itemIsRTL)
+//			{
+//				glyphs->moveTo(cPosX - itemWidth, y);
+//				cPosX -= itemWidth;
+//			}
+//			else
+//			{
+//				glyphs->moveTo(x,y);
+//				cPosX += itemWidth;
+//			}
+//			glyphs->setWidth();
+//			glyphs->setAscent(asc);
+//			glyphs->setDescent(-desc);
+//			line->addBox(glyphs);
+//			while(e < lResult.endPos)
+//			{
+//				c = e+1;
+//				item = gs->findItem(c);
+//				itemWidth = gs->itemWidth(item);
+//				if(itemIsRTL != story->charAttributes(gs->itemTextPosition(item)).testFlag(TextFlag_RightToLeft))
+//				{
+//					// we need to go forward and find all consecutive items in the same direction
+//					QList<int> reversItems;
+//					double stackOffset(0);
+//					int curItem(item);
+//					while()
+//				}
+
+//				e = qMin(int(gs->itemCharCount(item) + c), lResult.endPos);
+//				glyphs = new GlyphBox(const_cast<GlyphStore*>(gs),  m_textFrame->doc()->PageColors, item, c, e);
+//				if(itemIsRTL)
+//					glyphs->moveTo(lResult.width - itemWidth, y);
+//				else
+//					glyphs->moveTo(x,y);
+//				glyphs->setWidth(gs->itemWidth(item));
+//				glyphs->setAscent(asc);
+//				glyphs->setDescent(-desc);
+//				line->addBox(glyphs);
+//			}
 
 
 		}

Modified: branches/ScribusOIF/scribus/text/boxes.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/text/boxes.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/boxes.cpp (original)
+++ branches/ScribusOIF/scribus/text/boxes.cpp Thu Nov 25 19:12:35 2010
@@ -39,7 +39,7 @@
 	m_x = newRect.x();
 	m_width = newRect.width();
 	m_descent = newRect.height() - m_ascent;
-	qDebug()<<"BoxGroup::addBox"<< b->toString()<< "\n\t->" <<toString();
+//	qDebug()<<"BoxGroup::addBox"<< b->toString()<< "\n\t->" <<toString();
 }
 
 void BoxGroup::render(ScPainter* p, const RenderOptions& renderOptions) const
@@ -414,12 +414,14 @@
 {
 	const CharStyle& style(m_glyphs->story()->charStyle(m_charStart));
 	const bool rtl(m_glyphs->story()->charAttributes(m_charStart).testFlag(TextFlag_RightToLeft));
+
 	p->save();
-	p->setPen(Qt::lightGray);
+	p->setPen(Qt::lightGray, 0.5, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin);
 	p->setFillMode(ScPainter::None);
-//	p->drawRect(x(), y()-m_ascent, width(), height());
+	p->drawRect(x(), y()-m_ascent, width(), height());
 	p->drawLine(FPoint(x(), y()), FPoint(x() + width(), y()));
 	p->restore();
+
 	p->save();
 	p->setAntialiasing(true);
 	if(rtl)

Modified: branches/ScribusOIF/scribus/text/glyphstore.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/text/glyphstore.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/glyphstore.cpp (original)
+++ branches/ScribusOIF/scribus/text/glyphstore.cpp Thu Nov 25 19:12:35 2010
@@ -242,12 +242,45 @@
 }
 
 
-double GlyphStore::itemWidth(uint i) const
+double GlyphStore::itemWidth(uint i, unsigned int start , unsigned int len) const
 {
 	double res = 0.0;
-	const GlyphLayout* end = itemGlyphStart(i) + itemGlyphCount(i);
-	for (const GlyphLayout* p = itemGlyphStart(i); p < end; ++p)
-		res += p->xadvance + p->xoffset;
+	const ItemData& item(m_items[i]);
+	if((0 == start)
+			&& ((0 == len) || (len >= item.charCount)))
+	{
+		const GlyphLayout* end = itemGlyphStart(i) + itemGlyphCount(i);
+		for (const GlyphLayout* p = itemGlyphStart(i); p < end; ++p)
+			res += p->xadvance + p->xoffset;
+	}
+	else
+	{
+		Cluster cluster(itemStart(i));
+		unsigned int limit(item.textPosition + len);
+		unsigned int ctp(0);
+		while(true)
+		{
+			ctp = cluster.textPosition();
+			if(ctp < start)
+			{
+				if(haveNext(cluster))
+					cluster = next(cluster);
+				else
+					break;
+				continue;
+			}
+			else if(ctp < limit)
+			{
+				res += clusterWidth(cluster);
+				if(haveNext(cluster))
+					cluster = next(cluster);
+				else
+					break;
+			}
+			else
+				break;
+		}
+	}
 	return res;
 }
 

Modified: branches/ScribusOIF/scribus/text/glyphstore.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/text/glyphstore.h
==============================================================================
--- branches/ScribusOIF/scribus/text/glyphstore.h (original)
+++ branches/ScribusOIF/scribus/text/glyphstore.h Thu Nov 25 19:12:35 2010
@@ -147,7 +147,9 @@
 	void markCluster(uint item, int charPos, GlyphLayout* start);
 	
 	/// returns the current width of this item
-	double itemWidth(uint i) const;
+	/// starting from start (start is a O based index in the char string hold by the item)
+	/// for len charachters (len == 0 stands for all chars in the item)
+	double itemWidth(uint i, unsigned int start = 0, unsigned int len = 0) const;
 	
 	/// splits an item after n chars
 	void splitItem(uint i, int n);

Modified: branches/ScribusOIF/scribus/text/linelayouter.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/text/linelayouter.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/linelayouter.cpp (original)
+++ branches/ScribusOIF/scribus/text/linelayouter.cpp Thu Nov 25 19:12:35 2010
@@ -49,28 +49,14 @@
 	double wordSpacing(m_layout->story()->charStyle(start).wordTracking());
 	QList<unsigned int> items;
 	double stackWidth(0.0);
-	double rtlStack(0.0);
-	bool rtl(false);
 	double currentClusterWidth(0.0);
 	unsigned int lastBreak(0);
 	double lastBreakWidth(0.0);
 	int resultCount(0);
 	int lastPos(start);
-	for(unsigned int i(firstItem); i < itemCount; ++i)
-	{
-		items << i;
-	}
-	foreach(unsigned int item, items)
+	for(unsigned int item(firstItem); item < itemCount; ++item)
 	{
 		Cluster cluster(gs->itemStart(item));
-		if(!rtl)
-			rtlStack = 0.0;
-		else if(!m_layout->story()->charAttributes(cluster.textPosition()).testFlag(TextFlag_RightToLeft))
-		{
-			stackWidth += rtlStack;
-			rtlStack = 0.0;
-		}
-		rtl = m_layout->story()->charAttributes(cluster.textPosition()).testFlag(TextFlag_RightToLeft);
 		while(true)
 		{
 			lastPos = cluster.textPosition();
@@ -93,7 +79,7 @@
 			currentClusterWidth = gs->clusterWidth(cluster) * wordSpacing;
 			if(0 == resultCount)
 			{
-				if((stackWidth + rtlStack + currentClusterWidth) > lineWidth)
+				if((stackWidth  + currentClusterWidth) > lineWidth)
 				{
 					if(lastBreak > 0)
 					{
@@ -101,10 +87,9 @@
 						ret << lr;
 						resultCount = 1;
 					}
-					else if(m_layout->story()->charAttributes(cluster.textPosition()).testFlag(TextFlag_HyphenationPossible)
-						|| SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
+					else if(SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
 					{
-						LineResult lr(stackWidth + rtlStack + currentClusterWidth, 1, cluster.textPosition()); // overfullbox
+						LineResult lr(stackWidth + currentClusterWidth, 1, cluster.textPosition()); // overfullbox
 						ret << lr;
 						resultCount = 1;
 					}
@@ -112,32 +97,28 @@
 				}
 				else if(cluster.textPosition() + 1 == m_layout->story()->length())
 				{
-					LineResult lr(stackWidth + rtlStack + currentClusterWidth, 0, cluster.textPosition());
+					LineResult lr(stackWidth + currentClusterWidth, 0, cluster.textPosition());
 					ret << lr;
 //					qDebug()<<"Inserting Line Result1"<<lr.width<<lr.endPos;
 					resultCount = 2;
 				}
 				// put a possible break for next iteration
-				if(m_layout->story()->charAttributes(cluster.textPosition()).testFlag(TextFlag_HyphenationPossible)
-					|| SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
+				if(SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
 				{
 					lastBreak = cluster.textPosition();
-					lastBreakWidth = stackWidth + rtlStack + currentClusterWidth;
+					lastBreakWidth = stackWidth + currentClusterWidth;
 				}
 			}
-			else if(m_layout->story()->charAttributes(cluster.textPosition()).testFlag(TextFlag_HyphenationPossible)
-				|| SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
+			else if( SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
 			{
-				LineResult lr(stackWidth + rtlStack + currentClusterWidth, 1, cluster.textPosition());
+				LineResult lr(stackWidth + currentClusterWidth, 1, cluster.textPosition());
 				ret << lr;
 //				qDebug()<<"Inserting Line Result2"<<lr.width<<lr.endPos;
 				resultCount = 2;
 				break;
 			}
-			if(rtl)
-				rtlStack += currentClusterWidth;
-			else
-				stackWidth += currentClusterWidth;
+
+			stackWidth += currentClusterWidth;
 
 			if(gs->haveNext(cluster))
 				cluster = gs->next(cluster);
@@ -150,7 +131,7 @@
 //qDebug()<<"Result len"<<ret.length();
 	if(ret.count() == 0)
 	{
-		LineResult lr(stackWidth + rtlStack, 0, lastPos);
+		LineResult lr(stackWidth, 0, lastPos);
 		ret << lr;
 	}
 	return ret;

Modified: branches/ScribusOIF/scribus/text/shaper.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/text/shaper.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/shaper.cpp (original)
+++ branches/ScribusOIF/scribus/text/shaper.cpp Thu Nov 25 19:12:35 2010
@@ -22,12 +22,13 @@
 
 #include "text/glyphstore.h"
 #include "text/storytext.h"
+#include "text/scbidi.h"
 #include "langmgr.h"
 
 #include <QDebug>
 
 Shaper::Shaper(TextLayout * lyt):
-		m_layout(lyt)
+	m_layout(lyt)
 {
 }
 
@@ -38,43 +39,49 @@
 	GlyphStore *gs(const_cast<GlyphStore*>(m_layout->storyGlyphs()));
 	LanguageManager * lm(LanguageManager::instance());
 
+	const QString txt(story->text(start, end - start));
+	ScBidi bidi(txt);
+
 	QList<uint> items;
 	// redo itemization for this run
 	CharStyle ref;
 	int itStart(start);
 	bool first(true);
-	bool rtl(false);
+	bool currentRTL( bidi.isRTL(0));
+	bool previousRTL(currentRTL);
 	for(int cursor(start); cursor <= end; ++cursor )
 	{
+		currentRTL = bidi.isRTL(cursor - start);
+		if(currentRTL)
+			story->charAttributes(cursor) |= TextFlag_RightToLeft;
+		else
+			story->charAttributes(cursor) &= ~TextFlag_RightToLeft;
 		if(first)
 		{
 			first = false;
 			ref = story->charStyle(cursor) ;
-			rtl = lm->isRightToLeft(lm->getAbbrevFromLang(story->charStyle(cursor).language(), false, false));
-			if(rtl)
-				story->charAttributes(cursor) |= TextFlag_RightToLeft;
-			else
-				story->charAttributes(cursor) &= ~TextFlag_RightToLeft;
 		}
 		else
 		{
 			if((story->charStyle(cursor) != ref)
-				|| (cursor == end))
+					|| (currentRTL != previousRTL)
+					|| (cursor == end))
 			{
 				if(cursor != end)
 				{
 					ref = story->charStyle(cursor) ;
-					rtl = lm->isRightToLeft(lm->getAbbrevFromLang(story->charStyle(cursor).language(), false, false));
+					items << gs->addItem(itStart, (cursor) - itStart);
 				}
-				items << gs->addItem(itStart, (cursor) - itStart + 1);
-				itStart = cursor + 1;
+				else
+				{
+					items << gs->addItem(itStart, (cursor) - itStart + 1);
+				}
+//				QString itemStr(story->text(itStart, (cursor) - itStart + 1));
+//				qDebug()<<"ADD ITEM"<<itStart<<(cursor) - itStart + 1<<itemStr;
+				itStart = cursor;
 			}
-			if(rtl)
-				story->charAttributes(cursor) |= TextFlag_RightToLeft;
-			else
-				story->charAttributes(cursor) &= ~TextFlag_RightToLeft;
 		}
-		qDebug()<<cursor<<story->charStyle(cursor).language()<<ref.language()<< rtl;
+		previousRTL = currentRTL;
 	}
 
 	foreach(uint it, items)

Modified: branches/ScribusOIF/scribus/text/specialchars.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/text/specialchars.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/specialchars.cpp (original)
+++ branches/ScribusOIF/scribus/text/specialchars.cpp Thu Nov 25 19:12:35 2010
@@ -151,12 +151,14 @@
 
 bool SpecialChars::isBreakingSpace(QChar c)
 {
-	return c == BLANK || c == ZWSPACE;
+//	return c == BLANK || c == ZWSPACE;
+	return c.isSpace() && (c != NBSPACE);
 }
 
 bool SpecialChars::isExpandingSpace(QChar c)
 {
-	return c == BLANK || c == NBSPACE;
+//	return c == BLANK || c == NBSPACE;
+	return c.isSpace() && (c != ZWSPACE);
 }
 
 bool SpecialChars::isBreak(QChar c, bool includeColBreak)

Modified: branches/ScribusOIF/scribus/third_party/CMakeLists.txt
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15990&path=/branches/ScribusOIF/scribus/third_party/CMakeLists.txt
==============================================================================
--- branches/ScribusOIF/scribus/third_party/CMakeLists.txt (original)
+++ branches/ScribusOIF/scribus/third_party/CMakeLists.txt Thu Nov 25 19:12:35 2010
@@ -15,3 +15,4 @@
 ADD_SUBDIRECTORY(pgf)
 
 ADD_SUBDIRECTORY(harfbuzz/src)
+ADD_SUBDIRECTORY(fribidi)




More information about the scribus-commit mailing list