r15877 by pierremarc - Changed store model for cluster offsets, which allowed to display many paragraphs.

scribus-commit scribus-commit at lists.scribus.net
Mon Nov 15 17:42:17 CET 2010


Author: pierremarc
Date: Mon Nov 15 16:42:17 2010
New Revision: 15877

URL: http://scribus.info/websvn/listing.php?repname=Scribus&sc=1&rev=15877
Log:
Changed store model for cluster offsets, which allowed to display many paragraphs.

Modified:
    branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
    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/shaper.cpp
    branches/ScribusOIF/scribus/text/textlayout.cpp

Modified: branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15877&path=/branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface_ttf.cpp (original)
+++ branches/ScribusOIF/scribus/fonts/scface_ttf.cpp Mon Nov 15 16:42:17 2010
@@ -747,6 +747,7 @@
 	QString language(story->charStyle(gs->itemTextPosition(item)).language());
 	bool isAuto(story->charStyle(gs->itemTextPosition(item)).autoShape());
 	double fSize(story->charStyle(gs->itemTextPosition(item)).fontSize() /10.0);
+	int itemPos(gs->itemTextPosition(item));
 	if(isAuto)
 	{
 		LanguageManager *lm(LanguageManager::instance());
@@ -795,27 +796,28 @@
 				stackY = positions[ ( ( gIdx + 1 ) * 2 ) + 1];
 				glList << curGlyph;
 				charList << indices[gIdx];
-				qDebug()<<"icu"<<text.at(indices[gIdx])<< curGlyph.glyph <<curGlyph.xadvance <<curGlyph.yoffset ;
+				qDebug()<<"icu"<<text.at(indices[gIdx])<< itemPos + indices[gIdx] << curGlyph.glyph <<curGlyph.xadvance <<curGlyph.yoffset ;
 			}
 		}
 		icuLE->reset();
 
-		delete  ts;
-		delete  glyphs;
-		delete  indices;
-		delete  positions;
+		delete[]  ts;
+		delete[]  glyphs;
+		delete[]  indices;
+		delete[]  positions;
 		gs->itemSetGlyphCount(item, glList.count());
 		GlyphLayout* curGlyph(gs->itemGlyphStart(item));
 		for(unsigned int i(0); i < glList.count(); ++i)
 		{
 			const GlyphLayout& g(glList.at(i));
-			const le_int32& c(charList.at(i) + gs->itemTextPosition(item));
+			const le_int32& c(charList.at(i) + itemPos);
 			curGlyph->glyph = g.glyph;
 			curGlyph->xadvance = g.xadvance;
 			curGlyph->xoffset = g.xoffset;
 			curGlyph->yadvance = g.yadvance;
 			curGlyph->yoffset = g.yoffset;
 			gs->markCluster(item, c , curGlyph);
+			const_cast<TextFlags&>(story->charAttributes(c)) |= TextFlag_ClusterStart;
 			++curGlyph;
 		}
 
@@ -882,7 +884,8 @@
 			curGlyph->yoffset = gp.y_offset;
 			curGlyph->glyph = gi.codepoint;
 
-			gs->markCluster(item, gi.cluster + gs->itemTextPosition(item) , curGlyph);
+			gs->markCluster(item, gi.cluster + itemPos , curGlyph);
+			const_cast<TextFlags&>(story->charAttributes(gi.cluster + itemPos)) |= TextFlag_ClusterStart;
 
 			qDebug()<<"ScFace_ttf::shapeText:" <<curGlyph->glyph <<glyphWidth(gi.codepoint, fSize) <<curGlyph->xadvance <<curGlyph->xoffset;
 

Modified: branches/ScribusOIF/scribus/text/blocklayouter.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15877&path=/branches/ScribusOIF/scribus/text/blocklayouter.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/blocklayouter.cpp (original)
+++ branches/ScribusOIF/scribus/text/blocklayouter.cpp Mon Nov 15 16:42:17 2010
@@ -64,11 +64,10 @@
 	double asc(charStyle.font().ascent() * charStyle.fontSize() / 10.0);
 	double desc(charStyle.font().descent() * charStyle.fontSize() / 10.0);
 	double y(0.0);
-	double x(parStyle.leftMargin() + parStyle.firstIndent());
+	double x(parStyle.leftMargin());
 	if(bg->boxCount() > 0)
 	{
-		const Box* previousBox(bg->boxes().last());
-		y =  previousBox->bbox().bottom()
+		y =  m_layout->box()->bbox().bottom()
 		     + story->paragraphStyle(startPos - 1).gapAfter()
 		     + parStyle.gapBefore();
 	}
