• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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.method;
18 
19 import android.graphics.Rect;
20 import android.text.Editable;
21 import android.text.GetChars;
22 import android.text.Spannable;
23 import android.text.Spanned;
24 import android.text.SpannedString;
25 import android.text.TextUtils;
26 import android.view.View;
27 
28 /**
29  * This transformation method causes the characters in the {@link #getOriginal}
30  * array to be replaced by the corresponding characters in the
31  * {@link #getReplacement} array.
32  */
33 @android.ravenwood.annotation.RavenwoodKeepWholeClass
34 public abstract class ReplacementTransformationMethod
35 implements TransformationMethod
36 {
37     /**
38      * Returns the list of characters that are to be replaced by other
39      * characters when displayed.
40      */
getOriginal()41     protected abstract char[] getOriginal();
42     /**
43      * Returns a parallel array of replacement characters for the ones
44      * that are to be replaced.
45      */
getReplacement()46     protected abstract char[] getReplacement();
47 
48     /**
49      * Returns a CharSequence that will mirror the contents of the
50      * source CharSequence but with the characters in {@link #getOriginal}
51      * replaced by ones from {@link #getReplacement}.
52      */
getTransformation(CharSequence source, View v)53     public CharSequence getTransformation(CharSequence source, View v) {
54         char[] original = getOriginal();
55         char[] replacement = getReplacement();
56 
57         /*
58          * Short circuit for faster display if the text will never change.
59          */
60         if (!(source instanceof Editable)) {
61             /*
62              * Check whether the text does not contain any of the
63              * source characters so can be used unchanged.
64              */
65             boolean doNothing = true;
66             int n = original.length;
67             for (int i = 0; i < n; i++) {
68                 if (TextUtils.indexOf(source, original[i]) >= 0) {
69                     doNothing = false;
70                     break;
71                 }
72             }
73             if (doNothing) {
74                 return source;
75             }
76 
77             if (!(source instanceof Spannable)) {
78                 /*
79                  * The text contains some of the source characters,
80                  * but they can be flattened out now instead of
81                  * at display time.
82                  */
83                 if (source instanceof Spanned) {
84                     return new SpannedString(new SpannedReplacementCharSequence(
85                                                         (Spanned) source,
86                                                         original, replacement));
87                 } else {
88                     return new ReplacementCharSequence(source,
89                                                        original,
90                                                        replacement).toString();
91                 }
92             }
93         }
94 
95         if (source instanceof Spanned) {
96             return new SpannedReplacementCharSequence((Spanned) source,
97                                                       original, replacement);
98         } else {
99             return new ReplacementCharSequence(source, original, replacement);
100         }
101     }
102 
onFocusChanged(View view, CharSequence sourceText, boolean focused, int direction, Rect previouslyFocusedRect)103     public void onFocusChanged(View view, CharSequence sourceText,
104                                boolean focused, int direction,
105                                Rect previouslyFocusedRect) {
106         // This callback isn't used.
107     }
108 
109     private static class ReplacementCharSequence
110     implements CharSequence, GetChars {
111         private char[] mOriginal, mReplacement;
112 
ReplacementCharSequence(CharSequence source, char[] original, char[] replacement)113         public ReplacementCharSequence(CharSequence source, char[] original,
114                                        char[] replacement) {
115             mSource = source;
116             mOriginal = original;
117             mReplacement = replacement;
118         }
119 
length()120         public int length() {
121             return mSource.length();
122         }
123 
charAt(int i)124         public char charAt(int i) {
125             char c = mSource.charAt(i);
126 
127             int n = mOriginal.length;
128             for (int j = 0; j < n; j++) {
129                 if (c == mOriginal[j]) {
130                     c = mReplacement[j];
131                 }
132             }
133 
134             return c;
135         }
136 
subSequence(int start, int end)137         public CharSequence subSequence(int start, int end) {
138             char[] c = new char[end - start];
139 
140             getChars(start, end, c, 0);
141             return new String(c);
142         }
143 
toString()144         public String toString() {
145             char[] c = new char[length()];
146 
147             getChars(0, length(), c, 0);
148             return new String(c);
149         }
150 
getChars(int start, int end, char[] dest, int off)151         public void getChars(int start, int end, char[] dest, int off) {
152             TextUtils.getChars(mSource, start, end, dest, off);
153             int offend = end - start + off;
154             int n = mOriginal.length;
155 
156             for (int i = off; i < offend; i++) {
157                 char c = dest[i];
158 
159                 for (int j = 0; j < n; j++) {
160                     if (c == mOriginal[j]) {
161                         dest[i] = mReplacement[j];
162                     }
163                 }
164             }
165         }
166 
167         private CharSequence mSource;
168     }
169 
170     private static class SpannedReplacementCharSequence
171     extends ReplacementCharSequence
172     implements Spanned
173     {
SpannedReplacementCharSequence(Spanned source, char[] original, char[] replacement)174         public SpannedReplacementCharSequence(Spanned source, char[] original,
175                                               char[] replacement) {
176             super(source, original, replacement);
177             mSpanned = source;
178         }
179 
subSequence(int start, int end)180         public CharSequence subSequence(int start, int end) {
181             return new SpannedString(this).subSequence(start, end);
182         }
183 
getSpans(int start, int end, Class<T> type)184         public <T> T[] getSpans(int start, int end, Class<T> type) {
185             return mSpanned.getSpans(start, end, type);
186         }
187 
getSpanStart(Object tag)188         public int getSpanStart(Object tag) {
189             return mSpanned.getSpanStart(tag);
190         }
191 
getSpanEnd(Object tag)192         public int getSpanEnd(Object tag) {
193             return mSpanned.getSpanEnd(tag);
194         }
195 
getSpanFlags(Object tag)196         public int getSpanFlags(Object tag) {
197             return mSpanned.getSpanFlags(tag);
198         }
199 
nextSpanTransition(int start, int end, Class type)200         public int nextSpanTransition(int start, int end, Class type) {
201             return mSpanned.nextSpanTransition(start, end, type);
202         }
203 
204         private Spanned mSpanned;
205     }
206 }
207