001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.bridge;
020:
021: import java.awt.RenderingHints;
022: import java.awt.geom.Rectangle2D;
023:
024: import org.apache.batik.gvt.CompositeGraphicsNode;
025: import org.apache.batik.gvt.GraphicsNode;
026: import org.w3c.dom.Element;
027: import org.w3c.dom.Node;
028: import org.w3c.dom.events.MutationEvent;
029:
030: /**
031: * Bridge class for the <g> element.
032: *
033: * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
034: * @version $Id: SVGGElementBridge.java 491178 2006-12-30 06:18:34Z cam $
035: */
036: public class SVGGElementBridge extends AbstractGraphicsNodeBridge {
037:
038: /**
039: * Constructs a new bridge for the <g> element.
040: */
041: public SVGGElementBridge() {
042: }
043:
044: /**
045: * Returns 'g'.
046: */
047: public String getLocalName() {
048: return SVG_G_TAG;
049: }
050:
051: /**
052: * Returns a new instance of this bridge.
053: */
054: public Bridge getInstance() {
055: return new SVGGElementBridge();
056: }
057:
058: /**
059: * Creates a <tt>GraphicsNode</tt> according to the specified parameters.
060: *
061: * @param ctx the bridge context to use
062: * @param e the element that describes the graphics node to build
063: * @return a graphics node that represents the specified element
064: */
065: public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
066: CompositeGraphicsNode gn = (CompositeGraphicsNode) super
067: .createGraphicsNode(ctx, e);
068: if (gn == null)
069: return null;
070:
071: associateSVGContext(ctx, e, gn);
072:
073: // 'color-rendering'
074: RenderingHints hints = null;
075: hints = CSSUtilities.convertColorRendering(e, hints);
076: if (hints != null)
077: gn.setRenderingHints(hints);
078:
079: // 'enable-background'
080: Rectangle2D r = CSSUtilities.convertEnableBackground(e);
081: if (r != null)
082: gn.setBackgroundEnable(r);
083:
084: return gn;
085: }
086:
087: /**
088: * Creates a <tt>CompositeGraphicsNode</tt>.
089: */
090: protected GraphicsNode instantiateGraphicsNode() {
091: return new CompositeGraphicsNode();
092: }
093:
094: /**
095: * Returns true as the <g> element is a container.
096: */
097: public boolean isComposite() {
098: return true;
099: }
100:
101: // BridgeUpdateHandler implementation //////////////////////////////////
102:
103: /**
104: * Invoked when an MutationEvent of type 'DOMNodeInserted' is fired.
105: */
106: public void handleDOMNodeInsertedEvent(MutationEvent evt) {
107: if (evt.getTarget() instanceof Element) {
108: handleElementAdded((CompositeGraphicsNode) node, e,
109: (Element) evt.getTarget());
110: } else {
111: super .handleDOMNodeInsertedEvent(evt);
112: }
113: }
114:
115: /**
116: * Invoked when an MutationEvent of type 'DOMNodeInserted' is fired.
117: */
118: protected void handleElementAdded(CompositeGraphicsNode gn,
119: Node parent, Element childElt) {
120: // build the graphics node
121: GVTBuilder builder = ctx.getGVTBuilder();
122: GraphicsNode childNode = builder.build(ctx, childElt);
123: if (childNode == null) {
124: return; // the added element is not a graphic element
125: }
126:
127: // Find the index where the GraphicsNode should be added
128: int idx = -1;
129: for (Node ps = childElt.getPreviousSibling(); ps != null; ps = ps
130: .getPreviousSibling()) {
131: if (ps.getNodeType() != Node.ELEMENT_NODE)
132: continue;
133: Element pse = (Element) ps;
134: GraphicsNode psgn = ctx.getGraphicsNode(pse);
135: while ((psgn != null) && (psgn.getParent() != gn)) {
136: // In some cases the GN linked is
137: // a child (in particular for images).
138: psgn = psgn.getParent();
139: }
140: if (psgn == null)
141: continue;
142: idx = gn.indexOf(psgn);
143: if (idx == -1)
144: continue;
145: break;
146: }
147: // insert after prevSibling, if
148: // it was -1 this becomes 0 (first slot)
149: idx++;
150: gn.add(idx, childNode);
151: }
152: }
|