Start offset for backspace key or moving left from the current offset. Same methods are also included in Android APIs but they don't work as expected in API Levels lower than 24. Reference for the logic in this code is the Android source code.
Following if statements for Emoji tag sequence and Variation selector are skipping these modifiers for going through the last statement that is for handling emojis. They return the offset if they don't find proper base characters
57 {
59 return 0;
60 }
61
62 int codePoint = Character.codePointBefore(
text,
offset);
63 int deleteCharCount = Character.charCount(codePoint);
64 int lastOffset =
offset - deleteCharCount;
65
66 if (lastOffset == 0) {
67 return 0;
68 }
69
70
72 codePoint = Character.codePointBefore(
text, lastOffset);
74 ++deleteCharCount;
75 }
76 return offset - deleteCharCount;
77 }
78
79
81 codePoint = Character.codePointBefore(
text, lastOffset);
82 lastOffset -= Character.charCount(codePoint);
83 int regionalIndicatorSymbolCount = 1;
85 codePoint = Character.codePointBefore(
text, lastOffset);
86 lastOffset -= Character.charCount(codePoint);
87 regionalIndicatorSymbolCount++;
88 }
89 if (regionalIndicatorSymbolCount % 2 == 0) {
90 deleteCharCount += 2;
91 }
92 return offset - deleteCharCount;
93 }
94
95
97 codePoint = Character.codePointBefore(
text, lastOffset);
98 lastOffset -= Character.charCount(codePoint);
100 int tmpCodePoint = Character.codePointBefore(
text, lastOffset);
102 deleteCharCount += Character.charCount(codePoint) + Character.charCount(tmpCodePoint);
103 }
105 deleteCharCount += Character.charCount(codePoint);
106 }
107 return offset - deleteCharCount;
108 }
109
110
111
112
113
114
115
117 codePoint = Character.codePointBefore(
text, lastOffset);
118 lastOffset -= Character.charCount(codePoint);
120 deleteCharCount += Character.charCount(codePoint);
121 codePoint = Character.codePointBefore(
text, lastOffset);
122 lastOffset -= Character.charCount(codePoint);
123 }
126 }
127 deleteCharCount += Character.charCount(codePoint);
128 }
129
131 codePoint = Character.codePointBefore(
text, lastOffset);
133 return offset - deleteCharCount;
134 }
135 deleteCharCount += Character.charCount(codePoint);
136
137 lastOffset -= deleteCharCount;
138 }
139
141 boolean isZwj = false;
142 int lastSeenVariantSelectorCharCount = 0;
143 do {
144 if (isZwj) {
145 deleteCharCount += Character.charCount(codePoint) + lastSeenVariantSelectorCharCount + 1;
146 isZwj = false;
147 }
148 lastSeenVariantSelectorCharCount = 0;
150 codePoint = Character.codePointBefore(
text, lastOffset);
151 lastOffset -= Character.charCount(codePoint);
153 codePoint = Character.codePointBefore(
text, lastOffset);
155 return offset - deleteCharCount;
156 }
157 lastSeenVariantSelectorCharCount = Character.charCount(codePoint);
158 lastOffset -= Character.charCount(codePoint);
159 }
161 deleteCharCount += lastSeenVariantSelectorCharCount + Character.charCount(codePoint);
162 }
163 break;
164 }
165
166 if (lastOffset > 0) {
167 codePoint = Character.codePointBefore(
text, lastOffset);
168 lastOffset -= Character.charCount(codePoint);
170 isZwj = true;
171 codePoint = Character.codePointBefore(
text, lastOffset);
172 lastOffset -= Character.charCount(codePoint);
174 codePoint = Character.codePointBefore(
text, lastOffset);
175 lastSeenVariantSelectorCharCount = Character.charCount(codePoint);
176 lastOffset -= Character.charCount(codePoint);
177 }
178 }
179 }
180
181 if (lastOffset == 0) {
182 break;
183 }
184 }
while (isZwj &&
isEmoji(codePoint));
185 }
186
187 return offset - deleteCharCount;
188 }
boolean isEmojiModifierBase(int codePoint)
static final int CANCEL_TAG
boolean isTagSpecChar(int codePoint)