@@ -76,7 +75,7 @@
 
 	VBox * resultBox(new VBox);
 	resultBox->moveTo(x,y);
-	double width(m_textFrame->width());
+	double width(m_textFrame->width() - (parStyle.leftMargin() + parStyle.rightMargin()) );
 	int curPos(startPos);
 	while(curPos < endPos)
 	{

Modified: branches/ScribusOIF/scribus/text/boxes.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15877&path=/branches/ScribusOIF/scribus/text/boxes.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/boxes.cpp (original)
+++ branches/ScribusOIF/scribus/text/boxes.cpp Mon Nov 15 16:42:17 2010
@@ -43,15 +43,15 @@
 		double tBottom(m_y + height());
 		double maxBottom(qMax(bBottom, tBottom));
 		m_y = qMin(m_y, b->y());
-		m_ascent = maxBottom - m_y;
-		m_descent = 0;
+		m_ascent = qMax(b->ascent(), m_ascent);
+		m_descent = (maxBottom - m_y) - m_ascent;
 	}
 	else
 	{
 		m_ascent = qMax(b->ascent(), m_ascent);
 		m_descent = qMax(b->descent(), m_descent);
-	}
-	m_y = qMin(m_y, b->y());
+		m_y = qMin(m_y, b->y());
+	}
 	qDebug()<<"BoxGroup::addBox"<< b->toString()<<toString();
 }
 
@@ -456,7 +456,7 @@
 		strokeColor.setAlphaF(shade / 100.0);
 		p->setPen(strokeColor, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
 	}
-
+qDebug() << "Render"<<m_item<<m_charStart<<m_charEnd;
 	Cluster cluster(m_glyphs->itemStart(m_item));
 	while(cluster.textPosition() <= m_charEnd)
 	{

Modified: branches/ScribusOIF/scribus/text/glyphstore.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15877&path=/branches/ScribusOIF/scribus/text/glyphstore.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/glyphstore.cpp (original)
+++ branches/ScribusOIF/scribus/text/glyphstore.cpp Mon Nov 15 16:42:17 2010
@@ -10,6 +10,66 @@
 #include "glyphstore.h"
 #include "sctextstruct.h"
 
+
+
+int GlyphStore::clusterOffsetForGlyph(uint glyphIndex) const
+{
+	return m_clusterOffsets[m_clusterRuns[glyphIndex]];
+}
+
+int GlyphStore::textPosForGlyph(uint i, uint glyphIndex) const
+{
+//	int delta = clusterOffsetForGlyph(glyphIndex);
+	const ItemData& item(m_items[i]);
+//	return item.textPosition + (glyphIndex - item.glyphIndex) + delta;
+	return  m_clusterOffsets[glyphIndex + item.glyphIndex];
+	for(uint c(item.glyphIndex); c <= (item.glyphIndex + item.glyphCount); ++c)
+	{
+		if(m_clusterOffsets[c] == glyphIndex)
+			return c;
+	}
+	qDebug() << "Failed to find Text Pos for:"<<i<<glyphIndex;
+	return item.textPosition + item.charCount - 1;
+}
+
+uint GlyphStore::glyphIndexForCharacter(uint i, int pos) const
+{
+	assert( signed(i) < m_items.count() );
+	const ItemData& item(m_items[i]);
+	if(m_clusterOffsets.contains(pos))
+		return m_clusterOffsets.value(pos) - item.glyphIndex;
+	qDebug() << "Failed to find glyph Index for:"<<i<<pos;
+	return item.glyphCount;
+
+//	uint glyphIndex = pos - item.textPosition;
+////	qDebug() << "glyphIndexForCharacter:" << i << "of" << m_items.count() << pos << item.textPosition << item.charCount << item.glyphIndex << item.glyphCount;
+
+//	if (item.glyphCount == 0 || pos < item.textPosition)
+//	{
+//		qDebug() << "glyphIndexForCharacter RESULT 0";
+//		return 0;
+//	}
+
+//	if (glyphIndex > item.glyphCount)
+//		glyphIndex = item.glyphCount;
+//	else
+//	{
+//		// here we have more glyphs than characters
+////		qDebug() << "+" << clusterOffsetForGlyph(glyphIndex) << "/" << glyphIndex;
+//		while (glyphIndex < item.glyphCount && signed(glyphIndex + clusterOffsetForGlyph(glyphIndex)) < pos )
+//		{
+//			++glyphIndex;
+//		}
+//	}
+//	// here we have less glyphs than characters; now we make sure to get the first glyphIndex that matches pos
+////	qDebug() << "-" << clusterOffsetForGlyph(glyphIndex-1) << "/" << glyphIndex;
+//	while (glyphIndex > 0 && signed(glyphIndex - 1 + clusterOffsetForGlyph(glyphIndex - 1)) >= pos)
+//	{
+//		--glyphIndex;
+//	}
+////	qDebug() << "<--" << glyphIndex;
+//	return glyphIndex;
+}
 
 
 uint GlyphStore::addItem(int pos, uint len)
@@ -235,19 +295,21 @@
 	int delta = (charPos - item.textPosition) - (glyphIndex - item.glyphIndex);
 	if (delta != 0)
 		qDebug() << "markCluster: delta" << charPos-item.textPosition << "~" << glyphIndex-item.glyphIndex;
-	uint run = m_clusterRuns[glyphIndex];
-	if (m_clusterOffsets[run] != delta)
-	{
-		if (m_clusterRuns.offset(run) == glyphIndex)
-		{
-			m_clusterOffsets[run] = delta;
-		}
-		else
-		{
-			run = m_clusterRuns.insert(glyphIndex);
-			m_clusterOffsets.insert(run, delta);
-		}
-	}	
+//	m_clusterOffsets.insert(glyphIndex, m_clusterRuns.insert(charPos));
+	m_clusterOffsets.insert(charPos, glyphIndex);
+//	uint run = m_clusterRuns[glyphIndex];
+//	if (m_clusterOffsets[run] != delta)
+//	{
+//		if (m_clusterRuns.offset(run) == glyphIndex)
+//		{
+//			m_clusterOffsets[run] = delta;
+//		}
+//		else
+//		{
+//			run = m_clusterRuns.insert(glyphIndex);
+//			m_clusterOffsets.insert(run, delta);
+//		}
+//	}
 }
 
 /// returns the Cluster following c
