182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Licensed under the Apache License, Version 2.0 (the "License"); 582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * you may not use this file except in compliance with the License. 682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * You may obtain a copy of the License at 782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * http://www.apache.org/licenses/LICENSE-2.0 982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 1082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Unless required by applicable law or agreed to in writing, software 1182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * distributed under the License is distributed on an "AS IS" BASIS, 1282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * See the License for the specific language governing permissions and 1482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * limitations under the License. 1582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.emoji.text; 1782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 18ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 1982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 2082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.graphics.Canvas; 2182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.graphics.Paint; 223dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinirimport android.graphics.Typeface; 2338746a682208c764867ffe4415d0b62fb22b5b9aAurimas Liutikas 24ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.AnyThread; 25ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.IntDef; 26ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.IntRange; 27ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.NonNull; 28ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RequiresApi; 29ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RestrictTo; 3038746a682208c764867ffe4415d0b62fb22b5b9aAurimas Liutikasimport androidx.text.emoji.flatbuffer.MetadataItem; 3138746a682208c764867ffe4415d0b62fb22b5b9aAurimas Liutikasimport androidx.text.emoji.flatbuffer.MetadataList; 3282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 3382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport java.lang.annotation.Retention; 3482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport java.lang.annotation.RetentionPolicy; 3582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 3682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir/** 3782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Information about a single emoji. 3882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 3982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @hide 4082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 4182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir@RestrictTo(LIBRARY_GROUP) 4282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir@AnyThread 4377b5c5b734f9f665577d1e3d178615db43ae1d4fSiyamed Sinir@RequiresApi(19) 4482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirpublic class EmojiMetadata { 4582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 4682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Defines whether the system can render the emoji. 4782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 4882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @IntDef({HAS_GLYPH_UNKNOWN, HAS_GLYPH_ABSENT, HAS_GLYPH_EXISTS}) 4982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @Retention(RetentionPolicy.SOURCE) 5082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public @interface HasGlyph { 5182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 5282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 5382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 5482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Not calculated on device yet. 5582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 5682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public static final int HAS_GLYPH_UNKNOWN = 0; 5782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 5882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 5982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Device cannot render the emoji. 6082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 6182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public static final int HAS_GLYPH_ABSENT = 1; 6282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 6382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 6482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Device can render the emoji. 6582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 6682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public static final int HAS_GLYPH_EXISTS = 2; 6782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 6882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 6982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @see #getMetadataItem() 7082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 7182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir private static final ThreadLocal<MetadataItem> sMetadataItem = new ThreadLocal<>(); 7282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 7382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 7482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Index of the EmojiMetadata in {@link MetadataList}. 7582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 7682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir private final int mIndex; 7782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 7882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 7982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * MetadataRepo that holds this instance. 8082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 8182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir private final MetadataRepo mMetadataRepo; 8282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 8382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 8482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Whether the system can render the emoji. Calculated at runtime on the device. 8582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 8682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @HasGlyph 8782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir private volatile int mHasGlyph = HAS_GLYPH_UNKNOWN; 8882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 8982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir EmojiMetadata(@NonNull final MetadataRepo metadataRepo, @IntRange(from = 0) final int index) { 9082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir mMetadataRepo = metadataRepo; 9182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir mIndex = index; 9282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 9382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 9482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 9582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Draws the emoji represented by this EmojiMetadata onto a canvas with origin at (x,y), using 9682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * the specified paint. 9782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 9882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @param canvas Canvas to be drawn 9982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @param x x-coordinate of the origin of the emoji being drawn 10082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @param y y-coordinate of the baseline of the emoji being drawn 10182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @param paint Paint used for the text (e.g. color, size, style) 10282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 10382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public void draw(@NonNull final Canvas canvas, final float x, final float y, 10482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @NonNull final Paint paint) { 1053dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final Typeface typeface = mMetadataRepo.getTypeface(); 1063dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final Typeface oldTypeface = paint.getTypeface(); 1073dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir paint.setTypeface(typeface); 10882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // MetadataRepo.getEmojiCharArray() is a continous array of chars that is used to store the 10982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // chars for emojis. since all emojis are mapped to a single codepoint, and since it is 2 11082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // chars wide, we assume that the start index of the current emoji is mIndex * 2, and it is 11182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // 2 chars long. 11282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final int charArrayStartIndex = mIndex * 2; 11382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir canvas.drawText(mMetadataRepo.getEmojiCharArray(), charArrayStartIndex, 2, x, y, paint); 1143dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir paint.setTypeface(oldTypeface); 11582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 11682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 11782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 118478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir * @return return typeface to be used to render this metadata 119478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir */ 120478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir public Typeface getTypeface() { 121478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir return mMetadataRepo.getTypeface(); 122478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir } 123478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir 124478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir /** 12582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return a ThreadLocal instance of MetadataItem for this EmojiMetadata 12682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 12782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir private MetadataItem getMetadataItem() { 12882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir MetadataItem result = sMetadataItem.get(); 12982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir if (result == null) { 13082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir result = new MetadataItem(); 13182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir sMetadataItem.set(result); 13282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 13382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // MetadataList is a wrapper around the metadata ByteBuffer. MetadataItem is a wrapper with 13482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // an index (pointer) on this ByteBuffer that represents a single emoji. Both are FlatBuffer 13582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // classes that wraps a ByteBuffer and gives access to the information in it. In order not 13682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // to create a wrapper class for each EmojiMetadata, we use mIndex as the index of the 13782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // MetadataItem in the ByteBuffer. We need to reiniitalize the current thread local instance 13882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // by executing the statement below. All the statement does is to set an int index in 13982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // MetadataItem. the same instance is used by all EmojiMetadata classes in the same thread. 14082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir mMetadataRepo.getMetadataList().list(result, mIndex); 14182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return result; 14282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 14382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 14482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 14582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return unique id for the emoji 14682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 14782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public int getId() { 14882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return getMetadataItem().id(); 14982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 15082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 15182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 15282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return width of the emoji image 15382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 15482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public short getWidth() { 15582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return getMetadataItem().width(); 15682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 15782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 15882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 15982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return height of the emoji image 16082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 16182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public short getHeight() { 16282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return getMetadataItem().height(); 16382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 16482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 16582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 16682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return in which metadata version the emoji was added to metadata 16782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 16882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public short getCompatAdded() { 16982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return getMetadataItem().compatAdded(); 17082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 17182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 17282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 17382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return first SDK that the support for this emoji was added 17482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 17582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public short getSdkAdded() { 17682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return getMetadataItem().sdkAdded(); 17782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 17882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 17982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 18082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return whether the emoji is in Emoji Presentation by default (without emoji 18182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * style selector 0xFE0F) 18282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 18382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @HasGlyph 18482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public int getHasGlyph() { 18582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return mHasGlyph; 18682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 18782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 18882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 18982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Set whether the system can render the emoji. 19082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 19182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @param hasGlyph {@code true} if system can render the emoji 19282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 19382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public void setHasGlyph(boolean hasGlyph) { 19482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir mHasGlyph = hasGlyph ? HAS_GLYPH_EXISTS : HAS_GLYPH_ABSENT; 19582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 19682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 19782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 19882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return whether the emoji is in Emoji Presentation by default (without emoji 19982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * style selector 0xFE0F) 20082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 20182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public boolean isDefaultEmoji() { 20282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return getMetadataItem().emojiStyle(); 20382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 20482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 20582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 20682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @param index index of the codepoint 20782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 20882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return the codepoint at index 20982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 21082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public int getCodepointAt(int index) { 21182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return getMetadataItem().codepoints(index); 21282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 21382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 21482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 21582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * @return the length of the codepoints for this emoji 21682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 21782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public int getCodepointsLength() { 21882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return getMetadataItem().codepointsLength(); 21982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 22082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 221478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir @Override 222478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir public String toString() { 223478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir final StringBuilder builder = new StringBuilder(); 224478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir builder.append(super.toString()); 225478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir builder.append(", id:"); 226478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir builder.append(Integer.toHexString(getId())); 227478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir builder.append(", codepoints:"); 228478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir final int codepointsLength = getCodepointsLength(); 229478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir for (int i = 0; i < codepointsLength; i++) { 230478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir builder.append(Integer.toHexString(getCodepointAt(i))); 231478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir builder.append(" "); 232478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir } 233478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir return builder.toString(); 234478b4ffdd939482869779da95c45b259771a620bSiyamed Sinir } 23582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir} 236