summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeisuke Kuroyanagi <ksk@google.com>2016-02-18 11:35:42 -0800
committerKeisuke Kuroyanagi <ksk@google.com>2016-02-18 11:46:48 -0800
commitea408fc18e8e78d984ebdf63703da668a15720de (patch)
tree91c7967daa762f1ca26cc17633b73d7526260108
parentaa736d00548da691e75a09a70deb886e1f68b060 (diff)
downloadandroid_frameworks_minikin-ea408fc18e8e78d984ebdf63703da668a15720de.tar.gz
android_frameworks_minikin-ea408fc18e8e78d984ebdf63703da668a15720de.tar.bz2
android_frameworks_minikin-ea408fc18e8e78d984ebdf63703da668a15720de.zip
Optimize: Use measureText instead of doLayout.
With this CL, measureText is used for getRunAdvance, getOffsetForAdvance and line breaking. Bug: 24505153 Change-Id: Ib699f6b1391b46537736fc274cdb41686586b550
-rw-r--r--include/minikin/Measurement.h5
-rw-r--r--libs/minikin/LineBreaker.cpp24
-rw-r--r--libs/minikin/Measurement.cpp20
3 files changed, 25 insertions, 24 deletions
diff --git a/include/minikin/Measurement.h b/include/minikin/Measurement.h
index fc47fa3..7bcab66 100644
--- a/include/minikin/Measurement.h
+++ b/include/minikin/Measurement.h
@@ -21,9 +21,10 @@
namespace android {
-float getRunAdvance(Layout& layout, const uint16_t* buf, size_t start, size_t count, size_t offset);
+float getRunAdvance(const float* advances, const uint16_t* buf, size_t start, size_t count,
+ size_t offset);
-size_t getOffsetForAdvance(Layout& layout, const uint16_t* buf, size_t start, size_t count,
+size_t getOffsetForAdvance(const float* advances, const uint16_t* buf, size_t start, size_t count,
float advance);
}
diff --git a/libs/minikin/LineBreaker.cpp b/libs/minikin/LineBreaker.cpp
index 22c3954..9c4ff6f 100644
--- a/libs/minikin/LineBreaker.cpp
+++ b/libs/minikin/LineBreaker.cpp
@@ -122,17 +122,13 @@ static bool isLineBreakingHyphen(uint16_t c) {
// to addCandidate.
float LineBreaker::addStyleRun(MinikinPaint* paint, const FontCollection* typeface,
FontStyle style, size_t start, size_t end, bool isRtl) {
- Layout layout; // performance TODO: move layout to self object to reduce allocation cost?
float width = 0.0f;
int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
float hyphenPenalty = 0.0;
if (paint != nullptr) {
- layout.setFontCollection(typeface);
- layout.doLayout(mTextBuf.data(), start, end - start, mTextBuf.size(), bidiFlags, style,
- *paint);
- layout.getAdvances(mCharWidths.data() + start);
- width = layout.getAdvance();
+ width = Layout::measureText(mTextBuf.data(), start, end - start, mTextBuf.size(), bidiFlags,
+ style, *paint, typeface, mCharWidths.data() + start);
// a heuristic that seems to perform well
hyphenPenalty = 0.5 * paint->size * paint->scaleX * mLineWidths.getLineWidth(0);
@@ -192,13 +188,17 @@ float LineBreaker::addStyleRun(MinikinPaint* paint, const FontCollection* typefa
uint8_t hyph = mHyphBuf[j - wordStart];
if (hyph) {
paint->hyphenEdit = hyph;
- layout.doLayout(mTextBuf.data(), lastBreak, j - lastBreak,
- mTextBuf.size(), bidiFlags, style, *paint);
- ParaWidth hyphPostBreak = lastBreakWidth + layout.getAdvance();
+
+ const float firstPartWidth = Layout::measureText(mTextBuf.data(),
+ lastBreak, j - lastBreak, mTextBuf.size(), bidiFlags, style,
+ *paint, typeface, nullptr);
+ ParaWidth hyphPostBreak = lastBreakWidth + firstPartWidth;
paint->hyphenEdit = 0;
- layout.doLayout(mTextBuf.data(), j, afterWord - j,
- mTextBuf.size(), bidiFlags, style, *paint);
- ParaWidth hyphPreBreak = postBreak - layout.getAdvance();
+
+ const float secondPartWith = Layout::measureText(mTextBuf.data(), j,
+ afterWord - j, mTextBuf.size(), bidiFlags, style, *paint,
+ typeface, nullptr);
+ ParaWidth hyphPreBreak = postBreak - secondPartWith;
addWordBreak(j, hyphPreBreak, hyphPostBreak, hyphenPenalty, hyph);
}
}
diff --git a/libs/minikin/Measurement.cpp b/libs/minikin/Measurement.cpp
index 0b68ac5..1ba6678 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.
-static float getRunAdvance(Layout& layout, const uint16_t* buf, size_t layoutStart, size_t start,
- size_t count, size_t offset) {
+static float getRunAdvance(const float* advances, 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 - layoutStart);
+ float charAdvance = advances[i - layoutStart];
if (charAdvance != 0.0f) {
advance += charAdvance;
lastCluster = i;
clusterWidth = charAdvance;
}
}
- if (offset < start + count && layout.getCharAdvance(offset - layoutStart) == 0.0f) {
+ if (offset < start + count && advances[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 - layoutStart) != 0.0f) break;
+ if (advances[nextCluster - layoutStart] != 0.0f) break;
}
int numGraphemeClusters = 0;
int numGraphemeClustersAfter = 0;
@@ -67,9 +67,9 @@ static float getRunAdvance(Layout& layout, const uint16_t* buf, size_t layoutSta
return advance;
}
-float getRunAdvance(Layout& layout, const uint16_t* buf, size_t start, size_t count,
+float getRunAdvance(const float* advances, const uint16_t* buf, size_t start, size_t count,
size_t offset) {
- return getRunAdvance(layout, buf, start, start, count, offset);
+ return getRunAdvance(advances, buf, start, start, count, offset);
}
/**
@@ -80,7 +80,7 @@ float getRunAdvance(Layout& layout, const uint16_t* buf, size_t start, size_t co
* The actual implementation fast-forwards through clusters to get "close", then does a finer-grain
* search within the cluster and grapheme breaks.
*/
-size_t getOffsetForAdvance(Layout& layout, const uint16_t* buf, size_t start, size_t count,
+size_t getOffsetForAdvance(const float* advances, const uint16_t* buf, size_t start, size_t count,
float advance) {
float x = 0.0f, xLastClusterStart = 0.0f, xSearchStart = 0.0f;
size_t lastClusterStart = start, searchStart = start;
@@ -89,7 +89,7 @@ size_t getOffsetForAdvance(Layout& layout, const uint16_t* buf, size_t start, si
searchStart = lastClusterStart;
xSearchStart = xLastClusterStart;
}
- float width = layout.getCharAdvance(i - start);
+ float width = advances[i - start];
if (width != 0.0f) {
lastClusterStart = i;
xLastClusterStart = x;
@@ -104,7 +104,7 @@ size_t getOffsetForAdvance(Layout& layout, const uint16_t* buf, size_t start, si
for (size_t i = searchStart; i <= start + count; i++) {
if (GraphemeBreak::isGraphemeBreak(buf, start, count, i)) {
// "getRunAdvance(layout, buf, start, count, i) - advance" but more efficient
- float delta = getRunAdvance(layout, buf, start, searchStart, count - searchStart, i)
+ float delta = getRunAdvance(advances, buf, start, searchStart, count - searchStart, i)
+ xSearchStart - advance;
if (std::abs(delta) < bestDist) {