KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > bridge > CSSUtilities


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

18 package org.apache.batik.bridge;
19
20 import java.awt.AlphaComposite JavaDoc;
21 import java.awt.Color JavaDoc;
22 import java.awt.Composite JavaDoc;
23 import java.awt.Cursor JavaDoc;
24 import java.awt.RenderingHints JavaDoc;
25 import java.awt.geom.GeneralPath JavaDoc;
26 import java.awt.geom.Rectangle2D JavaDoc;
27
28 import org.apache.batik.css.engine.CSSEngine;
29 import org.apache.batik.css.engine.CSSStylableElement;
30 import org.apache.batik.css.engine.SVGCSSEngine;
31 import org.apache.batik.css.engine.value.ListValue;
32 import org.apache.batik.css.engine.value.Value;
33 import org.apache.batik.css.engine.value.svg.ICCColor;
34 import org.apache.batik.dom.svg.SVGOMDocument;
35 import org.apache.batik.ext.awt.MultipleGradientPaint;
36 import org.apache.batik.ext.awt.image.renderable.ClipRable;
37 import org.apache.batik.ext.awt.image.renderable.Filter;
38 import org.apache.batik.gvt.CompositeGraphicsNode;
39 import org.apache.batik.gvt.GraphicsNode;
40 import org.apache.batik.gvt.filter.Mask;
41 import org.apache.batik.util.CSSConstants;
42 import org.apache.batik.util.XMLConstants;
43 import org.w3c.dom.Element JavaDoc;
44 import org.w3c.dom.css.CSSPrimitiveValue;
45 import org.w3c.dom.css.CSSValue;
46
47 /**
48  * A collection of utility method involving CSS property. The listed
49  * methods bellow could be used as convenient methods to create
50  * concrete objects regarding to CSS properties.
51  *
52  * @author <a HREF="mailto:tkormann@apache.org">Thierry Kormann</a>
53  * @version $Id: CSSUtilities.java,v 1.51 2004/08/20 19:29:46 deweese Exp $
54  */

