r15889 by pierremarc - First bits of right-to-left composition support
scribus-commit
scribus-commit at lists.scribus.net
Wed Nov 17 14:01:35 CET 2010
Author: pierremarc
Date: Wed Nov 17 13:01:35 2010
New Revision: 15889
URL: http://scribus.info/websvn/listing.php?repname=Scribus&sc=1&rev=15889
Log:
First bits of right-to-left composition support
Modified:
branches/ScribusOIF/scribus/langmgr.cpp
branches/ScribusOIF/scribus/langmgr.h
branches/ScribusOIF/scribus/sctextstruct.h
branches/ScribusOIF/scribus/text/boxes.cpp
branches/ScribusOIF/scribus/text/linelayouter.cpp
branches/ScribusOIF/scribus/text/shaper.cpp
branches/ScribusOIF/scribus/ui/smcstylewidget.cpp
branches/ScribusOIF/scribus/ui/smtextstyles.cpp
Modified: branches/ScribusOIF/scribus/langmgr.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15889&path=/branches/ScribusOIF/scribus/langmgr.cpp
==============================================================================
--- branches/ScribusOIF/scribus/langmgr.cpp (original)
+++ branches/ScribusOIF/scribus/langmgr.cpp Wed Nov 17 13:01:35 2010
@@ -316,6 +316,9 @@
isoLang.insert(QString("za"), QString("zha"));
isoLang.insert(QString("zu"), QString("zul"));
+ RTLLangs << QString("ar");
+ RTLLangs << QString("he");
+
}
void LanguageManager::generateInstalledLangList()
@@ -339,6 +342,19 @@
}
}
+const QStringList LanguageManager::getAllLangs(bool getTranslated)
+{
+ QStringList ret;
+ foreach(const langPair& lp, langList)
+ {
+ if(getTranslated)
+ ret << lp.second;
+ else
+ ret << lp.first;
+ }
+ return ret;
+}
+
const QString LanguageManager::getLangFromAbbrev(QString langAbbrev, bool getTranslated)
{
QMap<QString, langPair>::Iterator it;
@@ -492,6 +508,11 @@
return retSeq;
}
+bool LanguageManager::isRightToLeft(const QString &langAbbr)
+{
+ return RTLLangs.contains(langAbbr);
+}
+
LanguageManager::~LanguageManager()
{
langList.clear();
Modified: branches/ScribusOIF/scribus/langmgr.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15889&path=/branches/ScribusOIF/scribus/langmgr.h
==============================================================================
--- branches/ScribusOIF/scribus/langmgr.h (original)
+++ branches/ScribusOIF/scribus/langmgr.h Wed Nov 17 13:01:35 2010
@@ -36,13 +36,14 @@
class SCRIBUS_API LanguageManager
{
static LanguageManager* m_instance;
- LanguageManager() {};
+ LanguageManager(){}
~LanguageManager();
void init(bool generateInstalledList = true);
public:
static LanguageManager* instance();
-
+
+ const QStringList getAllLangs(bool getTranslated=true);
const QString getLangFromAbbrev(QString, bool getTranslated=true);
const QString getAbbrevFromLang(QString, bool getFromTranslated=true, bool useInstalled=true);
const QString getLangFromTransLang(QString lang);
@@ -51,6 +52,8 @@
void fillInstalledStringList(QStringList *stringListToFill, bool addDefaults);
void printInstalledList();
QString numericSequence(QString seq);
+ bool isRightToLeft(const QString& langAbbr);
+
void addHyphLang(const QString& lang, const QString& filename);
const QString getHyphFilename(const QString& lang, bool langIsAbbreviated = true);
@@ -61,6 +64,7 @@
QMap<QString, QString> installedLangList;
QMap<QString, QString> hyphLangList; // <lang abbreviated, dict filename>
QMap<QString, QString> isoLang; // <lang abbreviated, iso639-2 abbreviation>
+ QStringList RTLLangs;
void generateLangList();
void generateInstalledLangList();
Modified: branches/ScribusOIF/scribus/sctextstruct.h
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15889&path=/branches/ScribusOIF/scribus/sctextstruct.h
==============================================================================
--- branches/ScribusOIF/scribus/sctextstruct.h (original)
+++ branches/ScribusOIF/scribus/sctextstruct.h Wed Nov 17 13:01:35 2010
@@ -56,6 +56,7 @@
TextFlag_StartOfLine = 16,
TextFlag_ClusterStart = 32,
TextFlag_WordBoundary = 64,
+ TextFlag_RightToLeft = 128
};
Q_DECLARE_FLAGS(TextFlags, TextFlag)
Modified: branches/ScribusOIF/scribus/text/boxes.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15889&path=/branches/ScribusOIF/scribus/text/boxes.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/boxes.cpp (original)
+++ branches/ScribusOIF/scribus/text/boxes.cpp Wed Nov 17 13:01:35 2010
@@ -413,6 +413,7 @@
void GlyphBox::render(ScPainter* p, const RenderOptions& renderOptions) const
{
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->setFillMode(ScPainter::None);
@@ -420,7 +421,10 @@
p->restore();
p->save();
p->setAntialiasing(true);
- p->translate(x(), y());
+ if(rtl)
+ p->translate(x() + width(), y());
+ else
+ p->translate(x(), y());
QString color = style.fillColor();
QColor fillColor(Qt::transparent);
@@ -461,6 +465,8 @@
}
GlyphLayout* layout = cluster.glyphs();
uint glyph = layout->glyph;
+ if(rtl)
+ p->translate(-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))
@@ -513,8 +519,9 @@
p->setFillMode(1);
p->drawRect(glyphs.xoffset, glyphs.yoffset - (style.fontSize() / 10.0) * glyphs.scaleV , (style.fontSize() / 10.0) * glyphs.scaleH, (style.fontSize() / 10.0) * glyphs.scaleV);
}
- */
- p->translate(layout->xadvance, 0);
+ */
+ if(!rtl)
+ p->translate(layout->xadvance, 0);
if(m_glyphs->haveNext(cluster))
cluster = m_glyphs->next(cluster);
else
Modified: branches/ScribusOIF/scribus/text/linelayouter.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15889&path=/branches/ScribusOIF/scribus/text/linelayouter.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/linelayouter.cpp (original)
+++ branches/ScribusOIF/scribus/text/linelayouter.cpp Wed Nov 17 13:01:35 2010
@@ -34,6 +34,12 @@
}
// We start with the simpler implementation - pm
+// this method tries to return a result set containing 3 possible lines
+// one at first break before line is longer than available space
+// one at the break just after the line becomes lomger than available space
+// one more after the previous break
+// In first intention, the score is not intended to take in account the difference
+// between available space and line width, just the quality of the break.
LineLayouterBase::ResultSet LineLayouter::layoutLine(int start, double lineWidth) const
{
ResultSet ret;
@@ -43,21 +49,27 @@
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);
for(unsigned int i(firstItem); i < itemCount; ++i)
{
- stackWidth += gs->itemWidth(i);
items << i;
- if(stackWidth >= (3.0 * lineWidth)) // weak
- break;
}
- stackWidth = 0.0;
foreach(unsigned int item, items)
{
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)
{
if(cluster.textPosition() < start)
@@ -79,24 +91,26 @@
currentClusterWidth = gs->clusterWidth(cluster) * wordSpacing;
if(0 == resultCount)
{
- if((stackWidth + currentClusterWidth) > lineWidth)
+ if((stackWidth + rtlStack + currentClusterWidth) > lineWidth)
{
if(lastBreak > 0)
{
LineResult lr(lastBreakWidth, 0, lastBreak);
ret << lr;
+ resultCount = 1;
}
- else
+ else if(m_layout->story()->charAttributes(cluster.textPosition()).testFlag(TextFlag_HyphenationPossible)
+ || SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
{
- LineResult lr(stackWidth + currentClusterWidth, 1, cluster.textPosition()); // overbox
+ LineResult lr(stackWidth + rtlStack + currentClusterWidth, 1, cluster.textPosition()); // overfullbox
ret << lr;
+ resultCount = 1;
}
// qDebug()<<"Inserting Line Result0"<<lr.width<<lr.endPos;
- resultCount = 1;
}
else if(cluster.textPosition() + 1 == m_layout->story()->length())
{
- LineResult lr(stackWidth + currentClusterWidth, 0, cluster.textPosition());
+ LineResult lr(stackWidth + rtlStack + currentClusterWidth, 0, cluster.textPosition());
ret << lr;
// qDebug()<<"Inserting Line Result1"<<lr.width<<lr.endPos;
resultCount = 2;
@@ -106,19 +120,22 @@
|| SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
{
lastBreak = cluster.textPosition();
- lastBreakWidth = stackWidth + currentClusterWidth;
+ lastBreakWidth = stackWidth + rtlStack + currentClusterWidth;
}
}
else if(m_layout->story()->charAttributes(cluster.textPosition()).testFlag(TextFlag_HyphenationPossible)
|| SpecialChars::isBreakingSpace(m_layout->story()->text(cluster.textPosition())))
{
- LineResult lr(stackWidth + currentClusterWidth, 1, cluster.textPosition());
+ LineResult lr(stackWidth + rtlStack + currentClusterWidth, 1, cluster.textPosition());
ret << lr;
// qDebug()<<"Inserting Line Result2"<<lr.width<<lr.endPos;
resultCount = 2;
break;
}
- stackWidth += currentClusterWidth;
+ if(rtl)
+ rtlStack += currentClusterWidth;
+ else
+ stackWidth += currentClusterWidth;
if(gs->haveNext(cluster))
cluster = gs->next(cluster);
Modified: branches/ScribusOIF/scribus/text/shaper.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15889&path=/branches/ScribusOIF/scribus/text/shaper.cpp
==============================================================================
--- branches/ScribusOIF/scribus/text/shaper.cpp (original)
+++ branches/ScribusOIF/scribus/text/shaper.cpp Wed Nov 17 13:01:35 2010
@@ -22,6 +22,7 @@
#include "text/glyphstore.h"
#include "text/storytext.h"
+#include "langmgr.h"
#include <QDebug>
@@ -35,29 +36,45 @@
{
StoryText * story(const_cast<StoryText *>(m_layout->story()));
GlyphStore *gs(const_cast<GlyphStore*>(m_layout->storyGlyphs()));
+ LanguageManager * lm(LanguageManager::instance());
QList<uint> items;
// redo itemization for this run
CharStyle ref;
int itStart(start);
bool first(true);
+ bool rtl(false);
for(int cursor(start); cursor <= end; ++cursor )
{
if(first)
{
first = false;
- ref = story->charStyle(cursor);
+ 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))
{
+ if(cursor != end)
+ {
+ ref = story->charStyle(cursor) ;
+ rtl = lm->isRightToLeft(lm->getAbbrevFromLang(story->charStyle(cursor).language(), false, false));
+ }
items << gs->addItem(itStart, (cursor) - itStart + 1);
- qDebug()<<"AddItem"<<itStart<< (cursor - itStart + 1);
itStart = cursor + 1;
}
+ if(rtl)
+ story->charAttributes(cursor) |= TextFlag_RightToLeft;
+ else
+ story->charAttributes(cursor) &= ~TextFlag_RightToLeft;
}
+ qDebug()<<cursor<<story->charStyle(cursor).language()<<ref.language()<< rtl;
}
foreach(uint it, items)
Modified: branches/ScribusOIF/scribus/ui/smcstylewidget.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15889&path=/branches/ScribusOIF/scribus/ui/smcstylewidget.cpp
==============================================================================
--- branches/ScribusOIF/scribus/ui/smcstylewidget.cpp (original)
+++ branches/ScribusOIF/scribus/ui/smcstylewidget.cpp Wed Nov 17 13:01:35 2010
@@ -120,18 +120,23 @@
void SMCStyleWidget::fillLangCombo(QMap<QString,QString> langMap)
{
- QStringList sortList;
- QMap<QString,QString>::Iterator it;
-
- langMap_ = langMap;
-
- language_->clear();
-
- for (it = langMap.begin(); it != langMap.end(); ++it)
- sortList.push_back(it.value());
-
- language_->addItems(sortQStringList(sortList));
-
+// QStringList sortList;
+// QMap<QString,QString>::Iterator it;
+
+ LanguageManager * lm( LanguageManager::instance() );
+ langMap_.clear();
+ foreach(const QString& tl, lm->getAllLangs())
+ {
+ langMap_.insert(lm->getLangFromTransLang(tl), tl);
+ }
+
+// language_->clear();
+
+// for (it = langMap.begin(); it != langMap.end(); ++it)
+// sortList.push_back(it.value());
+
+// language_->addItems(sortQStringList(sortList));
+ language_->addItems(lm->getAllLangs());
QListView *tmpView = dynamic_cast<QListView*>(language_->view()); Q_ASSERT(tmpView);
int tmpWidth = tmpView->sizeHintForColumn(0);
if (tmpWidth > 0)
Modified: branches/ScribusOIF/scribus/ui/smtextstyles.cpp
URL: http://scribus.info/websvn/diff.php?repname=Scribus&rev=15889&path=/branches/ScribusOIF/scribus/ui/smtextstyles.cpp
==============================================================================
--- branches/ScribusOIF/scribus/ui/smtextstyles.cpp (original)
+++ branches/ScribusOIF/scribus/ui/smtextstyles.cpp Wed Nov 17 13:01:35 2010
@@ -12,6 +12,7 @@
#include "colorcombo.h"
#include "commonstrings.h"
#include "fontcombo.h"
+#include "langmgr.h"
#include "ui/scmwmenumanager.h"
#include "prefsmanager.h"
#include "propertiespalette.h"
@@ -1201,14 +1202,15 @@
selection_[i]->charStyle().resetLanguage();
else
{
- for (it = doc_->scMW()->LangTransl.begin(); it != doc_->scMW()->LangTransl.end(); ++it)
- {
- if (it.value() == pwidget_->cpage->language_->currentText())
- {
- language = it.key();
- break;
- }
- }
+// for (it = doc_->scMW()->LangTransl.begin(); it != doc_->scMW()->LangTransl.end(); ++it)
+// {
+// if (it.value() == pwidget_->cpage->language_->currentText())
+// {
+// language = it.key();
+// break;
+// }
+// }
+ language = LanguageManager::instance()->getLangFromTransLang(pwidget_->cpage->language_->currentText());
for (int i = 0; i < selection_.count(); ++i)
selection_[i]->charStyle().setLanguage(language);
}
@@ -2119,14 +2121,15 @@
selection_[i]->resetLanguage();
else
{
- for (it = doc_->scMW()->LangTransl.begin(); it != doc_->scMW()->LangTransl.end(); ++it)
- {
- if (it.value() == page_->language_->currentText())
- {
- language = it.key();
- break;
- }
- }
+// for (it = doc_->scMW()->LangTransl.begin(); it != doc_->scMW()->LangTransl.end(); ++it)
+// {
+// if (it.value() == page_->language_->currentText())
+// {
+// language = it.key();
+// break;
+// }
+// }
+ language = LanguageManager::instance()->getLangFromTransLang(page_->language_->currentText());
for (int i = 0; i < selection_.count(); ++i)
selection_[i]->setLanguage(language);
}
More information about the scribus-commit
mailing list