| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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. |
| */ |
| |
| /* $Id$ */ |
| |
| package org.apache.fop.render.awt; |
| |
| /* |
| * originally contributed by |
| * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com, |
| * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com, |
| * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com |
| */ |
| |
| // Java |
| import java.awt.Color; |
| import java.awt.Dimension; |
| import java.awt.geom.Point2D; |
| import java.awt.geom.Rectangle2D; |
| import java.awt.print.PageFormat; |
| import java.awt.print.Pageable; |
| import java.awt.print.Paper; |
| import java.awt.print.Printable; |
| import java.io.IOException; |
| |
| import org.apache.xmlgraphics.util.UnitConv; |
| |
| import org.apache.fop.apps.FOPException; |
| import org.apache.fop.apps.FOUserAgent; |
| import org.apache.fop.apps.FopFactoryConfig; |
| import org.apache.fop.apps.MimeConstants; |
| import org.apache.fop.area.Area; |
| import org.apache.fop.area.PageViewport; |
| import org.apache.fop.render.awt.viewer.PreviewDialog; |
| import org.apache.fop.render.awt.viewer.Renderable; |
| import org.apache.fop.render.awt.viewer.StatusListener; |
| import org.apache.fop.render.extensions.prepress.PageScale; |
| import org.apache.fop.render.java2d.Java2DRenderer; |
| |
| /** |
| * The AWTRender outputs the pages generated by the layout engine to a Swing |
| * window. This Swing window serves as default viewer for the -awt switch and as |
| * an example of how to embed the AWTRenderer into an AWT/Swing application. |
| */ |
| public class AWTRenderer extends Java2DRenderer implements Pageable { |
| |
| /** The MIME type for AWT-Rendering */ |
| public static final String MIME_TYPE = MimeConstants.MIME_FOP_AWT_PREVIEW; |
| |
| /** flag for debugging */ |
| public boolean debug; |
| |
| /** |
| * Will be notified when rendering progresses |
| */ |
| protected StatusListener statusListener; |
| |
| |
| /** |
| * Creates a new AWTRenderer instance. |
| * |
| * @param userAgent the user agent that contains configuration data |
| */ |
| public AWTRenderer(FOUserAgent userAgent) { |
| this(userAgent, null, false, false); |
| } |
| |
| /** |
| * Creates a new AWTRenderer instance. |
| * |
| * @param userAgent the user agent that contains configuration data |
| * @param renderable a Renderable instance can be set so the Preview Dialog can enable the |
| * "Reload" button which causes the current document to be reprocessed and redisplayed. |
| * @param previewAsMainWindow true if the preview dialog created by the renderer should be |
| * the main window of the application. |
| * @param show sets whether the preview dialog should be created and displayed when the |
| * rendering has finished. |
| */ |
| public AWTRenderer(FOUserAgent userAgent, Renderable renderable, boolean previewAsMainWindow, |
| boolean show) { |
| super(userAgent); |
| if (show) { |
| // MH: Not sure about this??? If show is false, there's no way for this class |
| // to create a preview dialog... Previously a "setUserAgent" could be called. |
| setStatusListener(PreviewDialog.createPreviewDialog(userAgent, renderable, |
| previewAsMainWindow)); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| * @throws FOPException thrown by java2DRenderer |
| */ |
| public void renderPage(PageViewport pageViewport) throws IOException, FOPException { |
| |
| super.renderPage(pageViewport); |
| if (statusListener != null) { |
| statusListener.notifyPageRendered(); |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| public void stopRenderer() throws IOException { |
| super.stopRenderer(); |
| if (statusListener != null) { |
| statusListener.notifyRendererStopped(); // Refreshes view of page |
| } |
| } |
| |
| /** |
| * @return the dimensions of the specified page |
| * @param pageNum the page number |
| * @exception FOPException If the page is out of range or has not been rendered. |
| */ |
| public Dimension getPageImageSize(int pageNum) throws FOPException { |
| Rectangle2D bounds = getPageViewport(pageNum).getViewArea(); |
| pageWidth = (int) Math.round(bounds.getWidth() / 1000f); |
| pageHeight = (int) Math.round(bounds.getHeight() / 1000f); |
| double scaleX = scaleFactor |
| * (UnitConv.IN2MM / FopFactoryConfig.DEFAULT_TARGET_RESOLUTION) |
| / userAgent.getTargetPixelUnitToMillimeter(); |
| double scaleY = scaleFactor |
| * (UnitConv.IN2MM / FopFactoryConfig.DEFAULT_TARGET_RESOLUTION) |
| / userAgent.getTargetPixelUnitToMillimeter(); |
| if (getPageViewport(pageNum).getForeignAttributes() != null) { |
| String scale = getPageViewport(pageNum).getForeignAttributes().get( |
| PageScale.EXT_PAGE_SCALE); |
| Point2D scales = PageScale.getScale(scale); |
| if (scales != null) { |
| scaleX *= scales.getX(); |
| scaleY *= scales.getY(); |
| } |
| } |
| int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5); |
| int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5); |
| return new Dimension(bitmapWidth, bitmapHeight); |
| } |
| |
| /** {@inheritDoc} */ |
| public PageFormat getPageFormat(int pageIndex) |
| throws IndexOutOfBoundsException { |
| try { |
| if (pageIndex >= getNumberOfPages()) { |
| return null; |
| } |
| |
| PageFormat pageFormat = new PageFormat(); |
| |
| Paper paper = new Paper(); |
| |
| Rectangle2D dim = getPageViewport(pageIndex).getViewArea(); |
| double width = dim.getWidth(); |
| double height = dim.getHeight(); |
| |
| // if the width is greater than the height assume lanscape mode |
| // and swap the width and height values in the paper format |
| if (width > height) { |
| paper.setImageableArea(0, 0, height / 1000d, width / 1000d); |
| paper.setSize(height / 1000d, width / 1000d); |
| pageFormat.setOrientation(PageFormat.LANDSCAPE); |
| } else { |
| paper.setImageableArea(0, 0, width / 1000d, height / 1000d); |
| paper.setSize(width / 1000d, height / 1000d); |
| pageFormat.setOrientation(PageFormat.PORTRAIT); |
| } |
| pageFormat.setPaper(paper); |
| return pageFormat; |
| } catch (FOPException fopEx) { |
| throw new IndexOutOfBoundsException(fopEx.getMessage()); |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| public Printable getPrintable(int pageIndex) |
| throws IndexOutOfBoundsException { |
| return this; |
| } |
| |
| /** {@inheritDoc} */ |
| public boolean supportsOutOfOrder() { |
| return false; |
| } |
| |
| /** {@inheritDoc} */ |
| public String getMimeType() { |
| return MIME_TYPE; |
| } |
| |
| /** |
| * Draws the background and borders and adds a basic debug view // TODO |
| * implement visual-debugging as standalone |
| * |
| * {@inheritDoc} |
| * float, float, float, float) |
| * |
| * @param area the area to get the traits from |
| * @param startx the start x position |
| * @param starty the start y position |
| * @param width the width of the area |
| * @param height the height of the area |
| */ |
| protected void drawBackAndBorders(Area area, float startx, float starty, |
| float width, float height) { |
| |
| if (debug) { |
| debugBackAndBorders(area, startx, starty, width, height); |
| } |
| |
| super.drawBackAndBorders(area, startx, starty, width, height); |
| } |
| |
| /** Draws a thin border around every area to help debugging */ |
| private void debugBackAndBorders(Area area, float startx, float starty, |
| float width, float height) { |
| |
| // saves the graphics state in a stack |
| saveGraphicsState(); |
| |
| Color col = new Color(0.7f, 0.7f, 0.7f); |
| state.updateColor(col); |
| state.updateStroke(0.4f, EN_SOLID); |
| state.getGraph().draw( |
| new Rectangle2D.Float(startx, starty, width, height)); |
| |
| // restores the last graphics state from the stack |
| restoreGraphicsState(); |
| } |
| |
| /** @return the StatusListener. */ |
| public StatusListener getStatusListener() { |
| return statusListener; |
| } |
| |
| /** |
| * Sets a StatusListener this renderer uses to notify about events. |
| * @param statusListener The StatusListener to set. |
| */ |
| public void setStatusListener(StatusListener statusListener) { |
| this.statusListener = statusListener; |
| } |
| |
| } |