55 public abstract class CSSUtilities
56     implements CSSConstants, ErrorConstants, XMLConstants {
57
58     /**
59      * No instance of this class is required.
60      */

61     protected CSSUtilities() {}
62
63     /////////////////////////////////////////////////////////////////////////
64
// Global methods
65
/////////////////////////////////////////////////////////////////////////
66

67     /**
68      * Returns CSSEngine associated to the specified element.
69      * @param e the element
70      */

71     public static CSSEngine getCSSEngine(Element e) {
72         return ((SVGOMDocument)e.getOwnerDocument()).getCSSEngine();
73     }
74
75     /**
76      * Returns the computed style of the given property.
77      */

78     public static Value getComputedStyle(Element e, int property) {
79         CSSEngine engine = getCSSEngine(e);
80         if (engine == null) return null;
81         return engine.getComputedStyle((CSSStylableElement)e,
82                                        null, property);
83     }
84
85     /////////////////////////////////////////////////////////////////////////
86
// 'pointer-events'
87
/////////////////////////////////////////////////////////////////////////
88

89     /**
90      * Returns the type that describes how this graphics node reacts to events.
91      *
92      * @return GraphicsNode.VISIBLE_PAINTED |
93      * GraphicsNode.VISIBLE_FILL |
94      * GraphicsNode.VISIBLE_STROKE |
95      * GraphicsNode.VISIBLE |
96      * GraphicsNode.PAINTED |
97      * GraphicsNode.FILL |
98      * GraphicsNode.STROKE |
99      * GraphicsNode.ALL |
100      * GraphicsNode.NONE
101      */

102     public static int convertPointerEvents(Element e) {
103         Value v = getComputedStyle(e, SVGCSSEngine.POINTER_EVENTS_INDEX);
104         String JavaDoc s = v.getStringValue();
105         switch(s.charAt(0)) {
106         case 'v':
107             if (s.length() == 7) {
108                 return GraphicsNode.VISIBLE;
109             } else {
110                 switch(s.charAt(7)) {
111                 case 'p':
112                     return GraphicsNode.VISIBLE_PAINTED;
113                 case 'f':
114                     return GraphicsNode.VISIBLE_FILL;
115                 case 's':
116                     return GraphicsNode.VISIBLE_STROKE;
117                 default:
118                     throw new Error JavaDoc(); // can't be reached
119
}
120             }
121         case 'p':
122             return GraphicsNode.PAINTED;
123         case 'f':
124             return GraphicsNode.FILL;
125         case 's':
126             return GraphicsNode.STROKE;
127         case 'a':
128             return GraphicsNode.ALL;
129         case 'n':
130             return GraphicsNode.NONE;
131         default:
132             throw new Error JavaDoc(); // can't be reached
133
}
134     }
135
136     /////////////////////////////////////////////////////////////////////////
137
// 'enable-background'
138
/////////////////////////////////////////////////////////////////////////
139

140     /**
141      * Returns the subregion of user space where access to the
142      * background image is allowed to happen.
143      *
144      * @param e the container element
145      */

146     public static Rectangle2D JavaDoc convertEnableBackground(Element e /*,
147                                         UnitProcessor.Context uctx*/
) {
148         Value v = getComputedStyle(e, SVGCSSEngine.ENABLE_BACKGROUND_INDEX);
149         if (v.getCssValueType() != CSSValue.CSS_VALUE_LIST) {
150             return null; // accumulate
151
}
152         ListValue lv = (ListValue)v;
153         int length = lv.getLength();
154         switch (length) {
155         case 1:
156             return CompositeGraphicsNode.VIEWPORT; // new
157
case 5: // new <x>,<y>,<width>,<height>
158
float x = lv.item(1).getFloatValue();
159             float y = lv.item(2).getFloatValue();
160             float w = lv.item(3).getFloatValue();
161             float h = lv.item(4).getFloatValue();
162             return new Rectangle2D.Float JavaDoc(x, y, w, h);
163
164         default:
165             throw new InternalError JavaDoc(); // Cannot happen
166
}
167     }
168
169     /////////////////////////////////////////////////////////////////////////
170
// 'color-interpolation-filters'
171
/////////////////////////////////////////////////////////////////////////
172

173     /**
174      * Returns the color space for the specified filter element. Checks the
175      * 'color-interpolation-filters' property.
176      *
177      * @param e the element
178      * @return true if the color space is linear, false otherwise (sRGB).
179      */

180     public static boolean convertColorInterpolationFilters(Element e) {
181         Value v = getComputedStyle(e,
182                              SVGCSSEngine.COLOR_INTERPOLATION_FILTERS_INDEX);
183         return CSS_LINEARRGB_VALUE == v.getStringValue();
184     }
185
186     /////////////////////////////////////////////////////////////////////////
187
// 'color-interpolation'
188
/////////////////////////////////////////////////////////////////////////
189

190     /**
191      * Returns the color space for the specified element. Checks the
192      * 'color-interpolation' property
193      *
194      * @param e the element
195      */

196     public static MultipleGradientPaint.ColorSpaceEnum
197         convertColorInterpolation(Element e) {
198         Value v = getComputedStyle(e, SVGCSSEngine.COLOR_INTERPOLATION_INDEX);
199         return (CSS_LINEARRGB_VALUE == v.getStringValue())
200             ? MultipleGradientPaint.LINEAR_RGB
201             : MultipleGradientPaint.SRGB;
202     }
203
204     /////////////////////////////////////////////////////////////////////////
205
// 'cursor'
206
/////////////////////////////////////////////////////////////////////////
207

208     /**
209      * Checks if the cursor property on the input element is set to auto
210      */

211     public static boolean isAutoCursor(Element e) {
212         Value cursorValue =
213             CSSUtilities.getComputedStyle(e,
214                                           SVGCSSEngine.CURSOR_INDEX);
215
216         boolean isAuto = false;
217         if (cursorValue != null){
218             if(
219                cursorValue.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE
220                &&
221                cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT
222                &&
223                cursorValue.getStringValue().charAt(0) == 'a'
224                ) {
225                 isAuto = true;
226             } else if (
227                        cursorValue.getCssValueType() == CSSValue.CSS_VALUE_LIST
228                        &&
229                        cursorValue.getLength() == 1) {
230                 Value lValue = cursorValue.item(0);
231                 if (lValue != null
232                     &&
233                     lValue.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE
234                     &&
235                     lValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT
236                     &&
237                     lValue.getStringValue().charAt(0) == 'a') {
238                     isAuto = true;
239                 }
240             }
241         }
242
243         return isAuto;
244     }
245
246     /**
247      * Returns the Cursor corresponding to the input element's
248      * cursor property
249      *
250      * @param e the element
251      */

252     public static Cursor JavaDoc
253         convertCursor(Element e, BridgeContext ctx) {
254         return ctx.getCursorManager().convertCursor(e);
255     }
256
257     ////////////////////////////////////////////////////////////////////////
258
// 'color-rendering', 'text-rendering', 'image-rendering',
259
// 'shape-rendering'
260
////////////////////////////////////////////////////////////////////////
261

262     /**
263      * Fills the rendering hints for the specified shape element or do
264      * nothing none has been specified. Checks the 'shape-rendering'
265      * property. If the given RenderingHints is null, a new
266      * RenderingHints is created.
267      *
268      * <p>Here is how the mapping between SVG rendering hints and the Java2D
269      * rendering hints is done:</p>
270      *
271      * <dl>
272      * <dt>'optimizeSpeed':</dt>
273      * <dd>
274      * <ul>
275      * <li>KEY_RENDERING=VALUE_RENDER_SPEED</li>
276      * <li>KEY_ANTIALIASING=VALUE_ANTIALIAS_OFF</li>
277      * </ul>
278      * </dd>
279      * <dt>'crispEdges':</dt>
280      * <dd>
281      * <ul>
282      * <li>KEY_RENDERING=VALUE_RENDER_DEFAULT</li>
283      * <li>KEY_ANTIALIASING=VALUE_ANTIALIAS_OFF</li>
284      * </ul>
285      * </dd>
286      * <dt>'geometricPrecision':</dt>
287      * <dd>
288      * <ul>
289      * <li>KEY_RENDERING=VALUE_RENDER_QUALITY</li>
290      * <li>KEY_ANTIALIASING=VALUE_ANTIALIAS_ON</li>
291      * </ul>
292      * </dd>
293      * </dl>
294      *
295      * @param e the element
296      * @param hints a RenderingHints to fill, or null.
297      */

298     public static RenderingHints JavaDoc convertShapeRendering(Element e,
299                                                        RenderingHints JavaDoc hints) {
300         Value v = getComputedStyle(e, SVGCSSEngine.SHAPE_RENDERING_INDEX);
301         String JavaDoc s = v.getStringValue();
302         int len = s.length();
303         if ((len == 4) && (s.charAt(0) == 'a')) // auto
304
return hints;
305         if (len < 10) return hints; // Unknown.
306

307         if (hints == null)
308             hints = new RenderingHints JavaDoc(null);
309         
310         switch(s.charAt(0)) {
311         case 'o': // optimizeSpeed
312
hints.put(RenderingHints.KEY_RENDERING,
313                       RenderingHints.VALUE_RENDER_SPEED);
314             hints.put(RenderingHints.KEY_ANTIALIASING,
315                       RenderingHints.VALUE_ANTIALIAS_OFF);
316             break;
317         case 'c': // crispEdges
318
hints.put(RenderingHints.KEY_RENDERING,
319                       RenderingHints.VALUE_RENDER_DEFAULT);
320             hints.put(RenderingHints.KEY_ANTIALIASING,
321                       RenderingHints.VALUE_ANTIALIAS_OFF);
322             break;
323         case 'g': // geometricPrecision
324
hints.put(RenderingHints.KEY_RENDERING,
325                       RenderingHints.VALUE_RENDER_QUALITY);
326             hints.put(RenderingHints.KEY_ANTIALIASING,
327                       RenderingHints.VALUE_ANTIALIAS_ON);
328             hints.put(RenderingHints.KEY_STROKE_CONTROL,
329                       RenderingHints.VALUE_STROKE_PURE);
330             break;
331         }
332         return hints;
333     }
334
335     /**
336      * Fills the rendering hints for the specified text element or do
337      * nothing if none has been specified. If the given RenderingHints
338      * is null, a new one is created. Checks the 'text-rendering'
339      * property.
340      *
341      * <p>Here is how the mapping between SVG rendering hints and the Java2D
342      * rendering hints is done:</p>
343      *
344      * <dl>
345      * <dt>'optimizeSpeed':</dt>
346      * <dd>
347      * <ul>
348      * <li>KEY_RENDERING=VALUE_RENDER_SPEED</li>
349      * <li>KEY_ANTIALIASING=VALUE_ANTIALIAS_OFF</li>
350      * <li>KEY_TEXT_ANTIALIASING=VALUE_TEXT_ANTIALIAS_OFF</li>
351      * <li>KEY_FRACTIONALMETRICS=VALUE_FRACTIONALMETRICS_OFF</li>
352      * </ul>
353      * </dd>
354      * <dt>'optimizeLegibility':</dt>
355      * <dd>
356      * <ul>
357      * <li>KEY_RENDERING=VALUE_RENDER_QUALITY</li>
358      * <li>KEY_ANTIALIASING=VALUE_ANTIALIAS_ON</li>
359      * <li>KEY_TEXT_ANTIALIASING=VALUE_TEXT_ANTIALIAS_ON</li>
360      * <li>KEY_FRACTIONALMETRICS=VALUE_FRACTIONALMETRICS_OFF</li>
361      * </ul>
362      * </dd>
363      * <dt>'geometricPrecision':</dt>
364      * <dd>
365      * <ul>
366      * <li>KEY_RENDERING=VALUE_RENDER_QUALITY</li>
367      * <li>KEY_ANTIALIASING=VALUE_ANTIALIAS_DEFAULT</li>
368      * <li>KEY_TEXT_ANTIALIASING=VALUE_TEXT_ANTIALIAS_DEFAULT</li>
369      * <li>KEY_FRACTIONALMETRICS=VALUE_FRACTIONALMETRICS_ON</li>
370      * </ul>
371      * </dd>
372      * </dl>
373      *
374      * <p>Note that for text both KEY_TEXT_ANTIALIASING and
375      * KEY_ANTIALIASING are set as there is no guarantee that a Java2D
376      * text rendering primitive will be used to draw text (eg. SVG
377      * Font...).</p>
378      *
379      * @param e the element
380      * @param hints a RenderingHints to fill, or null.
381      */

382     public static RenderingHints JavaDoc convertTextRendering(Element e,
383                                                       RenderingHints JavaDoc hints) {
384         Value v = getComputedStyle(e, SVGCSSEngine.TEXT_RENDERING_INDEX);
385         String JavaDoc s = v.getStringValue();
386         int len = s.length();
387         if ((len == 4) && (s.charAt(0) == 'a')) // auto
388
return hints;
389         if (len < 13) return hints; // Unknown.
390

391         if (hints == null)
392             hints = new RenderingHints JavaDoc(null);
393
394         switch(s.charAt(8)) {
395         case 's': // optimizeSpeed
396
hints.put(RenderingHints.KEY_RENDERING,
397                       RenderingHints.VALUE_RENDER_SPEED);
398             hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
399                       RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
400             hints.put(RenderingHints.KEY_ANTIALIASING,
401                       RenderingHints.VALUE_ANTIALIAS_OFF);
402             // hints.put(RenderingHints.KEY_FRACTIONALMETRICS,
403
// RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
404
break;
405         case 'l': // optimizeLegibility
406
hints.put(RenderingHints.KEY_RENDERING,
407                       RenderingHints.VALUE_RENDER_QUALITY);
408             hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
409                       RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
410             hints.put(RenderingHints.KEY_ANTIALIASING,
411                       RenderingHints.VALUE_ANTIALIAS_ON);
412             // hints.put(RenderingHints.KEY_FRACTIONALMETRICS,
413
// RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
414
break;
415         case 'c': // geometricPrecision
416
hints.put(RenderingHints.KEY_RENDERING,
417                       RenderingHints.VALUE_RENDER_QUALITY);
418             hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
419                       RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
420             hints.put(RenderingHints.KEY_ANTIALIASING,
421                       RenderingHints.VALUE_ANTIALIAS_ON);
422             hints.put(RenderingHints.KEY_FRACTIONALMETRICS,
423                       RenderingHints.VALUE_FRACTIONALMETRICS_ON);
424             hints.put(RenderingHints.KEY_STROKE_CONTROL,
425                       RenderingHints.VALUE_STROKE_PURE);
426             break;
427         }
428         return hints;
429     }
430
431     /**
432      * Fills the rendering hints for the specified image element or do
433      * nothing if none has been specified. If the given RenderingHints
434      * is null, a new one is created. Checks the 'image-rendering'
435      * property.
436      *
437      * <p>Here is how the mapping between SVG rendering hints and the Java2D
438      * rendering hints is done:</p>
439      *
440      * <dl>
441      * <dt>'optimizeSpeed':</dt>
442      * <dd>
443      * <ul>
444      * <li>KEY_RENDERING=VALUE_RENDER_SPEED</li>
445      * <li>KEY_INTERPOLATION=VALUE_INTERPOLATION_NEAREST_NEIGHBOR</li>
446      * </ul>
447      * </dd>
448      * <dt>'optimizeQuality':</dt>
449      * <dd>
450      * <ul>
451      * <li>KEY_RENDERING=VALUE_RENDER_QUALITY</li>
452      * <li>KEY_INTERPOLATION=VALUE_INTERPOLATION_BICUBIC</li>
453      * </ul>
454      * </dd>
455      * </dl>
456      *
457      * @param e the element
458      * @param hints a RenderingHints to fill, or null.
459      */

460     public static RenderingHints JavaDoc convertImageRendering(Element e,
461                                                        RenderingHints JavaDoc hints) {
462         Value v = getComputedStyle(e, SVGCSSEngine.IMAGE_RENDERING_INDEX);
463         String JavaDoc s = v.getStringValue();
464         int len = s.length();
465         if ((len == 4) && (s.charAt(0) == 'a')) // auto
466
return hints;
467         if (len < 13) return hints; // Unknown.
468

469         if (hints == null)
470             hints = new RenderingHints JavaDoc(null);
471
472         switch(s.charAt(8)) {
473         case 's': // optimizeSpeed
474
hints.put(RenderingHints.KEY_RENDERING,
475                       RenderingHints.VALUE_RENDER_SPEED);
476             hints.put(RenderingHints.KEY_INTERPOLATION,
477                       RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
478             break;
479         case 'q': // optimizeQuality
480
hints.put(RenderingHints.KEY_RENDERING,
481                       RenderingHints.VALUE_RENDER_QUALITY);
482             hints.put(RenderingHints.KEY_INTERPOLATION,
483                       RenderingHints.VALUE_INTERPOLATION_BICUBIC);
484             break;
485         }
486         return hints;
487     }
488
489     /**
490      * Fills the rendering hints for the specified element or do
491      * nothing if none has been specified. If the given RenderingHints
492      * is null, a new one is created. Checks the 'color-rendering'
493      * property.
494      *
495      * <p>Here is how the mapping between SVG rendering hints and the Java2D
496      * rendering hints is done:</p>
497      *
498      * <dl>
499      * <dt>'optimizeSpeed':</dt>
500      * <dd>
501      * <ul>
502      * <li>KEY_COLOR_RENDERING=VALUE_COLOR_RENDER_SPEED</li>
503      * <li>KEY_ALPHA_INTERPOLATION=VALUE_ALPHA_INTERPOLATION_SPEED</li>
504      * </ul>
505      * </dd>
506      * <dt>'optimizeQuality':</dt>
507      * <dd>
508      * <ul>
509      * <li>KEY_COLOR_RENDERING=VALUE_COLOR_RENDER_QUALITY</li>
510      * <li>KEY_ALPHA_INTERPOLATION=VALUE_ALPHA_INTERPOLATION_QUALITY</li>
511      * </ul>
512      * </dd>
513      * </dl>
514      *
515      * @param e the element
516      * @param hints a RenderingHints to fill, or null.
517      */

518     public static RenderingHints JavaDoc convertColorRendering(Element e,
519                                                        RenderingHints JavaDoc hints) {
520         Value v = getComputedStyle(e, SVGCSSEngine.COLOR_RENDERING_INDEX);
521         String JavaDoc s = v.getStringValue();
522         int len = s.length();
523         if ((len == 4) && (s.charAt(0) == 'a')) // auto
524
return hints;
525         if (len < 13) return hints; // Unknown.
526

527         if (hints == null)
528             hints = new RenderingHints JavaDoc(null);
529
530         switch(s.charAt(8)) {
531         case 's': // optimizeSpeed
532
hints.put(RenderingHints.KEY_COLOR_RENDERING,
533                       RenderingHints.VALUE_COLOR_RENDER_SPEED);
534             hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
535                       RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
536             break;
537         case 'q': // optimizeQuality
538
hints.put(RenderingHints.KEY_COLOR_RENDERING,
539                       RenderingHints.VALUE_COLOR_RENDER_QUALITY);
540             hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
541                       RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
542             break;
543         }
544         return hints;
545     }
546
547     /////////////////////////////////////////////////////////////////////////
548
// 'display'
549
/////////////////////////////////////////////////////////////////////////
550

551     /**
552      * Returns true if the specified element has to be displayed, false
553      * otherwise. Checks the 'display' property.
554      *
555      * @param e the element
556      */

557     public static boolean convertDisplay(Element e) {
558         Value v = getComputedStyle(e, SVGCSSEngine.DISPLAY_INDEX);
559         return v.getStringValue().charAt(0) != 'n';
560     }
561
562     /////////////////////////////////////////////////////////////////////////
563
// 'visibility'
564
/////////////////////////////////////////////////////////////////////////
565

566     /**
567      * Returns true if the specified element is visible, false
568      * otherwise. Checks the 'visibility' property.
569      *
570      * @param e the element
571      */

572     public static boolean convertVisibility(Element e) {
573         Value v = getComputedStyle(e, SVGCSSEngine.VISIBILITY_INDEX);
574         return v.getStringValue().charAt(0) == 'v';
575     }
576
577     /////////////////////////////////////////////////////////////////////////
578
// 'opacity'
579
/////////////////////////////////////////////////////////////////////////
580

581     public final static Composite JavaDoc TRANSPARENT =
582         AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0);
583
584     /**
585      * Returns a composite object that represents the 'opacity' of the
586      * specified element.
587      *
588      * @param e the element
589      */

590     public static Composite JavaDoc convertOpacity(Element e) {
591         Value v = getComputedStyle(e, SVGCSSEngine.OPACITY_INDEX);
592         float f = v.getFloatValue();
593         if (f <= 0f) {
594             return TRANSPARENT;
595         } else if (f >= 1f) {
596             return AlphaComposite.SrcOver;
597         } else {
598             return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, f);
599         }
600     }
601
602     /////////////////////////////////////////////////////////////////////////
603
// 'overflow' and 'clip'
604
/////////////////////////////////////////////////////////////////////////
605

