Decrease code duplication by reusing QTextEngine::findItem()

Use the findItem()'s optimized binary search impl instead of a generic one.
Also drop the "already shaped item" case since setBoundary() is only
called from itemize(), where the items are not shaped yet.

Change-Id: Ifbecdc41b2e3cb7791a7896fbb0cbea439ca0706
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Konstantin Ritt 2014-05-18 03:43:04 +03:00
parent cdbd3c412c
commit 0412ad3513
2 changed files with 6 additions and 54 deletions

View File

@ -2749,64 +2749,17 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
return layoutData->string.mid(from, to - from);
}
namespace {
struct QScriptItemComparator {
bool operator()(int p, const QScriptItem &b) { return p < b.position; }
#if defined(Q_CC_MSVC) && _MSC_VER < 1600
//The STL implementation of MSVC 2008 requires the definition
bool operator()(const QScriptItem &a, int p) { return a.position < p; }
bool operator()(const QScriptItem &a, const QScriptItem &b) { return a.position < b.position; }
#endif
};
}
void QTextEngine::setBoundary(int strPos) const
{
if (strPos <= 0 || strPos >= layoutData->string.length())
const int item = findItem(strPos);
if (item < 0)
return;
const QScriptItem* it = std::upper_bound(layoutData->items.constBegin(), layoutData->items.constEnd(),
strPos, QScriptItemComparator());
Q_ASSERT(it > layoutData->items.constBegin());
--it;
if (it->position == strPos) {
// already a split at the requested position
return;
QScriptItem newItem = layoutData->items.at(item);
if (newItem.position != strPos) {
newItem.position = strPos;
layoutData->items.insert(item + 1, newItem);
}
splitItem(it - layoutData->items.constBegin(), strPos - it->position);
}
void QTextEngine::splitItem(int item, int pos) const
{
if (pos <= 0)
return;
layoutData->items.insert(item + 1, layoutData->items[item]);
QScriptItem &oldItem = layoutData->items[item];
QScriptItem &newItem = layoutData->items[item+1];
newItem.position += pos;
if (oldItem.num_glyphs) {
// already shaped, break glyphs aswell
int breakGlyph = logClusters(&oldItem)[pos];
newItem.num_glyphs = oldItem.num_glyphs - breakGlyph;
oldItem.num_glyphs = breakGlyph;
newItem.glyph_data_offset = oldItem.glyph_data_offset + breakGlyph;
for (int i = 0; i < newItem.num_glyphs; i++)
logClusters(&newItem)[i] -= breakGlyph;
QFixed w = 0;
const QGlyphLayout g = shapedGlyphs(&oldItem);
for(int j = 0; j < breakGlyph; ++j)
w += g.advances[j] * !g.attributes[j].dontPrint;
newItem.width = oldItem.width - w;
oldItem.width = w;
}
// qDebug("split at position %d itempos=%d", pos, item);
}
QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const

View File

@ -641,7 +641,6 @@ private:
int shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const;
#endif
int shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const;
void splitItem(int item, int pos) const;
int endOfLine(int lineNum);
int beginningOfLine(int lineNum);