Browse Source

Resurrected AWT/Java2D renderer

Submitted by:	Renaud Richardet <renaud.richardet.at.gmail.com>

Modifications to the patch:
- correct copyright years
- warning message when EPS files are used as images
- removed/commented hard-coded path names, should be improved by loading the image from an InputStream obtained throug the user agent
- Enabled loading images from the bitmap array coming from FopImage. There are hard-coded value which need to be fixed but they show the approach.


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198472 13f79535-47bb-0310-9956-ffa450edef68
tags/Root_Temp_KnuthStylePageBreaking
Jeremias Maerki 19 years ago
parent
commit
c230af051c

+ 332
- 0
src/java/org/apache/fop/render/awt/AWTGraphicsState.java View File

@@ -0,0 +1,332 @@
/*
* Copyright 2005 The Apache Software Foundation.
*
* 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.
*/

/* $Id$ */

package org.apache.fop.render.awt;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.util.List;

import org.apache.fop.datatypes.ColorType;
import org.apache.fop.fo.Constants;
import org.apache.fop.fonts.FontInfo;

/**
* Keeps information about the current state of the Graphics2D currentGraphics.
* It is also used as a stack to hold a graphics context.
* <p>
* The graphics context is updated with the updateXXX() methods.
*/
public class AWTGraphicsState implements Constants, RendererState {

/** Holds the datas of the current state */
private Graphics2D currentGraphics;

private BasicStroke currentStroke;

private float currentStrokeWidth;

private int currentStrokeStyle;

private List stateStack = new java.util.ArrayList();

/** Font configuration, passed from AWTRenderer */
private FontInfo fontInfo;

/** State for storing graphics state. */
public AWTGraphicsState(Graphics2D graphics, FontInfo fontInfo) {
this.fontInfo = fontInfo;
this.currentGraphics = graphics;
}

/**
* @return the currently valid state
*/
public Graphics2D getGraph() {
return currentGraphics;
}

/** @see org.apache.fop.render.awt.RendererState#push() */
public void push() {
Graphics2D tmpGraphics = (Graphics2D) currentGraphics.create();
stateStack.add(tmpGraphics);
}

/** @see org.apache.fop.render.awt.RendererState#pop() */
public Graphics2D pop() {
if (getStackLevel() > 0) {
Graphics2D popped = (Graphics2D) stateStack.remove(stateStack
.size() - 1);

currentGraphics = popped;
return popped;
} else {
return null;
}
}

/** @see org.apache.fop.render.awt.RendererState#getStackLevel() */
public int getStackLevel() {
return stateStack.size();
}

/**
* Restore the state to a particular level. this can be used to restore to a
* known level without making multiple pop calls.
*
* @param stack the level to restore to
*/
/*
* public void restoreLevel(int stack) { int pos = stack; while
* (stateStack.size() > pos + 1) { stateStack.remove(stateStack.size() - 1); }
* if (stateStack.size() > pos) { pop(); } }
*/

/**
* Set the current background color. Check if the background color will
* change and then set the new color.
*
* @param col the new color as a java.awt.Color
* @return true if the background color has changed
*/
public boolean updateColor(Color col) {
if (!col.equals(getGraph().getColor())) {
getGraph().setColor(col);
return true;
} else {
return false;
}
}

/**
* Converts a ColorType to a java.awt.Color (sRGB).
*
* @param col the color as a org.apache.fop.datatypes.ColorType
* @return the converted color as a java.awt.Color
*/
public Color toColor(ColorType col) {
return new Color(col.getRed(), col.getGreen(), col.getBlue());
}

/**
* @see org.apache.fop.render.awt.RendererState#updateColor(org.apache.fop.datatypes.ColorType,
* boolean, java.lang.StringBuffer)
*/
public boolean updateColor(ColorType col, boolean fill, StringBuffer pdf) {
if (col == null) {
return false;
}
Color newCol = toColor(col);
return updateColor(newCol);
}

/**
* Update the current Color
* @param col the ColorType
*/
public void updateColor(ColorType col) {
if (col == null) {
return;
}
Color newCol = toColor(col);
updateColor(newCol);
}

/**
* @return the current java.awt.Color
*/
public java.awt.Color getColor() {
return currentGraphics.getColor();
}

/**
* @see org.apache.fop.render.awt.RendererState#updateFont(java.lang.String,
* int, java.lang.StringBuffer)
*/
public boolean updateFont(String name, int size, StringBuffer pdf) {

boolean updateName = (!name.equals(getGraph().getFont().getFontName()));
boolean updateSize = (size != (getGraph().getFont().getSize()));

if (updateName || updateSize) {
// the font name and/or the font size have changed
FontMetricsMapper mapper = (FontMetricsMapper) fontInfo
.getMetricsFor(name);
java.awt.Font font = mapper.getFont(size);

currentGraphics.setFont(font);
return true;
} else {
return false;
}
}

/**
* @return the current java.awt.Font
*/
public java.awt.Font getFont() {
return currentGraphics.getFont();
}

/**
* @see org.apache.fop.render.awt.RendererState#updateStroke(float, int)
*/
public boolean updateStroke(float width, int style) {

boolean update = false;

// only update if necessary
if ((width != currentStrokeWidth) || (style != currentStrokeStyle)) {

update = true;

switch (style) {
case EN_DOTTED:

currentStroke = new BasicStroke(width, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL, 0f, new float[] { 2f }, 0f);
currentGraphics.setStroke(currentStroke);

currentStrokeWidth = width;
currentStrokeStyle = style;

break;

case EN_DASHED:

currentStroke = new BasicStroke(width, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL, 0f, new float[] { 8f, 2f }, 0f);
currentGraphics.setStroke(currentStroke);

currentStrokeWidth = width;
currentStrokeStyle = style;

break;

default: // EN_SOLID:

currentStroke = new BasicStroke(width);
currentGraphics.setStroke(currentStroke);

currentStrokeWidth = width;
currentStrokeStyle = style;

break;
}
}

return update;
}

public BasicStroke getStroke() {
return (BasicStroke) currentGraphics.getStroke();
}

/** @see org.apache.fop.render.awt.RendererState#updatePaint(java.awt.Paint) */
public boolean updatePaint(Paint p) {
if (getGraph().getPaint() == null) {
if (p != null) {
getGraph().setPaint(p);
return true;
}
} else if (p.equals(getGraph().getPaint())) {
getGraph().setPaint(p);
return true;
}
return false;
}

/** @see org.apache.fop.render.awt.RendererState#checkClip(java.awt.Shape) */
// TODO implement and test
public boolean checkClip(Shape cl) {
if (getGraph().getClip() == null) {
if (cl != null) {
return true;
}
} else if (cl.equals(getGraph().getClip())) {
return true;
}
// TODO check for clips that are larger than the current
return false;
}

/**
* @see org.apache.fop.render.awt.RendererState#updateClip(java.awt.Shape)
*/
public boolean updateClip(Shape cl) {
if (getGraph().getClip() != null) {
Area newClip = new Area(getGraph().getClip());
newClip.intersect(new Area(cl));
getGraph().setClip(new GeneralPath(newClip));
} else {
getGraph().setClip(cl);
}
return true; // TODO only update if necessary
}

/**
* @see org.apache.fop.render.awt.RendererState#checkTransform(java.awt.geom.AffineTransform)
*/
public boolean checkTransform(AffineTransform tf) {
return !tf.equals(getGraph().getTransform());
}

/**
* @see org.apache.fop.render.awt.RendererState#setTransform(java.awt.geom.AffineTransform)
*/
public void setTransform(AffineTransform tf) {
getGraph().setTransform(tf);
}

/**
* @see org.apache.fop.render.awt.RendererState#transform(java.awt.geom.AffineTransform)
*/
public void transform(AffineTransform tf) {
getGraph().transform(tf);
}

/**
* @see org.apache.fop.render.awt.RendererState#getTransform()
*/
public AffineTransform getTransform() {
/*
* AffineTransform tf; AffineTransform at = new AffineTransform(); for
* (Iterator iter = stateStack.iterator(); iter.hasNext();) { Data d =
* (Data) iter.next(); tf = d.transform; at.concatenate(tf); }
* at.concatenate(getCurrentGraphics().transform);
*
* return at;
*/
return getGraph().getTransform();
}

/** a verbose description of the current state */
public String toString() {
String s = "AWTGraphicsState " + currentGraphics.toString()
+ ", Stroke (width: " + currentStrokeWidth + " style: "
+ currentStrokeStyle + "), " + getTransform()
+ ", StackLevel: " + getStackLevel();
return s;
}
}

