Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.text;
     18 
     19 import android.icu.lang.UCharacter;
     20 import android.icu.lang.UProperty;
     21 
     22 /**
     23  * An utility class for Emoji.
     24  * @hide
     25  */
     26 public class Emoji {
     27     public static int COMBINING_ENCLOSING_KEYCAP = 0x20E3;
     28 
     29     public static int ZERO_WIDTH_JOINER = 0x200D;
     30 
     31     public static int VARIATION_SELECTOR_16 = 0xFE0F;
     32 
     33     public static int CANCEL_TAG = 0xE007F;
     34 
     35     /**
     36      * Returns true if the given code point is regional indicator symbol.
     37      */
     38     public static boolean isRegionalIndicatorSymbol(int codePoint) {
     39         return 0x1F1E6 <= codePoint && codePoint <= 0x1F1FF;
     40     }
     41 
     42     /**
     43      * Returns true if the given code point is emoji modifier.
     44      */
     45     public static boolean isEmojiModifier(int codePoint) {
     46         return UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI_MODIFIER);
     47     }
     48 
     49     // Returns true if the given code point is emoji modifier base.
     50     public static boolean isEmojiModifierBase(int codePoint) {
     51         // These two characters were removed from Emoji_Modifier_Base in Emoji 4.0, but we need to
     52         // keep them as emoji modifier bases since there are fonts and user-generated text out there
     53         // that treats these as potential emoji bases.
     54         if (codePoint == 0x1F91D || codePoint == 0x1F93C) {
     55             return true;
     56         }
     57         // Emoji Modifier Base characters new in Unicode emoji 5.0.
     58         // From http://www.unicode.org/Public/emoji/5.0/emoji-data.txt
     59         // TODO: Remove once emoji-data.text 5.0 is in ICU or update to 6.0.
     60         if (codePoint == 0x1F91F
     61                 || (0x1F931 <= codePoint && codePoint <= 0x1F932)
     62                 || (0x1F9D1 <= codePoint && codePoint <= 0x1F9DD)) {
     63             return true;
     64         }
     65         return UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI_MODIFIER_BASE);
     66     }
     67 
     68     /**
     69      * Returns true if the character is a new emoji still not supported in our version of ICU.
     70      */
     71     public static boolean isNewEmoji(int codePoint) {
     72         // Emoji characters new in Unicode emoji 5.0.
     73         // From http://www.unicode.org/Public/emoji/5.0/emoji-data.txt
     74         // TODO: Remove once emoji-data.text 5.0 is in ICU or update to 6.0.
     75         if (codePoint < 0x1F6F7 || codePoint > 0x1F9E6) {
     76             // Optimization for characters outside the new emoji range.
     77             return false;
     78         }
     79         return (0x1F6F7 <= codePoint && codePoint <= 0x1F6F8)
     80                 || codePoint == 0x1F91F
     81                 || (0x1F928 <= codePoint && codePoint <= 0x1F92F)
     82                 || (0x1F931 <= codePoint && codePoint <= 0x1F932)
     83                 || codePoint == 0x1F94C
     84                 || (0x1F95F <= codePoint && codePoint <= 0x1F96B)
     85                 || (0x1F992 <= codePoint && codePoint <= 0x1F997)
     86                 || (0x1F9D0 <= codePoint && codePoint <= 0x1F9E6);
     87     }
     88 
     89     /**
     90      * Returns true if the character has Emoji property.
     91      */
     92     public static boolean isEmoji(int codePoint) {
     93         return isNewEmoji(codePoint) || UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI);
     94     }
     95 
     96     // Returns true if the character can be a base character of COMBINING ENCLOSING KEYCAP.
     97     public static boolean isKeycapBase(int codePoint) {
     98         return ('0' <= codePoint && codePoint <= '9') || codePoint == '#' || codePoint == '*';
     99     }
    100 
    101     /**
    102      * Returns true if the character can be a part of tag_spec in emoji tag sequence.
    103      *
    104      * Note that 0xE007F (CANCEL TAG) is not included.
    105      */
    106     public static boolean isTagSpecChar(int codePoint) {
    107         return 0xE0020 <= codePoint && codePoint <= 0xE007E;
    108     }
    109 }
    110