diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-08-13 08:09:53 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-08-13 08:33:13 (GMT) |
commit | 5114fcb45d584ea50da7397088f084dfd74922b9 (patch) | |
tree | 18cb40f048186ebf0eac568e2ae53ec092044c55 /src/gui/text/qtextlayout.cpp | |
parent | 55e47566dd1ac83ff674401dfd6284f07490cd8b (diff) | |
parent | ee62807198a2525577c14f718b98d07ae0ec7bec (diff) | |
download | Qt-5114fcb45d584ea50da7397088f084dfd74922b9.zip Qt-5114fcb45d584ea50da7397088f084dfd74922b9.tar.gz Qt-5114fcb45d584ea50da7397088f084dfd74922b9.tar.bz2 |
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts:
src/gui/painting/qpainter.cpp
src/gui/text/qtextengine.cpp
tests/auto/qimage/tst_qimage.cpp
tests/auto/qpainter/tst_qpainter.cpp
tools/qdoc3/test/assistant.qdocconf
tools/qdoc3/test/designer.qdocconf
tools/qdoc3/test/linguist.qdocconf
tools/qdoc3/test/qmake.qdocconf
tools/qdoc3/test/qt-build-docs.qdocconf
tools/qdoc3/test/qt-html-templates.qdocconf
tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf
tools/qdoc3/test/qt.qdocconf
Diffstat (limited to 'src/gui/text/qtextlayout.cpp')
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 9d27343..3f83aee 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -76,6 +76,8 @@ static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line int pos = line.length; const HB_CharAttributes *attributes = eng->attributes(); + if (!attributes) + return QFixed(); while (pos > 0 && attributes[line.from + pos - 1].whiteSpace) --pos; return eng->width(line.from + pos, line.length - pos); @@ -612,7 +614,7 @@ bool QTextLayout::cacheEnabled() const void QTextLayout::beginLayout() { #ifndef QT_NO_DEBUG - if (d->layoutData && d->layoutData->inLayout) { + if (d->layoutData && d->layoutData->layoutState == QTextEngine::InLayout) { qWarning("QTextLayout::beginLayout: Called while already doing layout"); return; } @@ -620,7 +622,7 @@ void QTextLayout::beginLayout() d->invalidate(); d->clearLineData(); d->itemize(); - d->layoutData->inLayout = true; + d->layoutData->layoutState = QTextEngine::InLayout; } /*! @@ -631,7 +633,7 @@ void QTextLayout::beginLayout() void QTextLayout::endLayout() { #ifndef QT_NO_DEBUG - if (!d->layoutData || !d->layoutData->inLayout) { + if (!d->layoutData || d->layoutData->layoutState == QTextEngine::LayoutEmpty) { qWarning("QTextLayout::endLayout: Called without beginLayout()"); return; } @@ -640,7 +642,7 @@ void QTextLayout::endLayout() if (l && d->lines.at(l-1).length < 0) { QTextLine(l-1, d).setNumColumns(INT_MAX); } - d->layoutData->inLayout = false; + d->layoutData->layoutState = QTextEngine::LayoutEmpty; if (!d->cacheGlyphs) d->freeMemory(); } @@ -768,11 +770,14 @@ bool QTextLayout::isValidCursorPosition(int pos) const QTextLine QTextLayout::createLine() { #ifndef QT_NO_DEBUG - if (!d->layoutData || !d->layoutData->inLayout) { + if (!d->layoutData || d->layoutData->layoutState == QTextEngine::LayoutEmpty) { qWarning("QTextLayout::createLine: Called without layouting"); return QTextLine(); } #endif + if (d->layoutData->layoutState == QTextEngine::LayoutFailed) + return QTextLine(); + int l = d->lines.size(); if (l && d->lines.at(l-1).length < 0) { QTextLine(l-1, d).setNumColumns(INT_MAX); @@ -1776,14 +1781,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() @@ -1884,6 +1893,8 @@ void QTextLine::layout_helper(int maxGlyphs) Qt::Alignment alignment = eng->option.alignment(); const HB_CharAttributes *attributes = eng->attributes(); + if (!attributes) + return; lbh.currentPosition = line.from; int end = 0; lbh.logClusters = eng->layoutData->logClustersPtr; @@ -1897,6 +1908,8 @@ void QTextLine::layout_helper(int maxGlyphs) if (!current.num_glyphs) { eng->shape(item); attributes = eng->attributes(); + if (!attributes) + return; lbh.logClusters = eng->layoutData->logClustersPtr; } lbh.currentPosition = qMax(line.from, current.position); @@ -1975,6 +1988,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); @@ -2018,9 +2034,17 @@ 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 !defined(Q_WS_MAC) if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width) +#endif 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; } |