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:
parent
cdbd3c412c
commit
0412ad3513
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user