1 18 package org.apache.batik.bridge; 19 20 import java.awt.Paint ; 21 import java.awt.Stroke ; 22 import java.awt.font.TextAttribute ; 23 import java.text.AttributedCharacterIterator ; 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 ; 32 import org.w3c.dom.Node ; 33 import org.w3c.dom.NodeList ; 34 35 36 42 public class SVGAltGlyphElementBridge extends AbstractSVGBridge 43 implements ErrorConstants { 44 45 public static final AttributedCharacterIterator.Attribute PAINT_INFO 46 = GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO; 47 48 51 public SVGAltGlyphElementBridge() { 52 } 53 54 57 public String getLocalName() { 58 return SVG_ALT_GLYPH_TAG; 59 } 60 61 73 public Glyph[] createAltGlyphArray(BridgeContext ctx, 74 Element altGlyphElement, 75 float fontSize, 76 AttributedCharacterIterator aci) { 77 78 String uri = XLinkSupport.getXLinkHref(altGlyphElement); 80 81 Element 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 return null; 94 } 95 if (!SVG_NAMESPACE_URI.equals(refElement.getNamespaceURI())) 96 return null; 98 if (refElement.getLocalName().equals(SVG_GLYPH_TAG)) { 100 101 Glyph glyph = getGlyph(ctx, uri, altGlyphElement, fontSize, aci); 102 103 if (glyph == null) { 104 return null; 106 } 107 108 Glyph[] glyphArray = new Glyph[1]; 109 glyphArray[0] = glyph; 110 return glyphArray; 111 } 112 113 if (refElement.getLocalName().equals(SVG_ALT_GLYPH_DEF_TAG)) { 115 116 SVGOMDocument document 119 = (SVGOMDocument)altGlyphElement.getOwnerDocument(); 120 SVGOMDocument refDocument 121 = (SVGOMDocument)refElement.getOwnerDocument(); 122 boolean isLocal = (refDocument == document); 123 124 Element localRefElement = (isLocal) ? refElement 125 : (Element )document.importNode(refElement, true); 126 if (!isLocal) { 127 String base = XMLBaseSupport.getCascadedXMLBase(altGlyphElement); 130 Element 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 NodeList altGlyphDefChildren = localRefElement.getChildNodes(); 142 boolean containsGlyphRefNodes = false; 143 int numAltGlyphDefChildren = altGlyphDefChildren.getLength(); 144 for (int i = 0; i < numAltGlyphDefChildren; i++) { 145 Node altGlyphChild = altGlyphDefChildren.item(i); 146 if (altGlyphChild.getNodeType() == Node.ELEMENT_NODE) { 147 Element agc = (Element )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) { 157 NodeList 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 Element glyphRefElement = (Element )glyphRefNodes.item(i); 165 String glyphUri = XLinkSupport.getXLinkHref(glyphRefElement); 166 167 Glyph glyph 168 = getGlyph(ctx, glyphUri, glyphRefElement, fontSize, aci); 169 if (glyph == null) { 170 return null; 172 } 173 glyphArray[i] = glyph; 174 } 175 return glyphArray; 176 177 } else { 179 NodeList 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 190 for (int i = 0; i < numAltGlyphItemNodes && !foundMatchingGlyph ; i++) { 191 192 Element altGlyphItemElement = (Element )altGlyphItemNodes.item(i); 194 NodeList 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 foundMatchingGlyph = true; 204 205 for (int j = 0; j < numAltGlyphRefNodes; j++) { 206 Element glyphRefElement = (Element )altGlyphRefNodes.item(j); 208 String glyphUri = XLinkSupport.getXLinkHref(glyphRefElement); 209 210 Glyph glyph = getGlyph(ctx, glyphUri, glyphRefElement, fontSize, aci); 211 if (glyph != null) { 212 glyphArray[j] = glyph; 214 } 215 else{ 216 foundMatchingGlyph = false; 219 break; 220 } 221 } 222 } 223 if (!foundMatchingGlyph) { 224 return null; 228 } 229 230 return glyphArray; 231 } 232 } 233 } 234 235 236 241 return null; 243 } 244 245 246 256 private Glyph getGlyph(BridgeContext ctx, 257 String glyphUri, 258 Element altGlyphElement, 259 float fontSize, 260 AttributedCharacterIterator aci) { 261 262 Element refGlyphElement = null; 263 try { 264 refGlyphElement = ctx.getReferencedElement(altGlyphElement, 265 glyphUri); 266 } catch (BridgeException e) { 267 270 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 return null; 282 283 SVGOMDocument document 285 = (SVGOMDocument)altGlyphElement.getOwnerDocument(); 286 SVGOMDocument refDocument 287 = (SVGOMDocument)refGlyphElement.getOwnerDocument(); 288 boolean isLocal = (refDocument == document); 289 290 Element localGlyphElement = null; 292 Element localFontFaceElement = null; 293 Element localFontElement = null; 294 if (isLocal) { 295 localGlyphElement = refGlyphElement; 296 localFontElement = (Element )localGlyphElement.getParentNode(); 297 NodeList fontFaceElements 298 = localFontElement.getElementsByTagNameNS 299 (SVG_NAMESPACE_URI, SVG_FONT_FACE_TAG); 300 if (fontFaceElements.getLength() > 0) { 301 localFontFaceElement = (Element )fontFaceElements.item(0); 302 } 303 304 } else { 305 localFontElement = (Element )document.importNode 307 (refGlyphElement.getParentNode(), true); 308 String base = XMLBaseSupport.getCascadedXMLBase(altGlyphElement); 309 Element 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 )refGlyphElement.getParentNode(), 316 localFontElement, glyphUri); 317 318 String glyphId = refGlyphElement.getAttributeNS 320 (null, SVG_ID_ATTRIBUTE); 321 NodeList glyphElements = localFontElement.getElementsByTagNameNS 322 (SVG_NAMESPACE_URI, SVG_GLYPH_TAG); 323 for (int i = 0; i < glyphElements.getLength(); i++) { 324 Element glyphElem = (Element )glyphElements.item(i); 325 if (glyphElem.getAttributeNS(null, SVG_ID_ATTRIBUTE).equals(glyphId)) { 326 localGlyphElement = glyphElem; 327 break; 328 } 329 } 330 NodeList fontFaceElements 332 = localFontElement.getElementsByTagNameNS 333 (SVG_NAMESPACE_URI, SVG_FONT_FACE_TAG); 334 if (fontFaceElements.getLength() > 0) { 335 localFontFaceElement = (Element )fontFaceElements.item(0); 336 } 337 } 338 339 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 |