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; 18 19 // XXX should this really be in the public API at all? 20 /** 21 * An AlteredCharSequence is a CharSequence that is largely mirrored from 22 * another CharSequence, except that a specified range of characters are 23 * mirrored from a different char array instead. 24 */ 25 public class AlteredCharSequence 26 implements CharSequence, GetChars 27 { 28 /** 29 * Create an AlteredCharSequence whose text (and possibly spans) 30 * are mirrored from <code>source</code>, except that the range of 31 * offsets <code>substart</code> inclusive to <code>subend</code> exclusive 32 * are mirrored instead from <code>sub</code>, beginning at offset 0. 33 */ 34 public static AlteredCharSequence make(CharSequence source, char[] sub, 35 int substart, int subend) { 36 if (source instanceof Spanned) 37 return new AlteredSpanned(source, sub, substart, subend); 38 else 39 return new AlteredCharSequence(source, sub, substart, subend); 40 } 41 42 private AlteredCharSequence(CharSequence source, char[] sub, 43 int substart, int subend) { 44 mSource = source; 45 mChars = sub; 46 mStart = substart; 47 mEnd = subend; 48 } 49 50 /* package */ void update(char[] sub, int substart, int subend) { 51 mChars = sub; 52 mStart = substart; 53 mEnd = subend; 54 } 55 56 private static class AlteredSpanned 57 extends AlteredCharSequence 58 implements Spanned 59 { 60 private AlteredSpanned(CharSequence source, char[] sub, 61 int substart, int subend) { 62 super(source, sub, substart, subend); 63 mSpanned = (Spanned) source; 64 } 65 66 public <T> T[] getSpans(int start, int end, Class<T> kind) { 67 return mSpanned.getSpans(start, end, kind); 68 } 69 70 public int getSpanStart(Object span) { 71 return mSpanned.getSpanStart(span); 72 } 73 74 public int getSpanEnd(Object span) { 75 return mSpanned.getSpanEnd(span); 76 } 77 78 public int getSpanFlags(Object span) { 79 return mSpanned.getSpanFlags(span); 80 } 81 82 public int nextSpanTransition(int start, int end, Class kind) { 83 return mSpanned.nextSpanTransition(start, end, kind); 84 } 85 86 private Spanned mSpanned; 87 } 88 89 public char charAt(int off) { 90 if (off >= mStart && off < mEnd) 91 return mChars[off - mStart]; 92 else 93 return mSource.charAt(off); 94 } 95 96 public int length() { 97 return mSource.length(); 98 } 99 100 public CharSequence subSequence(int start, int end) { 101 return AlteredCharSequence.make(mSource.subSequence(start, end), 102 mChars, mStart - start, mEnd - start); 103 } 104 105 public void getChars(int start, int end, char[] dest, int off) { 106 TextUtils.getChars(mSource, start, end, dest, off); 107 108 start = Math.max(mStart, start); 109 end = Math.min(mEnd, end); 110 111 if (start > end) 112 System.arraycopy(mChars, start - mStart, dest, off, end - start); 113 } 114 115 public String toString() { 116 int len = length(); 117 118 char[] ret = new char[len]; 119 getChars(0, len, ret, 0); 120 return String.valueOf(ret); 121 } 122 123 private int mStart; 124 private int mEnd; 125 private char[] mChars; 126 private CharSequence mSource; 127 } 128