606     /**
607      * Returns true if the 'overflow' property indicates that an
608      * additional clip is required, false otherwise. An additional
609      * clip is needed if the 'overflow' property is 'scroll' or
610      * 'hidden'.
611      *
612      * @param e the element with the 'overflow' property
613      */

614     public static boolean convertOverflow(Element e) {
615         Value v = getComputedStyle(e, SVGCSSEngine.OVERFLOW_INDEX);
616         String JavaDoc s = v.getStringValue();
617         return (s.charAt(0) == 'h') || (s.charAt(0) == 's');
618     }
619
620     /**
621      * Returns an array of floating offsets representing the 'clip'
622      * property or null if 'auto'. The offsets are specified in the
623      * order top, right, bottom, left.
624      *
625      * @param e the element with the 'clip' property
626      */

627     public static float[] convertClip(Element e) {
628         Value v = getComputedStyle(e, SVGCSSEngine.CLIP_INDEX);
629         switch (v.getPrimitiveType()) {
630         case CSSPrimitiveValue.CSS_RECT:
631             float [] off = new float[4];
632             off[0] = v.getTop().getFloatValue();
633             off[1] = v.getRight().getFloatValue();
634             off[2] = v.getBottom().getFloatValue();
635             off[3] = v.getLeft().getFloatValue();
636             return off;
637         case CSSPrimitiveValue.CSS_IDENT:
638             return null; // 'auto' means no offsets
639
default:
640             throw new Error JavaDoc(); // can't be reached
641
}
642     }
643
644     /////////////////////////////////////////////////////////////////////////
645
// 'filter'
646
/////////////////////////////////////////////////////////////////////////
647

