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