001/*
002 * SVG Salamander
003 * Copyright (c) 2004, Mark McKay
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or 
007 * without modification, are permitted provided that the following
008 * conditions are met:
009 *
010 *   - Redistributions of source code must retain the above 
011 *     copyright notice, this list of conditions and the following
012 *     disclaimer.
013 *   - Redistributions in binary form must reproduce the above
014 *     copyright notice, this list of conditions and the following
015 *     disclaimer in the documentation and/or other materials 
016 *     provided with the distribution.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
021 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
022 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
023 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
026 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
027 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
029 * OF THE POSSIBILITY OF SUCH DAMAGE. 
030 * 
031 * Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
032 * projects can be found at http://www.kitfox.com
033 *
034 * Created on April 21, 2005, 10:43 AM
035 */
036
037package com.kitfox.svg.app.beans;
038
039import com.kitfox.svg.*;
040import java.awt.*;
041import java.awt.geom.*;
042import java.net.*;
043import javax.swing.*;
044
045/**
046 *
047 * @author  kitfox
048 */
049public class SVGPanel extends JPanel
050{
051    public static final long serialVersionUID = 1;
052    public static final String PROP_AUTOSIZE = "PROP_AUTOSIZE";
053
054    SVGUniverse svgUniverse = SVGCache.getSVGUniverse();
055    
056    private boolean antiAlias;
057    
058//    private String svgPath;
059    URI svgURI;
060
061//    private boolean scaleToFit;
062    AffineTransform scaleXform = new AffineTransform();
063
064    public static final int AUTOSIZE_NONE = 0;
065    public static final int AUTOSIZE_HORIZ = 1;
066    public static final int AUTOSIZE_VERT = 2;
067    public static final int AUTOSIZE_BESTFIT = 3;
068    public static final int AUTOSIZE_STRETCH = 4;
069    private int autosize = AUTOSIZE_NONE;
070    
071    /** Creates new form SVGIcon */
072    public SVGPanel()
073    {
074        initComponents();
075    }
076        
077    public int getSVGHeight()
078    {
079        if (autosize == AUTOSIZE_VERT || autosize == AUTOSIZE_STRETCH 
080                || autosize == AUTOSIZE_BESTFIT)
081        {
082            return getPreferredSize().height;
083        }
084        
085        SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
086        if (diagram == null)
087        {
088            return 0;
089        }
090        return (int)diagram.getHeight();
091    }
092    
093    public int getSVGWidth()
094    {
095        if (autosize == AUTOSIZE_HORIZ || autosize == AUTOSIZE_STRETCH 
096                || autosize == AUTOSIZE_BESTFIT)
097        {
098            return getPreferredSize().width;
099        }
100        
101        SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
102        if (diagram == null)
103        {
104            return 0;
105        }
106        return (int)diagram.getWidth();
107    }
108    
109    public void paintComponent(Graphics gg)
110    {
111        super.paintComponent(gg);
112
113        Graphics2D g = (Graphics2D)gg.create();
114        paintComponent(g);
115        g.dispose();
116    }
117    
118    private void paintComponent(Graphics2D g)
119    {
120        Object oldAliasHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
121        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
122
123        
124        SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
125        if (diagram == null)
126        {
127            return;
128        }
129        
130        if (autosize == AUTOSIZE_NONE)
131        {
132            try
133            {
134                diagram.render(g);
135                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
136            }
137            catch (SVGException e)
138            {
139                throw new RuntimeException(e);
140            }
141            return;
142        }
143        
144        Dimension dim = getSize();
145        final int width = dim.width;
146        final int height = dim.height;
147            
148//        final Rectangle2D.Double rect = new Rectangle2D.Double();
149//        diagram.getViewRect(rect);
150        
151        double diaWidth = diagram.getWidth();
152        double diaHeight = diagram.getHeight();
153        
154        double scaleW = 1;
155        double scaleH = 1;
156        if (autosize == AUTOSIZE_BESTFIT)
157        {
158            scaleW = scaleH = (height / diaHeight < width / diaWidth) 
159                    ? height / diaHeight : width / diaWidth;
160        }
161        else if (autosize == AUTOSIZE_HORIZ)
162        {
163            scaleW = scaleH = width / diaWidth;
164        }
165        else if (autosize == AUTOSIZE_VERT)
166        {
167            scaleW = scaleH = height / diaHeight;
168        }
169        else if (autosize == AUTOSIZE_STRETCH)
170        {
171            scaleW = width / diaWidth;
172            scaleH = height / diaHeight;
173        }
174        scaleXform.setToScale(scaleW, scaleH);
175        
176        AffineTransform oldXform = g.getTransform();
177        g.transform(scaleXform);
178
179        try
180        {
181            diagram.render(g);
182        }
183        catch (SVGException e)
184        {
185            throw new RuntimeException(e);
186        }
187        
188        g.setTransform(oldXform);
189        
190        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
191    }
192    
193    public SVGUniverse getSvgUniverse()
194    {
195        return svgUniverse;
196    }
197
198    public void setSvgUniverse(SVGUniverse svgUniverse)
199    {
200        SVGUniverse old = this.svgUniverse;
201        this.svgUniverse = svgUniverse;
202        firePropertyChange("svgUniverse", old, svgUniverse);
203    }
204
205    public URI getSvgURI()
206    {
207        return svgURI;
208    }
209
210    public void setSvgURI(URI svgURI)
211    {
212        URI old = this.svgURI;
213        this.svgURI = svgURI;
214        firePropertyChange("svgURI", old, svgURI);
215    }
216    
217    /**
218     * Most resources your component will want to access will be resources on your classpath.  
219     * This method will interpret the passed string as a path in the classpath and use
220     * Class.getResource() to determine the URI of the SVG.
221     */
222    public void setSvgResourcePath(String resourcePath) throws SVGException
223    {
224        URI old = this.svgURI;
225        
226        try
227        {
228            svgURI = new URI(getClass().getResource(resourcePath).toString());
229//System.err.println("SVGPanel: new URI " + svgURI + " from path " + resourcePath);
230            
231            firePropertyChange("svgURI", old, svgURI);
232            
233            repaint();
234        }
235        catch (Exception e)
236        {
237            throw new SVGException("Could not resolve path " + resourcePath, e);
238//            svgURI = old;
239        }
240    }
241    
242    /**
243     * If this SVG document has a viewbox, if scaleToFit is set, will scale the viewbox to match the
244     * preferred size of this icon
245     * @deprecated 
246     * @return 
247     */
248    public boolean isScaleToFit()
249    {
250        return autosize == AUTOSIZE_STRETCH;
251    }
252    
253    /**
254     * @deprecated 
255     * @return 
256     */
257    public void setScaleToFit(boolean scaleToFit)
258    {
259        setAutosize(AUTOSIZE_STRETCH);
260//        boolean old = this.scaleToFit;
261//        this.scaleToFit = scaleToFit;
262//        firePropertyChange("scaleToFit", old, scaleToFit);
263    }
264    
265    /**
266     * @return true if antiAliasing is turned on.
267     * @deprecated
268     */
269    public boolean getUseAntiAlias()
270    {
271        return getAntiAlias();
272    }
273
274    /**
275     * @param antiAlias true to use antiAliasing.
276     * @deprecated
277     */
278    public void setUseAntiAlias(boolean antiAlias)
279    {
280        setAntiAlias(antiAlias);
281    }
282    
283    /**
284     * @return true if antiAliasing is turned on.
285     */
286    public boolean getAntiAlias()
287    {
288        return antiAlias;
289    }
290
291    /**
292     * @param antiAlias true to use antiAliasing.
293     */
294    public void setAntiAlias(boolean antiAlias)
295    {
296        boolean old = this.antiAlias;
297        this.antiAlias = antiAlias;
298        firePropertyChange("antiAlias", old, antiAlias);
299    }
300
301    /**
302     * @return the autosize
303     */
304    public int getAutosize()
305    {
306        return autosize;
307    }
308
309    /**
310     * @param autosize the autosize to set
311     */
312    public void setAutosize(int autosize)
313    {
314        int oldAutosize = this.autosize;
315        this.autosize = autosize;
316        firePropertyChange(PROP_AUTOSIZE, oldAutosize, autosize);
317    }
318    
319    /** This method is called from within the constructor to
320     * initialize the form.
321     * WARNING: Do NOT modify this code. The content of this method is
322     * always regenerated by the Form Editor.
323     */
324    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
325    private void initComponents()
326    {
327
328        setLayout(new java.awt.BorderLayout());
329
330    }
331    // </editor-fold>//GEN-END:initComponents
332    
333    
334    // Variables declaration - do not modify//GEN-BEGIN:variables
335    // End of variables declaration//GEN-END:variables
336
337    
338}