summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qtextlayout.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2010-07-01 17:24:01 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2010-07-01 17:24:01 (GMT)
commit745ecfd8925716d962c97a4415881377faf6bdd5 (patch)
treec4f78b3bd143af52372064cd3ba5c0ae440813c5 /src/gui/text/qtextlayout.cpp
parentbda164303570629e44185e8baa52908ced6da301 (diff)
parent8968c79c575755cdb52d5e615ed19e4529047464 (diff)
downloadQt-745ecfd8925716d962c97a4415881377faf6bdd5.zip
Qt-745ecfd8925716d962c97a4415881377faf6bdd5.tar.gz
Qt-745ecfd8925716d962c97a4415881377faf6bdd5.tar.bz2
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts: bin/syncqt src/gui/text/qtextlayout.cpp tools/assistant/tools/assistant/helpviewer_qwv.cpp tools/assistant/tools/assistant/helpviewer_qwv.h tools/configure/configureapp.cpp
Diffstat (limited to 'src/gui/text/qtextlayout.cpp')
-rw-r--r--src/gui/text/qtextlayout.cpp63
1 files changed, 37 insertions, 26 deletions
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index c1a33e7..0df3c2e 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -71,7 +71,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;
@@ -88,7 +88,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));
@@ -283,12 +283,11 @@ Qt::LayoutDirection QTextInlineObject::textDirection() const
\class QTextLayout
\reentrant
- \brief The QTextLayout class is used to lay out and paint a single
- paragraph of text.
+ \brief The QTextLayout class is used to lay out and render text.
\ingroup richtext-processing
- It offers most features expected from a modern text layout
+ It offers many features expected from a modern text layout
engine, including Unicode compliant rendering, line breaking and
handling of cursor positioning. It can also produce and render
device independent layout, something that is important for WYSIWYG
@@ -298,29 +297,33 @@ Qt::LayoutDirection QTextInlineObject::textDirection() const
implement your own text rendering for some specialized widget, you
probably won't need to use it directly.
- QTextLayout can currently deal with plain text and rich text
- paragraphs that are part of a QTextDocument.
+ QTextLayout can be used with both plain and rich text.
- QTextLayout can be used to create a sequence of QTextLine's with
- given widths and can position them independently on the screen.
- Once the layout is done, these lines can be drawn on a paint
- device.
+ QTextLayout can be used to create a sequence of QTextLine
+ instances with given widths and can position them independently
+ on the screen. Once the layout is done, these lines can be drawn
+ on a paint device.
- Here's some code snippet that presents the layout phase:
+ The text to be laid out can be provided in the constructor or set with
+ setText().
+
+ The layout can be seen as a sequence of QTextLine objects; use createLine()
+ to create a QTextLine instance, and lineAt() or lineForTextPosition() to retrieve
+ created lines.
+
+ Here is a code snippet that demonstrates the layout phase:
\snippet doc/src/snippets/code/src_gui_text_qtextlayout.cpp 0
- The text can be drawn by calling the layout's draw() function:
+ The text can then be rendered by calling the layout's draw() function:
\snippet doc/src/snippets/code/src_gui_text_qtextlayout.cpp 1
- The text layout's text is set in the constructor or with
- setText(). The layout can be seen as a sequence of QTextLine
- objects; use lineAt() or lineForTextPosition() to get a QTextLine,
- createLine() to create one. For a given position in the text you
- can find a valid cursor position with isValidCursorPosition(),
- nextCursorPosition(), and previousCursorPosition(). The layout
- itself can be positioned with setPosition(); it has a
- boundingRect(), and a minimumWidth() and a maximumWidth(). A text
- layout can be drawn on a painter device using draw().
+ For a given position in the text you can find a valid cursor position with
+ isValidCursorPosition(), nextCursorPosition(), and previousCursorPosition().
+
+ The QTextLayout itself can be positioned with setPosition(); it has a
+ boundingRect(), and a minimumWidth() and a maximumWidth().
+
+ \sa QStaticText
*/
/*!
@@ -1364,7 +1367,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)
@@ -1691,7 +1694,7 @@ namespace {
{
LineBreakHelper()
: glyphCount(0), maxGlyphs(0), currentPosition(0), fontEngine(0), logClusters(0),
- manualWrap(false)
+ manualWrap(false), whiteSpaceOrObject(true)
{
}
@@ -1714,6 +1717,7 @@ namespace {
const unsigned short *logClusters;
bool manualWrap;
+ bool whiteSpaceOrObject;
bool checkFullOtherwiseExtend(QScriptLine &line);
@@ -1723,8 +1727,10 @@ namespace {
}
inline glyph_t currentGlyph() const
- {
+ {
Q_ASSERT(currentPosition > 0);
+ Q_ASSERT(logClusters[currentPosition - 1] < glyphs.numGlyphs);
+
return glyphs.glyphs[logClusters[currentPosition - 1]];
}
@@ -1870,6 +1876,7 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) {
+ lbh.whiteSpaceOrObject = true;
if (lbh.checkFullOtherwiseExtend(line))
goto found;
@@ -1886,6 +1893,7 @@ void QTextLine::layout_helper(int maxGlyphs)
if (lbh.checkFullOtherwiseExtend(line))
goto found;
} else if (current.analysis.flags == QScriptAnalysis::LineOrParagraphSeparator) {
+ lbh.whiteSpaceOrObject = true;
// if the line consists only of the line separator make sure
// we have a sane height
if (!line.length && !lbh.tmpData.length)
@@ -1899,6 +1907,7 @@ void QTextLine::layout_helper(int maxGlyphs)
line += lbh.tmpData;
goto found;
} else if (current.analysis.flags == QScriptAnalysis::Object) {
+ lbh.whiteSpaceOrObject = true;
lbh.tmpData.length++;
QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item]));
@@ -1912,6 +1921,7 @@ void QTextLine::layout_helper(int maxGlyphs)
if (lbh.checkFullOtherwiseExtend(line))
goto found;
} else if (attributes[lbh.currentPosition].whiteSpace) {
+ lbh.whiteSpaceOrObject = true;
while (lbh.currentPosition < end && attributes[lbh.currentPosition].whiteSpace)
addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount,
current, lbh.logClusters, lbh.glyphs);
@@ -1921,6 +1931,7 @@ void QTextLine::layout_helper(int maxGlyphs)
goto found;
}
} else {
+ lbh.whiteSpaceOrObject = false;
bool sb_or_ws = false;
do {
addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
@@ -1982,7 +1993,7 @@ void QTextLine::layout_helper(int maxGlyphs)
LB_DEBUG("reached end of line");
lbh.checkFullOtherwiseExtend(line);
found:
- if (lbh.rightBearing > 0) // If right bearing has not yet been adjusted
+ if (lbh.rightBearing > 0 && !lbh.whiteSpaceOrObject) // If right bearing has not yet been adjusted
lbh.adjustRightBearing();
line.textAdvance = line.textWidth;
line.textWidth -= qMin(QFixed(), lbh.rightBearing);