KickJava   Java API By Example, From Geeks To Geeks.

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


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.Paint JavaDoc;
21 import java.awt.Stroke JavaDoc;
22 import java.awt.font.TextAttribute JavaDoc;
23 import java.text.AttributedCharacterIterator JavaDoc;
24
25 import org.apache.batik.dom.svg.SVGOMDocument;
26 import org.apache.batik.dom.svg.XMLBaseSupport;
27 import org.apache.batik.dom.util.XLinkSupport;
28 import org.apache.batik.gvt.font.Glyph;
29 import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
30 import org.apache.batik.gvt.text.TextPaintInfo;
31 import org.w3c.dom.Element JavaDoc;
32 import org.w3c.dom.Node JavaDoc;
33 import org.w3c.dom.NodeList JavaDoc;
34
35
36 /**
37  * Bridge class for the <altGlyph> element.
38  *
39  * @author <a HREF="mailto:bella.robinson@cmis.csiro.au">Bella Robinson</a>
40  * @version $Id: SVGAltGlyphElementBridge.java,v 1.18 2005/03/03 01:19:52 deweese Exp $
41  */

42 public class SVGAltGlyphElementBridge extends AbstractSVGBridge
43                                       implements ErrorConstants {
44
45     public static final AttributedCharacterIterator.Attribute JavaDoc PAINT_INFO
46         = GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO;
47
48     /**
49      * Constructs a new bridge for the &lt;altGlyph> element.
50      */

51     public SVGAltGlyphElementBridge() {
52     }
53
54     /**
55      * Returns 'altGlyph'.
56      */

57     public String JavaDoc getLocalName() {
58         return SVG_ALT_GLYPH_TAG;
59     }
60
61     /**
62      * Constructs an array of Glyphs that represents the specified
63      * &lt;altGlyph> element at the requested size.
64      *
65      * @param ctx The current bridge context.
66      * @param altGlyphElement The altGlyph element to base the SVGGVTGlyphVector
67      * construction on.
68      * @param fontSize The font size of the Glyphs to create.
69      *
70      * @return The new SVGGVTGlyphVector or null if any of the glyphs are
71      * unavailable.
72      */

73     public Glyph[] createAltGlyphArray(BridgeContext ctx,
74                                        Element JavaDoc altGlyphElement,
75                                        float fontSize,
76                                        AttributedCharacterIterator JavaDoc aci) {
77
78         // get the referenced element
79
String JavaDoc uri = XLinkSupport.getXLinkHref(altGlyphElement);
80
81         Element JavaDoc refElement = null;
82
83         try {
84             refElement = ctx.getReferencedElement(altGlyphElement, uri);
85         } catch (BridgeException e) {
86             if (ERR_URI_UNSECURE.equals(e.getCode())) {
87                 ctx.getUserAgent().displayError(e);
88             }
89         }
90
91         if (refElement == null) {
92             // couldn't find the referenced element
93
return null;
94         }
95         if (!SVG_NAMESPACE_URI.equals(refElement.getNamespaceURI()))
96             return null; // Not an SVG element.
97

98         // if the referenced element is a glyph
99
if (refElement.getLocalName().equals(SVG_GLYPH_TAG)) {
100
101             Glyph glyph = getGlyph(ctx, uri, altGlyphElement, fontSize, aci);
102
103             if (glyph == null) {
104                 // failed to create a glyph for the specified glyph uri
105
return null;
106             }
107
108             Glyph[] glyphArray = new Glyph[1];
109             glyphArray[0] = glyph;
110             return glyphArray;
111         }
112
113         // else should be an altGlyphDef element
114
if (refElement.getLocalName().equals(SVG_ALT_GLYPH_DEF_TAG)) {
115
116             // if not local import the referenced altGlyphDef
117
// into the current document
118
SVGOMDocument document
119                 = (SVGOMDocument)altGlyphElement.getOwnerDocument();
120             SVGOMDocument refDocument
121                 = (SVGOMDocument)refElement.getOwnerDocument();
122             boolean isLocal = (refDocument == document);
123
124             Element JavaDoc localRefElement = (isLocal) ? refElement
125                                  : (Element JavaDoc)document.importNode(refElement, true);
126             if (!isLocal) {
127                 // need to attach the imported element to the document and
128
// then compute the styles and uris
129
String JavaDoc base = XMLBaseSupport.getCascadedXMLBase(altGlyphElement);
130                 Element JavaDoc g = document.createElementNS(SVG_NAMESPACE_URI, SVG_G_TAG);
131                 g.appendChild(localRefElement);
132                 g.setAttributeNS(XMLBaseSupport.XML_NAMESPACE_URI,
133                                  "xml:base",
134                                  base);
135                 CSSUtilities.computeStyleAndURIs(refElement,
136                                                  localRefElement,
137                                                  uri);
138             }
139
140             // look for glyphRef children
141
NodeList JavaDoc altGlyphDefChildren = localRefElement.getChildNodes();
142             boolean containsGlyphRefNodes = false;
143             int numAltGlyphDefChildren = altGlyphDefChildren.getLength();
144             for (int i = 0; i < numAltGlyphDefChildren; i++) {
145                 Node JavaDoc altGlyphChild = altGlyphDefChildren.item(i);
146                 if (altGlyphChild.getNodeType() == Node.ELEMENT_NODE) {
147                     Element JavaDoc agc = (Element JavaDoc)altGlyphChild;
148                     if (SVG_NAMESPACE_URI.equals(agc.getNamespaceURI()) &&
149                         SVG_GLYPH_REF_TAG.equals(agc.getLocalName())) {
150                         containsGlyphRefNodes = true;
151                         break;
152                     }
153                 }
154             }
155             if (containsGlyphRefNodes) { // process the glyphRef children
156

157                 NodeList JavaDoc glyphRefNodes
158                     = localRefElement.getElementsByTagNameNS(SVG_NAMESPACE_URI,
159                                  SVG_GLYPH_REF_TAG);
160                 int numGlyphRefNodes = glyphRefNodes.getLength();
161                 Glyph[] glyphArray = new Glyph[numGlyphRefNodes];
162                 for (int i = 0; i < numGlyphRefNodes; i++) {
163                     // get the referenced glyph element
164
Element JavaDoc glyphRefElement = (Element JavaDoc)glyphRefNodes.item(i);
165                     String JavaDoc glyphUri = XLinkSupport.getXLinkHref(glyphRefElement);
166
167                     Glyph glyph
168                         = getGlyph(ctx, glyphUri, glyphRefElement, fontSize, aci);
169                     if (glyph == null) {
170                         // failed to create a glyph for the specified glyph uri
171
return null;
172                     }
173                     glyphArray[i] = glyph;
174                 }
175                 return glyphArray;
176
177             } else { // try looking for altGlyphItem children
178

179                 NodeList JavaDoc altGlyphItemNodes
180                     = localRefElement.getElementsByTagNameNS
181             (SVG_NAMESPACE_URI, SVG_ALT_GLYPH_ITEM_TAG);
182                 int numAltGlyphItemNodes = altGlyphItemNodes.getLength();
183                 if (numAltGlyphItemNodes > 0) {
184                     boolean foundMatchingGlyph = false;
185                     Glyph[] glyphArray = null;
186
187                     //look through all altGlyphItem to find the one
188
//that have all its glyphs available
189

190                     for (int i = 0; i < numAltGlyphItemNodes && !foundMatchingGlyph ; i++) {
191
192                         // try to find a resolvable glyphRef
193
Element JavaDoc altGlyphItemElement = (Element JavaDoc)altGlyphItemNodes.item(i);
194                         NodeList JavaDoc altGlyphRefNodes
195                             = altGlyphItemElement.getElementsByTagNameNS
196                 (SVG_NAMESPACE_URI, SVG_GLYPH_REF_TAG);
197                         int numAltGlyphRefNodes = altGlyphRefNodes.getLength();
198
199                         glyphArray = new Glyph[numAltGlyphRefNodes];
200
201                         // consider that all glyphs are available
202
// and check if they can be found
203
foundMatchingGlyph = true;
204
205                         for (int j = 0; j < numAltGlyphRefNodes; j++) {
206                             // get the referenced glyph element
207
Element JavaDoc glyphRefElement = (Element JavaDoc)altGlyphRefNodes.item(j);
208                             String JavaDoc glyphUri = XLinkSupport.getXLinkHref(glyphRefElement);
209
210                             Glyph glyph = getGlyph(ctx, glyphUri, glyphRefElement, fontSize, aci);
211                             if (glyph != null) {
212                                 // found a matching glyph for this altGlyphItem
213
glyphArray[j] = glyph;
214                             }
215                             else{
216                                 //this altGlyphItem is not good
217
//seek for the next one
218
foundMatchingGlyph = false;
219                                 break;
220                             }
221                         }
222                     }
223                     if (!foundMatchingGlyph) {
224                         // couldn't find a alGlyphItem
225
// with all its glyphs available
226
// so stop and return null
227
return null;
228                     }
229                     
230                     return glyphArray;
231                 }
232             }
233         }
234
235
236         /*
237         // reference is not to a valid element type, throw an exception
238         throw new BridgeException(altGlyphElement, ERR_URI_BAD_TARGET,
239                                   new Object[] {uri});
240         */

241         //reference not valid, no altGlyph created
242
return null;
243     }
244
245
246     /**
247      * Returns a Glyph object that represents the glyph at the specified URI
248      * scaled to the required font size.
249      *
250      * @param ctx The bridge context.
251      * @param glyphUri The URI of the glyph to retreive.
252      * @param altGlyphElement The element that references the glyph.
253      * @param fontSize Indicates the required size of the glyph.
254      * @return The Glyph or null if the glyph URI is not available.
255      */

256     private Glyph getGlyph(BridgeContext ctx,
257                            String JavaDoc glyphUri,
258                            Element JavaDoc altGlyphElement,
259                            float fontSize,
260                            AttributedCharacterIterator JavaDoc aci) {
261
262         Element JavaDoc refGlyphElement = null;
263         try {
264             refGlyphElement = ctx.getReferencedElement(altGlyphElement,
265                                                        glyphUri);
266         } catch (BridgeException e) {
267             // this is ok, it is possible that the glyph at the given
268
// uri is not available.
269

270             // Display an error message if a security exception occured
271
if (ERR_URI_UNSECURE.equals(e.getCode())) {
272                 ctx.getUserAgent().displayError(e);
273             }
274         }
275
276         if ((refGlyphElement == null) ||
277             (!SVG_NAMESPACE_URI.equals(refGlyphElement.getNamespaceURI())) ||
278             (!SVG_GLYPH_TAG.equals(refGlyphElement.getLocalName())))
279             // couldn't find the referenced glyph element,
280
// or referenced element not a glyph
281
return null;
282
283         // see if the referenced glyph element is local
284
SVGOMDocument document
285             = (SVGOMDocument)altGlyphElement.getOwnerDocument();
286         SVGOMDocument refDocument
287             = (SVGOMDocument)refGlyphElement.getOwnerDocument();
288         boolean isLocal = (refDocument == document);
289
290         // if not local, import both the glyph and its font-face element
291
Element JavaDoc localGlyphElement = null;
292         Element JavaDoc localFontFaceElement = null;
293         Element JavaDoc localFontElement = null;
294         if (isLocal) {
295             localGlyphElement = refGlyphElement;
296             localFontElement = (Element JavaDoc)localGlyphElement.getParentNode();
297             NodeList JavaDoc fontFaceElements
298                 = localFontElement.getElementsByTagNameNS
299         (SVG_NAMESPACE_URI, SVG_FONT_FACE_TAG);
300             if (fontFaceElements.getLength() > 0) {
301                 localFontFaceElement = (Element JavaDoc)fontFaceElements.item(0);
302             }
303
304         } else {
305             // import the whole font
306
localFontElement = (Element JavaDoc)document.importNode
307                 (refGlyphElement.getParentNode(), true);
308             String JavaDoc base = XMLBaseSupport.getCascadedXMLBase(altGlyphElement);
309             Element JavaDoc g = document.createElementNS(SVG_NAMESPACE_URI, SVG_G_TAG);
310             g.appendChild(localFontElement);
311             g.setAttributeNS(XMLBaseSupport.XML_NAMESPACE_URI,
312                              "xml:base",
313                              base);
314             CSSUtilities.computeStyleAndURIs(
315                 (Element JavaDoc)refGlyphElement.getParentNode(),
316                 localFontElement, glyphUri);
317
318             // get the local glyph element
319
String JavaDoc glyphId = refGlyphElement.getAttributeNS
320                 (null, SVG_ID_ATTRIBUTE);
321             NodeList JavaDoc glyphElements = localFontElement.getElementsByTagNameNS
322         (SVG_NAMESPACE_URI, SVG_GLYPH_TAG);
323             for (int i = 0; i < glyphElements.getLength(); i++) {
324                 Element JavaDoc glyphElem = (Element JavaDoc)glyphElements.item(i);
325                 if (glyphElem.getAttributeNS(null, SVG_ID_ATTRIBUTE).equals(glyphId)) {
326                     localGlyphElement = glyphElem;
327                     break;
328                 }
329             }
330             // get the local font-face element
331
NodeList JavaDoc fontFaceElements
332                 = localFontElement.getElementsByTagNameNS
333         (SVG_NAMESPACE_URI, SVG_FONT_FACE_TAG);
334             if (fontFaceElements.getLength() > 0) {
335                 localFontFaceElement = (Element JavaDoc)fontFaceElements.item(0);
336             }
337         }
338
339         // if couldn't find the glyph or its font-face return null
340
if (localGlyphElement == null || localFontFaceElement == null) {
341             return null;
342         }
343
344         SVGFontFaceElementBridge fontFaceBridge
345             = (SVGFontFaceElementBridge)ctx.getBridge(localFontFaceElement);
346         SVGFontFace fontFace = fontFaceBridge.createFontFace
347             (ctx, localFontFaceElement);
348         SVGGlyphElementBridge glyphBridge
349             = (SVGGlyphElementBridge)ctx.getBridge(localGlyphElement);
350
351         aci.first();
352         TextPaintInfo tpi = (TextPaintInfo)aci.getAttribute(PAINT_INFO);
353
354         return glyphBridge.createGlyph(ctx, localGlyphElement, altGlyphElement,
355                                        -1, fontSize, fontFace, tpi);
356     }
357 }
358
Popular Tags