648     /**
649      * Returns a <tt>Filter</tt> referenced by the specified element
650      * and which applies on the specified graphics node.
651      * Handle the 'filter' property.
652      *
653      * @param filteredElement the element that references the filter
654      * @param filteredNode the graphics node associated to the element
655      * to filter.
656      * @param ctx the bridge context
657      */

658     public static Filter convertFilter(Element filteredElement,
659                                        GraphicsNode filteredNode,
660                                        BridgeContext ctx) {
661         Value v = getComputedStyle(filteredElement, SVGCSSEngine.FILTER_INDEX);
662         switch (v.getPrimitiveType()) {
663         case CSSPrimitiveValue.CSS_IDENT:
664             return null; // 'filter:none'
665

666         case CSSPrimitiveValue.CSS_URI:
667             String JavaDoc uri = v.getStringValue();
668             Element filter = ctx.getReferencedElement(filteredElement, uri);
669             Bridge bridge = ctx.getBridge(filter);
670             if (bridge == null || !(bridge instanceof FilterBridge)) {
671                 throw new BridgeException(filteredElement,
672                                           ERR_CSS_URI_BAD_TARGET,
673                                           new Object JavaDoc[] {uri});
674             }
675             return ((FilterBridge)bridge).createFilter(ctx,
676                                                        filter,
677                                                        filteredElement,
678                                                        filteredNode);
679         default:
680             throw new InternalError JavaDoc(); // can't be reached
681

682         }
683     }
684
685     /////////////////////////////////////////////////////////////////////////
686
// 'clip-path' and 'clip-rule'
687
/////////////////////////////////////////////////////////////////////////
688

