Skip to content

Instantly share code, notes, and snippets.

@Lesmiscore
Last active September 26, 2017 15:35
Show Gist options
  • Save Lesmiscore/8d4d198348faa0c6f23c3ae275ca6640 to your computer and use it in GitHub Desktop.
Save Lesmiscore/8d4d198348faa0c6f23c3ae275ca6640 to your computer and use it in GitHub Desktop.
Minecraftの文字色とスタイル(Obfuscate以外)を再現 on Android
ENG
MinecraftFormattingCodeParser.java is provided and licensed under the Public Domain.
https://commons.wikimedia.org/wiki/Template:PD-self
How to use
MinecraftFormattingCodeParser mfcp=new MinecraftFormattingCodeParser();//Construct an instance
mfcp.loadFlags("§6Wisecraft",0);//Load flags(Colors and styles) You need to call this for above operation. First arg is a String with Minecraft Formatting Codes. Second arg is a default flag.
mTextView.setText(mfcp.build());//Generate a Spannable object and set it to a TextView. This is colored and styled string.
JPN
MinecraftFormattingCodeParser.javaはパブリックドメインで提供されるものとします。
https://commons.wikimedia.org/wiki/Template:PD-self
使い方
MinecraftFormattingCodeParser mfcp=new MinecraftFormattingCodeParser();//インスタンスを作成
mfcp.loadFlags("§6Wisecraft",0);//Flagを読み込みます。(色とスタイル) 次の呼び出しで必要となります。最初の引数は色とスタイルをMinecraft装飾コードで指定した文字列です。2番目の引数はデフォルトのFlagです。
mTextView.setText(mfcp.build());//TextViewなどにbuild()メソッドを使用して生成したSpannableオブジェクトを設定します。これは色付けとスタイル設定がされた文字列です。
ENG
flag is byte array.
One byte represents all the colors and styles.
0b00000000
IUSBCCCC
"I" bit is italic. Set it 1 to make the char italic.
"U" bit is underline. Set it 1 to make the char underlined.
"S" bit is strikethrough. Set it 1 to make the char strikethroughed.
"B" bit is bold. Set it 1 to make the char bolded.
Four "C" bits are color. e.g.) 0000=§0 0101=§5 1010=§a 0110=§6
JPN
flagはbyte配列です。
1つのbyteで全ての色及びスタイルを表現します。
0b00000000
IUSBCCCC
"I"ビットはイタリック体(斜体)を指定します。これを1にするとイタリック体になります。
"U"ビットは下線を指定します。これを1にすると下線が追加されます。
"S"ビットは取り消し線を指定します。これを1にすると取り消し線が追加されます。
"B"ビットは太字を指定します。これを1にすると太字になります。
4つの"C"ビットは色を指定します。例) 0000=§0 0101=§5 1010=§a 0110=§6
import android.text.style.*;
import android.graphics.Typeface;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.util.Log;
public class MinecraftFormattingCodeParser {
private static final int[] TEXT_COLORS=new int[]{
0xff000000,
0xff0000AA,
0xff00AA00,
0xff00AAAA,
0xffAA0000,
0xffAA00AA,
0xffFFAA00,
0xffAAAAAA,
0xff555555,
0xff5555FF,
0xff55FF55,
0xff55FFFF,
0xffFF5555,
0xffFF55FF,
0xffFFFF55,
0xffFFFFFF
};
public byte[] flags=null;
public char[] escaped=null;
public void loadFlags(String s,byte defaultFlag){
escaped=deleteDecorations(s).toCharArray();
flags=new byte[escaped.length];
char[] chars=s.toCharArray();
int offset=0;
int undecOffset=0;
byte flag=defaultFlag;
while (chars.length > offset) {
if (chars[offset] == '§') {
offset++;
char keyChar=chars[offset++];
switch(keyChar){
/*Colors*/
case '0':
flag=0;
break;
case '1':
flag=1;
break;
case '2':
flag=2;
break;
case '3':
flag=3;
break;
case '4':
flag=4;
break;
case '5':
flag=5;
break;
case '6':
flag=6;
break;
case '7':
flag=7;
break;
case '8':
flag=8;
break;
case '9':
flag=9;
break;
case 'a':case 'A':
flag=10;
break;
case 'b':case 'B':
flag=11;
break;
case 'c':case 'C':
flag=12;
break;
case 'd':case 'D':
flag=13;
break;
case 'e':case 'E':
flag=14;
break;
case 'f':case 'F':
flag=15;
break;
/*Styles*/
case 'l':case 'L':
flag=(byte)(flag|0b00010000);
break;
case 'm':case 'M':
flag=(byte)(flag|0b00100000);
break;
case 'n':case 'N':
flag=(byte)(flag|0b01000000);
break;
case 'o':case 'O':
flag=(byte)(flag|0b10000000);
break;
/*Reset*/
case 'r':case 'R':
flag=defaultFlag;
break;
}
continue;
}
flags[undecOffset]=flag;
offset++;
undecOffset++;
}
Log.d("MFCP","offset:"+offset+",undecOffset:"+undecOffset+",flags[0]:"+flags[0]);
}
public Spannable build(){
SpannableStringBuilder ssb=new SpannableStringBuilder();
for(int i=0;i<escaped.length;i++){
ForegroundColorSpan fcs=new ForegroundColorSpan(TEXT_COLORS[flags[i]&0xF]);
ssb.append(escaped[i]+"",fcs,SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
if(0!=(flags[i]&0b00010000)){
ssb.setSpan(new StyleSpan(Typeface.BOLD),ssb.length()-1,ssb.length(),SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if(0!=(flags[i]&0b00100000)){
ssb.setSpan(new StrikethroughSpan(),ssb.length()-1,ssb.length(),SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if(0!=(flags[i]&0b01000000)){
ssb.setSpan(new UnderlineSpan(),ssb.length()-1,ssb.length(),SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if(0!=(flags[i]&0b10000000)){
ssb.setSpan(new StyleSpan(Typeface.ITALIC),ssb.length()-1,ssb.length(),SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return ssb;
}
public static String deleteDecorations(String decorated) {
StringBuilder sb=new StringBuilder();
char[] chars=decorated.toCharArray();
int offset=0;
while (chars.length > offset) {
if (chars[offset] == '§') {
offset += 2;
continue;
}
sb.append(chars[offset]);
offset++;
}
return sb.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment