]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/richtext/styledtext/MConstText.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / richtext / styledtext / MConstText.java
1 /*\r
2  * (C) Copyright IBM Corp. 1998-2004.  All Rights Reserved.\r
3  *\r
4  * The program is provided "as is" without any warranty express or\r
5  * implied, including the warranty of non-infringement and the implied\r
6  * warranties of merchantibility and fitness for a particular purpose.\r
7  * IBM will not be liable for any damages suffered by you as a result\r
8  * of using the Program. In no event will IBM be liable for any\r
9  * special, indirect or consequential damages or lost profits even if\r
10  * IBM has been advised of the possibility of their occurrence. IBM\r
11  * will not be liable for any third party claims against you.\r
12  */\r
13 package com.ibm.richtext.styledtext;\r
14 \r
15 import com.ibm.richtext.textlayout.attributes.AttributeMap;\r
16 import java.text.CharacterIterator;\r
17 import java.awt.datatransfer.DataFlavor;\r
18 \r
19 /**\r
20  * MConstText is a base class for text with multiple character and\r
21  * paragraph styles.  The text is a sequence of Unicode characters,\r
22  * represented by <code>char</code>.  Character and paragraph\r
23  * styles are represented by the <code>AttributeMap</code> class.\r
24  * <p>\r
25  * Characters in the text are accessed with an integer index using the\r
26  * <code>at</code> method.\r
27  * Valid indices are between 0 and (length-1), where length is the number\r
28  * of characters in the text.  Additionally, the\r
29  * characters in the text may be accessed through a\r
30  * <code>java.text.CharacterIterator</code>.\r
31  * <p>\r
32  * Every character in the text has a character style associated with it,\r
33  * represented by the <code>AttributeMap</code> class.  The character\r
34  * style for a particular character can be obtained using the\r
35  * <code>characterStyleAt</code> method.\r
36  * <p>\r
37  * Each character in the text is contained in a paragraph.  A paragraph\r
38  * is a range of text including and terminated by a\r
39  * paragraph separator (either <code>\n</code> or <code>U+2029</code>).\r
40  * Every\r
41  * paragraph has a paragraph style associated with it, represented\r
42  * by the <code>AttributeMap</code> class.  Paragraph boundaries and\r
43  * styles can be obtained from the MConstText.\r
44  * <p>\r
45  * This class does not have methods for modifying the text or styles.\r
46  * However, subclasses may add this capability, so it is not safe to\r
47  * assume that an MConstText instance is immutable.  In particular,\r
48  * the MText class adds modification protocol to this class.  Clients\r
49  * can detect whether an MConstText has changed by keeping track of its\r
50  * timestamp.\r
51  * <p>\r
52  * A DataFlavor for clipboard content is defined in this class.  Using\r
53  * this DataFlavor insures that all clients will recognize MConstText\r
54  * content on the clipboard.\r
55  * @see MText\r
56  * @see AttributeMap\r
57  * @see java.text.CharacterIterator\r
58  * @see java.awt.datatransfer.DataFlavor\r
59  */\r
60 public abstract class MConstText {\r
61 \r
62     static final String COPYRIGHT =\r
63                 "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";\r
64     /**\r
65      * The DataFlavor for MConstText clipboard content.  Used to\r
66      * indicate that clipboard data has an MConstText representation.\r
67      */\r
68     public static final DataFlavor styledTextFlavor =\r
69                             new DataFlavor(MConstText.class, "Styled Text");\r
70 \r
71     protected MConstText() {\r
72     }\r
73 \r
74 //========================================================\r
75 // CHARACTER ACCESS\r
76 //========================================================\r
77 /**\r
78 * Return the character at offset <code>pos</code>.\r
79 * @param pos a valid offset into the text\r
80 * @return the character at offset <code>pos</code>\r
81 */\r
82     public abstract char at(int pos);\r
83 \r
84 /**\r
85 * Copy the characters in the range [<code>start</code>, <code>limit</code>)\r
86 * into the array <code>dst</code>, beginning at <code>dstStart</code>.\r
87 * @param start offset of first character which will be copied into the array\r
88 * @param limit offset immediately after the last character which will be copied into the array\r
89 * @param dst array in which to copy characters.  The length of <code>dst</code> must be at least\r
90 * (<code>dstStart + limit - start</code>).\r
91 */\r
92     public abstract void extractChars(int start, int limit, char[] dst, int dstStart);\r
93 \r
94 /**\r
95 * Create an MConstText containing the characters and styles in the range\r
96 * [<code>start</code>, <code>limit</code>).\r
97 * @param start offset of first character in the new text\r
98 * @param limit offset immediately after the last character in the new text\r
99 * @return an MConstText object containing the characters and styles in the given range\r
100 */\r
101     public abstract MConstText extract(int start, int limit);\r
102 \r
103 /**\r
104 * Create a <code>java.text.CharacterIterator</code> over all\r
105 * of the characters in the text.  Default implementation calls\r
106 * <code>createCharacterIterator(0, length())</code>\r
107 * @return a <code>java.text.CharacterIterator</code> over all\r
108 *      of the characters in the text\r
109 */\r
110     public CharacterIterator createCharacterIterator() {\r
111 \r
112         return createCharacterIterator(0, length());\r
113     }\r
114 \r
115 /**\r
116 * Create a <code>java.text.CharacterIterator</code> over the\r
117 * given range of characters in the text.\r
118 * @param start the first index in the iteration range\r
119 * @param limit the index after the last character in the iteration range\r
120 * @return a <code>java.text.CharacterIterator</code> over the\r
121 *     given range\r
122 */\r
123     public abstract CharacterIterator createCharacterIterator(int start,\r
124                                                               int limit);\r
125 \r
126 \r
127 //========================================================\r
128 // SIZE/CAPACITY\r
129 //========================================================\r
130 /**\r
131 * Return the length of the MConstText object.  The length is the number of characters in the text.\r
132 * @return the length of the MConstText object\r
133 */\r
134     public abstract int length();\r
135 \r
136 //========================================================\r
137 // Character styles\r
138 //========================================================\r
139 \r
140 /**\r
141 * Return the index of the first character in the character style run\r
142 * containing pos.  All characters in a style run have the same character\r
143 * style.\r
144 * @return the style at offset <code>pos</code>\r
145 */\r
146     public abstract int characterStyleStart(int pos);\r
147 \r
148 /**\r
149 * Return the index after the last character in the character style run\r
150 * containing pos.  All characters in a style run have the same character\r
151 * style.\r
152 * @return the style at offset <code>pos</code>\r
153 */\r
154     public abstract int characterStyleLimit(int pos);\r
155 \r
156 /**\r
157 * Return the style applied to the character at offset <code>pos</code>.\r
158 * @param pos a valid offset into the text\r
159 * @return the style at offset <code>pos</code>\r
160 */\r
161     public abstract AttributeMap characterStyleAt(int pos);\r
162 \r
163 //========================================================\r
164 // PARAGRAPH BOUNDARIES\r
165 //========================================================\r
166 /**\r
167 * Return the start of the paragraph containing the character at offset <code>pos</code>.\r
168 * @param pos a valid offset into the text\r
169 * @return the start of the paragraph containing the character at offset <code>pos</code>\r
170 */\r
171     public abstract int paragraphStart(int pos);\r
172 \r
173 /**\r
174 * Return the limit of the paragraph containing the character at offset <code>pos</code>.\r
175 * @param pos a valid offset into the text\r
176 * @return the limit of the paragraph containing the character at offset <code>pos</code>\r
177 */\r
178     public abstract int paragraphLimit(int pos);\r
179 \r
180 /**\r
181 * Return the paragraph style applied to the paragraph containing offset <code>pos</code>.\r
182 * @param pos a valid offset into the text\r
183 * @return the paragraph style in effect at <code>pos</code>\r
184 */\r
185     public abstract AttributeMap paragraphStyleAt(int pos);\r
186 \r
187 /**\r
188 * Return the current time stamp.  The time stamp is\r
189 * incremented whenever the contents of the MConstText changes.\r
190 * @return the current paragraph style time stamp\r
191 */\r
192     public abstract int getTimeStamp();\r
193 \r
194 /**\r
195 * Return the start of the damaged range.  If the start is not less\r
196 * than the the limit of the damaged range, then the damaged range\r
197 * is empty.\r
198 * @return the start of the damaged range\r
199 * @see #damagedRangeLimit\r
200 * @see MText#resetDamagedRange\r
201 */\r
202     public abstract int damagedRangeStart();\r
203 \r
204 /**\r
205 * Return the limit of the damaged range.  If the start is not less\r
206 * than the the limit of the damaged range, then the damaged range\r
207 * is empty.\r
208 * @return the start of the damaged range\r
209 * @see #damagedRangeStart\r
210 * @see MText#resetDamagedRange\r
211 */\r
212     public abstract int damagedRangeLimit();\r
213 \r
214 //========================================================\r
215 // Equality and hashCode\r
216 //========================================================\r
217 /**\r
218 * Compare this to another Object for equality.  This is\r
219 * equal to rhs if rhs is an MConstText which is equal\r
220 * to this.\r
221 * @param rhs Object to compare to\r
222 * @return true if this equals <code>rhs</code>\r
223 */\r
224     public final boolean equals(Object rhs) {\r
225 \r
226         MConstText otherText;\r
227 \r
228         try {\r
229             otherText = (MConstText) rhs;\r
230         }\r
231         catch(ClassCastException e) {\r
232             return false;\r
233         }\r
234 \r
235         return equals(otherText);\r
236     }\r
237 \r
238 /**\r
239 * Compare this to another MConstText for equality.  This is\r
240 * equal to rhs if the characters and styles in rhs are the\r
241 * same as this.  Subclasses may override this implementation\r
242 * for efficiency, but they should preserve these semantics.\r
243 * Determining that two MConstText instances are equal may be\r
244 * an expensive operation, since every character and style must\r
245 * be compared.\r
246 * @param rhs Object to compare to\r
247 * @return true if this equals <code>rhs</code>\r
248 */\r
249     public boolean equals(MConstText rhs) {\r
250 \r
251         if (rhs == null) {\r
252             return false;\r
253         }\r
254 \r
255         if (rhs == this) {\r
256             return true;\r
257         }\r
258 \r
259         if (hashCode() != rhs.hashCode()) {\r
260             return false;\r
261         }\r
262 \r
263         int length = length();\r
264         if (length != rhs.length()) {\r
265             return false;\r
266         }\r
267 \r
268         for (int i=0; i < length; i++) {\r
269             if (i < length && at(i) != rhs.at(i)) {\r
270                 return false;\r
271             }\r
272         }\r
273 \r
274         for (int start = 0; start < length;) {\r
275             if (!characterStyleAt(start).equals(rhs.characterStyleAt(start))) {\r
276                 return false;\r
277             }\r
278             int limit = characterStyleLimit(start);\r
279             if (limit != rhs.characterStyleLimit(start)) {\r
280                 return false;\r
281             }\r
282             start = limit;\r
283         }\r
284 \r
285         for (int start = 0; start < length;) {\r
286 \r
287             if (!paragraphStyleAt(start).equals(rhs.paragraphStyleAt(start))) {\r
288                 return false;\r
289             }\r
290             start = paragraphLimit(start);\r
291         }\r
292 \r
293         return paragraphStyleAt(length).equals(rhs.paragraphStyleAt(length));\r
294     }\r
295 \r
296     /**\r
297      * Return the hashCode for this MConstText.  An empty MConstText\r
298      * has hashCode 0;  a nonempty MConstText's hashCode is\r
299      * <blockquote><pre>\r
300      *       at(0) +\r
301      *       at(length/2)*31^1 +\r
302      *       at(length-1)*31^2 +\r
303      *       characterStyleAt(0).hashCode()*31^3 +\r
304      *       paragraphStyleAt(length-1).hashCode()*31^4\r
305      * </pre></blockquote>\r
306      * where <code>^</code> is exponentiation (not bitwise XOR).\r
307      */\r
308     public final int hashCode() {\r
309 \r
310         int hashCode = 0;\r
311         int length = length();\r
312 \r
313         if (length > 0) {\r
314             hashCode = paragraphStyleAt(length-1).hashCode();\r
315             hashCode = hashCode*31 + characterStyleAt(0).hashCode();\r
316             hashCode = hashCode*31 + at(length-1);\r
317             hashCode = hashCode*31 + at(length/2);\r
318             hashCode = hashCode*31 + at(0);\r
319         }\r
320 \r
321         return hashCode;\r
322     }\r
323 }\r