206 lines
6.6 KiB
Java
206 lines
6.6 KiB
Java
/*
|
|
* Copyright (C) 2006 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.text.method;
|
|
|
|
import android.graphics.Rect;
|
|
import android.text.Editable;
|
|
import android.text.GetChars;
|
|
import android.text.Spannable;
|
|
import android.text.Spanned;
|
|
import android.text.SpannedString;
|
|
import android.text.TextUtils;
|
|
import android.view.View;
|
|
|
|
/**
|
|
* This transformation method causes the characters in the {@link #getOriginal}
|
|
* array to be replaced by the corresponding characters in the
|
|
* {@link #getReplacement} array.
|
|
*/
|
|
public abstract class ReplacementTransformationMethod
|
|
implements TransformationMethod
|
|
{
|
|
/**
|
|
* Returns the list of characters that are to be replaced by other
|
|
* characters when displayed.
|
|
*/
|
|
protected abstract char[] getOriginal();
|
|
/**
|
|
* Returns a parallel array of replacement characters for the ones
|
|
* that are to be replaced.
|
|
*/
|
|
protected abstract char[] getReplacement();
|
|
|
|
/**
|
|
* Returns a CharSequence that will mirror the contents of the
|
|
* source CharSequence but with the characters in {@link #getOriginal}
|
|
* replaced by ones from {@link #getReplacement}.
|
|
*/
|
|
public CharSequence getTransformation(CharSequence source, View v) {
|
|
char[] original = getOriginal();
|
|
char[] replacement = getReplacement();
|
|
|
|
/*
|
|
* Short circuit for faster display if the text will never change.
|
|
*/
|
|
if (!(source instanceof Editable)) {
|
|
/*
|
|
* Check whether the text does not contain any of the
|
|
* source characters so can be used unchanged.
|
|
*/
|
|
boolean doNothing = true;
|
|
int n = original.length;
|
|
for (int i = 0; i < n; i++) {
|
|
if (TextUtils.indexOf(source, original[i]) >= 0) {
|
|
doNothing = false;
|
|
break;
|
|
}
|
|
}
|
|
if (doNothing) {
|
|
return source;
|
|
}
|
|
|
|
if (!(source instanceof Spannable)) {
|
|
/*
|
|
* The text contains some of the source characters,
|
|
* but they can be flattened out now instead of
|
|
* at display time.
|
|
*/
|
|
if (source instanceof Spanned) {
|
|
return new SpannedString(new SpannedReplacementCharSequence(
|
|
(Spanned) source,
|
|
original, replacement));
|
|
} else {
|
|
return new ReplacementCharSequence(source,
|
|
original,
|
|
replacement).toString();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (source instanceof Spanned) {
|
|
return new SpannedReplacementCharSequence((Spanned) source,
|
|
original, replacement);
|
|
} else {
|
|
return new ReplacementCharSequence(source, original, replacement);
|
|
}
|
|
}
|
|
|
|
public void onFocusChanged(View view, CharSequence sourceText,
|
|
boolean focused, int direction,
|
|
Rect previouslyFocusedRect) {
|
|
// This callback isn't used.
|
|
}
|
|
|
|
private static class ReplacementCharSequence
|
|
implements CharSequence, GetChars {
|
|
private char[] mOriginal, mReplacement;
|
|
|
|
public ReplacementCharSequence(CharSequence source, char[] original,
|
|
char[] replacement) {
|
|
mSource = source;
|
|
mOriginal = original;
|
|
mReplacement = replacement;
|
|
}
|
|
|
|
public int length() {
|
|
return mSource.length();
|
|
}
|
|
|
|
public char charAt(int i) {
|
|
char c = mSource.charAt(i);
|
|
|
|
int n = mOriginal.length;
|
|
for (int j = 0; j < n; j++) {
|
|
if (c == mOriginal[j]) {
|
|
c = mReplacement[j];
|
|
}
|
|
}
|
|
|
|
return c;
|
|
}
|
|
|
|
public CharSequence subSequence(int start, int end) {
|
|
char[] c = new char[end - start];
|
|
|
|
getChars(start, end, c, 0);
|
|
return new String(c);
|
|
}
|
|
|
|
public String toString() {
|
|
char[] c = new char[length()];
|
|
|
|
getChars(0, length(), c, 0);
|
|
return new String(c);
|
|
}
|
|
|
|
public void getChars(int start, int end, char[] dest, int off) {
|
|
TextUtils.getChars(mSource, start, end, dest, off);
|
|
int offend = end - start + off;
|
|
int n = mOriginal.length;
|
|
|
|
for (int i = off; i < offend; i++) {
|
|
char c = dest[i];
|
|
|
|
for (int j = 0; j < n; j++) {
|
|
if (c == mOriginal[j]) {
|
|
dest[i] = mReplacement[j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private CharSequence mSource;
|
|
}
|
|
|
|
private static class SpannedReplacementCharSequence
|
|
extends ReplacementCharSequence
|
|
implements Spanned
|
|
{
|
|
public SpannedReplacementCharSequence(Spanned source, char[] original,
|
|
char[] replacement) {
|
|
super(source, original, replacement);
|
|
mSpanned = source;
|
|
}
|
|
|
|
public CharSequence subSequence(int start, int end) {
|
|
return new SpannedString(this).subSequence(start, end);
|
|
}
|
|
|
|
public <T> T[] getSpans(int start, int end, Class<T> type) {
|
|
return mSpanned.getSpans(start, end, type);
|
|
}
|
|
|
|
public int getSpanStart(Object tag) {
|
|
return mSpanned.getSpanStart(tag);
|
|
}
|
|
|
|
public int getSpanEnd(Object tag) {
|
|
return mSpanned.getSpanEnd(tag);
|
|
}
|
|
|
|
public int getSpanFlags(Object tag) {
|
|
return mSpanned.getSpanFlags(tag);
|
|
}
|
|
|
|
public int nextSpanTransition(int start, int end, Class type) {
|
|
return mSpanned.nextSpanTransition(start, end, type);
|
|
}
|
|
|
|
private Spanned mSpanned;
|
|
}
|
|
}
|