Fix bug which caused repeated characters in a QML Text
[profile/ivi/qtbase.git] / src / gui / text / qtextlayout.cpp
index 9e067d7..f9bfcbf 100644 (file)
@@ -2151,7 +2151,7 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
         }
 
         int relativeFrom = qMax(iterator.itemStart, from) - si.position;
-        int relativeTo = qMin(iterator.itemEnd, from + length - 1) - si.position;
+        int relativeTo = qMin(iterator.itemEnd - 1, from + length - 1) - si.position;
 
         unsigned short *logClusters = eng->logClusters(&si);
         int glyphsStart = logClusters[relativeFrom];
@@ -2170,7 +2170,7 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
                 pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(),
                                glyphLayout.advances_y[i].toReal());
             }
-        } else if (relativeTo != (iterator.itemEnd - si.position) && rtl) {
+        } else if (relativeTo != (iterator.itemEnd - si.position - 1) && rtl) {
             for (int i=glyphLayout.numGlyphs - 1; i>glyphsEnd; --i) {
                 QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
                 pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(),
@@ -2282,10 +2282,20 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
             glyphIndexes.setRawFont(font);
 
             QPair<QFontEngine *, int> key(fontEngine, int(flags));
-            if (!glyphsHash.contains(key))
+            if (!glyphsHash.contains(key)) {
                 glyphsHash.insert(key, glyphIndexes);
-            else
-                glyphsHash[key] += glyphIndexes;
+            } else {
+                QGlyphRun &glyphRun = glyphsHash[key];
+
+                QVector<quint32> indexes = glyphRun.glyphIndexes();
+                QVector<QPointF> positions = glyphRun.positions();
+
+                indexes += glyphIndexes.glyphIndexes();
+                positions += glyphIndexes.positions();
+
+                glyphRun.setGlyphIndexes(indexes);
+                glyphRun.setPositions(positions);
+            }
         }
     }
 
@@ -2609,8 +2619,8 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
     } else {
         bool rtl = eng->isRightToLeft();
         bool visual = eng->visualCursorMovement();
+        int end = qMin(lineEnd, si->position + l) - si->position;
         if (reverse) {
-            int end = qMin(lineEnd, si->position + l) - si->position;
             int glyph_end = end == l ? si->num_glyphs : logClusters[end];
             int glyph_start = glyph_pos;
             if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem)))
@@ -2626,7 +2636,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
             for (int i = glyph_start; i <= glyph_end; i++)
                 x += glyphs.effectiveAdvance(i);
         }
-        x += eng->offsetInLigature(si, pos, line.length, glyph_pos);
+        x += eng->offsetInLigature(si, pos, end, glyph_pos);
     }
 
     *cursorPos = pos + si->position;
@@ -2741,6 +2751,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
             }
 
             int glyph_pos = -1;
+            QFixed edge;
             // has to be inside run
             if (cpos == QTextLine::CursorOnCharacter) {
                 if (si.analysis.bidiLevel % 2) {
@@ -2751,6 +2762,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
                             if (pos < x)
                                 break;
                             glyph_pos = gs;
+                            edge = pos;
                             break;
                         }
                         pos -= glyphs.effectiveAdvance(gs);
@@ -2763,6 +2775,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
                             if (pos > x)
                                 break;
                             glyph_pos = gs;
+                            edge = pos;
                         }
                         pos += glyphs.effectiveAdvance(gs);
                         ++gs;
@@ -2776,6 +2789,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
                         while (gs <= ge) {
                             if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
                                 glyph_pos = gs;
+                                edge = pos;
                                 dist = qAbs(x-pos);
                             }
                             pos -= glyphs.effectiveAdvance(gs);
@@ -2785,6 +2799,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
                         while (ge >= gs) {
                             if (glyphs.attributes[ge].clusterStart && qAbs(x-pos) < dist) {
                                 glyph_pos = ge;
+                                edge = pos;
                                 dist = qAbs(x-pos);
                             }
                             pos += glyphs.effectiveAdvance(ge);
@@ -2796,6 +2811,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
                         while (gs <= ge) {
                             if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
                                 glyph_pos = gs;
+                                edge = pos;
                                 dist = qAbs(x-pos);
                             }
                             pos += glyphs.effectiveAdvance(gs);
@@ -2807,6 +2823,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
                             pos += glyphs.effectiveAdvance(gs);
                             if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
                                 glyph_pos = gs;
+                                edge = pos;
                                 dist = qAbs(x-pos);
                             }
                             ++gs;
@@ -2823,16 +2840,13 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
                         if (rtl && nchars > 0)
                             return insertionPoints[lastLine ? nchars : nchars - 1];
                     }
-                    return si.position + end;
+                    return eng->positionInLigature(&si, end, x, pos, -1,
+                                                   cpos == QTextLine::CursorOnCharacter);
                 }
             }
             Q_ASSERT(glyph_pos != -1);
-            int j;
-            for (j = 0; j < eng->length(item); ++j)
-                if (logClusters[j] == glyph_pos)
-                    break;
-//             qDebug("at pos %d (in run: %d)", si.position + j, j);
-            return si.position + j;
+            return eng->positionInLigature(&si, end, x, edge, glyph_pos,
+                                           cpos == QTextLine::CursorOnCharacter);
         }
     }
     // right of last item