001/* An icon that displays a specified java.awt.Image.
002
003 Copyright (c) 2009-2016 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.vergil.pdfrenderer;
029
030import java.awt.Graphics2D;
031import java.awt.Image;
032import java.awt.Rectangle;
033import java.awt.Toolkit;
034import java.awt.geom.Rectangle2D;
035import java.net.URL;
036
037import com.sun.pdfview.PDFPage;
038import com.sun.pdfview.PDFRenderer;
039
040import diva.canvas.Figure;
041import diva.canvas.toolbox.PaintedFigure;
042import diva.util.java2d.PaintedObject;
043import ptolemy.kernel.util.IllegalActionException;
044import ptolemy.kernel.util.NameDuplicationException;
045import ptolemy.kernel.util.NamedObj;
046import ptolemy.kernel.util.Workspace;
047import ptolemy.vergil.icon.DynamicEditorIcon;
048
049///////////////////////////////////////////////////////////////////
050//// PDFIcon
051
052/**
053 An icon that displays a specified PDF page.
054
055 <p> This class uses pdf-renderer, obtainable from <a
056 href="https://pdf-renderer.dev.java.net/">https://pdf-renderer.dev.java.net/</a>.
057 This is an "an open source, all Java library which renders PDF
058 documents to the screen using Java2D." By using this icon, an actor
059 or attribute in Vergil can be defined by a PDF file.  Using this icon
060 requires that PDFRenderer.jar in the classpath, it is usually found
061 in $PTII/lib/PDFRenderer.jar.</p>
062
063 @author Edward A. Lee
064 @version $Id$
065 @since Ptolemy II 8.0
066 @Pt.ProposedRating Yellow (eal)
067 @Pt.AcceptedRating Red (johnr)
068 */
069public class PDFIcon extends DynamicEditorIcon {
070    /** Create a new icon with the given name in the given container.
071     *  @param container The container.
072     *  @param name The name of the attribute.
073     *  @exception IllegalActionException If the attribute is not of an
074     *   acceptable class for the container.
075     *  @exception NameDuplicationException If the name coincides with
076     *   an attribute already in the container.
077     */
078    public PDFIcon(NamedObj container, String name)
079            throws IllegalActionException, NameDuplicationException {
080        super(container, name);
081    }
082
083    ///////////////////////////////////////////////////////////////////
084    ////                         public methods                    ////
085
086    /** Clone the object into the specified workspace. The new object is
087     *  <i>not</i> added to the directory of that workspace (you must do this
088     *  yourself if you want it there).
089     *  The result is an object with no container.
090     *  @param workspace The workspace for the cloned object.
091     *  @exception CloneNotSupportedException Not thrown in this base class
092     *  @return The new Attribute.
093     */
094    @Override
095    public Object clone(Workspace workspace) throws CloneNotSupportedException {
096        PDFIcon newObject = (PDFIcon) super.clone(workspace);
097        newObject._page = null;
098        return newObject;
099    }
100
101    /** Create a new default background figure, which is an instance
102     *  of PDFFigure.
103     *  @return A figure representing the specified PDF page.
104     */
105    @Override
106    public Figure createBackgroundFigure() {
107        PaintedFigure newFigure = new PaintedFigure();
108        newFigure.add(new PDFPaintedObject());
109        return newFigure;
110    }
111
112    /** Specify an PDF page to display.
113     *  @param page The PDF page to display.
114     */
115    public void setPage(PDFPage page) {
116        _page = page;
117    }
118
119    /** Specify a scaling percentage of the PDF page.
120     *  @param scalePercentage The scale percentage.
121     */
122    public void setScale(double scalePercentage) {
123        _scale = scalePercentage / 100.0;
124    }
125
126    ///////////////////////////////////////////////////////////////////
127    ////                         private variables                 ////
128
129    /** The PDF page to render. */
130    private PDFPage _page;
131
132    // The scale percentage.
133    private double _scale = 1.0;
134
135    ///////////////////////////////////////////////////////////////////
136    ////                         inner classes                     ////
137
138    private class PDFPaintedObject implements PaintedObject {
139
140        @Override
141        public Rectangle2D getBounds() {
142            if (_page == null) {
143                return new Rectangle2D.Double(0.0, 0.0, 40.0, 40.0);
144            }
145            Rectangle2D boundingBox = _page.getBBox();
146            return new Rectangle2D.Double(boundingBox.getX(),
147                    boundingBox.getY(), boundingBox.getWidth() * _scale,
148                    boundingBox.getHeight() * _scale);
149        }
150
151        @Override
152        public void paint(Graphics2D graphics) {
153            if (_page == null) {
154                // No page. Paint an error image.
155                URL url = getClass()
156                        .getResource("/diva/canvas/toolbox/errorImage.gif");
157                Toolkit tk = Toolkit.getDefaultToolkit();
158                Image image = tk.getImage(url);
159                graphics.drawImage(image, null, null);
160
161                return;
162            }
163            Rectangle2D boundingBox = _page.getBBox();
164            PDFRenderer renderer = new PDFRenderer(_page, graphics,
165                    new Rectangle(0, 0, (int) (boundingBox.getWidth() * _scale),
166                            (int) (boundingBox.getHeight() * _scale)),
167                    null, // No clipping.
168                    null // Transparent background.
169            );
170            try {
171                _page.waitForFinish();
172            } catch (InterruptedException e) {
173                // What can we do here?
174                e.printStackTrace();
175            }
176            renderer.run();
177        }
178    }
179}