Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / org.gvsig.app.document.layout.app / org.gvsig.app.document.layout.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / fframes / FFramePicture.java @ 36648

History | View | Annotate | Download (14.2 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.app.project.documents.layout.fframes;
23

    
24
import java.awt.Dimension;
25
import java.awt.Graphics2D;
26
import java.awt.Image;
27
import java.awt.RenderingHints;
28
import java.awt.geom.AffineTransform;
29
import java.awt.geom.Rectangle2D;
30
import java.awt.image.BufferedImage;
31
import java.awt.image.ImagingOpException;
32
import java.io.File;
33

    
34
import javax.swing.ImageIcon;
35

    
36
import com.sun.jimi.core.Jimi;
37

    
38
import org.apache.batik.bridge.BridgeContext;
39
import org.apache.batik.bridge.DocumentLoader;
40
import org.apache.batik.bridge.GVTBuilder;
41
import org.apache.batik.bridge.UserAgentAdapter;
42
import org.apache.batik.bridge.ViewBox;
43
import org.apache.batik.gvt.GraphicsNode;
44
import org.apache.batik.gvt.renderer.StaticRenderer;
45
import org.w3c.dom.Document;
46
import org.w3c.dom.Element;
47
import org.w3c.dom.svg.SVGDocument;
48

    
49
import org.gvsig.andami.PluginServices;
50
import org.gvsig.andami.messages.NotificationManager;
51
import org.gvsig.compat.print.PrintAttributes;
52
import org.gvsig.fmap.geom.Geometry;
53
import org.gvsig.tools.ToolsLocator;
54
import org.gvsig.tools.dynobject.DynStruct;
55
import org.gvsig.tools.persistence.PersistenceManager;
56
import org.gvsig.tools.persistence.PersistentState;
57
import org.gvsig.tools.persistence.exception.PersistenceException;
58

    
59
/**
60
 * FFrame para introducir una imagen en el Layout o para dibujar sobre el
61
 * graphics un SVG.
62
 * 
63
 * @author Vicente Caballero Navarro
64
 */
65
public class FFramePicture extends FFrame {
66

    
67
    public static final String PERSISTENCE_DEFINITION_NAME = "FFramePicture";
68

    
69
    private static final String PATH_FIELD = "path";
70
    private static final String QUALITY_FIELD = "quality";
71
    private static final String VIEWING_FIELD = "viewing";
72

    
73
    protected static RenderingHints defaultRenderingHints;
74

    
75
    static {
76
        defaultRenderingHints = new RenderingHints(null);
77
        defaultRenderingHints.put(RenderingHints.KEY_ANTIALIASING,
78
            RenderingHints.VALUE_ANTIALIAS_ON);
79

    
80
        defaultRenderingHints.put(RenderingHints.KEY_INTERPOLATION,
81
            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
82
    }
83

    
84
    private static final int PRESENTACION = 0;
85
    private static final int ACTIVO = 1;
86
    private BufferedImage m_image = null;
87
    private int m_quality = PRESENTACION;
88
    private int m_viewing = ACTIVO;
89
    private String m_path = null;
90
    private boolean isSVG = false;
91
    private StaticRenderer renderer = new StaticRenderer();
92
    private Element elt;
93
    private GVTBuilder gvtBuilder = new GVTBuilder();
94
    private GraphicsNode gvtRoot = null;
95
    private BridgeContext ctx;
96

    
97
    /**
98
     * Creates a new FFramePicture object.
99
     */
100
    public FFramePicture() {
101
    }
102

    
103
    /**
104
     * M?todo que dibuja sobre el graphics que se le pasa como par?metro, seg?n
105
     * la transformada afin que se debe de aplicar y el rect?ngulo que se debe
106
     * de dibujar.
107
     * 
108
     * @param g
109
     *            Graphics
110
     * @param at
111
     *            Transformada afin.
112
     * @param rv
113
     *            rect?ngulo sobre el que hacer un clip.
114
     * @param imgBase
115
     *            Imagen para acelerar el dibujado.
116
     */
117
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D rv,
118
        BufferedImage imgBase) {
119
        Rectangle2D.Double r = getBoundingBox(at);
120
        g.rotate(Math.toRadians(getRotation()), r.x + (r.width / 2), r.y
121
            + (r.height / 2));
122

    
123
        double x = r.getMinX();
124
        double y = r.getMinY();
125
        double w = r.getWidth();
126
        double h = r.getHeight();
127

    
128
        if (intersects(rv, r) || w != 0 || h != 0) {
129
            if ((m_image == null) && !isSVG) { // Que no hay una imagen.
130
                drawEmpty(g);
131
            } else {
132
                if ((rv == null) || (getQuality() == PRESENTACION)) {
133
                    if (!isSVG) {
134
                        double scalex = w / m_image.getWidth(null);
135
                        double scaley = h / m_image.getHeight(null);
136
                        try {
137
                            AffineTransform xform =
138
                                AffineTransform
139
                                    .getScaleInstance(scalex, scaley);
140
                            AffineTransform xpos =
141
                                AffineTransform.getTranslateInstance(x, y);
142
                            xpos.concatenate(xform);
143
                            g.drawRenderedImage(m_image, xpos);
144
                        } catch (ImagingOpException e) {
145
                            NotificationManager.addError(
146
                                "Dibujando FFramePicture", e);
147
                        }
148
                    } else
149
                        if (isSVG) {
150
                            try {
151
                                if (r != null) {
152
                                    drawSVG(g, r, rv);
153
                                }
154
                            } catch (OutOfMemoryError e) {
155
                                NotificationManager.addError(
156
                                    "Dibujando SVG FFramePicture", e);
157
                            } catch (IllegalArgumentException e) {
158
                                NotificationManager.addError(
159
                                    "Dibujando SVG FFramePicture", e);
160
                            }
161
                        }
162
                    System.gc();
163
                } else {
164
                    drawDraft(g);
165
                }
166
            }
167
        }
168

    
169
        g.rotate(Math.toRadians(-getRotation()), r.x + (r.width / 2), r.y
170
            + (r.height / 2));
171
    }
172

    
173
    /**
174
     * Dibuja SVG sobre el Graphics que se pasa como par?metro.
175
     * 
176
     * @param g
177
     *            Graphics
178
     * @param rect
179
     *            rect?ngulo que ocupa.
180
     * @param rv
181
     *            Rect?ngulo que forma la parte visible del Layout.
182
     */
183
    private void drawSVG(Graphics2D g, Rectangle2D rect, Rectangle2D rv) {
184
        if ((rv == null) || rv.contains(rect)) {
185
            AffineTransform ataux = new AffineTransform();
186

    
187
            ataux.translate(rect.getX(), rect.getY());
188

    
189
            try {
190
                ataux.concatenate(ViewBox.getViewTransform(null, elt,
191
                    (float) rect.getWidth(), (float) rect.getHeight(), ctx));
192
                gvtRoot.setTransform(ataux);
193
            } catch (Exception e) {
194
                // TODO: handle exception
195
            }
196
        } else {
197
            AffineTransform ataux = new AffineTransform();
198

    
199
            ataux.translate(rect.getX(), rect.getY());
200
            ataux.concatenate(ViewBox.getViewTransform(null, elt,
201
                (float) rect.getWidth(), (float) rect.getHeight(), ctx));
202

    
203
            gvtRoot.setTransform(ataux);
204
        }
205

    
206
        RenderingHints renderingHints = defaultRenderingHints;
207
        g.setRenderingHints(renderingHints);
208

    
209
        if (gvtRoot != null) {
210
            gvtRoot.paint(g);
211
        }
212
    }
213

    
214
    /**
215
     * Rellena la calidad seg?n el entero que se pasa como par?metro.
216
     * 
217
     * @param q
218
     *            entero que representa el tipo de calidad elegido.
219
     */
220
    public void setQuality(int q) {
221
        m_quality = q;
222
    }
223

    
224
    /**
225
     * Devuelve la calidad que est? seleccionada.
226
     * 
227
     * @return entero que representa la calidad seleccionada.
228
     */
229
    public int getQuality() {
230
        return m_quality;
231
    }
232

    
233
    /**
234
     * Devuelve un entero que representa la forma en que se actualiza la vista.
235
     * 
236
     * @return forma que se actualiza la vista.
237
     */
238
    public int getViewing() {
239
        return m_viewing;
240
    }
241

    
242
    /**
243
     * Rellena la forma de actualizar la vista.
244
     * 
245
     * @param v
246
     *            entero que representa la forma de actualizar la vista.
247
     */
248
    public void setViewing(int v) {
249
        m_viewing = v;
250
    }
251

    
252
    /**
253
     * Rellena el nombre de la imagen.
254
     * 
255
     * @param path
256
     *            nombre de la imagen.
257
     */
258
    public void setPath(String path) {
259
        m_path = path;
260
    }
261

    
262
    /**
263
     * Devuelve la ruta del fichero.
264
     * 
265
     * @return String
266
     */
267
    public String getPath() {
268
        return m_path;
269
    }
270

    
271
    /**
272
     * Rellena la imagen.
273
     * 
274
     * @param image
275
     */
276
    public void setImage(BufferedImage image) {
277
        m_image = image;
278
    }
279

    
280
    /**
281
     * Devuelve la dimensi?n dela imagen.
282
     * 
283
     * @param file
284
     *            Nombre del fichero donde se encuentra la imagen.
285
     * 
286
     * @return DOCUMENT ME!
287
     */
288
    public Dimension getBound(String file) {
289
        Image img = load(file);
290

    
291
        if (isSVG) {
292
            return new Dimension(100, 100);
293
        }
294

    
295
        if (img == null) {
296
            return new Dimension((int) getBoundingBox(null).getWidth(),
297
                (int) getBoundingBox(null).getHeight());
298
        }
299

    
300
        return new Dimension(img.getWidth(null), img.getHeight(null));
301
    }
302

    
303
    /**
304
     * Carga el contnido del fichero.
305
     * 
306
     * @param file
307
     *            Nombre del fichero a cargar.
308
     * 
309
     * @return Imagen
310
     */
311
    public Image load(String file) {
312
        if (file == null) {
313
            return null;
314
        }
315
        ImageIcon tmpIcon = null;
316
        File f = new File(file);
317
        if (file == null || !f.exists()) {
318
            return null;
319
        }
320
        setPath(file);
321
        String iString = file.toLowerCase();
322

    
323
        if (iString.endsWith("jpg") || iString.endsWith("jpeg")
324
            || iString.endsWith("gif")) {
325
            tmpIcon = new ImageIcon(Jimi.getImage(file, Jimi.VIRTUAL_MEMORY)); // ((File)main.allImages.elementAt(x)).getAbsolutePath());
326
        } else
327
            if (iString.endsWith("png") || iString.endsWith("tif")
328
                || iString.endsWith("ico") || iString.endsWith("xpm")
329
                || iString.endsWith("bmp")) {
330
                tmpIcon =
331
                    new ImageIcon(Jimi.getImage(file, Jimi.VIRTUAL_MEMORY)); // new
332
                                                                             // ImageIcon(f.getPath());
333
            } else
334
                if (iString.endsWith("svg")) {
335
                    isSVG = true;
336
                    obtainStaticRenderer(new File(file));
337
                } else {
338
                    tmpIcon = new ImageIcon(file);
339
                }
340

    
341
        if (!isSVG && (tmpIcon != null)) {
342
            Image image = tmpIcon.getImage();
343

    
344
            if (image.getWidth(null) == -1 || image.getHeight(null) == -1) {
345
                NotificationManager.showMessageError(
346
                    PluginServices.getText(this, "unsupported_format"),
347
                    new Exception());
348
                return null;
349
            }
350

    
351
            BufferedImage bi =
352
                new BufferedImage(image.getWidth(null), image.getHeight(null),
353
                    BufferedImage.TYPE_INT_ARGB);
354
            Graphics2D biContext = bi.createGraphics();
355
            biContext.drawImage(image, 0, 0, null);
356

    
357
            setImage(bi);
358

    
359
            return image;
360
        }
361

    
362
        return null;
363
    }
364

    
365
    /**
366
     * Obtiene el renderer para svg a partir del svg.
367
     * 
368
     * @param file
369
     *            Nombre del fichero.
370
     */
371
    private void obtainStaticRenderer(File file) {
372
        try {
373
            UserAgentAdapter userAgent = new UserAgentAdapter();
374
            DocumentLoader loader = new DocumentLoader(userAgent);
375
            BridgeContext ctx = new BridgeContext(userAgent, loader);
376
            Document svgDoc = loader.loadDocument(file.toURI().toString());
377
            gvtRoot = gvtBuilder.build(ctx, svgDoc);
378
            renderer.setTree(gvtRoot);
379
            elt = ((SVGDocument) svgDoc).getRootElement();
380
            ctx = new BridgeContext(userAgent, loader);
381
        } catch (Exception ex) {
382
            ex.printStackTrace();
383
        }
384
    }
385

    
386
    /**
387
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNameFFrame()
388
     */
389
    public String getNameFFrame() {
390
        return PluginServices.getText(this, "imagen") + num;
391
    }
392

    
393
    public String getName() {
394
        return PERSISTENCE_DEFINITION_NAME;
395
    }
396

    
397
    public void initialize() {
398
        // TODO Auto-generated method stub
399

    
400
    }
401

    
402
    public void cloneActions(IFFrame frame) {
403
        m_image = null;
404
    }
405

    
406
    public void print(Graphics2D g, AffineTransform at, Geometry geom,
407
        PrintAttributes properties) {
408
        draw(g, at, null, null);
409
    }
410

    
411
    public static void registerPersistent() {
412
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
413
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
414
            DynStruct definition =
415
                manager.addDefinition(FFramePicture.class,
416
                    PERSISTENCE_DEFINITION_NAME,
417
                    "FFramePicture persistence definition", null, null);
418

    
419
            definition.extend(manager
420
                .getDefinition(FFrame.PERSISTENCE_DEFINITION_NAME));
421

    
422
            definition.addDynFieldString(PATH_FIELD).setMandatory(true);
423
            definition.addDynFieldInt(QUALITY_FIELD).setMandatory(true);
424
            definition.addDynFieldInt(VIEWING_FIELD).setMandatory(true);
425
        }
426
    }
427

    
428
    @Override
429
    public void loadFromState(PersistentState state)
430
        throws PersistenceException {
431
        super.loadFromState(state);
432
        m_path = state.getString(PATH_FIELD);
433
        m_quality = state.getInt(QUALITY_FIELD);
434
        m_viewing = state.getInt(VIEWING_FIELD);
435
        load(m_path);
436
    }
437

    
438
    @Override
439
    public void saveToState(PersistentState state) throws PersistenceException {
440
        super.saveToState(state);
441
        state.set(PATH_FIELD, m_path);
442
        state.set(QUALITY_FIELD, m_quality);
443
        state.set(VIEWING_FIELD, m_viewing);
444
    }
445
}