author | prr |
Sat, 19 Sep 2015 15:45:59 -0700 | |
changeset 32865 | f9cb6e427f9e |
parent 28231 | b608ffcaed74 |
child 47160 | ac5434728c3b |
permissions | -rw-r--r-- |
2 | 1 |
/* |
22567
5816a47fa4dd
8032047: Fix static lint warnings in client libraries
darcy
parents:
22260
diff
changeset
|
2 |
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
package javax.swing.text.html; |
|
26 |
||
27 |
import sun.swing.SwingUtilities2; |
|
28 |
import java.util.*; |
|
29 |
import java.awt.*; |
|
30 |
import java.io.*; |
|
31 |
import java.net.*; |
|
32 |
import javax.swing.Icon; |
|
33 |
import javax.swing.ImageIcon; |
|
2493
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
34 |
import javax.swing.UIManager; |
2 | 35 |
import javax.swing.border.*; |
36 |
import javax.swing.event.ChangeListener; |
|
37 |
import javax.swing.text.*; |
|
38 |
||
39 |
/** |
|
40 |
* Support for defining the visual characteristics of |
|
41 |
* HTML views being rendered. The StyleSheet is used to |
|
42 |
* translate the HTML model into visual characteristics. |
|
43 |
* This enables views to be customized by a look-and-feel, |
|
44 |
* multiple views over the same model can be rendered |
|
45 |
* differently, etc. This can be thought of as a CSS |
|
46 |
* rule repository. The key for CSS attributes is an |
|
47 |
* object of type CSS.Attribute. The type of the value |
|
48 |
* is up to the StyleSheet implementation, but the |
|
49 |
* <code>toString</code> method is required |
|
50 |
* to return a string representation of CSS value. |
|
51 |
* <p> |
|
52 |
* The primary entry point for HTML View implementations |
|
53 |
* to get their attributes is the |
|
7959 | 54 |
* {@link #getViewAttributes getViewAttributes} |
2 | 55 |
* method. This should be implemented to establish the |
56 |
* desired policy used to associate attributes with the view. |
|
57 |
* Each HTMLEditorKit (i.e. and therefore each associated |
|
58 |
* JEditorPane) can have its own StyleSheet, but by default one |
|
59 |
* sheet will be shared by all of the HTMLEditorKit instances. |
|
60 |
* HTMLDocument instance can also have a StyleSheet, which |
|
61 |
* holds the document-specific CSS specifications. |
|
62 |
* <p> |
|
63 |
* In order for Views to store less state and therefore be |
|
64 |
* more lightweight, the StyleSheet can act as a factory for |
|
65 |
* painters that handle some of the rendering tasks. This allows |
|
66 |
* implementations to determine what they want to cache |
|
67 |
* and have the sharing potentially at the level that a |
|
68 |
* selector is common to multiple views. Since the StyleSheet |
|
69 |
* may be used by views over multiple documents and typically |
|
70 |
* the HTML attributes don't effect the selector being used, |
|
71 |
* the potential for sharing is significant. |
|
72 |
* <p> |
|
73 |
* The rules are stored as named styles, and other information |
|
74 |
* is stored to translate the context of an element to a |
|
75 |
* rule quickly. The following code fragment will display |
|
76 |
* the named styles, and therefore the CSS rules contained. |
|
20169 | 77 |
* <pre><code> |
2 | 78 |
* |
79 |
* import java.util.*; |
|
80 |
* import javax.swing.text.*; |
|
81 |
* import javax.swing.text.html.*; |
|
82 |
* |
|
83 |
* public class ShowStyles { |
|
84 |
* |
|
85 |
* public static void main(String[] args) { |
|
86 |
* HTMLEditorKit kit = new HTMLEditorKit(); |
|
87 |
* HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument(); |
|
88 |
* StyleSheet styles = doc.getStyleSheet(); |
|
89 |
* |
|
90 |
* Enumeration rules = styles.getStyleNames(); |
|
91 |
* while (rules.hasMoreElements()) { |
|
92 |
* String name = (String) rules.nextElement(); |
|
93 |
* Style rule = styles.getStyle(name); |
|
94 |
* System.out.println(rule.toString()); |
|
95 |
* } |
|
96 |
* System.exit(0); |
|
97 |
* } |
|
98 |
* } |
|
99 |
* |
|
20169 | 100 |
* </code></pre> |
2 | 101 |
* <p> |
102 |
* The semantics for when a CSS style should overide visual attributes |
|
103 |
* defined by an element are not well defined. For example, the html |
|
104 |
* <code><body bgcolor=red></code> makes the body have a red |
|
105 |
* background. But if the html file also contains the CSS rule |
|
106 |
* <code>body { background: blue }</code> it becomes less clear as to |
|
107 |
* what color the background of the body should be. The current |
|
21278 | 108 |
* implementation gives visual attributes defined in the element the |
2 | 109 |
* highest precedence, that is they are always checked before any styles. |
110 |
* Therefore, in the previous example the background would have a |
|
111 |
* red color as the body element defines the background color to be red. |
|
112 |
* <p> |
|
113 |
* As already mentioned this supports CSS. We don't support the full CSS |
|
114 |
* spec. Refer to the javadoc of the CSS class to see what properties |
|
115 |
* we support. The two major CSS parsing related |
|
116 |
* concepts we do not currently |
|
117 |
* support are pseudo selectors, such as <code>A:link { color: red }</code>, |
|
118 |
* and the <code>important</code> modifier. |
|
23715 | 119 |
* |
22260
c9185e010e03
8031082: Fix non-missing doclint problems in client libraries
darcy
parents:
21278
diff
changeset
|
120 |
* @implNote This implementation is currently |
2 | 121 |
* incomplete. It can be replaced with alternative implementations |
122 |
* that are complete. Future versions of this class will provide |
|
22260
c9185e010e03
8031082: Fix non-missing doclint problems in client libraries
darcy
parents:
21278
diff
changeset
|
123 |
* better CSS support. |
2 | 124 |
* |
125 |
* @author Timothy Prinzing |
|
126 |
* @author Sunita Mani |
|
127 |
* @author Sara Swanson |
|
128 |
* @author Jill Nakata |
|
129 |
*/ |
|
23697 | 130 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
2 | 131 |
public class StyleSheet extends StyleContext { |
132 |
// As the javadoc states, this class maintains a mapping between |
|
133 |
// a CSS selector (such as p.bar) and a Style. |
|
134 |
// This consists of a number of parts: |
|
135 |
// . Each selector is broken down into its constituent simple selectors, |
|
136 |
// and stored in an inverted graph, for example: |
|
137 |
// p { color: red } ol p { font-size: 10pt } ul p { font-size: 12pt } |
|
138 |
// results in the graph: |
|
139 |
// root |
|
140 |
// | |
|
141 |
// p |
|
142 |
// / \ |
|
143 |
// ol ul |
|
144 |
// each node (an instance of SelectorMapping) has an associated |
|
145 |
// specificity and potentially a Style. |
|
146 |
// . Every rule that is asked for (either by way of getRule(String) or |
|
147 |
// getRule(HTML.Tag, Element)) results in a unique instance of |
|
148 |
// ResolvedStyle. ResolvedStyles contain the AttributeSets from the |
|
149 |
// SelectorMapping. |
|
150 |
// . When a new rule is created it is inserted into the graph, and |
|
151 |
// the AttributeSets of each ResolvedStyles are updated appropriately. |
|
152 |
// . This class creates special AttributeSets, LargeConversionSet and |
|
153 |
// SmallConversionSet, that maintain a mapping between StyleConstants |
|
154 |
// and CSS so that developers that wish to use the StyleConstants |
|
155 |
// methods can do so. |
|
156 |
// . When one of the AttributeSets is mutated by way of a |
|
157 |
// StyleConstants key, all the associated CSS keys are removed. This is |
|
158 |
// done so that the two representations don't get out of sync. For |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
159 |
// example, if the developer adds StyleConstants.BOLD, FALSE to an |
2 | 160 |
// AttributeSet that contains HTML.Tag.B, the HTML.Tag.B entry will |
161 |
// be removed. |
|
162 |
||
163 |
/** |
|
164 |
* Construct a StyleSheet |
|
165 |
*/ |
|
166 |
public StyleSheet() { |
|
167 |
super(); |
|
168 |
selectorMapping = new SelectorMapping(0); |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
169 |
resolvedStyles = new Hashtable<String, ResolvedStyle>(); |
2 | 170 |
if (css == null) { |
171 |
css = new CSS(); |
|
172 |
} |
|
173 |
} |
|
174 |
||
175 |
/** |
|
176 |
* Fetches the style to use to render the given type |
|
177 |
* of HTML tag. The element given is representing |
|
178 |
* the tag and can be used to determine the nesting |
|
179 |
* for situations where the attributes will differ |
|
180 |
* if nesting inside of elements. |
|
181 |
* |
|
182 |
* @param t the type to translate to visual attributes |
|
183 |
* @param e the element representing the tag; the element |
|
184 |
* can be used to determine the nesting for situations where |
|
185 |
* the attributes will differ if nested inside of other |
|
186 |
* elements |
|
187 |
* @return the set of CSS attributes to use to render |
|
188 |
* the tag |
|
189 |
*/ |
|
190 |
public Style getRule(HTML.Tag t, Element e) { |
|
191 |
SearchBuffer sb = SearchBuffer.obtainSearchBuffer(); |
|
192 |
||
193 |
try { |
|
194 |
// Build an array of all the parent elements. |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
195 |
@SuppressWarnings("unchecked") |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
196 |
Vector<Element> searchContext = sb.getVector(); |
2 | 197 |
|
198 |
for (Element p = e; p != null; p = p.getParentElement()) { |
|
199 |
searchContext.addElement(p); |
|
200 |
} |
|
201 |
||
202 |
// Build a fully qualified selector. |
|
203 |
int n = searchContext.size(); |
|
204 |
StringBuffer cacheLookup = sb.getStringBuffer(); |
|
205 |
AttributeSet attr; |
|
206 |
String eName; |
|
207 |
Object name; |
|
208 |
||
209 |
// >= 1 as the HTML.Tag for the 0th element is passed in. |
|
210 |
for (int counter = n - 1; counter >= 1; counter--) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
211 |
e = searchContext.elementAt(counter); |
2 | 212 |
attr = e.getAttributes(); |
213 |
name = attr.getAttribute(StyleConstants.NameAttribute); |
|
214 |
eName = name.toString(); |
|
215 |
cacheLookup.append(eName); |
|
216 |
if (attr != null) { |
|
217 |
if (attr.isDefined(HTML.Attribute.ID)) { |
|
218 |
cacheLookup.append('#'); |
|
219 |
cacheLookup.append(attr.getAttribute |
|
220 |
(HTML.Attribute.ID)); |
|
221 |
} |
|
222 |
else if (attr.isDefined(HTML.Attribute.CLASS)) { |
|
223 |
cacheLookup.append('.'); |
|
224 |
cacheLookup.append(attr.getAttribute |
|
225 |
(HTML.Attribute.CLASS)); |
|
226 |
} |
|
227 |
} |
|
228 |
cacheLookup.append(' '); |
|
229 |
} |
|
230 |
cacheLookup.append(t.toString()); |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
231 |
e = searchContext.elementAt(0); |
2 | 232 |
attr = e.getAttributes(); |
233 |
if (e.isLeaf()) { |
|
234 |
// For leafs, we use the second tier attributes. |
|
235 |
Object testAttr = attr.getAttribute(t); |
|
236 |
if (testAttr instanceof AttributeSet) { |
|
237 |
attr = (AttributeSet)testAttr; |
|
238 |
} |
|
239 |
else { |
|
240 |
attr = null; |
|
241 |
} |
|
242 |
} |
|
243 |
if (attr != null) { |
|
244 |
if (attr.isDefined(HTML.Attribute.ID)) { |
|
245 |
cacheLookup.append('#'); |
|
246 |
cacheLookup.append(attr.getAttribute(HTML.Attribute.ID)); |
|
247 |
} |
|
248 |
else if (attr.isDefined(HTML.Attribute.CLASS)) { |
|
249 |
cacheLookup.append('.'); |
|
250 |
cacheLookup.append(attr.getAttribute |
|
251 |
(HTML.Attribute.CLASS)); |
|
252 |
} |
|
253 |
} |
|
254 |
||
255 |
Style style = getResolvedStyle(cacheLookup.toString(), |
|
256 |
searchContext, t); |
|
257 |
return style; |
|
258 |
} |
|
259 |
finally { |
|
260 |
SearchBuffer.releaseSearchBuffer(sb); |
|
261 |
} |
|
262 |
} |
|
263 |
||
264 |
/** |
|
265 |
* Fetches the rule that best matches the selector given |
|
266 |
* in string form. Where <code>selector</code> is a space separated |
|
267 |
* String of the element names. For example, <code>selector</code> |
|
268 |
* might be 'html body tr td''<p> |
|
269 |
* The attributes of the returned Style will change |
|
270 |
* as rules are added and removed. That is if you to ask for a rule |
|
271 |
* with a selector "table p" and a new rule was added with a selector |
|
272 |
* of "p" the returned Style would include the new attributes from |
|
273 |
* the rule "p". |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
274 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
275 |
* @param selector a space separated String of the element names. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
276 |
* @return the rule that best matches the selector. |
2 | 277 |
*/ |
278 |
public Style getRule(String selector) { |
|
279 |
selector = cleanSelectorString(selector); |
|
280 |
if (selector != null) { |
|
281 |
Style style = getResolvedStyle(selector); |
|
282 |
return style; |
|
283 |
} |
|
284 |
return null; |
|
285 |
} |
|
286 |
||
287 |
/** |
|
288 |
* Adds a set of rules to the sheet. The rules are expected to |
|
289 |
* be in valid CSS format. Typically this would be called as |
|
290 |
* a result of parsing a <style> tag. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
291 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
292 |
* @param rule a set of rules |
2 | 293 |
*/ |
294 |
public void addRule(String rule) { |
|
295 |
if (rule != null) { |
|
296 |
//tweaks to control display properties |
|
297 |
//see BasicEditorPaneUI |
|
298 |
final String baseUnitsDisable = "BASE_SIZE_DISABLE"; |
|
299 |
final String baseUnits = "BASE_SIZE "; |
|
300 |
final String w3cLengthUnitsEnable = "W3C_LENGTH_UNITS_ENABLE"; |
|
301 |
final String w3cLengthUnitsDisable = "W3C_LENGTH_UNITS_DISABLE"; |
|
302 |
if (rule == baseUnitsDisable) { |
|
303 |
sizeMap = sizeMapDefault; |
|
304 |
} else if (rule.startsWith(baseUnits)) { |
|
305 |
rebaseSizeMap(Integer. |
|
306 |
parseInt(rule.substring(baseUnits.length()))); |
|
307 |
} else if (rule == w3cLengthUnitsEnable) { |
|
308 |
w3cLengthUnits = true; |
|
309 |
} else if (rule == w3cLengthUnitsDisable) { |
|
310 |
w3cLengthUnits = false; |
|
311 |
} else { |
|
312 |
CssParser parser = new CssParser(); |
|
313 |
try { |
|
314 |
parser.parse(getBase(), new StringReader(rule), false, false); |
|
315 |
} catch (IOException ioe) { } |
|
316 |
} |
|
317 |
} |
|
318 |
} |
|
319 |
||
320 |
/** |
|
321 |
* Translates a CSS declaration to an AttributeSet that represents |
|
322 |
* the CSS declaration. Typically this would be called as a |
|
323 |
* result of encountering an HTML style attribute. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
324 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
325 |
* @param decl a CSS declaration |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
326 |
* @return a set of attributes that represents the CSS declaration. |
2 | 327 |
*/ |
328 |
public AttributeSet getDeclaration(String decl) { |
|
329 |
if (decl == null) { |
|
330 |
return SimpleAttributeSet.EMPTY; |
|
331 |
} |
|
332 |
CssParser parser = new CssParser(); |
|
333 |
return parser.parseDeclaration(decl); |
|
334 |
} |
|
335 |
||
336 |
/** |
|
337 |
* Loads a set of rules that have been specified in terms of |
|
338 |
* CSS1 grammar. If there are collisions with existing rules, |
|
339 |
* the newly specified rule will win. |
|
340 |
* |
|
341 |
* @param in the stream to read the CSS grammar from |
|
342 |
* @param ref the reference URL. This value represents the |
|
343 |
* location of the stream and may be null. All relative |
|
344 |
* URLs specified in the stream will be based upon this |
|
345 |
* parameter. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
346 |
* @throws java.io.IOException if I/O error occured. |
2 | 347 |
*/ |
348 |
public void loadRules(Reader in, URL ref) throws IOException { |
|
349 |
CssParser parser = new CssParser(); |
|
350 |
parser.parse(ref, in, false, false); |
|
351 |
} |
|
352 |
||
353 |
/** |
|
354 |
* Fetches a set of attributes to use in the view for |
|
355 |
* displaying. This is basically a set of attributes that |
|
356 |
* can be used for View.getAttributes. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
357 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
358 |
* @param v a view |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
359 |
* @return the of attributes |
2 | 360 |
*/ |
361 |
public AttributeSet getViewAttributes(View v) { |
|
362 |
return new ViewAttributeSet(v); |
|
363 |
} |
|
364 |
||
365 |
/** |
|
366 |
* Removes a named style previously added to the document. |
|
367 |
* |
|
368 |
* @param nm the name of the style to remove |
|
369 |
*/ |
|
370 |
public void removeStyle(String nm) { |
|
371 |
Style aStyle = getStyle(nm); |
|
372 |
||
373 |
if (aStyle != null) { |
|
374 |
String selector = cleanSelectorString(nm); |
|
375 |
String[] selectors = getSimpleSelectors(selector); |
|
376 |
synchronized(this) { |
|
377 |
SelectorMapping mapping = getRootSelectorMapping(); |
|
378 |
for (int i = selectors.length - 1; i >= 0; i--) { |
|
379 |
mapping = mapping.getChildSelectorMapping(selectors[i], |
|
380 |
true); |
|
381 |
} |
|
382 |
Style rule = mapping.getStyle(); |
|
383 |
if (rule != null) { |
|
384 |
mapping.setStyle(null); |
|
385 |
if (resolvedStyles.size() > 0) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
386 |
Enumeration<ResolvedStyle> values = resolvedStyles.elements(); |
2 | 387 |
while (values.hasMoreElements()) { |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
388 |
ResolvedStyle style = values.nextElement(); |
2 | 389 |
style.removeStyle(rule); |
390 |
} |
|
391 |
} |
|
392 |
} |
|
393 |
} |
|
394 |
} |
|
395 |
super.removeStyle(nm); |
|
396 |
} |
|
397 |
||
398 |
/** |
|
399 |
* Adds the rules from the StyleSheet <code>ss</code> to those of |
|
400 |
* the receiver. <code>ss's</code> rules will override the rules of |
|
401 |
* any previously added style sheets. An added StyleSheet will never |
|
402 |
* override the rules of the receiving style sheet. |
|
403 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
404 |
* @param ss a StyleSheet |
2 | 405 |
* @since 1.3 |
406 |
*/ |
|
407 |
public void addStyleSheet(StyleSheet ss) { |
|
408 |
synchronized(this) { |
|
409 |
if (linkedStyleSheets == null) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
410 |
linkedStyleSheets = new Vector<StyleSheet>(); |
2 | 411 |
} |
412 |
if (!linkedStyleSheets.contains(ss)) { |
|
413 |
int index = 0; |
|
414 |
if (ss instanceof javax.swing.plaf.UIResource |
|
415 |
&& linkedStyleSheets.size() > 1) { |
|
416 |
index = linkedStyleSheets.size() - 1; |
|
417 |
} |
|
418 |
linkedStyleSheets.insertElementAt(ss, index); |
|
419 |
linkStyleSheetAt(ss, index); |
|
420 |
} |
|
421 |
} |
|
422 |
} |
|
423 |
||
424 |
/** |
|
425 |
* Removes the StyleSheet <code>ss</code> from those of the receiver. |
|
426 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
427 |
* @param ss a StyleSheet |
2 | 428 |
* @since 1.3 |
429 |
*/ |
|
430 |
public void removeStyleSheet(StyleSheet ss) { |
|
431 |
synchronized(this) { |
|
432 |
if (linkedStyleSheets != null) { |
|
433 |
int index = linkedStyleSheets.indexOf(ss); |
|
434 |
if (index != -1) { |
|
435 |
linkedStyleSheets.removeElementAt(index); |
|
436 |
unlinkStyleSheet(ss, index); |
|
437 |
if (index == 0 && linkedStyleSheets.size() == 0) { |
|
438 |
linkedStyleSheets = null; |
|
439 |
} |
|
440 |
} |
|
441 |
} |
|
442 |
} |
|
443 |
} |
|
444 |
||
445 |
// |
|
446 |
// The following is used to import style sheets. |
|
447 |
// |
|
448 |
||
449 |
/** |
|
450 |
* Returns an array of the linked StyleSheets. Will return null |
|
451 |
* if there are no linked StyleSheets. |
|
452 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
453 |
* @return an array of StyleSheets. |
2 | 454 |
* @since 1.3 |
455 |
*/ |
|
456 |
public StyleSheet[] getStyleSheets() { |
|
457 |
StyleSheet[] retValue; |
|
458 |
||
459 |
synchronized(this) { |
|
460 |
if (linkedStyleSheets != null) { |
|
461 |
retValue = new StyleSheet[linkedStyleSheets.size()]; |
|
462 |
linkedStyleSheets.copyInto(retValue); |
|
463 |
} |
|
464 |
else { |
|
465 |
retValue = null; |
|
466 |
} |
|
467 |
} |
|
468 |
return retValue; |
|
469 |
} |
|
470 |
||
471 |
/** |
|
472 |
* Imports a style sheet from <code>url</code>. The resulting rules |
|
473 |
* are directly added to the receiver. If you do not want the rules |
|
474 |
* to become part of the receiver, create a new StyleSheet and use |
|
475 |
* addStyleSheet to link it in. |
|
476 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
477 |
* @param url an url |
2 | 478 |
* @since 1.3 |
479 |
*/ |
|
480 |
public void importStyleSheet(URL url) { |
|
481 |
try { |
|
482 |
InputStream is; |
|
483 |
||
484 |
is = url.openStream(); |
|
485 |
Reader r = new BufferedReader(new InputStreamReader(is)); |
|
486 |
CssParser parser = new CssParser(); |
|
487 |
parser.parse(url, r, false, true); |
|
488 |
r.close(); |
|
489 |
is.close(); |
|
490 |
} catch (Throwable e) { |
|
491 |
// on error we simply have no styles... the html |
|
492 |
// will look mighty wrong but still function. |
|
493 |
} |
|
494 |
} |
|
495 |
||
496 |
/** |
|
497 |
* Sets the base. All import statements that are relative, will be |
|
498 |
* relative to <code>base</code>. |
|
499 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
500 |
* @param base a base. |
2 | 501 |
* @since 1.3 |
502 |
*/ |
|
503 |
public void setBase(URL base) { |
|
504 |
this.base = base; |
|
505 |
} |
|
506 |
||
507 |
/** |
|
508 |
* Returns the base. |
|
509 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
510 |
* @return the base. |
2 | 511 |
* @since 1.3 |
512 |
*/ |
|
513 |
public URL getBase() { |
|
514 |
return base; |
|
515 |
} |
|
516 |
||
517 |
/** |
|
518 |
* Adds a CSS attribute to the given set. |
|
519 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
520 |
* @param attr a set of attributes |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
521 |
* @param key a CSS property |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
522 |
* @param value an HTML attribute value |
2 | 523 |
* @since 1.3 |
524 |
*/ |
|
525 |
public void addCSSAttribute(MutableAttributeSet attr, CSS.Attribute key, |
|
526 |
String value) { |
|
527 |
css.addInternalCSSValue(attr, key, value); |
|
528 |
} |
|
529 |
||
530 |
/** |
|
531 |
* Adds a CSS attribute to the given set. |
|
532 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
533 |
* @param attr a set of attributes |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
534 |
* @param key a CSS property |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
535 |
* @param value an HTML attribute value |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
536 |
* @return {@code true} if an HTML attribute {@code value} can be converted |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
537 |
* to a CSS attribute, false otherwise. |
2 | 538 |
* @since 1.3 |
539 |
*/ |
|
540 |
public boolean addCSSAttributeFromHTML(MutableAttributeSet attr, |
|
541 |
CSS.Attribute key, String value) { |
|
542 |
Object iValue = css.getCssValue(key, value); |
|
543 |
if (iValue != null) { |
|
544 |
attr.addAttribute(key, iValue); |
|
545 |
return true; |
|
546 |
} |
|
547 |
return false; |
|
548 |
} |
|
549 |
||
550 |
// ---- Conversion functionality --------------------------------- |
|
551 |
||
552 |
/** |
|
553 |
* Converts a set of HTML attributes to an equivalent |
|
554 |
* set of CSS attributes. |
|
555 |
* |
|
556 |
* @param htmlAttrSet AttributeSet containing the HTML attributes. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
557 |
* @return the set of CSS attributes. |
2 | 558 |
*/ |
559 |
public AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet) { |
|
560 |
AttributeSet cssAttrSet = css.translateHTMLToCSS(htmlAttrSet); |
|
561 |
||
562 |
MutableAttributeSet cssStyleSet = addStyle(null, null); |
|
563 |
cssStyleSet.addAttributes(cssAttrSet); |
|
564 |
||
565 |
return cssStyleSet; |
|
566 |
} |
|
567 |
||
568 |
/** |
|
569 |
* Adds an attribute to the given set, and returns |
|
570 |
* the new representative set. This is reimplemented to |
|
571 |
* convert StyleConstant attributes to CSS prior to forwarding |
|
572 |
* to the superclass behavior. The StyleConstants attribute |
|
573 |
* has no corresponding CSS entry, the StyleConstants attribute |
|
574 |
* is stored (but will likely be unused). |
|
575 |
* |
|
576 |
* @param old the old attribute set |
|
577 |
* @param key the non-null attribute key |
|
578 |
* @param value the attribute value |
|
579 |
* @return the updated attribute set |
|
580 |
* @see MutableAttributeSet#addAttribute |
|
581 |
*/ |
|
582 |
public AttributeSet addAttribute(AttributeSet old, Object key, |
|
583 |
Object value) { |
|
584 |
if (css == null) { |
|
585 |
// supers constructor will call this before returning, |
|
586 |
// and we need to make sure CSS is non null. |
|
587 |
css = new CSS(); |
|
588 |
} |
|
589 |
if (key instanceof StyleConstants) { |
|
590 |
HTML.Tag tag = HTML.getTagForStyleConstantsKey( |
|
591 |
(StyleConstants)key); |
|
592 |
||
593 |
if (tag != null && old.isDefined(tag)) { |
|
594 |
old = removeAttribute(old, tag); |
|
595 |
} |
|
596 |
||
597 |
Object cssValue = css.styleConstantsValueToCSSValue |
|
598 |
((StyleConstants)key, value); |
|
599 |
if (cssValue != null) { |
|
600 |
Object cssKey = css.styleConstantsKeyToCSSKey |
|
601 |
((StyleConstants)key); |
|
602 |
if (cssKey != null) { |
|
603 |
return super.addAttribute(old, cssKey, cssValue); |
|
604 |
} |
|
605 |
} |
|
606 |
} |
|
607 |
return super.addAttribute(old, key, value); |
|
608 |
} |
|
609 |
||
610 |
/** |
|
611 |
* Adds a set of attributes to the element. If any of these attributes |
|
612 |
* are StyleConstants attributes, they will be converted to CSS prior |
|
613 |
* to forwarding to the superclass behavior. |
|
614 |
* |
|
615 |
* @param old the old attribute set |
|
616 |
* @param attr the attributes to add |
|
617 |
* @return the updated attribute set |
|
618 |
* @see MutableAttributeSet#addAttribute |
|
619 |
*/ |
|
620 |
public AttributeSet addAttributes(AttributeSet old, AttributeSet attr) { |
|
621 |
if (!(attr instanceof HTMLDocument.TaggedAttributeSet)) { |
|
622 |
old = removeHTMLTags(old, attr); |
|
623 |
} |
|
624 |
return super.addAttributes(old, convertAttributeSet(attr)); |
|
625 |
} |
|
626 |
||
627 |
/** |
|
628 |
* Removes an attribute from the set. If the attribute is a StyleConstants |
|
629 |
* attribute, the request will be converted to a CSS attribute prior to |
|
630 |
* forwarding to the superclass behavior. |
|
631 |
* |
|
632 |
* @param old the old set of attributes |
|
633 |
* @param key the non-null attribute name |
|
634 |
* @return the updated attribute set |
|
635 |
* @see MutableAttributeSet#removeAttribute |
|
636 |
*/ |
|
637 |
public AttributeSet removeAttribute(AttributeSet old, Object key) { |
|
638 |
if (key instanceof StyleConstants) { |
|
639 |
HTML.Tag tag = HTML.getTagForStyleConstantsKey( |
|
640 |
(StyleConstants)key); |
|
641 |
if (tag != null) { |
|
642 |
old = super.removeAttribute(old, tag); |
|
643 |
} |
|
644 |
||
645 |
Object cssKey = css.styleConstantsKeyToCSSKey((StyleConstants)key); |
|
646 |
if (cssKey != null) { |
|
647 |
return super.removeAttribute(old, cssKey); |
|
648 |
} |
|
649 |
} |
|
650 |
return super.removeAttribute(old, key); |
|
651 |
} |
|
652 |
||
653 |
/** |
|
654 |
* Removes a set of attributes for the element. If any of the attributes |
|
655 |
* is a StyleConstants attribute, the request will be converted to a CSS |
|
656 |
* attribute prior to forwarding to the superclass behavior. |
|
657 |
* |
|
658 |
* @param old the old attribute set |
|
659 |
* @param names the attribute names |
|
660 |
* @return the updated attribute set |
|
661 |
* @see MutableAttributeSet#removeAttributes |
|
662 |
*/ |
|
663 |
public AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names) { |
|
664 |
// PENDING: Should really be doing something similar to |
|
665 |
// removeHTMLTags here, but it is rather expensive to have to |
|
666 |
// clone names |
|
667 |
return super.removeAttributes(old, names); |
|
668 |
} |
|
669 |
||
670 |
/** |
|
671 |
* Removes a set of attributes. If any of the attributes |
|
672 |
* is a StyleConstants attribute, the request will be converted to a CSS |
|
673 |
* attribute prior to forwarding to the superclass behavior. |
|
674 |
* |
|
675 |
* @param old the old attribute set |
|
676 |
* @param attrs the attributes |
|
677 |
* @return the updated attribute set |
|
678 |
* @see MutableAttributeSet#removeAttributes |
|
679 |
*/ |
|
680 |
public AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs) { |
|
681 |
if (old != attrs) { |
|
682 |
old = removeHTMLTags(old, attrs); |
|
683 |
} |
|
684 |
return super.removeAttributes(old, convertAttributeSet(attrs)); |
|
685 |
} |
|
686 |
||
687 |
/** |
|
688 |
* Creates a compact set of attributes that might be shared. |
|
689 |
* This is a hook for subclasses that want to alter the |
|
690 |
* behavior of SmallAttributeSet. This can be reimplemented |
|
691 |
* to return an AttributeSet that provides some sort of |
|
692 |
* attribute conversion. |
|
693 |
* |
|
694 |
* @param a The set of attributes to be represented in the |
|
695 |
* the compact form. |
|
696 |
*/ |
|
697 |
protected SmallAttributeSet createSmallAttributeSet(AttributeSet a) { |
|
698 |
return new SmallConversionSet(a); |
|
699 |
} |
|
700 |
||
701 |
/** |
|
702 |
* Creates a large set of attributes that should trade off |
|
703 |
* space for time. This set will not be shared. This is |
|
704 |
* a hook for subclasses that want to alter the behavior |
|
705 |
* of the larger attribute storage format (which is |
|
706 |
* SimpleAttributeSet by default). This can be reimplemented |
|
707 |
* to return a MutableAttributeSet that provides some sort of |
|
708 |
* attribute conversion. |
|
709 |
* |
|
710 |
* @param a The set of attributes to be represented in the |
|
711 |
* the larger form. |
|
712 |
*/ |
|
713 |
protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) { |
|
714 |
return new LargeConversionSet(a); |
|
715 |
} |
|
716 |
||
717 |
/** |
|
718 |
* For any StyleConstants key in attr that has an associated HTML.Tag, |
|
719 |
* it is removed from old. The resulting AttributeSet is then returned. |
|
720 |
*/ |
|
721 |
private AttributeSet removeHTMLTags(AttributeSet old, AttributeSet attr) { |
|
722 |
if (!(attr instanceof LargeConversionSet) && |
|
723 |
!(attr instanceof SmallConversionSet)) { |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
724 |
Enumeration<?> names = attr.getAttributeNames(); |
2 | 725 |
|
726 |
while (names.hasMoreElements()) { |
|
727 |
Object key = names.nextElement(); |
|
728 |
||
729 |
if (key instanceof StyleConstants) { |
|
730 |
HTML.Tag tag = HTML.getTagForStyleConstantsKey( |
|
731 |
(StyleConstants)key); |
|
732 |
||
733 |
if (tag != null && old.isDefined(tag)) { |
|
734 |
old = super.removeAttribute(old, tag); |
|
735 |
} |
|
736 |
} |
|
737 |
} |
|
738 |
} |
|
739 |
return old; |
|
740 |
} |
|
741 |
||
742 |
/** |
|
743 |
* Converts a set of attributes (if necessary) so that |
|
744 |
* any attributes that were specified as StyleConstants |
|
745 |
* attributes and have a CSS mapping, will be converted |
|
746 |
* to CSS attributes. |
|
747 |
*/ |
|
748 |
AttributeSet convertAttributeSet(AttributeSet a) { |
|
749 |
if ((a instanceof LargeConversionSet) || |
|
750 |
(a instanceof SmallConversionSet)) { |
|
751 |
// known to be converted. |
|
752 |
return a; |
|
753 |
} |
|
754 |
// in most cases, there are no StyleConstants attributes |
|
755 |
// so we iterate the collection of keys to avoid creating |
|
756 |
// a new set. |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
757 |
Enumeration<?> names = a.getAttributeNames(); |
2 | 758 |
while (names.hasMoreElements()) { |
759 |
Object name = names.nextElement(); |
|
760 |
if (name instanceof StyleConstants) { |
|
761 |
// we really need to do a conversion, iterate again |
|
762 |
// building a new set. |
|
763 |
MutableAttributeSet converted = new LargeConversionSet(); |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
764 |
Enumeration<?> keys = a.getAttributeNames(); |
2 | 765 |
while (keys.hasMoreElements()) { |
766 |
Object key = keys.nextElement(); |
|
767 |
Object cssValue = null; |
|
768 |
if (key instanceof StyleConstants) { |
|
769 |
// convert the StyleConstants attribute if possible |
|
770 |
Object cssKey = css.styleConstantsKeyToCSSKey |
|
771 |
((StyleConstants)key); |
|
772 |
if (cssKey != null) { |
|
773 |
Object value = a.getAttribute(key); |
|
774 |
cssValue = css.styleConstantsValueToCSSValue |
|
775 |
((StyleConstants)key, value); |
|
776 |
if (cssValue != null) { |
|
777 |
converted.addAttribute(cssKey, cssValue); |
|
778 |
} |
|
779 |
} |
|
780 |
} |
|
781 |
if (cssValue == null) { |
|
782 |
converted.addAttribute(key, a.getAttribute(key)); |
|
783 |
} |
|
784 |
} |
|
785 |
return converted; |
|
786 |
} |
|
787 |
} |
|
788 |
return a; |
|
789 |
} |
|
790 |
||
791 |
/** |
|
792 |
* Large set of attributes that does conversion of requests |
|
793 |
* for attributes of type StyleConstants. |
|
794 |
*/ |
|
23697 | 795 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
2 | 796 |
class LargeConversionSet extends SimpleAttributeSet { |
797 |
||
798 |
/** |
|
799 |
* Creates a new attribute set based on a supplied set of attributes. |
|
800 |
* |
|
801 |
* @param source the set of attributes |
|
802 |
*/ |
|
803 |
public LargeConversionSet(AttributeSet source) { |
|
804 |
super(source); |
|
805 |
} |
|
806 |
||
807 |
public LargeConversionSet() { |
|
808 |
super(); |
|
809 |
} |
|
810 |
||
811 |
/** |
|
812 |
* Checks whether a given attribute is defined. |
|
813 |
* |
|
814 |
* @param key the attribute key |
|
815 |
* @return true if the attribute is defined |
|
816 |
* @see AttributeSet#isDefined |
|
817 |
*/ |
|
818 |
public boolean isDefined(Object key) { |
|
819 |
if (key instanceof StyleConstants) { |
|
820 |
Object cssKey = css.styleConstantsKeyToCSSKey |
|
821 |
((StyleConstants)key); |
|
822 |
if (cssKey != null) { |
|
823 |
return super.isDefined(cssKey); |
|
824 |
} |
|
825 |
} |
|
826 |
return super.isDefined(key); |
|
827 |
} |
|
828 |
||
829 |
/** |
|
830 |
* Gets the value of an attribute. |
|
831 |
* |
|
832 |
* @param key the attribute name |
|
833 |
* @return the attribute value |
|
834 |
* @see AttributeSet#getAttribute |
|
835 |
*/ |
|
836 |
public Object getAttribute(Object key) { |
|
837 |
if (key instanceof StyleConstants) { |
|
838 |
Object cssKey = css.styleConstantsKeyToCSSKey |
|
839 |
((StyleConstants)key); |
|
840 |
if (cssKey != null) { |
|
841 |
Object value = super.getAttribute(cssKey); |
|
842 |
if (value != null) { |
|
843 |
return css.cssValueToStyleConstantsValue |
|
844 |
((StyleConstants)key, value); |
|
845 |
} |
|
846 |
} |
|
847 |
} |
|
848 |
return super.getAttribute(key); |
|
849 |
} |
|
850 |
} |
|
851 |
||
852 |
/** |
|
853 |
* Small set of attributes that does conversion of requests |
|
854 |
* for attributes of type StyleConstants. |
|
855 |
*/ |
|
856 |
class SmallConversionSet extends SmallAttributeSet { |
|
857 |
||
858 |
/** |
|
859 |
* Creates a new attribute set based on a supplied set of attributes. |
|
860 |
* |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
861 |
* @param attrs the set of attributes |
2 | 862 |
*/ |
863 |
public SmallConversionSet(AttributeSet attrs) { |
|
864 |
super(attrs); |
|
865 |
} |
|
866 |
||
867 |
/** |
|
868 |
* Checks whether a given attribute is defined. |
|
869 |
* |
|
870 |
* @param key the attribute key |
|
871 |
* @return true if the attribute is defined |
|
872 |
* @see AttributeSet#isDefined |
|
873 |
*/ |
|
874 |
public boolean isDefined(Object key) { |
|
875 |
if (key instanceof StyleConstants) { |
|
876 |
Object cssKey = css.styleConstantsKeyToCSSKey |
|
877 |
((StyleConstants)key); |
|
878 |
if (cssKey != null) { |
|
879 |
return super.isDefined(cssKey); |
|
880 |
} |
|
881 |
} |
|
882 |
return super.isDefined(key); |
|
883 |
} |
|
884 |
||
885 |
/** |
|
886 |
* Gets the value of an attribute. |
|
887 |
* |
|
888 |
* @param key the attribute name |
|
889 |
* @return the attribute value |
|
890 |
* @see AttributeSet#getAttribute |
|
891 |
*/ |
|
892 |
public Object getAttribute(Object key) { |
|
893 |
if (key instanceof StyleConstants) { |
|
894 |
Object cssKey = css.styleConstantsKeyToCSSKey |
|
895 |
((StyleConstants)key); |
|
896 |
if (cssKey != null) { |
|
897 |
Object value = super.getAttribute(cssKey); |
|
898 |
if (value != null) { |
|
899 |
return css.cssValueToStyleConstantsValue |
|
900 |
((StyleConstants)key, value); |
|
901 |
} |
|
902 |
} |
|
903 |
} |
|
904 |
return super.getAttribute(key); |
|
905 |
} |
|
906 |
} |
|
907 |
||
908 |
// ---- Resource handling ---------------------------------------- |
|
909 |
||
910 |
/** |
|
911 |
* Fetches the font to use for the given set of attributes. |
|
912 |
*/ |
|
913 |
public Font getFont(AttributeSet a) { |
|
914 |
return css.getFont(this, a, 12, this); |
|
915 |
} |
|
916 |
||
917 |
/** |
|
918 |
* Takes a set of attributes and turn it into a foreground color |
|
919 |
* specification. This might be used to specify things |
|
920 |
* like brighter, more hue, etc. |
|
921 |
* |
|
922 |
* @param a the set of attributes |
|
923 |
* @return the color |
|
924 |
*/ |
|
925 |
public Color getForeground(AttributeSet a) { |
|
926 |
Color c = css.getColor(a, CSS.Attribute.COLOR); |
|
927 |
if (c == null) { |
|
928 |
return Color.black; |
|
929 |
} |
|
930 |
return c; |
|
931 |
} |
|
932 |
||
933 |
/** |
|
934 |
* Takes a set of attributes and turn it into a background color |
|
935 |
* specification. This might be used to specify things |
|
936 |
* like brighter, more hue, etc. |
|
937 |
* |
|
938 |
* @param a the set of attributes |
|
939 |
* @return the color |
|
940 |
*/ |
|
941 |
public Color getBackground(AttributeSet a) { |
|
942 |
return css.getColor(a, CSS.Attribute.BACKGROUND_COLOR); |
|
943 |
} |
|
944 |
||
945 |
/** |
|
946 |
* Fetches the box formatter to use for the given set |
|
947 |
* of CSS attributes. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
948 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
949 |
* @param a a set of CSS attributes |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
950 |
* @return the box formatter. |
2 | 951 |
*/ |
952 |
public BoxPainter getBoxPainter(AttributeSet a) { |
|
953 |
return new BoxPainter(a, css, this); |
|
954 |
} |
|
955 |
||
956 |
/** |
|
957 |
* Fetches the list formatter to use for the given set |
|
958 |
* of CSS attributes. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
959 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
960 |
* @param a a set of CSS attributes |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
961 |
* @return the list formatter. |
2 | 962 |
*/ |
963 |
public ListPainter getListPainter(AttributeSet a) { |
|
964 |
return new ListPainter(a, this); |
|
965 |
} |
|
966 |
||
967 |
/** |
|
968 |
* Sets the base font size, with valid values between 1 and 7. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
969 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
970 |
* @param sz a font size. |
2 | 971 |
*/ |
972 |
public void setBaseFontSize(int sz) { |
|
973 |
css.setBaseFontSize(sz); |
|
974 |
} |
|
975 |
||
976 |
/** |
|
977 |
* Sets the base font size from the passed in String. The string |
|
978 |
* can either identify a specific font size, with legal values between |
|
21278 | 979 |
* 1 and 7, or identify a relative font size such as +1 or -2. |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
980 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
981 |
* @param size a font size. |
2 | 982 |
*/ |
983 |
public void setBaseFontSize(String size) { |
|
984 |
css.setBaseFontSize(size); |
|
985 |
} |
|
986 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
987 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
988 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
989 |
* Returns the index of HTML/CSS size model. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
990 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
991 |
* @param pt a size of point |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
992 |
* @return the index of HTML/CSS size model. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
993 |
*/ |
2 | 994 |
public static int getIndexOfSize(float pt) { |
995 |
return CSS.getIndexOfSize(pt, sizeMapDefault); |
|
996 |
} |
|
997 |
||
998 |
/** |
|
999 |
* Returns the point size, given a size index. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1000 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1001 |
* @param index a size index |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1002 |
* @return the point size value. |
2 | 1003 |
*/ |
1004 |
public float getPointSize(int index) { |
|
1005 |
return css.getPointSize(index, this); |
|
1006 |
} |
|
1007 |
||
1008 |
/** |
|
1009 |
* Given a string such as "+2", "-2", or "2", |
|
1010 |
* returns a point size value. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1011 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1012 |
* @param size a CSS string describing font size |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1013 |
* @return the point size value. |
2 | 1014 |
*/ |
1015 |
public float getPointSize(String size) { |
|
1016 |
return css.getPointSize(size, this); |
|
1017 |
} |
|
1018 |
||
1019 |
/** |
|
1020 |
* Converts a color string such as "RED" or "#NNNNNN" to a Color. |
|
1021 |
* Note: This will only convert the HTML3.2 color strings |
|
1022 |
* or a string of length 7; |
|
1023 |
* otherwise, it will return null. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1024 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1025 |
* @param string color string such as "RED" or "#NNNNNN" |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1026 |
* @return the color |
2 | 1027 |
*/ |
1028 |
public Color stringToColor(String string) { |
|
1029 |
return CSS.stringToColor(string); |
|
1030 |
} |
|
1031 |
||
1032 |
/** |
|
1033 |
* Returns the ImageIcon to draw in the background for |
|
1034 |
* <code>attr</code>. |
|
1035 |
*/ |
|
1036 |
ImageIcon getBackgroundImage(AttributeSet attr) { |
|
1037 |
Object value = attr.getAttribute(CSS.Attribute.BACKGROUND_IMAGE); |
|
1038 |
||
1039 |
if (value != null) { |
|
1040 |
return ((CSS.BackgroundImage)value).getImage(getBase()); |
|
1041 |
} |
|
1042 |
return null; |
|
1043 |
} |
|
1044 |
||
1045 |
/** |
|
1046 |
* Adds a rule into the StyleSheet. |
|
1047 |
* |
|
1048 |
* @param selector the selector to use for the rule. |
|
1049 |
* This will be a set of simple selectors, and must |
|
1050 |
* be a length of 1 or greater. |
|
1051 |
* @param declaration the set of CSS attributes that |
|
1052 |
* make up the rule. |
|
1053 |
*/ |
|
1054 |
void addRule(String[] selector, AttributeSet declaration, |
|
1055 |
boolean isLinked) { |
|
1056 |
int n = selector.length; |
|
7014
eb4fcf73ee99
6432566: Replace usage of StringBuffer with StringBuilder in Swing
rupashka
parents:
5506
diff
changeset
|
1057 |
StringBuilder sb = new StringBuilder(); |
2 | 1058 |
sb.append(selector[0]); |
1059 |
for (int counter = 1; counter < n; counter++) { |
|
1060 |
sb.append(' '); |
|
1061 |
sb.append(selector[counter]); |
|
1062 |
} |
|
1063 |
String selectorName = sb.toString(); |
|
1064 |
Style rule = getStyle(selectorName); |
|
1065 |
if (rule == null) { |
|
1066 |
// Notice how the rule is first created, and it not part of |
|
1067 |
// the synchronized block. It is done like this as creating |
|
1068 |
// a new rule will fire a ChangeEvent. We do not want to be |
|
1069 |
// holding the lock when calling to other objects, it can |
|
1070 |
// result in deadlock. |
|
1071 |
Style altRule = addStyle(selectorName, null); |
|
1072 |
synchronized(this) { |
|
1073 |
SelectorMapping mapping = getRootSelectorMapping(); |
|
1074 |
for (int i = n - 1; i >= 0; i--) { |
|
1075 |
mapping = mapping.getChildSelectorMapping |
|
1076 |
(selector[i], true); |
|
1077 |
} |
|
1078 |
rule = mapping.getStyle(); |
|
1079 |
if (rule == null) { |
|
1080 |
rule = altRule; |
|
1081 |
mapping.setStyle(rule); |
|
1082 |
refreshResolvedRules(selectorName, selector, rule, |
|
1083 |
mapping.getSpecificity()); |
|
1084 |
} |
|
1085 |
} |
|
1086 |
} |
|
1087 |
if (isLinked) { |
|
1088 |
rule = getLinkedStyle(rule); |
|
1089 |
} |
|
1090 |
rule.addAttributes(declaration); |
|
1091 |
} |
|
1092 |
||
1093 |
// |
|
21278 | 1094 |
// The following gaggle of methods is used in maintaining the rules from |
2 | 1095 |
// the sheet. |
1096 |
// |
|
1097 |
||
1098 |
/** |
|
1099 |
* Updates the attributes of the rules to reference any related |
|
1100 |
* rules in <code>ss</code>. |
|
1101 |
*/ |
|
1102 |
private synchronized void linkStyleSheetAt(StyleSheet ss, int index) { |
|
1103 |
if (resolvedStyles.size() > 0) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1104 |
Enumeration<ResolvedStyle> values = resolvedStyles.elements(); |
2 | 1105 |
while (values.hasMoreElements()) { |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1106 |
ResolvedStyle rule = values.nextElement(); |
2 | 1107 |
rule.insertExtendedStyleAt(ss.getRule(rule.getName()), |
1108 |
index); |
|
1109 |
} |
|
1110 |
} |
|
1111 |
} |
|
1112 |
||
1113 |
/** |
|
1114 |
* Removes references to the rules in <code>ss</code>. |
|
1115 |
* <code>index</code> gives the index the StyleSheet was at, that is |
|
1116 |
* how many StyleSheets had been added before it. |
|
1117 |
*/ |
|
1118 |
private synchronized void unlinkStyleSheet(StyleSheet ss, int index) { |
|
1119 |
if (resolvedStyles.size() > 0) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1120 |
Enumeration<ResolvedStyle> values = resolvedStyles.elements(); |
2 | 1121 |
while (values.hasMoreElements()) { |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1122 |
ResolvedStyle rule = values.nextElement(); |
2 | 1123 |
rule.removeExtendedStyleAt(index); |
1124 |
} |
|
1125 |
} |
|
1126 |
} |
|
1127 |
||
1128 |
/** |
|
1129 |
* Returns the simple selectors that comprise selector. |
|
1130 |
*/ |
|
1131 |
/* protected */ |
|
1132 |
String[] getSimpleSelectors(String selector) { |
|
1133 |
selector = cleanSelectorString(selector); |
|
1134 |
SearchBuffer sb = SearchBuffer.obtainSearchBuffer(); |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
1135 |
@SuppressWarnings("unchecked") |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1136 |
Vector<String> selectors = sb.getVector(); |
2 | 1137 |
int lastIndex = 0; |
1138 |
int length = selector.length(); |
|
1139 |
while (lastIndex != -1) { |
|
1140 |
int newIndex = selector.indexOf(' ', lastIndex); |
|
1141 |
if (newIndex != -1) { |
|
1142 |
selectors.addElement(selector.substring(lastIndex, newIndex)); |
|
1143 |
if (++newIndex == length) { |
|
1144 |
lastIndex = -1; |
|
1145 |
} |
|
1146 |
else { |
|
1147 |
lastIndex = newIndex; |
|
1148 |
} |
|
1149 |
} |
|
1150 |
else { |
|
1151 |
selectors.addElement(selector.substring(lastIndex)); |
|
1152 |
lastIndex = -1; |
|
1153 |
} |
|
1154 |
} |
|
1155 |
String[] retValue = new String[selectors.size()]; |
|
1156 |
selectors.copyInto(retValue); |
|
1157 |
SearchBuffer.releaseSearchBuffer(sb); |
|
1158 |
return retValue; |
|
1159 |
} |
|
1160 |
||
1161 |
/** |
|
1162 |
* Returns a string that only has one space between simple selectors, |
|
1163 |
* which may be the passed in String. |
|
1164 |
*/ |
|
1165 |
/*protected*/ String cleanSelectorString(String selector) { |
|
1166 |
boolean lastWasSpace = true; |
|
1167 |
for (int counter = 0, maxCounter = selector.length(); |
|
1168 |
counter < maxCounter; counter++) { |
|
1169 |
switch(selector.charAt(counter)) { |
|
1170 |
case ' ': |
|
1171 |
if (lastWasSpace) { |
|
1172 |
return _cleanSelectorString(selector); |
|
1173 |
} |
|
1174 |
lastWasSpace = true; |
|
1175 |
break; |
|
1176 |
case '\n': |
|
1177 |
case '\r': |
|
1178 |
case '\t': |
|
1179 |
return _cleanSelectorString(selector); |
|
1180 |
default: |
|
1181 |
lastWasSpace = false; |
|
1182 |
} |
|
1183 |
} |
|
1184 |
if (lastWasSpace) { |
|
1185 |
return _cleanSelectorString(selector); |
|
1186 |
} |
|
1187 |
// It was fine. |
|
1188 |
return selector; |
|
1189 |
} |
|
1190 |
||
1191 |
/** |
|
1192 |
* Returns a new String that contains only one space between non |
|
1193 |
* white space characters. |
|
1194 |
*/ |
|
1195 |
private String _cleanSelectorString(String selector) { |
|
1196 |
SearchBuffer sb = SearchBuffer.obtainSearchBuffer(); |
|
1197 |
StringBuffer buff = sb.getStringBuffer(); |
|
1198 |
boolean lastWasSpace = true; |
|
1199 |
int lastIndex = 0; |
|
1200 |
char[] chars = selector.toCharArray(); |
|
1201 |
int numChars = chars.length; |
|
1202 |
String retValue = null; |
|
1203 |
try { |
|
1204 |
for (int counter = 0; counter < numChars; counter++) { |
|
1205 |
switch(chars[counter]) { |
|
1206 |
case ' ': |
|
1207 |
if (!lastWasSpace) { |
|
1208 |
lastWasSpace = true; |
|
1209 |
if (lastIndex < counter) { |
|
1210 |
buff.append(chars, lastIndex, |
|
1211 |
1 + counter - lastIndex); |
|
1212 |
} |
|
1213 |
} |
|
1214 |
lastIndex = counter + 1; |
|
1215 |
break; |
|
1216 |
case '\n': |
|
1217 |
case '\r': |
|
1218 |
case '\t': |
|
1219 |
if (!lastWasSpace) { |
|
1220 |
lastWasSpace = true; |
|
1221 |
if (lastIndex < counter) { |
|
1222 |
buff.append(chars, lastIndex, |
|
1223 |
counter - lastIndex); |
|
1224 |
buff.append(' '); |
|
1225 |
} |
|
1226 |
} |
|
1227 |
lastIndex = counter + 1; |
|
1228 |
break; |
|
1229 |
default: |
|
1230 |
lastWasSpace = false; |
|
1231 |
break; |
|
1232 |
} |
|
1233 |
} |
|
1234 |
if (lastWasSpace && buff.length() > 0) { |
|
1235 |
// Remove last space. |
|
1236 |
buff.setLength(buff.length() - 1); |
|
1237 |
} |
|
1238 |
else if (lastIndex < numChars) { |
|
1239 |
buff.append(chars, lastIndex, numChars - lastIndex); |
|
1240 |
} |
|
1241 |
retValue = buff.toString(); |
|
1242 |
} |
|
1243 |
finally { |
|
1244 |
SearchBuffer.releaseSearchBuffer(sb); |
|
1245 |
} |
|
1246 |
return retValue; |
|
1247 |
} |
|
1248 |
||
1249 |
/** |
|
1250 |
* Returns the root selector mapping that all selectors are relative |
|
1251 |
* to. This is an inverted graph of the selectors. |
|
1252 |
*/ |
|
1253 |
private SelectorMapping getRootSelectorMapping() { |
|
1254 |
return selectorMapping; |
|
1255 |
} |
|
1256 |
||
1257 |
/** |
|
1258 |
* Returns the specificity of the passed in String. It assumes the |
|
1259 |
* passed in string doesn't contain junk, that is each selector is |
|
1260 |
* separated by a space and each selector at most contains one . or one |
|
1261 |
* #. A simple selector has a weight of 1, an id selector has a weight |
|
1262 |
* of 100, and a class selector has a weight of 10000. |
|
1263 |
*/ |
|
1264 |
/*protected*/ static int getSpecificity(String selector) { |
|
1265 |
int specificity = 0; |
|
1266 |
boolean lastWasSpace = true; |
|
1267 |
||
1268 |
for (int counter = 0, maxCounter = selector.length(); |
|
1269 |
counter < maxCounter; counter++) { |
|
1270 |
switch(selector.charAt(counter)) { |
|
1271 |
case '.': |
|
1272 |
specificity += 100; |
|
1273 |
break; |
|
1274 |
case '#': |
|
1275 |
specificity += 10000; |
|
1276 |
break; |
|
1277 |
case ' ': |
|
1278 |
lastWasSpace = true; |
|
1279 |
break; |
|
1280 |
default: |
|
1281 |
if (lastWasSpace) { |
|
1282 |
lastWasSpace = false; |
|
1283 |
specificity += 1; |
|
1284 |
} |
|
1285 |
} |
|
1286 |
} |
|
1287 |
return specificity; |
|
1288 |
} |
|
1289 |
||
1290 |
/** |
|
1291 |
* Returns the style that linked attributes should be added to. This |
|
1292 |
* will create the style if necessary. |
|
1293 |
*/ |
|
1294 |
private Style getLinkedStyle(Style localStyle) { |
|
1295 |
// NOTE: This is not synchronized, and the caller of this does |
|
1296 |
// not synchronize. There is the chance for one of the callers to |
|
1297 |
// overwrite the existing resolved parent, but it is quite rare. |
|
1298 |
// The reason this is left like this is because setResolveParent |
|
1299 |
// will fire a ChangeEvent. It is really, REALLY bad for us to |
|
1300 |
// hold a lock when calling outside of us, it may cause a deadlock. |
|
1301 |
Style retStyle = (Style)localStyle.getResolveParent(); |
|
1302 |
if (retStyle == null) { |
|
1303 |
retStyle = addStyle(null, null); |
|
1304 |
localStyle.setResolveParent(retStyle); |
|
1305 |
} |
|
1306 |
return retStyle; |
|
1307 |
} |
|
1308 |
||
1309 |
/** |
|
1310 |
* Returns the resolved style for <code>selector</code>. This will |
|
1311 |
* create the resolved style, if necessary. |
|
1312 |
*/ |
|
1313 |
private synchronized Style getResolvedStyle(String selector, |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
1314 |
Vector<Element> elements, |
2 | 1315 |
HTML.Tag t) { |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1316 |
Style retStyle = resolvedStyles.get(selector); |
2 | 1317 |
if (retStyle == null) { |
1318 |
retStyle = createResolvedStyle(selector, elements, t); |
|
1319 |
} |
|
1320 |
return retStyle; |
|
1321 |
} |
|
1322 |
||
1323 |
/** |
|
1324 |
* Returns the resolved style for <code>selector</code>. This will |
|
1325 |
* create the resolved style, if necessary. |
|
1326 |
*/ |
|
1327 |
private synchronized Style getResolvedStyle(String selector) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1328 |
Style retStyle = resolvedStyles.get(selector); |
2 | 1329 |
if (retStyle == null) { |
1330 |
retStyle = createResolvedStyle(selector); |
|
1331 |
} |
|
1332 |
return retStyle; |
|
1333 |
} |
|
1334 |
||
1335 |
/** |
|
1336 |
* Adds <code>mapping</code> to <code>elements</code>. It is added |
|
1337 |
* such that <code>elements</code> will remain ordered by |
|
1338 |
* specificity. |
|
1339 |
*/ |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1340 |
private void addSortedStyle(SelectorMapping mapping, Vector<SelectorMapping> elements) { |
2 | 1341 |
int size = elements.size(); |
1342 |
||
1343 |
if (size > 0) { |
|
1344 |
int specificity = mapping.getSpecificity(); |
|
1345 |
||
1346 |
for (int counter = 0; counter < size; counter++) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1347 |
if (specificity >= elements.elementAt(counter).getSpecificity()) { |
2 | 1348 |
elements.insertElementAt(mapping, counter); |
1349 |
return; |
|
1350 |
} |
|
1351 |
} |
|
1352 |
} |
|
1353 |
elements.addElement(mapping); |
|
1354 |
} |
|
1355 |
||
1356 |
/** |
|
1357 |
* Adds <code>parentMapping</code> to <code>styles</code>, and |
|
1358 |
* recursively calls this method if <code>parentMapping</code> has |
|
1359 |
* any child mappings for any of the Elements in <code>elements</code>. |
|
1360 |
*/ |
|
1361 |
private synchronized void getStyles(SelectorMapping parentMapping, |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1362 |
Vector<SelectorMapping> styles, |
2 | 1363 |
String[] tags, String[] ids, String[] classes, |
1364 |
int index, int numElements, |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1365 |
Hashtable<SelectorMapping, SelectorMapping> alreadyChecked) { |
2 | 1366 |
// Avoid desending the same mapping twice. |
1367 |
if (alreadyChecked.contains(parentMapping)) { |
|
1368 |
return; |
|
1369 |
} |
|
1370 |
alreadyChecked.put(parentMapping, parentMapping); |
|
1371 |
Style style = parentMapping.getStyle(); |
|
1372 |
if (style != null) { |
|
1373 |
addSortedStyle(parentMapping, styles); |
|
1374 |
} |
|
1375 |
for (int counter = index; counter < numElements; counter++) { |
|
1376 |
String tagString = tags[counter]; |
|
1377 |
if (tagString != null) { |
|
1378 |
SelectorMapping childMapping = parentMapping. |
|
1379 |
getChildSelectorMapping(tagString, false); |
|
1380 |
if (childMapping != null) { |
|
1381 |
getStyles(childMapping, styles, tags, ids, classes, |
|
1382 |
counter + 1, numElements, alreadyChecked); |
|
1383 |
} |
|
1384 |
if (classes[counter] != null) { |
|
1385 |
String className = classes[counter]; |
|
1386 |
childMapping = parentMapping.getChildSelectorMapping( |
|
1387 |
tagString + "." + className, false); |
|
1388 |
if (childMapping != null) { |
|
1389 |
getStyles(childMapping, styles, tags, ids, classes, |
|
1390 |
counter + 1, numElements, alreadyChecked); |
|
1391 |
} |
|
1392 |
childMapping = parentMapping.getChildSelectorMapping( |
|
1393 |
"." + className, false); |
|
1394 |
if (childMapping != null) { |
|
1395 |
getStyles(childMapping, styles, tags, ids, classes, |
|
1396 |
counter + 1, numElements, alreadyChecked); |
|
1397 |
} |
|
1398 |
} |
|
1399 |
if (ids[counter] != null) { |
|
1400 |
String idName = ids[counter]; |
|
1401 |
childMapping = parentMapping.getChildSelectorMapping( |
|
1402 |
tagString + "#" + idName, false); |
|
1403 |
if (childMapping != null) { |
|
1404 |
getStyles(childMapping, styles, tags, ids, classes, |
|
1405 |
counter + 1, numElements, alreadyChecked); |
|
1406 |
} |
|
1407 |
childMapping = parentMapping.getChildSelectorMapping( |
|
1408 |
"#" + idName, false); |
|
1409 |
if (childMapping != null) { |
|
1410 |
getStyles(childMapping, styles, tags, ids, classes, |
|
1411 |
counter + 1, numElements, alreadyChecked); |
|
1412 |
} |
|
1413 |
} |
|
1414 |
} |
|
1415 |
} |
|
1416 |
} |
|
1417 |
||
1418 |
/** |
|
1419 |
* Creates and returns a Style containing all the rules that match |
|
1420 |
* <code>selector</code>. |
|
1421 |
*/ |
|
1422 |
private synchronized Style createResolvedStyle(String selector, |
|
1423 |
String[] tags, |
|
1424 |
String[] ids, String[] classes) { |
|
1425 |
SearchBuffer sb = SearchBuffer.obtainSearchBuffer(); |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
1426 |
@SuppressWarnings("unchecked") |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1427 |
Vector<SelectorMapping> tempVector = sb.getVector(); |
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
1428 |
@SuppressWarnings("unchecked") |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1429 |
Hashtable<SelectorMapping, SelectorMapping> tempHashtable = sb.getHashtable(); |
2 | 1430 |
// Determine all the Styles that are appropriate, placing them |
1431 |
// in tempVector |
|
1432 |
try { |
|
1433 |
SelectorMapping mapping = getRootSelectorMapping(); |
|
1434 |
int numElements = tags.length; |
|
1435 |
String tagString = tags[0]; |
|
1436 |
SelectorMapping childMapping = mapping.getChildSelectorMapping( |
|
1437 |
tagString, false); |
|
1438 |
if (childMapping != null) { |
|
1439 |
getStyles(childMapping, tempVector, tags, ids, classes, 1, |
|
1440 |
numElements, tempHashtable); |
|
1441 |
} |
|
1442 |
if (classes[0] != null) { |
|
1443 |
String className = classes[0]; |
|
1444 |
childMapping = mapping.getChildSelectorMapping( |
|
1445 |
tagString + "." + className, false); |
|
1446 |
if (childMapping != null) { |
|
1447 |
getStyles(childMapping, tempVector, tags, ids, classes, 1, |
|
1448 |
numElements, tempHashtable); |
|
1449 |
} |
|
1450 |
childMapping = mapping.getChildSelectorMapping( |
|
1451 |
"." + className, false); |
|
1452 |
if (childMapping != null) { |
|
1453 |
getStyles(childMapping, tempVector, tags, ids, classes, |
|
1454 |
1, numElements, tempHashtable); |
|
1455 |
} |
|
1456 |
} |
|
1457 |
if (ids[0] != null) { |
|
1458 |
String idName = ids[0]; |
|
1459 |
childMapping = mapping.getChildSelectorMapping( |
|
1460 |
tagString + "#" + idName, false); |
|
1461 |
if (childMapping != null) { |
|
1462 |
getStyles(childMapping, tempVector, tags, ids, classes, |
|
1463 |
1, numElements, tempHashtable); |
|
1464 |
} |
|
1465 |
childMapping = mapping.getChildSelectorMapping( |
|
1466 |
"#" + idName, false); |
|
1467 |
if (childMapping != null) { |
|
1468 |
getStyles(childMapping, tempVector, tags, ids, classes, |
|
1469 |
1, numElements, tempHashtable); |
|
1470 |
} |
|
1471 |
} |
|
1472 |
// Create a new Style that will delegate to all the matching |
|
1473 |
// Styles. |
|
1474 |
int numLinkedSS = (linkedStyleSheets != null) ? |
|
1475 |
linkedStyleSheets.size() : 0; |
|
1476 |
int numStyles = tempVector.size(); |
|
1477 |
AttributeSet[] attrs = new AttributeSet[numStyles + numLinkedSS]; |
|
1478 |
for (int counter = 0; counter < numStyles; counter++) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1479 |
attrs[counter] = tempVector.elementAt(counter).getStyle(); |
2 | 1480 |
} |
1481 |
// Get the AttributeSet from linked style sheets. |
|
1482 |
for (int counter = 0; counter < numLinkedSS; counter++) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1483 |
AttributeSet attr = linkedStyleSheets.elementAt(counter).getRule(selector); |
2 | 1484 |
if (attr == null) { |
1485 |
attrs[counter + numStyles] = SimpleAttributeSet.EMPTY; |
|
1486 |
} |
|
1487 |
else { |
|
1488 |
attrs[counter + numStyles] = attr; |
|
1489 |
} |
|
1490 |
} |
|
1491 |
ResolvedStyle retStyle = new ResolvedStyle(selector, attrs, |
|
1492 |
numStyles); |
|
1493 |
resolvedStyles.put(selector, retStyle); |
|
1494 |
return retStyle; |
|
1495 |
} |
|
1496 |
finally { |
|
1497 |
SearchBuffer.releaseSearchBuffer(sb); |
|
1498 |
} |
|
1499 |
} |
|
1500 |
||
1501 |
/** |
|
1502 |
* Creates and returns a Style containing all the rules that |
|
1503 |
* matches <code>selector</code>. |
|
1504 |
* |
|
1505 |
* @param elements a Vector of all the Elements |
|
1506 |
* the style is being asked for. The |
|
1507 |
* first Element is the deepest Element, with the last Element |
|
1508 |
* representing the root. |
|
1509 |
* @param t the Tag to use for |
|
1510 |
* the first Element in <code>elements</code> |
|
1511 |
*/ |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
1512 |
private Style createResolvedStyle(String selector, Vector<Element> elements, |
2 | 1513 |
HTML.Tag t) { |
1514 |
int numElements = elements.size(); |
|
1515 |
// Build three arrays, one for tags, one for class's, and one for |
|
1516 |
// id's |
|
1517 |
String tags[] = new String[numElements]; |
|
1518 |
String ids[] = new String[numElements]; |
|
1519 |
String classes[] = new String[numElements]; |
|
1520 |
for (int counter = 0; counter < numElements; counter++) { |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
1521 |
Element e = elements.elementAt(counter); |
2 | 1522 |
AttributeSet attr = e.getAttributes(); |
1523 |
if (counter == 0 && e.isLeaf()) { |
|
1524 |
// For leafs, we use the second tier attributes. |
|
1525 |
Object testAttr = attr.getAttribute(t); |
|
1526 |
if (testAttr instanceof AttributeSet) { |
|
1527 |
attr = (AttributeSet)testAttr; |
|
1528 |
} |
|
1529 |
else { |
|
1530 |
attr = null; |
|
1531 |
} |
|
1532 |
} |
|
1533 |
if (attr != null) { |
|
1534 |
HTML.Tag tag = (HTML.Tag)attr.getAttribute(StyleConstants. |
|
1535 |
NameAttribute); |
|
1536 |
if (tag != null) { |
|
1537 |
tags[counter] = tag.toString(); |
|
1538 |
} |
|
1539 |
else { |
|
1540 |
tags[counter] = null; |
|
1541 |
} |
|
1542 |
if (attr.isDefined(HTML.Attribute.CLASS)) { |
|
1543 |
classes[counter] = attr.getAttribute |
|
1544 |
(HTML.Attribute.CLASS).toString(); |
|
1545 |
} |
|
1546 |
else { |
|
1547 |
classes[counter] = null; |
|
1548 |
} |
|
1549 |
if (attr.isDefined(HTML.Attribute.ID)) { |
|
1550 |
ids[counter] = attr.getAttribute(HTML.Attribute.ID). |
|
1551 |
toString(); |
|
1552 |
} |
|
1553 |
else { |
|
1554 |
ids[counter] = null; |
|
1555 |
} |
|
1556 |
} |
|
1557 |
else { |
|
1558 |
tags[counter] = ids[counter] = classes[counter] = null; |
|
1559 |
} |
|
1560 |
} |
|
1561 |
tags[0] = t.toString(); |
|
1562 |
return createResolvedStyle(selector, tags, ids, classes); |
|
1563 |
} |
|
1564 |
||
1565 |
/** |
|
1566 |
* Creates and returns a Style containing all the rules that match |
|
1567 |
* <code>selector</code>. It is assumed that each simple selector |
|
1568 |
* in <code>selector</code> is separated by a space. |
|
1569 |
*/ |
|
1570 |
private Style createResolvedStyle(String selector) { |
|
1571 |
SearchBuffer sb = SearchBuffer.obtainSearchBuffer(); |
|
1572 |
// Will contain the tags, ids, and classes, in that order. |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
1573 |
@SuppressWarnings("unchecked") |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1574 |
Vector<String> elements = sb.getVector(); |
2 | 1575 |
try { |
1576 |
boolean done; |
|
1577 |
int dotIndex = 0; |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1578 |
int spaceIndex; |
2 | 1579 |
int poundIndex = 0; |
1580 |
int lastIndex = 0; |
|
1581 |
int length = selector.length(); |
|
1582 |
while (lastIndex < length) { |
|
1583 |
if (dotIndex == lastIndex) { |
|
1584 |
dotIndex = selector.indexOf('.', lastIndex); |
|
1585 |
} |
|
1586 |
if (poundIndex == lastIndex) { |
|
1587 |
poundIndex = selector.indexOf('#', lastIndex); |
|
1588 |
} |
|
1589 |
spaceIndex = selector.indexOf(' ', lastIndex); |
|
1590 |
if (spaceIndex == -1) { |
|
1591 |
spaceIndex = length; |
|
1592 |
} |
|
1593 |
if (dotIndex != -1 && poundIndex != -1 && |
|
1594 |
dotIndex < spaceIndex && poundIndex < spaceIndex) { |
|
1595 |
if (poundIndex < dotIndex) { |
|
1596 |
// #. |
|
1597 |
if (lastIndex == poundIndex) { |
|
1598 |
elements.addElement(""); |
|
1599 |
} |
|
1600 |
else { |
|
1601 |
elements.addElement(selector.substring(lastIndex, |
|
1602 |
poundIndex)); |
|
1603 |
} |
|
1604 |
if ((dotIndex + 1) < spaceIndex) { |
|
1605 |
elements.addElement(selector.substring |
|
1606 |
(dotIndex + 1, spaceIndex)); |
|
1607 |
} |
|
1608 |
else { |
|
1609 |
elements.addElement(null); |
|
1610 |
} |
|
1611 |
if ((poundIndex + 1) == dotIndex) { |
|
1612 |
elements.addElement(null); |
|
1613 |
} |
|
1614 |
else { |
|
1615 |
elements.addElement(selector.substring |
|
1616 |
(poundIndex + 1, dotIndex)); |
|
1617 |
} |
|
1618 |
} |
|
1619 |
else if(poundIndex < spaceIndex) { |
|
1620 |
// .# |
|
1621 |
if (lastIndex == dotIndex) { |
|
1622 |
elements.addElement(""); |
|
1623 |
} |
|
1624 |
else { |
|
1625 |
elements.addElement(selector.substring(lastIndex, |
|
1626 |
dotIndex)); |
|
1627 |
} |
|
1628 |
if ((dotIndex + 1) < poundIndex) { |
|
1629 |
elements.addElement(selector.substring |
|
1630 |
(dotIndex + 1, poundIndex)); |
|
1631 |
} |
|
1632 |
else { |
|
1633 |
elements.addElement(null); |
|
1634 |
} |
|
1635 |
if ((poundIndex + 1) == spaceIndex) { |
|
1636 |
elements.addElement(null); |
|
1637 |
} |
|
1638 |
else { |
|
1639 |
elements.addElement(selector.substring |
|
1640 |
(poundIndex + 1, spaceIndex)); |
|
1641 |
} |
|
1642 |
} |
|
1643 |
dotIndex = poundIndex = spaceIndex + 1; |
|
1644 |
} |
|
1645 |
else if (dotIndex != -1 && dotIndex < spaceIndex) { |
|
1646 |
// . |
|
1647 |
if (dotIndex == lastIndex) { |
|
1648 |
elements.addElement(""); |
|
1649 |
} |
|
1650 |
else { |
|
1651 |
elements.addElement(selector.substring(lastIndex, |
|
1652 |
dotIndex)); |
|
1653 |
} |
|
1654 |
if ((dotIndex + 1) == spaceIndex) { |
|
1655 |
elements.addElement(null); |
|
1656 |
} |
|
1657 |
else { |
|
1658 |
elements.addElement(selector.substring(dotIndex + 1, |
|
1659 |
spaceIndex)); |
|
1660 |
} |
|
1661 |
elements.addElement(null); |
|
1662 |
dotIndex = spaceIndex + 1; |
|
1663 |
} |
|
1664 |
else if (poundIndex != -1 && poundIndex < spaceIndex) { |
|
1665 |
// # |
|
1666 |
if (poundIndex == lastIndex) { |
|
1667 |
elements.addElement(""); |
|
1668 |
} |
|
1669 |
else { |
|
1670 |
elements.addElement(selector.substring(lastIndex, |
|
1671 |
poundIndex)); |
|
1672 |
} |
|
1673 |
elements.addElement(null); |
|
1674 |
if ((poundIndex + 1) == spaceIndex) { |
|
1675 |
elements.addElement(null); |
|
1676 |
} |
|
1677 |
else { |
|
1678 |
elements.addElement(selector.substring(poundIndex + 1, |
|
1679 |
spaceIndex)); |
|
1680 |
} |
|
1681 |
poundIndex = spaceIndex + 1; |
|
1682 |
} |
|
1683 |
else { |
|
1684 |
// id |
|
1685 |
elements.addElement(selector.substring(lastIndex, |
|
1686 |
spaceIndex)); |
|
1687 |
elements.addElement(null); |
|
1688 |
elements.addElement(null); |
|
1689 |
} |
|
1690 |
lastIndex = spaceIndex + 1; |
|
1691 |
} |
|
1692 |
// Create the tag, id, and class arrays. |
|
1693 |
int total = elements.size(); |
|
1694 |
int numTags = total / 3; |
|
1695 |
String[] tags = new String[numTags]; |
|
1696 |
String[] ids = new String[numTags]; |
|
1697 |
String[] classes = new String[numTags]; |
|
1698 |
for (int index = 0, eIndex = total - 3; index < numTags; |
|
1699 |
index++, eIndex -= 3) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1700 |
tags[index] = elements.elementAt(eIndex); |
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1701 |
classes[index] = elements.elementAt(eIndex + 1); |
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1702 |
ids[index] = elements.elementAt(eIndex + 2); |
2 | 1703 |
} |
1704 |
return createResolvedStyle(selector, tags, ids, classes); |
|
1705 |
} |
|
1706 |
finally { |
|
1707 |
SearchBuffer.releaseSearchBuffer(sb); |
|
1708 |
} |
|
1709 |
} |
|
1710 |
||
1711 |
/** |
|
1712 |
* Should be invoked when a new rule is added that did not previously |
|
1713 |
* exist. Goes through and refreshes the necessary resolved |
|
1714 |
* rules. |
|
1715 |
*/ |
|
1716 |
private synchronized void refreshResolvedRules(String selectorName, |
|
1717 |
String[] selector, |
|
1718 |
Style newStyle, |
|
1719 |
int specificity) { |
|
1720 |
if (resolvedStyles.size() > 0) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1721 |
Enumeration<ResolvedStyle> values = resolvedStyles.elements(); |
2 | 1722 |
while (values.hasMoreElements()) { |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1723 |
ResolvedStyle style = values.nextElement(); |
2 | 1724 |
if (style.matches(selectorName)) { |
1725 |
style.insertStyle(newStyle, specificity); |
|
1726 |
} |
|
1727 |
} |
|
1728 |
} |
|
1729 |
} |
|
1730 |
||
1731 |
||
1732 |
/** |
|
1733 |
* A temporary class used to hold a Vector, a StringBuffer and a |
|
1734 |
* Hashtable. This is used to avoid allocing a lot of garbage when |
|
1735 |
* searching for rules. Use the static method obtainSearchBuffer and |
|
1736 |
* releaseSearchBuffer to get a SearchBuffer, and release it when |
|
1737 |
* done. |
|
1738 |
*/ |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
1739 |
@SuppressWarnings("rawtypes") |
2 | 1740 |
private static class SearchBuffer { |
1741 |
/** A stack containing instances of SearchBuffer. Used in getting |
|
1742 |
* rules. */ |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1743 |
static Stack<SearchBuffer> searchBuffers = new Stack<SearchBuffer>(); |
2 | 1744 |
// A set of temporary variables that can be used in whatever way. |
1745 |
Vector vector = null; |
|
1746 |
StringBuffer stringBuffer = null; |
|
1747 |
Hashtable hashtable = null; |
|
1748 |
||
1749 |
/** |
|
1750 |
* Returns an instance of SearchBuffer. Be sure and issue |
|
1751 |
* a releaseSearchBuffer when done with it. |
|
1752 |
*/ |
|
1753 |
static SearchBuffer obtainSearchBuffer() { |
|
1754 |
SearchBuffer sb; |
|
1755 |
try { |
|
1756 |
if(!searchBuffers.empty()) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1757 |
sb = searchBuffers.pop(); |
2 | 1758 |
} else { |
1759 |
sb = new SearchBuffer(); |
|
1760 |
} |
|
1761 |
} catch (EmptyStackException ese) { |
|
1762 |
sb = new SearchBuffer(); |
|
1763 |
} |
|
1764 |
return sb; |
|
1765 |
} |
|
1766 |
||
1767 |
/** |
|
1768 |
* Adds <code>sb</code> to the stack of SearchBuffers that can |
|
1769 |
* be used. |
|
1770 |
*/ |
|
1771 |
static void releaseSearchBuffer(SearchBuffer sb) { |
|
1772 |
sb.empty(); |
|
1773 |
searchBuffers.push(sb); |
|
1774 |
} |
|
1775 |
||
1776 |
StringBuffer getStringBuffer() { |
|
1777 |
if (stringBuffer == null) { |
|
1778 |
stringBuffer = new StringBuffer(); |
|
1779 |
} |
|
1780 |
return stringBuffer; |
|
1781 |
} |
|
1782 |
||
1783 |
Vector getVector() { |
|
1784 |
if (vector == null) { |
|
1785 |
vector = new Vector(); |
|
1786 |
} |
|
1787 |
return vector; |
|
1788 |
} |
|
1789 |
||
1790 |
Hashtable getHashtable() { |
|
1791 |
if (hashtable == null) { |
|
1792 |
hashtable = new Hashtable(); |
|
1793 |
} |
|
1794 |
return hashtable; |
|
1795 |
} |
|
1796 |
||
1797 |
void empty() { |
|
1798 |
if (stringBuffer != null) { |
|
1799 |
stringBuffer.setLength(0); |
|
1800 |
} |
|
1801 |
if (vector != null) { |
|
1802 |
vector.removeAllElements(); |
|
1803 |
} |
|
1804 |
if (hashtable != null) { |
|
1805 |
hashtable.clear(); |
|
1806 |
} |
|
1807 |
} |
|
1808 |
} |
|
1809 |
||
1810 |
||
1811 |
static final Border noBorder = new EmptyBorder(0,0,0,0); |
|
1812 |
||
1813 |
/** |
|
1814 |
* Class to carry out some of the duties of |
|
1815 |
* CSS formatting. Implementations of this |
|
1816 |
* class enable views to present the CSS formatting |
|
1817 |
* while not knowing anything about how the CSS values |
|
1818 |
* are being cached. |
|
1819 |
* <p> |
|
1820 |
* As a delegate of Views, this object is responsible for |
|
1821 |
* the insets of a View and making sure the background |
|
1822 |
* is maintained according to the CSS attributes. |
|
1823 |
*/ |
|
23697 | 1824 |
@SuppressWarnings("serial") // Same-version serialization only |
2 | 1825 |
public static class BoxPainter implements Serializable { |
1826 |
||
1827 |
BoxPainter(AttributeSet a, CSS css, StyleSheet ss) { |
|
1828 |
this.ss = ss; |
|
1829 |
this.css = css; |
|
1830 |
border = getBorder(a); |
|
1831 |
binsets = border.getBorderInsets(null); |
|
1832 |
topMargin = getLength(CSS.Attribute.MARGIN_TOP, a); |
|
1833 |
bottomMargin = getLength(CSS.Attribute.MARGIN_BOTTOM, a); |
|
1834 |
leftMargin = getLength(CSS.Attribute.MARGIN_LEFT, a); |
|
1835 |
rightMargin = getLength(CSS.Attribute.MARGIN_RIGHT, a); |
|
1836 |
bg = ss.getBackground(a); |
|
1837 |
if (ss.getBackgroundImage(a) != null) { |
|
1838 |
bgPainter = new BackgroundImagePainter(a, css, ss); |
|
1839 |
} |
|
1840 |
} |
|
1841 |
||
1842 |
/** |
|
1843 |
* Fetches a border to render for the given attributes. |
|
1844 |
* PENDING(prinz) This is pretty badly hacked at the |
|
1845 |
* moment. |
|
1846 |
*/ |
|
1847 |
Border getBorder(AttributeSet a) { |
|
1848 |
return new CSSBorder(a); |
|
1849 |
} |
|
1850 |
||
1851 |
/** |
|
1852 |
* Fetches the color to use for borders. This will either be |
|
1853 |
* the value specified by the border-color attribute (which |
|
1854 |
* is not inherited), or it will default to the color attribute |
|
1855 |
* (which is inherited). |
|
1856 |
*/ |
|
1857 |
Color getBorderColor(AttributeSet a) { |
|
1858 |
Color color = css.getColor(a, CSS.Attribute.BORDER_COLOR); |
|
1859 |
if (color == null) { |
|
1860 |
color = css.getColor(a, CSS.Attribute.COLOR); |
|
1861 |
if (color == null) { |
|
1862 |
return Color.black; |
|
1863 |
} |
|
1864 |
} |
|
1865 |
return color; |
|
1866 |
} |
|
1867 |
||
1868 |
/** |
|
1869 |
* Fetches the inset needed on a given side to |
|
1870 |
* account for the margin, border, and padding. |
|
1871 |
* |
|
1872 |
* @param side The size of the box to fetch the |
|
1873 |
* inset for. This can be View.TOP, |
|
1874 |
* View.LEFT, View.BOTTOM, or View.RIGHT. |
|
1875 |
* @param v the view making the request. This is |
|
1876 |
* used to get the AttributeSet, and may be used to |
|
1877 |
* resolve percentage arguments. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24528
diff
changeset
|
1878 |
* @return the inset needed for the margin, border and padding. |
2 | 1879 |
* @exception IllegalArgumentException for an invalid direction |
1880 |
*/ |
|
1881 |
public float getInset(int side, View v) { |
|
1882 |
AttributeSet a = v.getAttributes(); |
|
1883 |
float inset = 0; |
|
1884 |
switch(side) { |
|
1885 |
case View.LEFT: |
|
1886 |
inset += getOrientationMargin(HorizontalMargin.LEFT, |
|
1887 |
leftMargin, a, isLeftToRight(v)); |
|
1888 |
inset += binsets.left; |
|
1889 |
inset += getLength(CSS.Attribute.PADDING_LEFT, a); |
|
1890 |
break; |
|
1891 |
case View.RIGHT: |
|
1892 |
inset += getOrientationMargin(HorizontalMargin.RIGHT, |
|
1893 |
rightMargin, a, isLeftToRight(v)); |
|
1894 |
inset += binsets.right; |
|
1895 |
inset += getLength(CSS.Attribute.PADDING_RIGHT, a); |
|
1896 |
break; |
|
1897 |
case View.TOP: |
|
1898 |
inset += topMargin; |
|
1899 |
inset += binsets.top; |
|
1900 |
inset += getLength(CSS.Attribute.PADDING_TOP, a); |
|
1901 |
break; |
|
1902 |
case View.BOTTOM: |
|
1903 |
inset += bottomMargin; |
|
1904 |
inset += binsets.bottom; |
|
1905 |
inset += getLength(CSS.Attribute.PADDING_BOTTOM, a); |
|
1906 |
break; |
|
1907 |
default: |
|
1908 |
throw new IllegalArgumentException("Invalid side: " + side); |
|
1909 |
} |
|
1910 |
return inset; |
|
1911 |
} |
|
1912 |
||
1913 |
/** |
|
1914 |
* Paints the CSS box according to the attributes |
|
1915 |
* given. This should paint the border, padding, |
|
1916 |
* and background. |
|
1917 |
* |
|
1918 |
* @param g the rendering surface. |
|
1919 |
* @param x the x coordinate of the allocated area to |
|
1920 |
* render into. |
|
1921 |
* @param y the y coordinate of the allocated area to |
|
1922 |
* render into. |
|
1923 |
* @param w the width of the allocated area to render into. |
|
1924 |
* @param h the height of the allocated area to render into. |
|
1925 |
* @param v the view making the request. This is |
|
1926 |
* used to get the AttributeSet, and may be used to |
|
1927 |
* resolve percentage arguments. |
|
1928 |
*/ |
|
1929 |
public void paint(Graphics g, float x, float y, float w, float h, View v) { |
|
1930 |
// PENDING(prinz) implement real rendering... which would |
|
1931 |
// do full set of border and background capabilities. |
|
1932 |
// remove margin |
|
1933 |
||
1934 |
float dx = 0; |
|
1935 |
float dy = 0; |
|
1936 |
float dw = 0; |
|
1937 |
float dh = 0; |
|
1938 |
AttributeSet a = v.getAttributes(); |
|
1939 |
boolean isLeftToRight = isLeftToRight(v); |
|
1940 |
float localLeftMargin = getOrientationMargin(HorizontalMargin.LEFT, |
|
1941 |
leftMargin, |
|
1942 |
a, isLeftToRight); |
|
1943 |
float localRightMargin = getOrientationMargin(HorizontalMargin.RIGHT, |
|
1944 |
rightMargin, |
|
1945 |
a, isLeftToRight); |
|
1946 |
if (!(v instanceof HTMLEditorKit.HTMLFactory.BodyBlockView)) { |
|
1947 |
dx = localLeftMargin; |
|
1948 |
dy = topMargin; |
|
1949 |
dw = -(localLeftMargin + localRightMargin); |
|
1950 |
dh = -(topMargin + bottomMargin); |
|
1951 |
} |
|
1952 |
if (bg != null) { |
|
1953 |
g.setColor(bg); |
|
1954 |
g.fillRect((int) (x + dx), |
|
1955 |
(int) (y + dy), |
|
1956 |
(int) (w + dw), |
|
1957 |
(int) (h + dh)); |
|
1958 |
} |
|
1959 |
if (bgPainter != null) { |
|
1960 |
bgPainter.paint(g, x + dx, y + dy, w + dw, h + dh, v); |
|
1961 |
} |
|
1962 |
x += localLeftMargin; |
|
1963 |
y += topMargin; |
|
1964 |
w -= localLeftMargin + localRightMargin; |
|
1965 |
h -= topMargin + bottomMargin; |
|
1966 |
if (border instanceof BevelBorder) { |
|
1967 |
//BevelBorder does not support border width |
|
1968 |
int bw = (int) getLength(CSS.Attribute.BORDER_TOP_WIDTH, a); |
|
1969 |
for (int i = bw - 1; i >= 0; i--) { |
|
1970 |
border.paintBorder(null, g, (int) x + i, (int) y + i, |
|
1971 |
(int) w - 2 * i, (int) h - 2 * i); |
|
1972 |
} |
|
1973 |
} else { |
|
1974 |
border.paintBorder(null, g, (int) x, (int) y, (int) w, (int) h); |
|
1975 |
} |
|
1976 |
} |
|
1977 |
||
1978 |
float getLength(CSS.Attribute key, AttributeSet a) { |
|
1979 |
return css.getLength(a, key, ss); |
|
1980 |
} |
|
1981 |
||
1982 |
static boolean isLeftToRight(View v) { |
|
1983 |
boolean ret = true; |
|
1984 |
if (isOrientationAware(v)) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
1985 |
Container container; |
2 | 1986 |
if (v != null && (container = v.getContainer()) != null) { |
1987 |
ret = container.getComponentOrientation().isLeftToRight(); |
|
1988 |
} |
|
1989 |
} |
|
1990 |
return ret; |
|
1991 |
} |
|
1992 |
||
1993 |
/* |
|
1994 |
* only certain tags are concerned about orientation |
|
1995 |
* <dir>, <menu>, <ul>, <ol> |
|
1996 |
* for all others we return true. It is implemented this way |
|
1997 |
* for performance purposes |
|
1998 |
*/ |
|
1999 |
static boolean isOrientationAware(View v) { |
|
2000 |
boolean ret = false; |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
2001 |
AttributeSet attr; |
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
2002 |
Object obj; |
2 | 2003 |
if (v != null |
2004 |
&& (attr = v.getElement().getAttributes()) != null |
|
2005 |
&& (obj = attr.getAttribute(StyleConstants.NameAttribute)) instanceof HTML.Tag |
|
2006 |
&& (obj == HTML.Tag.DIR |
|
2007 |
|| obj == HTML.Tag.MENU |
|
2008 |
|| obj == HTML.Tag.UL |
|
2009 |
|| obj == HTML.Tag.OL)) { |
|
2010 |
ret = true; |
|
2011 |
} |
|
2012 |
||
2013 |
return ret; |
|
2014 |
} |
|
2015 |
||
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
2016 |
static enum HorizontalMargin { LEFT, RIGHT } |
2 | 2017 |
|
2018 |
/** |
|
2019 |
* for <dir>, <menu>, <ul> etc. |
|
2020 |
* margins are Left-To-Right/Right-To-Left depended. |
|
2021 |
* see 5088268 for more details |
|
2022 |
* margin-(left|right)-(ltr|rtl) were introduced to describe it |
|
2023 |
* if margin-(left|right) is present we are to use it. |
|
2024 |
* |
|
2025 |
* @param side The horizontal side to fetch margin for |
|
2026 |
* This can be HorizontalMargin.LEFT or HorizontalMargin.RIGHT |
|
2027 |
* @param cssMargin margin from css |
|
2028 |
* @param a AttributeSet for the View we getting margin for |
|
2029 |
* @param isLeftToRight |
|
2030 |
* @return orientation depended margin |
|
2031 |
*/ |
|
2032 |
float getOrientationMargin(HorizontalMargin side, float cssMargin, |
|
2033 |
AttributeSet a, boolean isLeftToRight) { |
|
2034 |
float margin = cssMargin; |
|
2035 |
float orientationMargin = cssMargin; |
|
2036 |
Object cssMarginValue = null; |
|
2037 |
switch (side) { |
|
2038 |
case RIGHT: |
|
2039 |
{ |
|
2040 |
orientationMargin = (isLeftToRight) ? |
|
2041 |
getLength(CSS.Attribute.MARGIN_RIGHT_LTR, a) : |
|
2042 |
getLength(CSS.Attribute.MARGIN_RIGHT_RTL, a); |
|
2043 |
cssMarginValue = a.getAttribute(CSS.Attribute.MARGIN_RIGHT); |
|
2044 |
} |
|
2045 |
break; |
|
2046 |
case LEFT : |
|
2047 |
{ |
|
2048 |
orientationMargin = (isLeftToRight) ? |
|
2049 |
getLength(CSS.Attribute.MARGIN_LEFT_LTR, a) : |
|
2050 |
getLength(CSS.Attribute.MARGIN_LEFT_RTL, a); |
|
2051 |
cssMarginValue = a.getAttribute(CSS.Attribute.MARGIN_LEFT); |
|
2052 |
} |
|
2053 |
break; |
|
2054 |
} |
|
2055 |
||
2056 |
if (cssMarginValue == null |
|
2057 |
&& orientationMargin != Integer.MIN_VALUE) { |
|
2058 |
margin = orientationMargin; |
|
2059 |
} |
|
2060 |
return margin; |
|
2061 |
} |
|
2062 |
||
2063 |
float topMargin; |
|
2064 |
float bottomMargin; |
|
2065 |
float leftMargin; |
|
2066 |
float rightMargin; |
|
2067 |
// Bitmask, used to indicate what margins are relative: |
|
2068 |
// bit 0 for top, 1 for bottom, 2 for left and 3 for right. |
|
2069 |
short marginFlags; |
|
2070 |
Border border; |
|
2071 |
Insets binsets; |
|
2072 |
CSS css; |
|
2073 |
StyleSheet ss; |
|
2074 |
Color bg; |
|
2075 |
BackgroundImagePainter bgPainter; |
|
2076 |
} |
|
2077 |
||
2078 |
/** |
|
2079 |
* Class to carry out some of the duties of CSS list |
|
2080 |
* formatting. Implementations of this |
|
2081 |
* class enable views to present the CSS formatting |
|
2082 |
* while not knowing anything about how the CSS values |
|
2083 |
* are being cached. |
|
2084 |
*/ |
|
23697 | 2085 |
@SuppressWarnings("serial") // Same-version serialization only |
2 | 2086 |
public static class ListPainter implements Serializable { |
2087 |
||
2088 |
ListPainter(AttributeSet attr, StyleSheet ss) { |
|
2089 |
this.ss = ss; |
|
2090 |
/* Get the image to use as a list bullet */ |
|
2091 |
String imgstr = (String)attr.getAttribute(CSS.Attribute. |
|
2092 |
LIST_STYLE_IMAGE); |
|
2093 |
type = null; |
|
2094 |
if (imgstr != null && !imgstr.equals("none")) { |
|
2095 |
String tmpstr = null; |
|
2096 |
try { |
|
2097 |
StringTokenizer st = new StringTokenizer(imgstr, "()"); |
|
2098 |
if (st.hasMoreTokens()) |
|
2099 |
tmpstr = st.nextToken(); |
|
2100 |
if (st.hasMoreTokens()) |
|
2101 |
tmpstr = st.nextToken(); |
|
2102 |
URL u = new URL(tmpstr); |
|
2103 |
img = new ImageIcon(u); |
|
2104 |
} catch (MalformedURLException e) { |
|
2105 |
if (tmpstr != null && ss != null && ss.getBase() != null) { |
|
2106 |
try { |
|
2107 |
URL u = new URL(ss.getBase(), tmpstr); |
|
2108 |
img = new ImageIcon(u); |
|
2109 |
} catch (MalformedURLException murle) { |
|
2110 |
img = null; |
|
2111 |
} |
|
2112 |
} |
|
2113 |
else { |
|
2114 |
img = null; |
|
2115 |
} |
|
2116 |
} |
|
2117 |
} |
|
2118 |
||
2119 |
/* Get the type of bullet to use in the list */ |
|
2120 |
if (img == null) { |
|
2121 |
type = (CSS.Value)attr.getAttribute(CSS.Attribute. |
|
2122 |
LIST_STYLE_TYPE); |
|
2123 |
} |
|
2124 |
start = 1; |
|
2125 |
||
2126 |
paintRect = new Rectangle(); |
|
2127 |
} |
|
2128 |
||
2129 |
/** |
|
2130 |
* Returns a string that represents the value |
|
2131 |
* of the HTML.Attribute.TYPE attribute. |
|
2132 |
* If this attributes is not defined, then |
|
2133 |
* then the type defaults to "disc" unless |
|
2134 |
* the tag is on Ordered list. In the case |
|
2135 |
* of the latter, the default type is "decimal". |
|
2136 |
*/ |
|
2137 |
private CSS.Value getChildType(View childView) { |
|
2138 |
CSS.Value childtype = (CSS.Value)childView.getAttributes(). |
|
2139 |
getAttribute(CSS.Attribute.LIST_STYLE_TYPE); |
|
2140 |
||
2141 |
if (childtype == null) { |
|
2142 |
if (type == null) { |
|
2143 |
// Parent view. |
|
2144 |
View v = childView.getParent(); |
|
2145 |
HTMLDocument doc = (HTMLDocument)v.getDocument(); |
|
22567
5816a47fa4dd
8032047: Fix static lint warnings in client libraries
darcy
parents:
22260
diff
changeset
|
2146 |
if (HTMLDocument.matchNameAttribute(v.getElement().getAttributes(), |
5816a47fa4dd
8032047: Fix static lint warnings in client libraries
darcy
parents:
22260
diff
changeset
|
2147 |
HTML.Tag.OL)) { |
2 | 2148 |
childtype = CSS.Value.DECIMAL; |
2149 |
} else { |
|
2150 |
childtype = CSS.Value.DISC; |
|
2151 |
} |
|
2152 |
} else { |
|
2153 |
childtype = type; |
|
2154 |
} |
|
2155 |
} |
|
2156 |
return childtype; |
|
2157 |
} |
|
2158 |
||
2159 |
/** |
|
2160 |
* Obtains the starting index from <code>parent</code>. |
|
2161 |
*/ |
|
2162 |
private void getStart(View parent) { |
|
2163 |
checkedForStart = true; |
|
2164 |
Element element = parent.getElement(); |
|
2165 |
if (element != null) { |
|
2166 |
AttributeSet attr = element.getAttributes(); |
|
2167 |
Object startValue; |
|
2168 |
if (attr != null && attr.isDefined(HTML.Attribute.START) && |
|
2169 |
(startValue = attr.getAttribute |
|
2170 |
(HTML.Attribute.START)) != null && |
|
2171 |
(startValue instanceof String)) { |
|
2172 |
||
2173 |
try { |
|
2174 |
start = Integer.parseInt((String)startValue); |
|
2175 |
} |
|
2176 |
catch (NumberFormatException nfe) {} |
|
2177 |
} |
|
2178 |
} |
|
2179 |
} |
|
2180 |
||
2181 |
/** |
|
2182 |
* Returns an integer that should be used to render the child at |
|
2183 |
* <code>childIndex</code> with. The retValue will usually be |
|
2184 |
* <code>childIndex</code> + 1, unless <code>parentView</code> |
|
2185 |
* has some Views that do not represent LI's, or one of the views |
|
2186 |
* has a HTML.Attribute.START specified. |
|
2187 |
*/ |
|
2188 |
private int getRenderIndex(View parentView, int childIndex) { |
|
2189 |
if (!checkedForStart) { |
|
2190 |
getStart(parentView); |
|
2191 |
} |
|
2192 |
int retIndex = childIndex; |
|
2193 |
for (int counter = childIndex; counter >= 0; counter--) { |
|
2194 |
AttributeSet as = parentView.getElement().getElement(counter). |
|
2195 |
getAttributes(); |
|
2196 |
if (as.getAttribute(StyleConstants.NameAttribute) != |
|
2197 |
HTML.Tag.LI) { |
|
2198 |
retIndex--; |
|
2199 |
} else if (as.isDefined(HTML.Attribute.VALUE)) { |
|
2200 |
Object value = as.getAttribute(HTML.Attribute.VALUE); |
|
2201 |
if (value != null && |
|
2202 |
(value instanceof String)) { |
|
2203 |
try { |
|
2204 |
int iValue = Integer.parseInt((String)value); |
|
2205 |
return retIndex - counter + iValue; |
|
2206 |
} |
|
2207 |
catch (NumberFormatException nfe) {} |
|
2208 |
} |
|
2209 |
} |
|
2210 |
} |
|
2211 |
return retIndex + start; |
|
2212 |
} |
|
2213 |
||
2214 |
/** |
|
2215 |
* Paints the CSS list decoration according to the |
|
2216 |
* attributes given. |
|
2217 |
* |
|
2218 |
* @param g the rendering surface. |
|
2219 |
* @param x the x coordinate of the list item allocation |
|
2220 |
* @param y the y coordinate of the list item allocation |
|
2221 |
* @param w the width of the list item allocation |
|
2222 |
* @param h the height of the list item allocation |
|
2223 |
* @param v the allocated area to paint into. |
|
2224 |
* @param item which list item is being painted. This |
|
2225 |
* is a number greater than or equal to 0. |
|
2226 |
*/ |
|
2227 |
public void paint(Graphics g, float x, float y, float w, float h, View v, int item) { |
|
2228 |
View cv = v.getView(item); |
|
2493
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2229 |
Container host = v.getContainer(); |
2 | 2230 |
Object name = cv.getElement().getAttributes().getAttribute |
2231 |
(StyleConstants.NameAttribute); |
|
2232 |
// Only draw something if the View is a list item. This won't |
|
2233 |
// be the case for comments. |
|
2234 |
if (!(name instanceof HTML.Tag) || |
|
2235 |
name != HTML.Tag.LI) { |
|
2236 |
return; |
|
2237 |
} |
|
2238 |
// deside on what side draw bullets, etc. |
|
2239 |
isLeftToRight = |
|
2493
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2240 |
host.getComponentOrientation().isLeftToRight(); |
2 | 2241 |
|
2242 |
// How the list indicator is aligned is not specified, it is |
|
2243 |
// left up to the UA. IE and NS differ on this behavior. |
|
2244 |
// This is closer to NS where we align to the first line of text. |
|
2245 |
// If the child is not text we draw the indicator at the |
|
2246 |
// origin (0). |
|
2247 |
float align = 0; |
|
2248 |
if (cv.getViewCount() > 0) { |
|
2249 |
View pView = cv.getView(0); |
|
2250 |
Object cName = pView.getElement().getAttributes(). |
|
2251 |
getAttribute(StyleConstants.NameAttribute); |
|
2252 |
if ((cName == HTML.Tag.P || cName == HTML.Tag.IMPLIED) && |
|
2253 |
pView.getViewCount() > 0) { |
|
2254 |
paintRect.setBounds((int)x, (int)y, (int)w, (int)h); |
|
2255 |
Shape shape = cv.getChildAllocation(0, paintRect); |
|
2256 |
if (shape != null && (shape = pView.getView(0). |
|
2257 |
getChildAllocation(0, shape)) != null) { |
|
2258 |
Rectangle rect = (shape instanceof Rectangle) ? |
|
2259 |
(Rectangle)shape : shape.getBounds(); |
|
2260 |
||
2261 |
align = pView.getView(0).getAlignment(View.Y_AXIS); |
|
2262 |
y = rect.y; |
|
2263 |
h = rect.height; |
|
2264 |
} |
|
2265 |
} |
|
2266 |
} |
|
2267 |
||
2268 |
// set the color of a decoration |
|
2493
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2269 |
Color c = (host.isEnabled() |
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2270 |
? (ss != null |
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2271 |
? ss.getForeground(cv.getAttributes()) |
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2272 |
: host.getForeground()) |
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2273 |
: UIManager.getColor("textInactiveText")); |
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2274 |
g.setColor(c); |
2 | 2275 |
|
2276 |
if (img != null) { |
|
2493
93a357c96600
4783068: Components with HTML text should gray out the text when disabled
peterz
parents:
1639
diff
changeset
|
2277 |
drawIcon(g, (int) x, (int) y, (int) w, (int) h, align, host); |
2 | 2278 |
return; |
2279 |
} |
|
2280 |
CSS.Value childtype = getChildType(cv); |
|
2281 |
Font font = ((StyledDocument)cv.getDocument()). |
|
2282 |
getFont(cv.getAttributes()); |
|
2283 |
if (font != null) { |
|
2284 |
g.setFont(font); |
|
2285 |
} |
|
2286 |
if (childtype == CSS.Value.SQUARE || childtype == CSS.Value.CIRCLE |
|
2287 |
|| childtype == CSS.Value.DISC) { |
|
2288 |
drawShape(g, childtype, (int) x, (int) y, |
|
2289 |
(int) w, (int) h, align); |
|
2290 |
} else if (childtype == CSS.Value.DECIMAL) { |
|
2291 |
drawLetter(g, '1', (int) x, (int) y, (int) w, (int) h, align, |
|
2292 |
getRenderIndex(v, item)); |
|
2293 |
} else if (childtype == CSS.Value.LOWER_ALPHA) { |
|
2294 |
drawLetter(g, 'a', (int) x, (int) y, (int) w, (int) h, align, |
|
2295 |
getRenderIndex(v, item)); |
|
2296 |
} else if (childtype == CSS.Value.UPPER_ALPHA) { |
|
2297 |
drawLetter(g, 'A', (int) x, (int) y, (int) w, (int) h, align, |
|
2298 |
getRenderIndex(v, item)); |
|
2299 |
} else if (childtype == CSS.Value.LOWER_ROMAN) { |
|
2300 |
drawLetter(g, 'i', (int) x, (int) y, (int) w, (int) h, align, |
|
2301 |
getRenderIndex(v, item)); |
|
2302 |
} else if (childtype == CSS.Value.UPPER_ROMAN) { |
|
2303 |
drawLetter(g, 'I', (int) x, (int) y, (int) w, (int) h, align, |
|
2304 |
getRenderIndex(v, item)); |
|
2305 |
} |
|
2306 |
} |
|
2307 |
||
2308 |
/** |
|
2309 |
* Draws the bullet icon specified by the list-style-image argument. |
|
2310 |
* |
|
2311 |
* @param g the graphics context |
|
2312 |
* @param ax x coordinate to place the bullet |
|
2313 |
* @param ay y coordinate to place the bullet |
|
2314 |
* @param aw width of the container the bullet is placed in |
|
2315 |
* @param ah height of the container the bullet is placed in |
|
2316 |
* @param align preferred alignment factor for the child view |
|
2317 |
*/ |
|
2318 |
void drawIcon(Graphics g, int ax, int ay, int aw, int ah, |
|
2319 |
float align, Component c) { |
|
2320 |
// Align to bottom of icon. |
|
2321 |
int gap = isLeftToRight ? - (img.getIconWidth() + bulletgap) : |
|
2322 |
(aw + bulletgap); |
|
2323 |
int x = ax + gap; |
|
2324 |
int y = Math.max(ay, ay + (int)(align * ah) -img.getIconHeight()); |
|
2325 |
||
2326 |
img.paintIcon(c, g, x, y); |
|
2327 |
} |
|
2328 |
||
2329 |
/** |
|
2330 |
* Draws the graphical bullet item specified by the type argument. |
|
2331 |
* |
|
2332 |
* @param g the graphics context |
|
2333 |
* @param type type of bullet to draw (circle, square, disc) |
|
2334 |
* @param ax x coordinate to place the bullet |
|
2335 |
* @param ay y coordinate to place the bullet |
|
2336 |
* @param aw width of the container the bullet is placed in |
|
2337 |
* @param ah height of the container the bullet is placed in |
|
2338 |
* @param align preferred alignment factor for the child view |
|
2339 |
*/ |
|
2340 |
void drawShape(Graphics g, CSS.Value type, int ax, int ay, int aw, |
|
2341 |
int ah, float align) { |
|
2342 |
// Align to bottom of shape. |
|
2343 |
int gap = isLeftToRight ? - (bulletgap + 8) : (aw + bulletgap); |
|
2344 |
int x = ax + gap; |
|
2345 |
int y = Math.max(ay, ay + (int)(align * ah) - 8); |
|
2346 |
||
2347 |
if (type == CSS.Value.SQUARE) { |
|
2348 |
g.drawRect(x, y, 8, 8); |
|
2349 |
} else if (type == CSS.Value.CIRCLE) { |
|
2350 |
g.drawOval(x, y, 8, 8); |
|
2351 |
} else { |
|
2352 |
g.fillOval(x, y, 8, 8); |
|
2353 |
} |
|
2354 |
} |
|
2355 |
||
2356 |
/** |
|
2357 |
* Draws the letter or number for an ordered list. |
|
2358 |
* |
|
2359 |
* @param g the graphics context |
|
2360 |
* @param letter type of ordered list to draw |
|
2361 |
* @param ax x coordinate to place the bullet |
|
2362 |
* @param ay y coordinate to place the bullet |
|
2363 |
* @param aw width of the container the bullet is placed in |
|
2364 |
* @param ah height of the container the bullet is placed in |
|
2365 |
* @param index position of the list item in the list |
|
2366 |
*/ |
|
2367 |
void drawLetter(Graphics g, char letter, int ax, int ay, int aw, |
|
2368 |
int ah, float align, int index) { |
|
2369 |
String str = formatItemNum(index, letter); |
|
2370 |
str = isLeftToRight ? str + "." : "." + str; |
|
2371 |
FontMetrics fm = SwingUtilities2.getFontMetrics(null, g); |
|
2372 |
int stringwidth = SwingUtilities2.stringWidth(null, fm, str); |
|
2373 |
int gap = isLeftToRight ? - (stringwidth + bulletgap) : |
|
2374 |
(aw + bulletgap); |
|
2375 |
int x = ax + gap; |
|
2376 |
int y = Math.max(ay + fm.getAscent(), ay + (int)(ah * align)); |
|
2377 |
SwingUtilities2.drawString(null, g, str, x, y); |
|
2378 |
} |
|
2379 |
||
2380 |
/** |
|
2381 |
* Converts the item number into the ordered list number |
|
2382 |
* (i.e. 1 2 3, i ii iii, a b c, etc. |
|
2383 |
* |
|
2384 |
* @param itemNum number to format |
|
2385 |
* @param type type of ordered list |
|
2386 |
*/ |
|
24528 | 2387 |
@SuppressWarnings("fallthrough") |
2 | 2388 |
String formatItemNum(int itemNum, char type) { |
2389 |
String numStyle = "1"; |
|
2390 |
||
2391 |
boolean uppercase = false; |
|
2392 |
||
2393 |
String formattedNum; |
|
2394 |
||
2395 |
switch (type) { |
|
2396 |
case '1': |
|
2397 |
default: |
|
2398 |
formattedNum = String.valueOf(itemNum); |
|
2399 |
break; |
|
2400 |
||
2401 |
case 'A': |
|
2402 |
uppercase = true; |
|
2403 |
// fall through |
|
2404 |
case 'a': |
|
2405 |
formattedNum = formatAlphaNumerals(itemNum); |
|
2406 |
break; |
|
2407 |
||
2408 |
case 'I': |
|
2409 |
uppercase = true; |
|
2410 |
// fall through |
|
2411 |
case 'i': |
|
2412 |
formattedNum = formatRomanNumerals(itemNum); |
|
2413 |
} |
|
2414 |
||
2415 |
if (uppercase) { |
|
2416 |
formattedNum = formattedNum.toUpperCase(); |
|
2417 |
} |
|
2418 |
||
2419 |
return formattedNum; |
|
2420 |
} |
|
2421 |
||
2422 |
/** |
|
2423 |
* Converts the item number into an alphabetic character |
|
2424 |
* |
|
2425 |
* @param itemNum number to format |
|
2426 |
*/ |
|
2427 |
String formatAlphaNumerals(int itemNum) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
2428 |
String result; |
2 | 2429 |
|
2430 |
if (itemNum > 26) { |
|
2431 |
result = formatAlphaNumerals(itemNum / 26) + |
|
2432 |
formatAlphaNumerals(itemNum % 26); |
|
2433 |
} else { |
|
2434 |
// -1 because item is 1 based. |
|
2435 |
result = String.valueOf((char)('a' + itemNum - 1)); |
|
2436 |
} |
|
2437 |
||
2438 |
return result; |
|
2439 |
} |
|
2440 |
||
2441 |
/* list of roman numerals */ |
|
2442 |
static final char romanChars[][] = { |
|
2443 |
{'i', 'v'}, |
|
2444 |
{'x', 'l' }, |
|
2445 |
{'c', 'd' }, |
|
2446 |
{'m', '?' }, |
|
2447 |
}; |
|
2448 |
||
2449 |
/** |
|
2450 |
* Converts the item number into a roman numeral |
|
2451 |
* |
|
2452 |
* @param num number to format |
|
2453 |
*/ |
|
2454 |
String formatRomanNumerals(int num) { |
|
2455 |
return formatRomanNumerals(0, num); |
|
2456 |
} |
|
2457 |
||
2458 |
/** |
|
2459 |
* Converts the item number into a roman numeral |
|
2460 |
* |
|
2461 |
* @param num number to format |
|
2462 |
*/ |
|
2463 |
String formatRomanNumerals(int level, int num) { |
|
2464 |
if (num < 10) { |
|
2465 |
return formatRomanDigit(level, num); |
|
2466 |
} else { |
|
2467 |
return formatRomanNumerals(level + 1, num / 10) + |
|
2468 |
formatRomanDigit(level, num % 10); |
|
2469 |
} |
|
2470 |
} |
|
2471 |
||
2472 |
||
2473 |
/** |
|
2474 |
* Converts the item number into a roman numeral |
|
2475 |
* |
|
2476 |
* @param level position |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
2477 |
* @param digit digit to format |
2 | 2478 |
*/ |
2479 |
String formatRomanDigit(int level, int digit) { |
|
2480 |
String result = ""; |
|
2481 |
if (digit == 9) { |
|
2482 |
result = result + romanChars[level][0]; |
|
2483 |
result = result + romanChars[level + 1][0]; |
|
2484 |
return result; |
|
2485 |
} else if (digit == 4) { |
|
2486 |
result = result + romanChars[level][0]; |
|
2487 |
result = result + romanChars[level][1]; |
|
2488 |
return result; |
|
2489 |
} else if (digit >= 5) { |
|
2490 |
result = result + romanChars[level][1]; |
|
2491 |
digit -= 5; |
|
2492 |
} |
|
2493 |
||
2494 |
for (int i = 0; i < digit; i++) { |
|
2495 |
result = result + romanChars[level][0]; |
|
2496 |
} |
|
2497 |
||
2498 |
return result; |
|
2499 |
} |
|
2500 |
||
2501 |
private Rectangle paintRect; |
|
2502 |
private boolean checkedForStart; |
|
2503 |
private int start; |
|
2504 |
private CSS.Value type; |
|
2505 |
URL imageurl; |
|
2506 |
private StyleSheet ss = null; |
|
2507 |
Icon img = null; |
|
2508 |
private int bulletgap = 5; |
|
2509 |
private boolean isLeftToRight; |
|
2510 |
} |
|
2511 |
||
2512 |
||
2513 |
/** |
|
2514 |
* Paints the background image. |
|
2515 |
*/ |
|
23697 | 2516 |
@SuppressWarnings("serial") // Same-version serialization only |
2 | 2517 |
static class BackgroundImagePainter implements Serializable { |
2518 |
ImageIcon backgroundImage; |
|
2519 |
float hPosition; |
|
2520 |
float vPosition; |
|
2521 |
// bit mask: 0 for repeat x, 1 for repeat y, 2 for horiz relative, |
|
2522 |
// 3 for vert relative |
|
2523 |
short flags; |
|
2524 |
// These are used when painting, updatePaintCoordinates updates them. |
|
2525 |
private int paintX; |
|
2526 |
private int paintY; |
|
2527 |
private int paintMaxX; |
|
2528 |
private int paintMaxY; |
|
2529 |
||
2530 |
BackgroundImagePainter(AttributeSet a, CSS css, StyleSheet ss) { |
|
2531 |
backgroundImage = ss.getBackgroundImage(a); |
|
2532 |
// Determine the position. |
|
2533 |
CSS.BackgroundPosition pos = (CSS.BackgroundPosition)a.getAttribute |
|
2534 |
(CSS.Attribute.BACKGROUND_POSITION); |
|
2535 |
if (pos != null) { |
|
2536 |
hPosition = pos.getHorizontalPosition(); |
|
2537 |
vPosition = pos.getVerticalPosition(); |
|
2538 |
if (pos.isHorizontalPositionRelativeToSize()) { |
|
2539 |
flags |= 4; |
|
2540 |
} |
|
2541 |
else if (pos.isHorizontalPositionRelativeToSize()) { |
|
22567
5816a47fa4dd
8032047: Fix static lint warnings in client libraries
darcy
parents:
22260
diff
changeset
|
2542 |
hPosition *= CSS.getFontSize(a, 12, ss); |
2 | 2543 |
} |
2544 |
if (pos.isVerticalPositionRelativeToSize()) { |
|
2545 |
flags |= 8; |
|
2546 |
} |
|
2547 |
else if (pos.isVerticalPositionRelativeToFontSize()) { |
|
22567
5816a47fa4dd
8032047: Fix static lint warnings in client libraries
darcy
parents:
22260
diff
changeset
|
2548 |
vPosition *= CSS.getFontSize(a, 12, ss); |
2 | 2549 |
} |
2550 |
} |
|
2551 |
// Determine any repeating values. |
|
2552 |
CSS.Value repeats = (CSS.Value)a.getAttribute(CSS.Attribute. |
|
2553 |
BACKGROUND_REPEAT); |
|
2554 |
if (repeats == null || repeats == CSS.Value.BACKGROUND_REPEAT) { |
|
2555 |
flags |= 3; |
|
2556 |
} |
|
2557 |
else if (repeats == CSS.Value.BACKGROUND_REPEAT_X) { |
|
2558 |
flags |= 1; |
|
2559 |
} |
|
2560 |
else if (repeats == CSS.Value.BACKGROUND_REPEAT_Y) { |
|
2561 |
flags |= 2; |
|
2562 |
} |
|
2563 |
} |
|
2564 |
||
28231
b608ffcaed74
8066621: Suppress deprecation warnings in java.desktop module
darcy
parents:
25859
diff
changeset
|
2565 |
@SuppressWarnings("deprecation") |
2 | 2566 |
void paint(Graphics g, float x, float y, float w, float h, View v) { |
2567 |
Rectangle clip = g.getClipRect(); |
|
2568 |
if (clip != null) { |
|
2569 |
// Constrain the clip so that images don't draw outside the |
|
2570 |
// legal bounds. |
|
2571 |
g.clipRect((int)x, (int)y, (int)w, (int)h); |
|
2572 |
} |
|
2573 |
if ((flags & 3) == 0) { |
|
2574 |
// no repeating |
|
2575 |
int width = backgroundImage.getIconWidth(); |
|
2576 |
int height = backgroundImage.getIconWidth(); |
|
2577 |
if ((flags & 4) == 4) { |
|
2578 |
paintX = (int)(x + w * hPosition - |
|
2579 |
(float)width * hPosition); |
|
2580 |
} |
|
2581 |
else { |
|
2582 |
paintX = (int)x + (int)hPosition; |
|
2583 |
} |
|
2584 |
if ((flags & 8) == 8) { |
|
2585 |
paintY = (int)(y + h * vPosition - |
|
2586 |
(float)height * vPosition); |
|
2587 |
} |
|
2588 |
else { |
|
2589 |
paintY = (int)y + (int)vPosition; |
|
2590 |
} |
|
2591 |
if (clip == null || |
|
2592 |
!((paintX + width <= clip.x) || |
|
2593 |
(paintY + height <= clip.y) || |
|
2594 |
(paintX >= clip.x + clip.width) || |
|
2595 |
(paintY >= clip.y + clip.height))) { |
|
2596 |
backgroundImage.paintIcon(null, g, paintX, paintY); |
|
2597 |
} |
|
2598 |
} |
|
2599 |
else { |
|
2600 |
int width = backgroundImage.getIconWidth(); |
|
2601 |
int height = backgroundImage.getIconHeight(); |
|
2602 |
if (width > 0 && height > 0) { |
|
2603 |
paintX = (int)x; |
|
2604 |
paintY = (int)y; |
|
2605 |
paintMaxX = (int)(x + w); |
|
2606 |
paintMaxY = (int)(y + h); |
|
2607 |
if (updatePaintCoordinates(clip, width, height)) { |
|
2608 |
while (paintX < paintMaxX) { |
|
2609 |
int ySpot = paintY; |
|
2610 |
while (ySpot < paintMaxY) { |
|
2611 |
backgroundImage.paintIcon(null, g, paintX, |
|
2612 |
ySpot); |
|
2613 |
ySpot += height; |
|
2614 |
} |
|
2615 |
paintX += width; |
|
2616 |
} |
|
2617 |
} |
|
2618 |
} |
|
2619 |
} |
|
2620 |
if (clip != null) { |
|
2621 |
// Reset clip. |
|
2622 |
g.setClip(clip.x, clip.y, clip.width, clip.height); |
|
2623 |
} |
|
2624 |
} |
|
2625 |
||
2626 |
private boolean updatePaintCoordinates |
|
2627 |
(Rectangle clip, int width, int height){ |
|
2628 |
if ((flags & 3) == 1) { |
|
2629 |
paintMaxY = paintY + 1; |
|
2630 |
} |
|
2631 |
else if ((flags & 3) == 2) { |
|
2632 |
paintMaxX = paintX + 1; |
|
2633 |
} |
|
2634 |
if (clip != null) { |
|
2635 |
if ((flags & 3) == 1 && ((paintY + height <= clip.y) || |
|
2636 |
(paintY > clip.y + clip.height))) { |
|
2637 |
// not visible. |
|
2638 |
return false; |
|
2639 |
} |
|
2640 |
if ((flags & 3) == 2 && ((paintX + width <= clip.x) || |
|
2641 |
(paintX > clip.x + clip.width))) { |
|
2642 |
// not visible. |
|
2643 |
return false; |
|
2644 |
} |
|
2645 |
if ((flags & 1) == 1) { |
|
2646 |
if ((clip.x + clip.width) < paintMaxX) { |
|
2647 |
if ((clip.x + clip.width - paintX) % width == 0) { |
|
2648 |
paintMaxX = clip.x + clip.width; |
|
2649 |
} |
|
2650 |
else { |
|
2651 |
paintMaxX = ((clip.x + clip.width - paintX) / |
|
2652 |
width + 1) * width + paintX; |
|
2653 |
} |
|
2654 |
} |
|
2655 |
if (clip.x > paintX) { |
|
2656 |
paintX = (clip.x - paintX) / width * width + paintX; |
|
2657 |
} |
|
2658 |
} |
|
2659 |
if ((flags & 2) == 2) { |
|
2660 |
if ((clip.y + clip.height) < paintMaxY) { |
|
2661 |
if ((clip.y + clip.height - paintY) % height == 0) { |
|
2662 |
paintMaxY = clip.y + clip.height; |
|
2663 |
} |
|
2664 |
else { |
|
2665 |
paintMaxY = ((clip.y + clip.height - paintY) / |
|
2666 |
height + 1) * height + paintY; |
|
2667 |
} |
|
2668 |
} |
|
2669 |
if (clip.y > paintY) { |
|
2670 |
paintY = (clip.y - paintY) / height * height + paintY; |
|
2671 |
} |
|
2672 |
} |
|
2673 |
} |
|
2674 |
// Valid |
|
2675 |
return true; |
|
2676 |
} |
|
2677 |
} |
|
2678 |
||
2679 |
||
2680 |
/** |
|
2681 |
* A subclass of MuxingAttributeSet that translates between |
|
2682 |
* CSS and HTML and StyleConstants. The AttributeSets used are |
|
2683 |
* the CSS rules that match the Views Elements. |
|
2684 |
*/ |
|
23697 | 2685 |
@SuppressWarnings("serial") // Same-version serialization only |
2 | 2686 |
class ViewAttributeSet extends MuxingAttributeSet { |
2687 |
ViewAttributeSet(View v) { |
|
2688 |
host = v; |
|
2689 |
||
2690 |
// PENDING(prinz) fix this up to be a more realistic |
|
2691 |
// implementation. |
|
2692 |
Document doc = v.getDocument(); |
|
2693 |
SearchBuffer sb = SearchBuffer.obtainSearchBuffer(); |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
2694 |
@SuppressWarnings("unchecked") |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
2695 |
Vector<AttributeSet> muxList = sb.getVector(); |
2 | 2696 |
try { |
2697 |
if (doc instanceof HTMLDocument) { |
|
2698 |
StyleSheet styles = StyleSheet.this; |
|
2699 |
Element elem = v.getElement(); |
|
2700 |
AttributeSet a = elem.getAttributes(); |
|
2701 |
AttributeSet htmlAttr = styles.translateHTMLToCSS(a); |
|
2702 |
||
2703 |
if (htmlAttr.getAttributeCount() != 0) { |
|
2704 |
muxList.addElement(htmlAttr); |
|
2705 |
} |
|
2706 |
if (elem.isLeaf()) { |
|
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24528
diff
changeset
|
2707 |
Enumeration<?> keys = a.getAttributeNames(); |
2 | 2708 |
while (keys.hasMoreElements()) { |
2709 |
Object key = keys.nextElement(); |
|
2710 |
if (key instanceof HTML.Tag) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
2711 |
if (key == HTML.Tag.A) { |
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
2712 |
Object o = a.getAttribute(key); |
2 | 2713 |
/** |
2714 |
In the case of an A tag, the css rules |
|
2715 |
apply only for tags that have their |
|
2716 |
href attribute defined and not for |
|
2717 |
anchors that only have their name attributes |
|
2718 |
defined, i.e anchors that function as |
|
2719 |
destinations. Hence we do not add the |
|
2720 |
attributes for that latter kind of |
|
2721 |
anchors. When CSS2 support is added, |
|
2722 |
it will be possible to specificity this |
|
2723 |
kind of conditional behaviour in the |
|
2724 |
stylesheet. |
|
2725 |
**/ |
|
2726 |
if (o != null && o instanceof AttributeSet) { |
|
2727 |
AttributeSet attr = (AttributeSet)o; |
|
2728 |
if (attr.getAttribute(HTML.Attribute.HREF) == null) { |
|
2729 |
continue; |
|
2730 |
} |
|
2731 |
} |
|
2732 |
} |
|
2733 |
AttributeSet cssRule = styles.getRule((HTML.Tag) key, elem); |
|
2734 |
if (cssRule != null) { |
|
2735 |
muxList.addElement(cssRule); |
|
2736 |
} |
|
2737 |
} |
|
2738 |
} |
|
2739 |
} else { |
|
2740 |
HTML.Tag t = (HTML.Tag) a.getAttribute |
|
2741 |
(StyleConstants.NameAttribute); |
|
2742 |
AttributeSet cssRule = styles.getRule(t, elem); |
|
2743 |
if (cssRule != null) { |
|
2744 |
muxList.addElement(cssRule); |
|
2745 |
} |
|
2746 |
} |
|
2747 |
} |
|
2748 |
AttributeSet[] attrs = new AttributeSet[muxList.size()]; |
|
2749 |
muxList.copyInto(attrs); |
|
2750 |
setAttributes(attrs); |
|
2751 |
} |
|
2752 |
finally { |
|
2753 |
SearchBuffer.releaseSearchBuffer(sb); |
|
2754 |
} |
|
2755 |
} |
|
2756 |
||
2757 |
// --- AttributeSet methods ---------------------------- |
|
2758 |
||
2759 |
/** |
|
2760 |
* Checks whether a given attribute is defined. |
|
2761 |
* This will convert the key over to CSS if the |
|
2762 |
* key is a StyleConstants key that has a CSS |
|
2763 |
* mapping. |
|
2764 |
* |
|
2765 |
* @param key the attribute key |
|
2766 |
* @return true if the attribute is defined |
|
2767 |
* @see AttributeSet#isDefined |
|
2768 |
*/ |
|
2769 |
public boolean isDefined(Object key) { |
|
2770 |
if (key instanceof StyleConstants) { |
|
2771 |
Object cssKey = css.styleConstantsKeyToCSSKey |
|
2772 |
((StyleConstants)key); |
|
2773 |
if (cssKey != null) { |
|
2774 |
key = cssKey; |
|
2775 |
} |
|
2776 |
} |
|
2777 |
return super.isDefined(key); |
|
2778 |
} |
|
2779 |
||
2780 |
/** |
|
2781 |
* Gets the value of an attribute. If the requested |
|
2782 |
* attribute is a StyleConstants attribute that has |
|
2783 |
* a CSS mapping, the request will be converted. |
|
2784 |
* |
|
2785 |
* @param key the attribute name |
|
2786 |
* @return the attribute value |
|
2787 |
* @see AttributeSet#getAttribute |
|
2788 |
*/ |
|
2789 |
public Object getAttribute(Object key) { |
|
2790 |
if (key instanceof StyleConstants) { |
|
2791 |
Object cssKey = css.styleConstantsKeyToCSSKey |
|
2792 |
((StyleConstants)key); |
|
2793 |
if (cssKey != null) { |
|
2794 |
Object value = doGetAttribute(cssKey); |
|
2795 |
if (value instanceof CSS.CssValue) { |
|
2796 |
return ((CSS.CssValue)value).toStyleConstants |
|
2797 |
((StyleConstants)key, host); |
|
2798 |
} |
|
2799 |
} |
|
2800 |
} |
|
2801 |
return doGetAttribute(key); |
|
2802 |
} |
|
2803 |
||
2804 |
Object doGetAttribute(Object key) { |
|
2805 |
Object retValue = super.getAttribute(key); |
|
2806 |
if (retValue != null) { |
|
2807 |
return retValue; |
|
2808 |
} |
|
2809 |
// didn't find it... try parent if it's a css attribute |
|
2810 |
// that is inherited. |
|
2811 |
if (key instanceof CSS.Attribute) { |
|
2812 |
CSS.Attribute css = (CSS.Attribute) key; |
|
2813 |
if (css.isInherited()) { |
|
2814 |
AttributeSet parent = getResolveParent(); |
|
2815 |
if (parent != null) |
|
2816 |
return parent.getAttribute(key); |
|
2817 |
} |
|
2818 |
} |
|
2819 |
return null; |
|
2820 |
} |
|
2821 |
||
2822 |
/** |
|
2823 |
* If not overriden, the resolving parent defaults to |
|
2824 |
* the parent element. |
|
2825 |
* |
|
2826 |
* @return the attributes from the parent |
|
2827 |
* @see AttributeSet#getResolveParent |
|
2828 |
*/ |
|
2829 |
public AttributeSet getResolveParent() { |
|
2830 |
if (host == null) { |
|
2831 |
return null; |
|
2832 |
} |
|
2833 |
View parent = host.getParent(); |
|
2834 |
return (parent != null) ? parent.getAttributes() : null; |
|
2835 |
} |
|
2836 |
||
2837 |
/** View created for. */ |
|
2838 |
View host; |
|
2839 |
} |
|
2840 |
||
2841 |
||
2842 |
/** |
|
2843 |
* A subclass of MuxingAttributeSet that implements Style. Currently |
|
2844 |
* the MutableAttributeSet methods are unimplemented, that is they |
|
2845 |
* do nothing. |
|
2846 |
*/ |
|
2847 |
// PENDING(sky): Decide what to do with this. Either make it |
|
2848 |
// contain a SimpleAttributeSet that modify methods are delegated to, |
|
2849 |
// or change getRule to return an AttributeSet and then don't make this |
|
2850 |
// implement Style. |
|
23697 | 2851 |
@SuppressWarnings("serial") // Same-version serialization only |
2 | 2852 |
static class ResolvedStyle extends MuxingAttributeSet implements |
2853 |
Serializable, Style { |
|
2854 |
ResolvedStyle(String name, AttributeSet[] attrs, int extendedIndex) { |
|
2855 |
super(attrs); |
|
2856 |
this.name = name; |
|
2857 |
this.extendedIndex = extendedIndex; |
|
2858 |
} |
|
2859 |
||
2860 |
/** |
|
2861 |
* Inserts a Style into the receiver so that the styles the |
|
2862 |
* receiver represents are still ordered by specificity. |
|
2863 |
* <code>style</code> will be added before any extended styles, that |
|
2864 |
* is before extendedIndex. |
|
2865 |
*/ |
|
2866 |
synchronized void insertStyle(Style style, int specificity) { |
|
2867 |
AttributeSet[] attrs = getAttributes(); |
|
2868 |
int maxCounter = attrs.length; |
|
2869 |
int counter = 0; |
|
2870 |
for (;counter < extendedIndex; counter++) { |
|
2871 |
if (specificity > getSpecificity(((Style)attrs[counter]). |
|
2872 |
getName())) { |
|
2873 |
break; |
|
2874 |
} |
|
2875 |
} |
|
2876 |
insertAttributeSetAt(style, counter); |
|
2877 |
extendedIndex++; |
|
2878 |
} |
|
2879 |
||
2880 |
/** |
|
2881 |
* Removes a previously added style. This will do nothing if |
|
2882 |
* <code>style</code> is not referenced by the receiver. |
|
2883 |
*/ |
|
2884 |
synchronized void removeStyle(Style style) { |
|
2885 |
AttributeSet[] attrs = getAttributes(); |
|
2886 |
||
2887 |
for (int counter = attrs.length - 1; counter >= 0; counter--) { |
|
2888 |
if (attrs[counter] == style) { |
|
2889 |
removeAttributeSetAt(counter); |
|
2890 |
if (counter < extendedIndex) { |
|
2891 |
extendedIndex--; |
|
2892 |
} |
|
2893 |
break; |
|
2894 |
} |
|
2895 |
} |
|
2896 |
} |
|
2897 |
||
2898 |
/** |
|
2899 |
* Adds <code>s</code> as one of the Attributesets to look up |
|
2900 |
* attributes in. |
|
2901 |
*/ |
|
2902 |
synchronized void insertExtendedStyleAt(Style attr, int index) { |
|
2903 |
insertAttributeSetAt(attr, extendedIndex + index); |
|
2904 |
} |
|
2905 |
||
2906 |
/** |
|
2907 |
* Adds <code>s</code> as one of the AttributeSets to look up |
|
2908 |
* attributes in. It will be the AttributeSet last checked. |
|
2909 |
*/ |
|
2910 |
synchronized void addExtendedStyle(Style attr) { |
|
2911 |
insertAttributeSetAt(attr, getAttributes().length); |
|
2912 |
} |
|
2913 |
||
2914 |
/** |
|
2915 |
* Removes the style at <code>index</code> + |
|
2916 |
* <code>extendedIndex</code>. |
|
2917 |
*/ |
|
2918 |
synchronized void removeExtendedStyleAt(int index) { |
|
2919 |
removeAttributeSetAt(extendedIndex + index); |
|
2920 |
} |
|
2921 |
||
2922 |
/** |
|
2923 |
* Returns true if the receiver matches <code>selector</code>, where |
|
2924 |
* a match is defined by the CSS rule matching. |
|
2925 |
* Each simple selector must be separated by a single space. |
|
2926 |
*/ |
|
2927 |
protected boolean matches(String selector) { |
|
2928 |
int sLast = selector.length(); |
|
2929 |
||
2930 |
if (sLast == 0) { |
|
2931 |
return false; |
|
2932 |
} |
|
2933 |
int thisLast = name.length(); |
|
2934 |
int sCurrent = selector.lastIndexOf(' '); |
|
2935 |
int thisCurrent = name.lastIndexOf(' '); |
|
2936 |
if (sCurrent >= 0) { |
|
2937 |
sCurrent++; |
|
2938 |
} |
|
2939 |
if (thisCurrent >= 0) { |
|
2940 |
thisCurrent++; |
|
2941 |
} |
|
2942 |
if (!matches(selector, sCurrent, sLast, thisCurrent, thisLast)) { |
|
2943 |
return false; |
|
2944 |
} |
|
2945 |
while (sCurrent != -1) { |
|
2946 |
sLast = sCurrent - 1; |
|
2947 |
sCurrent = selector.lastIndexOf(' ', sLast - 1); |
|
2948 |
if (sCurrent >= 0) { |
|
2949 |
sCurrent++; |
|
2950 |
} |
|
2951 |
boolean match = false; |
|
2952 |
while (!match && thisCurrent != -1) { |
|
2953 |
thisLast = thisCurrent - 1; |
|
2954 |
thisCurrent = name.lastIndexOf(' ', thisLast - 1); |
|
2955 |
if (thisCurrent >= 0) { |
|
2956 |
thisCurrent++; |
|
2957 |
} |
|
2958 |
match = matches(selector, sCurrent, sLast, thisCurrent, |
|
2959 |
thisLast); |
|
2960 |
} |
|
2961 |
if (!match) { |
|
2962 |
return false; |
|
2963 |
} |
|
2964 |
} |
|
2965 |
return true; |
|
2966 |
} |
|
2967 |
||
2968 |
/** |
|
2969 |
* Returns true if the substring of the receiver, in the range |
|
2970 |
* thisCurrent, thisLast matches the substring of selector in |
|
2971 |
* the ranme sCurrent to sLast based on CSS selector matching. |
|
2972 |
*/ |
|
2973 |
boolean matches(String selector, int sCurrent, int sLast, |
|
2974 |
int thisCurrent, int thisLast) { |
|
2975 |
sCurrent = Math.max(sCurrent, 0); |
|
2976 |
thisCurrent = Math.max(thisCurrent, 0); |
|
2977 |
int thisDotIndex = boundedIndexOf(name, '.', thisCurrent, |
|
2978 |
thisLast); |
|
2979 |
int thisPoundIndex = boundedIndexOf(name, '#', thisCurrent, |
|
2980 |
thisLast); |
|
2981 |
int sDotIndex = boundedIndexOf(selector, '.', sCurrent, sLast); |
|
2982 |
int sPoundIndex = boundedIndexOf(selector, '#', sCurrent, sLast); |
|
2983 |
if (sDotIndex != -1) { |
|
2984 |
// Selector has a '.', which indicates name must match it, |
|
2985 |
// or if the '.' starts the selector than name must have |
|
2986 |
// the same class (doesn't matter what element name). |
|
2987 |
if (thisDotIndex == -1) { |
|
2988 |
return false; |
|
2989 |
} |
|
2990 |
if (sCurrent == sDotIndex) { |
|
2991 |
if ((thisLast - thisDotIndex) != (sLast - sDotIndex) || |
|
2992 |
!selector.regionMatches(sCurrent, name, thisDotIndex, |
|
2993 |
(thisLast - thisDotIndex))) { |
|
2994 |
return false; |
|
2995 |
} |
|
2996 |
} |
|
2997 |
else { |
|
2998 |
// Has to fully match. |
|
2999 |
if ((sLast - sCurrent) != (thisLast - thisCurrent) || |
|
3000 |
!selector.regionMatches(sCurrent, name, thisCurrent, |
|
3001 |
(thisLast - thisCurrent))) { |
|
3002 |
return false; |
|
3003 |
} |
|
3004 |
} |
|
3005 |
return true; |
|
3006 |
} |
|
3007 |
if (sPoundIndex != -1) { |
|
3008 |
// Selector has a '#', which indicates name must match it, |
|
3009 |
// or if the '#' starts the selector than name must have |
|
3010 |
// the same id (doesn't matter what element name). |
|
3011 |
if (thisPoundIndex == -1) { |
|
3012 |
return false; |
|
3013 |
} |
|
3014 |
if (sCurrent == sPoundIndex) { |
|
3015 |
if ((thisLast - thisPoundIndex) !=(sLast - sPoundIndex) || |
|
3016 |
!selector.regionMatches(sCurrent, name, thisPoundIndex, |
|
3017 |
(thisLast - thisPoundIndex))) { |
|
3018 |
return false; |
|
3019 |
} |
|
3020 |
} |
|
3021 |
else { |
|
3022 |
// Has to fully match. |
|
3023 |
if ((sLast - sCurrent) != (thisLast - thisCurrent) || |
|
3024 |
!selector.regionMatches(sCurrent, name, thisCurrent, |
|
3025 |
(thisLast - thisCurrent))) { |
|
3026 |
return false; |
|
3027 |
} |
|
3028 |
} |
|
3029 |
return true; |
|
3030 |
} |
|
3031 |
if (thisDotIndex != -1) { |
|
21278 | 3032 |
// Receiver references a class, just check element name. |
2 | 3033 |
return (((thisDotIndex - thisCurrent) == (sLast - sCurrent)) && |
3034 |
selector.regionMatches(sCurrent, name, thisCurrent, |
|
3035 |
thisDotIndex - thisCurrent)); |
|
3036 |
} |
|
3037 |
if (thisPoundIndex != -1) { |
|
21278 | 3038 |
// Receiver references an id, just check element name. |
2 | 3039 |
return (((thisPoundIndex - thisCurrent) ==(sLast - sCurrent))&& |
3040 |
selector.regionMatches(sCurrent, name, thisCurrent, |
|
3041 |
thisPoundIndex - thisCurrent)); |
|
3042 |
} |
|
3043 |
// Fail through, no classes or ides, just check string. |
|
3044 |
return (((thisLast - thisCurrent) == (sLast - sCurrent)) && |
|
3045 |
selector.regionMatches(sCurrent, name, thisCurrent, |
|
3046 |
thisLast - thisCurrent)); |
|
3047 |
} |
|
3048 |
||
3049 |
/** |
|
21278 | 3050 |
* Similar to String.indexOf, but allows an upper bound |
2 | 3051 |
* (this is slower in that it will still check string starting at |
3052 |
* start. |
|
3053 |
*/ |
|
3054 |
int boundedIndexOf(String string, char search, int start, |
|
3055 |
int end) { |
|
3056 |
int retValue = string.indexOf(search, start); |
|
3057 |
if (retValue >= end) { |
|
3058 |
return -1; |
|
3059 |
} |
|
3060 |
return retValue; |
|
3061 |
} |
|
3062 |
||
3063 |
public void addAttribute(Object name, Object value) {} |
|
3064 |
public void addAttributes(AttributeSet attributes) {} |
|
3065 |
public void removeAttribute(Object name) {} |
|
3066 |
public void removeAttributes(Enumeration<?> names) {} |
|
3067 |
public void removeAttributes(AttributeSet attributes) {} |
|
3068 |
public void setResolveParent(AttributeSet parent) {} |
|
3069 |
public String getName() {return name;} |
|
3070 |
public void addChangeListener(ChangeListener l) {} |
|
3071 |
public void removeChangeListener(ChangeListener l) {} |
|
3072 |
public ChangeListener[] getChangeListeners() { |
|
3073 |
return new ChangeListener[0]; |
|
3074 |
} |
|
3075 |
||
3076 |
/** The name of the Style, which is the selector. |
|
3077 |
* This will NEVER change! |
|
3078 |
*/ |
|
3079 |
String name; |
|
3080 |
/** Start index of styles coming from other StyleSheets. */ |
|
3081 |
private int extendedIndex; |
|
3082 |
} |
|
3083 |
||
3084 |
||
3085 |
/** |
|
3086 |
* SelectorMapping contains a specifitiy, as an integer, and an associated |
|
3087 |
* Style. It can also reference children <code>SelectorMapping</code>s, |
|
3088 |
* so that it behaves like a tree. |
|
3089 |
* <p> |
|
3090 |
* This is not thread safe, it is assumed the caller will take the |
|
3091 |
* necessary precations if this is to be used in a threaded environment. |
|
3092 |
*/ |
|
23697 | 3093 |
@SuppressWarnings("serial") // Same-version serialization only |
2 | 3094 |
static class SelectorMapping implements Serializable { |
3095 |
public SelectorMapping(int specificity) { |
|
3096 |
this.specificity = specificity; |
|
3097 |
} |
|
3098 |
||
3099 |
/** |
|
3100 |
* Returns the specificity this mapping represents. |
|
3101 |
*/ |
|
3102 |
public int getSpecificity() { |
|
3103 |
return specificity; |
|
3104 |
} |
|
3105 |
||
3106 |
/** |
|
3107 |
* Sets the Style associated with this mapping. |
|
3108 |
*/ |
|
3109 |
public void setStyle(Style style) { |
|
3110 |
this.style = style; |
|
3111 |
} |
|
3112 |
||
3113 |
/** |
|
3114 |
* Returns the Style associated with this mapping. |
|
3115 |
*/ |
|
3116 |
public Style getStyle() { |
|
3117 |
return style; |
|
3118 |
} |
|
3119 |
||
3120 |
/** |
|
3121 |
* Returns the child mapping identified by the simple selector |
|
3122 |
* <code>selector</code>. If a child mapping does not exist for |
|
3123 |
*<code>selector</code>, and <code>create</code> is true, a new |
|
3124 |
* one will be created. |
|
3125 |
*/ |
|
3126 |
public SelectorMapping getChildSelectorMapping(String selector, |
|
3127 |
boolean create) { |
|
3128 |
SelectorMapping retValue = null; |
|
3129 |
||
3130 |
if (children != null) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
3131 |
retValue = children.get(selector); |
2 | 3132 |
} |
3133 |
else if (create) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
3134 |
children = new HashMap<String, SelectorMapping>(7); |
2 | 3135 |
} |
3136 |
if (retValue == null && create) { |
|
3137 |
int specificity = getChildSpecificity(selector); |
|
3138 |
||
3139 |
retValue = createChildSelectorMapping(specificity); |
|
3140 |
children.put(selector, retValue); |
|
3141 |
} |
|
3142 |
return retValue; |
|
3143 |
} |
|
3144 |
||
3145 |
/** |
|
3146 |
* Creates a child <code>SelectorMapping</code> with the specified |
|
3147 |
* <code>specificity</code>. |
|
3148 |
*/ |
|
3149 |
protected SelectorMapping createChildSelectorMapping(int specificity) { |
|
3150 |
return new SelectorMapping(specificity); |
|
3151 |
} |
|
3152 |
||
3153 |
/** |
|
3154 |
* Returns the specificity for the child selector |
|
3155 |
* <code>selector</code>. |
|
3156 |
*/ |
|
3157 |
protected int getChildSpecificity(String selector) { |
|
3158 |
// class (.) 100 |
|
3159 |
// id (#) 10000 |
|
3160 |
char firstChar = selector.charAt(0); |
|
3161 |
int specificity = getSpecificity(); |
|
3162 |
||
3163 |
if (firstChar == '.') { |
|
3164 |
specificity += 100; |
|
3165 |
} |
|
3166 |
else if (firstChar == '#') { |
|
3167 |
specificity += 10000; |
|
3168 |
} |
|
3169 |
else { |
|
3170 |
specificity += 1; |
|
3171 |
if (selector.indexOf('.') != -1) { |
|
3172 |
specificity += 100; |
|
3173 |
} |
|
3174 |
if (selector.indexOf('#') != -1) { |
|
3175 |
specificity += 10000; |
|
3176 |
} |
|
3177 |
} |
|
3178 |
return specificity; |
|
3179 |
} |
|
3180 |
||
3181 |
/** |
|
3182 |
* The specificity for this selector. |
|
3183 |
*/ |
|
3184 |
private int specificity; |
|
3185 |
/** |
|
3186 |
* Style for this selector. |
|
3187 |
*/ |
|
3188 |
private Style style; |
|
3189 |
/** |
|
3190 |
* Any sub selectors. Key will be String, and value will be |
|
3191 |
* another SelectorMapping. |
|
3192 |
*/ |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
3193 |
private HashMap<String, SelectorMapping> children; |
2 | 3194 |
} |
3195 |
||
3196 |
||
3197 |
// ---- Variables --------------------------------------------- |
|
3198 |
||
32865
f9cb6e427f9e
8136783: Run blessed-modifier-order script on java.desktop
prr
parents:
28231
diff
changeset
|
3199 |
static final int DEFAULT_FONT_SIZE = 3; |
2 | 3200 |
|
3201 |
private CSS css; |
|
3202 |
||
3203 |
/** |
|
3204 |
* An inverted graph of the selectors. |
|
3205 |
*/ |
|
3206 |
private SelectorMapping selectorMapping; |
|
3207 |
||
3208 |
/** Maps from selector (as a string) to Style that includes all |
|
3209 |
* relevant styles. */ |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
3210 |
private Hashtable<String, ResolvedStyle> resolvedStyles; |
2 | 3211 |
|
3212 |
/** Vector of StyleSheets that the rules are to reference. |
|
3213 |
*/ |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
3214 |
private Vector<StyleSheet> linkedStyleSheets; |
2 | 3215 |
|
3216 |
/** Where the style sheet was found. Used for relative imports. */ |
|
3217 |
private URL base; |
|
3218 |
||
3219 |
||
3220 |
/** |
|
3221 |
* Default parser for CSS specifications that get loaded into |
|
3222 |
* the StyleSheet.<p> |
|
3223 |
* This class is NOT thread safe, do not ask it to parse while it is |
|
3224 |
* in the middle of parsing. |
|
3225 |
*/ |
|
3226 |
class CssParser implements CSSParser.CSSParserCallback { |
|
3227 |
||
3228 |
/** |
|
3229 |
* Parses the passed in CSS declaration into an AttributeSet. |
|
3230 |
*/ |
|
3231 |
public AttributeSet parseDeclaration(String string) { |
|
3232 |
try { |
|
3233 |
return parseDeclaration(new StringReader(string)); |
|
3234 |
} catch (IOException ioe) {} |
|
3235 |
return null; |
|
3236 |
} |
|
3237 |
||
3238 |
/** |
|
3239 |
* Parses the passed in CSS declaration into an AttributeSet. |
|
3240 |
*/ |
|
3241 |
public AttributeSet parseDeclaration(Reader r) throws IOException { |
|
3242 |
parse(base, r, true, false); |
|
3243 |
return declaration.copyAttributes(); |
|
3244 |
} |
|
3245 |
||
3246 |
/** |
|
3247 |
* Parse the given CSS stream |
|
3248 |
*/ |
|
3249 |
public void parse(URL base, Reader r, boolean parseDeclaration, |
|
3250 |
boolean isLink) throws IOException { |
|
3251 |
this.base = base; |
|
3252 |
this.isLink = isLink; |
|
3253 |
this.parsingDeclaration = parseDeclaration; |
|
3254 |
declaration.removeAttributes(declaration); |
|
3255 |
selectorTokens.removeAllElements(); |
|
3256 |
selectors.removeAllElements(); |
|
3257 |
propertyName = null; |
|
3258 |
parser.parse(r, this, parseDeclaration); |
|
3259 |
} |
|
3260 |
||
3261 |
// |
|
3262 |
// CSSParserCallback methods, public to implement the interface. |
|
3263 |
// |
|
3264 |
||
3265 |
/** |
|
3266 |
* Invoked when a valid @import is encountered, will call |
|
3267 |
* <code>importStyleSheet</code> if a |
|
3268 |
* <code>MalformedURLException</code> is not thrown in creating |
|
3269 |
* the URL. |
|
3270 |
*/ |
|
3271 |
public void handleImport(String importString) { |
|
3272 |
URL url = CSS.getURL(base, importString); |
|
3273 |
if (url != null) { |
|
3274 |
importStyleSheet(url); |
|
3275 |
} |
|
3276 |
} |
|
3277 |
||
3278 |
/** |
|
3279 |
* A selector has been encountered. |
|
3280 |
*/ |
|
3281 |
public void handleSelector(String selector) { |
|
3282 |
//class and index selectors are case sensitive |
|
3283 |
if (!(selector.startsWith(".") |
|
3284 |
|| selector.startsWith("#"))) { |
|
3285 |
selector = selector.toLowerCase(); |
|
3286 |
} |
|
3287 |
int length = selector.length(); |
|
3288 |
||
3289 |
if (selector.endsWith(",")) { |
|
3290 |
if (length > 1) { |
|
3291 |
selector = selector.substring(0, length - 1); |
|
3292 |
selectorTokens.addElement(selector); |
|
3293 |
} |
|
3294 |
addSelector(); |
|
3295 |
} |
|
3296 |
else if (length > 0) { |
|
3297 |
selectorTokens.addElement(selector); |
|
3298 |
} |
|
3299 |
} |
|
3300 |
||
3301 |
/** |
|
3302 |
* Invoked when the start of a rule is encountered. |
|
3303 |
*/ |
|
3304 |
public void startRule() { |
|
3305 |
if (selectorTokens.size() > 0) { |
|
3306 |
addSelector(); |
|
3307 |
} |
|
3308 |
propertyName = null; |
|
3309 |
} |
|
3310 |
||
3311 |
/** |
|
3312 |
* Invoked when a property name is encountered. |
|
3313 |
*/ |
|
3314 |
public void handleProperty(String property) { |
|
3315 |
propertyName = property; |
|
3316 |
} |
|
3317 |
||
3318 |
/** |
|
3319 |
* Invoked when a property value is encountered. |
|
3320 |
*/ |
|
3321 |
public void handleValue(String value) { |
|
3322 |
if (propertyName != null && value != null && value.length() > 0) { |
|
3323 |
CSS.Attribute cssKey = CSS.getAttribute(propertyName); |
|
3324 |
if (cssKey != null) { |
|
3325 |
// There is currently no mechanism to determine real |
|
3326 |
// base that style sheet was loaded from. For the time |
|
3327 |
// being, this maps for LIST_STYLE_IMAGE, which appear |
|
3328 |
// to be the only one that currently matters. A more |
|
3329 |
// general mechanism is definately needed. |
|
3330 |
if (cssKey == CSS.Attribute.LIST_STYLE_IMAGE) { |
|
3331 |
if (value != null && !value.equals("none")) { |
|
3332 |
URL url = CSS.getURL(base, value); |
|
3333 |
||
3334 |
if (url != null) { |
|
3335 |
value = url.toString(); |
|
3336 |
} |
|
3337 |
} |
|
3338 |
} |
|
3339 |
addCSSAttribute(declaration, cssKey, value); |
|
3340 |
} |
|
3341 |
propertyName = null; |
|
3342 |
} |
|
3343 |
} |
|
3344 |
||
3345 |
/** |
|
3346 |
* Invoked when the end of a rule is encountered. |
|
3347 |
*/ |
|
3348 |
public void endRule() { |
|
3349 |
int n = selectors.size(); |
|
3350 |
for (int i = 0; i < n; i++) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
3351 |
String[] selector = selectors.elementAt(i); |
2 | 3352 |
if (selector.length > 0) { |
3353 |
StyleSheet.this.addRule(selector, declaration, isLink); |
|
3354 |
} |
|
3355 |
} |
|
3356 |
declaration.removeAttributes(declaration); |
|
3357 |
selectors.removeAllElements(); |
|
3358 |
} |
|
3359 |
||
3360 |
private void addSelector() { |
|
3361 |
String[] selector = new String[selectorTokens.size()]; |
|
3362 |
selectorTokens.copyInto(selector); |
|
3363 |
selectors.addElement(selector); |
|
3364 |
selectorTokens.removeAllElements(); |
|
3365 |
} |
|
3366 |
||
3367 |
||
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
3368 |
Vector<String[]> selectors = new Vector<String[]>(); |
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
2
diff
changeset
|
3369 |
Vector<String> selectorTokens = new Vector<String>(); |
2 | 3370 |
/** Name of the current property. */ |
3371 |
String propertyName; |
|
3372 |
MutableAttributeSet declaration = new SimpleAttributeSet(); |
|
3373 |
/** True if parsing a declaration, that is the Reader will not |
|
3374 |
* contain a selector. */ |
|
3375 |
boolean parsingDeclaration; |
|
3376 |
/** True if the attributes are coming from a linked/imported style. */ |
|
3377 |
boolean isLink; |
|
3378 |
/** Where the CSS stylesheet lives. */ |
|
3379 |
URL base; |
|
3380 |
CSSParser parser = new CSSParser(); |
|
3381 |
} |
|
3382 |
||
3383 |
void rebaseSizeMap(int base) { |
|
3384 |
final int minimalFontSize = 4; |
|
3385 |
sizeMap = new int[sizeMapDefault.length]; |
|
3386 |
for (int i = 0; i < sizeMapDefault.length; i++) { |
|
3387 |
sizeMap[i] = Math.max(base * sizeMapDefault[i] / |
|
3388 |
sizeMapDefault[CSS.baseFontSizeIndex], |
|
3389 |
minimalFontSize); |
|
3390 |
} |
|
3391 |
||
3392 |
} |
|
3393 |
||
3394 |
int[] getSizeMap() { |
|
3395 |
return sizeMap; |
|
3396 |
} |
|
3397 |
boolean isW3CLengthUnits() { |
|
3398 |
return w3cLengthUnits; |
|
3399 |
} |
|
3400 |
||
3401 |
/** |
|
3402 |
* The HTML/CSS size model has seven slots |
|
3403 |
* that one can assign sizes to. |
|
3404 |
*/ |
|
3405 |
static final int sizeMapDefault[] = { 8, 10, 12, 14, 18, 24, 36 }; |
|
3406 |
||
3407 |
private int sizeMap[] = sizeMapDefault; |
|
3408 |
private boolean w3cLengthUnits = false; |
|
3409 |
} |