689     /**
690      * Returns a <tt>Clip</tt> referenced by the specified element and
691      * which applies on the specified graphics node.
692      * Handle the 'clip-path' property.
693      *
694      * @param clippedElement the element that references the clip
695      * @param clippedNode the graphics node associated to the element to clip
696      * @param ctx the bridge context
697      */

698     public static ClipRable convertClipPath(Element clippedElement,
699                                             GraphicsNode clippedNode,
700                                             BridgeContext ctx) {
701         Value v = getComputedStyle(clippedElement,
702                                    SVGCSSEngine.CLIP_PATH_INDEX);
703         switch (v.getPrimitiveType()) {
704         case CSSPrimitiveValue.CSS_IDENT:
705             return null; // 'clip-path:none'
706

707         case CSSPrimitiveValue.CSS_URI:
708             String JavaDoc uri = v.getStringValue();
709             Element cp = ctx.getReferencedElement(clippedElement, uri);
710             Bridge bridge = ctx.getBridge(cp);
711             if (bridge == null || !(bridge instanceof ClipBridge)) {
712                 throw new BridgeException(clippedElement,
713                                           ERR_CSS_URI_BAD_TARGET,
714                                           new Object JavaDoc[] {uri});
715             }
716             return ((ClipBridge)bridge).createClip(ctx,
717                                                    cp,
718                                                    clippedElement,
719                                                    clippedNode);
720         default:
721             throw new InternalError JavaDoc(); // can't be reached
722

723         }
724     }
725
726     /**
727      * Returns the 'clip-rule' for the specified element.
728      *
729      * @param e the element interested in its a 'clip-rule'
730      * @return GeneralPath.WIND_NON_ZERO | GeneralPath.WIND_EVEN_ODD
731      */

