Subversion Repositories Scribus

Compare Revisions

Ignore whitespace Rev 16036 → Rev 16037

/branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
768,23 → 768,17
++ci;
}
icuLE->reset();
int glAllocated = icuLE->layoutChars( ts, 0, sCount , sCount, isRTL, 0, 0, err );
/*int glAllocated = */icuLE->layoutChars( ts, 0, sCount , sCount, isRTL, 0, 0, err );
 
le_int32 gCount(icuLE->getGlyphCount());
LEGlyphID *glyphs = new LEGlyphID[gCount];
le_int32 *indices = new le_int32[gCount];
// float *positions = new float[ ( glAllocated * 2 ) + 2];
icuLE->getGlyphs ( glyphs, err );
icuLE->getCharIndices ( indices, err );
// icuLE->getGlyphPositions ( positions, err );
// float stackX ( 0.0 );
// float stackY ( 0.0 );
float xShift(0.0);
float yShift(0.0);
QList<GlyphLayout> glList;
QList<le_int32> charList;
QList<bool> markList;
double sHeight((m_ascent - m_descent) * fSize);
QList<le_int32> baseCharList;
double sFactor(fSize / m_uniEM);
float icuX(0);
float icuY(0);
806,38 → 800,33
icuFwdY *= sFactor;
if(err != LE_NO_ERROR)
continue;
QChar c(text.at(indices[gIdx]));
bool isDiacritic(c.isMark());
bool isCombining(indices[gIdx] == indices[nextIdx]);
bool isCombining(text.at(indices[gIdx]).isMark());
GlyphLayout curGlyph;
curGlyph.glyph = glyphs[gIdx];
curGlyph.xadvance = glyphWidth(curGlyph.glyph, fSize);
curGlyph.xoffset = isRTL ? (icuFwdX - icuX) - curGlyph.xadvance : xShift;
curGlyph.yoffset = yShift;
curGlyph.yoffset = icuY;
curGlyph.yadvance = 0;
xShift = (icuFwdX - icuX) - curGlyph.xadvance;
yShift = (icuFwdY - icuY) - sHeight;
if(isDiacritic || isCombining)
yShift -= sHeight - curGlyph.yoffset;
// stackY = icuFwdY;
// stackX = icuX;
if(isRTL)
{
glList.prepend( curGlyph );
charList.prepend(indices[gIdx]);
markList.prepend(isDiacritic);
if(!isCombining)
baseCharList.prepend(indices[gIdx]);
}
else
{
glList << curGlyph;
charList << indices[gIdx];
markList << isDiacritic;
if(!isCombining)
baseCharList << indices[gIdx];
}
// qDebug()<<"icu"<<indices[gIdx]
// << curGlyph.glyph
// << sHeight
// << icuY
// << icuFwdY ;
// << icuFwdY;
}
}
icuLE->reset();
845,24 → 834,30
delete[] ts;
delete[] glyphs;
delete[] indices;
// delete[] positions;
gs->itemSetGlyphCount(item, glList.count());
GlyphLayout* curGlyph(gs->itemGlyphStart(item));
GlyphLayout* startOfCluster(curGlyph);
int baseCharIdx(0);
for(unsigned int i(0); i < glList.count(); ++i)
{
const GlyphLayout& g(glList.at(i));
const le_int32& c(charList.at(i) + itemPos);
bool isCombining((i > 0) && (c == charList.at(i-1) + itemPos));
curGlyph->glyph = g.glyph;
curGlyph->xadvance = g.xadvance;
curGlyph->xoffset = g.xoffset;
curGlyph->yadvance = g.yadvance;
curGlyph->yoffset = g.yoffset;
if(!markList.at(i) && !isCombining)
if(baseCharIdx < baseCharList.count()
&& baseCharList.at(baseCharIdx) == charList.at(i))
{
gs->markCluster(item, c , curGlyph);
gs->markCluster(item, c , startOfCluster);
const_cast<TextFlags&>(story->charAttributes(c)) |= TextFlag_ClusterStart;
startOfCluster = curGlyph + 1;
baseCharIdx++;
}
if(baseCharIdx < baseCharList.count()
&& charList.at(i) < baseCharList.at(baseCharIdx))
startOfCluster = curGlyph + 1;
++curGlyph;
}
 