+ 924
- 197
src/java/org/apache/fop/render/awt/AWTRenderer.java
File diff suppressed because it is too large
View File


+ 145
- 0
src/java/org/apache/fop/render/awt/RendererState.java View File

@@ -0,0 +1,145 @@
/*
* Copyright 2005 The Apache Software Foundation.
*
* 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.
*/

/* $Id$ */

package org.apache.fop.render.awt;

import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.AffineTransform;

import org.apache.fop.datatypes.ColorType;

/**
* An interface for the classes which hold the state of the current graphics context.
*/
public interface RendererState {

/**
* Push the current state onto the stack.
*/
public abstract void push();

/**
* Pop the state from the stack and restore the graphics context.
* @return the restored state, null if the stack is empty.
*/
public abstract Graphics2D pop();

/**
* Get the current stack level.
*
* @return the current stack level
*/
public abstract int getStackLevel();

/**
* Establishes a new foreground or fill color.
* @param col the color to apply (null skips this operation)
* @param fill true to set the fill color, false for the foreground color
* @param pdf only used by the PDFRenderer, is set to null.
* @return true if the new Color changes the current Color
*/
public abstract boolean updateColor(ColorType col, boolean fill, StringBuffer pdf);

/**
* Set the current font name. Check if the font name will change and then
* set the new name.
*
* @param name the new font name
* @param size
* @param pdf
* @return true if the new Font changes the current Font
*/
public abstract boolean updateFont(String name, int size, StringBuffer pdf);

/**
* Sets the current Stroke. The line width should be set with
* updateLineWidth() before calling this method
*
* @param style the constant for the style of the line as an int
* @return true if the new Stroke changes the current Stroke
*/
public abstract boolean updateStroke(float width, int style);

/**
* Set the current paint. This checks if the paint will change and then sets
* the current paint.
*
* @param p the new paint
* @return true if the new paint changes the current paint
*/
public abstract boolean updatePaint(Paint p);

/**
* Check if the clip will change the current state. A clip is assumed to be
* used in a situation where it will add to any clip in the current or
* parent states. A clip cannot be cleared, this can only be achieved by
* going to a parent level with the correct clip. If the clip is different
* then it may start a new state so that it can return to the previous clip.
*
* @param cl the clip shape to check
* @return true if the clip will change the current clip.
*/
// TODO test
public abstract boolean checkClip(Shape cl);

/**
* Set the current clip. This either sets a new clip or sets the clip to the
* intersect of the old clip and the new clip.
*
* @param cl the new clip in the current state
*/
public abstract boolean updateClip(Shape cl);

/**
* Check the current transform. The transform for the current state is the
* combination of all transforms in the current state. The parameter is
* compared against this current transform.
*
* @param tf the transform to check against
* @return true if the new transform is different from the current transform
*/
public abstract boolean checkTransform(AffineTransform tf);

/**
* Overwrites the Transform in the Graphics2D context. Use <code>transform()</code> if you
* wish to compose with the current Affinetransform instead.
* @see java.awt.Graphics2D.setTransform().
* @param tf the transform to concatonate to the current level transform
*/
public abstract void setTransform(AffineTransform tf);

/**
* Composes an AffineTransform object with the Transform in this Graphics2D
* according to the rule last-specified-first-applied.
* @see java.awt.Graphics2D.transform().
*
* @param tf the transform to concatonate to the current level transform
*/
public abstract void transform(AffineTransform tf);

/**
* Get the current transform. This gets the combination of all transforms in
* the current state.
*
* @return the calculate combined transform for the current state
*/
public abstract AffineTransform getTransform();

}

