summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeisuke Kuroyanagi <ksk@google.com>2015-06-10 17:45:46 +0900
committerKeisuke Kuroyanagi <ksk@google.com>2015-06-10 17:45:46 +0900
commit4ea1cc82b0e8170d6ab6a7e9ee274c81315cd59e (patch)
tree2e576acd8cf85ade2af5b0785cd4495877ff4a9d
parent73fa6dfd6366c6ac04d6a25cdcc0721f5b3e7fbb (diff)
downloadandroid_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.cpp22
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;