r15962 by pierremarc - Made many adjustments in boxes rendering and ICU output parsing to get correct arabic composition
scribus-commit
scribus-commit at lists.scribus.net
Tue Nov 23 17:23:03 CET 2010
Author: pierremarc
Date: Tue Nov 23 16:23:03 2010
New Revision: 15962
URL: http://scribus.info/websvn/listing.php?repname=Scribus&sc=1&rev=15962
Log:
Made many adjustments in boxes rendering and ICU output parsing to get correct arabic composition
Modified:
branches/ScribusOIF/resources/loremipsum/ar.xml
branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
branches/ScribusOIF/scribus/fonts/scfontmetrics.cpp
branches/ScribusOIF/scribus/text/boxes.cpp
branches/ScribusOIF/scribus/text/glyphlayout.cpp
branches/ScribusOIF/scribus/text/linelayouter.cpp
Modified: branches/ScribusOIF/resources/loremipsum/ar.xml
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15962&path=/branches/ScribusOIF/resources/loremipsum/ar.xml
==============================================================================
--- branches/ScribusOIF/resources/loremipsum/ar.xml (original)
+++ branches/ScribusOIF/resources/loremipsum/ar.xml Tue Nov 23 16:23:03 2010
@@ -5,6 +5,9 @@
<author>Marek Moehling</author>
<url>http://lorem-ipsum.info</url>
+<p>
+جع٠شبÙØ© اÙÙÙب اÙعاÙÙ
ÙÙØ© عاÙÙ
ÙÙØ© ØÙÙÙا
+</p>
<p>
تصÙØ Ø§ÙØربÙØ Ø¨ÙØ Ù£Ù , إذ اÙشتاء اÙÙ
برÙ
Ø© ØدÙ. Ù
Ù ÙÙÙ
Ù
رجع ÙزÙÙ
Ø© ÙسÙ
ÙÙت, ÙÙد ع٠اÙجÙÙب بÙÙادة. Ùع٠ب٠باØتÙا٠ÙباÙتØدÙدØ, ÙØت٠اÙÙ
عرÙØ©Ø Ø£Ù
ÙصÙ, اÙÙاش٠اÙØ¥Ùتصاد٠ا٠تÙÙ. ÙÙس Ù
شارÙØ© اÙÙاباÙØ Ø§ÙØ¥ÙتصادÙØ© عÙ, Ø£Ù
بزÙا٠تجÙÙز تعد, Ù ÙتÙ
Ø®Ùار Ùعاد٠اÙØ£ÙÙÙØ©. ٠ساعة استراÙÙØ§Ø Øدة.
</p>
@@ -39,4 +42,4 @@
بÙ٠ع٠أراض٠ÙاÙعتاد ÙÙØ£ÙÙ
اÙ, Ùص٠Ù
ا Ù
ÙÙ٠بÙ
ØاÙÙØ©. ÙÙزÙ
Ù
Ø´ÙÙØ© Ùع٠ثÙ
, Ù٠بعض بÙرض بÙاد٠ÙتعÙÙÙ. Ø£ÙÙ٠أÙÙ
اÙ٠اÙعصبة Øت٠Ù
ا, أدÙات اÙتÙبر جزÙرت٠Ù
ع ÙÙÙ
. تÙÙ Ø«Ù
ÙاÙتا ÙاÙÙ
عدات ÙاÙرÙسÙØ©, Ù٠سÙطت ÙاÙتصار أخذ.
</p>
-</lorem>
+</lorem>
Modified: branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15962&path=/branches/ScribusOIF/scribus/fonts/scface_ttf.cpp
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scface_ttf.cpp (original)
+++ branches/ScribusOIF/scribus/fonts/scface_ttf.cpp Tue Nov 23 16:23:03 2010
@@ -744,6 +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 isAuto(story->charStyle(gs->itemTextPosition(item)).autoShape());
double fSize(story->charStyle(gs->itemTextPosition(item)).fontSize() /10.0);
int itemPos(gs->itemTextPosition(item));
@@ -767,7 +768,7 @@
++ci;
}
icuLE->reset();
- int glAllocated = icuLE->layoutChars( ts, 0, sCount , sCount, false, 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];
@@ -776,43 +777,67 @@
icuLE->getGlyphs ( glyphs, err );
icuLE->getCharIndices ( indices, err );
// icuLE->getGlyphPositions ( positions, err );
- float stackX ( 0.0 );
- float stackY ( 0.0 );
+// 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);
-
+ double sFactor(fSize / m_uniEM);
float icuX(0);
float icuY(0);
float icuFwdX(0);
float icuFwdY(0);
for ( le_int32 gIdx ( 0 ); gIdx < gCount ; ++gIdx )
{
- if(glyphs[gIdx] != 0xFFFF)
+ if((glyphs[gIdx] != 0xFFFF)
+ && (glyphs[gIdx] != 0xFFFE))
{
icuLE->getGlyphPosition(gIdx, icuX, icuY, err);
le_int32 nextIdx(gIdx + 1);
while((glyphs[nextIdx] == 0xFFFF) && (nextIdx < gCount))
++nextIdx;
icuLE->getGlyphPosition(nextIdx, icuFwdX, icuFwdY, err);
-
+ icuX *= sFactor;
+ icuY *= sFactor;
+ icuFwdX *= sFactor;
+ icuFwdY *= sFactor;
if(err != LE_NO_ERROR)
continue;
+ QChar c(text.at(indices[gIdx]));
+ bool isDiacritic(c.isMark());
+ bool isCombining(indices[gIdx] == indices[nextIdx]);
GlyphLayout curGlyph;
curGlyph.glyph = glyphs[gIdx];
-// curGlyph.xadvance = (positions[ ( gIdx + 1 ) * 2] * fSize / m_uniEM) - stackX;
-// curGlyph.yoffset = ((stackY - positions[ ( ( gIdx + 1 ) * 2 ) + 1]) * fSize / m_uniEM) + sHeight;
curGlyph.xadvance = glyphWidth(curGlyph.glyph, fSize);
- curGlyph.xoffset = stackX;
- curGlyph.yoffset = (icuY - stackY) * fSize / m_uniEM;
+ curGlyph.xoffset = isRTL ? (icuFwdX - icuX) - curGlyph.xadvance : xShift;
+ curGlyph.yoffset = yShift;
curGlyph.yadvance = 0;
- stackY = icuFwdY;
- stackX = ((icuFwdX - icuX) * fSize / m_uniEM) - curGlyph.xadvance;
-// stackX += curGlyph.xadvance;
-// stackY = positions[ ( ( gIdx + 1 ) * 2 ) + 1];
- glList << curGlyph;
- charList << indices[gIdx];
-// qDebug()<<"icu"<<text.at(indices[gIdx])<< itemPos + indices[gIdx] << curGlyph.glyph <<curGlyph.xadvance <<curGlyph.yoffset ;
+ 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);
+ }
+ else
+ {
+ glList << curGlyph;
+ charList << indices[gIdx];
+ markList << isDiacritic;
+ }
+ qDebug()<<"icu"<<indices[gIdx]
+ << curGlyph.glyph
+ << sHeight
+ << icuY
+ << icuFwdY ;
}
}
icuLE->reset();
@@ -827,19 +852,23 @@
{
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;
- gs->markCluster(item, c , curGlyph);
- const_cast<TextFlags&>(story->charAttributes(c)) |= TextFlag_ClusterStart;
+ if(!markList.at(i) && !isCombining)
+ {
+ gs->markCluster(item, c , curGlyph);
+ const_cast<TextFlags&>(story->charAttributes(c)) |= TextFlag_ClusterStart;
+ }
++curGlyph;
}
}
- else // FIXME_OIF should be able to mix auto and "manual"
+ else // FIXME_OIF should be able to mix auto and "manual" - will be easier when using harfbuzz shaper
{
hb_face_t * face = hb_ft_face_create(ftFace(), releaseFaceForHB );
hb_font_t * font = hb_ft_font_create (ftFace(), releaseFaceForHB);
Modified: branches/ScribusOIF/scribus/fonts/scfontmetrics.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15962&path=/branches/ScribusOIF/scribus/fonts/scfontmetrics.cpp
==============================================================================
--- branches/ScribusOIF/scribus/fonts/scfontmetrics.cpp (original)
+++ branches/ScribusOIF/scribus/fonts/scfontmetrics.cpp Tue Nov 23 16:23:03 2010
@@ -203,7 +203,7 @@
QTransform ma;
ma.scale(0.01, -0.01);
pts.map(ma);
- pts.translate(0, chs);
+// pts.translate(0, chs);
pts2.putPoints(0, pts.size()-2, pts, 0);
return pts2;
Modified: branches/ScribusOIF/scribus/text/boxes.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15962&path=/branches/ScribusOIF/scribus/text/boxes.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/boxes.cpp (original)
+++ branches/ScribusOIF/scribus/text/boxes.cpp Tue Nov 23 16:23:03 2010
@@ -417,7 +417,8 @@
p->save();
p->setPen(Qt::lightGray);
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);
@@ -463,55 +464,66 @@
else
break;
}
- GlyphLayout* layout = cluster.glyphs();
- uint glyph = layout->glyph;
- if(rtl)
- p->translate(-(layout->xadvance + layout->xoffset), 0);
-// qDebug() << "render pos"<< cluster.textPosition()<<"glyph" << glyph << "width" << layout->xadvance << "font" << style.font().scName() << "@" << x() << y() ;
- if ((renderOptions.showControls) &&
- (glyph == style.font().char2CMap(QChar(' ')) || glyph >= ScFace::CONTROL_GLYPHS))
- {
- layout->renderControlChar(p, renderOptions, style);
- if(m_glyphs->haveNext(cluster))
- cluster = m_glyphs->next(cluster);
- else
- break;
- continue;
- }
- else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
+
+ uint gCount(m_glyphs->glyphCount(cluster));
+ // consume all the glyphs in the cluster
+ for(uint gIdx(0); gIdx < gCount; ++gIdx )
+ {
+ GlyphLayout* layout = cluster.glyphs() + gIdx;
+ uint glyph = layout->glyph;
+ if(rtl)
+ {
+ p->translate(- (layout->xoffset + layout->xadvance), 0);
+ }
+ // qDebug() << "render pos"<< cluster.textPosition()<<"glyph" << glyph << "width" << layout->xadvance << "font" << style.font().scName() << "@" << x() << y() ;
+ if ((renderOptions.showControls) &&
+ (glyph == style.font().char2CMap(QChar(' ')) || glyph >= ScFace::CONTROL_GLYPHS))
+ {
+ layout->renderControlChar(p, renderOptions, style);
+ if(m_glyphs->haveNext(cluster))
+ cluster = m_glyphs->next(cluster);
+ else
+ break;
+ continue;
+ }
+ else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
glyph == (ScFace::CONTROL_GLYPHS + 32))
- glyph = style.font().char2CMap(QChar(' '));
- else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
- glyph = style.font().char2CMap(QChar('-'));
-
- if (glyph >= ScFace::CONTROL_GLYPHS || (style.effects() & ScStyle_SuppressSpace))
- {
-// qDebug() << "render GlyphBox: skipping" << glyph;
- // all those are empty
-
- if(m_glyphs->haveNext(cluster))
- cluster = m_glyphs->next(cluster);
- else
- break;
- continue;
- }
- // if (style.font().canRender(QChar(glyph)))
- {
- // Do underlining first so you can get typographically correct
- // underlines when drawing a white outline
- if (((style.effects() & ScStyle_Underline) || ((style.effects() & ScStyle_UnderlineWords) && glyph != style.font().char2CMap(QChar(' ')))) && (style.strokeColor() != CommonStrings::None))
- {
- layout->renderUnderline(p, renderOptions, style);
- }
-
- layout->renderOutlines(p, renderOptions, style);
-
- if ((style.effects() & ScStyle_Strikethrough) && (style.strokeColor() != CommonStrings::None))
- {
- layout->renderStrikeThrough(p, renderOptions, style);
- }
- }
- /* else
+ glyph = style.font().char2CMap(QChar(' '));
+ else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
+ glyph = style.font().char2CMap(QChar('-'));
+
+ if (glyph >= ScFace::CONTROL_GLYPHS || (style.effects() & ScStyle_SuppressSpace))
+ {
+ // qDebug() << "render GlyphBox: skipping" << glyph;
+ // all those are empty
+
+ if(m_glyphs->haveNext(cluster))
+ cluster = m_glyphs->next(cluster);
+ else
+ break;
+ continue;
+ }
+ // if (style.font().canRender(QChar(glyph)))
+ {
+ // Do underlining first so you can get typographically correct
+ // underlines when drawing a white outline
+ if (((style.effects() & ScStyle_Underline) || ((style.effects() & ScStyle_UnderlineWords) && glyph != style.font().char2CMap(QChar(' ')))) && (style.strokeColor() != CommonStrings::None))
+ {
+ layout->renderUnderline(p, renderOptions, style);
+ }
+ // p->save();
+ // p->setPen(Qt::lightGray);
+ // p->setFillMode(ScPainter::None);
+ // p->drawRect(0, -m_ascent, layout->xadvance , height());
+ // p->restore();
+ layout->renderOutlines(p, renderOptions, style);
+
+ if ((style.effects() & ScStyle_Strikethrough) && (style.strokeColor() != CommonStrings::None))
+ {
+ layout->renderStrikeThrough(p, renderOptions, style);
+ }
+ }
+ /* else
{
p->setLineWidth(1);
p->setPen(red);
@@ -520,8 +532,9 @@
p->drawRect(glyphs.xoffset, glyphs.yoffset - (style.fontSize() / 10.0) * glyphs.scaleV , (style.fontSize() / 10.0) * glyphs.scaleH, (style.fontSize() / 10.0) * glyphs.scaleV);
}
*/
- if(!rtl)
- p->translate(layout->xadvance + layout->xoffset, 0);
+ if(!rtl)
+ p->translate(layout->xadvance + layout->xoffset, 0);
+ }
if(m_glyphs->haveNext(cluster))
cluster = m_glyphs->next(cluster);
else
Modified: branches/ScribusOIF/scribus/text/glyphlayout.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15962&path=/branches/ScribusOIF/scribus/text/glyphlayout.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/glyphlayout.cpp (original)
+++ branches/ScribusOIF/scribus/text/glyphlayout.cpp Tue Nov 23 16:23:03 2010
@@ -41,7 +41,10 @@
// qDebug() << QString("glyph 0: (%1,%2) * %3 %4 + %5").arg(glyphs.xoffset).arg(glyphs.yoffset).arg(glyphs.scaleH).arg(glyphs.scaleV).arg(glyphs.xadvance));
}
p->save();
- p->translate(xoffset, yoffset - ((fontSize / 10.0) * scaleV));
+ // As xoffset has an impact on line composition, it is applied independently of glyph drawing (see GlyphBox::render)
+ // FIXME - make it clear how yoffset should be presented to this method
+// p->translate(/*xoffset*/ 0, yoffset - ((fontSize / 10.0) * scaleV));
+ p->translate(0, yoffset * scaleV);
if (renderOptions.reverse)
{
p->scale(-1, 1);
Modified: branches/ScribusOIF/scribus/text/linelayouter.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15962&path=/branches/ScribusOIF/scribus/text/linelayouter.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/linelayouter.cpp (original)
+++ branches/ScribusOIF/scribus/text/linelayouter.cpp Tue Nov 23 16:23:03 2010
@@ -55,6 +55,7 @@
unsigned int lastBreak(0);
double lastBreakWidth(0.0);
int resultCount(0);
+ int lastPos(start);
for(unsigned int i(firstItem); i < itemCount; ++i)
{
items << i;
@@ -72,6 +73,7 @@
rtl = m_layout->story()->charAttributes(cluster.textPosition()).testFlag(TextFlag_RightToLeft);
while(true)
{
+ lastPos = cluster.textPosition();
if(cluster.textPosition() < start)
{
if(gs->haveNext(cluster))
@@ -146,6 +148,11 @@
break;
}
//qDebug()<<"Result len"<<ret.length();
+ if(ret.count() == 0)
+ {
+ LineResult lr(stackWidth + rtlStack, 0, lastPos);
+ ret << lr;
+ }
return ret;
}
More information about the scribus-commit
mailing list