732     public static int convertClipRule(Element e) {
733         Value v = getComputedStyle(e, SVGCSSEngine.CLIP_RULE_INDEX);
734         return (v.getStringValue().charAt(0) == 'n')
735             ? GeneralPath.WIND_NON_ZERO
736             : GeneralPath.WIND_EVEN_ODD;
737     }
738
739     /////////////////////////////////////////////////////////////////////////
740
// 'mask'
741
/////////////////////////////////////////////////////////////////////////
742

743     /**
744      * Returns a <tt>Mask</tt> referenced by the specified element and
745      * which applies on the specified graphics node.
746      * Handle the 'mask' property.
747      *
748      * @param maskedElement the element that references the mask
749      * @param maskedNode the graphics node associated to the element to mask
750      * @param ctx the bridge context
751      */

752     public static Mask convertMask(Element maskedElement,
753                                    GraphicsNode maskedNode,
754                                    BridgeContext ctx) {
755         Value v = getComputedStyle(maskedElement, SVGCSSEngine.MASK_INDEX);
756         switch (v.getPrimitiveType()) {
757         case CSSPrimitiveValue.CSS_IDENT:
758             return null; // 'mask:none'
759

760         case CSSPrimitiveValue.CSS_URI:
761             String JavaDoc uri = v.getStringValue();
762             Element m = ctx.getReferencedElement(maskedElement, uri);
763             Bridge bridge = ctx.getBridge(m);
764             if (bridge == null || !(bridge instanceof MaskBridge)) {
765                 throw new BridgeException(maskedElement,
766                                           ERR_CSS_URI_BAD_TARGET,
767                                           new Object JavaDoc[] {uri});
768             }
769             return ((MaskBridge)bridge).createMask(ctx,
770                                                    m,
771                                                    maskedElement,
772                                                    maskedNode);
773         default:
774             throw new InternalError JavaDoc(); // can't be reached
775

776         }
777     }
778
779     /**
780      * Returns the 'fill-rule' for the specified element.
781      *
782      * @param e the element interested in its a 'fill-rule'
783      * @return GeneralPath.WIND_NON_ZERO | GeneralPath.WIND_EVEN_ODD
784      */

