Package gov.nasa.arc.mct.graphics.view

Source Code of gov.nasa.arc.mct.graphics.view.SVGRasterizer$SVGRasterizerListener

/*******************************************************************************
* Mission Control Technologies, Copyright (c) 2009-2012, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* The MCT platform is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* MCT includes source code licensed under additional open source licenses. See
* the MCT Open Source Licenses file included with this distribution or the About
* MCT Licenses dialog available at runtime from the MCT Help menu for additional
* information.
*******************************************************************************/
package gov.nasa.arc.mct.graphics.view;

import java.awt.Dimension;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.renderer.ConcreteImageRendererFactory;
import org.apache.batik.gvt.renderer.ImageRenderer;
import org.apache.batik.swing.gvt.GVTTreeRenderer;
import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
import org.apache.batik.swing.gvt.GVTTreeRendererListener;
import org.apache.batik.swing.svg.GVTTreeBuilder;
import org.apache.batik.swing.svg.GVTTreeBuilderEvent;
import org.apache.batik.swing.svg.GVTTreeBuilderListener;
import org.apache.batik.swing.svg.SVGDocumentLoader;
import org.apache.batik.swing.svg.SVGDocumentLoaderEvent;
import org.apache.batik.swing.svg.SVGDocumentLoaderListener;
import org.w3c.dom.svg.SVGDocument;


/**
* An SVGRasterizer renders SVG graphics to BufferedImages at
* requested resolutions (does not preserve aspect ratio)
*
* @author vwoeltje
*
*/
public class SVGRasterizer {
  private Dimension nextRenderingSize = null;
  private Dimension lastRenderingSize = null;
 
  private SVGDocument     svgDocument = null;
  private BufferedImage   latestImage = null
 
  private GraphicsNode    graphicsNode = null;
 
  private Runnable        callback     = null;
 
  private boolean isLoading = true;

 
  /**
   * Create a new rasterizer to convert an SVG document
   * to BufferedImages, for display on a specific component
   * Note that loading/parsing and rendering are both done
   * asynchronously.
   * @param documentURL the URL of the document to rasterize

   */
  public SVGRasterizer(String documentURL) {
    UserAgent userAgent = new UserAgentAdapter();
    SVGDocumentLoader loader = new SVGDocumentLoader(documentURL,
        new DocumentLoader(userAgent));   
    loader.addSVGDocumentLoaderListener(new SVGRasterizerListener());
    /* Note that Batik uses the context class loader for loading SAX Parser, etc.
     * Context class loader is inappropriate under the Felix implementation of OSGi,
     * so replace it with the regular class loader. */
    loader.setContextClassLoader(loader.getClass().getClassLoader());
    loader.start();
  }
 
  /**
   * Inject behavior to be called when rendering is complete
   * @param callback the behavior to run after rendering
   */
  public void setCallback(Runnable callback) {
    this.callback = callback;
  }

  /**
   * Request a raster image of the loaded SVG document,
   * at a specified width and height.
   * Note that rendering will be done asynchronously;
   * subsequent calls to getLatestImage() will return
   * the rendered image once complete (and the previously
   * rendered image until then)
   * @param width the width in pixels at which to render
   * @param height the height in pixels at which to render
   */
  public void requestRender(int width, int height) {
    width = (width < 1) ? 1 : width;
    height = (height < 1) ? 1 : height;
    if (latestImage != null &&
      width  == latestImage.getWidth() &&
      height == latestImage.getHeight()) return;
    nextRenderingSize = new Dimension (width, height);
    renderIfReady();   
  }
 
  /**
   * Get the most recently rendered raster image of this
   * SVG document. This may be null if no renders have
   * completed, and may not match the size of the last 
   * rendering request if rendering is incomplete.
   * @return
   */
  public BufferedImage getLatestImage() {
    return latestImage;
  }
 
  /**
   * Check to see if document loading failed
   * @return true if the document could not be loaded/parsed;
   *         false if it was successful, or is still loading
   */
  public boolean hasFailed() {
    return graphicsNode == null && !isLoading;
  }

  /**
   * Check to see if the document has been loaded & parsed
   * @return true if loaded; otherwise false
   */
  public boolean isLoaded() {
    return graphicsNode != null;
  }
 
  /**
   * Check to see if any rendering operation has completed
   * (not necessarily the most recently requested one)
   * @return true if an image is available; false if not
   */
  public boolean isRendered() {
    return latestImage != null;
  }
 
  /**
   * Check to see if all rendering options have completed 
   * @return true if an up-to-date image is available
   */
  public boolean isCurrent() {
    return latestImage != null &&
           nextRenderingSize == null &&
           lastRenderingSize == null;
  }
 
