1 18 package org.apache.batik.transcoder; 19 20 import java.awt.Dimension ; 21 import java.awt.geom.AffineTransform ; 22 import java.awt.geom.Dimension2D ; 23 import java.awt.geom.Rectangle2D ; 24 import java.net.URL ; 25 import java.net.MalformedURLException ; 26 import java.util.StringTokenizer ; 27 import java.util.LinkedList ; 28 import java.util.List ; 29 30 import org.apache.batik.bridge.BaseScriptingEnvironment; 31 import org.apache.batik.bridge.BridgeContext; 32 import org.apache.batik.bridge.BridgeException; 33 import org.apache.batik.bridge.DefaultScriptSecurity; 34 import org.apache.batik.bridge.GVTBuilder; 35 import org.apache.batik.bridge.NoLoadScriptSecurity; 36 import org.apache.batik.bridge.RelaxedScriptSecurity; 37 import org.apache.batik.bridge.ScriptSecurity; 38 import org.apache.batik.bridge.UserAgent; 39 import org.apache.batik.bridge.UserAgentAdapter; 40 import org.apache.batik.bridge.ViewBox; 41 import org.apache.batik.dom.svg.SAXSVGDocumentFactory; 42 import org.apache.batik.dom.svg.SVGDOMImplementation; 43 import org.apache.batik.dom.svg.SVGOMDocument; 44 import org.apache.batik.dom.util.DocumentFactory; 45 import org.apache.batik.dom.util.DOMUtilities; 46 import org.apache.batik.gvt.CanvasGraphicsNode; 47 import org.apache.batik.gvt.CompositeGraphicsNode; 48 import org.apache.batik.gvt.GraphicsNode; 49 import org.apache.batik.transcoder.keys.BooleanKey; 50 import org.apache.batik.transcoder.keys.FloatKey; 51 import org.apache.batik.transcoder.keys.LengthKey; 52 import org.apache.batik.transcoder.keys.Rectangle2DKey; 53 import org.apache.batik.transcoder.keys.StringKey; 54 import org.apache.batik.util.ParsedURL; 55 import org.apache.batik.util.SVGConstants; 56 import org.w3c.dom.DOMImplementation ; 57 import org.w3c.dom.Document ; 58 import org.w3c.dom.svg.SVGSVGElement; 59 60 61 74 public abstract class SVGAbstractTranscoder extends XMLAbstractTranscoder { 75 78 public static final String DEFAULT_DEFAULT_FONT_FAMILY 79 = "Arial, Helvetica, sans-serif"; 80 81 84 protected Rectangle2D curAOI; 85 86 89 protected AffineTransform curTxf; 90 91 95 protected GraphicsNode root; 96 97 100 protected BridgeContext ctx; 101 102 105 protected GVTBuilder builder; 106 107 110 protected float width=400, height=400; 111 112 113 protected UserAgent userAgent; 114 115 protected SVGAbstractTranscoder() { 116 userAgent = createUserAgent(); 117 118 hints.put(KEY_DOCUMENT_ELEMENT_NAMESPACE_URI, 119 SVGConstants.SVG_NAMESPACE_URI); 120 hints.put(KEY_DOCUMENT_ELEMENT, 121 SVGConstants.SVG_SVG_TAG); 122 hints.put(KEY_DOM_IMPLEMENTATION, 123 SVGDOMImplementation.getDOMImplementation()); 124 hints.put(KEY_MEDIA, 125 "screen"); 126 hints.put(KEY_DEFAULT_FONT_FAMILY, 127 DEFAULT_DEFAULT_FONT_FAMILY); 128 hints.put(KEY_EXECUTE_ONLOAD, 129 Boolean.FALSE); 130 hints.put(KEY_ALLOWED_SCRIPT_TYPES, 131 DEFAULT_ALLOWED_SCRIPT_TYPES); 132 } 133 134 135 protected UserAgent createUserAgent() { 136 return new SVGAbstractTranscoderUserAgent(); 137 } 138 139 147 protected DocumentFactory createDocumentFactory(DOMImplementation domImpl, 148 String parserClassname) { 149 return new SAXSVGDocumentFactory(parserClassname); 150 } 151 152 public void transcode(TranscoderInput input, TranscoderOutput output) 153 throws TranscoderException { 154 155 super.transcode(input, output); 156 157 if (ctx != null) 158 ctx.dispose(); 159 } 160 168 protected void transcode(Document document, 169 String uri, 170 TranscoderOutput output) 171 throws TranscoderException { 172 173 if ((document != null) && 174 !(document.getImplementation() instanceof SVGDOMImplementation)) { 175 DOMImplementation impl; 176 impl = (DOMImplementation)hints.get(KEY_DOM_IMPLEMENTATION); 177 document = DOMUtilities.deepCloneDocument(document, impl); 179 if (uri != null) { 180 try { 181 URL url = new URL (uri); 182 ((SVGOMDocument)document).setURLObject(url); 183 } catch (MalformedURLException mue) { 184 } 185 } 186 } 187 188 ctx = createBridgeContext(); 189 SVGOMDocument svgDoc = (SVGOMDocument)document; 190 SVGSVGElement root = svgDoc.getRootElement(); 191 192 builder = new GVTBuilder(); 194 boolean isDynamic = 196 (hints.containsKey(KEY_EXECUTE_ONLOAD) && 197 ((Boolean )hints.get(KEY_EXECUTE_ONLOAD)).booleanValue() && 198 ctx.isDynamicDocument(svgDoc)); 199 200 GraphicsNode gvtRoot; 201 try { 202 if (isDynamic) 203 ctx.setDynamicState(BridgeContext.DYNAMIC); 204 205 gvtRoot = builder.build(ctx, svgDoc); 206 207 if (ctx.isDynamic()) { 209 BaseScriptingEnvironment se; 210 se = new BaseScriptingEnvironment(ctx); 211 se.loadScripts(); 212 se.dispatchSVGLoadEvent(); 213 } 214 } catch (BridgeException ex) { 215 throw new TranscoderException(ex); 216 } 217 218 float docWidth = (float)ctx.getDocumentSize().getWidth(); 220 float docHeight = (float)ctx.getDocumentSize().getHeight(); 221 222 setImageSize(docWidth, docHeight); 223 224 AffineTransform Px; 226 227 if (hints.containsKey(KEY_AOI)) { 229 Rectangle2D aoi = (Rectangle2D )hints.get(KEY_AOI); 230 Px = new AffineTransform (); 232 double sx = width / aoi.getWidth(); 233 double sy = height / aoi.getHeight(); 234 double scale = Math.min(sx,sy); 235 Px.scale(scale, scale); 236 double tx = -aoi.getX() + (width/scale - aoi.getWidth())/2; 237 double ty = -aoi.getY() + (height/scale -aoi.getHeight())/2;; 238 Px.translate(tx, ty); 239 curAOI = aoi; 242 } else { 243 String ref = new ParsedURL(uri).getRef(); 244 245 try { 246 Px = ViewBox.getViewTransform(ref, root, width, height); 247 } catch (BridgeException ex) { 248 throw new TranscoderException(ex); 249 } 250 251 if (Px.isIdentity() && 252 (width != docWidth || height != docHeight)) { 253 float xscale, yscale; 256 xscale = width/docWidth; 257 yscale = height/docHeight; 258 float scale = Math.min(xscale,yscale); 259 Px = AffineTransform.getScaleInstance(scale, scale); 260 } 261 262 curAOI = new Rectangle2D.Float (0, 0, width, height); 263 } 264 265 CanvasGraphicsNode cgn = getCanvasGraphicsNode(gvtRoot); 266 if (cgn != null) { 267 cgn.setViewingTransform(Px); 268 curTxf = new AffineTransform (); 269 } else { 270 curTxf = Px; 271 } 272 273 this.root = gvtRoot; 274 } 275 276 protected CanvasGraphicsNode getCanvasGraphicsNode(GraphicsNode gn) { 277 if (!(gn instanceof CompositeGraphicsNode)) 278 return null; 279 CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn; 280 List children = cgn.getChildren(); 281 if (children.size() == 0) 282 return null; 283 gn = (GraphicsNode)children.get(0); 284 if (!(gn instanceof CanvasGraphicsNode)) 285 return null; 286 return (CanvasGraphicsNode)gn; 287 } 288 289 294 protected BridgeContext createBridgeContext() { 295 return new BridgeContext(userAgent); 296 } 297 298 305 protected void setImageSize(float docWidth, float docHeight) { 306 307 float imgWidth = -1; 309 if (hints.containsKey(KEY_WIDTH)) { 310 imgWidth = ((Float )hints.get(KEY_WIDTH)).floatValue(); 311 } 312 float imgHeight = -1; 313 if (hints.containsKey(KEY_HEIGHT)) { 314 imgHeight = ((Float )hints.get(KEY_HEIGHT)).floatValue(); 315 } 316 317 if (imgWidth > 0 && imgHeight > 0) { 318 width = imgWidth; 319 height = imgHeight; 320 } else if (imgHeight > 0) { 321 width = (docWidth * imgHeight) / docHeight; 322 height = imgHeight; 323 } else if (imgWidth > 0) { 324 width = imgWidth; 325 height = (docHeight * imgWidth) / docWidth; 326 } else { 327 width = docWidth; 328 height = docHeight; 329 } 330 331 float imgMaxWidth = -1; 333 if (hints.containsKey(KEY_MAX_WIDTH)) { 334 imgMaxWidth = ((Float )hints.get(KEY_MAX_WIDTH)).floatValue(); 335 } 336 float imgMaxHeight = -1; 337 if (hints.containsKey(KEY_MAX_HEIGHT)) { 338 imgMaxHeight = ((Float )hints.get(KEY_MAX_HEIGHT)).floatValue(); 339 } 340 341 if ((imgMaxHeight > 0) && (height > imgMaxHeight)) { 342 width = (docWidth * imgMaxHeight) / docHeight; 343 height = imgMaxHeight; 344 } 345 if ((imgMaxWidth > 0) && (width > imgMaxWidth)) { 346 width = imgMaxWidth; 347 height = (docHeight * imgMaxWidth) / docWidth; 348 } 349 } 350 351 352 356 375 public static final TranscodingHints.Key KEY_WIDTH 376 = new LengthKey(); 377 378 397 public static final TranscodingHints.Key KEY_HEIGHT 398 = new LengthKey(); 399 400 423 public static final TranscodingHints.Key KEY_MAX_WIDTH 424 = new LengthKey(); 425 426 449 public static final TranscodingHints.Key KEY_MAX_HEIGHT 450 = new LengthKey(); 451 452 474 public static final TranscodingHints.Key KEY_AOI 475 = new Rectangle2DKey(); 476 477 498 public static final TranscodingHints.Key KEY_LANGUAGE 499 = new StringKey(); 500 501 522 public static final TranscodingHints.Key KEY_MEDIA 523 = new StringKey(); 524 525 549 public static final TranscodingHints.Key KEY_DEFAULT_FONT_FAMILY 550 = new StringKey(); 551 552 573 public static final TranscodingHints.Key KEY_ALTERNATE_STYLESHEET 574 = new StringKey(); 575 576 596 public static final TranscodingHints.Key KEY_USER_STYLESHEET_URI 597 = new StringKey(); 598 599 620 public static final TranscodingHints.Key KEY_PIXEL_UNIT_TO_MILLIMETER 621 = new FloatKey(); 622 623 647 public static final TranscodingHints.Key KEY_PIXEL_TO_MM 648 = KEY_PIXEL_UNIT_TO_MILLIMETER; 649 650 671 public static final TranscodingHints.Key KEY_EXECUTE_ONLOAD 672 = new BooleanKey(); 673 674 699 public static final TranscodingHints.Key KEY_ALLOWED_SCRIPT_TYPES 700 = new StringKey(); 701 702 705 public static final String DEFAULT_ALLOWED_SCRIPT_TYPES 706 = SVGConstants.SVG_SCRIPT_TYPE_ECMASCRIPT + ", " 707 + SVGConstants.SVG_SCRIPT_TYPE_JAVA; 708 709 735 public static final TranscodingHints.Key KEY_CONSTRAIN_SCRIPT_ORIGIN 736 = new BooleanKey(); 737 738 739 742 protected class SVGAbstractTranscoderUserAgent extends UserAgentAdapter { 743 746 protected List scripts; 747 748 public SVGAbstractTranscoderUserAgent() { 749 addStdFeatures(); 750 } 751 752 755 public AffineTransform getTransform() { 756 return SVGAbstractTranscoder.this.curTxf; 757 } 758 759 762 public void setTransform(AffineTransform at) { 763 SVGAbstractTranscoder.this.curTxf = at; 764 } 765 766 769 public Dimension2D getViewportSize() { 770 return new Dimension ((int)SVGAbstractTranscoder.this.width, 771 (int)SVGAbstractTranscoder.this.height); 772 } 773 774 777 public void displayError(String message) { 778 try { 779 SVGAbstractTranscoder.this.handler.error 780 (new TranscoderException(message)); 781 } catch (TranscoderException ex) { 782 throw new RuntimeException (); 783 } 784 } 785 786 789 public void displayError(Exception e) { 790 try { 791 e.printStackTrace(); 792 SVGAbstractTranscoder.this.handler.error 793 (new TranscoderException(e)); 794 } catch (TranscoderException ex) { 795 throw new RuntimeException (); 796 } 797 } 798 799 802 public void displayMessage(String message) { 803 try { 804 SVGAbstractTranscoder.this.handler.warning 805 (new TranscoderException(message)); 806 } catch (TranscoderException ex) { 807 throw new RuntimeException (); 808 } 809 } 810 811 815 public float getPixelUnitToMillimeter() { 816 Object obj = SVGAbstractTranscoder.this.hints.get 817 (KEY_PIXEL_UNIT_TO_MILLIMETER); 818 if (obj != null) { 819 return ((Float )obj).floatValue(); 820 } 821 822 return super.getPixelUnitToMillimeter(); 823 } 824 825 829 public String getLanguages() { 830 if (SVGAbstractTranscoder.this.hints.containsKey(KEY_LANGUAGE)) { 831 return (String )SVGAbstractTranscoder.this.hints.get 832 (KEY_LANGUAGE); 833 } 834 835 return super.getLanguages(); 836 } 837 838 841 public String getMedia() { 842 String s = (String )hints.get(KEY_MEDIA); 843 if (s != null) return s; 844 845 return super.getMedia(); 846 } 847 848 851 public String getDefaultFontFamily() { 852 String s = (String )hints.get(KEY_DEFAULT_FONT_FAMILY); 853 if (s != null) return s; 854 855 return super.getDefaultFontFamily(); 856 } 857 858 861 public String getAlternateStyleSheet() { 862 String s = (String )hints.get(KEY_ALTERNATE_STYLESHEET); 863 if (s != null) 864 return s; 865 866 return super.getAlternateStyleSheet(); 867 } 868 869 873 public String getUserStyleSheetURI() { 874 String s = (String )SVGAbstractTranscoder.this.hints.get 875 (KEY_USER_STYLESHEET_URI); 876 if (s != null) 877 return s; 878 879 return super.getUserStyleSheetURI(); 880 } 881 882 885 public String getXMLParserClassName() { 886 String s = (String )SVGAbstractTranscoder.this.hints.get 887 (KEY_XML_PARSER_CLASSNAME); 888 if (s != null) 889 return s; 890 891 return super.getXMLParserClassName(); 892 } 893 894 898 public boolean isXMLParserValidating() { 899 Boolean b = (Boolean )SVGAbstractTranscoder.this.hints.get 900 (KEY_XML_PARSER_VALIDATING); 901 if (b != null) 902 return b.booleanValue(); 903 904 return super.isXMLParserValidating(); 905 } 906 907 920 public ScriptSecurity getScriptSecurity(String scriptType, 921 ParsedURL scriptPURL, 922 ParsedURL docPURL){ 923 if (scripts == null){ 924 computeAllowedScripts(); 925 } 926 927 if (!scripts.contains(scriptType)) { 928 return new NoLoadScriptSecurity(scriptType); 929 } 930 931 932 boolean constrainOrigin = true; 933 934 if (SVGAbstractTranscoder.this.hints.containsKey 935 (KEY_CONSTRAIN_SCRIPT_ORIGIN)) { 936 constrainOrigin = 937 ((Boolean )SVGAbstractTranscoder.this.hints.get 938 (KEY_CONSTRAIN_SCRIPT_ORIGIN)).booleanValue(); 939 } 940 941 if (constrainOrigin) { 942 return new DefaultScriptSecurity 943 (scriptType,scriptPURL,docPURL); 944 } else { 945 return new RelaxedScriptSecurity 946 (scriptType,scriptPURL,docPURL); 947 } 948 } 949 950 954 protected void computeAllowedScripts(){ 955 scripts = new LinkedList (); 956 if (!SVGAbstractTranscoder.this.hints.containsKey 957 (KEY_ALLOWED_SCRIPT_TYPES)) { 958 return; 959 } 960 961 String allowedScripts 962 = (String )SVGAbstractTranscoder.this.hints.get 963 (KEY_ALLOWED_SCRIPT_TYPES); 964 965 StringTokenizer st = new StringTokenizer (allowedScripts, ","); 966 while (st.hasMoreTokens()) { 967 scripts.add(st.nextToken()); 968 } 969 } 970 971 } 972 } 973 | Popular Tags |