diff options
author | Raph Levien <raph@google.com> | 2014-06-04 15:20:37 -0700 |
---|---|---|
committer | Raph Levien <raph@google.com> | 2014-06-05 12:23:21 -0700 |
commit | 3f1ea5da2ee12b0d95c17c56928c3e553d4eeda0 (patch) | |
tree | c9db6cf3111c20c2372e8a44b789d745bd6040bd | |
parent | 3164d1a77eecf3185347a44342131f4275de824f (diff) | |
download | android_frameworks_minikin-3f1ea5da2ee12b0d95c17c56928c3e553d4eeda0.tar.gz android_frameworks_minikin-3f1ea5da2ee12b0d95c17c56928c3e553d4eeda0.tar.bz2 android_frameworks_minikin-3f1ea5da2ee12b0d95c17c56928c3e553d4eeda0.zip |
Support for context in API
This patch completes support for adding context for complex script
layout, for example when a string with joins straddles two spans.
Part of the fix for 15431028: "Properly support context for joining
scripts (Minikin)"
Change-Id: I65b0833be92eb477aa531bbef0ac6eddeb3a962a
-rw-r--r-- | include/minikin/Layout.h | 2 | ||||
-rw-r--r-- | libs/minikin/Layout.cpp | 35 |
2 files changed, 15 insertions, 22 deletions
diff --git a/include/minikin/Layout.h b/include/minikin/Layout.h index a1ef0c1..91b8ef6 100644 --- a/include/minikin/Layout.h +++ b/include/minikin/Layout.h @@ -105,7 +105,7 @@ private: // Lay out a single bidi run void doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize, - bool isRtl, LayoutContext* ctx); + bool isRtl, LayoutContext* ctx, size_t dstStart); // Lay out a single word void doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize, diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp index c66559a..3cab673 100644 --- a/libs/minikin/Layout.cpp +++ b/libs/minikin/Layout.cpp @@ -485,17 +485,6 @@ void Layout::doLayout(const uint16_t* buf, size_t nchars) { doLayout(buf, 0, nchars, nchars, mCssString); } -// TODO: use some standard implementation -template<typename T> -static T mymin(const T& a, const T& b) { - return a < b ? a : b; -} - -template<typename T> -static T mymax(const T& a, const T& b) { - return a > b ? a : b; -} - static void clearHbFonts(LayoutContext* ctx) { for (size_t i = 0; i < ctx->hbFonts.size(); i++) { hb_font_destroy(ctx->hbFonts[i]); @@ -503,7 +492,6 @@ static void clearHbFonts(LayoutContext* ctx) { ctx->hbFonts.clear(); } -// TODO: API should probably take context void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize, const string& css) { AutoMutex _l(gMinikinLock); @@ -560,9 +548,14 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu // skip the invalid run continue; } - isRtl = (runDir == UBIDI_RTL); - // TODO: min/max with context - doLayoutRunCached(buf, startRun, lengthRun, bufSize, isRtl, &ctx); + int32_t endRun = std::min(startRun + lengthRun, int32_t(start + count)); + startRun = std::max(startRun, int32_t(start)); + lengthRun = endRun - startRun; + if (lengthRun > 0) { + isRtl = (runDir == UBIDI_RTL); + doLayoutRunCached(buf, startRun, lengthRun, bufSize, isRtl, &ctx, + start); + } } } } else { @@ -574,22 +567,22 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu } } if (doSingleRun) { - doLayoutRunCached(buf, start, count, bufSize, isRtl, &ctx); + doLayoutRunCached(buf, start, count, bufSize, isRtl, &ctx, start); } clearHbFonts(&ctx); } void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize, - bool isRtl, LayoutContext* ctx) { + bool isRtl, LayoutContext* ctx, size_t dstStart) { if (!isRtl) { // left to right size_t wordstart = start == bufSize ? start : getPrevWordBreak(buf, start + 1); size_t wordend; for (size_t iter = start; iter < start + count; iter = wordend) { wordend = getNextWordBreak(buf, iter, bufSize); - size_t wordcount = mymin(start + count, wordend) - iter; + size_t wordcount = std::min(start + count, wordend) - iter; doLayoutWord(buf + wordstart, iter - wordstart, wordcount, wordend - wordstart, - isRtl, ctx, iter); + isRtl, ctx, iter - dstStart); wordstart = wordend; } } else { @@ -599,9 +592,9 @@ void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t wordend = end == 0 ? 0 : getNextWordBreak(buf, end - 1, bufSize); for (size_t iter = end; iter > start; iter = wordstart) { wordstart = getPrevWordBreak(buf, iter); - size_t bufStart = mymax(start, wordstart); + size_t bufStart = std::max(start, wordstart); doLayoutWord(buf + wordstart, bufStart - wordstart, iter - bufStart, - wordend - wordstart, isRtl, ctx, bufStart); + wordend - wordstart, isRtl, ctx, bufStart - dstStart); wordend = wordstart; } } |