+ 41
- 20
src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java View File

@@ -1,6 +1,6 @@
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Copyright 1999-2005 The Apache Software Foundation.
*
* 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
@@ -19,19 +19,6 @@
package org.apache.fop.render.awt.viewer;

//Java
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
@@ -44,13 +31,26 @@ import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.print.PrinterJob;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

//FOP
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.fo.Constants;
import org.apache.fop.render.awt.AWTRenderer;

@@ -123,6 +123,18 @@ public class PreviewDialog extends JFrame {
reload();
}
};
Command debugAction = new Command(" Debug") {
//TODO use Translator
public void doit() {
debug();
}
};

//set the system look&feel
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) { }

setTitle("FOP: AWT-" + translator.getString("Title.Preview"));
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
@@ -171,8 +183,9 @@ public class PreviewDialog extends JFrame {
toolBar.add(lastPageAction);
toolBar.addSeparator();
toolBar.add(new JLabel(translator.getString("Menu.Zoom")));
toolBar.addSeparator();
toolBar.add(scale);
toolBar.addSeparator();
toolBar.add(debugAction);
getContentPane().add(toolBar, BorderLayout.NORTH);
//Status bar
JPanel statusBar = new JPanel();
@@ -378,6 +391,14 @@ public class PreviewDialog extends JFrame {
}
}

/**
* Allows a (yet) simple visual debug of the document.
*/
private void debug(){
renderer.debug = !renderer.debug;
showPage();
}

/**
* This class is used to reload document in
* a thread safe way.

Loading…
Cancel
Save