785     public static int convertFillRule(Element e) {
786         Value v = getComputedStyle(e, SVGCSSEngine.FILL_RULE_INDEX);
787         return (v.getStringValue().charAt(0) == 'n')
788             ? GeneralPath.WIND_NON_ZERO
789             : GeneralPath.WIND_EVEN_ODD;
790     }
791
792     /////////////////////////////////////////////////////////////////////////
793
// 'lighting-color'
794
/////////////////////////////////////////////////////////////////////////
795

796     /**
797      * Converts the color defined on the specified lighting filter element
798      * to a <tt>Color</tt>.
799      *
800      * @param e the lighting filter element
801      * @param ctx the bridge context
802      */

803     public static Color JavaDoc convertLightingColor(Element e, BridgeContext ctx) {
804         Value v = getComputedStyle(e, SVGCSSEngine.LIGHTING_COLOR_INDEX);
805         if (v.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
806             return PaintServer.convertColor(v, 1);
807         } else {
808             return PaintServer.convertRGBICCColor
809                 (e, v.item(0), (ICCColor)v.item(1), 1, ctx);
810         }
811     }
812
813     /////////////////////////////////////////////////////////////////////////
814
// 'flood-color' and 'flood-opacity'
815
/////////////////////////////////////////////////////////////////////////
816

