diff options
author | Gunnar Sletta <gunnar.sletta@nokia.com> | 2011-08-25 10:11:49 +0200 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@nokia.com> | 2011-08-25 12:48:52 +0200 |
commit | 04d0a9626ce61b2e05a40f9562c2bcf12e234639 (patch) | |
tree | f1643f829aedc9ac51fcc260f7df2639dfe08360 /src/gui/text | |
parent | 17f3451daa286b88a52f18c802d7b158dfb653b2 (diff) | |
parent | bdc417b3828737334723eae23097c85f70c23a33 (diff) |
Merge branch 'master' into refactor
Conflicts:
src/gui/kernel/qapplication_qpa.cpp
src/gui/kernel/qcursor_qpa.cpp
src/gui/kernel/qwindowsysteminterface_qpa.cpp
src/gui/kernel/qwindowsysteminterface_qpa.h
src/gui/kernel/qwindowsysteminterface_qpa_p.h
src/gui/text/qtextcontrol.cpp
src/plugins/platforms/wayland/wayland.pro
src/widgets/accessible/qaccessible2.h
src/widgets/widgets/qwidgetlinecontrol_p.h
Change-Id: I5e6f4eb184159dccc67e8f13673edb884d179c74
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfontdatabase_qpa.cpp | 3 | ||||
-rw-r--r-- | src/gui/text/qfontengine_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 30 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.h | 4 | ||||
-rw-r--r-- | src/gui/text/qglyphrun.cpp | 45 | ||||
-rw-r--r-- | src/gui/text/qglyphrun.h | 3 | ||||
-rw-r--r-- | src/gui/text/qglyphrun_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol.cpp | 24 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol_p.h | 3 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 44 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 63 | ||||
-rw-r--r-- | src/gui/text/qtextobject.cpp | 17 | ||||
-rw-r--r-- | src/gui/text/qtextobject.h | 2 |
13 files changed, 162 insertions, 80 deletions
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index d8b79840f6..c0edce1009 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -275,7 +275,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, if (!engine) { if (!request.family.isEmpty()) { QStringList fallbacks = fallbackFamilies(request.family,QFont::Style(request.style),QFont::StyleHint(request.styleHint),QUnicodeTables::Script(script)); - for (int i = 0; i < fallbacks.size(); i++) { + for (int i = 0; !engine && i < fallbacks.size(); i++) { QFontDef def = request; def.family = fallbacks.at(i); QFontCache::Key key(def,script); @@ -289,7 +289,6 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, engine = loadEngine(script, def, desc.family, desc.foundry, desc.style, desc.size); if (engine) { initFontDef(desc, def, &engine->fontDef); - break; } } } diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index c53e841cf4..b32e6916f0 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -291,7 +291,7 @@ private: struct GlyphCacheEntry { void *context; QExplicitlySharedDataPointer<QFontEngineGlyphCache> cache; - bool operator==(const GlyphCacheEntry &other) { return context == other.context && cache == other.cache; } + bool operator==(const GlyphCacheEntry &other) const { return context == other.context && cache == other.cache; } }; mutable QLinkedList<GlyphCacheEntry> m_glyphCaches; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 9e1646f046..9fce85f25b 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -224,7 +224,6 @@ QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm) } /*! - \overload Returns true if \a other is equal to this object; otherwise returns false. @@ -240,21 +239,6 @@ bool QFontMetrics::operator ==(const QFontMetrics &other) const } /*! - Returns true if \a other is equal to this object; otherwise - returns false. - - Two font metrics are considered equal if they were constructed - from the same QFont and the paint devices they were constructed - for are considered compatible. - - \sa operator!=() -*/ -bool QFontMetrics::operator ==(const QFontMetrics &other) -{ - return d == other.d; -} - -/*! \fn bool QFontMetrics::operator!=(const QFontMetrics &other) Returns true if \a other is not equal to this object; otherwise returns false. @@ -1118,7 +1102,6 @@ QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm) } /*! - \overload Returns true if the font metrics are equal to the \a other font metrics; otherwise returns false. @@ -1132,19 +1115,6 @@ bool QFontMetricsF::operator ==(const QFontMetricsF &other) const } /*! - Returns true if the font metrics are equal to the \a other font - metrics; otherwise returns false. - - Two font metrics are considered equal if they were constructed from the - same QFont and the paint devices they were constructed for are - considered to be compatible. -*/ -bool QFontMetricsF::operator ==(const QFontMetricsF &other) -{ - return d == other.d; -} - -/*! \fn bool QFontMetricsF::operator!=(const QFontMetricsF &other) Returns true if the font metrics are not equal to the \a other font diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index 50e4dbb46a..f21e820556 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -117,9 +117,7 @@ public: int strikeOutPos() const; int lineWidth() const; - bool operator==(const QFontMetrics &other); // 5.0 - remove me bool operator==(const QFontMetrics &other) const; - inline bool operator !=(const QFontMetrics &other) { return !operator==(other); } // 5.0 - remove me inline bool operator !=(const QFontMetrics &other) const { return !operator==(other); } private: @@ -183,9 +181,7 @@ public: qreal strikeOutPos() const; qreal lineWidth() const; - bool operator==(const QFontMetricsF &other); // 5.0 - remove me bool operator==(const QFontMetricsF &other) const; - inline bool operator !=(const QFontMetricsF &other) { return !operator==(other); } // 5.0 - remove me inline bool operator !=(const QFontMetricsF &other) const { return !operator==(other); } private: diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp index cc825525c4..be9c058693 100644 --- a/src/gui/text/qglyphrun.cpp +++ b/src/gui/text/qglyphrun.cpp @@ -45,6 +45,7 @@ #include "qglyphrun.h" #include "qglyphrun_p.h" +#include <qdebug.h> QT_BEGIN_NAMESPACE @@ -343,12 +344,44 @@ void QGlyphRun::setStrikeOut(bool strikeOut) } /*! - Returns the smallest rectangle that contains all glyphs in this QGlyphRun. + Sets the bounding rect of the glyphs in this QGlyphRun to be \a boundingRect. This rectangle + will be returned by boundingRect() unless it is empty, in which case the bounding rectangle of the + glyphs in the glyph run will be returned instead. + + \note Unless you are implementing text shaping, you should not have to use this function. + It is used specifically when the QGlyphRun should represent an area which is smaller than the + area of the glyphs it contains. This could happen e.g. if the glyph run is retrieved by calling + QTextLayout::glyphRuns() and the specified range only includes part of a ligature (where two or + more characters are combined to a single glyph.) When this is the case, the bounding rect should + only include the appropriate part of the ligature glyph, based on a calculation of the average + width of the characters in the ligature. + + In order to support such a case (an example is selections which should be drawn with a different + color than the main text color), it is necessary to clip the painting mechanism to the rectangle + returned from boundingRect() to avoid drawing the entire ligature glyph. + + \sa boundingRect() + + \since 5.0 +*/ +void QGlyphRun::setBoundingRect(const QRectF &boundingRect) +{ + detach(); + d->boundingRect = boundingRect; +} + +/*! + Returns the smallest rectangle that contains all glyphs in this QGlyphRun. If a bounding rect + has been set using setBoundingRect(), then this will be returned. Otherwise the bounding rect + will be calculated based on the font metrics of the glyphs in the glyph run. \since 5.0 */ QRectF QGlyphRun::boundingRect() const { + if (!d->boundingRect.isEmpty()) + return d->boundingRect; + qreal minX, minY, maxX, maxY; for (int i=0; i<qMin(d->glyphPositions.size(), d->glyphIndexes.size()); ++i) { @@ -371,6 +404,16 @@ QRectF QGlyphRun::boundingRect() const return QRectF(QPointF(minX, minY), QPointF(maxX, maxY)); } +/*! + Returns true if the QGlyphRun does not contain any glyphs. + + \since 5.0 +*/ +bool QGlyphRun::isEmpty() const +{ + return d->glyphIndexes.isEmpty(); +} + QT_END_NAMESPACE #endif // QT_NO_RAWFONT diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h index b4f02f0d87..da88bc72f9 100644 --- a/src/gui/text/qglyphrun.h +++ b/src/gui/text/qglyphrun.h @@ -91,8 +91,11 @@ public: void setStrikeOut(bool strikeOut); bool strikeOut() const; + void setBoundingRect(const QRectF &boundingRect); QRectF boundingRect() const; + bool isEmpty() const; + private: friend class QGlyphRunPrivate; friend class QTextLine; diff --git a/src/gui/text/qglyphrun_p.h b/src/gui/text/qglyphrun_p.h index a7745e68ce..b632678971 100644 --- a/src/gui/text/qglyphrun_p.h +++ b/src/gui/text/qglyphrun_p.h @@ -83,6 +83,7 @@ public: , glyphIndexes(other.glyphIndexes) , glyphPositions(other.glyphPositions) , rawFont(other.rawFont) + , boundingRect(other.boundingRect) , overline(other.overline) , underline(other.underline) , strikeOut(other.strikeOut) @@ -96,6 +97,7 @@ public: QVector<quint32> glyphIndexes; QVector<QPointF> glyphPositions; QRawFont rawFont; + QRectF boundingRect; uint overline : 1; uint underline : 1; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index d280a67a1b..9ca6a24ce7 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -406,6 +406,8 @@ void QTextControlPrivate::init(Qt::TextFormat format, const QString &text, QText doc->setUndoRedoEnabled(interactionFlags & Qt::TextEditable); q->setCursorWidth(-1); + + QObject::connect(q, SIGNAL(updateCursorRequest(QRectF)), q, SIGNAL(updateRequest(QRectF))); } void QTextControlPrivate::setContent(Qt::TextFormat format, const QString &text, QTextDocument *document) @@ -544,7 +546,7 @@ void QTextControlPrivate::setCursorPosition(int pos, QTextCursor::MoveMode mode) void QTextControlPrivate::repaintCursor() { Q_Q(QTextControl); - emit q->updateRequest(cursorRectPlusUnicodeDirectionMarkers(cursor)); + emit q->updateCursorRequest(cursorRectPlusUnicodeDirectionMarkers(cursor)); } void QTextControlPrivate::repaintOldAndNewSelection(const QTextCursor &oldSelection) @@ -562,9 +564,16 @@ void QTextControlPrivate::repaintOldAndNewSelection(const QTextCursor &oldSelect differenceSelection.setPosition(cursor.position(), QTextCursor::KeepAnchor); emit q->updateRequest(q->selectionRect(differenceSelection)); } else { - if (!oldSelection.isNull()) - emit q->updateRequest(q->selectionRect(oldSelection) | cursorRectPlusUnicodeDirectionMarkers(oldSelection)); - emit q->updateRequest(q->selectionRect() | cursorRectPlusUnicodeDirectionMarkers(cursor)); + if (!oldSelection.hasSelection() && !cursor.hasSelection()) { + if (!oldSelection.isNull()) + emit q->updateCursorRequest(q->selectionRect(oldSelection) | cursorRectPlusUnicodeDirectionMarkers(oldSelection)); + emit q->updateCursorRequest(q->selectionRect() | cursorRectPlusUnicodeDirectionMarkers(cursor)); + + } else { + if (!oldSelection.isNull()) + emit q->updateRequest(q->selectionRect(oldSelection) | cursorRectPlusUnicodeDirectionMarkers(oldSelection)); + emit q->updateRequest(q->selectionRect() | cursorRectPlusUnicodeDirectionMarkers(cursor)); + } } } @@ -2750,6 +2759,12 @@ void QTextControl::setPalette(const QPalette &pal) d->palette = pal; } +bool QTextControl::cursorOn() const +{ + Q_D(const QTextControl); + return d->cursorOn; +} + QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext() const { Q_D(const QTextControl); @@ -2887,6 +2902,7 @@ void QTextEditMimeData::setup() const fragment = QTextDocumentFragment(); } + QT_END_NAMESPACE #include "moc_qtextcontrol_p.cpp" diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h index 95c5f4d56a..bb91415fd2 100644 --- a/src/gui/text/qtextcontrol_p.h +++ b/src/gui/text/qtextcontrol_p.h @@ -215,6 +215,7 @@ Q_SIGNALS: void cursorPositionChanged(); // control signals + void updateCursorRequest(const QRectF &rect = QRectF()); void updateRequest(const QRectF &rect = QRectF()); void documentSizeChanged(const QSizeF &); void blockCountChanged(int newBlockCount); @@ -247,6 +248,8 @@ public: bool setFocusToNextOrPreviousAnchor(bool next); bool findNextPrevAnchor(const QTextCursor& from, bool next, QTextCursor& newAnchor); + bool cursorOn() const; + protected: virtual void timerEvent(QTimerEvent *e); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 0d3aa0b585..58cccfcbf7 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1532,33 +1532,38 @@ void QTextEngine::itemize() const const ushort *e = uc + length; int lastScript = QUnicodeTables::Common; while (uc < e) { - int script = QUnicodeTables::script(*uc); - if (script == QUnicodeTables::Inherited) - script = lastScript; - analysis->flags = QScriptAnalysis::None; - if (*uc == QChar::ObjectReplacementCharacter) { - if (analysis->bidiLevel % 2) - --analysis->bidiLevel; + switch (*uc) { + case QChar::ObjectReplacementCharacter: analysis->script = QUnicodeTables::Common; analysis->flags = QScriptAnalysis::Object; - } else if (*uc == QChar::LineSeparator) { + break; + case QChar::LineSeparator: if (analysis->bidiLevel % 2) --analysis->bidiLevel; analysis->script = QUnicodeTables::Common; analysis->flags = QScriptAnalysis::LineOrParagraphSeparator; if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) *const_cast<ushort*>(uc) = 0x21B5; // visual line separator - } else if (*uc == 9) { + break; + case 9: // Tab analysis->script = QUnicodeTables::Common; analysis->flags = QScriptAnalysis::Tab; analysis->bidiLevel = control.baseLevel(); - } else if ((*uc == 32 || *uc == QChar::Nbsp) - && (option.flags() & QTextOption::ShowTabsAndSpaces)) { - analysis->script = QUnicodeTables::Common; - analysis->flags = QScriptAnalysis::Space; - analysis->bidiLevel = control.baseLevel(); - } else { - analysis->script = script; + break; + case 32: // Space + case QChar::Nbsp: + if (option.flags() & QTextOption::ShowTabsAndSpaces) { + analysis->script = QUnicodeTables::Common; + analysis->flags = QScriptAnalysis::Space; + analysis->bidiLevel = control.baseLevel(); + break; + } + // fall through + default: + int script = QUnicodeTables::script(*uc); + analysis->script = script == QUnicodeTables::Inherited ? lastScript : script; + analysis->flags = QScriptAnalysis::None; + break; } lastScript = analysis->script; ++uc; @@ -2432,7 +2437,7 @@ void QTextEngine::indexAdditionalFormats() between the text that gets truncated and the ellipsis. This is important to get correctly shaped results for arabic text. */ -static bool nextCharJoins(const QString &string, int pos) +static inline bool nextCharJoins(const QString &string, int pos) { while (pos < string.length() && string.at(pos).category() == QChar::Mark_NonSpacing) ++pos; @@ -2441,13 +2446,14 @@ static bool nextCharJoins(const QString &string, int pos) return string.at(pos).joining() != QChar::OtherJoining; } -static bool prevCharJoins(const QString &string, int pos) +static inline bool prevCharJoins(const QString &string, int pos) { while (pos > 0 && string.at(pos - 1).category() == QChar::Mark_NonSpacing) --pos; if (pos == 0) return false; - return (string.at(pos - 1).joining() == QChar::Dual || string.at(pos - 1).joining() == QChar::Center); + QChar::Joining joining = string.at(pos - 1).joining(); + return (joining == QChar::Dual || joining == QChar::Center); } QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int flags) const diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index d6eca77b00..25d7de827e 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -42,6 +42,7 @@ #include "qtextlayout.h" #include "qtextengine_p.h" +#include <qthread.h> #include <qfont.h> #include <qpainter.h> #include <qvarlengtharray.h> @@ -2106,8 +2107,10 @@ static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const Q } +#if !defined(QT_NO_RAWFONT) static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, const QGlyphLayout &glyphLayout, - const QPointF &pos, const QTextItem::RenderFlags &flags) + const QPointF &pos, const QTextItem::RenderFlags &flags, + const QFixed &selectionX, const QFixed &selectionWidth) { QGlyphRun glyphRun; @@ -2115,6 +2118,7 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, const QGlyphLayout &g QRawFont font; QRawFontPrivate *fontD = QRawFontPrivate::get(font); fontD->fontEngine = fontEngine; + fontD->thread = QThread::currentThread(); fontD->fontEngine->ref.ref(); #if defined(Q_WS_WIN) @@ -2149,13 +2153,27 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, const QGlyphLayout &g positionsArray); Q_ASSERT(glyphsArray.size() == positionsArray.size()); + qreal fontHeight = font.ascent() + font.descent(); + qreal minY; + qreal maxY; QVector<quint32> glyphs; QVector<QPointF> positions; for (int i=0; i<glyphsArray.size(); ++i) { glyphs.append(glyphsArray.at(i) & 0xffffff); - positions.append(positionsArray.at(i).toPointF() + pos); + + QPointF position = positionsArray.at(i).toPointF() + pos; + positions.append(position); + + if (i == 0) { + maxY = minY = position.y(); + } else { + minY = qMin(minY, position.y()); + maxY = qMax(maxY, position.y()); + } } + qreal height = maxY + fontHeight - minY; + glyphRun.setGlyphIndexes(glyphs); glyphRun.setPositions(positions); @@ -2164,6 +2182,8 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, const QGlyphLayout &g glyphRun.setStrikeOut(flags.testFlag(QTextItem::StrikeOut)); glyphRun.setRawFont(font); + glyphRun.setBoundingRect(QRectF(selectionX.toReal(), minY, selectionWidth.toReal(), height)); + return glyphRun; } @@ -2180,7 +2200,6 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, const QGlyphLayout &g \sa QTextLayout::glyphRuns() */ -#if !defined(QT_NO_RAWFONT) QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const { const QScriptLine &line = eng->lines[i]; @@ -2194,7 +2213,14 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const if (length < 0) length = textLength(); - QTextLineItemIterator iterator(eng, i); + if (length == 0) + return QList<QGlyphRun>(); + + QTextLayout::FormatRange selection; + selection.start = from; + selection.length = length; + + QTextLineItemIterator iterator(eng, i, QPointF(), &selection); qreal y = line.y.toReal() + line.base().toReal(); QList<QGlyphRun> glyphRuns; while (!iterator.atEnd()) { @@ -2204,7 +2230,10 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const QPointF pos(iterator.x.toReal(), y); if (from >= 0 && length >= 0 && - (from >= si.position + eng->length(&si) || from + length <= si.position)) { + (from >= si.position + eng->length(&si) + || from + length <= si.position + || from + length <= iterator.itemStart + || from >= iterator.itemEnd)) { continue; } @@ -2233,19 +2262,22 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const ? si.num_glyphs - 1 : logClusters[relativeTo]; + int itemGlyphsStart = logClusters[iterator.itemStart - si.position]; + int itemGlyphsEnd = logClusters[iterator.itemEnd - 1 - si.position]; + QGlyphLayout glyphLayout = eng->shapedGlyphs(&si); // Calculate new x position of glyph layout for a subset. This becomes somewhat complex // when we're breaking a RTL script item, since the expected position passed into // getGlyphPositions() is the left-most edge of the left-most glyph in an RTL run. if (relativeFrom != (iterator.itemStart - si.position) && !rtl) { - for (int i=0; i<glyphsStart; ++i) { + for (int i=itemGlyphsStart; i<glyphsStart; ++i) { QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6); pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(), glyphLayout.advances_y[i].toReal()); } } else if (relativeTo != (iterator.itemEnd - si.position - 1) && rtl) { - for (int i=glyphLayout.numGlyphs - 1; i>glyphsEnd; --i) { + for (int i=itemGlyphsEnd; i>glyphsEnd; --i) { QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6); pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(), glyphLayout.advances_y[i].toReal()); @@ -2254,6 +2286,10 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const glyphLayout = glyphLayout.mid(glyphsStart, glyphsEnd - glyphsStart + 1); + QFixed x; + QFixed width; + iterator.getSelectionBounds(&x, &width); + if (glyphLayout.numGlyphs > 0) { QFontEngine *mainFontEngine = font.d->engineForScript(si.analysis.script); if (mainFontEngine->type() == QFontEngine::Multi) { @@ -2268,7 +2304,7 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const QGlyphLayout subLayout = glyphLayout.mid(start, end - start); glyphRuns.append(glyphRunWithInfo(multiFontEngine->engine(which), - subLayout, pos, flags)); + subLayout, pos, flags, x, width)); for (int i = 0; i < subLayout.numGlyphs; i++) { pos += QPointF(subLayout.advances_x[i].toReal(), subLayout.advances_y[i].toReal()); @@ -2279,10 +2315,15 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const } QGlyphLayout subLayout = glyphLayout.mid(start, end - start); - glyphRuns.append(glyphRunWithInfo(multiFontEngine->engine(which), - subLayout, pos, flags)); + QGlyphRun glyphRun = glyphRunWithInfo(multiFontEngine->engine(which), + subLayout, pos, flags, x, width); + if (!glyphRun.isEmpty()) + glyphRuns.append(glyphRun); } else { - glyphRuns.append(glyphRunWithInfo(mainFontEngine, glyphLayout, pos, flags)); + QGlyphRun glyphRun = glyphRunWithInfo(mainFontEngine, glyphLayout, pos, flags, x, + width); + if (!glyphRun.isEmpty()) + glyphRuns.append(glyphRun); } } } diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index cea5eac465..d641266367 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1667,21 +1667,24 @@ QTextBlock::iterator &QTextBlock::iterator::operator--() \sa QGlyphRun, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun() */ #if !defined(QT_NO_RAWFONT) -QList<QGlyphRun> QTextFragment::glyphRuns() const +QList<QGlyphRun> QTextFragment::glyphRuns(int pos, int len) const { if (!p || !n) return QList<QGlyphRun>(); - int pos = position(); - int len = length(); - if (len == 0) - return QList<QGlyphRun>(); - - int blockNode = p->blockMap().findNode(pos); + int blockNode = p->blockMap().findNode(position()); const QTextBlockData *blockData = p->blockMap().fragment(blockNode); QTextLayout *layout = blockData->layout; + int blockPosition = p->blockMap().position(blockNode); + if (pos < 0) + pos = position() - blockPosition; + if (len < 0) + len = length(); + if (len == 0) + return QList<QGlyphRun>(); + QList<QGlyphRun> ret; for (int i=0; i<layout->lineCount(); ++i) { QTextLine textLine = layout->lineAt(i); diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index 9c5cc13539..c2b46e4d12 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -317,7 +317,7 @@ public: QString text() const; #if !defined(QT_NO_RAWFONT) - QList<QGlyphRun> glyphRuns() const; + QList<QGlyphRun> glyphRuns(int from = -1, int length = -1) const; #endif private: |