Remove EmojiFactory and its mentions from frameworks.
Bug: 18134313 Bug: 20158206 Change-Id: If46cdbd9d558e6592280b2b95f00b87d04de70a2
This commit is contained in:
@@ -1,289 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.emoji;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A class for the factories which produce Emoji (pictgram) images.
|
||||
* This is intended to be used by IME, Email app, etc.
|
||||
* There's no plan to make this public for now.
|
||||
* @hide
|
||||
*/
|
||||
public final class EmojiFactory {
|
||||
// private static final String LOG_TAG = "EmojiFactory";
|
||||
|
||||
private int sCacheSize = 100;
|
||||
|
||||
// HashMap for caching Bitmap object. In order not to make a cache object
|
||||
// blow up, we use LinkedHashMap with size limit.
|
||||
private class CustomLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
|
||||
public CustomLinkedHashMap() {
|
||||
// These magic numbers are gotten from the source code of
|
||||
// LinkedHashMap.java and HashMap.java.
|
||||
super(16, 0.75f, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* If size() becomes more than sCacheSize, least recently used cache
|
||||
* is erased.
|
||||
* @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)
|
||||
*/
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
|
||||
return size() > sCacheSize;
|
||||
}
|
||||
}
|
||||
|
||||
// A pointer to native EmojiFactory object.
|
||||
private long mNativeEmojiFactory;
|
||||
private String mName;
|
||||
// Cache.
|
||||
private Map<Integer, WeakReference<Bitmap>> mCache;
|
||||
|
||||
/**
|
||||
* @noinspection UnusedDeclaration
|
||||
*/
|
||||
/*
|
||||
* Private constructor that must received an already allocated native
|
||||
* EmojiFactory int (pointer).
|
||||
*
|
||||
* This can be called from JNI code.
|
||||
*/
|
||||
private EmojiFactory(long nativeEmojiFactory, String name) {
|
||||
mNativeEmojiFactory = nativeEmojiFactory;
|
||||
mName = name;
|
||||
mCache = new CustomLinkedHashMap<Integer, WeakReference<Bitmap>>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
nativeDestructor(mNativeEmojiFactory);
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Bitmap object corresponding to the AndroidPua.
|
||||
*
|
||||
* Note that each Bitmap is cached by this class, which means that, if you modify a
|
||||
* Bitmap object (using setPos() method), all same emoji Bitmap will be modified.
|
||||
* If it is unacceptable, please copy the object before modifying it.
|
||||
*
|
||||
* @param pua A unicode codepoint.
|
||||
* @return Bitmap object when this factory knows the Bitmap relevant to the codepoint.
|
||||
* Otherwise null is returned.
|
||||
*/
|
||||
public synchronized Bitmap getBitmapFromAndroidPua(int pua) {
|
||||
WeakReference<Bitmap> cache = mCache.get(pua);
|
||||
if (cache == null) {
|
||||
Bitmap ret = nativeGetBitmapFromAndroidPua(mNativeEmojiFactory, pua);
|
||||
// There is no need to cache returned null, since in most cases it means there
|
||||
// is no map from the AndroidPua to a specific image. In other words, it usually does
|
||||
// not include the cost of creating Bitmap object.
|
||||
if (ret != null) {
|
||||
mCache.put(pua, new WeakReference<Bitmap>(ret));
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
Bitmap tmp = cache.get();
|
||||
if (tmp == null) {
|
||||
Bitmap ret = nativeGetBitmapFromAndroidPua(mNativeEmojiFactory, pua);
|
||||
mCache.put(pua, new WeakReference<Bitmap>(ret));
|
||||
return ret;
|
||||
} else {
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Bitmap object corresponding to the vendor specified sjis.
|
||||
*
|
||||
* See comments in getBitmapFromAndroidPua().
|
||||
*
|
||||
* @param sjis sjis code specific to each career(vendor)
|
||||
* @return Bitmap object when this factory knows the Bitmap relevant to the code. Otherwise
|
||||
* null is returned.
|
||||
*/
|
||||
public synchronized Bitmap getBitmapFromVendorSpecificSjis(char sjis) {
|
||||
return getBitmapFromAndroidPua(getAndroidPuaFromVendorSpecificSjis(sjis));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Bitmap object corresponding to the vendor specific Unicode.
|
||||
*
|
||||
* See comments in getBitmapFromAndroidPua().
|
||||
*
|
||||
* @param vsp vendor specific PUA.
|
||||
* @return Bitmap object when this factory knows the Bitmap relevant to the code. Otherwise
|
||||
* null is returned.
|
||||
*/
|
||||
public synchronized Bitmap getBitmapFromVendorSpecificPua(int vsp) {
|
||||
return getBitmapFromAndroidPua(getAndroidPuaFromVendorSpecificPua(vsp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Unicode PUA for Android corresponding to the vendor specific sjis.
|
||||
*
|
||||
* @param sjis vendor specific sjis
|
||||
* @return Unicode PUA for Android, or -1 if there's no map for the sjis.
|
||||
*/
|
||||
public int getAndroidPuaFromVendorSpecificSjis(char sjis) {
|
||||
return nativeGetAndroidPuaFromVendorSpecificSjis(mNativeEmojiFactory, sjis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns vendor specific sjis corresponding to the Unicode AndroidPua.
|
||||
*
|
||||
* @param pua Unicode PUA for Android,
|
||||
* @return vendor specific sjis, or -1 if there's no map for the AndroidPua.
|
||||
*/
|
||||
public int getVendorSpecificSjisFromAndroidPua(int pua) {
|
||||
return nativeGetVendorSpecificSjisFromAndroidPua(mNativeEmojiFactory, pua);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Unicode PUA for Android corresponding to the vendor specific Unicode.
|
||||
*
|
||||
* @param vsp vendor specific PUA.
|
||||
* @return Unicode PUA for Android, or -1 if there's no map for the
|
||||
* Unicode.
|
||||
*/
|
||||
public int getAndroidPuaFromVendorSpecificPua(int vsp) {
|
||||
return nativeGetAndroidPuaFromVendorSpecificPua(mNativeEmojiFactory, vsp);
|
||||
}
|
||||
|
||||
public String getAndroidPuaFromVendorSpecificPua(String vspString) {
|
||||
if (vspString == null) {
|
||||
return null;
|
||||
}
|
||||
int minVsp = nativeGetMinimumVendorSpecificPua(mNativeEmojiFactory);
|
||||
int maxVsp = nativeGetMaximumVendorSpecificPua(mNativeEmojiFactory);
|
||||
int len = vspString.length();
|
||||
int[] codePoints = new int[vspString.codePointCount(0, len)];
|
||||
|
||||
int new_len = 0;
|
||||
for (int i = 0; i < len; i = vspString.offsetByCodePoints(i, 1), new_len++) {
|
||||
int codePoint = vspString.codePointAt(i);
|
||||
if (minVsp <= codePoint && codePoint <= maxVsp) {
|
||||
int newCodePoint = getAndroidPuaFromVendorSpecificPua(codePoint);
|
||||
if (newCodePoint > 0) {
|
||||
codePoints[new_len] = newCodePoint;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
codePoints[new_len] = codePoint;
|
||||
}
|
||||
return new String(codePoints, 0, new_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns vendor specific Unicode corresponding to the Unicode AndroidPua.
|
||||
*
|
||||
* @param pua Unicode PUA for Android,
|
||||
* @return vendor specific sjis, or -1 if there's no map for the AndroidPua.
|
||||
*/
|
||||
public int getVendorSpecificPuaFromAndroidPua(int pua) {
|
||||
return nativeGetVendorSpecificPuaFromAndroidPua(mNativeEmojiFactory, pua);
|
||||
}
|
||||
|
||||
public String getVendorSpecificPuaFromAndroidPua(String puaString) {
|
||||
if (puaString == null) {
|
||||
return null;
|
||||
}
|
||||
int minVsp = nativeGetMinimumAndroidPua(mNativeEmojiFactory);
|
||||
int maxVsp = nativeGetMaximumAndroidPua(mNativeEmojiFactory);
|
||||
int len = puaString.length();
|
||||
int[] codePoints = new int[puaString.codePointCount(0, len)];
|
||||
|
||||
int new_len = 0;
|
||||
for (int i = 0; i < len; i = puaString.offsetByCodePoints(i, 1), new_len++) {
|
||||
int codePoint = puaString.codePointAt(i);
|
||||
if (minVsp <= codePoint && codePoint <= maxVsp) {
|
||||
int newCodePoint = getVendorSpecificPuaFromAndroidPua(codePoint);
|
||||
if (newCodePoint > 0) {
|
||||
codePoints[new_len] = newCodePoint;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
codePoints[new_len] = codePoint;
|
||||
}
|
||||
return new String(codePoints, 0, new_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of EmojiFactory corresponding to the name.
|
||||
*
|
||||
* @param class_name Name of the factory. This must include complete package name.
|
||||
* @return A concrete EmojiFactory instance corresponding to factory_name.
|
||||
* If factory_name is invalid, null is returned.
|
||||
*/
|
||||
public static native EmojiFactory newInstance(String class_name);
|
||||
|
||||
/**
|
||||
* Constructs an instance of available EmojiFactory.
|
||||
*
|
||||
* @return A concrete EmojiFactory instance. If there are several available
|
||||
* EmojiFactory class, preferred one is chosen by the system. If there isn't, null
|
||||
* is returned.
|
||||
*/
|
||||
public static native EmojiFactory newAvailableInstance();
|
||||
|
||||
/**
|
||||
* Returns the lowest code point corresponding to an Android
|
||||
* emoji character.
|
||||
*/
|
||||
public int getMinimumAndroidPua() {
|
||||
return nativeGetMinimumAndroidPua(mNativeEmojiFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest code point corresponding to an Android
|
||||
* emoji character.
|
||||
*/
|
||||
public int getMaximumAndroidPua() {
|
||||
return nativeGetMaximumAndroidPua(mNativeEmojiFactory);
|
||||
}
|
||||
|
||||
// native methods
|
||||
|
||||
private native void nativeDestructor(long nativeEmojiFactory);
|
||||
private native Bitmap nativeGetBitmapFromAndroidPua(long nativeEmojiFactory, int AndroidPua);
|
||||
private native int nativeGetAndroidPuaFromVendorSpecificSjis(long nativeEmojiFactory,
|
||||
char sjis);
|
||||
private native int nativeGetVendorSpecificSjisFromAndroidPua(long nativeEmojiFactory,
|
||||
int pua);
|
||||
private native int nativeGetAndroidPuaFromVendorSpecificPua(long nativeEmojiFactory,
|
||||
int vsp);
|
||||
private native int nativeGetVendorSpecificPuaFromAndroidPua(long nativeEmojiFactory,
|
||||
int pua);
|
||||
private native int nativeGetMaximumVendorSpecificPua(long nativeEmojiFactory);
|
||||
private native int nativeGetMinimumVendorSpecificPua(long nativeEmojiFactory);
|
||||
private native int nativeGetMaximumAndroidPua(long nativeEmojiFactory);
|
||||
private native int nativeGetMinimumAndroidPua(long nativeEmojiFactory);
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
package android.text;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.emoji.EmojiFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
@@ -103,19 +102,6 @@ public abstract class Layout {
|
||||
private static final ParagraphStyle[] NO_PARA_SPANS =
|
||||
ArrayUtils.emptyArray(ParagraphStyle.class);
|
||||
|
||||
/* 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 must be in order to display the
|
||||
* specified text with one line per paragraph.
|
||||
@@ -360,9 +346,9 @@ public abstract class Layout {
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasTabOrEmoji = getLineContainsTab(lineNum);
|
||||
boolean hasTab = getLineContainsTab(lineNum);
|
||||
// Can't tell if we have tabs for sure, currently
|
||||
if (hasTabOrEmoji && !tabStopsIsInitialized) {
|
||||
if (hasTab && !tabStopsIsInitialized) {
|
||||
if (tabStops == null) {
|
||||
tabStops = new TabStops(TAB_INCREMENT, spans);
|
||||
} else {
|
||||
@@ -405,11 +391,11 @@ public abstract class Layout {
|
||||
|
||||
paint.setHyphenEdit(getHyphen(lineNum));
|
||||
Directions directions = getLineDirections(lineNum);
|
||||
if (directions == DIRS_ALL_LEFT_TO_RIGHT && !mSpannedText && !hasTabOrEmoji) {
|
||||
if (directions == DIRS_ALL_LEFT_TO_RIGHT && !mSpannedText && !hasTab) {
|
||||
// XXX: assumes there's nothing additional to be done
|
||||
canvas.drawText(buf, start, end, x, lbaseline, paint);
|
||||
} else {
|
||||
tl.set(paint, buf, start, end, dir, directions, hasTabOrEmoji, tabStops);
|
||||
tl.set(paint, buf, start, end, dir, directions, hasTab, tabStops);
|
||||
tl.draw(canvas, x, ltop, lbaseline, lbottom);
|
||||
}
|
||||
paint.setHyphenEdit(0);
|
||||
@@ -710,8 +696,7 @@ public abstract class Layout {
|
||||
|
||||
/**
|
||||
* Returns whether the specified line contains one or more
|
||||
* characters that need to be handled specially, like tabs
|
||||
* or emoji.
|
||||
* characters that need to be handled specially, like tabs.
|
||||
*/
|
||||
public abstract boolean getLineContainsTab(int line);
|
||||
|
||||
@@ -911,11 +896,11 @@ public abstract class Layout {
|
||||
int start = getLineStart(line);
|
||||
int end = getLineEnd(line);
|
||||
int dir = getParagraphDirection(line);
|
||||
boolean hasTabOrEmoji = getLineContainsTab(line);
|
||||
boolean hasTab = getLineContainsTab(line);
|
||||
Directions directions = getLineDirections(line);
|
||||
|
||||
TabStops tabStops = null;
|
||||
if (hasTabOrEmoji && mText instanceof Spanned) {
|
||||
if (hasTab && mText instanceof Spanned) {
|
||||
// Just checking this line should be good enough, tabs should be
|
||||
// consistent across all lines in a paragraph.
|
||||
TabStopSpan[] tabs = getParagraphSpans((Spanned) mText, start, end, TabStopSpan.class);
|
||||
@@ -925,7 +910,7 @@ public abstract class Layout {
|
||||
}
|
||||
|
||||
TextLine tl = TextLine.obtain();
|
||||
tl.set(mPaint, mText, start, end, dir, directions, hasTabOrEmoji, tabStops);
|
||||
tl.set(mPaint, mText, start, end, dir, directions, hasTab, tabStops);
|
||||
float wid = tl.measure(offset - start, trailing, null);
|
||||
TextLine.recycle(tl);
|
||||
|
||||
@@ -1031,9 +1016,9 @@ public abstract class Layout {
|
||||
int start = getLineStart(line);
|
||||
int end = full ? getLineEnd(line) : getLineVisibleEnd(line);
|
||||
|
||||
boolean hasTabsOrEmoji = getLineContainsTab(line);
|
||||
boolean hasTabs = getLineContainsTab(line);
|
||||
TabStops tabStops = null;
|
||||
if (hasTabsOrEmoji && mText instanceof Spanned) {
|
||||
if (hasTabs && mText instanceof Spanned) {
|
||||
// Just checking this line should be good enough, tabs should be
|
||||
// consistent across all lines in a paragraph.
|
||||
TabStopSpan[] tabs = getParagraphSpans((Spanned) mText, start, end, TabStopSpan.class);
|
||||
@@ -1049,7 +1034,7 @@ public abstract class Layout {
|
||||
int dir = getParagraphDirection(line);
|
||||
|
||||
TextLine tl = TextLine.obtain();
|
||||
tl.set(mPaint, mText, start, end, dir, directions, hasTabsOrEmoji, tabStops);
|
||||
tl.set(mPaint, mText, start, end, dir, directions, hasTabs, tabStops);
|
||||
float width = tl.metrics(null);
|
||||
TextLine.recycle(tl);
|
||||
return width;
|
||||
@@ -1066,12 +1051,12 @@ public abstract class Layout {
|
||||
private float getLineExtent(int line, TabStops tabStops, boolean full) {
|
||||
int start = getLineStart(line);
|
||||
int end = full ? getLineEnd(line) : getLineVisibleEnd(line);
|
||||
boolean hasTabsOrEmoji = getLineContainsTab(line);
|
||||
boolean hasTabs = getLineContainsTab(line);
|
||||
Directions directions = getLineDirections(line);
|
||||
int dir = getParagraphDirection(line);
|
||||
|
||||
TextLine tl = TextLine.obtain();
|
||||
tl.set(mPaint, mText, start, end, dir, directions, hasTabsOrEmoji, tabStops);
|
||||
tl.set(mPaint, mText, start, end, dir, directions, hasTabs, tabStops);
|
||||
float width = tl.metrics(null);
|
||||
TextLine.recycle(tl);
|
||||
return width;
|
||||
|
||||
@@ -1308,7 +1308,7 @@ public class StaticLayout extends Layout {
|
||||
private static final int INITIAL_SIZE = 16;
|
||||
public int[] breaks = new int[INITIAL_SIZE];
|
||||
public float[] widths = new float[INITIAL_SIZE];
|
||||
public int[] flags = new int[INITIAL_SIZE]; // hasTabOrEmoji
|
||||
public int[] flags = new int[INITIAL_SIZE]; // hasTab
|
||||
// breaks, widths, and flags should all have the same length
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ class TextLine {
|
||||
* @param limit the limit of the line relative to the text
|
||||
* @param dir the paragraph direction of this line
|
||||
* @param directions the directions information of this line
|
||||
* @param hasTabs true if the line might contain tabs or emoji
|
||||
* @param hasTabs true if the line might contain tabs
|
||||
* @param tabStops the tabStops. Can be null.
|
||||
*/
|
||||
void set(TextPaint paint, CharSequence text, int start, int limit, int dir,
|
||||
@@ -204,7 +204,6 @@ class TextLine {
|
||||
|
||||
float h = 0;
|
||||
int[] runs = mDirections.mDirections;
|
||||
RectF emojiRect = null;
|
||||
|
||||
int lastRunIndex = runs.length - 2;
|
||||
for (int i = 0; i < runs.length; i += 2) {
|
||||
@@ -218,41 +217,23 @@ class TextLine {
|
||||
int segstart = runStart;
|
||||
for (int j = mHasTabs ? runStart : runLimit; j <= runLimit; j++) {
|
||||
int codept = 0;
|
||||
Bitmap bm = null;
|
||||
|
||||
if (mHasTabs && j < runLimit) {
|
||||
codept = mChars[j];
|
||||
if (codept >= 0xd800 && codept < 0xdc00 && j + 1 < runLimit) {
|
||||
if (codept >= 0xD800 && codept < 0xDC00 && j + 1 < runLimit) {
|
||||
codept = Character.codePointAt(mChars, j);
|
||||
if (codept >= Layout.MIN_EMOJI && codept <= Layout.MAX_EMOJI) {
|
||||
bm = Layout.EMOJI_FACTORY.getBitmapFromAndroidPua(codept);
|
||||
} else if (codept > 0xffff) {
|
||||
if (codept > 0xFFFF) {
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j == runLimit || codept == '\t' || bm != null) {
|
||||
if (j == runLimit || codept == '\t') {
|
||||
h += drawRun(c, segstart, j, runIsRtl, x+h, top, y, bottom,
|
||||
i != lastRunIndex || j != mLen);
|
||||
|
||||
if (codept == '\t') {
|
||||
h = mDir * nextTab(h * mDir);
|
||||
} else if (bm != null) {
|
||||
float bmAscent = ascent(j);
|
||||
float bitmapHeight = bm.getHeight();
|
||||
float scale = -bmAscent / bitmapHeight;
|
||||
float width = bm.getWidth() * scale;
|
||||
|
||||
if (emojiRect == null) {
|
||||
emojiRect = new RectF();
|
||||
}
|
||||
emojiRect.set(x + h, y + bmAscent,
|
||||
x + h + width, y);
|
||||
c.drawBitmap(bm, null, emojiRect, mPaint);
|
||||
h += width;
|
||||
j++;
|
||||
}
|
||||
segstart = j + 1;
|
||||
}
|
||||
@@ -313,22 +294,18 @@ class TextLine {
|
||||
int segstart = runStart;
|
||||
for (int j = mHasTabs ? runStart : runLimit; j <= runLimit; j++) {
|
||||
int codept = 0;
|
||||
Bitmap bm = null;
|
||||
|
||||
if (mHasTabs && j < runLimit) {
|
||||
codept = chars[j];
|
||||
if (codept >= 0xd800 && codept < 0xdc00 && j + 1 < runLimit) {
|
||||
if (codept >= 0xD800 && codept < 0xDC00 && j + 1 < runLimit) {
|
||||
codept = Character.codePointAt(chars, j);
|
||||
if (codept >= Layout.MIN_EMOJI && codept <= Layout.MAX_EMOJI) {
|
||||
bm = Layout.EMOJI_FACTORY.getBitmapFromAndroidPua(codept);
|
||||
} else if (codept > 0xffff) {
|
||||
if (codept > 0xFFFF) {
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j == runLimit || codept == '\t' || bm != null) {
|
||||
if (j == runLimit || codept == '\t') {
|
||||
boolean inSegment = target >= segstart && target < j;
|
||||
|
||||
boolean advance = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
|
||||
@@ -353,13 +330,6 @@ class TextLine {
|
||||
}
|
||||
}
|
||||
|
||||
if (bm != null) {
|
||||
float bmAscent = ascent(j);
|
||||
float wid = bm.getWidth() * -bmAscent / bm.getHeight();
|
||||
h += mDir * wid;
|
||||
j++;
|
||||
}
|
||||
|
||||
segstart = j + 1;
|
||||
}
|
||||
}
|
||||
@@ -705,7 +675,7 @@ class TextLine {
|
||||
|
||||
/**
|
||||
* Utility function for measuring and rendering text. The text must
|
||||
* not include a tab or emoji.
|
||||
* not include a tab.
|
||||
*
|
||||
* @param wp the working paint
|
||||
* @param start the start of the text
|
||||
@@ -860,7 +830,7 @@ class TextLine {
|
||||
|
||||
/**
|
||||
* Utility function for handling a unidirectional run. The run must not
|
||||
* contain tabs or emoji but can contain styles.
|
||||
* contain tabs but can contain styles.
|
||||
*
|
||||
*
|
||||
* @param start the line-relative start of the run
|
||||
@@ -993,32 +963,6 @@ class TextLine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ascent of the text at start. This is used for scaling
|
||||
* emoji.
|
||||
*
|
||||
* @param pos the line-relative position
|
||||
* @return the ascent of the text at start
|
||||
*/
|
||||
float ascent(int pos) {
|
||||
if (mSpanned == null) {
|
||||
return mPaint.ascent();
|
||||
}
|
||||
|
||||
pos += mStart;
|
||||
MetricAffectingSpan[] spans = mSpanned.getSpans(pos, pos + 1, MetricAffectingSpan.class);
|
||||
if (spans.length == 0) {
|
||||
return mPaint.ascent();
|
||||
}
|
||||
|
||||
TextPaint wp = mWorkPaint;
|
||||
wp.set(mPaint);
|
||||
for (MetricAffectingSpan span : spans) {
|
||||
span.updateMeasureState(wp);
|
||||
}
|
||||
return wp.ascent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next tab position.
|
||||
*
|
||||
|
||||
@@ -49,7 +49,6 @@ LOCAL_SRC_FILES:= \
|
||||
android_database_SQLiteConnection.cpp \
|
||||
android_database_SQLiteGlobal.cpp \
|
||||
android_database_SQLiteDebug.cpp \
|
||||
android_emoji_EmojiFactory.cpp \
|
||||
android_view_DisplayEventReceiver.cpp \
|
||||
android_view_DisplayListCanvas.cpp \
|
||||
android_view_GraphicBuffer.cpp \
|
||||
@@ -201,7 +200,6 @@ LOCAL_C_INCLUDES += \
|
||||
external/tremor/Tremor \
|
||||
external/jpeg \
|
||||
external/harfbuzz_ng/src \
|
||||
frameworks/opt/emoji \
|
||||
libcore/include \
|
||||
$(call include-path-for, audio-utils) \
|
||||
frameworks/minikin/include \
|
||||
|
||||
@@ -107,7 +107,6 @@ extern int register_android_util_EventLog(JNIEnv* env);
|
||||
extern int register_android_util_Log(JNIEnv* env);
|
||||
extern int register_android_content_StringBlock(JNIEnv* env);
|
||||
extern int register_android_content_XmlBlock(JNIEnv* env);
|
||||
extern int register_android_emoji_EmojiFactory(JNIEnv* env);
|
||||
extern int register_android_graphics_Canvas(JNIEnv* env);
|
||||
extern int register_android_graphics_CanvasProperty(JNIEnv* env);
|
||||
extern int register_android_graphics_ColorFilter(JNIEnv* env);
|
||||
@@ -1265,7 +1264,6 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_content_AssetManager),
|
||||
REG_JNI(register_android_content_StringBlock),
|
||||
REG_JNI(register_android_content_XmlBlock),
|
||||
REG_JNI(register_android_emoji_EmojiFactory),
|
||||
REG_JNI(register_android_text_AndroidCharacter),
|
||||
REG_JNI(register_android_text_StaticLayout),
|
||||
REG_JNI(register_android_text_AndroidBidi),
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
#include "SkTypes.h"
|
||||
#include "SkImageDecoder.h"
|
||||
|
||||
#define LOG_TAG "EmojiFactory_jni"
|
||||
#include <utils/Log.h>
|
||||
#include <ScopedUtfChars.h>
|
||||
|
||||
#include "BitmapFactory.h"
|
||||
#include "EmojiFactory.h"
|
||||
#include "GraphicsJNI.h"
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
// #include <pthread.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class EmojiFactoryCaller {
|
||||
public:
|
||||
EmojiFactoryCaller() {}
|
||||
virtual ~EmojiFactoryCaller();
|
||||
bool Init();
|
||||
EmojiFactory *TryCallGetImplementation(const char* name);
|
||||
EmojiFactory *TryCallGetAvailableImplementation();
|
||||
private:
|
||||
void *m_handle;
|
||||
EmojiFactory *(*m_get_implementation)(const char*);
|
||||
EmojiFactory *(*m_get_available_implementation)();
|
||||
};
|
||||
|
||||
bool EmojiFactoryCaller::Init() {
|
||||
const char* error_msg;
|
||||
m_handle = dlopen("libemoji.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
|
||||
if (m_handle == NULL) {
|
||||
error_msg = "Failed to load libemoji.so";
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
m_get_implementation =
|
||||
reinterpret_cast<EmojiFactory *(*)(const char*)>(
|
||||
dlsym(m_handle, "GetImplementation"));
|
||||
if (m_get_implementation == NULL) {
|
||||
error_msg = "Failed to get symbol of GetImplementation";
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
m_get_available_implementation =
|
||||
reinterpret_cast<EmojiFactory *(*)()>(
|
||||
dlsym(m_handle,"GetAvailableImplementation"));
|
||||
if (m_get_available_implementation == NULL) {
|
||||
error_msg = "Failed to get symbol of GetAvailableImplementation";
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
FAIL:
|
||||
const char* error_str = dlerror();
|
||||
if (error_str == NULL) {
|
||||
error_str = "unknown reason";
|
||||
}
|
||||
|
||||
ALOGE("%s: %s", error_msg, error_str);
|
||||
if (m_handle != NULL) {
|
||||
dlclose(m_handle);
|
||||
m_handle = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
EmojiFactoryCaller::~EmojiFactoryCaller() {
|
||||
if (m_handle) {
|
||||
dlclose(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
EmojiFactory *EmojiFactoryCaller::TryCallGetImplementation(
|
||||
const char* name) {
|
||||
if (NULL == m_handle) {
|
||||
return NULL;
|
||||
}
|
||||
return m_get_implementation(name);
|
||||
}
|
||||
|
||||
EmojiFactory *EmojiFactoryCaller::TryCallGetAvailableImplementation() {
|
||||
if (NULL == m_handle) {
|
||||
return NULL;
|
||||
}
|
||||
return m_get_available_implementation();
|
||||
}
|
||||
|
||||
static EmojiFactoryCaller* gCaller;
|
||||
static pthread_once_t g_once = PTHREAD_ONCE_INIT;
|
||||
static bool lib_emoji_factory_is_ready;
|
||||
|
||||
static jclass gEmojiFactory_class;
|
||||
static jmethodID gEmojiFactory_constructorMethodID;
|
||||
|
||||
static void InitializeCaller() {
|
||||
gCaller = new EmojiFactoryCaller();
|
||||
lib_emoji_factory_is_ready = gCaller->Init();
|
||||
}
|
||||
|
||||
static jobject create_java_EmojiFactory(
|
||||
JNIEnv* env, EmojiFactory* factory, jstring name) {
|
||||
jobject obj = env->NewObject(gEmojiFactory_class, gEmojiFactory_constructorMethodID,
|
||||
reinterpret_cast<jlong>(factory), name);
|
||||
if (env->ExceptionCheck() != 0) {
|
||||
ALOGE("*** Uncaught exception returned from Java call!\n");
|
||||
env->ExceptionDescribe();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
static jobject android_emoji_EmojiFactory_newInstance(
|
||||
JNIEnv* env, jobject clazz, jstring name) {
|
||||
if (NULL == name) {
|
||||
return NULL;
|
||||
}
|
||||
pthread_once(&g_once, InitializeCaller);
|
||||
if (!lib_emoji_factory_is_ready) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ScopedUtfChars nameUtf(env, name);
|
||||
|
||||
EmojiFactory *factory = gCaller->TryCallGetImplementation(nameUtf.c_str());
|
||||
// EmojiFactory *factory = EmojiFactory::GetImplementation(str.string());
|
||||
if (NULL == factory) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return create_java_EmojiFactory(env, factory, name);
|
||||
}
|
||||
|
||||
static jobject android_emoji_EmojiFactory_newAvailableInstance(
|
||||
JNIEnv* env, jobject clazz) {
|
||||
pthread_once(&g_once, InitializeCaller);
|
||||
if (!lib_emoji_factory_is_ready) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EmojiFactory *factory = gCaller->TryCallGetAvailableImplementation();
|
||||
// EmojiFactory *factory = EmojiFactory::GetAvailableImplementation();
|
||||
if (NULL == factory) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jstring jname = env->NewStringUTF(factory->Name());
|
||||
if (NULL == jname) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return create_java_EmojiFactory(env, factory, jname);
|
||||
}
|
||||
|
||||
static jobject android_emoji_EmojiFactory_getBitmapFromAndroidPua(
|
||||
JNIEnv* env, jobject clazz, jlong nativeEmojiFactory, jint pua) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
|
||||
int size;
|
||||
const char *bytes = factory->GetImageBinaryFromAndroidPua(pua, &size);
|
||||
if (bytes == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return decodeBitmap(env, (void*)bytes, size);
|
||||
}
|
||||
|
||||
static void android_emoji_EmojiFactory_destructor(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
|
||||
/*
|
||||
// Must not delete this object!!
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
delete factory;
|
||||
*/
|
||||
}
|
||||
|
||||
static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jchar sjis) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
return factory->GetAndroidPuaFromVendorSpecificSjis(sjis);
|
||||
}
|
||||
|
||||
static jint android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint pua) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
return factory->GetVendorSpecificSjisFromAndroidPua(pua);
|
||||
}
|
||||
|
||||
static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint vsu) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
return factory->GetAndroidPuaFromVendorSpecificPua(vsu);
|
||||
}
|
||||
|
||||
static jint android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint pua) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
return factory->GetVendorSpecificPuaFromAndroidPua(pua);
|
||||
}
|
||||
|
||||
static jint android_emoji_EmojiFactory_getMaximumVendorSpecificPua(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
return factory->GetMaximumVendorSpecificPua();
|
||||
}
|
||||
|
||||
static jint android_emoji_EmojiFactory_getMinimumVendorSpecificPua(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
return factory->GetMinimumVendorSpecificPua();
|
||||
}
|
||||
|
||||
static jint android_emoji_EmojiFactory_getMaximumAndroidPua(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
return factory->GetMaximumAndroidPua();
|
||||
}
|
||||
|
||||
static jint android_emoji_EmojiFactory_getMinimumAndroidPua(
|
||||
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
|
||||
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
|
||||
return factory->GetMinimumAndroidPua();
|
||||
}
|
||||
|
||||
static JNINativeMethod gMethods[] = {
|
||||
{ "newInstance", "(Ljava/lang/String;)Landroid/emoji/EmojiFactory;",
|
||||
(void*)android_emoji_EmojiFactory_newInstance},
|
||||
{ "newAvailableInstance", "()Landroid/emoji/EmojiFactory;",
|
||||
(void*)android_emoji_EmojiFactory_newAvailableInstance},
|
||||
{ "nativeDestructor", "(J)V",
|
||||
(void*)android_emoji_EmojiFactory_destructor},
|
||||
{ "nativeGetBitmapFromAndroidPua", "(JI)Landroid/graphics/Bitmap;",
|
||||
(void*)android_emoji_EmojiFactory_getBitmapFromAndroidPua},
|
||||
{ "nativeGetAndroidPuaFromVendorSpecificSjis", "(JC)I",
|
||||
(void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis},
|
||||
{ "nativeGetVendorSpecificSjisFromAndroidPua", "(JI)I",
|
||||
(void*)android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua},
|
||||
{ "nativeGetAndroidPuaFromVendorSpecificPua", "(JI)I",
|
||||
(void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua},
|
||||
{ "nativeGetVendorSpecificPuaFromAndroidPua", "(JI)I",
|
||||
(void*)android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua},
|
||||
{ "nativeGetMaximumVendorSpecificPua", "(J)I",
|
||||
(void*)android_emoji_EmojiFactory_getMaximumVendorSpecificPua},
|
||||
{ "nativeGetMinimumVendorSpecificPua", "(J)I",
|
||||
(void*)android_emoji_EmojiFactory_getMinimumVendorSpecificPua},
|
||||
{ "nativeGetMaximumAndroidPua", "(J)I",
|
||||
(void*)android_emoji_EmojiFactory_getMaximumAndroidPua},
|
||||
{ "nativeGetMinimumAndroidPua", "(J)I",
|
||||
(void*)android_emoji_EmojiFactory_getMinimumAndroidPua}
|
||||
};
|
||||
|
||||
static jclass make_globalref(JNIEnv* env, const char classname[])
|
||||
{
|
||||
jclass c = env->FindClass(classname);
|
||||
SkASSERT(c);
|
||||
return (jclass)env->NewGlobalRef(c);
|
||||
}
|
||||
|
||||
int register_android_emoji_EmojiFactory(JNIEnv* env) {
|
||||
gEmojiFactory_class = make_globalref(env, "android/emoji/EmojiFactory");
|
||||
gEmojiFactory_constructorMethodID = env->GetMethodID(
|
||||
gEmojiFactory_class, "<init>", "(JLjava/lang/String;)V");
|
||||
return jniRegisterNativeMethods(env, "android/emoji/EmojiFactory",
|
||||
gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
@@ -742,7 +742,6 @@ android.ddm.DdmHandleProfiling
|
||||
android.ddm.DdmHandleThread
|
||||
android.ddm.DdmHandleViewDebug
|
||||
android.ddm.DdmRegister
|
||||
android.emoji.EmojiFactory
|
||||
android.graphics.AvoidXfermode
|
||||
android.graphics.Bitmap
|
||||
android.graphics.Bitmap$1
|
||||
|
||||
Reference in New Issue
Block a user