001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: SVGElement.java 495371 2007-01-11 21:03:07Z adelmelle $ */
019:
020: package org.apache.fop.fo.extensions.svg;
021:
022: // FOP
023: import org.apache.fop.apps.FOPException;
024: import org.apache.fop.fo.FONode;
025: import org.apache.fop.fo.PropertyList;
026: import org.apache.fop.util.ContentHandlerFactory;
027: import org.apache.fop.util.DOMBuilderContentHandlerFactory;
028:
029: import org.apache.batik.dom.svg.SVGOMDocument;
030: import org.apache.batik.dom.svg.SVGOMElement;
031: import org.apache.batik.dom.svg.SVGContext;
032: import org.apache.batik.dom.util.XMLSupport;
033: import org.w3c.dom.Element;
034: import org.w3c.dom.svg.SVGDocument;
035: import org.xml.sax.Attributes;
036: import org.xml.sax.Locator;
037: import org.apache.batik.bridge.UnitProcessor;
038: import org.apache.batik.util.SVGConstants;
039:
040: import org.w3c.dom.DOMImplementation;
041:
042: import org.apache.batik.dom.svg.SVGDOMImplementation;
043:
044: import java.net.URL;
045: import java.awt.geom.AffineTransform;
046: import java.awt.geom.Point2D;
047: import java.awt.geom.Rectangle2D;
048:
049: /**
050: * class representing the SVG root element
051: * for constructing an svg document.
052: */
053: public class SVGElement extends SVGObj {
054:
055: /**
056: * Constructs an SVG object
057: *
058: * @param parent the parent formatting object
059: */
060: public SVGElement(FONode parent) {
061: super (parent);
062: }
063:
064: /**
065: * @see org.apache.fop.fo.FONode#getContentHandlerFactory()
066: */
067: public ContentHandlerFactory getContentHandlerFactory() {
068: return new DOMBuilderContentHandlerFactory(getNamespaceURI(),
069: SVGDOMImplementation.getDOMImplementation());
070: }
071:
072: /**
073: * @see org.apache.fop.fo.FONode#processNode
074: */
075: public void processNode(String elementName, Locator locator,
076: Attributes attlist, PropertyList propertyList)
077: throws FOPException {
078: super .processNode(elementName, locator, attlist, propertyList);
079: init();
080: }
081:
082: /**
083: * Get the dimensions of this XML document.
084: * @param view the viewport dimensions
085: * @return the dimensions of this SVG document
086: */
087: public Point2D getDimension(final Point2D view) {
088:
089: // TODO change so doesn't hold onto fo, area tree
090: Element svgRoot = element;
091: /* create an SVG area */
092: /* if width and height are zero, get the bounds of the content. */
093:
094: try {
095: URL baseURL = new URL(
096: getUserAgent().getBaseURL() == null ? new java.io.File(
097: "").toURL().toExternalForm()
098: : getUserAgent().getBaseURL());
099: if (baseURL != null) {
100: SVGOMDocument svgdoc = (SVGOMDocument) doc;
101: svgdoc.setURLObject(baseURL);
102: //The following line should not be called to leave FOP compatible to Batik 1.6.
103: //svgdoc.setDocumentURI(baseURL.toString());
104: }
105: } catch (Exception e) {
106: log.error("Could not set base URL for svg", e);
107: }
108:
109: Element e = ((SVGDocument) doc).getRootElement();
110: final float ptmm = getUserAgent()
111: .getSourcePixelUnitToMillimeter();
112: // temporary svg context
113: SVGContext dc = new SVGContext() {
114: public float getPixelToMM() {
115: return ptmm;
116: }
117:
118: public float getPixelUnitToMillimeter() {
119: return ptmm;
120: }
121:
122: public Rectangle2D getBBox() {
123: return new Rectangle2D.Double(0, 0, view.getX(), view
124: .getY());
125: }
126:
127: /**
128: * Returns the transform from the global transform space to pixels.
129: */
130: public AffineTransform getScreenTransform() {
131: throw new UnsupportedOperationException("NYI");
132: }
133:
134: /**
135: * Sets the transform to be used from the global transform space
136: * to pixels.
137: */
138: public void setScreenTransform(AffineTransform at) {
139: throw new UnsupportedOperationException("NYI");
140: }
141:
142: public AffineTransform getCTM() {
143: return new AffineTransform();
144: }
145:
146: public AffineTransform getGlobalTransform() {
147: return new AffineTransform();
148: }
149:
150: public float getViewportWidth() {
151: return (float) view.getX();
152: }
153:
154: public float getViewportHeight() {
155: return (float) view.getY();
156: }
157:
158: public float getFontSize() {
159: return 12;
160: }
161:
162: public void deselectAll() {
163: }
164: };
165: ((SVGOMElement) e).setSVGContext(dc);
166:
167: //if (!e.hasAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns")) {
168: e.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns",
169: SVGDOMImplementation.SVG_NAMESPACE_URI);
170: //}
171: int fontSize = 12;
172: Point2D p2d = getSize(fontSize, svgRoot, getUserAgent()
173: .getSourcePixelUnitToMillimeter());
174: ((SVGOMElement) e).setSVGContext(null);
175:
176: return p2d;
177: }
178:
179: private void init() {
180: DOMImplementation impl = SVGDOMImplementation
181: .getDOMImplementation();
182: String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
183: doc = impl.createDocument(svgNS, "svg", null);
184:
185: element = doc.getDocumentElement();
186:
187: buildTopLevel(doc, element);
188: }
189:
190: /**
191: * Get the size of the SVG root element.
192: * @param size the font size
193: * @param svgRoot the svg root element
194: * @param ptmm the pixel to millimeter conversion factor
195: * @return the size of the SVG document
196: */
197: public static Point2D getSize(int size, Element svgRoot, float ptmm) {
198: String str;
199: UnitProcessor.Context ctx;
200: ctx = new PDFUnitContext(size, svgRoot, ptmm);
201: str = svgRoot.getAttributeNS(null,
202: SVGConstants.SVG_WIDTH_ATTRIBUTE);
203: if (str.length() == 0) {
204: str = "100%";
205: }
206: float width = UnitProcessor.svgHorizontalLengthToUserSpace(str,
207: SVGConstants.SVG_WIDTH_ATTRIBUTE, ctx);
208:
209: str = svgRoot.getAttributeNS(null,
210: SVGConstants.SVG_HEIGHT_ATTRIBUTE);
211: if (str.length() == 0) {
212: str = "100%";
213: }
214: float height = UnitProcessor.svgVerticalLengthToUserSpace(str,
215: SVGConstants.SVG_HEIGHT_ATTRIBUTE, ctx);
216: return new Point2D.Float(width, height);
217: }
218:
219: /**
220: * This class is the default context for a particular
221: * element. Information not available on the element are obtained from
222: * the bridge context (such as the viewport or the pixel to
223: * millimeter factor.
224: */
225: public static class PDFUnitContext implements UnitProcessor.Context {
226:
227: /** The element. */
228: private Element e;
229: private int fontSize;
230: private float pixeltoMM;
231:
232: /**
233: * Create a PDF unit context.
234: * @param size the font size.
235: * @param e the svg element
236: * @param ptmm the pixel to millimeter factor
237: */
238: public PDFUnitContext(int size, Element e, float ptmm) {
239: this .e = e;
240: this .fontSize = size;
241: this .pixeltoMM = ptmm;
242: }
243:
244: /**
245: * Returns the element.
246: * @return the element
247: */
248: public Element getElement() {
249: return e;
250: }
251:
252: /**
253: * Returns the context of the parent element of this context.
254: * Since this is always for the root SVG element there never
255: * should be one...
256: * @return null
257: */
258: public UnitProcessor.Context getParentElementContext() {
259: return null;
260: }
261:
262: /**
263: * Returns the pixel to mm factor. (this is deprecated)
264: * @return the pixel to millimeter factor
265: */
266: public float getPixelToMM() {
267: return pixeltoMM;
268: }
269:
270: /**
271: * Returns the pixel to mm factor.
272: * @return the pixel to millimeter factor
273: */
274: public float getPixelUnitToMillimeter() {
275: return pixeltoMM;
276: }
277:
278: /**
279: * Returns the font-size value.
280: * @return the default font size
281: */
282: public float getFontSize() {
283: return fontSize;
284: }
285:
286: /**
287: * Returns the x-height value.
288: * @return the x-height value
289: */
290: public float getXHeight() {
291: return 0.5f;
292: }
293:
294: /**
295: * Returns the viewport width used to compute units.
296: * @return the default viewport width of 100
297: */
298: public float getViewportWidth() {
299: return 100;
300: }
301:
302: /**
303: * Returns the viewport height used to compute units.
304: * @return the default viewport height of 100
305: */
306: public float getViewportHeight() {
307: return 100;
308: }
309: }
310:
311: }
|