deweese 2003/06/05 03:03:17
Modified: samples/extensions multi.svg
sources/org/apache/batik/extension/svg
BatikMultiImageElementBridge.java
MultiResGraphicsNode.java
Added: samples sydney.svg
samples/extensions/opera opera-subImage.svg
opera-subImageRef.svg
samples/tests/resources/images operaBridge.jpg
operaSteps.jpg operaWalk.jpg
Removed: samples/extensions/opera opera.svg
Log:
1) The 'multiImage' element now implements both subImage and subImageRef.
So resolution selected content can be included inline (see
samples/extensions/opera-subImage.svg for an example).
2) New sample file: 'samples/sydney.svg' - layout images interactively.
Revision Changes Path
1.1 xml-batik/samples/sydney.svg
Index: sydney.svg
===================================================================
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="655" height="600" viewBox="0 0 655 600"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<script type="text/ecmascript">
<![CDATA[
var svgns = "http://www.w3.org/2000/svg";
var xlinkns = "http://www.w3.org/1999/xlink";
var dragNode;
var scaleNode;
var scaleTgt;
var dx;
var dy;
var imgGroup = document.getElementById("imgGroup")
var filter = imgGroup.getAttribute("style");
var dragged=false;
function dragOn(evt) {
dragNode = evt.target;
var currX = parseFloat(dragNode.getAttribute("x"));
var currY = parseFloat(dragNode.getAttribute("y"));
dx = evt.getClientX()-currX;
dy = evt.getClientY()-currY;
dragged=false;
}
function scaleOn(evt) {
scaleNode = scaleTgt;
var cW = parseFloat(scaleNode.getAttribute("width"));
var cH = parseFloat(scaleNode.getAttribute("height"));
dx = evt.getClientX()-cW;
dy = evt.getClientY()-cH;
dragged=false;
}
function dragScaleOff() {
if (dragged)
imgGroup.setAttribute("style",filter);
if (dragNode != null) {
if (dragNode != imgGroup.lastChild) {
imgGroup.appendChild(dragNode);
}
dragNode = null;
}
if (scaleNode != null) {
if (scaleNode != imgGroup.lastChild) {
imgGroup.appendChild(scaleNode);
}
scaleNode = null;
}
}
function dragScaleImgBg(evt) {
if ((dragNode == null) && (scaleNode == null)) {
hideOverlay();
return;
}
dragScaleImg(evt);
}
function dragScaleImg(evt) {
if ((dragNode == null) && (scaleNode == null))
return;
dragged = true;
imgGroup.setAttribute("style","");
if (dragNode != null) {
if (dragNode != imgGroup.lastChild)
imgGroup.appendChild(dragNode);
dragNode.setAttribute("x",""+(evt.getClientX()-dx));
dragNode.setAttribute("y",""+(evt.getClientY()-dy));
updateOverlay(dragNode);
}
if (scaleNode != null) {
if (scaleNode != imgGroup.lastChild)
imgGroup.appendChild(scaleNode);
var cW = parseFloat(scaleNode.getAttribute("width"));
var cH = parseFloat(scaleNode.getAttribute("height"));
var ar = cW/cH;
var nW = evt.getClientX()-dx;
var nH = evt.getClientY()-dy;
if (nW/nH < ar) {
nW = ar*nH;
} else {
nH = nW/ar;
}
scaleNode.setAttribute("width", ""+nW);
scaleNode.setAttribute("height",""+nH);
updateOverlay(scaleNode);
}
}
function updateOverlay(tgt) {
var cX = parseFloat(tgt.getAttribute("x"));
var cY = parseFloat(tgt.getAttribute("y"));
var cW = parseFloat(tgt.getAttribute("width"));
var cH = parseFloat(tgt.getAttribute("height"));
var over = document.getElementById("overlay");
over.setAttribute("transform","translate("+(cX+cW-1)+","+(cY+cH-1)+")");
scaleTgt = tgt;
}
function showOverlay(evt) {
if ((dragNode != null) || (scaleNode != null))
return;
var tgt = evt.target;
updateOverlay(tgt);
var over = document.getElementById("overlay");
over.setAttribute("visibility","visible");
}
function hideOverlay() {
if ((dragNode != null) || (scaleNode != null))
return;
var over = document.getElementById("overlay");
over.setAttribute("visibility","hidden");
}
]]></script>
<filter id="merge" filterUnits="objectBoundingBox" >
<feMorphology operator="dilate" radius="10" in="SourceAlpha" />
<feGaussianBlur stdDeviation="4" />
<feOffset dx="3" dy="3"/>
<feComponentTransfer result="shadow">
<feFuncA type="linear" slope=".6" intercept="0" />
</feComponentTransfer>
<feComposite operator="over" in="SourceGraphic" in2="shadow"/>
</filter>
<rect fill="#88A" x="0%" y="0%" width="100%" height="100%"/>
<text x="302" y="47" font-size="24" fill="#448"
>Click and drag to move images</text>
<text x="300" y="45" font-size="24" fill="white"
>Click and drag to move images</text>
<rect fill="none" x="0%" y="0%" width="100%" height="100%"
pointer-events="fill"
onmousedown="dragScaleOff()"
onmouseup="dragScaleOff()"
onmousemove="dragScaleImgBg(evt)"/>
<g id="imgGroup" style="filter:url(#merge)"
onmousedown="dragOn(evt)"
onmouseup="dragScaleOff()"
onmousemove="dragScaleImg(evt)"
onmouseover="showOverlay(evt)">
<image x="25" y="315" width="360" height="240"
xlink:href="tests/resources/images/operaSteps.jpg"/>
<image x="50" y="40" width="200" height="300"
xlink:href="tests/resources/images/operaWalk.jpg"/>
<image x="270" y="200" width="360" height="240"
xlink:href="tests/resources/images/operaBridge.jpg"/>
</g>
<g id="overlay" visibility="hidden"
onmousedown="scaleOn(evt)"
onmouseup="dragScaleOff()"
onmousemove="dragScaleImg(evt)">
<path fill="darkgrey" stroke="white"
d="M0,0 h-20 l20,-20 z M-12,-3 l9-9 z M-6,-3 l3-3z"/>
</g>
</svg>
1.6 +13 -13 xml-batik/samples/extensions/multi.svg
Index: multi.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/extensions/multi.svg,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- multi.svg 28 May 2003 18:45:59 -0000 1.5
+++ multi.svg 5 Jun 2003 10:03:16 -0000 1.6
@@ -2,20 +2,20 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
-<!-- ====================================================================== -->
-<!-- Copyright (C) The Apache Software Foundation. All rights reserved. -->
-<!-- -->
-<!-- This software is published under the terms of the Apache Software -->
-<!-- License version 1.1, a copy of which has been included with this -->
-<!-- distribution in the LICENSE file. -->
-<!-- ====================================================================== -->
+<!-- =================================================================== -->
+<!-- Copyright (C) The Apache Software Foundation. All rights reserved. -->
+<!-- -->
+<!-- This software is published under the terms of the Apache Software -->
+<!-- License version 1.1, a copy of which has been included with this -->
+<!-- distribution in the LICENSE file. -->
+<!-- =================================================================== -->
-<!-- ====================================================================== -->
-<!-- Tests 'multiImage' element with just 'subImageRef' children. -->
-<!-- -->
-<!-- @author [EMAIL PROTECTED] -->
+<!-- =================================================================== -->
+<!-- Tests 'multiImage' element with just 'subImageRef' children. -->
+<!-- -->
+<!-- @author [EMAIL PROTECTED] -->
<!-- @version $Id$ -->
-<!-- ====================================================================== -->
+<!-- =================================================================== -->
<svg width="450" height="500" xml:space="preserve"
viewBox="0 0 450 500"
1.1 xml-batik/samples/extensions/opera/opera-subImage.svg
Index: opera-subImage.svg
===================================================================
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- =================================================================== -->
<!-- Copyright (C) The Apache Software Foundation. All rights reserved. -->
<!-- -->
<!-- This software is published under the terms of the Apache Software -->
<!-- License version 1.1, a copy of which has been included with this -->
<!-- distribution in the LICENSE file. -->
<!-- =================================================================== -->
<!-- =================================================================== -->
<!-- Tests 'multiImage' element with a combination of 'subImage' and -->
<!-- 'subImageRef' children. -->
<!-- -->
<!-- @author [EMAIL PROTECTED] -->
<!-- @version $Id: opera-subImage.svg,v 1.1 2003/06/05 10:03:16 deweese Exp $ -->
<!-- =================================================================== -->
<svg width="640" height="480" viewBox="0 0 640 480"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<style type="text/css"><![CDATA[
.overlay { fill:none; stroke-width:4; }
]]></style>
<symbol id="opera" viewBox="0 0 90 135">
<multiImage x="0" y="0" width="90" height="135"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-3-0-0.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%" viewBox="0 0 180 270">
<multiImage x="0" y="0" width="180" height="180"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-2-0-0.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%" viewBox="0 0 360 360">
<multiImage x="0" y="0" width="180" height="180"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-1-0-0.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%"
viewBox="0 0 360 360">
<image x="0" y="0" width="180" height="180"
xlink:href="multires/opera-0-0-0.jpg"/>
<image x="180" y="0" width="180" height="180"
xlink:href="multires/opera-0-1-0.jpg"/>
<image x="0" y="180" width="180" height="180"
xlink:href="multires/opera-0-0-1.jpg"/>
<image x="180" y="180"
width="180" height="180"
xlink:href="multires/opera-0-1-1.jpg"/>
<rect class="overlay" stroke="#F00"
x="0" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="0" y="180" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="180" width="180" height="180"/>
</svg>
</subImage>
</multiImage>
<multiImage x="180" y="0" width="180" height="180"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-1-1-0.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%"
viewBox="0 0 360 360">
<image x="0" y="0" width="180" height="180"
xlink:href="multires/opera-0-2-0.jpg"/>
<image x="180" y="0" width="180" height="180"
xlink:href="multires/opera-0-3-0.jpg"/>
<image x="0" y="180" width="180" height="180"
xlink:href="multires/opera-0-2-1.jpg"/>
<image x="180" y="180"
width="180" height="180"
xlink:href="multires/opera-0-3-1.jpg"/>
<rect class="overlay" stroke="#F00"
x="0" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="0" y="180" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="180" width="180" height="180"/>
</svg>
</subImage>
</multiImage>
<multiImage x="0" y="180" width="180" height="180"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-1-0-1.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%"
viewBox="0 0 360 360">
<image x="0" y="0" width="180" height="180"
xlink:href="multires/opera-0-0-2.jpg"/>
<image x="180" y="0" width="180" height="180"
xlink:href="multires/opera-0-1-2.jpg"/>
<image x="0" y="180" width="180" height="180"
xlink:href="multires/opera-0-0-3.jpg"/>
<image x="180" y="180"
width="180" height="180"
xlink:href="multires/opera-0-1-3.jpg"/>
<rect class="overlay" stroke="#F00"
x="0" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="0" y="180" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="180" width="180" height="180"/>
</svg>
</subImage>
</multiImage>
<multiImage x="180" y="180" width="180" height="180"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-1-1-1.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%"
viewBox="0 0 360 360">
<image x="0" y="0" width="180" height="180"
xlink:href="multires/opera-0-2-2.jpg"/>
<image x="180" y="0" width="180" height="180"
xlink:href="multires/opera-0-3-2.jpg"/>
<image x="0" y="180" width="180" height="180"
xlink:href="multires/opera-0-2-3.jpg"/>
<image x="180" y="180"
width="180" height="180"
xlink:href="multires/opera-0-3-3.jpg"/>
<rect class="overlay" stroke="#F00"
x="0" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="0" y="180" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="180" width="180" height="180"/>
</svg>
</subImage>
</multiImage>
<rect class="overlay"
stroke="#FF0"
x="0" y="0" width="180" height="180"/>
<rect class="overlay"
stroke="#FF0"
x="180" y="0" width="180" height="180"/>
<rect class="overlay"
stroke="#FF0"
x="0" y="180" width="180" height="180"/>
<rect class="overlay"
stroke="#FF0"
x="180" y="180" width="180" height="180"/>
</svg>
</subImage>
</multiImage>
<multiImage x="0" y="180" width="180" height="90"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-2-0-1.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%" viewBox="0 0 360 180">
<multiImage x="0" y="0" width="180" height="180"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-1-0-2.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%"
viewBox="0 0 360 360">
<image x="0" y="0" width="180" height="180"
xlink:href="multires/opera-0-0-4.jpg"/>
<image x="180" y="0" width="180" height="180"
xlink:href="multires/opera-0-1-4.jpg"/>
<image x="0" y="180" width="180" height="180"
xlink:href="multires/opera-0-0-5.jpg"/>
<image x="180" y="180"
width="180" height="180"
xlink:href="multires/opera-0-1-5.jpg"/>
<rect class="overlay" stroke="#F00"
x="0" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="0" y="180" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="180" width="180" height="180"/>
</svg>
</subImage>
</multiImage>
<multiImage x="180" y="0" width="180" height="180"
xmlns="http://xml.apache.org/batik/ext">
<subImageRef xlink:href="multires/opera-1-1-2.jpg"
min-pixel-size="1"/>
<subImage max-pixel-size="1">
<svg width="100%" height="100%"
viewBox="0 0 360 360">
<image x="0" y="0" width="180" height="180"
xlink:href="multires/opera-0-2-4.jpg"/>
<image x="180" y="0" width="180" height="180"
xlink:href="multires/opera-0-3-4.jpg"/>
<image x="0" y="180" width="180" height="180"
xlink:href="multires/opera-0-2-5.jpg"/>
<image x="180" y="180"
width="180" height="180"
xlink:href="multires/opera-0-3-5.jpg"/>
<rect class="overlay" stroke="#F00"
x="0" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="0" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="0" y="180" width="180" height="180"/>
<rect class="overlay" stroke="#F00"
x="180" y="180" width="180" height="180"/>
</svg>
</subImage>
</multiImage>
<rect class="overlay"
stroke="#FF0"
x="0" y="0" width="180" height="180"/>
<rect class="overlay"
stroke="#FF0"
x="180" y="0" width="180" height="180"/>
</svg>
</subImage>
</multiImage>
<rect class="overlay"
stroke="#0F0"
x="0" y="0" width="180" height="180"/>
<rect class="overlay"
stroke="#0F0"
x="0" y="180" width="180" height="90"/>
</svg>
</subImage>
</multiImage>
<rect class="overlay" stroke="#00F"
x="0" y="0" width="90" height="135"/>
</symbol>>
<use x="165" y="50" width="270" height="405" xlink:href="#opera"/>
<use x="10" y="50" width="135" height="202.5" xlink:href="#opera"/>
<use x="43.75" y="272.5" width="67.5" height="101.25" xlink:href="#opera"/>
</svg>
1.1 xml-batik/samples/extensions/opera/opera-subImageRef.svg
Index: opera-subImageRef.svg
===================================================================
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- =================================================================== -->
<!-- Copyright (C) The Apache Software Foundation. All rights reserved. -->
<!-- -->
<!-- This software is published under the terms of the Apache Software -->
<!-- License version 1.1, a copy of which has been included with this -->
<!-- distribution in the LICENSE file. -->
<!-- =================================================================== -->
<!-- =================================================================== -->
<!-- Tests 'multiImage' element with 'subImageRef' children that -->
<!-- reference external SVG files. -->
<!-- -->
<!-- @author [EMAIL PROTECTED] -->
<!-- @version $Id: opera-subImageRef.svg,v 1.1 2003/06/05 10:03:16 deweese Exp $ -->
<!-- =================================================================== -->
<svg width="640" height="480" viewBox="0 0 640 480"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="165" y="50" width="270" height="405"
xlink:href="opera-3-0-0.svg" />
<image x="10" y="50" width="135" height="202.5"
xlink:href="opera-3-0-0.svg" />
<image x="43.75" y="272.5" width="67.5" height="101.25"
xlink:href="opera-3-0-0.svg" />
</svg>
1.1 xml-batik/samples/tests/resources/images/operaBridge.jpg
<<Binary file>>
1.1 xml-batik/samples/tests/resources/images/operaSteps.jpg
<<Binary file>>
1.1 xml-batik/samples/tests/resources/images/operaWalk.jpg
<<Binary file>>
1.10 +158 -32
xml-batik/sources/org/apache/batik/extension/svg/BatikMultiImageElementBridge.java
Index: BatikMultiImageElementBridge.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/extension/svg/BatikMultiImageElementBridge.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- BatikMultiImageElementBridge.java 28 May 2003 14:40:57 -0000 1.9
+++ BatikMultiImageElementBridge.java 5 Jun 2003 10:03:16 -0000 1.10
@@ -9,25 +9,32 @@
package org.apache.batik.extension.svg;
import java.awt.Dimension;
+import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit;
+import org.apache.batik.ext.awt.image.renderable.Filter;
import org.apache.batik.bridge.Bridge;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.BridgeException;
import org.apache.batik.bridge.CSSUtilities;
import org.apache.batik.bridge.SVGImageElementBridge;
import org.apache.batik.bridge.SVGUtilities;
+import org.apache.batik.bridge.Viewport;
import org.apache.batik.dom.svg.SVGOMElement;
import org.apache.batik.dom.svg.XMLBaseSupport;
import org.apache.batik.dom.util.XLinkSupport;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.ImageNode;
import org.apache.batik.util.ParsedURL;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
@@ -99,7 +106,35 @@
Rectangle2D b = getImageBounds(ctx, e);
- List uris = new LinkedList();
+ // 'transform'
+ AffineTransform at = null;
+ String s = e.getAttribute(SVG_TRANSFORM_ATTRIBUTE);
+ if (s.length() != 0)
+ at = SVGUtilities.convertTransform(e, SVG_TRANSFORM_ATTRIBUTE, s);
+ else
+ at = new AffineTransform();
+
+ at.translate(b.getX(), b.getY());
+ imgNode.setTransform(at);
+
+ // 'visibility'
+ imgNode.setVisible(CSSUtilities.convertVisibility(e));
+
+ Rectangle2D clip;
+ clip = new Rectangle2D.Double(0,0,b.getWidth(), b.getHeight());
+ Filter filter = imgNode.getGraphicsNodeRable(true);
+ imgNode.setClip(new ClipRable8Bit(filter, clip));
+
+ // 'enable-background'
+ Rectangle2D r = CSSUtilities.convertEnableBackground(e);
+ if (r != null) {
+ imgNode.setBackgroundEnable(r);
+ }
+ ctx.openViewport(e, new MultiImageElementViewport
+ ((float)b.getWidth(), (float)b.getHeight()));
+
+
+ List elems = new LinkedList();
List minDim = new LinkedList();
List maxDim = new LinkedList();
@@ -108,19 +143,22 @@
continue;
Element se = (Element)n;
- if (!(se.getNamespaceURI().equals(BATIK_EXT_NAMESPACE_URI)) ||
- !(se.getLocalName().equals(BATIK_EXT_SUB_IMAGE_REF_TAG)))
+ if (!se.getNamespaceURI().equals(BATIK_EXT_NAMESPACE_URI))
continue;
-
- addInfo(se, uris, minDim, maxDim, b);
+ if (se.getLocalName().equals(BATIK_EXT_SUB_IMAGE_TAG)) {
+ addInfo(se, elems, minDim, maxDim, b);
+ }
+ if (se.getLocalName().equals(BATIK_EXT_SUB_IMAGE_REF_TAG)) {
+ addRefInfo(se, elems, minDim, maxDim, b);
+ }
}
- Dimension [] mindary = new Dimension[uris.size()];
- Dimension [] maxdary = new Dimension[uris.size()];
- ParsedURL [] uary = new ParsedURL[uris.size()];
+ Dimension [] mindary = new Dimension[elems.size()];
+ Dimension [] maxdary = new Dimension[elems.size()];
+ Element [] elemary = new Element [elems.size()];
Iterator mindi = minDim.iterator();
Iterator maxdi = maxDim.iterator();
- Iterator ui = uris.iterator();
+ Iterator ei = elems.iterator();
int n=0;
while (mindi.hasNext()) {
Dimension minD = (Dimension)mindi.next();
@@ -135,33 +173,20 @@
}
}
for (int j=n; j>i; j--) {
- uary[j] = uary[j-1];
+ elemary[j] = elemary[j-1];
mindary[j] = mindary[j-1];
maxdary[j] = maxdary[j-1];
}
- uary [i] = (ParsedURL)ui.next();
+ elemary[i] = (Element)ei.next();
mindary[i] = minD;
maxdary[i] = maxD;
n++;
}
- // System.out.println("Bounds: " + bounds);
- // System.out.println("ImgB: " + imgBounds);
-
-
- GraphicsNode node = new MultiResGraphicsNode(e, b, uary,
- mindary, maxdary);
-
- // 'transform'
- String s = e.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
- if (s.length() != 0) {
- node.setTransform
- (SVGUtilities.convertTransform(e, SVG_TRANSFORM_ATTRIBUTE, s));
- }
- // 'visibility'
- imgNode.setVisible(CSSUtilities.convertVisibility(e));
-
+ GraphicsNode node = new MultiResGraphicsNode(e, clip, elemary,
+ mindary, maxdary,
+ ctx);
imgNode.setImage(node);
return imgNode;
@@ -174,6 +199,18 @@
return false;
}
+ public void buildGraphicsNode(BridgeContext ctx,
+ Element e,
+ GraphicsNode node) {
+ if (ctx.isDynamic()) {
+ initializeDynamicSupport(ctx, e, node);
+ }
+ // Handle children elements such as <title>
+ //SVGUtilities.bridgeChildren(ctx, e);
+ //super.buildGraphicsNode(ctx, e, node);
+ ctx.closeViewport(e);
+ }
+
/**
* This method is invoked during the build phase if the document
* is dynamic. The responsability of this method is to ensure that
@@ -192,22 +229,78 @@
((SVGOMElement)e).setSVGContext(this);
}
- protected void addInfo(Element e, Collection uris,
+ /**
+ * Disposes this BridgeUpdateHandler and releases all resources.
+ */
+ public void dispose() {
+ ctx.removeViewport(e);
+ super.dispose();
+ }
+
+ protected void addInfo(Element e, Collection elems,
Collection minDim, Collection maxDim,
Rectangle2D bounds) {
+ Document doc = e.getOwnerDocument();
+ Element gElem = doc.createElementNS(SVG_NAMESPACE_URI,
+ SVG_G_TAG);
+ NamedNodeMap attrs = e.getAttributes();
+ int len = attrs.getLength();
+ for (int i = 0; i < len; i++) {
+ Attr attr = (Attr)attrs.item(i);
+ gElem.setAttributeNS(attr.getNamespaceURI(),
+ attr.getName(),
+ attr.getValue());
+ }
+ // move the children from <subImage> to the <g> element
+ for (Node n = e.getFirstChild();
+ n != null;
+ n = e.getFirstChild()) {
+ gElem.appendChild(n);
+ }
+ e.appendChild(gElem);
+ elems.add(gElem);
+ minDim.add(getElementMinPixel(e, bounds));
+ maxDim.add(getElementMaxPixel(e, bounds));
+ }
+
+ protected void addRefInfo(Element e, Collection elems,
+ Collection minDim, Collection maxDim,
+ Rectangle2D bounds) {
String uriStr = XLinkSupport.getXLinkHref(e);
if (uriStr.length() == 0) {
throw new BridgeException(e, ERR_ATTRIBUTE_MISSING,
new Object[] {"xlink:href"});
}
-
String baseURI = XMLBaseSupport.getCascadedXMLBase(e);
ParsedURL purl;
if (baseURI == null) purl = new ParsedURL(uriStr);
else purl = new ParsedURL(baseURI, uriStr);
- uris.add(purl);
+ Document doc = e.getOwnerDocument();
+ Element imgElem = doc.createElementNS(SVG_NAMESPACE_URI,
+ SVG_IMAGE_TAG);
+ imgElem.setAttributeNS(XLinkSupport.XLINK_NAMESPACE_URI,
+ "href", purl.toString());
+ // move the attributes from <subImageRef> to the <image> element
+ NamedNodeMap attrs = e.getAttributes();
+ int len = attrs.getLength();
+ for (int i = 0; i < len; i++) {
+ Attr attr = (Attr)attrs.item(i);
+ imgElem.setAttributeNS(attr.getNamespaceURI(),
+ attr.getName(),
+ attr.getValue());
+ }
+ String s;
+ s = e.getAttribute("x");
+ if (s.length() == 0) imgElem.setAttribute("x", "0");
+ s = e.getAttribute("y");
+ if (s.length() == 0) imgElem.setAttribute("y", "0");
+ s = e.getAttribute("width");
+ if (s.length() == 0) imgElem.setAttribute("width", "100%");
+ s = e.getAttribute("height");
+ if (s.length() == 0) imgElem.setAttribute("height", "100%");
+ e.appendChild(imgElem);
+ elems.add(imgElem);
-
minDim.add(getElementMinPixel(e, bounds));
maxDim.add(getElementMaxPixel(e, bounds));
}
@@ -240,5 +333,38 @@
return new Dimension((int)(bounds.getWidth()/xPixSz+0.5),
(int)(bounds.getHeight()/yPixSz+0.5));
+ }
+
+ /**
+ * A viewport defined an <svg> element.
+ */
+ public static class MultiImageElementViewport implements Viewport {
+ private float width;
+ private float height;
+
+ /**
+ * Constructs a new viewport with the specified <tt>SVGSVGElement</tt>.
+ * @param e the SVGSVGElement that defines this viewport
+ * @param w the width of the viewport
+ * @param h the height of the viewport
+ */
+ public MultiImageElementViewport(float w, float h) {
+ this.width = w;
+ this.height = h;
+ }
+
+ /**
+ * Returns the width of this viewport.
+ */
+ public float getWidth(){
+ return width;
+ }
+
+ /**
+ * Returns the height of this viewport.
+ */
+ public float getHeight(){
+ return height;
+ }
}
}
1.7 +59 -188
xml-batik/sources/org/apache/batik/extension/svg/MultiResGraphicsNode.java
Index: MultiResGraphicsNode.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/extension/svg/MultiResGraphicsNode.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- MultiResGraphicsNode.java 30 May 2003 01:07:15 -0000 1.6
+++ MultiResGraphicsNode.java 5 Jun 2003 10:03:16 -0000 1.7
@@ -47,46 +47,36 @@
extends AbstractGraphicsNode implements SVGConstants {
SoftReference [] srcs;
- ParsedURL [] srcURLs;
+ Element [] srcElems;
Dimension [] minSz;
Dimension [] maxSz;
Rectangle2D bounds;
- UserAgent userAgent;
- DocumentLoader loader;
BridgeContext ctx;
Element multiImgElem;
- /**
- * The error code when a required attribute is missing.
- * {0} = the name of the attribute
- */
- public static final String ERR_ATTRIBUTE_MISSING
- = "attribute.missing";
-
-
public MultiResGraphicsNode(Element multiImgElem,
Rectangle2D bounds,
- ParsedURL [] srcURLs,
+ Element [] srcElems,
Dimension [] minSz,
- Dimension [] maxSz) {
+ Dimension [] maxSz,
+ BridgeContext ctx) {
+
this.multiImgElem = multiImgElem;
- this.srcURLs = new ParsedURL[srcURLs.length];
- this.minSz = new Dimension[srcURLs.length];
- this.maxSz = new Dimension[srcURLs.length];
-
- for (int i=0; i<srcURLs.length; i++) {
- this.srcURLs[i] = srcURLs[i];
- this.minSz[i] = minSz[i];
- this.maxSz[i] = maxSz[i];
+ this.srcElems = new Element [srcElems.length];
+ this.minSz = new Dimension[srcElems.length];
+ this.maxSz = new Dimension[srcElems.length];
+ this.ctx = ctx;
+
+ for (int i=0; i<srcElems.length; i++) {
+ this.srcElems[i] = srcElems[i];
+ this.minSz[i] = minSz[i];
+ this.maxSz[i] = maxSz[i];
}
- this.srcs = new SoftReference[srcURLs.length];
+ this.srcs = new SoftReference[srcElems.length];
this.bounds = bounds;
- userAgent = new UserAgentAdapter();
- loader = new DocumentLoader(userAgent);
- ctx = new BridgeContext(userAgent, loader);
}
/**
@@ -95,12 +85,13 @@
* @param g2d the Graphics2D to use
*/
public void primitivePaint(Graphics2D g2d) {
- // System.err.println("PrimPaint: " + this);
// get the current affine transform
AffineTransform at = g2d.getTransform();
- double scx = Math.sqrt(at.getShearX()*at.getShearX()+
+ double scx = Math.sqrt(at.getShearY()*at.getShearY()+
at.getScaleX()*at.getScaleX());
+ double scy = Math.sqrt(at.getShearX()*at.getShearX()+
+ at.getScaleY()*at.getScaleY());
GraphicsNode gn = null;
int idx =-1;
@@ -133,7 +124,43 @@
if (gn == null) return;
- // Rectangle2D gnBounds = gn.getBounds();
+ // This makes sure that the image 'pushes out' to it's pixel
+ // bounderies.
+ Rectangle2D gnBounds = gn.getBounds();
+ double gnDevW = gnBounds.getWidth()*scx;
+ double gnDevH = gnBounds.getHeight()*scy;
+ double gnDevX = gnBounds.getX()*scx;
+ double gnDevY = gnBounds.getY()*scy;
+ double gnDevX0, gnDevX1, gnDevY0, gnDevY1;
+ if (gnDevW < 0) {
+ gnDevX0 = gnDevX+gnDevW;
+ gnDevX1 = gnDevX;
+ } else {
+ gnDevX0 = gnDevX;
+ gnDevX1 = gnDevX+gnDevW;
+ }
+ if (gnDevH < 0) {
+ gnDevY0 = gnDevY+gnDevH;
+ gnDevY1 = gnDevY;
+ } else {
+ gnDevY0 = gnDevY;
+ gnDevY1 = gnDevY+gnDevH;
+ }
+ // This calculate the width/height in pixels given 'worst
+ // case' assessment.
+ gnDevW = (int)(Math.ceil(gnDevX1)-Math.floor(gnDevX0));
+ gnDevH = (int)(Math.ceil(gnDevY1)-Math.floor(gnDevY0));
+ scx = (gnDevW/gnBounds.getWidth())/scx;
+ scy = (gnDevH/gnBounds.getHeight())/scy;
+
+ // This scales things up slightly so our edges fall on device
+ // pixel boundries.
+ AffineTransform nat = g2d.getTransform();
+ nat = new AffineTransform(nat.getScaleX()*scx, nat.getShearY()*scx,
+ nat.getShearX()*scy, nat.getScaleY()*scy,
+ nat.getTranslateX(), nat.getTranslateY());
+ g2d.setTransform(nat);
+
// double sx = bounds.getWidth()/sizes[idx].getWidth();
// double sy = bounds.getHeight()/sizes[idx].getHeight();
// System.err.println("Scale: [" + sx + ", " + sy + "]");
@@ -199,170 +226,14 @@
}
try {
- SVGDocument svgDoc = (SVGDocument)loader.loadDocument
- (srcURLs[idx].toString());
-
- GraphicsNode gn;
- gn = createSVGImageNode(ctx, multiImgElem,
- bounds, svgDoc);
- srcs[idx] = new SoftReference(gn);
- return gn;
- } catch (Exception ex) { /* ex.printStackTrace(); */ }
-
- try {
+ GVTBuilder builder = ctx.getGVTBuilder();
GraphicsNode gn;
- gn = createRasterImageNode(ctx, multiImgElem,
- bounds, srcURLs[idx]);
+ gn = builder.build(ctx, srcElems[idx]);
srcs[idx] = new SoftReference(gn);
return gn;
- } catch (Exception ex) { /* ex.printStackTrace(); */ }
+ } catch (Exception ex) { ex.printStackTrace(); }
return null;
- }
-
-
- /**
- * Returns a GraphicsNode that represents an raster image in JPEG or PNG
- * format.
- *
- * @param ctx the bridge context
- * @param e the image element
- * @param uriStr the uri of the image
- */
- protected static GraphicsNode createRasterImageNode(BridgeContext ctx,
- Element e,
- Rectangle2D bounds,
- ParsedURL purl) {
-
- RasterImageNode node = new RasterImageNode();
-
- ImageTagRegistry reg = ImageTagRegistry.getRegistry();
- Filter img = reg.readURL(purl);
- Object obj = img.getProperty
- (SVGBrokenLinkProvider.SVG_BROKEN_LINK_DOCUMENT_PROPERTY);
- if ((obj != null) && (obj instanceof SVGDocument)) {
- // Ok so we are dealing with a broken link.
- return createSVGImageNode(ctx, e, bounds, (SVGDocument)obj);
- }
- node.setImage(img);
- Rectangle2D imgBounds = img.getBounds2D();
-
- // create the implicit viewBox for the raster image. The viewBox for a
- // raster image is the size of the image
- float [] vb = new float[4];
- vb[0] = 0; // x
- vb[1] = 0; // y
- vb[2] = (float)imgBounds.getWidth(); // width
- vb[3] = (float)imgBounds.getHeight(); // height
-
- // System.err.println("Bounds: " + bounds);
- // System.err.println("ImgB: " + imgBounds);
- // handles the 'preserveAspectRatio', 'overflow' and 'clip' and
- // sets the appropriate AffineTransform to the image node
- initializeViewport(e, node, vb, bounds);
-
- return node;
- }
-
- /**
- * Returns a GraphicsNode that represents a svg document as an image.
- *
- * @param ctx the bridge context
- * @param e the image element
- * @param bounds the bounds for this graphicsNode
- * @param imgDocument the SVG document that represents the image
- */
- protected static GraphicsNode createSVGImageNode(BridgeContext ctx,
- Element e,
- Rectangle2D bounds,
- SVGDocument imgDocument) {
-
- CompositeGraphicsNode result = new CompositeGraphicsNode();
-
- Rectangle2D r = CSSUtilities.convertEnableBackground(e);
- if (r != null) {
- result.setBackgroundEnable(r);
- }
-
- SVGSVGElement svgElement = imgDocument.getRootElement();
- GVTBuilder builder = new GVTBuilder();
- GraphicsNode node = builder.build(ctx, imgDocument);
- // HACK: remove the clip set by the SVGSVGElement as the overflow
- // and clip properties must be ignored. The clip will be set later
- // using the overflow and clip of the <image> element.
- node.setClip(null);
- result.getChildren().add(node);
-
- // create the implicit viewBox for the SVG image. The viewBox
- // for a SVG image is the viewBox of the outermost SVG element
- // of the SVG file
- String viewBox =
- svgElement.getAttributeNS(null, SVG_VIEW_BOX_ATTRIBUTE);
- float [] vb = ViewBox.parseViewBoxAttribute(e, viewBox);
-
- // handles the 'preserveAspectRatio', 'overflow' and 'clip' and sets
- // the appropriate AffineTransform to the image node
-
- // System.err.println("Bounds: " + bounds);
- // System.err.println("ViewBox: " + viewBox);
- initializeViewport(e, result, vb, bounds);
-
- return result;
- }
-
- /**
- * Initializes according to the specified element, the specified graphics
- * node with the specified bounds. This method takes into account the
- * 'viewBox', 'preserveAspectRatio', and 'clip' properties. According to
- * those properties, a AffineTransform and a clip is set.
- *
- * @param e the image element that defines the properties
- * @param node the graphics node
- * @param vb the implicit viewBox definition
- * @param bounds the bounds of the image element
- */
- protected static void initializeViewport(Element e,
- GraphicsNode node,
- float [] vb,
- Rectangle2D bounds) {
-
- float x = (float)bounds.getX();
- float y = (float)bounds.getY();
- float w = (float)bounds.getWidth();
- float h = (float)bounds.getHeight();
-
- AffineTransform at
- = ViewBox.getPreserveAspectRatioTransform(e, vb, w, h);
- // System.err.println("VP Affine: " + at);
- at.preConcatenate(AffineTransform.getTranslateInstance(x, y));
- node.setTransform(at);
-
- // 'overflow' and 'clip'
- Shape clip = null;
- if (CSSUtilities.convertOverflow(e)) { // overflow:hidden
- float [] offsets = CSSUtilities.convertClip(e);
- if (offsets == null) { // clip:auto
- clip = new Rectangle2D.Float(x, y, w, h);
- } else { // clip:rect(<x> <y> <w> <h>)
- // offsets[0] = top
- // offsets[1] = right
- // offsets[2] = bottom
- // offsets[3] = left
- clip = new Rectangle2D.Float(x+offsets[3],
- y+offsets[0],
- w-offsets[1]-offsets[3],
- h-offsets[2]-offsets[0]);
- }
- }
-
- if (clip != null) {
- try {
- at = at.createInverse(); // clip in user space
- Filter filter = node.getGraphicsNodeRable(true);
- clip = at.createTransformedShape(clip);
- node.setClip(new ClipRable8Bit(filter, clip));
- } catch (java.awt.geom.NoninvertibleTransformException ex) {}
- }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]