diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qtextcursor.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 9 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentlayout.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 26 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtextformat.cpp | 7 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qtextlist.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextobject.cpp | 43 | ||||
-rw-r--r-- | src/gui/text/qtextobject.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextoption.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextoption.h | 4 |
12 files changed, 87 insertions, 25 deletions
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index d6ac3aa..23849bc 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -362,7 +362,7 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor QTextBlock blockIt = block(); if (op >= QTextCursor::Left && op <= QTextCursor::WordRight - && blockIt.blockFormat().layoutDirection() == Qt::RightToLeft) { + && blockIt.textDirection() == Qt::RightToLeft) { if (op == QTextCursor::Left) op = QTextCursor::NextCharacter; else if (op == QTextCursor::Right) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index c7a9756..48aee8f 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2496,13 +2496,10 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) QTextBlockFormat format = block.blockFormat(); emitAlignment(format.alignment()); - Qt::LayoutDirection dir = format.layoutDirection(); - if (dir == Qt::LeftToRight) { - // assume default to not bloat the html too much - // html += QLatin1String(" dir='ltr'"); - } else { + // assume default to not bloat the html too much + // html += QLatin1String(" dir='ltr'"); + if (block.textDirection() == Qt::RightToLeft) html += QLatin1String(" dir='rtl'"); - } QLatin1String style(" style=\""); html += style; diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index eeb66ce..ff14490 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -1369,9 +1369,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p QTextLine firstLine = layout->lineAt(0); Q_ASSERT(firstLine.isValid()); QPointF pos = (offset + layout->position()).toPoint(); - Qt::LayoutDirection dir = docPrivate->defaultTextOption.textDirection(); - if (blockFormat.hasProperty(QTextFormat::LayoutDirection)) - dir = blockFormat.layoutDirection(); + Qt::LayoutDirection dir = bl.textDirection(); { QRectF textRect = firstLine.naturalTextRect(); pos += textRect.topLeft().toPoint(); @@ -2530,9 +2528,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi //QTextFrameData *fd = data(layoutStruct->frame); - Qt::LayoutDirection dir = docPrivate->defaultTextOption.textDirection(); - if (blockFormat.hasProperty(QTextFormat::LayoutDirection)) - dir = blockFormat.layoutDirection(); + Qt::LayoutDirection dir = bl.textDirection(); QFixed extraMargin; if (docPrivate->defaultTextOption.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) { diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 3486264..ac1fffd 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1404,7 +1404,10 @@ void QTextEngine::itemize() const #else bool ignore = ignoreBidi; #endif - if (!ignore && option.textDirection() == Qt::LeftToRight) { + + bool rtl = isRightToLeft(); + + if (!ignore && !rtl) { ignore = true; const QChar *start = layoutData->string.unicode(); const QChar * const end = start + length; @@ -1420,7 +1423,7 @@ void QTextEngine::itemize() const QVarLengthArray<QScriptAnalysis, 4096> scriptAnalysis(length); QScriptAnalysis *analysis = scriptAnalysis.data(); - QBidiControl control(option.textDirection() == Qt::RightToLeft); + QBidiControl control(rtl); if (ignore) { memset(analysis, 0, length*sizeof(QScriptAnalysis)); @@ -1515,6 +1518,23 @@ void QTextEngine::itemize() const resolveAdditionalFormats(); } +bool QTextEngine::isRightToLeft() const +{ + switch (option.textDirection()) { + case Qt::LeftToRight: + return false; + case Qt::RightToLeft: + return true; + default: + break; + } + // this places the cursor in the right position depending on the keyboard layout + if (layoutData->string.isEmpty()) + return QApplication::keyboardInputDirection() == Qt::RightToLeft; + return layoutData->string.isRightToLeft(); +} + + int QTextEngine::findItem(int strPos) const { itemize(); @@ -2511,7 +2531,7 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const QList<QTextOption::Tab> tabArray = option.tabs(); if (!tabArray.isEmpty()) { - if (option.textDirection() == Qt::RightToLeft) { // rebase the tabArray positions. + if (isRightToLeft()) { // rebase the tabArray positions. QList<QTextOption::Tab> newTabs; QList<QTextOption::Tab>::Iterator iter = tabArray.begin(); while(iter != tabArray.end()) { diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 00b1392..908a0ec 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -458,6 +458,7 @@ public: void validate() const; void itemize() const; + bool isRightToLeft() const; static void bidiReorder(int numRuns, const quint8 *levels, int *visualOrder); const HB_CharAttributes *attributes() const; diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 140cf43..46db253 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -900,11 +900,14 @@ bool QTextFormat::boolProperty(int propertyId) const */ int QTextFormat::intProperty(int propertyId) const { + // required, since the default layout direction has to be LayoutDirectionAuto, which is not integer 0 + int def = (propertyId == QTextFormat::LayoutDirection) ? int(Qt::LayoutDirectionAuto) : 0; + if (!d) - return 0; + return def; const QVariant prop = d->property(propertyId); if (prop.userType() != QVariant::Int) - return 0; + return def; return prop.toInt(); } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index f5e252c..ddf9411 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -69,7 +69,7 @@ static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line if (!line.hasTrailingSpaces || (eng->option.flags() & QTextOption::IncludeTrailingSpaces) || !(eng->option.alignment() & Qt::AlignRight) - || (eng->option.textDirection() != Qt::RightToLeft)) + || !eng->isRightToLeft()) return QFixed(); int pos = line.length; @@ -86,7 +86,7 @@ static QFixed alignLine(QTextEngine *eng, const QScriptLine &line) // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned. if (!line.justified && line.width != QFIXED_MAX) { int align = eng->option.alignment(); - if (align & Qt::AlignJustify && eng->option.textDirection() == Qt::RightToLeft) + if (align & Qt::AlignJustify && eng->isRightToLeft()) align = Qt::AlignRight; if (align & Qt::AlignRight) x = line.width - (line.textAdvance + leadingSpaceWidth(eng, line)); @@ -1337,7 +1337,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition int itm = d->findItem(cursorPosition - 1); QFixed base = sl.base(); QFixed descent = sl.descent; - bool rightToLeft = (d->option.textDirection() == Qt::RightToLeft); + bool rightToLeft = d->isRightToLeft(); if (itm >= 0) { const QScriptItem &si = d->layoutData->items.at(itm); if (si.ascent > 0) diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp index 2986ee7..a0ff520 100644 --- a/src/gui/text/qtextlist.cpp +++ b/src/gui/text/qtextlist.cpp @@ -262,7 +262,7 @@ QString QTextList::itemText(const QTextBlock &blockIt) const default: Q_ASSERT(false); } - if (blockFormat.layoutDirection() == Qt::RightToLeft) + if (blockIt.textDirection() == Qt::RightToLeft) return result.prepend(QLatin1Char('.')); return result + QLatin1Char('.'); } diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 088eb98..f386871 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1140,6 +1140,49 @@ int QTextBlock::charFormatIndex() const } /*! + \since 4.7 + + Returns the resolved text direction. + + If the block has no explicit direction set, it will resolve the + direction from the blocks content. Returns either Qt::LeftToRight + or Qt::RightToLeft. + + \sa QTextBlock::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection +*/ +Qt::LayoutDirection QTextBlock::textDirection() const +{ + Qt::LayoutDirection dir = blockFormat().layoutDirection(); + if (dir != Qt::LayoutDirectionAuto) + return dir; + + const QString buffer = p->buffer(); + + const int pos = position(); + QTextDocumentPrivate::FragmentIterator it = p->find(pos); + QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char + for (; it != end; ++it) { + const QTextFragmentData * const frag = it.value(); + const QChar *p = buffer.constData() + frag->stringPosition; + const QChar * const end = p + frag->size_array[0]; + while (p < end) { + switch(QChar::direction(p->unicode())) + { + case QChar::DirL: + return Qt::LeftToRight; + case QChar::DirR: + case QChar::DirAL: + return Qt::RightToLeft; + default: + break; + } + ++p; + } + } + return Qt::LeftToRight; +} + +/*! Returns the block's contents as plain text. \sa length() charFormat() blockFormat() diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index 67f67d8..a573a26 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -221,6 +221,8 @@ public: QTextCharFormat charFormat() const; int charFormatIndex() const; + Qt::LayoutDirection textDirection() const; + QString text() const; const QTextDocument *document() const; diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index 527b603..8f31e46 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -65,7 +65,7 @@ QTextOption::QTextOption() tab(-1), d(0) { - direction = QApplication::layoutDirection(); + direction = Qt::LayoutDirectionAuto; } /*! diff --git a/src/gui/text/qtextoption.h b/src/gui/text/qtextoption.h index 5af7834..a48efc1 100644 --- a/src/gui/text/qtextoption.h +++ b/src/gui/text/qtextoption.h @@ -136,8 +136,8 @@ private: uint align : 8; uint wordWrap : 4; uint design : 1; - uint direction : 1; - uint unused : 19; + uint direction : 2; + uint unused : 18; uint f; qreal tab; QTextOptionPrivate *d; |