From f49490a13b664eb00207b2d3d6354071ae81f161 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Fri, 10 Dec 2010 16:07:25 +0100 Subject: Make sure num_glyphs pass to HarfBuzz is large enough (Backport from master) Currently we only pass the num_glyphs for the run to HB_ShapeItem, but it can be less then the string length for this run because of Unicode surrogates. Thus, we need to pass at least the length of that run as num_glyphs to HB (given that we have enough space allocated because for the entire string), if that's still not enough, we will do ensureSpace again according to the num_glyphs returned by HB and move remaining glyphs backwards. Task-number: QTBUG-15679 Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 5 ++++- tests/auto/qtextlayout/tst_qtextlayout.cpp | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index b511b5a..4378c62 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1233,6 +1233,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const shaper_item.num_glyphs -= itemBoundaries[k + 1]; } shaper_item.initialGlyphCount = shaper_item.num_glyphs; + if (shaper_item.num_glyphs < shaper_item.item.length) + shaper_item.num_glyphs = shaper_item.item.length; QFontEngine *actualFontEngine = font; uint engineIdx = 0; @@ -1257,7 +1259,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const } const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos); - moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); + if (shaper_item.num_glyphs > shaper_item.item.length) + moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); shaper_item.glyphs = g.glyphs; shaper_item.attributes = g.attributes; diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp index 2d15566..85e6616 100644 --- a/tests/auto/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp @@ -125,6 +125,7 @@ private slots: void textWidthVsWIdth(); void textWidthWithStackedTextEngine(); void textWidthWithLineSeparator(); + void textWithSurrogates_qtbug15679(); private: QFont testFont; @@ -1416,5 +1417,24 @@ void tst_QTextLayout::textWidthWithLineSeparator() QCOMPARE(line1.naturalTextWidth(), line2.naturalTextWidth()); } +void tst_QTextLayout::textWithSurrogates_qtbug15679() +{ + QString str = QString::fromUtf8("🀀a🀀"); + QTextLayout layout(str); + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + qreal x[6]; + for (int i = 0; i < 6; i++) + x[i] = line.cursorToX(i); + + // If the first and third character are using the same + // font, they must have the same advance (since they + // are surrogate pairs, we need to add two for each + // character) + QCOMPARE(x[2] - x[0], x[5] - x[3]); +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" -- cgit v0.12