1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * License for the specific language governing permissions and limitations under 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.text; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.text.AttributedCharacterIterator.Attribute; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashMap; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashSet; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ListIterator; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Map; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Set; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Holds a string with attributes describing the characters of 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this string. 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class AttributedString { 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String text; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map<AttributedCharacterIterator.Attribute, List<Range>> attributeMap; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static class Range { 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int start; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end; 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object value; 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Range(int s, int e, Object v) { 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start = s; 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end = e; 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project value = v; 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static class AttributedIterator implements AttributedCharacterIterator { 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int begin, end, offset; 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AttributedString attrString; 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private HashSet<Attribute> attributesAllowed; 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedIterator(AttributedString attrString) { 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.attrString = attrString; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin = 0; 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end = attrString.text.length(); 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = 0; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedIterator(AttributedString attrString, 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedCharacterIterator.Attribute[] attributes, int begin, 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end) { 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (begin < 0 || end > attrString.text.length() || begin > end) { 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.begin = begin; 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.end = end; 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = begin; 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.attrString = attrString; 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributes != null) { 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashSet<Attribute> set = new HashSet<Attribute>( 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (attributes.length * 4 / 3) + 1); 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = attributes.length; --i >= 0;) { 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project set.add(attributes[i]); 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributesAllowed = set; 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new {@code AttributedIterator} with the same source string, 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * begin, end, and current index as this attributed iterator. 93f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a shallow copy of this attributed iterator. 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.Cloneable 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object clone() { 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedIterator clone = (AttributedIterator) super.clone(); 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributesAllowed != null) { 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project clone.attributesAllowed = (HashSet<Attribute>) attributesAllowed 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .clone(); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return clone; 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (CloneNotSupportedException e) { 108fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes throw new AssertionError(e); 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public char current() { 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset == end) { 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return DONE; 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return attrString.text.charAt(offset); 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public char first() { 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (begin == end) { 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return DONE; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = begin; 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return attrString.text.charAt(offset); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the begin index in the source string. 129f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the index of the first character to iterate. 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getBeginIndex() { 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return begin; 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the end index in the source String. 138f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the index one past the last character to iterate. 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getEndIndex() { 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return end; 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the current index in the source String. 147f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the current index. 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getIndex() { 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return offset; 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean inRange(Range range) { 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(range.value instanceof Annotation)) { 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return range.start >= begin && range.start < end 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && range.end > begin && range.end <= end; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean inRange(List<Range> ranges) { 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<Range> it = ranges.iterator(); 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Range range = it.next(); 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (range.start >= begin && range.start < end) { 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return !(range.value instanceof Annotation) 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || (range.end > begin && range.end <= end); 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (range.end > begin && range.end <= end) { 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return !(range.value instanceof Annotation) 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || (range.start >= begin && range.start < end); 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a set of attributes present in the {@code AttributedString}. 1799b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * An empty set returned indicates that no attributes where defined. 1809b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a set of attribute keys that may be empty. 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<AttributedIterator.Attribute> getAllAttributeKeys() { 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (begin == 0 && end == attrString.text.length() 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && attributesAllowed == null) { 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return attrString.attributeMap.keySet(); 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Set<AttributedIterator.Attribute> result = new HashSet<Attribute>( 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (attrString.attributeMap.size() * 4 / 3) + 1); 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<Map.Entry<Attribute, List<Range>>> it = attrString.attributeMap 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .entrySet().iterator(); 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry<Attribute, List<Range>> entry = it.next(); 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributesAllowed == null 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || attributesAllowed.contains(entry.getKey())) { 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<Range> ranges = entry.getValue(); 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (inRange(ranges)) { 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(entry.getKey()); 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object currentValue(List<Range> ranges) { 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<Range> it = ranges.iterator(); 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Range range = it.next(); 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset >= range.start && offset < range.end) { 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return inRange(range) ? range.value : null; 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object getAttribute( 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedCharacterIterator.Attribute attribute) { 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributesAllowed != null 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && !attributesAllowed.contains(attribute)) { 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ArrayList<Range> ranges = (ArrayList<Range>) attrString.attributeMap 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .get(attribute); 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ranges == null) { 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return currentValue(ranges); 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Map<Attribute, Object> getAttributes() { 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map<Attribute, Object> result = new HashMap<Attribute, Object>( 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (attrString.attributeMap.size() * 4 / 3) + 1); 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<Map.Entry<Attribute, List<Range>>> it = attrString.attributeMap 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .entrySet().iterator(); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry<Attribute, List<Range>> entry = it.next(); 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributesAllowed == null 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || attributesAllowed.contains(entry.getKey())) { 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object value = currentValue(entry.getValue()); 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value != null) { 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.put(entry.getKey(), value); 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getRunLimit() { 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getRunLimit(getAllAttributeKeys()); 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int runLimit(List<Range> ranges) { 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = end; 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ListIterator<Range> it = ranges.listIterator(ranges.size()); 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasPrevious()) { 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Range range = it.previous(); 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (range.end <= begin) { 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset >= range.start && offset < range.end) { 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return inRange(range) ? range.end : result; 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (offset >= range.end) { 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = range.start; 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getRunLimit(AttributedCharacterIterator.Attribute attribute) { 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributesAllowed != null 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && !attributesAllowed.contains(attribute)) { 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return end; 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ArrayList<Range> ranges = (ArrayList<Range>) attrString.attributeMap 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .get(attribute); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ranges == null) { 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return end; 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return runLimit(ranges); 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getRunLimit(Set<? extends Attribute> attributes) { 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int limit = end; 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<? extends Attribute> it = attributes.iterator(); 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedCharacterIterator.Attribute attribute = it.next(); 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int newLimit = getRunLimit(attribute); 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (newLimit < limit) { 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project limit = newLimit; 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return limit; 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getRunStart() { 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getRunStart(getAllAttributeKeys()); 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int runStart(List<Range> ranges) { 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = begin; 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<Range> it = ranges.iterator(); 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Range range = it.next(); 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (range.start >= end) { 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset >= range.start && offset < range.end) { 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return inRange(range) ? range.start : result; 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (offset < range.start) { 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = range.end; 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getRunStart(AttributedCharacterIterator.Attribute attribute) { 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributesAllowed != null 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && !attributesAllowed.contains(attribute)) { 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return begin; 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ArrayList<Range> ranges = (ArrayList<Range>) attrString.attributeMap 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .get(attribute); 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ranges == null) { 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return begin; 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return runStart(ranges); 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getRunStart(Set<? extends Attribute> attributes) { 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int start = begin; 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<? extends Attribute> it = attributes.iterator(); 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedCharacterIterator.Attribute attribute = it.next(); 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int newStart = getRunStart(attribute); 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (newStart > start) { 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start = newStart; 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return start; 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public char last() { 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (begin == end) { 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return DONE; 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = end - 1; 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return attrString.text.charAt(offset); 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public char next() { 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset >= (end - 1)) { 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = end; 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return DONE; 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return attrString.text.charAt(++offset); 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public char previous() { 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset == begin) { 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return DONE; 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return attrString.text.charAt(--offset); 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public char setIndex(int location) { 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (location < begin || location > end) { 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = location; 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset == end) { 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return DONE; 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return attrString.text.charAt(offset); 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs an {@code AttributedString} from an {@code 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * AttributedCharacterIterator}, which represents attributed text. 3839b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param iterator 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code AttributedCharacterIterator} that contains the text 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for this attributed string. 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AttributedString(AttributedCharacterIterator iterator) { 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (iterator.getBeginIndex() > iterator.getEndIndex()) { 39003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Invalid substring range"); 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3929b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson StringBuilder buffer = new StringBuilder(); 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = iterator.getBeginIndex(); i < iterator.getEndIndex(); i++) { 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.append(iterator.current()); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project iterator.next(); 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project text = buffer.toString(); 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Set<AttributedCharacterIterator.Attribute> attributes = iterator 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getAllAttributeKeys(); 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributes == null) { 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributeMap = new HashMap<Attribute, List<Range>>( 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (attributes.size() * 4 / 3) + 1); 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<Attribute> it = attributes.iterator(); 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedCharacterIterator.Attribute attribute = it.next(); 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project iterator.setIndex(0); 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (iterator.current() != CharacterIterator.DONE) { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int start = iterator.getRunStart(attribute); 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int limit = iterator.getRunLimit(attribute); 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object value = iterator.getAttribute(attribute); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value != null) { 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project addAttribute(attribute, value, start, limit); 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project iterator.setIndex(limit); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AttributedString(AttributedCharacterIterator iterator, int start, 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end, Set<Attribute> attributes) { 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start < iterator.getBeginIndex() || end > iterator.getEndIndex() 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || start > end) { 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributes == null) { 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 4339b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson StringBuilder buffer = new StringBuilder(); 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project iterator.setIndex(start); 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (iterator.getIndex() < end) { 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.append(iterator.current()); 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project iterator.next(); 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project text = buffer.toString(); 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributeMap = new HashMap<Attribute, List<Range>>( 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (attributes.size() * 4 / 3) + 1); 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<Attribute> it = attributes.iterator(); 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedCharacterIterator.Attribute attribute = it.next(); 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project iterator.setIndex(start); 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (iterator.getIndex() < end) { 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object value = iterator.getAttribute(attribute); 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int runStart = iterator.getRunStart(attribute); 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int limit = iterator.getRunLimit(attribute); 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((value instanceof Annotation && runStart >= start && limit <= end) 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || (value != null && !(value instanceof Annotation))) { 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project addAttribute(attribute, value, (runStart < start ? start 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project : runStart) 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project - start, (limit > end ? end : limit) - start); 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project iterator.setIndex(limit); 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs an {@code AttributedString} from a range of the text contained 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in the specified {@code AttributedCharacterIterator}, starting at {@code 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * start} and ending at {@code end}. All attributes will be copied to this 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * attributed string. 4679b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param iterator 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code AttributedCharacterIterator} that contains the text 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for this attributed string. 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param start 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the start index of the range of the copied text. 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param end 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the end index of the range of the copied text. 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 4769b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * if {@code start} is less than first index of 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code iterator}, {@code end} is greater than the last 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * index + 1 in {@code iterator} or if {@code start > end}. 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AttributedString(AttributedCharacterIterator iterator, int start, 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end) { 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(iterator, start, end, iterator.getAllAttributeKeys()); 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs an {@code AttributedString} from a range of the text contained 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in the specified {@code AttributedCharacterIterator}, starting at {@code 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * start}, ending at {@code end} and it will copy the attributes defined in 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the specified set. If the set is {@code null} then all attributes are 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * copied. 4919b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param iterator 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code AttributedCharacterIterator} that contains the text 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for this attributed string. 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param start 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the start index of the range of the copied text. 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param end 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the end index of the range of the copied text. 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attributes 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the set of attributes that will be copied, or all if it is 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null}. 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 5039b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * if {@code start} is less than first index of 5049b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * {@code iterator}, {@code end} is greater than the last index + 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1 in {@code iterator} or if {@code start > end}. 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AttributedString(AttributedCharacterIterator iterator, int start, 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end, AttributedCharacterIterator.Attribute[] attributes) { 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(iterator, start, end, (attributes == null 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ? new HashSet<Attribute>() 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project : new HashSet<Attribute>(Arrays.asList(attributes)))); 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an {@code AttributedString} from the given text. 5169b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the text to take as base for this attributed string. 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AttributedString(String value) { 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) { 52286acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("value == null"); 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project text = value; 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributeMap = new HashMap<Attribute, List<Range>>(11); 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an {@code AttributedString} from the given text and the 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * attributes. The whole text has the given attributes applied. 5319b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the text to take as base for this attributed string. 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attributes 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the attributes that the text is associated with. 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the length of {@code value} is 0 but the size of {@code 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * attributes} is greater than 0. 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code value} is {@code null}. 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AttributedString(String value, 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map<? extends AttributedCharacterIterator.Attribute, ?> attributes) { 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) { 54586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("value == null"); 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value.length() == 0 && !attributes.isEmpty()) { 54803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Cannot add attributes to empty string"); 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project text = value; 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributeMap = new HashMap<Attribute, List<Range>>( 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (attributes.size() * 4 / 3) + 1); 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<?> it = attributes.entrySet().iterator(); 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next(); 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ArrayList<Range> ranges = new ArrayList<Range>(1); 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ranges.add(new Range(0, text.length(), entry.getValue())); 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributeMap.put((AttributedCharacterIterator.Attribute) entry 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getKey(), ranges); 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Applies a given attribute to this string. 5659b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attribute 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the attribute that will be applied to this string. 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the value of the attribute that will be applied to this 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * string. 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the length of this attributed string is 0. 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code attribute} is {@code null}. 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 576b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes public void addAttribute(AttributedCharacterIterator.Attribute attribute, Object value) { 577b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (attribute == null) { 57886acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("attribute == null"); 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (text.length() == 0) { 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<Range> ranges = attributeMap.get(attribute); 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ranges == null) { 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ranges = new ArrayList<Range>(1); 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributeMap.put(attribute, ranges); 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ranges.clear(); 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ranges.add(new Range(0, text.length(), value)); 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Applies a given attribute to the given range of this string. 5969b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attribute 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the attribute that will be applied to this string. 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the value of the attribute that will be applied to this 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * string. 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param start 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the start of the range where the attribute will be applied. 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param end 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the end of the range where the attribute will be applied. 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code start < 0}, {@code end} is greater than the length 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this string, or if {@code start >= end}. 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code attribute} is {@code null}. 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addAttribute(AttributedCharacterIterator.Attribute attribute, 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object value, int start, int end) { 614b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (attribute == null) { 61586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("attribute == null"); 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start < 0 || end > text.length() || start >= end) { 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) { 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<Range> ranges = attributeMap.get(attribute); 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ranges == null) { 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ranges = new ArrayList<Range>(1); 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ranges.add(new Range(start, end, value)); 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributeMap.put(attribute, ranges); 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ListIterator<Range> it = ranges.listIterator(); 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Range range = it.next(); 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (end <= range.start) { 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.previous(); 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (start < range.end 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || (start == range.end && value.equals(range.value))) { 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Range r1 = null, r3; 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.remove(); 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project r1 = new Range(range.start, start, range.value); 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project r3 = new Range(end, range.end, range.value); 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (end > range.end && it.hasNext()) { 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project range = it.next(); 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (end <= range.end) { 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (end > range.start 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || (end == range.start && value.equals(range.value))) { 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.remove(); 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project r3 = new Range(end, range.end, range.value); 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.remove(); 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value.equals(r1.value)) { 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value.equals(r3.value)) { 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(new Range(r1.start < start ? r1.start : start, 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project r3.end > end ? r3.end : end, r1.value)); 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(new Range(r1.start < start ? r1.start : start, 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end, r1.value)); 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (r3.start < r3.end) { 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(r3); 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value.equals(r3.value)) { 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (r1.start < r1.end) { 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(r1); 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(new Range(start, r3.end > end ? r3.end : end, 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project r3.value)); 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (r1.start < r1.end) { 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(r1); 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(new Range(start, end, value)); 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (r3.start < r3.end) { 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(r3); 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it.add(new Range(start, end, value)); 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Applies a given set of attributes to the given range of the string. 6959b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attributes 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the set of attributes that will be applied to this string. 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param start 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the start of the range where the attribute will be applied. 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param end 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the end of the range where the attribute will be applied. 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code start < 0}, {@code end} is greater than the length 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this string, or if {@code start >= end}. 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addAttributes( 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map<? extends AttributedCharacterIterator.Attribute, ?> attributes, 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int start, int end) { 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<?> it = attributes.entrySet().iterator(); 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next(); 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project addAttribute( 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (AttributedCharacterIterator.Attribute) entry.getKey(), 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project entry.getValue(), start, end); 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an {@code AttributedCharacterIterator} that gives access to the 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * complete content of this attributed string. 7219b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the newly created {@code AttributedCharacterIterator}. 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AttributedCharacterIterator getIterator() { 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new AttributedIterator(this); 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an {@code AttributedCharacterIterator} that gives access to the 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * complete content of this attributed string. Only attributes contained in 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code attributes} are available from this iterator if they are defined 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for this text. 7339b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attributes 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the array containing attributes that will be in the new 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * iterator if they are defined for this text. 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the newly created {@code AttributedCharacterIterator}. 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AttributedCharacterIterator getIterator( 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedCharacterIterator.Attribute[] attributes) { 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new AttributedIterator(this, attributes, 0, text.length()); 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an {@code AttributedCharacterIterator} that gives access to the 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contents of this attributed string starting at index {@code start} up to 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * index {@code end}. Only attributes contained in {@code attributes} are 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available from this iterator if they are defined for this text. 7499b354e75f2418e54638e02d153216660b67d01b8Jesse Wilson * 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attributes 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the array containing attributes that will be in the new 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * iterator if they are defined for this text. 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param start 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the start index of the iterator on the underlying text. 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param end 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the end index of the iterator on the underlying text. 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the newly created {@code AttributedCharacterIterator}. 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AttributedCharacterIterator getIterator( 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AttributedCharacterIterator.Attribute[] attributes, int start, 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end) { 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new AttributedIterator(this, attributes, start, end); 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 765