/branches/ScribusOIF/scribus/fonts/scicufont.cpp
74,7 → 74,9
if ( !FT_Load_Glyph ( face, glyph , FT_LOAD_NO_SCALE ) )
{
advance.fX = face->glyph->metrics.horiAdvance;
advance.fY = face->glyph->metrics.vertAdvance;
// Would be relevant only for fonts with vertical metrics
// advance.fY = face->glyph->metrics.vertAdvance;
advance.fY = 0;
}
else
{
/branches/ScribusOIF/scribus/ui/storyeditor.cpp
634,8 → 634,8
updateAll();
int npars = currItem->itemText.nrOfParagraphs();
SelParaStart = 0;
while (currItem->CPos >= (SelCharStart = currItem->itemText.endOfParagraph(SelParaStart))
&& SelParaStart < npars)
while (SelParaStart < npars
&& currItem->CPos >= (SelCharStart = currItem->itemText.endOfParagraph(SelParaStart)))
++SelParaStart;
if (currItem->CPos < SelCharStart)
SelCharStart = currItem->CPos;
/branches/ScribusOIF/scribus/text/glyphstore.cpp
14,7 → 14,7
 
int GlyphStore::clusterOffsetForGlyph(uint glyphIndex) const
{
return m_clusterOffsets[m_clusterRuns[glyphIndex]];
// return m_clusterOffsets[m_clusterRuns[glyphIndex]];
}
 
int GlyphStore::textPosForGlyph(uint i, uint glyphIndex) const
22,12 → 22,18
// 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)
const int cCount(m_clusterOffsets.count());
for(int c(0); c < cCount; ++c)
{
if(m_clusterOffsets[c] == glyphIndex)
return c;
if(m_clusterOffsets.at(c).second == int(glyphIndex))
return m_clusterOffsets.at(c).first;
}
// 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;
}
36,8 → 42,12
{
assert( signed(i) < m_items.count() );
const ItemData& item(m_items[i]);
if(m_clusterOffsets.contains(pos))
return m_clusterOffsets.value(pos) - item.glyphIndex;
const int cCount(m_clusterOffsets.count());
for(int c(0); c < cCount; ++c)
{
if(m_clusterOffsets.at(c).first == pos)
return m_clusterOffsets.at(c).second - item.glyphIndex;
}
qDebug() << "Failed to find glyph Index for:"<<i<<pos;
return item.glyphCount;
 
89,10 → 99,20
void GlyphStore::clearItem(uint i)
{
itemSetGlyphCount(i, 0);
for(int idx(m_items[i].textPosition); idx < m_items[i].textPosition + m_items[i].charCount; ++idx)
const ItemData& item(m_items[i]);
const int cCount(m_clusterOffsets.count());
QList<int> toRemove;
for(int c(0); c < cCount; ++c)
{
m_clusterOffsets.remove(idx);
if(m_clusterOffsets.at(c).first >= item.textPosition
&& m_clusterOffsets.at(c).first < item.textPosition + item.charCount)
toRemove << c;
}
foreach (const int& r, toRemove)
{
m_clusterOffsets.removeAt(r);
}
 
}
 
 
104,12 → 124,13
if(firstItem > 0)
{
int firstChar = m_items[firstItem].textPosition;
QMap<int, int> tmpC;
foreach(const int& k, m_clusterOffsets.keys())
QList< QPair<int, int> > tmpC;
const int cCount(m_clusterOffsets.count());
for(int c(0); c < cCount; ++c)
{
if(k == firstChar)
if(m_clusterOffsets.at(c).first == firstChar)
break;
tmpC.insert(k, m_clusterOffsets.value(k));
tmpC << m_clusterOffsets.at(c);
}
m_clusterOffsets = tmpC;
}
331,7 → 352,14
 
Cluster GlyphStore::itemStart(uint i) const
{
return Cluster(const_cast<GlyphLayout*>(m_glyphs.constData() + m_items[i].glyphIndex), m_items[i].textPosition, i);
const int tp(m_items[i].textPosition);
const int cCount(m_clusterOffsets.count());
for(int c(0); c < cCount; ++c)
{
if(m_clusterOffsets.at(c).first == tp)
return Cluster(const_cast<GlyphLayout*>(m_glyphs.constData() + m_clusterOffsets.at(c).second), tp, i, c);
}
// return Cluster(const_cast<GlyphLayout*>(m_glyphs.constData() + m_items[i].glyphIndex), m_items[i].textPosition, i);
}
 
 
352,10 → 380,12
const ItemData& item(m_items[i]);
int glyphIndex = (clusterStart - m_glyphs.data());
int delta = (charPos - item.textPosition) - (glyphIndex - item.glyphIndex);
// qDebug() << "markCluster:"<<i<<charPos<<glyphIndex;
// if (delta != 0)
// qDebug() << "markCluster: delta" << charPos-item.textPosition << "~" << glyphIndex-item.glyphIndex;
// m_clusterOffsets.insert(glyphIndex, m_clusterRuns.insert(charPos));
m_clusterOffsets.insert(charPos, glyphIndex);
m_clusterOffsets.append(qMakePair(charPos,glyphIndex));
// m_clusterOffsets.insert(charPos, glyphIndex);
// uint run = m_clusterRuns[glyphIndex];
// if (m_clusterOffsets[run] != delta)
// {
377,26 → 407,18
assert( c.isValid() );
const ItemData& item(m_items[c.m_item]);
int pos = c.m_pos;
int len = m_story->length();
QMap<int,int>::iterator it(m_clusterOffsets.lowerBound(pos + 1));
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;
// }
int nextClusterIndex(c.m_ref + 1);
int nextPos(nextClusterIndex < m_clusterOffsets.count() ? m_clusterOffsets.at(nextClusterIndex).first : -1);
 
if ((nextPos < 0)
|| (nextPos >= item.textPosition + signed(item.charCount)))
return Cluster(NULL, -1, 0); // not valid
return Cluster(NULL, -1, 0, -1); // not valid
else
{
Cluster rc(const_cast<GlyphLayout*>(itemGlyphStart(c.m_item) + glyphIndexForCharacter(c.m_item, nextPos)),
Cluster rc(const_cast<GlyphLayout*>(m_glyphs.constData() + m_clusterOffsets.at(nextClusterIndex).second),
nextPos,
c.m_item);
c.m_item,
nextClusterIndex);
return rc;
}
}
431,7 → 453,8
Cluster n = next(c);
if (n.isValid())
{
uint ret(n.glyphs() - c.glyphs());
// uint ret(n.glyphs() - c.glyphs());
uint ret(abs(m_clusterOffsets.at(n.m_ref).second - m_clusterOffsets.at(c.m_ref).second));
Q_ASSERT(ret <= item.glyphCount);
return ret;
}
460,18 → 483,18
 
