2013-06-27 20:57:27 -07:00
|
|
|
package org.thoughtcrime.securesms.util;
|
|
|
|
|
|
|
|
import android.content.Context;
|
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
import android.text.Spannable;
|
|
|
|
import android.text.SpannableString;
|
|
|
|
import android.text.style.ImageSpan;
|
|
|
|
import android.util.Log;
|
|
|
|
|
2013-06-28 16:56:30 -07:00
|
|
|
import java.io.File;
|
2013-06-27 20:57:27 -07:00
|
|
|
import java.io.IOException;
|
2013-06-28 16:56:30 -07:00
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Set;
|
2013-06-27 20:57:27 -07:00
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
public class Emoji {
|
|
|
|
|
2013-06-28 16:56:30 -07:00
|
|
|
private static Emoji instance = null;
|
|
|
|
|
|
|
|
public synchronized static Emoji getInstance(Context context) {
|
|
|
|
if (instance == null) {
|
|
|
|
instance = new Emoji(context);
|
2013-06-27 20:57:27 -07:00
|
|
|
}
|
2013-06-28 16:56:30 -07:00
|
|
|
|
|
|
|
return instance;
|
2013-06-27 20:57:27 -07:00
|
|
|
}
|
|
|
|
|
2013-06-28 16:56:30 -07:00
|
|
|
private static final Pattern EMOJI_RANGE = Pattern.compile("[\ud83d\ude01-\ud83d\ude4f]");
|
|
|
|
public static final double EMOJI_LARGE = 1;
|
|
|
|
public static final double EMOJI_SMALL = 0.7;
|
|
|
|
|
|
|
|
private final Context context;
|
|
|
|
private final String[] emojiAssets;
|
|
|
|
private final Set<String> emojiAssetsSet;
|
|
|
|
|
|
|
|
private Emoji(Context context) {
|
|
|
|
this.context = context.getApplicationContext();
|
|
|
|
this.emojiAssets = initializeEmojiAssets();
|
|
|
|
this.emojiAssetsSet = new HashSet<String>();
|
|
|
|
|
|
|
|
Collections.addAll(this.emojiAssetsSet, emojiAssets);
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getEmojiAssetCount() {
|
|
|
|
return emojiAssets.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getEmojiUnicode(int position) {
|
|
|
|
String hexString = emojiAssets[position].split("\\.")[0];
|
|
|
|
Integer unicodePoint = Integer.parseInt(hexString, 16);
|
|
|
|
return new String(Character.toChars(unicodePoint));
|
|
|
|
}
|
|
|
|
|
|
|
|
public Drawable getEmojiDrawable(int position) {
|
|
|
|
return getEmojiDrawable(emojiAssets[position]);
|
|
|
|
}
|
|
|
|
|
|
|
|
public SpannableString emojify(String text) {
|
|
|
|
return emojify(new SpannableString(text), EMOJI_LARGE);
|
|
|
|
}
|
2013-06-27 20:57:27 -07:00
|
|
|
|
2013-06-28 16:56:30 -07:00
|
|
|
public SpannableString emojify(SpannableString text, double size) {
|
|
|
|
if (text.toString().contains("\ud83d")) {
|
2013-06-27 20:57:27 -07:00
|
|
|
|
2013-06-28 16:56:30 -07:00
|
|
|
Matcher matches = EMOJI_RANGE.matcher(text);
|
|
|
|
|
|
|
|
while (matches.find()) {
|
|
|
|
String resource = Integer.toHexString(matches.group().codePointAt(0)) + ".png";
|
|
|
|
|
|
|
|
if (emojiAssetsSet.contains(resource)) {
|
|
|
|
Drawable drawable = getEmojiDrawable(resource);
|
|
|
|
drawable.setBounds(0, 0, (int)(drawable.getIntrinsicWidth()*size),
|
|
|
|
(int)(drawable.getIntrinsicHeight()*size));
|
|
|
|
|
|
|
|
|
|
|
|
ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
|
|
|
|
text.setSpan(imageSpan, matches.start(), matches.end(),
|
|
|
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
2013-06-27 20:57:27 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2013-06-28 16:56:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return text;
|
|
|
|
}
|
2013-06-27 20:57:27 -07:00
|
|
|
|
2013-06-28 16:56:30 -07:00
|
|
|
private Drawable getEmojiDrawable(String assetName) {
|
|
|
|
try {
|
|
|
|
return Drawable.createFromStream(context.getAssets().open("emoji" + File.separator + assetName), null);
|
2013-06-27 20:57:27 -07:00
|
|
|
} catch (IOException e) {
|
|
|
|
throw new AssertionError(e);
|
|
|
|
}
|
|
|
|
}
|
2013-06-28 16:56:30 -07:00
|
|
|
|
|
|
|
private String[] initializeEmojiAssets() {
|
|
|
|
try {
|
|
|
|
return context.getAssets().list("emoji");
|
|
|
|
} catch (IOException e) {
|
|
|
|
Log.w("Emoji", e);
|
|
|
|
return new String[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-27 20:57:27 -07:00
|
|
|
}
|