Add light weight methods for text measurement.

The intruduced method measureText can be used instead of
doLayout for text measurement purpose.

Bug: 24505153
Change-Id: Ic29bbb347daf18d1f6c13f86970dcdd11dd6a2bd
This commit is contained in:
Keisuke Kuroyanagi
2015-10-13 19:20:09 +09:00
parent d34c46ee7d
commit 84b080abc5
2 changed files with 65 additions and 19 deletions

View File

@@ -93,6 +93,10 @@ public:
void doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
int bidiFlags, const FontStyle &style, const MinikinPaint &paint);
static float measureText(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
int bidiFlags, const FontStyle &style, const MinikinPaint &paint,
const FontCollection* collection, float* advances);
void draw(minikin::Bitmap*, int x0, int y0, float size) const;
// Deprecated. Nont needed. Remove when callers are removed.
@@ -129,12 +133,16 @@ private:
int findFace(FakedFont face, LayoutContext* ctx);
// Lay out a single bidi run
void doLayoutRunCached(const uint16_t* buf, size_t runStart, size_t runLength, size_t bufSize,
bool isRtl, LayoutContext* ctx, size_t dstStart);
// When layout is not null, layout info will be stored in the object.
// When advances is not null, measurement results will be stored in the array.
static float doLayoutRunCached(const uint16_t* buf, size_t runStart, size_t runLength,
size_t bufSize, bool isRtl, LayoutContext* ctx, size_t dstStart,
const FontCollection* collection, Layout* layout, float* advances);
// Lay out a single word
void doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
bool isRtl, LayoutContext* ctx, size_t bufStart);
static float doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
bool isRtl, LayoutContext* ctx, size_t bufStart, const FontCollection* collection,
Layout* layout, float* advances);
// Lay out a single bidi run
void doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t bufSize,

View File

@@ -596,15 +596,37 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu
for (const BidiText::Iter::RunInfo& runInfo : BidiText(buf, start, count, bufSize, bidiFlags)) {
doLayoutRunCached(buf, runInfo.mRunStart, runInfo.mRunLength, bufSize, runInfo.mIsRtl, &ctx,
start);
start, mCollection, this, NULL);
}
ctx.clearHbFonts();
mCollection->purgeFontFamilyHbFontCache();
}
void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
bool isRtl, LayoutContext* ctx, size_t dstStart) {
float Layout::measureText(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
int bidiFlags, const FontStyle &style, const MinikinPaint &paint,
const FontCollection* collection, float* advances) {
AutoMutex _l(gMinikinLock);
LayoutContext ctx;
ctx.style = style;
ctx.paint = paint;
float advance = 0;
for (const BidiText::Iter::RunInfo& runInfo : BidiText(buf, start, count, bufSize, bidiFlags)) {
float* advancesForRun = advances ? advances + (runInfo.mRunStart - start) : advances;
advance += doLayoutRunCached(buf, runInfo.mRunStart, runInfo.mRunLength, bufSize,
runInfo.mIsRtl, &ctx, 0, collection, NULL, advancesForRun);
}
ctx.clearHbFonts();
return advance;
}
float Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
bool isRtl, LayoutContext* ctx, size_t dstStart, const FontCollection* collection,
Layout* layout, float* advances) {
HyphenEdit hyphen = ctx->paint.hyphenEdit;
float advance = 0;
if (!isRtl) {
// left to right
size_t wordstart =
@@ -615,8 +637,9 @@ void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count,
// Only apply hyphen to the last word in the string.
ctx->paint.hyphenEdit = wordend >= start + count ? hyphen : HyphenEdit();
size_t wordcount = std::min(start + count, wordend) - iter;
doLayoutWord(buf + wordstart, iter - wordstart, wordcount, wordend - wordstart,
isRtl, ctx, iter - dstStart);
advance += doLayoutWord(buf + wordstart, iter - wordstart, wordcount,
wordend - wordstart, isRtl, ctx, iter - dstStart, collection, layout,
advances ? advances + (iter - start) : advances);
wordstart = wordend;
}
} else {
@@ -629,25 +652,40 @@ void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count,
// Only apply hyphen to the last (leftmost) word in the string.
ctx->paint.hyphenEdit = iter == end ? hyphen : HyphenEdit();
size_t bufStart = std::max(start, wordstart);
doLayoutWord(buf + wordstart, bufStart - wordstart, iter - bufStart,
wordend - wordstart, isRtl, ctx, bufStart - dstStart);
advance += doLayoutWord(buf + wordstart, bufStart - wordstart, iter - bufStart,
wordend - wordstart, isRtl, ctx, bufStart - dstStart, collection, layout,
advances ? advances + (bufStart - start) : advances);
wordend = wordstart;
}
}
return advance;
}
void Layout::doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
bool isRtl, LayoutContext* ctx, size_t bufStart) {
float Layout::doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
bool isRtl, LayoutContext* ctx, size_t bufStart, const FontCollection* collection,
Layout* layout, float* advances) {
LayoutCache& cache = LayoutEngine::getInstance().layoutCache;
LayoutCacheKey key(mCollection, ctx->paint, ctx->style, buf, start, count, bufSize, isRtl);
LayoutCacheKey key(collection, ctx->paint, ctx->style, buf, start, count, bufSize, isRtl);
bool skipCache = ctx->paint.skipCache();
if (skipCache) {
Layout layout;
key.doLayout(&layout, ctx, mCollection);
appendLayout(&layout, bufStart);
Layout layoutForWord;
key.doLayout(&layoutForWord, ctx, collection);
if (layout) {
layout->appendLayout(&layoutForWord, bufStart);
}
if (advances) {
layoutForWord.getAdvances(advances);
}
return layoutForWord.getAdvance();
} else {
Layout* layout = cache.get(key, ctx, mCollection);
appendLayout(layout, bufStart);
Layout* layoutForWord = cache.get(key, ctx, collection);
if (layout) {
layout->appendLayout(layoutForWord, bufStart);
}
if (advances) {
layoutForWord->getAdvances(advances);
}
return layoutForWord->getAdvance();
}
}