summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-08-25 10:11:49 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-08-25 12:48:52 +0200
commit04d0a9626ce61b2e05a40f9562c2bcf12e234639 (patch)
treef1643f829aedc9ac51fcc260f7df2639dfe08360 /src/gui/text
parent17f3451daa286b88a52f18c802d7b158dfb653b2 (diff)
parentbdc417b3828737334723eae23097c85f70c23a33 (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.cpp3
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qfontmetrics.cpp30
-rw-r--r--src/gui/text/qfontmetrics.h4
-rw-r--r--src/gui/text/qglyphrun.cpp45
-rw-r--r--src/gui/text/qglyphrun.h3
-rw-r--r--src/gui/text/qglyphrun_p.h2
-rw-r--r--src/gui/text/qtextcontrol.cpp24
-rw-r--r--src/gui/text/qtextcontrol_p.h3
-rw-r--r--src/gui/text/qtextengine.cpp44
-rw-r--r--src/gui/text/qtextlayout.cpp63
-rw-r--r--src/gui/text/qtextobject.cpp17
-rw-r--r--src/gui/text/qtextobject.h2
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: