--- a/src/gui/text/qtextlayout.cpp Tue Jul 06 15:10:48 2010 +0300
+++ b/src/gui/text/qtextlayout.cpp Wed Aug 18 10:37:55 2010 +0300
@@ -69,7 +69,7 @@
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,12 +86,12 @@
// 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.textWidth + leadingSpaceWidth(eng, line));
+ x = line.width - (line.textAdvance + leadingSpaceWidth(eng, line));
else if (align & Qt::AlignHCenter)
- x = (line.width - line.textWidth)/2;
+ x = (line.width - line.textAdvance)/2;
}
return x;
}
@@ -282,12 +282,11 @@
\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
@@ -297,29 +296,33 @@
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 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.
-
- Here's some code snippet that presents the layout phase:
+ QTextLayout can be used with both plain and rich text.
+
+ 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.
+
+ 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
*/
@@ -858,7 +861,8 @@
const QScriptLine &si = d->lines[i];
xmin = qMin(xmin, si.x);
ymin = qMin(ymin, si.y);
- xmax = qMax(xmax, si.x+qMax(si.width, si.textWidth));
+ QFixed lineWidth = si.width < QFIXED_MAX ? qMax(si.width, si.textWidth) : si.textWidth;
+ xmax = qMax(xmax, si.x+lineWidth);
// ### shouldn't the ascent be used in ymin???
ymax = qMax(ymax, si.y+si.height());
}
@@ -1336,7 +1340,7 @@
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)
@@ -1660,7 +1664,7 @@
{
LineBreakHelper()
: glyphCount(0), maxGlyphs(0), currentPosition(0), fontEngine(0), logClusters(0),
- manualWrap(false)
+ manualWrap(false), whiteSpaceOrObject(true)
{
}
@@ -1683,6 +1687,7 @@
const unsigned short *logClusters;
bool manualWrap;
+ bool whiteSpaceOrObject;
bool checkFullOtherwiseExtend(QScriptLine &line);
@@ -1692,8 +1697,10 @@
}
inline glyph_t currentGlyph() const
- {
+ {
Q_ASSERT(currentPosition > 0);
+ Q_ASSERT(logClusters[currentPosition - 1] < glyphs.numGlyphs);
+
return glyphs.glyphs[logClusters[currentPosition - 1]];
}
@@ -1828,6 +1835,7 @@
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;
@@ -1844,6 +1852,7 @@
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)
@@ -1857,6 +1866,7 @@
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]));
@@ -1870,6 +1880,7 @@
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);
@@ -1879,6 +1890,7 @@
goto found;
}
} else {
+ lbh.whiteSpaceOrObject = false;
bool sb_or_ws = false;
do {
addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
@@ -1923,7 +1935,7 @@
// We ignore the right bearing if the minimum negative bearing is too little to
// expand the text beyond the edge.
if (sb_or_ws|breakany) {
- if (lbh.calculateNewWidth(line) + lbh.minimumRightBearing > line.width)
+ if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width)
lbh.adjustRightBearing();
if (lbh.checkFullOtherwiseExtend(line)) {
if (!breakany) {
@@ -1940,7 +1952,7 @@
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);