KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > gvt > text > GVTACIImpl


1 /*
2
3    Copyright 2001,2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.gvt.text;
19
20 import java.text.AttributedCharacterIterator JavaDoc;
21 import java.text.AttributedString JavaDoc;
22 import java.text.CharacterIterator JavaDoc;
23 import java.text.StringCharacterIterator JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Set JavaDoc;
29
30 /**
31  * GVTACIImpl
32  *
33  * Used to implement SVG <tspan> and <text>
34  * attributes. This implementation is designed for efficient support
35  * of per-character attributes (i.e. single character attribute spans).
36  * It supports an extended set of TextAttributes, via inner class
37  * GVTAttributedCharacterIterator.TextAttributes.
38  *
39  * @author <a HREF="mailto:bill.haneman@ireland.sun.com">Bill Haneman</a>
40  * @version $Id: GVTACIImpl.java,v 1.5 2004/08/18 07:14:41 vhardy Exp $
41  */

42
43 public class GVTACIImpl
44                 implements GVTAttributedCharacterIterator {
45
46     private String JavaDoc simpleString;
47     private Set JavaDoc allAttributes;
48     private ArrayList JavaDoc mapList;
49     private static int START_RUN = 2;
50     private static int END_RUN = 3;
51     private static int MID_RUN = 1;
52     private static int SINGLETON = 0;
53     private int[] charInRun;
54     private CharacterIterator JavaDoc iter = null;
55     private int currentIndex = -1;
56
57     /**
58      * Constructs a new GVTAttributedCharacterIterator with no attributes
59      * and a null string.
60      */

61     public GVTACIImpl() {
62         simpleString = "";
63         buildAttributeTables();
64     }
65
66     /**
67      * Constructs a GVTACIImpl whose contents are
68      * equivalent to those of aci.
69      * This constructor creates a new copy of the source data in <tt>aci</tt>.
70      */

71     public GVTACIImpl(AttributedCharacterIterator JavaDoc aci) {
72         buildAttributeTables(aci);
73     }
74
75     /**
76      * Sets this iterator's contents to an unattributed copy of String s.
77      */

78     public void setString(String JavaDoc s) {
79         simpleString = s;
80         iter = new StringCharacterIterator JavaDoc(simpleString);
81         buildAttributeTables();
82     }
83
84     /**
85      * Assigns this iterator's contents to be equivalent to AttributedString s.
86      */

87     public void setString(AttributedString JavaDoc s) {
88         iter = s.getIterator();
89         buildAttributeTables((AttributedCharacterIterator JavaDoc) iter);
90     }
91
92     /**
93      * Sets values of a per-character attribute associated with the
94      * content string.
95      * Characters from <tt>beginIndex</tt> to <tt>endIndex</tt>
96      * (zero-offset) are assigned values for attribute key <tt>attr</tt>
97      * from the array <tt>attValues.</tt>
98      * If the length of attValues is less than character span
99      * <tt>(endIndex-beginIndex)</tt> the last value is duplicated;
100      * if attValues is longer than the character span
101      * the extra values are ignored.
102      * Note that if either beginIndex or endIndex are outside the bounds
103      * of the current character array they are clipped accordingly.
104      */

105     public void setAttributeArray
106         (GVTAttributedCharacterIterator.TextAttribute attr,
107          Object JavaDoc[] attValues, int beginIndex, int endIndex) {
108
109         beginIndex = Math.max(beginIndex, 0);
110         endIndex = Math.min(endIndex, simpleString.length());
111         if (charInRun[beginIndex] == END_RUN) {
112             if (charInRun[beginIndex - 1] == MID_RUN) {
113                 charInRun[beginIndex - 1] = END_RUN;
114             } else {
115                 charInRun[beginIndex - 1] = SINGLETON;
116             }
117         }
118         if (charInRun[endIndex + 1] == END_RUN) {
119             charInRun[endIndex + 1] = SINGLETON;
120         } else if (charInRun[endIndex + 1] == MID_RUN) {
121             charInRun[endIndex + 1] = START_RUN;
122         }
123         for (int i = beginIndex; i <= endIndex; ++i) {
124             charInRun[i] = SINGLETON;
125             int n = Math.min(i, attValues.length - 1);
126             ((Map JavaDoc) mapList.get(i)).put(attr, attValues[n]);
127         }
128     }
129
130     //From java.text.AttributedCharacterIterator
131

132     /**
133      * Get the keys of all attributes defined on the iterator's text range.
134      */

135     public Set JavaDoc getAllAttributeKeys() {
136         return allAttributes;
137     }
138
139     /**
140      * Get the value of the named attribute for the current
141      * character.
142      */

143     public Object JavaDoc getAttribute(AttributedCharacterIterator.Attribute JavaDoc attribute)
144     {
145         return getAttributes().get(attribute);
146     }
147
148     /**
149      * Returns a map with the attributes defined on the current
150      * character.
151      */

152     public Map JavaDoc getAttributes() {
153         return (Map JavaDoc) mapList.get(currentIndex);
154     }
155
156     /**
157      * Get the index of the first character following the
158      * run with respect to all attributes containing the current
159      * character.
160      */

161     public int getRunLimit() {
162         int ndx = currentIndex;
163         do {
164             ++ndx;
165         } while (charInRun[ndx] == MID_RUN);
166         return ndx;
167     }
168
169     /**
170      * Get the index of the first character following the
171      * run with respect to the given attribute containing the current
172      * character.
173      */

174     public int getRunLimit(AttributedCharacterIterator.Attribute JavaDoc attribute) {
175         int ndx = currentIndex;
176         Object JavaDoc value = getAttributes().get(attribute);
177
178         //to avoid null pointer, treat null value as special case:-(
179
if (value == null) {
180             do {
181                  ++ndx;
182             } while (((Map JavaDoc) mapList.get(ndx)).get(attribute) == null);
183         } else {
184             do {
185                 ++ndx;
186             } while (value.equals(((Map JavaDoc) mapList.get(ndx)).get(attribute)));
187         }
188         return ndx;
189     }
190
191
192     /**
193      * Get the index of the first character following the
194      * run with respect to the given attributes containing the current
195      * character.
196      */

197     public int getRunLimit(Set JavaDoc attributes) {
198         int ndx = currentIndex;
199         do {
200             ++ndx;
201         } while (attributes.equals(mapList.get(ndx)));
202         return ndx;
203     }
204
205     /**
206      * Get the index of the first character of the run with
207      * respect to all attributes containing the current character.
208      */

209     public int getRunStart() {
210         int ndx = currentIndex;
211         while (charInRun[ndx] == MID_RUN) --ndx;
212         return ndx;
213     }
214
215     /**
216      * Get the index of the first character of the run with
217      * respect to the given attribute containing the current character.
218      * @param attribute The attribute for whose appearance the first offset
219      * is requested.
220      */

221     public int getRunStart(AttributedCharacterIterator.Attribute JavaDoc attribute) {
222         int ndx = currentIndex - 1;
223         Object JavaDoc value = getAttributes().get(attribute);
224
225         //to avoid null pointer, treat null value as special case:-(
226
try {
227             if (value == null) {
228                 while (((Map JavaDoc) mapList.get(ndx - 1)).get(attribute) == null)
229                     --ndx;
230             } else {
231                 while (value.equals(
232                         ((Map JavaDoc) mapList.get(ndx - 1)).get(attribute)) )
233                     --ndx;
234             }
235         } catch(IndexOutOfBoundsException JavaDoc e) {
236         }
237         return ndx;
238     }
239
240     /**
241      * Get the index of the first character of the run with
242      * respect to the given attributes containing the current character.
243      * @param attributes the Set of attributes which begins at the returned
244      * index.
245      */

246     public int getRunStart(Set JavaDoc attributes) {
247         int ndx = currentIndex;
248         try {
249             while (attributes.equals(mapList.get(ndx - 1))) --ndx;
250         } catch(IndexOutOfBoundsException JavaDoc e) {
251         }
252         return ndx;
253     }
254
255     //From CharacterIterator
256

257     /**
258      * Create a copy of this iterator
259      */

260     public Object JavaDoc clone() {
261         GVTAttributedCharacterIterator cloneACI =
262                 new GVTACIImpl(this);
263         return cloneACI;
264     }
265
266     /**
267      * Get the character at the current position (as returned
268      * by getIndex()).
269      * <br><b>Specified by:</b> java.text.CharacterIterator.
270      */

271     public char current() {
272         return iter.current();
273     }
274
275     /**
276      * Sets the position to getBeginIndex().
277      * @return the character at the start index of the text.
278      * <br><b>Specified by:</b> java.text.CharacterIterator.
279      */

280     public char first() {
281         return iter.first();
282     }
283
284     /**
285      * Get the start index of the text.
286      * <br><b>Specified by:</b> java.text.CharacterIterator.
287      */

288     public int getBeginIndex() {
289         return iter.getBeginIndex();
290     }
291
292     /**
293      * Get the end index of the text.
294      * <br><b>Specified by:</b> java.text.CharacterIterator.
295      */

296     public int getEndIndex() {
297         return iter.getEndIndex();
298     }
299
300     /**
301      * Get the current index.
302      * <br><b>Specified by:</b> java.text.CharacterIterator.
303      */

304     public int getIndex() {
305         return iter.getIndex();
306     }
307
308     /**
309      * Sets the position to getEndIndex()-1 (getEndIndex() if
310      * the text is empty) and returns the character at that position.
311      * <br><b>Specified by:</b> java.text.CharacterIterator.
312      */

313     public char last() {
314         return iter.last();
315     }
316
317     /**
318      * Increments the iterator's index by one, returning the next character.
319      * @return the character at the new index.
320      * <br><b>Specified by:</b> java.text.CharacterIterator.
321      */

322     public char next() {
323         return iter.next();
324     }
325
326     /**
327      * Decrements the iterator's index by one and returns
328      * the character at the new index.
329      * <br><b>Specified by:</b> java.text.CharacterIterator.
330      */

331     public char previous() {
332         return iter.previous();
333     }
334
335     /**
336      * Sets the position to the specified position in the text.
337      * @param position The new (current) index into the text.
338      * @return the character at new index <em>position</em>.
339      * <br><b>Specified by:</b> java.text.CharacterIterator.
340      */

341     public char setIndex(int position) {
342         return iter.setIndex(position);
343     }
344
345     //Private methods:
346

347     private void buildAttributeTables() {
348         allAttributes = new HashSet JavaDoc();
349         mapList = new ArrayList JavaDoc(simpleString.length());
350         charInRun = new int[simpleString.length()];
351         for (int i = 0; i < charInRun.length; ++i) {
352             charInRun[i] = SINGLETON;
353             /*
354              * XXX TODO: loosen assumption, initially each character has its own
355              * attribute map.
356              */

357             mapList.set(i, new HashMap JavaDoc());
358         }
359     }
360
361     private void buildAttributeTables(AttributedCharacterIterator JavaDoc aci) {
362         allAttributes = aci.getAllAttributeKeys();
363         int length = aci.getEndIndex() - aci.getBeginIndex();
364         mapList = new ArrayList JavaDoc(length);
365         charInRun = new int[length];
366         char c = aci.first();
367         char chars[] = new char[length];
368         for (int i = 0; i < length; ++i) {
369             chars[i] = c;
370             charInRun[i] = SINGLETON;
371             /*
372              * XXX TODO:loosen assumption, initially each character
373              * has its own attribute map.
374              */

375             mapList.set(i, new HashMap JavaDoc(aci.getAttributes()));
376             c = aci.next();
377         }
378         simpleString = new String JavaDoc(chars);
379     }
380
381     //Inner classes:
382

383     /**
384      * AttributeFilter which converts (extended) location attributes
385      * SVGAttributedCharacterIterator.TextAttribute.X, TextAttribute.Y,
386      * TextAttribute.ROTATE attributes to TextAttribute.TRANSFORM attributes.
387      */

388     public class TransformAttributeFilter implements
389                      GVTAttributedCharacterIterator.AttributeFilter {
390
391         /**
392          * Return a new AttributedCharacterIterator instance
393          * in which location attributes have been converted to
394          * TextAttribute.TRANSFORM attributes.
395          */

396         public AttributedCharacterIterator JavaDoc
397                      mutateAttributes(AttributedCharacterIterator JavaDoc aci) {
398             //TODO:Implement this !!!
399
return aci;
400         }
401     }
402 }
403
Popular Tags