void GlyphStore::dump() const
{
for (int i=0; i < m_items.count(); ++i)
{
const ItemData& it(m_items[i]);
qDebug() << i << "item" << it.textPosition << it.charCount << "glyphs" << it.glyphIndex << it.glyphCount;
}
QString s("clusteroffsets:");
for (int k =0; k < m_clusterRuns.count(); ++k)
{
s += " ";
s += m_clusterOffsets[k];
s += "@";
s += m_clusterRuns.offset(k);
}
qDebug() << s << m_clusterRuns.count() << m_clusterOffsets.count();
// for (int i=0; i < m_items.count(); ++i)
// {
// const ItemData& it(m_items[i]);
// qDebug() << i << "item" << it.textPosition << it.charCount << "glyphs" << it.glyphIndex << it.glyphCount;
// }
// QString s("clusteroffsets:");
// for (int k =0; k < m_clusterRuns.count(); ++k)
// {
// s += " ";
// s += m_clusterOffsets[k];
// s += "@";
// s += m_clusterRuns.offset(k);
// }
// qDebug() << s << m_clusterRuns.count() << m_clusterOffsets.count();
}
/branches/ScribusOIF/scribus/text/textlayout.cpp
364,6 → 364,9
int parSep = -1;
int startOfPar(qMax(m_story->startOfParagraph(parIdx), m_firstInFrame));
int endOfPar(m_story->endOfParagraph(parIdx) - 1);
// FIXME - really figure out what's happening
if(startOfPar >= endOfPar)
break;
qDebug()<< "StartOfPar"<<startOfPar << m_story->text(startOfPar,1).at(0).unicode()
<< "EndOfPar"<<endOfPar << m_story->text(endOfPar,1).at(0).unicode();
if(endOfPar <= startOfPar)
/branches/ScribusOIF/scribus/text/glyphstore.h
14,6 → 14,7
 
