Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / project / documents / layout / fframes / FFramePicture.java @ 38372

History | View | Annotate | Download (15.4 KB)

1
/*
2
 * Created on 20-feb-2004
3
 *
4
 */
5
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
6
 *
7
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
22
 *
23
 * For more information, contact:
24
 *
25
 *  Generalitat Valenciana
26
 *   Conselleria d'Infraestructures i Transport
27
 *   Av. Blasco Ib??ez, 50
28
 *   46010 VALENCIA
29
 *   SPAIN
30
 *
31
 *      +34 963862235
32
 *   gvsig@gva.es
33
 *      www.gvsig.gva.es
34
 *
35
 *    or
36
 *
37
 *   IVER T.I. S.A
38
 *   Salamanca 50
39
 *   46005 Valencia
40
 *   Spain
41
 *
42
 *   +34 963163400
43
 *   dac@iver.es
44
 */
45
package com.iver.cit.gvsig.project.documents.layout.fframes;
46

    
47
import java.awt.Dimension;
48
import java.awt.Graphics2D;
49
import java.awt.Image;
50
import java.awt.RenderingHints;
51
import java.awt.geom.AffineTransform;
52
import java.awt.geom.NoninvertibleTransformException;
53
import java.awt.geom.Rectangle2D;
54
import java.awt.image.BufferedImage;
55
import java.awt.image.ImagingOpException;
56
import java.io.File;
57

    
58
import javax.print.attribute.PrintRequestAttributeSet;
59
import javax.swing.ImageIcon;
60

    
61
import org.apache.batik.bridge.BridgeContext;
62
import org.apache.batik.bridge.DocumentLoader;
63
import org.apache.batik.bridge.GVTBuilder;
64
import org.apache.batik.bridge.UserAgentAdapter;
65
import org.apache.batik.bridge.ViewBox;
66
import org.apache.batik.gvt.GraphicsNode;
67
import org.apache.batik.gvt.renderer.StaticRenderer;
68
import org.gvsig.tools.file.PathGenerator;
69
import org.w3c.dom.Document;
70
import org.w3c.dom.Element;
71
import org.w3c.dom.svg.SVGDocument;
72

    
73
import com.iver.andami.PluginServices;
74
import com.iver.andami.messages.NotificationManager;
75
import com.iver.cit.gvsig.fmap.core.FShape;
76
import com.iver.cit.gvsig.project.documents.exceptions.SaveException;
77
import com.iver.cit.gvsig.project.documents.layout.fframes.gui.dialogs.FFramePictureDialog;
78
import com.iver.cit.gvsig.project.documents.layout.fframes.gui.dialogs.IFFrameDialog;
79
import com.iver.cit.gvsig.project.documents.layout.gui.Layout;
80
import com.iver.utiles.XMLEntity;
81
import com.sun.jimi.core.Jimi;
82

    
83

    
84
/**
85
 * FFrame para introducir una imagen en el Layout o para dibujar sobre el
86
 * graphics un SVG.
87
 *
88
 * @author Vicente Caballero Navarro
89
 */
