スマホで絵文字を入力して作成した発言もemojioneフォントで表示されるようにした

This commit is contained in:
tateisu 2017-04-28 01:28:35 +09:00
parent b885c6bf66
commit 6689da0bb3
4 changed files with 3561 additions and 3510 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned; import android.text.Spanned;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -15,7 +16,7 @@ public abstract class Emojione
private static final Pattern SHORTNAME_PATTERN = Pattern.compile(":([-+\\w]+):"); private static final Pattern SHORTNAME_PATTERN = Pattern.compile(":([-+\\w]+):");
public static final HashMap<String,String> map_name2unicode = EmojiMap._shortNameToUnicode; public static final HashMap<String,String> map_name2unicode = EmojiMap._shortNameToUnicode;
public static final HashMap<String,String> map_unicode2name = EmojiMap._unicodeToShortName; public static final HashSet<String> set_unicode = EmojiMap._unicode_set;
static class DecodeEnv{ static class DecodeEnv{
SpannableStringBuilder sb = new SpannableStringBuilder(); SpannableStringBuilder sb = new SpannableStringBuilder();
@ -45,46 +46,36 @@ public abstract class Emojione
int end = s.length(); int end = s.length();
while( i < end ){ while( i < end ){
int remain = end - i; int remain = end - i;
if( remain >= 4 ){ String emoji = null;
String check = s.substring( i, i + 4 ); for(int j = EmojiMap.max_length; j>0;--j ){
if( map_unicode2name.containsKey( check ) ){ if( j > remain ) continue;
addEmoji( check ); String check = s.substring( i, i + j );
i += 4; if( ! set_unicode.contains( check ) ) continue;
continue; emoji = check;
} break;
} }
if( remain >= 3 ){ if( emoji != null ){
String check = s.substring( i, i + 3 ); addEmoji( emoji );
if( map_unicode2name.containsKey( check ) ){ i += emoji.length();
addEmoji( check ); continue;
i += 3;
continue;
}
}
if( remain >= 2 ){
String check = s.substring( i, i + 2 );
if( map_unicode2name.containsKey( check ) ){
addEmoji( check );
i += 2;
continue;
}
}
if( remain >= 1 ){
String check = s.substring( i, i + 1 );
if( map_unicode2name.containsKey( check ) ){
addEmoji( check );
i += 1;
continue;
}
} }
closeSpan(); closeSpan();
sb.append( s.charAt( i ) ); int length = Character.charCount( s.codePointAt( i ) );
++ i; if( length == 1){
sb.append( s.charAt( i ) );
++ i;
}else{
sb.append( s.substring( i,i+length ));
i+= length;
}
} }
} }
} }
public static CharSequence decodeEmoji( String s ){ public static CharSequence decodeEmoji( String s ){
DecodeEnv decode_env = new DecodeEnv(); DecodeEnv decode_env = new DecodeEnv();
Matcher matcher = SHORTNAME_PATTERN.matcher(s); Matcher matcher = SHORTNAME_PATTERN.matcher(s);
int last_end = 0; int last_end = 0;
@ -103,13 +94,13 @@ public abstract class Emojione
decode_env.addEmoji( unicode ); decode_env.addEmoji( unicode );
} }
} }
// close span
decode_env.closeSpan();
// copy remain // copy remain
int end = s.length(); int end = s.length();
if( end > last_end ){ if( end > last_end ){
decode_env.addUnicodeString(s.substring( last_end, end )); decode_env.addUnicodeString(s.substring( last_end, end ));
} }
// close span
decode_env.closeSpan();
return decode_env.sb; return decode_env.sb;
} }
} }

View File

@ -11,6 +11,7 @@ import java.util.HashMap;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import jp.juggler.subwaytooter.BuildConfig;
import jp.juggler.subwaytooter.api.entity.TootMention; import jp.juggler.subwaytooter.api.entity.TootMention;
public class HTMLDecoder { public class HTMLDecoder {
@ -207,6 +208,10 @@ public class HTMLDecoder {
} }
} }
private static boolean isWhitespace( char c ){
return Character.isWhitespace( c ) || c == 0x0a || c == 0x0d;
}
public static SpannableStringBuilder decodeHTML( LinkClickContext account, String src ){ public static SpannableStringBuilder decodeHTML( LinkClickContext account, String src ){
try{ try{
TokenParser tracker = new TokenParser( src ); TokenParser tracker = new TokenParser( src );
@ -217,7 +222,7 @@ public class HTMLDecoder {
rootNode.encodeSpan( account, sb ); rootNode.encodeSpan( account, sb );
int end = sb.length(); int end = sb.length();
while( end > 0 && Character.isWhitespace( sb.charAt( end - 1 ) ) ) -- end; while( end > 0 && isWhitespace( sb.charAt( end - 1 ) ) ) -- end;
if( end < sb.length() ){ if( end < sb.length() ){
sb.delete( end, sb.length() ); sb.delete( end, sb.length() );
} }

View File

@ -179,6 +179,16 @@ public class Utils {
return a == null ? b == null : a.equals( b ); return a == null ? b == null : a.equals( b );
} }
public static CharSequence dumpCodePoints(String str){
StringBuilder sb = new StringBuilder();
for(int i=0,ie=str.length(),cp;i<ie;i+=Character.charCount(cp)){
cp = str.codePointAt( i );
sb.append( String.format( "0x%x,", cp ) );
}
return sb;
}
static final char[] hex = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; static final char[] hex = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static void addHex( StringBuilder sb, byte b ){ public static void addHex( StringBuilder sb, byte b ){