summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2015-01-29 16:28:37 -0800
committerRaph Levien <raph@google.com>2015-03-12 14:37:55 -0700
commitd692d6a9791145d41d7778cdf6b40b20c2be8cb4 (patch)
tree4a14446b1b09255c3e9dc8453c93c9eb7ed72e4d /libs
parent0bbff3a96d3836079371cdd4398c21afad3c5234 (diff)
downloadandroid_frameworks_minikin-d692d6a9791145d41d7778cdf6b40b20c2be8cb4.tar.gz
android_frameworks_minikin-d692d6a9791145d41d7778cdf6b40b20c2be8cb4.tar.bz2
android_frameworks_minikin-d692d6a9791145d41d7778cdf6b40b20c2be8cb4.zip
HyphenEdit in support of hyphenation
Adds a "HyphenEdit" field to the Minikin Paint object, which represents an edit to the text to add a hyphen (and, in the future, other edits to support nonstandard hyphenation). Change-Id: Ib4ee690b0fe2137e1d1e2c9251e5526b274ec3a7
Diffstat (limited to 'libs')
-rw-r--r--libs/minikin/Layout.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp
index 375f61d..8e5e546 100644
--- a/libs/minikin/Layout.cpp
+++ b/libs/minikin/Layout.cpp
@@ -594,12 +594,15 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu
void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
bool isRtl, LayoutContext* ctx, size_t dstStart) {
+ HyphenEdit hyphen = ctx->paint.hyphenEdit;
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);
+ // 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);
@@ -612,6 +615,8 @@ 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);
+ // 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);
@@ -729,6 +734,12 @@ void Layout::doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t
hb_buffer_set_language(buffer, hb_language_from_string(lang.c_str(), -1));
}
hb_buffer_add_utf16(buffer, buf, bufSize, srunstart + start, srunend - srunstart);
+ if (ctx->paint.hyphenEdit.hasHyphen() && srunend > srunstart) {
+ // TODO: check whether this is really the desired semantics. It could have the
+ // effect of assigning the hyphen width to a nonspacing mark
+ unsigned int lastCluster = srunend - 1;
+ hb_buffer_add(buffer, 0x2010, lastCluster);
+ }
hb_shape(hbFont, buffer, features.empty() ? NULL : &features[0], features.size());
unsigned int numGlyphs;
hb_glyph_info_t* info = hb_buffer_get_glyph_infos(buffer, &numGlyphs);
@@ -763,7 +774,12 @@ void Layout::doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t
ctx->paint.font->GetBounds(&glyphBounds, glyph_ix, ctx->paint);
glyphBounds.offset(x + xoff, y + yoff);
mBounds.join(glyphBounds);
- mAdvances[info[i].cluster - start] += xAdvance;
+ if (info[i].cluster - start < count) {
+ mAdvances[info[i].cluster - start] += xAdvance;
+ } else {
+ ALOGE("cluster %d (start %d) out of bounds of count %d",
+ info[i].cluster - start, start, count);
+ }
x += xAdvance;
}
if (numGlyphs)