90
public class FFramePicture extends FFrame {
91
    protected static RenderingHints defaultRenderingHints;
92

    
93
    static {
94
        defaultRenderingHints = new RenderingHints(null);
95
        defaultRenderingHints.put(RenderingHints.KEY_ANTIALIASING,
96
            RenderingHints.VALUE_ANTIALIAS_ON);
97

    
98
        defaultRenderingHints.put(RenderingHints.KEY_INTERPOLATION,
99
            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
100
    }
101

    
102
    private static final int PRESENTACION = 0;
103
    private static final int ACTIVO = 1;
104
    private BufferedImage m_image = null;
105
    private int m_quality = PRESENTACION;
106
    private int m_viewing = ACTIVO;
107
    private String m_path = null;
108
    private boolean isSVG = false;
109
    private StaticRenderer renderer = new StaticRenderer();
110
    private Element elt;
111
    private GVTBuilder gvtBuilder = new GVTBuilder();
112
    private GraphicsNode gvtRoot = null;
113
    private BridgeContext ctx;
114

    
115
    /**
116
     * Creates a new FFramePicture object.
117
     */
118
    public FFramePicture() {
119
    }
120

    
121
    /**
122
     * M?todo que dibuja sobre el graphics que se le pasa como par?metro, seg?n
123
     * la transformada afin que se debe de aplicar y el rect?ngulo que se debe
124
     * de dibujar.
125
     *
126
     * @param g Graphics
127
     * @param at Transformada afin.
128
     * @param rv rect?ngulo sobre el que hacer un clip.
129
     * @param imgBase Imagen para acelerar el dibujado.
130
     */
131
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D rv,
132
        BufferedImage imgBase) {
133
        Rectangle2D.Double r = getBoundingBox(at);
134
        g.rotate(Math.toRadians(getRotation()), r.x + (r.width / 2),
135
            r.y + (r.height / 2));
136

    
137
        double x = r.getMinX();
138
        double y = r.getMinY();
139
        double w = r.getWidth();
140
        double h = r.getHeight();
141

    
142
        if (intersects(rv, r)|| w!=0 || h!=0) {
143
            if ((m_image == null) && !isSVG) { //Que no hay una imagen.
144
                drawEmpty(g);
145
            } else {
146
                if ((rv == null) || (getQuality() == PRESENTACION)) {
147
                    if (!isSVG) {
148
                        double scalex = w / m_image.getWidth(null);
149
                        double scaley = h / m_image.getHeight(null);
150
                       try {
151
                        AffineTransform xform = AffineTransform.getScaleInstance(scalex,
152
                                scaley);
153
                        AffineTransform xpos = AffineTransform.getTranslateInstance(x,
154
                                y);
155
                        xpos.concatenate(xform);
156
                        g.drawRenderedImage(m_image, xpos);
157
                       }catch (ImagingOpException e) {
158
                               NotificationManager.addError("Dibujando FFramePicture", e);
159
                       }
160
                    } else if (isSVG) {
161
                        try {
162
                            if (r != null) {
163
                                drawSVG(g, r, rv);
164
                            }
165
                        } catch (OutOfMemoryError e) {
166
                                 NotificationManager.addError("Dibujando SVG FFramePicture", e);
167
                        } catch (IllegalArgumentException e) {
168
                                 NotificationManager.addError("Dibujando SVG FFramePicture", e);
169
                        }
170
                    }
171
                    System.gc();
172
                } else {
173
                    drawDraft(g);
174
                }
175
            }
176
        }
177

    
178
        g.rotate(Math.toRadians(-getRotation()), r.x + (r.width / 2),
179
            r.y + (r.height / 2));
180
    }
181

    
182
    /**
183
     * Dibuja SVG sobre el Graphics que se pasa como par?metro.
184
     *
185
     * @param g Graphics
186
     * @param rect rect?ngulo que ocupa.
187
     * @param rv Rect?ngulo que forma la parte visible del Layout.
188
     */
189
    private void drawSVG(Graphics2D g, Rectangle2D rect, Rectangle2D rv) {
190
            if (rv!=null && !rv.intersects(rect))
191
                    return;
192
            if (gvtRoot != null) {
193
                     //Si no tiene atributo "viewBox" el m?todo ViewBox.getViewTransform devuelve una transformaci?n que no hace nada
194
                    if (elt.hasAttribute("viewBox")) {
195
                            AffineTransform ataux = new AffineTransform();
196

    
197
                            ataux.translate(rect.getX(), rect.getY());
198

    
199
                            try {
200
                                    ataux.concatenate(ViewBox.getViewTransform(null, elt,
201
                                                    (float) rect.getWidth(), (float) rect.getHeight(), ctx));
202
                                    gvtRoot.setTransform(ataux);
203
                            } catch (Exception e) {
204
                                    // TODO: handle exception
205
                            }
206
                    } else {
207
                            Rectangle2D bounds = gvtRoot.getBounds();
208
                            AffineTransform ataux = new AffineTransform();
209
                            ataux.translate(rect.getX(), rect.getY());
210
                            double scaleX = 1;
211
                            double scaleY = 1;
212
                            //FIXME: Se podr?a mejorar el dibujado si parsearamos el atributo "preserveAspectRatio"
213
                            // seg?n http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute
214
                            // pero de momento me limito preservar el ratio de aspecto o no. 
215
                            if(elt.getAttribute("preserveAspectRatio").compareToIgnoreCase("")!=0){
216
                                    scaleX = scaleY = Math.min(rect.getWidth()/bounds.getWidth(),
217
                                                    rect.getHeight()/bounds.getHeight());
218

    
219
                            } else {
220
                                    scaleX = rect.getWidth()/bounds.getWidth() ;
221
                                    scaleY = rect.getHeight()/bounds.getHeight();
222
                            }
223
                            ataux.concatenate(AffineTransform.getScaleInstance(
224
                                            scaleX,
225
                                            scaleY));
226
                            RenderingHints renderingHints = defaultRenderingHints;
227
                            g.setRenderingHints(renderingHints);
228
                            gvtRoot.setTransform(ataux);
229
                    }
230

    
231
                    gvtRoot.paint(g);
232
            }
233
    }
234

    
235
    /**
236
     * Rellena la calidad seg?n el entero que se pasa como par?metro.
237
     *
238
     * @param q entero que representa el tipo de calidad elegido.
239
     */
240
    public void setQuality(int q) {
241
        m_quality = q;
242
    }
243

    
244
    /**
245
     * Devuelve la calidad que est? seleccionada.
246
     *
247
     * @return entero que representa la calidad seleccionada.
248
     */
249
    public int getQuality() {
250
        return m_quality;
251
    }
252

    
253
    /**
254
     * Devuelve un entero que representa la forma en que se actualiza la vista.
255
     *
256
     * @return forma que se actualiza la vista.
257
     */
258
    public int getViewing() {
259
        return m_viewing;
260
    }
261

    
262
    /**
263
     * Rellena la forma de actualizar la vista.
264
     *
265
     * @param v entero que representa la forma de actualizar la vista.
266
     */
267
    public void setViewing(int v) {
268
        m_viewing = v;
269
    }
270

    
271
    /**
272
     * Rellena el nombre de la imagen.
273
     *
274
     * @param path nombre de la imagen.
275
     */
276
    public void setPath(String path) {
277
        m_path = path;
278
    }
279

    
280
    /**
281
     * Devuelve la ruta del fichero.
282
     *
283
     * @return String
284
     */
285
    public String getPath() {
286
        return m_path;
287
    }
288

    
289
    /**
290
     * Rellena la imagen.
291
     *
292
     * @param image
293
     */
294
    public void setImage(BufferedImage image) {
295
        m_image = image;
296
    }
297

    
298
    /**
299
     * DOCUMENT ME!
300
     *
301
     * @return DOCUMENT ME!
302
     *
303
     * @throws SaveException
304
     *
305
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#getXMLEntity()
306
     */
307
    public XMLEntity getXMLEntity() throws SaveException {
308
        XMLEntity xml = super.getXMLEntity();
309

    
310
        try {
311
            xml.putProperty("m_path", PathGenerator.getInstance().getPath(m_path));
312
            xml.putProperty("m_quality", m_quality);
313
            xml.putProperty("m_viewing", m_viewing);
314
        } catch (Exception e) {
315
            throw new SaveException(e, this.getClass().getName());
316
        }
317

    
318
        return xml;
319
    }
320

    
321
    /**
322
     * Devuelve la dimensi?n dela imagen.
323
     *
324
     * @param file Nombre del fichero donde se encuentra la imagen.
325
     *
326
     * @return DOCUMENT ME!
327
     */
328
    public Dimension getBound(String file) {
329
        Image img = load(file);
330

    
331
        if (isSVG) {
332
            return new Dimension(100, 100);
333
        }
334

    
335
        if (img == null) {
336
            return new Dimension((int) getBoundingBox(null).getWidth(),
337
                (int) getBoundingBox(null).getHeight());
338
        }
339

    
340
        return new Dimension(img.getWidth(null), img.getHeight(null));
341
    }
342

    
343
    /**
344
     * Carga el contnido del fichero.
345
     *
346
     * @param file Nombre del fichero a cargar.
347
     *
348
     * @return Imagen
349
     */
350
    public Image load(String file) {
351
        if (file==null)
352
                return null;
353
            ImageIcon tmpIcon = null;
354
        File f=new File(file);
355
        if (file == null || !f.exists()) {
356
            return null;
357
        }
358

    
359
        if (new File(file).isFile()) {
360
            setPath(file);
361
            String iString = file.toLowerCase();
362

    
363
            if (iString.endsWith("jpg") || iString.endsWith("jpeg") ||
364
                    iString.endsWith("gif")) {
365
                tmpIcon = new ImageIcon(Jimi.getImage(file, Jimi.VIRTUAL_MEMORY)); //((File)main.allImages.elementAt(x)).getAbsolutePath());
366
            } else if (iString.endsWith("png") || iString.endsWith("tif") ||
367
                    iString.endsWith("ico") || iString.endsWith("xpm") ||
368
                    iString.endsWith("bmp")) {
369
                tmpIcon = new ImageIcon(Jimi.getImage(file, Jimi.VIRTUAL_MEMORY)); //new ImageIcon(f.getPath());
370
            } else if (iString.endsWith("svg")) {
371
                isSVG = true;
372
                obtainStaticRenderer(new File(file));
373
            }else {
374
                tmpIcon=new ImageIcon(file);
375
            }
376
        }
377

    
378
        if (!isSVG && (tmpIcon != null)) {
379
            Image image = tmpIcon.getImage();
380

    
381
            if (image.getWidth(null)==-1 || image.getHeight(null)==-1){
382
                    NotificationManager.showMessageError(PluginServices.getText(this,"unsupported_format"), new Exception());
383
                    return null;
384
            }
385
            BufferedImage bi = new BufferedImage(image.getWidth(null),
386
                    image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
387
            Graphics2D biContext = bi.createGraphics();
388
            biContext.drawImage(image, 0, 0, null);
389

    
390
            setImage(bi);
391

    
392
            return image;
393
        }
394

    
395
        return null;
396
    }
397

    
398
    /**
399
     * Obtiene el renderer para svg a partir del svg.
400
     *
401
     * @param file Nombre del fichero.
402
     */
403
    private void obtainStaticRenderer(File file) {
404
        try {
405
            UserAgentAdapter userAgent = new UserAgentAdapter();
406
            DocumentLoader loader = new DocumentLoader(userAgent);
407
            BridgeContext ctx = new BridgeContext(userAgent, loader);
408
            Document svgDoc = loader.loadDocument(file.toURI().toString());
409
            gvtRoot = gvtBuilder.build(ctx, svgDoc);
410
            renderer.setTree(gvtRoot);
411
            elt = ((SVGDocument) svgDoc).getRootElement();
412
            elt.getNodeName();
413
            elt.getNodeType();
414
            elt.getNodeValue();
415
            ctx =  new BridgeContext(userAgent, loader);
416
        } catch (Exception ex) {
417
            ex.printStackTrace();
418
        }
419
    }
420

    
421
    /**
422
     * Incorpora los atributos del XMLEntity en el objeto actual.
423
     *
424
     * @param xml XMLEntity
425
     * @param l Referencia al Layout.
426
     */
427
    public void setXMLEntity03(XMLEntity xml, Layout l) {
428
        if (xml.getIntProperty("m_Selected") != 0) {
429
            this.setSelected(true);
430
        } else {
431
            this.setSelected(false);
432
        }
433

    
434
        this.m_path = PathGenerator.getInstance().getAbsolutePath(xml.getStringProperty("m_path"));
435

    
436
        try {
437
            load(this.m_path);
438
        } catch (Exception ex) {
439
            NotificationManager.addError("Excepci?n :", ex);
440
        }
441

    
442
        this.m_quality = xml.getIntProperty("m_quality");
443
        this.m_viewing = xml.getIntProperty("m_viewing");
444
    }
445

    
446
    /**
447
     * Incorpora los atributos del XMLEntity en el objeto actual.
448
     *
449
     * @param xml XMLEntity
450
     */
451
    public void setXMLEntity(XMLEntity xml) {
452
        if (xml.getIntProperty("m_Selected") != 0) {
453
            this.setSelected(true);
454
        } else {
455
            this.setSelected(false);
456
        }
457

    
458
        this.m_path = PathGenerator.getInstance().getAbsolutePath(xml.getStringProperty("m_path"));
459

    
460
        try {
461
            load(this.m_path);
462
        } catch (Exception ex) {
463
            NotificationManager.addError("Excepci?n :", ex);
464
        }
465

    
466
        this.m_quality = xml.getIntProperty("m_quality");
467
        this.m_viewing = xml.getIntProperty("m_viewing");
468
        setRotation(xml.getDoubleProperty("m_rotation"));
469
    }
470

    
471
    /**
472
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#getNameFFrame()
473
     */
474
    public String getNameFFrame() {
475
        return PluginServices.getText(this, "imagen")+ num;
476
    }
477

    
478

    
479
    public void initialize() {
480
        // TODO Auto-generated method stub
481

    
482
    }
483

    
484
    public void cloneActions(IFFrame frame) {
485
       m_image=null;
486

    
487
    }
488

    
489
        public IFFrameDialog getPropertyDialog() {
490
                return new FFramePictureDialog(getLayout(), this);
491
        }
492

    
493
        public void print(Graphics2D g, AffineTransform at, FShape shape, PrintRequestAttributeSet properties) {
494
                draw(g, at, null, null);
495
        }
496
}