@@ -258,16 +320,26 @@
 	const ItemData& item(m_items[c.m_item]);
 	int pos = c.m_pos;
 	int len = m_story->length();
-	while (pos < item.textPosition + signed(item.charCount)) {
-		++pos;
-		if (pos >= len || (m_story->charAttributes(pos) & TextFlag_ClusterStart) != 0)
-			break;
-	}
-	if (pos >= item.textPosition + signed(item.charCount))
+	QMap<int,int>::iterator it(m_clusterOffsets.find(pos));
+	it++;
+	int nextPos = -1;
+	if(it != m_clusterOffsets.end())
+		nextPos = it.key();
+//	while (pos < item.textPosition + signed(item.charCount)) {
+//		++pos;
+//		if (pos >= len || (m_story->charAttributes(pos) & TextFlag_ClusterStart) != 0)
+//			break;
+//	}
+
+	if ((nextPos < 0)
+		|| (nextPos >= item.textPosition + signed(item.charCount)))
 		return Cluster(NULL, -1, 0); // not valid
 	else
 	{
-		return Cluster(const_cast<GlyphLayout*>(itemGlyphStart(c.m_item) + glyphIndexForCharacter(c.m_item, pos)), pos, c.m_item);
+		Cluster rc(const_cast<GlyphLayout*>(itemGlyphStart(c.m_item) + glyphIndexForCharacter(c.m_item, nextPos)),
+			   nextPos,
+			   c.m_item);
+		return rc;
 	}
 }
 

Modified: branches/ScribusOIF/scribus/text/glyphstore.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15877&path=/branches/ScribusOIF/scribus/text/glyphstore.h
==============================================================================
--- branches/ScribusOIF/scribus/text/glyphstore.h (original)
+++ branches/ScribusOIF/scribus/text/glyphstore.h Mon Nov 15 16:42:17 2010
@@ -13,7 +13,7 @@
 #undef NDEBUG
 
 #include <QDebug>
-#include <QHash>
+#include <QMap>
 #include <QList>
 #include "glyphlayout.h"
 #include "sctextstruct.h"
@@ -96,58 +96,17 @@
 	QList<ItemData> m_items;
 	
 	/// fine segmentation: stored as difference between glyphIndex and textPos. If each char has exactly one glyph, all offsets equal 0
-	QHash<int,int> m_clusterOffsets;
+	QMap<int,int> m_clusterOffsets;
 	Index m_clusterRuns;
 	
 	/// returns the offset for glyphIndex
