summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-08-09 08:31:16 (GMT)
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-08-09 08:35:56 (GMT)
commitc5fa9eb1cb02d979502e2c9918d752c6708fb406 (patch)
tree4b35490fde8398e9f1c4608f4e1f38adeb5e155a
parentcfe96b7c99cb12a666111c7861aba74d535adc89 (diff)
downloadQt-c5fa9eb1cb02d979502e2c9918d752c6708fb406.zip
Qt-c5fa9eb1cb02d979502e2c9918d752c6708fb406.tar.gz
Qt-c5fa9eb1cb02d979502e2c9918d752c6708fb406.tar.bz2
Fix scrollbar randomly popping up in QPlainTextEdit
When a line break was detected, we would retain the value of the right bearing for the character after the break instead of resetting it to the right bearing of the previous value. This could in some cases cause the bounding rect of the text to be wrong, and could cause unnecessary horizontal scrollbars to pop up. It was especially visible when using WrapAnywhere. Visible e.g. in the compile output in Creator. Done-by: mae Reviewed-by: Eskil Reviewed-by: Lars
-rw-r--r--src/gui/text/qtextlayout.cpp21
-rw-r--r--tests/auto/qtextlayout/tst_qtextlayout.cpp30
2 files changed, 47 insertions, 4 deletions
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 5a11c87..da43913 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -1709,14 +1709,18 @@ namespace {
return glyphs.glyphs[logClusters[currentPosition - 1]];
}
+ inline void adjustRightBearing(glyph_t glyph)
+ {
+ qreal rb;
+ fontEngine->getGlyphBearings(glyph, 0, &rb);
+ rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
+ }
+
inline void adjustRightBearing()
{
if (currentPosition <= 0)
return;
-
- qreal rb;
- fontEngine->getGlyphBearings(currentGlyph(), 0, &rb);
- rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
+ adjustRightBearing(currentGlyph());
}
inline void resetRightBearing()
@@ -1901,6 +1905,9 @@ void QTextLine::layout_helper(int maxGlyphs)
} else {
lbh.whiteSpaceOrObject = false;
bool sb_or_ws = false;
+ glyph_t previousGlyph = 0;
+ if (lbh.currentPosition > 0 && lbh.logClusters[lbh.currentPosition - 1] <lbh.glyphs.numGlyphs)
+ previousGlyph = lbh.currentGlyph(); // needed to calculate right bearing later
do {
addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
current, lbh.logClusters, lbh.glyphs);
@@ -1944,9 +1951,15 @@ void QTextLine::layout_helper(int maxGlyphs)
// 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) {
+ QFixed rightBearing = lbh.rightBearing; // store previous right bearing
if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width)
lbh.adjustRightBearing();
if (lbh.checkFullOtherwiseExtend(line)) {
+ // we are too wide, fix right bearing
+ if (rightBearing <= 0)
+ lbh.rightBearing = rightBearing; // take from cache
+ else if (previousGlyph > 0)
+ lbh.adjustRightBearing(previousGlyph);
if (!breakany) {
line.textWidth += lbh.softHyphenWidth;
}
diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp
index f798faf..659ba1a 100644
--- a/tests/auto/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp
@@ -122,6 +122,7 @@ private slots:
void smallTextLengthWrapAtWordBoundaryOrAnywhere();
void testLineBreakingAllSpaces();
void lineWidthFromBOM();
+ void textWidthVsWIdth();
private:
@@ -1359,5 +1360,34 @@ void tst_QTextLayout::glyphLessItems()
}
}
+void tst_QTextLayout::textWidthVsWIdth()
+{
+ QTextLayout layout;
+ QTextOption opt;
+ opt.setWrapMode(QTextOption::WrapAnywhere);
+ layout.setTextOption(opt);
+ layout.setText(QString::fromLatin1(
+ "g++ -c -m64 -pipe -g -fvisibility=hidden -fvisibility-inlines-hidden -Wall -W -D_REENTRANT -fPIC -DCORE_LIBRARY -DIDE_LIBRARY_BASENAME=\"lib\" -DWITH_TESTS "
+ "-DQT_NO_CAST_TO_ASCII -DQT_USE_FAST_OPERATOR_PLUS -DQT_USE_FAST_CONCATENATION -DQT_PLUGIN -DQT_TESTLIB_LIB -DQT_SCRIPT_LIB -DQT_SVG_LIB -DQT_SQL_LIB -DQT_XM"
+ "L_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I../../../../qt-qml/mkspecs/linux-g++-64 -I. -I../../../../qt-qml/include/QtCore -I../../../."
+ "./qt-qml/include/QtNetwork -I../../../../qt-qml/include/QtGui -I../../../../qt-qml/include/QtXml -I../../../../qt-qml/include/QtSql -I../../../../qt-qml/inc"
+ "lude/QtSvg -I../../../../qt-qml/include/QtScript -I../../../../qt-qml/include/QtTest -I../../../../qt-qml/include -I../../../../qt-qml/include/QtHelp -I../."
+ "./libs -I/home/ettrich/dev/creator/tools -I../../plugins -I../../shared/scriptwrapper -I../../libs/3rdparty/botan/build -Idialogs -Iactionmanager -Ieditorma"
+ "nager -Iprogressmanager -Iscriptmanager -I.moc/debug-shared -I.uic -o .obj/debug-shared/sidebar.o sidebar.cpp"));
+
+ // textWidth includes right bearing, but it should never be LARGER than width if there is space for at least one character
+ for (int width = 100; width < 1000; ++width) {
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ line.setLineWidth(width);
+ layout.endLayout();
+
+ qreal textWidthIsLargerBy = qMax(qreal(0), line.naturalTextWidth() - line.width());
+ qreal thisMustBeZero = 0;
+ QCOMPARE(textWidthIsLargerBy, thisMustBeZero);
+ }
+}
+
+
QTEST_MAIN(tst_QTextLayout)
#include "tst_qtextlayout.moc"