  /**
   * Check to see if the document is in the process of loading
   * & parsing.
   * @return true if loading & parsing; otherwise false
   */
  public boolean isLoading() {
    return isLoading;
  }
 
 
  private synchronized void renderIfReady() {
    if (graphicsNode == null) return;
    if (nextRenderingSize == null) return;
    if (lastRenderingSize != null) return; // Still waiting

    Dimension size = nextRenderingSize;
    Rectangle2D bounds = graphicsNode.getPrimitiveBounds();
    lastRenderingSize = nextRenderingSize;
    nextRenderingSize = null;
    // start renderer...
    double widthScale = size.getWidth() / bounds.getWidth();
    double heightScale = size.getHeight() / bounds.getHeight();

    AffineTransform renderTransform = new AffineTransform();   
    renderTransform.scale(widthScale, heightScale);
    renderTransform.translate(-bounds.getMinX(), -bounds.getMinY())
   
    ImageRenderer renderer     = new ConcreteImageRendererFactory().createStaticImageRenderer();
    renderer.setTree(graphicsNode);   
    GVTTreeRenderer gvtRenderer = new GVTTreeRenderer(
        renderer,
        renderTransform,
        true,
        bounds,
        size.width, size.height);
   
    gvtRenderer.addGVTTreeRendererListener(new SVGRasterizerListener());
    gvtRenderer.setContextClassLoader(gvtRenderer.getClass().getClassLoader());
    gvtRenderer.start();
  }

  private class SVGRasterizerListener implements  SVGDocumentLoaderListener,
                          GVTTreeBuilderListener,
                          GVTTreeRendererListener {
    /* SVGDocumentLoaderListener */
    @Override
    public void documentLoadingCancelled(SVGDocumentLoaderEvent arg0) {
      isLoading = false;
      if (callback != null) callback.run();
    }

    @Override
    public void documentLoadingCompleted(SVGDocumentLoaderEvent arg0) {
      svgDocument = arg0.getSVGDocument();
      GVTTreeBuilder gvtBuilder;
      gvtBuilder = new GVTTreeBuilder(svgDocument, new BridgeContext(new UserAgentAdapter()));
      gvtBuilder.addGVTTreeBuilderListener(this);
      gvtBuilder.setContextClassLoader(gvtBuilder.getClass().getClassLoader());
      gvtBuilder.start();   
    }

    @Override
    public void documentLoadingFailed(SVGDocumentLoaderEvent arg0) { 
      isLoading = false;
      if (callback != null) callback.run();
    }

    @Override
    public void documentLoadingStarted(SVGDocumentLoaderEvent arg0) {   
    }


    /* GVTTreeBuilderListener */
    @Override
    public void gvtBuildCancelled(GVTTreeBuilderEvent arg0) {
      isLoading = false;
      if (callback != null) callback.run();
    }

    @Override
    public void gvtBuildCompleted(GVTTreeBuilderEvent arg0) {
      graphicsNode = arg0.getGVTRoot();   
      renderIfReady();
      isLoading = false;
    }

    @Override
    public void gvtBuildFailed(GVTTreeBuilderEvent arg0) {
      isLoading = false;
      if (callback != null) callback.run();
    }

    @Override
    public void gvtBuildStarted(GVTTreeBuilderEvent arg0) {
    }


    /* GVTTreeRendererListener */
    @Override
    public void gvtRenderingCancelled(GVTTreeRendererEvent arg0) {
    }

    @Override
    public synchronized void gvtRenderingCompleted(GVTTreeRendererEvent arg0) {

      BufferedImage img = new BufferedImage(lastRenderingSize.width,
          lastRenderingSize.height, BufferedImage.TYPE_INT_ARGB);
      img.getGraphics().drawImage(arg0.getImage(),
          0, 0, lastRenderingSize.width, lastRenderingSize.height,
          0, 0, lastRenderingSize.width, lastRenderingSize.height,
          null);   
      latestImage = img;   
      lastRenderingSize = null;    

      if (callback != null) callback.run();

    }

    @Override
    public void gvtRenderingFailed(GVTTreeRendererEvent arg0) {
      if (callback != null) callback.run();
    }

    @Override
    public void gvtRenderingPrepare(GVTTreeRendererEvent arg0) {
    }

    @Override
    public void gvtRenderingStarted(GVTTreeRendererEvent arg0) {
    }
  }
 
 
 
}
TOP

Related Classes of gov.nasa.arc.mct.graphics.view.SVGRasterizer$SVGRasterizerListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.