1 18 package org.apache.batik.bridge; 19 20 import java.awt.geom.AffineTransform ; 21 import java.awt.geom.Point2D ; 22 import java.awt.geom.Rectangle2D ; 23 import java.io.IOException ; 24 import java.util.Iterator ; 25 import java.util.LinkedList ; 26 import java.util.List ; 27 import java.util.StringTokenizer ; 28 29 import org.apache.batik.css.engine.CSSEngine; 30 import org.apache.batik.dom.svg.SVGOMDocument; 31 import org.apache.batik.dom.util.XLinkSupport; 32 import org.apache.batik.dom.util.XMLSupport; 33 import org.apache.batik.gvt.GraphicsNode; 34 import org.apache.batik.parser.AWTTransformProducer; 35 import org.apache.batik.parser.ParseException; 36 import org.apache.batik.util.ParsedURL; 37 import org.apache.batik.util.SVG12Constants; 38 import org.apache.batik.util.SVGConstants; 39 import org.w3c.dom.Element ; 40 import org.w3c.dom.Node ; 41 import org.w3c.dom.svg.SVGDocument; 42 import org.w3c.dom.svg.SVGElement; 43 import org.w3c.dom.svg.SVGLangSpace; 44 import org.w3c.dom.svg.SVGNumberList; 45 46 53 public abstract class SVGUtilities implements SVGConstants, ErrorConstants { 54 55 58 protected SVGUtilities() {} 59 60 64 67 public static Node getImportedChild(Node n) { 68 return CSSEngine.getImportedChild(n); 69 } 70 71 76 public static Element getParentElement(Element elt) { 77 return CSSEngine.getParentElement(elt); 78 } 79 80 84 public static float[] convertSVGNumberList(SVGNumberList l) { 85 int n = l.getNumberOfItems(); 86 if (n == 0) { 87 return null; 88 } 89 float fl[] = new float[n]; 90 for (int i=0; i < n; i++) { 91 fl[i] = l.getItem(i).getValue(); 92 } 93 return fl; 94 } 95 96 100 public static float convertSVGNumber(String s) { 101 return Float.parseFloat(s); 102 } 103 104 108 public static int convertSVGInteger(String s) { 109 return Integer.parseInt(s); 110 } 111 112 118 public static float convertRatio(String v) { 119 float d = 1; 120 if (v.endsWith("%")) { 121 v = v.substring(0, v.length() - 1); 122 d = 100; 123 } 124 float r = Float.parseFloat(v)/d; 125 if (r < 0) { 126 r = 0; 127 } else if (r > 1) { 128 r = 1; 129 } 130 return r; 131 } 132 133 136 public static String getDescription(SVGElement elt) { 137 String result = ""; 138 boolean preserve = false; 139 Node n = elt.getFirstChild(); 140 if (n != null && n.getNodeType() == Node.ELEMENT_NODE) { 141 String name = 142 (n.getPrefix() == null) ? n.getNodeName() : n.getLocalName(); 143 if (name.equals(SVG_DESC_TAG)) { 144 preserve = ((SVGLangSpace)n).getXMLspace().equals 145 (SVG_PRESERVE_VALUE); 146 for (n = n.getFirstChild(); 147 n != null; 148 n = n.getNextSibling()) { 149 if (n.getNodeType() == Node.TEXT_NODE) { 150 result += n.getNodeValue(); 151 } 152 } 153 } 154 } 155 return (preserve) 156 ? XMLSupport.preserveXMLSpace(result) 157 : XMLSupport.defaultXMLSpace(result); 158 } 159 160 166 public static boolean matchUserAgent(Element elt, UserAgent ua) { 167 test: if (elt.hasAttributeNS(null, SVG_SYSTEM_LANGUAGE_ATTRIBUTE)) { 168 String sl = elt.getAttributeNS(null, 170 SVG_SYSTEM_LANGUAGE_ATTRIBUTE); 171 if (sl.length() == 0) return false; 173 StringTokenizer st = new StringTokenizer (sl, ", "); 174 while (st.hasMoreTokens()) { 175 String s = st.nextToken(); 176 if (matchUserLanguage(s, ua.getLanguages())) { 177 break test; 178 } 179 } 180 return false; 181 } 182 if (elt.hasAttributeNS(null, SVG_REQUIRED_FEATURES_ATTRIBUTE)) { 183 String rf = elt.getAttributeNS(null, 185 SVG_REQUIRED_FEATURES_ATTRIBUTE); 186 if (rf.length() == 0) return false; 188 StringTokenizer st = new StringTokenizer (rf, " "); 189 while (st.hasMoreTokens()) { 190 String s = st.nextToken(); 191 if (!ua.hasFeature(s)) { 192 return false; 193 } 194 } 195 } 196 if (elt.hasAttributeNS(null, SVG_REQUIRED_EXTENSIONS_ATTRIBUTE)) { 197 String re = elt.getAttributeNS(null, 199 SVG_REQUIRED_EXTENSIONS_ATTRIBUTE); 200 if (re.length() == 0) return false; 202 StringTokenizer st = new StringTokenizer (re, " "); 203 while (st.hasMoreTokens()) { 204 String s = st.nextToken(); 205 if (!ua.supportExtension(s)) { 206 return false; 207 } 208 } 209 } 210 return true; 211 } 212 213 220 protected static boolean matchUserLanguage(String s, 221 String userLanguages) { 222 StringTokenizer st = new StringTokenizer (userLanguages, ", "); 223 while (st.hasMoreTokens()) { 224 String t = st.nextToken(); 225 if (s.startsWith(t)) { 226 if (s.length() > t.length()) { 227 return (s.charAt(t.length()) == '-'); 228 } 229 return true; 230 } 231 } 232 return false; 233 } 234 235 246 public static String getChainableAttributeNS(Element element, 247 String namespaceURI, 248 String attrName, 249 BridgeContext ctx) { 250 251 DocumentLoader loader = ctx.getDocumentLoader(); 252 Element e = element; 253 List refs = new LinkedList (); 254 for (;;) { 255 String v = e.getAttributeNS(namespaceURI, attrName); 256 if (v.length() > 0) { return v; 258 } 259 String uriStr = XLinkSupport.getXLinkHref(e); 260 if (uriStr.length() == 0) { return ""; 262 } 263 SVGDocument svgDoc = (SVGDocument)e.getOwnerDocument(); 264 String baseURI = ((SVGOMDocument)svgDoc).getURL(); 265 266 ParsedURL purl = new ParsedURL(baseURI, uriStr); 267 if (!purl.complete()) 268 throw new BridgeException(e, ERR_URI_MALFORMED, 269 new Object [] {uriStr}); 270 271 Iterator iter = refs.iterator(); 272 while (iter.hasNext()) { 273 if (purl.equals(iter.next())) 274 throw new BridgeException 275 (e, ERR_XLINK_HREF_CIRCULAR_DEPENDENCIES, 276 new Object [] {uriStr}); 277 } 278 279 try { 280 URIResolver resolver = new URIResolver(svgDoc, loader); 281 e = resolver.getElement(purl.toString(), e); 282 refs.add(purl); 283 } catch(IOException ex) { 284 throw new BridgeException(e, ERR_URI_IO, 285 new Object [] {uriStr}); 286 } catch(SecurityException ex) { 287 throw new BridgeException(e, ERR_URI_UNSECURE, 288 new Object [] {uriStr}); 289 } 290 } 291 } 292 293 297 308 public static Point2D convertPoint(String xStr, 309 String xAttr, 310 String yStr, 311 String yAttr, 312 short unitsType, 313 UnitProcessor.Context uctx) { 314 float x, y; 315 switch (unitsType) { 316 case OBJECT_BOUNDING_BOX: 317 x = UnitProcessor.svgHorizontalCoordinateToObjectBoundingBox 318 (xStr, xAttr, uctx); 319 y = UnitProcessor.svgVerticalCoordinateToObjectBoundingBox 320 (yStr, yAttr, uctx); 321 break; 322 case USER_SPACE_ON_USE: 323 x = UnitProcessor.svgHorizontalCoordinateToUserSpace 324 (xStr, xAttr, uctx); 325 y = UnitProcessor.svgVerticalCoordinateToUserSpace 326 (yStr, yAttr, uctx); 327 break; 328 default: 329 throw new Error (); } 331 return new Point2D.Float (x, y); 332 } 333 334 343 public static float convertLength(String length, 344 String attr, 345 short unitsType, 346 UnitProcessor.Context uctx) { 347 switch (unitsType) { 348 case OBJECT_BOUNDING_BOX: 349 return UnitProcessor.svgOtherLengthToObjectBoundingBox 350 (length, attr, uctx); 351 case USER_SPACE_ON_USE: 352 return UnitProcessor.svgOtherLengthToUserSpace(length, attr, uctx); 353 default: 354 throw new Error (); } 356 } 357 358 362 371 public static Rectangle2D convertMaskRegion(Element maskElement, 372 Element maskedElement, 373 GraphicsNode maskedNode, 374 BridgeContext ctx) { 375 376 String xStr = maskElement.getAttributeNS(null, SVG_X_ATTRIBUTE); 378 if (xStr.length() == 0) { 379 xStr = SVG_MASK_X_DEFAULT_VALUE; 380 } 381 String yStr = maskElement.getAttributeNS(null, SVG_Y_ATTRIBUTE); 383 if (yStr.length() == 0) { 384 yStr = SVG_MASK_Y_DEFAULT_VALUE; 385 } 386 String wStr = maskElement.getAttributeNS(null, SVG_WIDTH_ATTRIBUTE); 388 if (wStr.length() == 0) { 389 wStr = SVG_MASK_WIDTH_DEFAULT_VALUE; 390 } 391 String hStr = maskElement.getAttributeNS(null, SVG_HEIGHT_ATTRIBUTE); 393 if (hStr.length() == 0) { 394 hStr = SVG_MASK_HEIGHT_DEFAULT_VALUE; 395 } 396 short unitsType; 398 String units = 399 maskElement.getAttributeNS(null, SVG_MASK_UNITS_ATTRIBUTE); 400 if (units.length() == 0) { 401 unitsType = OBJECT_BOUNDING_BOX; 402 } else { 403 unitsType = parseCoordinateSystem 404 (maskElement, SVG_MASK_UNITS_ATTRIBUTE, units); 405 } 406 407 UnitProcessor.Context uctx 409 = UnitProcessor.createContext(ctx, maskedElement); 410 411 return convertRegion(xStr, 412 yStr, 413 wStr, 414 hStr, 415 unitsType, 416 maskedNode, 417 uctx); 418 } 419 420 424 433 public static Rectangle2D convertPatternRegion(Element patternElement, 434 Element paintedElement, 435 GraphicsNode paintedNode, 436 BridgeContext ctx) { 437 438 String xStr = getChainableAttributeNS 440 (patternElement, null, SVG_X_ATTRIBUTE, ctx); 441 if (xStr.length() == 0) { 442 xStr = SVG_PATTERN_X_DEFAULT_VALUE; 443 } 444 String yStr = getChainableAttributeNS 446 (patternElement, null, SVG_Y_ATTRIBUTE, ctx); 447 if (yStr.length() == 0) { 448 yStr = SVG_PATTERN_Y_DEFAULT_VALUE; 449 } 450 String wStr = getChainableAttributeNS 452 (patternElement, null, SVG_WIDTH_ATTRIBUTE, ctx); 453 if (wStr.length() == 0) { 454 throw new BridgeException(patternElement, ERR_ATTRIBUTE_MISSING, 455 new Object [] {SVG_WIDTH_ATTRIBUTE}); 456 } 457 String hStr = getChainableAttributeNS 459 (patternElement, null, SVG_HEIGHT_ATTRIBUTE, ctx); 460 if (hStr.length() == 0) { 461 throw new BridgeException(patternElement, ERR_ATTRIBUTE_MISSING, 462 new Object [] {SVG_HEIGHT_ATTRIBUTE}); 463 } 464 short unitsType; 466 String units = getChainableAttributeNS 467 (patternElement, null, SVG_PATTERN_UNITS_ATTRIBUTE, ctx); 468 if (units.length() == 0) { 469 unitsType = OBJECT_BOUNDING_BOX; 470 } else { 471 unitsType = parseCoordinateSystem 472 (patternElement, SVG_PATTERN_UNITS_ATTRIBUTE, units); 473 } 474 475 UnitProcessor.Context uctx 477 = UnitProcessor.createContext(ctx, paintedElement); 478 479 return convertRegion(xStr, 480 yStr, 481 wStr, 482 hStr, 483 unitsType, 484 paintedNode, 485 uctx); 486 } 487 488 492 499 public static 500 float [] convertFilterRes(Element filterElement, BridgeContext ctx) { 501 502 float [] filterRes = new float[2]; 503 String s = getChainableAttributeNS 504 (filterElement, null, SVG_FILTER_RES_ATTRIBUTE, ctx); 505 Float [] vals = convertSVGNumberOptionalNumber 506 (filterElement, SVG_FILTER_RES_ATTRIBUTE, s); 507 508 if (filterRes[0] < 0 || filterRes[1] < 0) { 509 throw new BridgeException 510 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 511 new Object [] {SVG_FILTER_RES_ATTRIBUTE, s}); 512 } 513 514 if (vals[0] == null) 515 filterRes[0] = -1; 516 else { 517 filterRes[0] = vals[0].floatValue(); 518 if (filterRes[0] < 0) 519 throw new BridgeException 520 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 521 new Object [] {SVG_FILTER_RES_ATTRIBUTE, s}); 522 } 523 524 if (vals[1] == null) 525 filterRes[1] = filterRes[0]; 526 else { 527 filterRes[1] = vals[1].floatValue(); 528 if (filterRes[1] < 0) 529 throw new BridgeException 530 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 531 new Object [] {SVG_FILTER_RES_ATTRIBUTE, s}); 532 } 533 return filterRes; 534 } 535 536 541 public static Float [] 542 convertSVGNumberOptionalNumber(Element elem, 543 String attrName, 544 String attrValue) { 545 546 Float [] ret = new Float [2]; 547 if (attrValue.length() == 0) 548 return ret; 549 550 try { 551 StringTokenizer tokens = new StringTokenizer (attrValue, " "); 552 ret[0] = new Float (Float.parseFloat(tokens.nextToken())); 553 if (tokens.hasMoreTokens()) { 554 ret[1] = new Float (Float.parseFloat(tokens.nextToken())); 555 } 556 557 if (tokens.hasMoreTokens()) { 558 throw new BridgeException 559 (elem, ERR_ATTRIBUTE_VALUE_MALFORMED, 560 new Object [] {attrName, attrValue}); 561 } 562 } catch (NumberFormatException ex) { 563 throw new BridgeException 564 (elem, ERR_ATTRIBUTE_VALUE_MALFORMED, 565 new Object [] {attrName, attrValue, ex}); 566 } 567 return ret; 568 } 569 570 571 580 public static 581 Rectangle2D convertFilterChainRegion(Element filterElement, 582 Element filteredElement, 583 GraphicsNode filteredNode, 584 BridgeContext ctx) { 585 586 String xStr = getChainableAttributeNS 588 (filterElement, null, SVG_X_ATTRIBUTE, ctx); 589 if (xStr.length() == 0) { 590 xStr = SVG_FILTER_X_DEFAULT_VALUE; 591 } 592 String yStr = getChainableAttributeNS 594 (filterElement, null, SVG_Y_ATTRIBUTE, ctx); 595 if (yStr.length() == 0) { 596 yStr = SVG_FILTER_Y_DEFAULT_VALUE; 597 } 598 String wStr = getChainableAttributeNS 600 (filterElement, null, SVG_WIDTH_ATTRIBUTE, ctx); 601 if (wStr.length() == 0) { 602 wStr = SVG_FILTER_WIDTH_DEFAULT_VALUE; 603 } 604 String hStr = getChainableAttributeNS 606 (filterElement, null, SVG_HEIGHT_ATTRIBUTE, ctx); 607 if (hStr.length() == 0) { 608 hStr = SVG_FILTER_HEIGHT_DEFAULT_VALUE; 609 } 610 short unitsType; 612 String units = getChainableAttributeNS 613 (filterElement, null, SVG_FILTER_UNITS_ATTRIBUTE, ctx); 614 if (units.length() == 0) { 615 unitsType = OBJECT_BOUNDING_BOX; 616 } else { 617 unitsType = parseCoordinateSystem 618 (filterElement, SVG_FILTER_UNITS_ATTRIBUTE, units); 619 } 620 621 UnitProcessor.Context uctx 624 = UnitProcessor.createContext(ctx, filteredElement); 625 626 Rectangle2D region = convertRegion(xStr, 627 yStr, 628 wStr, 629 hStr, 630 unitsType, 631 filteredNode, 632 uctx); 633 units = getChainableAttributeNS 637 (filterElement, null, 638 SVG12Constants.SVG_FILTER_MARGINS_UNITS_ATTRIBUTE, ctx); 639 if (units.length() == 0) { 640 unitsType = USER_SPACE_ON_USE; 642 } else { 643 unitsType = parseCoordinateSystem 644 (filterElement, 645 SVG12Constants.SVG_FILTER_MARGINS_UNITS_ATTRIBUTE, units); 646 } 647 648 String dxStr = filterElement.getAttributeNS(null, 650 SVG12Constants.SVG_MX_ATRIBUTE); 651 if (dxStr.length() == 0) { 652 dxStr = SVG12Constants.SVG_FILTER_MX_DEFAULT_VALUE; 653 } 654 String dyStr = filterElement.getAttributeNS(null, SVG12Constants.SVG_MY_ATRIBUTE); 656 if (dyStr.length() == 0) { 657 dyStr = SVG12Constants.SVG_FILTER_MY_DEFAULT_VALUE; 658 } 659 String dwStr = filterElement.getAttributeNS(null, SVG12Constants.SVG_MW_ATRIBUTE); 661 if (dwStr.length() == 0) { 662 dwStr = SVG12Constants.SVG_FILTER_MW_DEFAULT_VALUE; 663 } 664 String dhStr = filterElement.getAttributeNS(null, SVG12Constants.SVG_MH_ATRIBUTE); 666 if (dhStr.length() == 0) { 667 dhStr = SVG12Constants.SVG_FILTER_MH_DEFAULT_VALUE; 668 } 669 670 return extendRegion(dxStr, 671 dyStr, 672 dwStr, 673 dhStr, 674 unitsType, 675 filteredNode, 676 region, 677 uctx); 678 } 679 680 693 protected static Rectangle2D extendRegion(String dxStr, 694 String dyStr, 695 String dwStr, 696 String dhStr, 697 short unitsType, 698 GraphicsNode filteredNode, 699 Rectangle2D region, 700 UnitProcessor.Context uctx) { 701 702 float dx,dy,dw,dh; 703 switch (unitsType) { 704 case USER_SPACE_ON_USE: 705 dx = UnitProcessor.svgHorizontalCoordinateToUserSpace 706 (dxStr, SVG12Constants.SVG_MX_ATRIBUTE, uctx); 707 dy = UnitProcessor.svgVerticalCoordinateToUserSpace 708 (dyStr, SVG12Constants.SVG_MY_ATRIBUTE, uctx); 709 dw = UnitProcessor.svgHorizontalCoordinateToUserSpace 710 (dwStr, SVG12Constants.SVG_MW_ATRIBUTE, uctx); 711 dh = UnitProcessor.svgVerticalCoordinateToUserSpace 712 (dhStr, SVG12Constants.SVG_MH_ATRIBUTE, uctx); 713 break; 714 case OBJECT_BOUNDING_BOX: 715 Rectangle2D bounds = filteredNode.getGeometryBounds(); 716 if (bounds == null) { 717 dx = dy = dw = dh = 0; 718 } else { 719 dx = UnitProcessor.svgHorizontalCoordinateToObjectBoundingBox 720 (dxStr, SVG12Constants.SVG_MX_ATRIBUTE, uctx); 721 dx *= bounds.getWidth(); 722 723 dy = UnitProcessor.svgVerticalCoordinateToObjectBoundingBox 724 (dyStr, SVG12Constants.SVG_MY_ATRIBUTE, uctx); 725 dy *= bounds.getHeight(); 726 727 dw = UnitProcessor.svgHorizontalCoordinateToObjectBoundingBox 728 (dwStr, SVG12Constants.SVG_MW_ATRIBUTE, uctx); 729 dw *= bounds.getWidth(); 730 731 dh = UnitProcessor.svgVerticalCoordinateToObjectBoundingBox 732 (dhStr, SVG12Constants.SVG_MH_ATRIBUTE, uctx); 733 dh *= bounds.getHeight(); 734 } 735 break; 736 default: 737 throw new Error (); } 739 740 region.setRect(region.getX() + dx, 741 region.getY() + dy, 742 region.getWidth() + dw, 743 region.getHeight() + dh); 744 745 return region; 746 } 747 748 760 public static Rectangle2D 761 convertFilterPrimitiveRegion(Element filterPrimitiveElement, 762 Element filteredElement, 763 GraphicsNode filteredNode, 764 Rectangle2D defaultRegion, 765 Rectangle2D filterRegion, 766 BridgeContext ctx) { 767 768 Node parentNode = filterPrimitiveElement.getParentNode(); 770 String units = ""; 771 if ((parentNode != null) && 772 (parentNode.getNodeType() == Node.ELEMENT_NODE)) { 773 Element parent = (Element )parentNode; 774 units = getChainableAttributeNS(parent, 775 null, 776 SVG_PRIMITIVE_UNITS_ATTRIBUTE, 777 ctx); 778 } 779 short unitsType; 780 if (units.length() == 0) { 781 unitsType = USER_SPACE_ON_USE; 782 } else { 783 unitsType = parseCoordinateSystem 784 (filterPrimitiveElement, SVG_FILTER_UNITS_ATTRIBUTE, units); 785 } 786 787 String xStr = 789 filterPrimitiveElement.getAttributeNS(null, SVG_X_ATTRIBUTE); 790 791 String yStr = 793 filterPrimitiveElement.getAttributeNS(null, SVG_Y_ATTRIBUTE); 794 795 String wStr = 797 filterPrimitiveElement.getAttributeNS(null, SVG_WIDTH_ATTRIBUTE); 798 799 String hStr = 801 filterPrimitiveElement.getAttributeNS(null, SVG_HEIGHT_ATTRIBUTE); 802 803 double x = defaultRegion.getX(); 804 double y = defaultRegion.getY(); 805 double w = defaultRegion.getWidth(); 806 double h = defaultRegion.getHeight(); 807 808 UnitProcessor.Context uctx 810 = UnitProcessor.createContext(ctx, filteredElement); 811 812 switch (unitsType) { 813 case OBJECT_BOUNDING_BOX: 814 Rectangle2D bounds = filteredNode.getGeometryBounds(); 815 if (bounds != null) { 816 if (xStr.length() != 0) { 817 x = UnitProcessor.svgHorizontalCoordinateToObjectBoundingBox 818 (xStr, SVG_X_ATTRIBUTE, uctx); 819 x = bounds.getX() + x*bounds.getWidth(); 820 } 821 if (yStr.length() != 0) { 822 y = UnitProcessor.svgVerticalCoordinateToObjectBoundingBox 823 (yStr, SVG_Y_ATTRIBUTE, uctx); 824 y = bounds.getY() + y*bounds.getHeight(); 825 } 826 if (wStr.length() != 0) { 827 w = UnitProcessor.svgHorizontalLengthToObjectBoundingBox 828 (wStr, SVG_WIDTH_ATTRIBUTE, uctx); 829 w *= bounds.getWidth(); 830 } 831 if (hStr.length() != 0) { 832 h = UnitProcessor.svgVerticalLengthToObjectBoundingBox 833 (hStr, SVG_HEIGHT_ATTRIBUTE, uctx); 834 h *= bounds.getHeight(); 835 } 836 } 837 break; 838 case USER_SPACE_ON_USE: 839 if (xStr.length() != 0) { 840 x = UnitProcessor.svgHorizontalCoordinateToUserSpace 841 (xStr, SVG_X_ATTRIBUTE, uctx); 842 } 843 if (yStr.length() != 0) { 844 y = UnitProcessor.svgVerticalCoordinateToUserSpace 845 (yStr, SVG_Y_ATTRIBUTE, uctx); 846 } 847 if (wStr.length() != 0) { 848 w = UnitProcessor.svgHorizontalLengthToUserSpace 849 (wStr, SVG_WIDTH_ATTRIBUTE, uctx); 850 } 851 if (hStr.length() != 0) { 852 h = UnitProcessor.svgVerticalLengthToUserSpace 853 (hStr, SVG_HEIGHT_ATTRIBUTE, uctx); 854 } 855 break; 856 default: 857 throw new Error (); } 859 860 Rectangle2D region = new Rectangle2D.Double (x, y, w, h); 861 862 866 units = ""; 867 if ((parentNode != null) && 868 (parentNode.getNodeType() == Node.ELEMENT_NODE)) { 869 Element parent = (Element )parentNode; 870 units = getChainableAttributeNS 871 (parent, null, 872 SVG12Constants.SVG_FILTER_PRIMITIVE_MARGINS_UNITS_ATTRIBUTE, 873 ctx); 874 } 875 876 if (units.length() == 0) { 877 unitsType = USER_SPACE_ON_USE; 878 } else { 879 unitsType = parseCoordinateSystem 880 (filterPrimitiveElement, 881 SVG12Constants.SVG_FILTER_PRIMITIVE_MARGINS_UNITS_ATTRIBUTE, units); 882 } 883 884 String dxStr = filterPrimitiveElement.getAttributeNS 886 (null, SVG12Constants.SVG_MX_ATRIBUTE); 887 if (dxStr.length() == 0) { 888 dxStr = SVG12Constants.SVG_FILTER_MX_DEFAULT_VALUE; 889 } 890 891 String dyStr = filterPrimitiveElement.getAttributeNS 893 (null, SVG12Constants.SVG_MY_ATRIBUTE); 894 if (dyStr.length() == 0) { 895 dyStr = SVG12Constants.SVG_FILTER_MY_DEFAULT_VALUE; 896 } 897 898 String dwStr = filterPrimitiveElement.getAttributeNS 900 (null, SVG12Constants.SVG_MW_ATRIBUTE); 901 if (dwStr.length() == 0) { 902 dwStr = SVG12Constants.SVG_FILTER_MW_DEFAULT_VALUE; 903 } 904 905 String dhStr = filterPrimitiveElement.getAttributeNS 907 (null, SVG12Constants.SVG_MH_ATRIBUTE); 908 if (dhStr.length() == 0) { 909 dhStr = SVG12Constants.SVG_FILTER_MH_DEFAULT_VALUE; 910 } 911 912 region = extendRegion(dxStr, 913 dyStr, 914 dwStr, 915 dhStr, 916 unitsType, 917 filteredNode, 918 region, 919 uctx); 920 921 Rectangle2D.intersect(region, filterRegion, region); 922 923 return region; 924 } 925 926 930 931 932 public static final short USER_SPACE_ON_USE = 1; 933 934 935 public static final short OBJECT_BOUNDING_BOX = 2; 936 937 938 public static final short STROKE_WIDTH = 3; 939 940 948 public static short parseCoordinateSystem(Element e, 949 String attr, 950 String coordinateSystem) { 951 if (SVG_USER_SPACE_ON_USE_VALUE.equals(coordinateSystem)) { 952 return USER_SPACE_ON_USE; 953 } else if (SVG_OBJECT_BOUNDING_BOX_VALUE.equals(coordinateSystem)) { 954 return OBJECT_BOUNDING_BOX; 955 } else { 956 throw new BridgeException(e, ERR_ATTRIBUTE_VALUE_MALFORMED, 957 new Object [] {attr, coordinateSystem}); 958 } 959 } 960 961 970 public static short parseMarkerCoordinateSystem(Element e, 971 String attr, 972 String coordinateSystem) { 973 if (SVG_USER_SPACE_ON_USE_VALUE.equals(coordinateSystem)) { 974 return USER_SPACE_ON_USE; 975 } else if (SVG_STROKE_WIDTH_VALUE.equals(coordinateSystem)) { 976 return STROKE_WIDTH; 977 } else { 978 throw new BridgeException(e, ERR_ATTRIBUTE_VALUE_MALFORMED, 979 new Object [] {attr, coordinateSystem}); 980 } 981 } 982 983 994 protected static Rectangle2D convertRegion(String xStr, 995 String yStr, 996 String wStr, 997 String hStr, 998 short unitsType, 999 GraphicsNode targetNode, 1000 UnitProcessor.Context uctx) { 1001 1002 double x, y, w, h; 1004 switch (unitsType) { 1005 case OBJECT_BOUNDING_BOX: 1006 x = UnitProcessor.svgHorizontalCoordinateToObjectBoundingBox 1007 (xStr, SVG_X_ATTRIBUTE, uctx); 1008 y = UnitProcessor.svgVerticalCoordinateToObjectBoundingBox 1009 (yStr, SVG_Y_ATTRIBUTE, uctx); 1010 w = UnitProcessor.svgHorizontalLengthToObjectBoundingBox 1011 (wStr, SVG_WIDTH_ATTRIBUTE, uctx); 1012 h = UnitProcessor.svgVerticalLengthToObjectBoundingBox 1013 (hStr, SVG_HEIGHT_ATTRIBUTE, uctx); 1014 1015 Rectangle2D bounds = targetNode.getGeometryBounds(); 1016 if (bounds != null ) { 1017 x = bounds.getX() + x*bounds.getWidth(); 1018 y = bounds.getY() + y*bounds.getHeight(); 1019 w *= bounds.getWidth(); 1020 h *= bounds.getHeight(); 1021 } else { 1022 x = y = w = h = 0; 1023 } 1024 break; 1025 case USER_SPACE_ON_USE: 1026 x = UnitProcessor.svgHorizontalCoordinateToUserSpace 1027 (xStr, SVG_X_ATTRIBUTE, uctx); 1028 y = UnitProcessor.svgVerticalCoordinateToUserSpace 1029 (yStr, SVG_Y_ATTRIBUTE, uctx); 1030 w = UnitProcessor.svgHorizontalLengthToUserSpace 1031 (wStr, SVG_WIDTH_ATTRIBUTE, uctx); 1032 h = UnitProcessor.svgVerticalLengthToUserSpace 1033 (hStr, SVG_HEIGHT_ATTRIBUTE, uctx); 1034 break; 1035 default: 1036 throw new Error (); } 1038 return new Rectangle2D.Double (x, y, w, h); 1039 } 1040 1041 1045 1053 public static AffineTransform convertTransform(Element e, 1054 String attr, 1055 String transform) { 1056 try { 1057 return AWTTransformProducer.createAffineTransform(transform); 1058 } catch (ParseException ex) { 1059 throw new BridgeException(e, ERR_ATTRIBUTE_VALUE_MALFORMED, 1060 new Object [] {attr, transform, ex}); 1061 } 1062 } 1063 1064 1072 public static AffineTransform toObjectBBox(AffineTransform Tx, 1073 GraphicsNode node) { 1074 1075 AffineTransform Mx = new AffineTransform (); 1076 Rectangle2D bounds = node.getGeometryBounds(); 1077 if (bounds != null) { 1078 Mx.translate(bounds.getX(), bounds.getY()); 1079 Mx.scale(bounds.getWidth(), bounds.getHeight()); 1080 } 1081 Mx.concatenate(Tx); 1082 return Mx; 1083 } 1084 1085 1093 public static Rectangle2D toObjectBBox(Rectangle2D r, 1094 GraphicsNode node) { 1095 1096 Rectangle2D bounds = node.getGeometryBounds(); 1097 if(bounds != null){ 1098 return new Rectangle2D.Double 1099 (bounds.getX() + r.getX()*bounds.getWidth(), 1100 bounds.getY() + r.getY()*bounds.getHeight(), 1101 r.getWidth() * bounds.getWidth(), 1102 r.getHeight() * bounds.getHeight()); 1103 } else { 1104 return new Rectangle2D.Double (); 1105 } 1106 } 1107} 1108 | Popular Tags |