-	int clusterOffsetForGlyph(uint glyphIndex) const
-	{
-		return m_clusterOffsets[m_clusterRuns[glyphIndex]];
-	}
+	int clusterOffsetForGlyph(uint glyphIndex) const;
 	
 	/// returns the text position given an item and a glyphIndex
-	int textPosForGlyph(uint i, uint glyphIndex) const
-	{
-		int delta = clusterOffsetForGlyph(glyphIndex);
-		const ItemData& item(m_items[i]);
-		return item.textPosition + (glyphIndex - item.glyphIndex) + delta;
-	}
+	int textPosForGlyph(uint i, uint glyphIndex) const;
 	
 	/// returns the glyph index for a given character position
-	uint glyphIndexForCharacter(uint i, int pos) const
-	{
-		assert( signed(i) < m_items.count() );
-		
-		const ItemData& item(m_items[i]);
-		uint glyphIndex = pos - item.textPosition;
-		//qDebug() << "glyphIndexForCharacter:" << i << "of" << m_items.count() << pos << item.textPosition << item.charCount << item.glyphIndex << item.glyphCount;
-		
-		if (item.glyphCount == 0 || pos < item.textPosition)
-		{
-			qDebug() << "glyphIndexForCharacter RESULT 0";
-			return 0;
-		}
-		
-		if (glyphIndex > item.glyphCount)
-			glyphIndex = item.glyphCount;
-		else
-		{
-			// here we have more glyphs than characters
-			//qDebug() << "+" << clusterOffsetForGlyph(glyphIndex) << "/" << glyphIndex;
-			while (glyphIndex < item.glyphCount && signed(glyphIndex + clusterOffsetForGlyph(glyphIndex)) < pos )
-			{
-				++glyphIndex;
-			}
-		}
-		// here we have less glyphs than characters; now we make sure to get the first glyphIndex that matches pos
-		//qDebug() << "-" << clusterOffsetForGlyph(glyphIndex-1) << "/" << glyphIndex;
-		while (glyphIndex > 0 && signed(glyphIndex - 1 + clusterOffsetForGlyph(glyphIndex - 1)) >= pos)
-		{
-			--glyphIndex;
-		}
-		//qDebug() << "<--" << glyphIndex;
-		return glyphIndex;
-	}
+	uint glyphIndexForCharacter(uint i, int pos) const;
 		
 public:
 	

Modified: branches/ScribusOIF/scribus/text/shaper.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15877&path=/branches/ScribusOIF/scribus/text/shaper.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/shaper.cpp (original)
+++ branches/ScribusOIF/scribus/text/shaper.cpp Mon Nov 15 16:42:17 2010
@@ -23,6 +23,8 @@
 #include "text/glyphstore.h"
 #include "text/storytext.h"
 
+#include <QDebug>
+
 Shaper::Shaper(TextLayout * lyt):
 		m_layout(lyt)
 {
@@ -34,18 +36,7 @@
 	StoryText * story(const_cast<StoryText *>(m_layout->story()));
 	GlyphStore *gs(const_cast<GlyphStore*>(m_layout->storyGlyphs()));
 
-	// clusters will be set by the shaper itself. Might be an idea to have a resetClusters method in StoryText
-	TextFlags* textFlags = &(story->charAttributes(start));
-	for (int i=0; i < end-start; ++i)
-	{
-		textFlags[i] ^= TextFlag_ClusterStart;
-	}
-
-	// reset items for this run. Radical!
-	QList<uint> items(gs->findItems(start, end));
-	gs->deleteItems(items);
-	items.clear();
-
+	QList<uint> items;
 	// redo itemization for this run
 	CharStyle ref;
 	int itStart(start);
@@ -62,7 +53,8 @@
 			if((story->charStyle(cursor) != ref)
 				|| (cursor == end))
 			{
-				items << gs->addItem(itStart, (cursor) - itStart);
+				items << gs->addItem(itStart, (cursor) - itStart + 1);
+				qDebug()<<"AddItem"<<itStart<< (cursor - itStart + 1);
 				itStart = cursor + 1;
 			}
 		}

Modified: branches/ScribusOIF/scribus/text/textlayout.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15877&path=/branches/ScribusOIF/scribus/text/textlayout.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/textlayout.cpp (original)
+++ branches/ScribusOIF/scribus/text/textlayout.cpp Mon Nov 15 16:42:17 2010
@@ -27,6 +27,7 @@
 #include "textlayout.h"
 #include "text/blocklayouter.h"
 #include "text/shaper.h"