817     /**
818      * Converts the color defined on the specified &lt;feFlood>
819      * element to a <tt>Color</tt>.
820      *
821      * @param e the feFlood element
822      * @param ctx the bridge context
823      */

824     public static Color JavaDoc convertFloodColor(Element e, BridgeContext ctx) {
825         Value v = getComputedStyle(e, SVGCSSEngine.FLOOD_COLOR_INDEX);
826         Value o = getComputedStyle(e, SVGCSSEngine.FLOOD_OPACITY_INDEX);
827         float f = PaintServer.convertOpacity(o);
828         if (v.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
829             return PaintServer.convertColor(v, f);
830         } else {
831             return PaintServer.convertRGBICCColor
832                 (e, v.item(0), (ICCColor)v.item(1), f, ctx);
833         }
834     }
835
836     /////////////////////////////////////////////////////////////////////////
837
// 'stop-color'
838
/////////////////////////////////////////////////////////////////////////
839

840     /**
841      * Converts the color defined on the specified &lt;stop> element
842      * to a <tt>Color</tt>.
843      *
844      * @param e the stop element
845      * @param opacity the paint opacity
846      * @param ctx the bridge context to use
847      */

848     public static Color JavaDoc convertStopColor(Element e,
849                                          float opacity,
850                                          BridgeContext ctx) {
851         Value v = getComputedStyle(e, SVGCSSEngine.STOP_COLOR_INDEX);
852         Value o = getComputedStyle(e, SVGCSSEngine.STOP_OPACITY_INDEX);
853         opacity *= PaintServer.convertOpacity(o);
854         if (v.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
855             return PaintServer.convertColor(v, opacity);
856         } else {
857             return PaintServer.convertRGBICCColor
858                 (e, v.item(0), (ICCColor)v.item(1), opacity, ctx);
859         }
860     }
861
862     /////////////////////////////////////////////////////////////////////////
863
// CSS support for <use>
864
/////////////////////////////////////////////////////////////////////////
865

866     /**
867      * Partially computes the style in the 'def' tree and set it in the 'use'
868      * tree.
869      * <p>Note: This method must be called only when 'use' has been
870      * added to the DOM tree.
871      *
872      * @param refElement the referenced element
873      * @param localRefElement the referenced element in the current document
874      */

875     public static void computeStyleAndURIs(Element refElement,
876                                            Element localRefElement,
877                                            String JavaDoc uri) {
878     // Pull fragement id off first...
879
int idx = uri.indexOf('#');
880         if (idx != -1)
881             uri = uri.substring(0,idx);
882
883     // Only set xml:base if we have a real URL.
884
if (uri.length() != 0)
885             localRefElement.setAttributeNS(XML_NAMESPACE_URI,
886                                            "base",
887                                            uri);
888
889         CSSEngine engine = CSSUtilities.getCSSEngine(localRefElement);
890         CSSEngine refEngine = CSSUtilities.getCSSEngine(refElement);
891         
892         engine.importCascadedStyleMaps(refElement, refEngine, localRefElement);
893     }
894
895     /////////////////////////////////////////////////////////////////////////
896
// Additional utility methods used internally
897
/////////////////////////////////////////////////////////////////////////
898

899     /**
900      * Returns the winding rule represented by the specified CSSValue.
901      *
902      * @param v the value that represents the rule
903      * @return GeneralPath.WIND_NON_ZERO | GeneralPath.WIND_EVEN_ODD
904      */

905     protected static int rule(CSSValue v) {
906         return (((CSSPrimitiveValue)v).getStringValue().charAt(0) == 'n')
907             ? GeneralPath.WIND_NON_ZERO
908             : GeneralPath.WIND_EVEN_ODD;
909     }
910 }
911
Popular Tags