diff options
author | Keisuke Kuroyanagi <ksk@google.com> | 2015-06-10 17:45:46 +0900 |
---|---|---|
committer | Keisuke Kuroyanagi <ksk@google.com> | 2015-06-10 17:45:46 +0900 |
commit | 4ea1cc82b0e8170d6ab6a7e9ee274c81315cd59e (patch) | |
tree | 2e576acd8cf85ade2af5b0785cd4495877ff4a9d | |
parent | 73fa6dfd6366c6ac04d6a25cdcc0721f5b3e7fbb (diff) | |
download | android_frameworks_minikin-4ea1cc82b0e8170d6ab6a7e9ee274c81315cd59e.tar.gz android_frameworks_minikin-4ea1cc82b0e8170d6ab6a7e9ee274c81315cd59e.tar.bz2 android_frameworks_minikin-4ea1cc82b0e8170d6ab6a7e9ee274c81315cd59e.zip |
Fix: getOffsetForAdvance can return worng offset.
searchStart was passed to getRunAdvance, but it can be
different from the start that has been used to initialize
Layout object. As a result, wrong index could be used in
getRunAdvance.
Bug: 21744454
Change-Id: Ibe83cc50ed6f0da2a1532318bc224502be350699
-rw-r--r-- | libs/minikin/Measurement.cpp | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/libs/minikin/Measurement.cpp b/libs/minikin/Measurement.cpp index 98d2c01..0b68ac5 100644 --- a/libs/minikin/Measurement.cpp +++ b/libs/minikin/Measurement.cpp @@ -28,26 +28,26 @@ namespace android { // These could be considered helper methods of layout, but need only be loosely coupled, so // are separate. -float getRunAdvance(Layout& layout, const uint16_t* buf, size_t start, size_t count, - size_t offset) { +static float getRunAdvance(Layout& layout, const uint16_t* buf, size_t layoutStart, size_t start, + size_t count, size_t offset) { float advance = 0.0f; size_t lastCluster = start; float clusterWidth = 0.0f; for (size_t i = start; i < offset; i++) { - float charAdvance = layout.getCharAdvance(i - start); + float charAdvance = layout.getCharAdvance(i - layoutStart); if (charAdvance != 0.0f) { advance += charAdvance; lastCluster = i; clusterWidth = charAdvance; } } - if (offset < start + count && layout.getCharAdvance(offset - start) == 0.0f) { + if (offset < start + count && layout.getCharAdvance(offset - layoutStart) == 0.0f) { // In the middle of a cluster, distribute width of cluster so that each grapheme cluster // gets an equal share. // TODO: get caret information out of font when that's available size_t nextCluster; for (nextCluster = offset + 1; nextCluster < start + count; nextCluster++) { - if (layout.getCharAdvance(nextCluster - start) != 0.0f) break; + if (layout.getCharAdvance(nextCluster - layoutStart) != 0.0f) break; } int numGraphemeClusters = 0; int numGraphemeClustersAfter = 0; @@ -67,6 +67,11 @@ float getRunAdvance(Layout& layout, const uint16_t* buf, size_t start, size_t co return advance; } +float getRunAdvance(Layout& layout, const uint16_t* buf, size_t start, size_t count, + size_t offset) { + return getRunAdvance(layout, buf, start, start, count, offset); +} + /** * Essentially the inverse of getRunAdvance. Compute the value of offset for which the * measured caret comes closest to the provided advance param, and which is on a grapheme @@ -98,9 +103,10 @@ size_t getOffsetForAdvance(Layout& layout, const uint16_t* buf, size_t start, si float bestDist = FLT_MAX; for (size_t i = searchStart; i <= start + count; i++) { if (GraphemeBreak::isGraphemeBreak(buf, start, count, i)) { - // "getRunAdvance(layout, buf, start, count, bufSize, i) - advance" but more efficient - float delta = getRunAdvance(layout, buf, searchStart, count, i) + xSearchStart - - advance; + // "getRunAdvance(layout, buf, start, count, i) - advance" but more efficient + float delta = getRunAdvance(layout, buf, start, searchStart, count - searchStart, i) + + + xSearchStart - advance; if (std::abs(delta) < bestDist) { bestDist = std::abs(delta); best = i; |