#include <QDebug>
#include <QMap>
#include <QPair>
#include <QList>
#include "glyphlayout.h"
#include "sctextstruct.h"
38,8 → 39,9
int m_pos;
uint m_item;
GlyphLayout* m_glyphs;
int m_ref; // this private reference can be used by GlyphStore to indicate e.g. an index into an array, making it way faster to find next/previous cluster
Cluster(GlyphLayout* glyphs, int pos, uint item) : m_pos(pos), m_item(item), m_glyphs(glyphs) {}
Cluster(GlyphLayout* glyphs, int pos, uint item, int ref) : m_pos(pos), m_item(item), m_glyphs(glyphs), m_ref(ref) {}
public:
friend class GlyphStore;
48,9 → 50,9
int textPosition() { return m_pos; }
bool isValid() const { return m_glyphs != NULL; }
Cluster() : m_pos(-1), m_item(0), m_glyphs(NULL) {}
Cluster(const Cluster& o) : m_pos(o.m_pos), m_item(o.m_item), m_glyphs(o.m_glyphs) {}
Cluster& operator= (const Cluster& o) { m_glyphs = o.m_glyphs; m_pos = o.m_pos; m_item = o.m_item; return *this; }
Cluster() : m_pos(-1), m_item(0), m_glyphs(NULL), m_ref(-1) {}
Cluster(const Cluster& o) : m_pos(o.m_pos), m_item(o.m_item), m_glyphs(o.m_glyphs), m_ref(o.m_ref) {}
Cluster& operator= (const Cluster& o) { m_glyphs = o.m_glyphs; m_pos = o.m_pos; m_item = o.m_item; m_ref = o.m_ref; return *this; }
};
 
 
96,7 → 98,7
QList<ItemData> m_items;
/// fine segmentation: stored as difference between glyphIndex and textPos. If each char has exactly one glyph, all offsets equal 0
QMap<int,int> m_clusterOffsets;
QList<QPair<int,int> > m_clusterOffsets; // qPair<charcode , glyph index in m_glyphs>
Index m_clusterRuns;
/// returns the offset for glyphIndex
/branches/ScribusOIF/scribus/text/storytext_shared.cpp
106,23 → 106,28
 
QString Storytext_Shared::text(int pos, uint len) const
{
assert( pos >= 0 && pos + signed(len) <= length());
int idx1 = pars[pos];
int idx2 = pars[pos + len - 1];
//assert( pos >= 0 && pos + signed(len) <= length());
// correct values rather than assert, could lead to artifacts but well, it's better than a crash.
int cpos(qMax(0, pos));
int clen(len);
if(cpos + len > length())
clen = length() - cpos ;
int idx1 = pars[cpos];
int idx2 = pars[cpos + clen - 1];
//qDebug() << "text(" << pos << "," << len << ") from" << idx1 << "," << idx2;
if (idx1 == idx2)
return paragraphs[idx1].text.mid(pos - pars.offset(idx1), len);
return paragraphs[idx1].text.mid(cpos - pars.offset(idx1), clen);
else
{
//for (int j=idx1; j <= idx2; ++j)
// qDebug() << "text() par" << j << paragraphs[j].text << "\n\n___";
QString result = paragraphs[idx1].text.mid(pos - pars.offset(idx1));
QString result = paragraphs[idx1].text.mid(cpos - pars.offset(idx1));
for (int i = idx1 + 1; i < idx2; ++i)
result.append(paragraphs[i].text);
result.append(paragraphs[idx2].text.left(pos + len - pars.offset(idx2)));
result.append(paragraphs[idx2].text.left(cpos + clen - pars.offset(idx2)));
//qDebug() << result.length() << result;
assert(result.length() == signed(len));
assert(result.length() == signed(clen));
return result;
}
}
/branches/ScribusOIF/scribus/langmgr.cpp
87,6 → 87,7
langList.insert("gl", langPair("Galician", QObject::tr( "Galician" )) );
langList.insert("el", langPair("Greek", QObject::tr( "Greek" )) );
langList.insert("he", langPair("Hebrew", QObject::tr( "Hebrew" )) );
langList.insert("hi", langPair("Hindi", QObject::tr( "Hindi" )) );
langList.insert("hu", langPair("Hungarian", QObject::tr( "Hungarian" )) );
langList.insert("ia", langPair("Latin", QObject::tr( "Latin" )) );
langList.insert("is", langPair("Icelandic", QObject::tr( "Icelandic" )) );
325,6 → 326,7
// http://www.microsoft.com/typography/otspec/scripttags.htm
// default is "latn"
scriptTag.insert(QString("ar"), QString("arab"));
scriptTag.insert(QString("hi"), QString("deva"));
// TODO_OIF ...continue
 
// http://www.microsoft.com/typography/otspec/languagetags.htm
331,6 → 333,7
// default is "DFLT"
// note that a tag _MUST_ be 4 chars long (padded with space)
langTag.insert(QString("ar"), QString("ARA "));
langTag.insert(QString("hi"), QString("HIN "));
// TODO_OIF ...continue
 
 
363,9 → 366,15
foreach(const langPair& lp, langList)
{
if(getTranslated)
ret << lp.second;
{
if(!ret.contains(lp.second))
ret << lp.second;
}
else
ret << lp.first;
{
if(!ret.contains(lp.first))
ret << lp.first;
}
}
return ret;
}