+#include "scribusdoc.h"
 
 #include <QDebug>
 
@@ -326,7 +327,9 @@
 	if(m_layout)
 		delete m_layout;
 	m_layout = new VBox;
+	m_layout->moveTo(m_frame->xPos(), m_frame->yPos());
 	m_firstInFrame = 0;
+	const int storyLen = m_story->length();
 	// a) the caller _MUST_ ensure that previous frame can provide a valid endOfFrame
 	// b) We adjust m_firstInFrame based on back frame
 	// c) finally return if there's no more text to layout
@@ -337,27 +340,41 @@
 		m_firstInFrame = m_frame->prevInChain()->textLayout->endOfFrame() + 1;
 	}
 
-	if(m_firstInFrame >= m_story->length())
+	if(m_firstInFrame >= storyLen)
 	{
 		m_lastInFrame = m_firstInFrame;
 		return;
 	}
+
+	// clusters will be set by the shaper itself. Might be an idea to have a resetClusters method in StoryText
+	for (int i(m_firstInFrame); i < storyLen; ++i)
+	{
+		m_story->charAttributes(i) &= ~TextFlag_ClusterStart;
+	}
+
+	// reset items for this run. Radical!
+	m_story->glyphStore()->deleteItems(m_story->glyphStore()->findItems(m_firstInFrame, storyLen - 1));
 
 	// We run each paragraph through the block layouter and adjust m_lastInFrame
 	int parIdx(m_story->nrOfParagraph(m_firstInFrame));
 	Shaper *shaper = new Shaper(this);
 	while(parIdx >= 0)
 	{
+		int parSep = -1;
 		int startOfPar(qMax(m_story->startOfParagraph(parIdx), m_firstInFrame));
-//		while((startOfPar < m_story->length() )
-//			&& (m_story->text(startOfPar,1) == SpecialChars::PARSEP))
-//			++startOfPar;
-		int endOfPar(m_story->endOfParagraph(parIdx));
+		int endOfPar(m_story->endOfParagraph(parIdx) - 1);
+		qDebug()<< "StartOfPar"<<startOfPar << m_story->text(startOfPar,1).at(0).unicode()
+				<< "EndOfPar"<<endOfPar << m_story->text(endOfPar,1).at(0).unicode();
 		if(endOfPar <= startOfPar)
 		{
 			parIdx =  m_story->nrOfParagraph(endOfPar + 1);
 			continue;
 		}
+		if(m_story->text(endOfPar,1).at(0) == SpecialChars::PARSEP)
+		{
+			parSep = endOfPar;
+			--endOfPar;
+		}
 		// We prepare the GlyphStore per paragraph
 		shaper->shape(startOfPar, endOfPar);
 
@@ -365,9 +382,32 @@
 		if(result.lastPos >= 0)
 		{
 			m_layout->addBox( result.box );
+			// FIXME_OIF position the parsep
+			if(parSep >= 0)
+			{
+				GlyphBox * psGlyph = 0;
+				int psItem(m_story->glyphStore()->addItem(parSep, 1));
+				m_story->glyphStore()->itemSetGlyphCount(psItem, 1);
+				m_story->glyphStore()->itemGlyphStart(psItem)->glyph = ScFace::CONTROL_GLYPHS +  SpecialChars::PARSEP.unicode();
+				psGlyph = new GlyphBox(m_story->glyphStore(), m_frame->doc()->PageColors, psItem, endOfPar, endOfPar);
+				psGlyph->setWidth(0);
+				psGlyph->setAscent(0);
+				psGlyph->setDescent(0);
+				psGlyph->moveTo(m_layout->x(),m_layout->y());
+				const_cast<TextFlags&>(m_story->charAttributes(parSep)) |= TextFlag_ClusterStart;
+				m_story->glyphStore()->markCluster(psItem, parSep, m_story->glyphStore()->itemGlyphStart(psItem));
+				m_layout->addBox(psGlyph);
+			}
 			qDebug()<<"Add Par Box:"<<result.box->toString();
 			m_lastInFrame = result.lastPos;
-			int nextPar(m_story->nrOfParagraph(result.lastPos + 1));
+			// seek next paragraph, if any
+			int nextPar(parIdx);
+			for(int lp(result.lastPos + 1); lp <= storyLen; ++lp)
+			{
+				nextPar = m_story->nrOfParagraph(lp);
+				if(nextPar > parIdx)
+					break;
+			}
 			if(nextPar > parIdx)
 				parIdx = nextPar;
 			else




More information about the scribus-commit mailing list