auto import from //branches/cupcake_rel/...@140373
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 95acf9d..23e740d 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -16,6 +16,8 @@
package android.text;
+import android.emoji.EmojiFactory;
+import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
@@ -36,6 +38,20 @@
* For text that will not change, use a {@link StaticLayout}.
*/
public abstract class Layout {
+ /* package */ static final EmojiFactory EMOJI_FACTORY =
+ EmojiFactory.newAvailableInstance();
+ /* package */ static final int MIN_EMOJI, MAX_EMOJI;
+
+ static {
+ if (EMOJI_FACTORY != null) {
+ MIN_EMOJI = EMOJI_FACTORY.getMinimumAndroidPua();
+ MAX_EMOJI = EMOJI_FACTORY.getMaximumAndroidPua();
+ } else {
+ MIN_EMOJI = -1;
+ MAX_EMOJI = -1;
+ }
+ };
+
/**
* Return how wide a layout would be necessary to display the
* specified text with one line per paragraph.
@@ -445,7 +461,9 @@
public abstract int getParagraphDirection(int line);
/**
- * Returns whether the specified line contains one or more tabs.
+ * Returns whether the specified line contains one or more
+ * characters that need to be handled specially, like tabs
+ * or emoji.
*/
public abstract boolean getLineContainsTab(int line);
@@ -1352,6 +1370,26 @@
h = dir * nextTab(text, start, end, h * dir, parspans);
segstart = j + 1;
+ } else if (hasTabs && buf[j] >= 0xD800 && buf[j] <= 0xDFFF && j + 1 < there) {
+ int emoji = Character.codePointAt(buf, j);
+
+ if (emoji >= MIN_EMOJI && emoji <= MAX_EMOJI) {
+ Bitmap bm = EMOJI_FACTORY.
+ getBitmapFromAndroidPua(emoji);
+
+ if (bm != null) {
+ h += Styled.drawText(canvas, text,
+ start + segstart, start + j,
+ dir, (i & 1) != 0, x + h,
+ top, y, bottom, paint, workPaint,
+ start + j != end);
+
+ canvas.drawBitmap(bm, x + h, y - bm.getHeight(), paint);
+ h += bm.getWidth();
+ j++;
+ segstart = j + 1;
+ }
+ }
}
}
@@ -1394,7 +1432,22 @@
int segstart = here;
for (int j = hasTabs ? here : there; j <= there; j++) {
- if (j == there || buf[j] == '\t') {
+ int codept = 0;
+ Bitmap bm = null;
+
+ if (hasTabs && j < there) {
+ codept = buf[j];
+ }
+
+ if (codept >= 0xD800 && codept <= 0xDFFF && j + 1 < there) {
+ codept = Character.codePointAt(buf, j);
+
+ if (codept >= MIN_EMOJI && codept <= MAX_EMOJI) {
+ bm = EMOJI_FACTORY.getBitmapFromAndroidPua(codept);
+ }
+ }
+
+ if (j == there || codept == '\t' || bm != null) {
float segw;
if (offset < start + j ||
@@ -1449,6 +1502,16 @@
h = dir * nextTab(text, start, end, h * dir, tabs);
}
+ if (bm != null) {
+ if (dir == DIR_RIGHT_TO_LEFT) {
+ h -= bm.getWidth();
+ } else {
+ h += bm.getWidth();
+ }
+
+ j++;
+ }
+
segstart = j + 1;
}
}
@@ -1488,7 +1551,22 @@
}
for (int i = hasTabs ? 0 : len; i <= len; i++) {
- if (i == len || buf[i] == '\t') {
+ int codept = 0;
+ Bitmap bm = null;
+
+ if (hasTabs && i < len) {
+ codept = buf[i];
+ }
+
+ if (codept >= 0xD800 && codept <= 0xDFFF && i < len) {
+ codept = Character.codePointAt(buf, i);
+
+ if (codept >= MIN_EMOJI && codept <= MAX_EMOJI) {
+ bm = EMOJI_FACTORY.getBitmapFromAndroidPua(codept);
+ }
+ }
+
+ if (i == len || codept == '\t' || bm != null) {
workPaint.baselineShift = 0;
h += Styled.measureText(paint, workPaint, text,
@@ -1505,8 +1583,14 @@
}
}
- if (i != len)
- h = nextTab(text, start, end, h, tabs);
+ if (i != len) {
+ if (bm == null) {
+ h = nextTab(text, start, end, h, tabs);
+ } else {
+ h += bm.getWidth();
+ i++;
+ }
+ }
if (fm != null) {
if (fm.ascent < ab) {
@@ -1522,6 +1606,17 @@
if (fm.bottom > bot) {
bot = fm.bottom;
}
+
+ if (bm != null) {
+ int ht = -bm.getHeight();
+
+ if (ht < ab) {
+ ab = ht;
+ }
+ if (ht < top) {
+ top = ht;
+ }
+ }
}
here = i + 1;