KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > gvt > svg12 > MultiResGraphicsNode


1 /*
2
3    Copyright 2002-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.gvt.svg12;
19
20 import java.awt.Dimension JavaDoc;
21 import java.awt.Graphics2D JavaDoc;
22 import java.awt.Shape JavaDoc;
23 import java.awt.geom.AffineTransform JavaDoc;
24 import java.awt.geom.Rectangle2D JavaDoc;
25 import java.lang.ref.SoftReference JavaDoc;
26
27 import org.apache.batik.bridge.BridgeContext;
28 import org.apache.batik.bridge.GVTBuilder;
29 import org.apache.batik.gvt.AbstractGraphicsNode;
30 import org.apache.batik.gvt.GraphicsNode;
31 import org.apache.batik.util.SVGConstants;
32 import org.w3c.dom.Element JavaDoc;
33
34 /**
35  * RasterRable This is used to wrap a Rendered Image back into the
36  * RenderableImage world.
37  *
38  * @author <a HREF="mailto:Thomas.DeWeese@Kodak.com">Thomas DeWeese</a>
39  * @version $Id: MultiResGraphicsNode.java,v 1.2 2005/03/27 08:58:35 cam Exp $
40  */

41 public class MultiResGraphicsNode
42     extends AbstractGraphicsNode implements SVGConstants {
43
44     SoftReference JavaDoc [] srcs;
45     Element JavaDoc [] srcElems;
46     Dimension JavaDoc [] minSz;
47     Dimension JavaDoc [] maxSz;
48     Rectangle2D JavaDoc bounds;
49
50     BridgeContext ctx;
51
52     Element JavaDoc multiImgElem;
53
54     public MultiResGraphicsNode(Element JavaDoc multiImgElem,
55                                 Rectangle2D JavaDoc bounds,
56                                 Element JavaDoc [] srcElems,
57                                 Dimension JavaDoc [] minSz,
58                                 Dimension JavaDoc [] maxSz,
59                                 BridgeContext ctx) {
60
61         this.multiImgElem = multiImgElem;
62         this.srcElems = new Element JavaDoc [srcElems.length];
63         this.minSz = new Dimension JavaDoc[srcElems.length];
64         this.maxSz = new Dimension JavaDoc[srcElems.length];
65         this.ctx = ctx;
66
67         for (int i=0; i<srcElems.length; i++) {
68             this.srcElems[i] = srcElems[i];
69             this.minSz[i] = minSz[i];
70             this.maxSz[i] = maxSz[i];
71         }
72
73         this.srcs = new SoftReference JavaDoc[srcElems.length];
74         this.bounds = bounds;
75     }
76
77     /**
78      * Paints this node without applying Filter, Mask, Composite, and clip.
79      *
80      * @param g2d the Graphics2D to use
81      */

82     public void primitivePaint(Graphics2D JavaDoc g2d) {
83         // get the current affine transform
84
AffineTransform JavaDoc at = g2d.getTransform();
85
86         double scx = Math.sqrt(at.getShearY()*at.getShearY()+
87                                at.getScaleX()*at.getScaleX());
88         double scy = Math.sqrt(at.getShearX()*at.getShearX()+
89                                at.getScaleY()*at.getScaleY());
90
91         GraphicsNode gn = null;
92         int idx =-1;
93         double w = bounds.getWidth()*scx;
94         double minDist = calcDist(w, minSz[0], maxSz[0]);
95         int minIdx = 0;
96         // System.err.println("Width: " + w);
97
for (int i=0; i<minSz.length; i++) {
98             double dist = calcDist(w, minSz[i], maxSz[i]);
99             // System.err.println("Dist: " + dist);
100
if (dist < minDist) {
101                 minDist = dist;
102                 minIdx = i;
103             }
104                 
105             if (((minSz[i] == null) || (w >= minSz[i].width)) &&
106                 ((maxSz[i] == null) || (w <= maxSz[i].width))) {
107                 // We have a range match
108
// System.err.println("Match: " + i + " " +
109
// minSz[i] + " -> " + maxSz[i]);
110
if ((idx == -1) || (minIdx == i)) {
111                     idx = i;
112                 }
113             }
114         }
115
116         if (idx == -1)
117             idx = minIdx;
118         gn = getGraphicsNode(idx);
119         if (gn == null) return;
120
121         // This makes sure that the image 'pushes out' to it's pixel
122
// bounderies.
123
Rectangle2D JavaDoc gnBounds = gn.getBounds();
124         if (gnBounds == null) return;
125
126         double gnDevW = gnBounds.getWidth()*scx;
127         double gnDevH = gnBounds.getHeight()*scy;
128         double gnDevX = gnBounds.getX()*scx;
129         double gnDevY = gnBounds.getY()*scy;
130         double gnDevX0, gnDevX1, gnDevY0, gnDevY1;
131         if (gnDevW < 0) {
132             gnDevX0 = gnDevX+gnDevW;
133             gnDevX1 = gnDevX;
134         } else {
135             gnDevX0 = gnDevX;
136             gnDevX1 = gnDevX+gnDevW;
137         }
138         if (gnDevH < 0) {
139             gnDevY0 = gnDevY+gnDevH;
140             gnDevY1 = gnDevY;
141         } else {
142             gnDevY0 = gnDevY;
143             gnDevY1 = gnDevY+gnDevH;
144         }
145         // This calculate the width/height in pixels given 'worst
146
// case' assessment.
147
gnDevW = (int)(Math.ceil(gnDevX1)-Math.floor(gnDevX0));
148         gnDevH = (int)(Math.ceil(gnDevY1)-Math.floor(gnDevY0));
149         scx = (gnDevW/gnBounds.getWidth())/scx;
150         scy = (gnDevH/gnBounds.getHeight())/scy;
151
152         // This scales things up slightly so our edges fall on device
153
// pixel boundries.
154
AffineTransform JavaDoc nat = g2d.getTransform();
155         nat = new AffineTransform JavaDoc(nat.getScaleX()*scx, nat.getShearY()*scx,
156                                  nat.getShearX()*scy, nat.getScaleY()*scy,
157                                  nat.getTranslateX(), nat.getTranslateY());
158         g2d.setTransform(nat);
159
160         // double sx = bounds.getWidth()/sizes[idx].getWidth();
161
// double sy = bounds.getHeight()/sizes[idx].getHeight();
162
// System.err.println("Scale: [" + sx + ", " + sy + "]");
163

164         gn.paint(g2d);
165     }
166
167     // This function can be tweaked to any extent. This is a very
168
// simple measure of 'goodness'. It has two main flaws as is,
169
// mostly in regards to distance calc with 'unbounded' ranges.
170
// First it doesn't punish if the distance is the wrong way on the
171
// unbounded range (so over a max by 10 is the same as under a max
172
// by 10) this is compensated by the absolute preference for
173
// matches 'in range' above. The other issue is that unbounded
174
// ranages tend to 'win' when the value is near the boundry point
175
// since they use distance from the boundry point rather than the
176
// middle of the range. As it is this seems to meet all the
177
// requirements of the SVG specification however.
178
public double calcDist(double loc, Dimension JavaDoc min, Dimension JavaDoc max) {
179         if (min == null) {
180             if (max == null)
181                 return 10E10; // very large number.
182
else
183                 return Math.abs(loc-max.width);
184         } else {
185             if (max == null)
186                 return Math.abs(loc-min.width);
187             else {
188                 double mid = (max.width+min.width)/2.0;
189                 return Math.abs(loc-mid);
190             }
191         }
192     }
193
194     /**
195      * Returns the bounds of the area covered by this node's primitive paint.
196      */

197     public Rectangle2D JavaDoc getPrimitiveBounds() {
198         return bounds;
199     }
200
201     public Rectangle2D JavaDoc getGeometryBounds(){
202         return bounds;
203     }
204
205     public Rectangle2D JavaDoc getSensitiveBounds(){
206         return bounds;
207     }
208
209     /**
210      * Returns the outline of this node.
211      */

212     public Shape JavaDoc getOutline() {
213         return bounds;
214     }
215
216     public GraphicsNode getGraphicsNode(int idx) {
217         if (srcs[idx] != null) {
218             Object JavaDoc o = srcs[idx].get();
219             if (o != null)
220                 return (GraphicsNode)o;
221         }
222         
223         try {
224             GVTBuilder builder = ctx.getGVTBuilder();
225             GraphicsNode gn;
226             gn = builder.build(ctx, srcElems[idx]);
227             srcs[idx] = new SoftReference JavaDoc(gn);
228             return gn;
229         } catch (Exception JavaDoc ex) { ex.printStackTrace(); }
230
231         return null;
232     }
233 }
234
235
Popular Tags