From 5feb2f8d04c7ef475316235c097a726290b6729a Mon Sep 17 00:00:00 2001
From: "(no author)" <(no author)@unknown>
Date: Sat, 6 Mar 2004 05:53:16 +0000
Subject: [PATCH] This commit was manufactured by cvs2svn to create branch
'FOP_0-20-0_Alt-Design'.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/FOP_0-20-0_Alt-Design@197413 13f79535-47bb-0310-9956-ffa450edef68
---
src/java/org/apache/fop/apps/Document.java | 390 +++++
.../org/apache/fop/apps/FOFileHandler.java | 113 ++
src/java/org/apache/fop/apps/FOUserAgent.java | 157 ++
.../org/apache/fop/apps/XSLTInputHandler.java | 180 +++
src/java/org/apache/fop/area/LineArea.java | 115 ++
src/java/org/apache/fop/area/Page.java | 136 ++
src/java/org/apache/fop/fonts/BFEntry.java | 66 +
src/java/org/apache/fop/fonts/CIDFont.java | 93 ++
.../org/apache/fop/fonts/CIDFontType.java | 78 +
src/java/org/apache/fop/fonts/CustomFont.java | 338 +++++
.../org/apache/fop/fonts/EmbedFontInfo.java | 80 +
src/java/org/apache/fop/fonts/FontReader.java | 286 ++++
src/java/org/apache/fop/fonts/FontSetup.java | 236 +++
.../org/apache/fop/fonts/FontTriplet.java | 71 +
src/java/org/apache/fop/fonts/FontUtil.java | 59 +
src/java/org/apache/fop/fonts/LazyFont.java | 256 ++++
.../org/apache/fop/fonts/MultiByteFont.java | 294 ++++
.../org/apache/fop/fonts/MutableFont.java | 126 ++
.../org/apache/fop/fonts/SingleByteFont.java | 96 ++
src/java/org/apache/fop/fonts/Typeface.java | 51 +
.../org/apache/fop/fonts/apps/PFMReader.java | 389 +++++
.../org/apache/fop/fonts/apps/TTFReader.java | 514 +++++++
.../fop/fonts/truetype/FontFileReader.java | 335 +++++
.../fop/fonts/truetype/TTFCmapEntry.java | 106 ++
.../fop/fonts/truetype/TTFDirTabEntry.java | 108 ++
.../apache/fop/fonts/truetype/TTFFile.java | 1312 +++++++++++++++++
.../fop/fonts/truetype/TTFMtxEntry.java | 194 +++
.../fop/fonts/truetype/TTFSubSetFile.java | 854 +++++++++++
.../org/apache/fop/fonts/type1/PFBData.java | 160 ++
.../org/apache/fop/fonts/type1/PFBParser.java | 235 +++
.../org/apache/fop/fonts/type1/PFMFile.java | 437 ++++++
.../fop/fonts/type1/PFMInputStream.java | 107 ++
.../apache/fop/render/AbstractRenderer.java | 758 ++++++++++
.../org/apache/fop/render/PrintRenderer.java | 48 +
src/java/org/apache/fop/render/Renderer.java | 190 +++
.../apache/fop/render/RendererContext.java | 95 ++
.../org/apache/fop/render/XMLHandler.java | 45 +
.../apache/fop/render/awt/AWTFontMetrics.java | 283 ++++
.../fop/render/awt/AWTPrintRenderer.java | 121 ++
.../apache/fop/render/awt/AWTRenderer.java | 465 ++++++
.../fop/render/awt/FontMetricsMapper.java | 166 +++
.../org/apache/fop/render/awt/FontSetup.java | 182 +++
.../apache/fop/render/awt/viewer/Command.java | 82 ++
.../fop/render/awt/viewer/GoToPageDialog.java | 128 ++
.../fop/render/awt/viewer/PreviewDialog.java | 571 +++++++
.../awt/viewer/PreviewDialogAboutBox.java | 118 ++
.../fop/render/awt/viewer/Translator.java | 59 +
47 files changed, 11283 insertions(+)
create mode 100644 src/java/org/apache/fop/apps/Document.java
create mode 100644 src/java/org/apache/fop/apps/FOFileHandler.java
create mode 100644 src/java/org/apache/fop/apps/FOUserAgent.java
create mode 100644 src/java/org/apache/fop/apps/XSLTInputHandler.java
create mode 100644 src/java/org/apache/fop/area/LineArea.java
create mode 100644 src/java/org/apache/fop/area/Page.java
create mode 100644 src/java/org/apache/fop/fonts/BFEntry.java
create mode 100644 src/java/org/apache/fop/fonts/CIDFont.java
create mode 100644 src/java/org/apache/fop/fonts/CIDFontType.java
create mode 100644 src/java/org/apache/fop/fonts/CustomFont.java
create mode 100644 src/java/org/apache/fop/fonts/EmbedFontInfo.java
create mode 100644 src/java/org/apache/fop/fonts/FontReader.java
create mode 100644 src/java/org/apache/fop/fonts/FontSetup.java
create mode 100644 src/java/org/apache/fop/fonts/FontTriplet.java
create mode 100644 src/java/org/apache/fop/fonts/FontUtil.java
create mode 100644 src/java/org/apache/fop/fonts/LazyFont.java
create mode 100644 src/java/org/apache/fop/fonts/MultiByteFont.java
create mode 100644 src/java/org/apache/fop/fonts/MutableFont.java
create mode 100644 src/java/org/apache/fop/fonts/SingleByteFont.java
create mode 100644 src/java/org/apache/fop/fonts/Typeface.java
create mode 100644 src/java/org/apache/fop/fonts/apps/PFMReader.java
create mode 100644 src/java/org/apache/fop/fonts/apps/TTFReader.java
create mode 100644 src/java/org/apache/fop/fonts/truetype/FontFileReader.java
create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java
create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java
create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFFile.java
create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFMtxEntry.java
create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
create mode 100644 src/java/org/apache/fop/fonts/type1/PFBData.java
create mode 100644 src/java/org/apache/fop/fonts/type1/PFBParser.java
create mode 100644 src/java/org/apache/fop/fonts/type1/PFMFile.java
create mode 100644 src/java/org/apache/fop/fonts/type1/PFMInputStream.java
create mode 100644 src/java/org/apache/fop/render/AbstractRenderer.java
create mode 100644 src/java/org/apache/fop/render/PrintRenderer.java
create mode 100644 src/java/org/apache/fop/render/Renderer.java
create mode 100644 src/java/org/apache/fop/render/RendererContext.java
create mode 100644 src/java/org/apache/fop/render/XMLHandler.java
create mode 100644 src/java/org/apache/fop/render/awt/AWTFontMetrics.java
create mode 100644 src/java/org/apache/fop/render/awt/AWTPrintRenderer.java
create mode 100644 src/java/org/apache/fop/render/awt/AWTRenderer.java
create mode 100644 src/java/org/apache/fop/render/awt/FontMetricsMapper.java
create mode 100644 src/java/org/apache/fop/render/awt/FontSetup.java
create mode 100644 src/java/org/apache/fop/render/awt/viewer/Command.java
create mode 100644 src/java/org/apache/fop/render/awt/viewer/GoToPageDialog.java
create mode 100644 src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java
create mode 100644 src/java/org/apache/fop/render/awt/viewer/PreviewDialogAboutBox.java
create mode 100644 src/java/org/apache/fop/render/awt/viewer/Translator.java
diff --git a/src/java/org/apache/fop/apps/Document.java b/src/java/org/apache/fop/apps/Document.java
new file mode 100644
index 000000000..2329050cb
--- /dev/null
+++ b/src/java/org/apache/fop/apps/Document.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright 1999-2004 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.apps;
+
+// Java
+import java.util.Map;
+import java.io.IOException;
+import java.util.Set;
+import java.util.HashSet;
+
+
+// FOP
+import org.apache.fop.apps.FOUserAgent;
+
+import org.apache.fop.area.AreaTree;
+import org.apache.fop.area.AreaTreeControl;
+import org.apache.fop.area.AreaTreeModel;
+
+import org.apache.fop.fo.extensions.Bookmarks;
+import org.apache.fop.fo.FOInputHandler;
+import org.apache.fop.fo.FOTreeControl;
+import org.apache.fop.fo.FOTreeEvent;
+import org.apache.fop.fo.FOTreeListener;
+import org.apache.fop.fo.pagination.PageSequence;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.layout.LayoutStrategy;
+
+// SAX
+import org.xml.sax.SAXException;
+
+// Avalon
+import org.apache.avalon.framework.logger.Logger;
+
+/**
+ * Class storing information for the FOP Document being processed, and managing
+ * the processing of it.
+ */
+public class Document implements FOTreeControl, FOTreeListener,
+ AreaTreeControl {
+
+ /** The parent Driver object */
+ private Driver driver;
+
+ /** Map containing fonts that have been used */
+ private Map usedFonts;
+
+ /** look up a font-triplet to find a font-name */
+ private Map triplets;
+
+ /** look up a font-name to get a font (that implements FontMetrics at least) */
+ private Map fonts;
+
+ /**
+ * the LayoutStrategy to be used to process this document
+ * TODO: this actually belongs in the RenderContext class, when it is
+ * created
+ */
+ private LayoutStrategy layoutStrategy = null;
+
+ /** The current AreaTree for the PageSequence being rendered. */
+ public AreaTree areaTree;
+ /** The AreaTreeModel for the PageSequence being rendered. */
+ public AreaTreeModel atModel;
+
+ private Bookmarks bookmarks = null;
+
+ /**
+ * The current set of id's in the FO tree.
+ * This is used so we know if the FO tree contains duplicates.
+ */
+ private Set idReferences = new HashSet();
+
+ /**
+ * Structure handler used to notify structure events
+ * such as start end element.
+ */
+ public FOInputHandler foInputHandler;
+
+ /**
+ * Main constructor
+ * @param driver the Driver object that is the "parent" of this Document
+ */
+ public Document(Driver driver) {
+ this.driver = driver;
+ this.triplets = new java.util.HashMap();
+ this.fonts = new java.util.HashMap();
+ this.usedFonts = new java.util.HashMap();
+ }
+
+ /**
+ * Checks if the font setup is valid (At least the ultimate fallback font
+ * must be registered.)
+ * @return True if valid
+ */
+ public boolean isSetupValid() {
+ return triplets.containsKey(Font.DEFAULT_FONT);
+ }
+
+ /**
+ * Adds a new font triplet.
+ * @param name internal key
+ * @param family font family name
+ * @param style font style (normal, italic, oblique...)
+ * @param weight font weight
+ */
+ public void addFontProperties(String name, String family, String style,
+ int weight) {
+ /*
+ * add the given family, style and weight as a lookup for the font
+ * with the given name
+ */
+
+ String key = createFontKey(family, style, weight);
+ this.triplets.put(key, name);
+ }
+
+ /**
+ * Adds font metrics for a specific font.
+ * @param name internal key
+ * @param metrics metrics to register
+ */
+ public void addMetrics(String name, FontMetrics metrics) {
+ // add the given metrics as a font with the given name
+
+ this.fonts.put(name, metrics);
+ }
+
+ /**
+ * Lookup a font.
+ *
+ * Locate the font name for a given family, style and weight.
+ * The font name can then be used as a key as it is unique for
+ * the associated document.
+ * This also adds the font to the list of used fonts.
+ * @param family font family
+ * @param style font style
+ * @param weight font weight
+ * @return internal key
+ */
+ public String fontLookup(String family, String style,
+ int weight) {
+ String key;
+ // first try given parameters
+ key = createFontKey(family, style, weight);
+ String f = (String)triplets.get(key);
+ if (f == null) {
+ // then adjust weight, favouring normal or bold
+ f = findAdjustWeight(family, style, weight);
+
+ // then try any family with orig weight
+ if (f == null) {
+ key = createFontKey("any", style, weight);
+ f = (String)triplets.get(key);
+ }
+
+ // then try any family with adjusted weight
+ if (f == null) {
+ f = findAdjustWeight(family, style, weight);
+ }
+
+ // then use default
+ if (f == null) {
+ f = (String)triplets.get(Font.DEFAULT_FONT);
+ }
+
+ }
+
+ usedFonts.put(f, fonts.get(f));
+ return f;
+ }
+
+ /**
+ * Find a font with a given family and style by trying
+ * different font weights according to the spec.
+ * @param family font family
+ * @param style font style
+ * @param weight font weight
+ * @return internal key
+ */
+ public String findAdjustWeight(String family, String style,
+ int weight) {
+ String key;
+ String f = null;
+ int newWeight = weight;
+ if (newWeight < 400) {
+ while (f == null && newWeight > 0) {
+ newWeight -= 100;
+ key = createFontKey(family, style, newWeight);
+ f = (String)triplets.get(key);
+ }
+ } else if (newWeight == 500) {
+ key = createFontKey(family, style, 400);
+ f = (String)triplets.get(key);
+ } else if (newWeight > 500) {
+ while (f == null && newWeight < 1000) {
+ newWeight += 100;
+ key = createFontKey(family, style, newWeight);
+ f = (String)triplets.get(key);
+ }
+ newWeight = weight;
+ while (f == null && newWeight > 400) {
+ newWeight -= 100;
+ key = createFontKey(family, style, newWeight);
+ f = (String)triplets.get(key);
+ }
+ }
+ if (f == null) {
+ key = createFontKey(family, style, 400);
+ f = (String)triplets.get(key);
+ }
+
+ return f;
+ }
+
+ /**
+ * Determines if a particular font is available.
+ * @param family font family
+ * @param style font style
+ * @param weight font weight
+ * @return True if available
+ */
+ public boolean hasFont(String family, String style, int weight) {
+ String key = createFontKey(family, style, weight);
+ return this.triplets.containsKey(key);
+ }
+
+ /**
+ * Creates a key from the given strings.
+ * @param family font family
+ * @param style font style
+ * @param weight font weight
+ * @return internal key
+ */
+ public static String createFontKey(String family, String style,
+ int weight) {
+ return family + "," + style + "," + weight;
+ }
+
+ /**
+ * Gets a Map of all registred fonts.
+ * @return a read-only Map with font key/FontMetrics pairs
+ */
+ public Map getFonts() {
+ return java.util.Collections.unmodifiableMap(this.fonts);
+ }
+
+ /**
+ * This is used by the renderers to retrieve all the
+ * fonts used in the document.
+ * This is for embedded font or creating a list of used fonts.
+ * @return a read-only Map with font key/FontMetrics pairs
+ */
+ public Map getUsedFonts() {
+ return this.usedFonts;
+ }
+
+ /**
+ * Returns the FontMetrics for a particular font
+ * @param fontName internal key
+ * @return font metrics
+ */
+ public FontMetrics getMetricsFor(String fontName) {
+ usedFonts.put(fontName, fonts.get(fontName));
+ return (FontMetrics)fonts.get(fontName);
+ }
+
+ /**
+ * Set the LayoutStrategy to be used to process this Document
+ * @param ls the LayoutStrategy object to be used to process this Document
+ */
+ public void setLayoutStrategy(LayoutStrategy ls) {
+ this.layoutStrategy = ls;
+ }
+
+ /**
+ * @return this Document's LayoutStrategy object
+ */
+ public LayoutStrategy getLayoutStrategy () {
+ return layoutStrategy;
+ }
+
+ /**
+ * Public accessor for the parent Driver of this Document
+ * @return the parent Driver for this Document
+ */
+ public Driver getDriver() {
+ return driver;
+ }
+
+ /**
+ * Required by the FOTreeListener interface. It handles an
+ * FOTreeEvent that is fired when a PageSequence object has been completed.
+ * @param event the FOTreeEvent that was fired
+ * @throws FOPException for errors in building the PageSequence
+ */
+ public void foPageSequenceComplete (FOTreeEvent event) throws FOPException {
+ PageSequence pageSeq = event.getPageSequence();
+ areaTree.addBookmarksToAreaTree();
+ layoutStrategy.format(pageSeq, areaTree);
+ }
+
+ /**
+ * Required by the FOTreeListener interface. It handles an FOTreeEvent that
+ * is fired when the Document has been completely parsed.
+ * @param event the FOTreeEvent that was fired
+ * @throws SAXException for parsing errors
+ */
+ public void foDocumentComplete (FOTreeEvent event) throws SAXException {
+ //processAreaTree(atModel);
+ try {
+ areaTree.endDocument();
+ driver.getRenderer().stopRenderer();
+ } catch (IOException ex) {
+ throw new SAXException(ex);
+ }
+ }
+
+ /**
+ * Get the area tree for this layout handler.
+ *
+ * @return the area tree for this document
+ */
+ public AreaTree getAreaTree() {
+ return areaTree;
+ }
+
+ /**
+ * Set the Bookmarks object for this Document
+ * @param bookmarks the Bookmarks object containing the bookmarks for this
+ * Document
+ */
+ public void setBookmarks(Bookmarks bookmarks) {
+ this.bookmarks = bookmarks;
+ }
+
+ /**
+ * Public accessor for the Bookmarks for this Document
+ * @return the Bookmarks for this Document
+ */
+ public Bookmarks getBookmarks() {
+ return bookmarks;
+ }
+
+ /**
+ * Retuns the set of ID references.
+ * @return the ID references
+ */
+ public Set getIDReferences() {
+ return idReferences;
+ }
+
+ /**
+ * @return the FOInputHandler for parsing this FO Tree
+ */
+ public FOInputHandler getFOInputHandler() {
+ return foInputHandler;
+ }
+
+ /**
+ * @return the Logger to be used for processing this Document
+ */
+ public Logger getLogger() {
+ return getDriver().getLogger();
+ }
+
+ /**
+ * @return the FOUserAgent used for processing this document
+ */
+ public FOUserAgent getUserAgent() {
+ return getDriver().getUserAgent();
+ }
+
+}
diff --git a/src/java/org/apache/fop/apps/FOFileHandler.java b/src/java/org/apache/fop/apps/FOFileHandler.java
new file mode 100644
index 000000000..28226e677
--- /dev/null
+++ b/src/java/org/apache/fop/apps/FOFileHandler.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1999-2004 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.apps;
+
+// Imported SAX classes
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotSupportedException;
+
+// java
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.File;
+import java.net.URL;
+
+
+/**
+ * Manages input if it is an XSL-FO file.
+ */
+public class FOFileHandler extends InputHandler {
+
+ private File fofile = null;
+ private URL foURL = null;
+
+ /**
+ * Create a FOFileHandler for a file.
+ * @param fofile the file to read the FO document.
+ */
+ public FOFileHandler(File fofile) {
+ this.fofile = fofile;
+ }
+
+ /**
+ * Create a FOFileHandler for an URL.
+ * @param url the URL to read the FO document.
+ */
+ public FOFileHandler(URL url) {
+ this.foURL = url;
+ }
+
+
+ /**
+ * @see org.apache.fop.apps.InputHandler#getInputSource()
+ */
+ public InputSource getInputSource () {
+ if (fofile != null) {
+ return super.fileInputSource(fofile);
+ }
+ return super.urlInputSource(foURL);
+ }
+
+ /**
+ * @see org.apache.fop.apps.InputHandler#getParser()
+ */
+ public XMLReader getParser() throws FOPException {
+ return createParser();
+ }
+
+ /**
+ * Creates XMLReader
object using default
+ * SAXParserFactory
+ * @return the created XMLReader
+ * @throws FOPException if the parser couldn't be created or configured for proper operation.
+ */
+ protected static XMLReader createParser() throws FOPException {
+ try {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ factory.setFeature(
+ "http://xml.org/sax/features/namespace-prefixes", true);
+ return factory.newSAXParser().getXMLReader();
+ } catch (SAXNotSupportedException se) {
+ throw new FOPException("Error: You need a parser which allows the"
+ + " http://xml.org/sax/features/namespace-prefixes"
+ + " feature to be set to true to support namespaces", se);
+ } catch (SAXException se) {
+ throw new FOPException("Couldn't create XMLReader", se);
+ } catch (ParserConfigurationException pce) {
+ throw new FOPException("Couldn't create XMLReader", pce);
+ }
+ }
+
+ /**
+ * Returns the fully qualified classname of the standard XML parser for FOP
+ * to use.
+ * @return the XML parser classname
+ */
+ public static final String getParserClassName() {
+ try {
+ return createParser().getClass().getName();
+ } catch (FOPException e) {
+ return null;
+ }
+ }
+}
+
diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java
new file mode 100644
index 000000000..024c5ad37
--- /dev/null
+++ b/src/java/org/apache/fop/apps/FOUserAgent.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 1999-2004 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.apps;
+
+// Java
+import java.util.Map;
+import java.io.IOException;
+import java.io.InputStream;
+
+// Avalon
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+
+// FOP
+import org.apache.fop.pdf.PDFEncryptionParams;
+
+/**
+ * The User Agent for fo.
+ * This user agent is used by the processing to obtain user configurable
+ * options.
+ *
+ * Renderer specific extensions (that do not produce normal areas on
+ * the output) will be done like so:
+ *
+ * The extension will create an area, custom if necessary
+ *
+ * this area will be added to the user agent with a key
+ *
+ * the renderer will know keys for particular extensions
+ *
+ * eg. bookmarks will be held in a special hierarchical area representing
+ * the title and bookmark structure
+ *
+ * These areas may contain resolveable areas that will be processed
+ * with other resolveable areas
+ */
+public class FOUserAgent implements LogEnabled {
+
+ private Logger log;
+ /** Map containing various default values */
+ public Map defaults = new java.util.HashMap();
+ /** Map containing XML handlers for various document types */
+ public Map handlers = new java.util.HashMap();
+ private String baseURL;
+ private PDFEncryptionParams pdfEncryptionParams;
+ private float px2mm = 0.35277777777777777778f; //72dpi (=25.4/dpi)
+
+ /**
+ * Sets the logger.
+ * @param log Logger to use
+ * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(Logger)
+ */
+ public void enableLogging(Logger log) {
+ this.log = log;
+ }
+
+ /**
+ * Returns the logger to use.
+ * @see org.apache.avalon.framework.logger.AbstractLogEnabled#getLogger()
+ * (todo) This breaks IoC/SoC. Should be improved.
+ */
+ public Logger getLogger() {
+ return this.log;
+ }
+
+ /**
+ * Sets the base URL.
+ * @param baseURL base URL
+ */
+ public void setBaseURL(String baseURL) {
+ this.baseURL = baseURL;
+ }
+
+ /**
+ * Returns the base URL.
+ * @return the base URL
+ */
+ public String getBaseURL() {
+ if ((this.baseURL == null) || (this.baseURL.trim().equals(""))) {
+ return "file:.";
+ } else {
+ return this.baseURL;
+ }
+ }
+
+ /**
+ * Returns the parameters for PDF encryption.
+ * @return the PDF encryption parameters, null if not applicable
+ */
+ public PDFEncryptionParams getPDFEncryptionParams() {
+ return pdfEncryptionParams;
+ }
+
+ /**
+ * Sets the parameters for PDF encryption.
+ * @param pdfEncryptionParams the PDF encryption parameters, null to
+ * disable PDF encryption
+ */
+ public void setPDFEncryptionParams(PDFEncryptionParams pdfEncryptionParams) {
+ this.pdfEncryptionParams = pdfEncryptionParams;
+ }
+
+
+ /**
+ * Get an input stream for a reference.
+ * Temporary solution until API better.
+ * @param uri URI to access
+ * @return InputStream for accessing the resource.
+ * @throws IOException in case of an I/O problem
+ */
+ public InputStream getStream(String uri) throws IOException {
+ return null;
+ }
+
+ /**
+ * Returns the conversion factor from pixel units to millimeters. This
+ * depends on the desired reolution.
+ * @return float conversion factor
+ */
+ public float getPixelUnitToMillimeter() {
+ return this.px2mm;
+ }
+
+ /**
+ * Sets the resolution in dpi.
+ * @param dpi resolution in dpi
+ */
+ public void setResolution(int dpi) {
+ this.px2mm = (float)(25.4 / dpi);
+ }
+
+ /**
+ * If to create hot links to footnotes and before floats.
+ * @return True if hot links dhould be created
+ */
+ public boolean linkToFootnotes() {
+ return true;
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/apps/XSLTInputHandler.java b/src/java/org/apache/fop/apps/XSLTInputHandler.java
new file mode 100644
index 000000000..9634f073f
--- /dev/null
+++ b/src/java/org/apache/fop/apps/XSLTInputHandler.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 1999-2004 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.apps;
+
+// Imported java.io classes
+import java.io.File;
+import java.util.Vector;
+
+// Imported TraX classes
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.SAXTransformerFactory;
+
+// Imported SAX classes
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.XMLFilter;
+
+/**
+ * XSLTInputHandler basically takes an XML file and transforms it with an XSLT
+ * file and the resulting XSL-FO document is input for FOP.
+ */
+public class XSLTInputHandler extends InputHandler {
+
+ private StreamSource xmlSource;
+ private Source xsltSource;
+ private Vector xsltParams = null; // not yet implemented
+
+ /**
+ * Constructor for files as input
+ * @param xmlfile XML file
+ * @param xsltfile XSLT file
+ * @param params Vector of command-line parameters (name, value,
+ * name, value, ...) for XSL stylesheet
+ * @throws FOPException if initializing the Transformer fails
+ */
+ public XSLTInputHandler(File xmlfile, File xsltfile, Vector params) throws FOPException {
+ this.xmlSource = new StreamSource(xmlfile);
+ this.xsltSource = new StreamSource(xsltfile);
+ xsltParams = params;
+ }
+
+ /**
+ * Constructor for files as input
+ * @param xmlfile XML file
+ * @param xsltfile XSLT file
+ * @throws FOPException if initializing the Transformer fails
+ * @deprecated Use JAXP instead.
+ */
+ public XSLTInputHandler(File xmlfile, File xsltfile) throws FOPException {
+ this.xmlSource = new StreamSource(xmlfile);
+ this.xsltSource = new StreamSource(xsltfile);
+ }
+
+ /**
+ * Constructor with URIs/URLs as input.
+ * @param xmlURL XML URL
+ * @param xsltURL XSLT URL
+ * @throws FOPException if initializing the Transformer fails
+ * @deprecated Use JAXP instead.
+ */
+ public XSLTInputHandler(String xmlURL, String xsltURL) throws FOPException {
+ this.xmlSource = new StreamSource(xmlURL);
+ this.xsltSource = new StreamSource(xsltURL);
+ }
+
+ /**
+ * Constructor with InputSources as input.
+ * @param xmlSource XML InputSource
+ * @param xsltSource XSLT InputSource
+ * @throws FOPException if initializing the Transformer fails
+ * @deprecated Use JAXP instead.
+ */
+ public XSLTInputHandler(InputSource xmlSource, InputSource xsltSource)
+ throws FOPException {
+ this.xmlSource = new StreamSource(xmlSource.getByteStream(),
+ xmlSource.getSystemId());
+ this.xsltSource = new StreamSource(xsltSource.getByteStream(),
+ xsltSource.getSystemId());
+ }
+
+ /**
+ * @see org.apache.fop.apps.InputHandler#getInputSource()
+ */
+ public InputSource getInputSource() {
+ InputSource is = new InputSource();
+ is.setByteStream(xmlSource.getInputStream());
+ is.setSystemId(xmlSource.getSystemId());
+ return is;
+ }
+
+ /**
+ * Overwrites this method of the super class and returns an XMLFilter
+ * instead of a simple XMLReader which allows chaining of transformations.
+ * @see org.apache.fop.apps.InputHandler#getParser()
+ */
+ public XMLReader getParser() throws FOPException {
+ return getXMLFilter(xsltSource, xsltParams);
+ }
+
+ /**
+ * Creates from the transformer an instance of an XMLFilter which
+ * then can be used in a chain with the XMLReader passed to Driver. This way
+ * during the conversion of the xml file + xslt stylesheet the resulting
+ * data is fed into Fop. This should help to avoid memory problems
+ * @param xsltSource An xslt stylesheet
+ * @return an XMLFilter which can be chained together with other
+ * XMLReaders or XMLFilters
+ * @throws FOPException if setting up the XMLFilter fails
+ */
+ public static XMLFilter getXMLFilter(Source xsltSource, Vector inParams) throws FOPException {
+ try {
+ // Instantiate a TransformerFactory.
+ TransformerFactory tFactory = TransformerFactory.newInstance();
+ // Determine whether the TransformerFactory supports The use of SAXSource
+ // and SAXResult
+ if (tFactory.getFeature(SAXSource.FEATURE)
+ && tFactory.getFeature(SAXResult.FEATURE)) {
+ // Cast the TransformerFactory to SAXTransformerFactory.
+ SAXTransformerFactory saxTFactory =
+ ((SAXTransformerFactory)tFactory);
+ // Create an XMLFilter for each stylesheet.
+ XMLFilter xmlfilter =
+ saxTFactory.newXMLFilter(xsltSource);
+
+/* if (inParams != null) {
+ Transformer transformer = ??? how to obtain from an XMLFilter?
+ int nParams = inParams.size();
+
+ for (int i = 0; i < nParams; i += 2) {
+ transformer.setParameter((String) inParams.elementAt(i),
+ (String) inParams.elementAt(i + 1));
+ }
+ }
+*/
+
+ // Create an XMLReader.
+ XMLReader parser = FOFileHandler.createParser();
+ if (parser == null) {
+ throw new FOPException("Unable to create SAX parser");
+ }
+
+ // xmlFilter1 uses the XMLReader as its reader.
+ xmlfilter.setParent(parser);
+ return xmlfilter;
+ } else {
+ throw new FOPException("Your parser doesn't support the "
+ + "features SAXSource and SAXResult."
+ + "\nMake sure you are using an XSLT engine which "
+ + "supports TrAX");
+ }
+ } catch (FOPException fe) {
+ throw fe;
+ } catch (Exception ex) {
+ throw new FOPException(ex);
+ }
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/area/LineArea.java b/src/java/org/apache/fop/area/LineArea.java
new file mode 100644
index 000000000..fa1d586db
--- /dev/null
+++ b/src/java/org/apache/fop/area/LineArea.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1999-2004 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.area;
+
+import org.apache.fop.area.inline.InlineArea;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The line area.
+ * This is a line area that contains inline areas.
+ */
+public class LineArea extends Area {
+ private int stacking = LR;
+ // contains inline areas
+ // has start indent and length, dominant baseline, height
+ private int startIndent;
+ private int length;
+
+ private int lineHeight;
+ // this is the offset for the dominant baseline
+ private int baseLine;
+
+ // this class can contain the dominant char styling info
+ // this means that many renderers can optimise a bit
+
+ private List inlineAreas = new ArrayList();
+
+ /**
+ * Set the height of this line area.
+ *
+ * @param height the height of the line area
+ */
+ public void setHeight(int height) {
+ lineHeight = height;
+ }
+
+ /**
+ * Get the height of this line area.
+ *
+ * @return the height of the line area
+ */
+ public int getHeight() {
+ return lineHeight;
+ }
+
+ /**
+ * Add a child area to this line area.
+ *
+ * @param childArea the inline child area to add
+ */
+ public void addChild(Area childArea) {
+ if (childArea instanceof InlineArea) {
+ addInlineArea((InlineArea)childArea);
+ }
+ }
+
+ /**
+ * Add an inline child area to this line area.
+ *
+ * @param area the inline child area to add
+ */
+ public void addInlineArea(InlineArea area) {
+ inlineAreas.add(area);
+ }
+
+ /**
+ * Get the inline child areas of this line area.
+ *
+ * @return the list of inline areas
+ */
+ public List getInlineAreas() {
+ return inlineAreas;
+ }
+
+ /**
+ * Set the start indent of this line area.
+ * The start indent is used for offsetting the start of
+ * the inline areas for alignment or other indents.
+ *
+ * @param si the start indent value
+ */
+ public void setStartIndent(int si) {
+ startIndent = si;
+ }
+
+ /**
+ * Get the start indent of this line area.
+ * The start indent is used for offsetting the start of
+ * the inline areas for alignment or other indents.
+ *
+ * @return the start indent value
+ */
+ public int getStartIndent() {
+ return startIndent;
+ }
+}
+
diff --git a/src/java/org/apache/fop/area/Page.java b/src/java/org/apache/fop/area/Page.java
new file mode 100644
index 000000000..49d74d7f2
--- /dev/null
+++ b/src/java/org/apache/fop/area/Page.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 1999-2004 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.area;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.apache.fop.fo.pagination.Region;
+
+/**
+ * The page.
+ * This holds the contents of the page. Each region is added.
+ * The unresolved references area added so that if the page is
+ * serialized then it will handle the resolving properly after
+ * being reloaded.
+ * This is serializable so it can be saved to cache to save
+ * memory if there are forward references.
+ * The page is cloneable so the page master can make copies of
+ * the top level page and regions.
+ */
+public class Page implements Serializable, Cloneable {
+ // contains before, start, body, end and after regions
+ private RegionViewport regionBefore = null;
+ private RegionViewport regionStart = null;
+ private RegionViewport regionBody = null;
+ private RegionViewport regionEnd = null;
+ private RegionViewport regionAfter = null;
+
+ // temporary map of unresolved objects used when serializing the page
+ private Map unresolved = null;
+
+ /**
+ * Set the region on this page.
+ *
+ * @param areaclass the area class of the region to set
+ * @param port the region viewport to set
+ */
+ public void setRegionViewport(int areaclass, RegionViewport port) {
+ if (areaclass == Region.BEFORE_CODE) {
+ regionBefore = port;
+ } else if (areaclass == Region.START_CODE) {
+ regionStart = port;
+ } else if (areaclass == Region.BODY_CODE) {
+ regionBody = port;
+ } else if (areaclass == Region.END_CODE) {
+ regionEnd = port;
+ } else if (areaclass == Region.AFTER_CODE) {
+ regionAfter = port;
+ }
+ }
+
+ /**
+ * Get the region from this page.
+ *
+ * @param areaclass the region area class
+ * @return the region viewport or null if none
+ */
+ public RegionViewport getRegionViewport(int areaclass) {
+ if (areaclass == Region.BEFORE_CODE) {
+ return regionBefore;
+ } else if (areaclass == Region.START_CODE) {
+ return regionStart;
+ } else if (areaclass == Region.BODY_CODE) {
+ return regionBody;
+ } else if (areaclass == Region.END_CODE) {
+ return regionEnd;
+ } else if (areaclass == Region.AFTER_CODE) {
+ return regionAfter;
+ }
+ return null;
+ }
+
+ /**
+ * Clone this page.
+ * This returns a new page with a clone of all the regions.
+ *
+ * @return a new clone of this page
+ */
+ public Object clone() {
+ Page p = new Page();
+ if (regionBefore != null) {
+ p.regionBefore = (RegionViewport)regionBefore.clone();
+ }
+ if (regionStart != null) {
+ p.regionStart = (RegionViewport)regionStart.clone();
+ }
+ if (regionBody != null) {
+ p.regionBody = (RegionViewport)regionBody.clone();
+ }
+ if (regionEnd != null) {
+ p.regionEnd = (RegionViewport)regionEnd.clone();
+ }
+ if (regionAfter != null) {
+ p.regionAfter = (RegionViewport)regionAfter.clone();
+ }
+
+ return p;
+ }
+
+ /**
+ * Set the unresolved references on this page for serializing.
+ *
+ * @param unres the map of unresolved objects
+ */
+ public void setUnresolvedReferences(Map unres) {
+ unresolved = unres;
+ }
+
+ /**
+ * Get the map unresolved references from this page.
+ * This should be called after deserializing to retrieve
+ * the map of unresolved references that were serialized.
+ *
+ * @return the de-serialized map of unresolved objects
+ */
+ public Map getUnresolvedReferences() {
+ return unresolved;
+ }
+}
+
diff --git a/src/java/org/apache/fop/fonts/BFEntry.java b/src/java/org/apache/fop/fonts/BFEntry.java
new file mode 100644
index 000000000..a367c91c1
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/BFEntry.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1999-2004 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.fonts;
+
+/**
+ * This is just a holder class for bfentries.
+ */
+public class BFEntry {
+
+ private int unicodeStart;
+ private int unicodeEnd;
+ private int glyphStartIndex;
+
+ /**
+ * Main constructor.
+ * @param unicodeStart Unicode start index
+ * @param unicodeEnd Unicode end index
+ * @param glyphStartIndex glyph start index
+ */
+ public BFEntry(int unicodeStart, int unicodeEnd, int glyphStartIndex) {
+ this.unicodeStart = unicodeStart;
+ this.unicodeEnd = unicodeEnd;
+ this.glyphStartIndex = glyphStartIndex;
+ }
+
+ /**
+ * Returns the unicodeStart.
+ * @return the Unicode start index
+ */
+ public int getUnicodeStart() {
+ return unicodeStart;
+ }
+
+ /**
+ * Returns the unicodeEnd.
+ * @return the Unicode end index
+ */
+ public int getUnicodeEnd() {
+ return unicodeEnd;
+ }
+
+ /**
+ * Returns the glyphStartIndex.
+ * @return the glyph start index
+ */
+ public int getGlyphStartIndex() {
+ return glyphStartIndex;
+ }
+
+}
diff --git a/src/java/org/apache/fop/fonts/CIDFont.java b/src/java/org/apache/fop/fonts/CIDFont.java
new file mode 100644
index 000000000..3214e484b
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/CIDFont.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2004 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.fonts;
+
+//Java
+import java.util.Map;
+
+/**
+ * Abstract base class for CID fonts.
+ */
+public abstract class CIDFont extends CustomFont {
+
+ /**
+ * usedGlyphs contains orginal, new glyph index
+ */
+ public Map usedGlyphs = new java.util.HashMap();
+
+ /**
+ * usedGlyphsIndex contains new glyph, original index
+ */
+ public Map usedGlyphsIndex = new java.util.HashMap();
+ public int usedGlyphsCount = 0;
+
+ //private PDFWArray warray = new PDFWArray();
+ public int width[] = null;
+
+ // ---- Required ----
+ /**
+ * Returns the name of the base font.
+ * @return the name of the base font
+ */
+ public abstract String getCidBaseFont();
+
+ /**
+ * Returns the type of the CID font.
+ * @return the type of the CID font
+ */
+ public abstract CIDFontType getCIDType();
+
+ /**
+ * Returns the name of the issuer of the font.
+ * @return a String identifying an issuer of character collections -
+ * for example, Adobe
+ */
+ public abstract String getRegistry();
+
+ /**
+ * Returns a font name for use within a registry.
+ * @return a String that uniquely names a character collection issued by
+ * a specific registry - for example, Japan1.
+ */
+ public abstract String getOrdering();
+
+ /**
+ * Returns the supplement number of the character collection.
+ * @return the supplement number
+ */
+ public abstract int getSupplement();
+
+
+ // ---- Optional ----
+ /**
+ * Returns the default width for this font.
+ * @return the default width
+ */
+ public int getDefaultWidth() {
+ return 0;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.Typeface#isMultiByte()
+ */
+ public boolean isMultiByte() {
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/src/java/org/apache/fop/fonts/CIDFontType.java b/src/java/org/apache/fop/fonts/CIDFontType.java
new file mode 100644
index 000000000..4a1ecff71
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/CIDFontType.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1999-2004 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.fonts;
+
+import org.apache.avalon.framework.ValuedEnum;
+
+/**
+ * This class enumerates all supported CID font types.
+ */
+public class CIDFontType extends ValuedEnum {
+
+ /**
+ * CID Font Type 0
+ */
+ public static final CIDFontType CIDTYPE0 = new CIDFontType("CIDFontType0", 0);
+
+ /**
+ * CID Font Type 2
+ */
+ public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 1);
+
+
+ /**
+ * @see org.apache.avalon.framework.Enum#Enum(String)
+ */
+ protected CIDFontType(String name, int value) {
+ super(name, value);
+ }
+
+
+ /**
+ * Returns the CIDFontType by name.
+ * @param name Name of the CID font type to look up
+ * @return FontType the CID font type
+ */
+ public static CIDFontType byName(String name) {
+ if (name.equalsIgnoreCase(CIDFontType.CIDTYPE0.getName())) {
+ return CIDFontType.CIDTYPE0;
+ } else if (name.equalsIgnoreCase(CIDFontType.CIDTYPE2.getName())) {
+ return CIDFontType.CIDTYPE2;
+ } else {
+ throw new IllegalArgumentException("Invalid CID font type: " + name);
+ }
+ }
+
+
+ /**
+ * Returns the CID FontType by value.
+ * @param value Value of the CID font type to look up
+ * @return FontType the CID font type
+ */
+ public static CIDFontType byValue(int value) {
+ if (value == CIDFontType.CIDTYPE0.getValue()) {
+ return CIDFontType.CIDTYPE0;
+ } else if (value == CIDFontType.CIDTYPE2.getValue()) {
+ return CIDFontType.CIDTYPE2;
+ } else {
+ throw new IllegalArgumentException("Invalid CID font type: " + value);
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java
new file mode 100644
index 000000000..cc29b77d6
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/CustomFont.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright 1999-2004 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.fonts;
+
+import java.util.Map;
+
+
+/**
+ * Abstract base class for custom fonts loaded from files, for example.
+ */
+public abstract class CustomFont extends Typeface
+ implements FontDescriptor, MutableFont {
+
+ private String fontName = null;
+ private String embedFileName = null;
+ private String embedResourceName = null;
+
+ private int capHeight = 0;
+ private int xHeight = 0;
+ private int ascender = 0;
+ private int descender = 0;
+ private int[] fontBBox = {0, 0, 0, 0};
+ private int flags = 4;
+ private int stemV = 0;
+ private int italicAngle = 0;
+ private int missingWidth = 0;
+ private FontType fontType = FontType.TYPE1;
+ private int firstChar = 0;
+ private int lastChar = 255;
+
+ private Map kerning = new java.util.HashMap();
+
+
+ private boolean useKerning = true;
+
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getFontName()
+ */
+ public String getFontName() {
+ return fontName;
+ }
+
+ /**
+ * Returns an URI representing an embeddable font file. The URI will often
+ * be a filename or an URL.
+ * @return URI to an embeddable font file or null if not available.
+ */
+ public String getEmbedFileName() {
+ return embedFileName;
+ }
+
+ /**
+ * Returns the lookup name to an embeddable font file available as a
+ * resource.
+ * (todo) Remove this method, this should be done using a resource: URI.
+ * @return the lookup name
+ */
+ public String getEmbedResourceName() {
+ return embedResourceName;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontDescriptor#getAscender()
+ */
+ public int getAscender() {
+ return ascender;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontDescriptor#getDescender()
+ */
+ public int getDescender() {
+ return descender;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontDescriptor#getCapHeight()
+ */
+ public int getCapHeight() {
+ return capHeight;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getAscender(int)
+ */
+ public int getAscender(int size) {
+ return size * ascender;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getDescender(int)
+ */
+ public int getDescender(int size) {
+ return size * descender;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getCapHeight(int)
+ */
+ public int getCapHeight(int size) {
+ return size * capHeight;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getXHeight(int)
+ */
+ public int getXHeight(int size) {
+ return size * xHeight;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontDescriptor#getFontBBox()
+ */
+ public int[] getFontBBox() {
+ return fontBBox;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontDescriptor#getFlags()
+ */
+ public int getFlags() {
+ return flags;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontDescriptor#getStemV()
+ */
+ public int getStemV() {
+ return stemV;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontDescriptor#getItalicAngle()
+ */
+ public int getItalicAngle() {
+ return italicAngle;
+ }
+
+ /**
+ * Returns the width to be used when no width is available.
+ * @return a character width
+ */
+ public int getMissingWidth() {
+ return missingWidth;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontDescriptor#getFontType()
+ */
+ public FontType getFontType() {
+ return fontType;
+ }
+
+ /**
+ * Returns the index of the first character defined in this font.
+ * @return the index of the first character
+ */
+ public int getFirstChar() {
+ return 0;
+ // return firstChar;
+ /**(todo) Why is this hardcoded??? This code was in SingleByteFont.java */
+ }
+
+ /**
+ * Returns the index of the last character defined in this font.
+ * @return the index of the last character
+ */
+ public int getLastChar() {
+ return lastChar;
+ }
+
+ /**
+ * Used to determine if kerning is enabled.
+ * @return True if kerning is enabled.
+ */
+ public boolean isKerningEnabled() {
+ return useKerning;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#hasKerningInfo()
+ */
+ public final boolean hasKerningInfo() {
+ return (isKerningEnabled() & kerning.isEmpty());
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getKerningInfo()
+ */
+ public final Map getKerningInfo() {
+ if (isKerningEnabled()) {
+ return kerning;
+ } else {
+ return java.util.Collections.EMPTY_MAP;
+ }
+ }
+
+
+ /* ---- MutableFont interface ---- */
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setFontName(String)
+ */
+ public void setFontName(String name) {
+ this.fontName = name;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setEmbedFileName(String)
+ */
+ public void setEmbedFileName(String path) {
+ this.embedFileName = path;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setEmbedResourceName(String)
+ */
+ public void setEmbedResourceName(String name) {
+ this.embedResourceName = name;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setCapHeight(int)
+ */
+ public void setCapHeight(int capHeight) {
+ this.capHeight = capHeight;
+ }
+
+ /**
+ * Returns the XHeight value of the font.
+ * @param xHeight the XHeight value
+ */
+ public void setXHeight(int xHeight) {
+ this.xHeight = xHeight;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setAscender(int)
+ */
+ public void setAscender(int ascender) {
+ this.ascender = ascender;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setDescender(int)
+ */
+ public void setDescender(int descender) {
+ this.descender = descender;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setFontBBox(int[])
+ */
+ public void setFontBBox(int[] bbox) {
+ this.fontBBox = bbox;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setFlags(int)
+ */
+ public void setFlags(int flags) {
+ this.flags = flags;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setStemV(int)
+ */
+ public void setStemV(int stemV) {
+ this.stemV = stemV;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setItalicAngle(int)
+ */
+ public void setItalicAngle(int italicAngle) {
+ this.italicAngle = italicAngle;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setMissingWidth(int)
+ */
+ public void setMissingWidth(int width) {
+ this.missingWidth = width;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setFontType(FontType)
+ */
+ public void setFontType(FontType fontType) {
+ this.fontType = fontType;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setFirstChar(int)
+ */
+ public void setFirstChar(int index) {
+ this.firstChar = index;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setLastChar(int)
+ */
+ public void setLastChar(int index) {
+ this.lastChar = index;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#setKerningEnabled(boolean)
+ */
+ public void setKerningEnabled(boolean enabled) {
+ this.useKerning = enabled;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.MutableFont#putKerningEntry(Integer, Map)
+ */
+ public void putKerningEntry(Integer key, Map value) {
+ this.kerning.put(key, value);
+ }
+
+}
diff --git a/src/java/org/apache/fop/fonts/EmbedFontInfo.java b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
new file mode 100644
index 000000000..63f3d3b0d
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1999-2004 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.fonts;
+
+import java.util.List;
+
+/**
+ * FontInfo contains meta information on fonts (where is the metrics file etc.)
+ */
+public class EmbedFontInfo {
+
+ private String metricsFile, embedFile;
+ private boolean kerning;
+ private List fontTriplets;
+
+ /**
+ * Main constructor
+ * @param metricsFile Path to the xml file containing font metrics
+ * @param kerning True if kerning should be enabled
+ * @param fontTriplets List of font triplets to associate with this font
+ * @param embedFile Path to the embeddable font file (may be null)
+ */
+ public EmbedFontInfo(String metricsFile, boolean kerning,
+ List fontTriplets, String embedFile) {
+ this.metricsFile = metricsFile;
+ this.embedFile = embedFile;
+ this.kerning = kerning;
+ this.fontTriplets = fontTriplets;
+ }
+
+ /**
+ * Returns the path to the metrics file
+ * @return the metrics file path
+ */
+ public String getMetricsFile() {
+ return metricsFile;
+ }
+
+ /**
+ * Returns the path to the embeddable font file
+ * @return the font file path
+ */
+ public String getEmbedFile() {
+ return embedFile;
+ }
+
+ /**
+ * Determines if kerning is enabled
+ * @return True if enabled
+ */
+ public boolean getKerning() {
+ return kerning;
+ }
+
+ /**
+ * Returns the list of font triplets associated with this font.
+ * @return List of font triplets
+ */
+ public List getFontTriplets() {
+ return fontTriplets;
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/fonts/FontReader.java b/src/java/org/apache/fop/fonts/FontReader.java
new file mode 100644
index 000000000..e5d5ecf32
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontReader.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 1999-2004 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.fonts;
+
+//Java
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+
+import javax.xml.parsers.SAXParserFactory;
+
+//SAX
+import org.xml.sax.XMLReader;
+import org.xml.sax.SAXException;
+import org.xml.sax.Locator;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.DefaultHandler;
+
+//FOP
+import org.apache.fop.apps.FOPException;
+
+/**
+ * Class for reading a metric.xml file and creating a font object.
+ * Typical usage:
+ *
+ * FontReader reader = new FontReader(+ */ +public class FontReader extends DefaultHandler { + + private Locator locator = null; + private boolean isCID = false; + private CustomFont returnFont = null; + private MultiByteFont multiFont = null; + private SingleByteFont singleFont = null; + private StringBuffer text = new StringBuffer(); + + private List cidWidths = null; + private int cidWidthIndex = 0; + + private Map currentKerning = null; + + private List bfranges = null; + + private void createFont(String path) throws FOPException { + XMLReader parser = null; + + try { + final SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + parser = factory.newSAXParser().getXMLReader(); + } catch (Exception e) { + throw new FOPException(e); + } + if (parser == null) { + throw new FOPException("Unable to create SAX parser"); + } + + try { + parser.setFeature("http://xml.org/sax/features/namespace-prefixes", + false); + } catch (SAXException e) { + throw new FOPException("You need a SAX parser which supports SAX version 2", + e); + } + + parser.setContentHandler(this); + + try { + parser.parse(path); + } catch (SAXException e) { + throw new FOPException(e); + } catch (IOException e) { + throw new FOPException(e); + } + + } + + /** + * Sets the path to embed a font. A null value disables font embedding. + * @param path URI for the embeddable file + */ + public void setFontEmbedPath(String path) { + returnFont.setEmbedFileName(path); + } + + /** + * Enable/disable use of kerning for the font + * @param enabled true to enable kerning, false to disable + */ + public void setKerningEnabled(boolean enabled) { + returnFont.setKerningEnabled(enabled); + } + + + /** + * Get the generated font object + * @return the font + */ + public Typeface getFont() { + return returnFont; + } + + /** + * Construct a FontReader object from a path to a metric.xml file + * and read metric data + * @param path URI to the font metric file + * @throws FOPException if loading the font fails + */ + public FontReader(String path) throws FOPException { + createFont(path); + } + + /** + * @see org.xml.sax.ContentHandler#startDocument() + */ + public void startDocument() { + } + + /** + * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator) + */ + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + /** + * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes) + */ + public void startElement(String uri, String localName, String qName, + Attributes attributes) { + if (localName.equals("font-metrics")) { + if ("TYPE0".equals(attributes.getValue("type"))) { + multiFont = new MultiByteFont(); + returnFont = multiFont; + isCID = true; + } else if ("TRUETYPE".equals(attributes.getValue("type"))) { + singleFont = new SingleByteFont(); + singleFont.setFontType(FontType.TRUETYPE); + returnFont = singleFont; + isCID = false; + } else { + singleFont = new SingleByteFont(); + singleFont.setFontType(FontType.TYPE1); + returnFont = singleFont; + isCID = false; + } + } else if ("embed".equals(localName)) { + returnFont.setEmbedFileName(attributes.getValue("file")); + returnFont.setEmbedResourceName(attributes.getValue("class")); + } else if ("cid-widths".equals(localName)) { + cidWidthIndex = getInt(attributes.getValue("start-index")); + cidWidths = new java.util.ArrayList(); + } else if ("kerning".equals(localName)) { + currentKerning = new java.util.HashMap(); + returnFont.putKerningEntry(new Integer(attributes.getValue("kpx1")), + currentKerning); + } else if ("bfranges".equals(localName)) { + bfranges = new java.util.ArrayList(); + } else if ("bf".equals(localName)) { + BFEntry entry = new BFEntry(getInt(attributes.getValue("us")), + getInt(attributes.getValue("ue")), + getInt(attributes.getValue("gi"))); + bfranges.add(entry); + } else if ("wx".equals(localName)) { + cidWidths.add(new Integer(attributes.getValue("w"))); + } else if ("widths".equals(localName)) { + //singleFont.width = new int[256]; + } else if ("char".equals(localName)) { + try { + singleFont.setWidth(Integer.parseInt(attributes.getValue("idx")), + Integer.parseInt(attributes.getValue("wdt"))); + } catch (NumberFormatException ne) { + System.out.println("Malformed width in metric file: " + + ne.getMessage()); + } + } else if ("pair".equals(localName)) { + currentKerning.put(new Integer(attributes.getValue("kpx2")), + new Integer(attributes.getValue("kern"))); + } + } + + private int getInt(String str) { + int ret = 0; + try { + ret = Integer.parseInt(str); + } catch (Exception e) { + /**@todo log this exception */ + } + return ret; + } + + /** + * @see org.xml.sax.ContentHandler#endElement(String, String, String) + */ + public void endElement(String uri, String localName, String qName) { + if ("font-name".equals(localName)) { + returnFont.setFontName(text.toString()); + } else if ("ttc-name".equals(localName) && isCID) { + multiFont.setTTCName(text.toString()); + } else if ("cap-height".equals(localName)) { + returnFont.setCapHeight(getInt(text.toString())); + } else if ("x-height".equals(localName)) { + returnFont.setXHeight(getInt(text.toString())); + } else if ("ascender".equals(localName)) { + returnFont.setAscender(getInt(text.toString())); + } else if ("descender".equals(localName)) { + returnFont.setDescender(getInt(text.toString())); + } else if ("left".equals(localName)) { + int[] bbox = returnFont.getFontBBox(); + bbox[0] = getInt(text.toString()); + returnFont.setFontBBox(bbox); + } else if ("bottom".equals(localName)) { + int[] bbox = returnFont.getFontBBox(); + bbox[1] = getInt(text.toString()); + returnFont.setFontBBox(bbox); + } else if ("right".equals(localName)) { + int[] bbox = returnFont.getFontBBox(); + bbox[2] = getInt(text.toString()); + returnFont.setFontBBox(bbox); + } else if ("top".equals(localName)) { + int[] bbox = returnFont.getFontBBox(); + bbox[3] = getInt(text.toString()); + returnFont.setFontBBox(bbox); + } else if ("first-char".equals(localName)) { + returnFont.setFirstChar(getInt(text.toString())); + } else if ("last-char".equals(localName)) { + returnFont.setLastChar(getInt(text.toString())); + } else if ("flags".equals(localName)) { + returnFont.setFlags(getInt(text.toString())); + } else if ("stemv".equals(localName)) { + returnFont.setStemV(getInt(text.toString())); + } else if ("italic-angle".equals(localName)) { + returnFont.setItalicAngle(getInt(text.toString())); + } else if ("missing-width".equals(localName)) { + returnFont.setMissingWidth(getInt(text.toString())); + } else if ("cid-type".equals(localName)) { + multiFont.setCIDType(CIDFontType.byName(text.toString())); + } else if ("default-width".equals(localName)) { + multiFont.setDefaultWidth(getInt(text.toString())); + } else if ("cid-widths".equals(localName)) { + int[] wds = new int[cidWidths.size()]; + int j = 0; + for (int count = 0; count < cidWidths.size(); count++) { + Integer i = (Integer)cidWidths.get(count); + wds[j++] = i.intValue(); + } + + //multiFont.addCIDWidthEntry(cidWidthIndex, wds); + multiFont.setWidthArray(wds); + + } else if ("bfranges".equals(localName)) { + multiFont.setBFEntries((BFEntry[])bfranges.toArray(new BFEntry[0])); + } + text.setLength(0); //Reset text buffer (see characters()) + } + + /** + * @see org.xml.sax.ContentHandler#characters(char[], int, int) + */ + public void characters(char[] ch, int start, int length) { + text.append(ch, start, length); + } + +} + + diff --git a/src/java/org/apache/fop/fonts/FontSetup.java b/src/java/org/apache/fop/fonts/FontSetup.java new file mode 100644 index 000000000..9c0c1e6f6 --- /dev/null +++ b/src/java/org/apache/fop/fonts/FontSetup.java @@ -0,0 +1,236 @@ +/* + * Copyright 1999-2004 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.fonts; + +// FOP +import org.apache.fop.apps.Document; + +// FOP (base 14 fonts) +import org.apache.fop.fonts.base14.Helvetica; +import org.apache.fop.fonts.base14.HelveticaBold; +import org.apache.fop.fonts.base14.HelveticaOblique; +import org.apache.fop.fonts.base14.HelveticaBoldOblique; +import org.apache.fop.fonts.base14.TimesRoman; +import org.apache.fop.fonts.base14.TimesBold; +import org.apache.fop.fonts.base14.TimesItalic; +import org.apache.fop.fonts.base14.TimesBoldItalic; +import org.apache.fop.fonts.base14.Courier; +import org.apache.fop.fonts.base14.CourierBold; +import org.apache.fop.fonts.base14.CourierOblique; +import org.apache.fop.fonts.base14.CourierBoldOblique; +import org.apache.fop.fonts.base14.Symbol; +import org.apache.fop.fonts.base14.ZapfDingbats; + +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; + +// Java +import java.util.List; + +/** + * Default fonts for FOP application; currently this uses PDF's fonts + * by default. + * + * Assigns the font (with metrics) to internal names like "F1" and + * assigns family-style-weight triplets to the fonts + */ +public class FontSetup { + + /** + * Sets up the font info object. + * + * Adds metrics for basic fonts and useful family-style-weight + * triplets for lookup. + * + * @param fontInfo the font info object to set up + * @param embedList ??? + */ + public static void setup(Document fontInfo, List embedList) { + + fontInfo.addMetrics("F1", new Helvetica()); + fontInfo.addMetrics("F2", new HelveticaOblique()); + fontInfo.addMetrics("F3", new HelveticaBold()); + fontInfo.addMetrics("F4", new HelveticaBoldOblique()); + fontInfo.addMetrics("F5", new TimesRoman()); + fontInfo.addMetrics("F6", new TimesItalic()); + fontInfo.addMetrics("F7", new TimesBold()); + fontInfo.addMetrics("F8", new TimesBoldItalic()); + fontInfo.addMetrics("F9", new Courier()); + fontInfo.addMetrics("F10", new CourierOblique()); + fontInfo.addMetrics("F11", new CourierBold()); + fontInfo.addMetrics("F12", new CourierBoldOblique()); + fontInfo.addMetrics("F13", new Symbol()); + fontInfo.addMetrics("F14", new ZapfDingbats()); + + // Custom type 1 fonts step 1/2 + // fontInfo.addMetrics("F15", new OMEP()); + // fontInfo.addMetrics("F16", new GaramondLightCondensed()); + // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic()); + + /* any is treated as serif */ + fontInfo.addFontProperties("F5", "any", "normal", Font.NORMAL); + fontInfo.addFontProperties("F6", "any", "italic", Font.NORMAL); + fontInfo.addFontProperties("F6", "any", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F7", "any", "normal", Font.BOLD); + fontInfo.addFontProperties("F8", "any", "italic", Font.BOLD); + fontInfo.addFontProperties("F8", "any", "oblique", Font.BOLD); + + fontInfo.addFontProperties("F1", "sans-serif", "normal", Font.NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", "italic", Font.NORMAL); + fontInfo.addFontProperties("F3", "sans-serif", "normal", Font.BOLD); + fontInfo.addFontProperties("F4", "sans-serif", "oblique", Font.BOLD); + fontInfo.addFontProperties("F4", "sans-serif", "italic", Font.BOLD); + fontInfo.addFontProperties("F5", "serif", "normal", Font.NORMAL); + fontInfo.addFontProperties("F6", "serif", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F6", "serif", "italic", Font.NORMAL); + fontInfo.addFontProperties("F7", "serif", "normal", Font.BOLD); + fontInfo.addFontProperties("F8", "serif", "oblique", Font.BOLD); + fontInfo.addFontProperties("F8", "serif", "italic", Font.BOLD); + fontInfo.addFontProperties("F9", "monospace", "normal", Font.NORMAL); + fontInfo.addFontProperties("F10", "monospace", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F10", "monospace", "italic", Font.NORMAL); + fontInfo.addFontProperties("F11", "monospace", "normal", Font.BOLD); + fontInfo.addFontProperties("F12", "monospace", "oblique", Font.BOLD); + fontInfo.addFontProperties("F12", "monospace", "italic", Font.BOLD); + + fontInfo.addFontProperties("F1", "Helvetica", "normal", Font.NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", "italic", Font.NORMAL); + fontInfo.addFontProperties("F3", "Helvetica", "normal", Font.BOLD); + fontInfo.addFontProperties("F4", "Helvetica", "oblique", Font.BOLD); + fontInfo.addFontProperties("F4", "Helvetica", "italic", Font.BOLD); + fontInfo.addFontProperties("F5", "Times", "normal", Font.NORMAL); + fontInfo.addFontProperties("F6", "Times", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F6", "Times", "italic", Font.NORMAL); + fontInfo.addFontProperties("F7", "Times", "normal", Font.BOLD); + fontInfo.addFontProperties("F8", "Times", "oblique", Font.BOLD); + fontInfo.addFontProperties("F8", "Times", "italic", Font.BOLD); + fontInfo.addFontProperties("F9", "Courier", "normal", Font.NORMAL); + fontInfo.addFontProperties("F10", "Courier", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F10", "Courier", "italic", Font.NORMAL); + fontInfo.addFontProperties("F11", "Courier", "normal", Font.BOLD); + fontInfo.addFontProperties("F12", "Courier", "oblique", Font.BOLD); + fontInfo.addFontProperties("F12", "Courier", "italic", Font.BOLD); + fontInfo.addFontProperties("F13", "Symbol", "normal", Font.NORMAL); + fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", Font.NORMAL); + + // Custom type 1 fonts step 2/2 + // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL); + // fontInfo.addFontProperties("F16", "Garamond-LightCondensed", "normal", FontInfo.NORMAL); + // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD); + + /* for compatibility with PassiveTex */ + fontInfo.addFontProperties("F5", "Times-Roman", "normal", Font.NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", "italic", Font.NORMAL); + fontInfo.addFontProperties("F7", "Times-Roman", "normal", Font.BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", "oblique", Font.BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", "italic", Font.BOLD); + fontInfo.addFontProperties("F5", "Times Roman", "normal", Font.NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", "oblique", Font.NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", "italic", Font.NORMAL); + fontInfo.addFontProperties("F7", "Times Roman", "normal", Font.BOLD); + fontInfo.addFontProperties("F8", "Times Roman", "oblique", Font.BOLD); + fontInfo.addFontProperties("F8", "Times Roman", "italic", Font.BOLD); + fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter", + "normal", Font.NORMAL); + + /* Add configured fonts */ + addConfiguredFonts(fontInfo, embedList, 15); + } + + /** + * Add fonts from configuration file starting with + * internalnames F); + * reader.setFontEmbedPath( ); + * reader.useKerning(true); + * Font f = reader.getFont(); + *
+ * + * The region may clip the area and it establishes a position from where + * the region is placed.
+ * + * @param port The region viewport to be rendered + */ + protected void renderRegionViewport(RegionViewport port) { + if (port != null) { + Rectangle2D view = port.getViewArea(); + // The CTM will transform coordinates relative to + // this region-reference area into page coords, so + // set origin for the region to 0,0. + currentBPPosition = 0; + currentIPPosition = 0; + currentBlockIPPosition = currentIPPosition; + + RegionReference region = port.getRegion(); + handleRegionTraits(port); + + // shouldn't the viewport have the CTM + startVParea(region.getCTM()); + // do after starting viewport area + if (region.getRegionClass() == Region.BODY_CODE) { + renderBodyRegion((BodyRegion) region); + } else { + renderRegion(region); + } + endVParea(); + } + } + + /** + * (todo) Description of the Method + * + * @param ctm The coordinate transformation matrix to use + */ + protected void startVParea(CTM ctm) { } + + /** + * Handle the traits for a region + * This is used to draw the traits for the given page region. + * (See Sect. 6.4.1.2 of XSL-FO spec.) + * @param rv the RegionViewport whose region is to be drawn + */ + protected void handleRegionTraits(RegionViewport rv) { + // draw border and background + } + + /** + * (todo) Description of the Method + */ + protected void endVParea() { } + + /** + * Renders a region reference area. + * + * @param region The region reference area + */ + protected void renderRegion(RegionReference region) { + List blocks = region.getBlocks(); + + renderBlocks(null, blocks); + + } + + /** + * Renders a body region area. + * + * @param region The body region + */ + protected void renderBodyRegion(BodyRegion region) { + BeforeFloat bf = region.getBeforeFloat(); + if (bf != null) { + renderBeforeFloat(bf); + } + MainReference mr = region.getMainReference(); + if (mr != null) { + renderMainReference(mr); + } + Footnote foot = region.getFootnote(); + if (foot != null) { + renderFootnote(foot); + } + } + + /** + * Renders a before float area. + * + * @param bf The before float area + */ + protected void renderBeforeFloat(BeforeFloat bf) { + List blocks = bf.getChildAreas(); + if (blocks != null) { + renderBlocks(null, blocks); + Block sep = bf.getSeparator(); + if (sep != null) { + renderBlock(sep); + } + } + } + + /** + * Renders a footnote + * + * @param footnote The footnote + */ + protected void renderFootnote(Footnote footnote) { + List blocks = footnote.getChildAreas(); + if (blocks != null) { + Block sep = footnote.getSeparator(); + if (sep != null) { + renderBlock(sep); + } + renderBlocks(null, blocks); + } + } + + /** + * Renders the main reference area. + *+ * The main reference area contains a list of spans that are + * stacked on the page. + * The spans contain a list of normal flow reference areas + * that are positioned into columns. + *
+ * + * @param mr The main reference area + */ + protected void renderMainReference(MainReference mr) { + int saveIPPos = currentIPPosition; + + Span span = null; + List spans = mr.getSpans(); + for (int count = 0; count < spans.size(); count++) { + span = (Span) spans.get(count); + int offset = (mr.getWidth() + - (span.getColumnCount() - 1) * mr.getColumnGap()) + / span.getColumnCount() + mr.getColumnGap(); + for (int c = 0; c < span.getColumnCount(); c++) { + Flow flow = (Flow) span.getFlow(c); + + renderFlow(flow); + currentIPPosition += offset; + } + currentIPPosition = saveIPPos; + currentBPPosition += span.getHeight(); + } + } + + /** + * Renders a flow reference area. + * + * @param flow The flow reference area + */ + protected void renderFlow(Flow flow) { + // the normal flow reference area contains stacked blocks + List blocks = flow.getChildAreas(); + if (blocks != null) { + renderBlocks(null, blocks); + } + } + + /** + * Handle block traits. + * This method is called when the correct ip and bp posiiton is + * set. This should be overridden to draw border and background + * traits for the block area. + * + * @param block the block area + */ + protected void handleBlockTraits(Block block) { + // draw border and background + } + + /** + * Renders a block viewport. + * + * @param bv The block viewport + * @param children The children to render within the block viewport + */ + protected void renderBlockViewport(BlockViewport bv, List children) { + // clip and position viewport if necessary + if (bv.getPositioning() == Block.ABSOLUTE) { + // save positions + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + CTM ctm = bv.getCTM(); + currentIPPosition = 0; + currentBPPosition = 0; + + startVParea(ctm); + handleBlockTraits(bv); + renderBlocks(bv, children); + endVParea(); + + // clip if necessary + + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } else { + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + handleBlockTraits(bv); + renderBlocks(bv, children); + + currentIPPosition = saveIP; + currentBPPosition = saveBP + bv.getHeight(); + } + } + + /** + * Renders a list of block areas. + * + * @param parent the parent block if the parent is a block, otherwise + * a null value. + * @param blocks The block areas + */ + protected void renderBlocks(Block parent, List blocks) { + // the position of the containing block is used for + // absolutely positioned areas + int contBP = currentBPPosition; + int contIP = currentIPPosition; + containingBPPosition = contBP; + containingIPPosition = contIP; + + for (int count = 0; count < blocks.size(); count++) { + Object obj = blocks.get(count); + if (obj instanceof Block) { + containingBPPosition = contBP; + containingIPPosition = contIP; + renderBlock((Block) obj); + containingBPPosition = contBP; + containingIPPosition = contIP; + } else { + // a line area is rendered from the top left position + // of the line, each inline object is offset from there + LineArea line = (LineArea) obj; + currentBlockIPPosition = + currentIPPosition + line.getStartIndent(); + renderLineArea(line); + currentBPPosition += line.getHeight(); + } + } + } + + /** + * Renders a block area. + * + * @param block The block area + */ + protected void renderBlock(Block block) { + List children = block.getChildAreas(); + if (children == null) { + handleBlockTraits(block); + // simply move position + currentBPPosition += block.getHeight(); + } else if (block instanceof BlockViewport) { + renderBlockViewport((BlockViewport) block, children); + } else { + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + if (block.getPositioning() == Block.ABSOLUTE) { + currentIPPosition = containingIPPosition + block.getXOffset(); + currentBPPosition = containingBPPosition + block.getYOffset(); + + handleBlockTraits(block); + + renderBlocks(block, children); + + // absolute blocks do not effect the layout + currentBPPosition = saveBP; + } else { + // relative blocks are offset + currentIPPosition += block.getXOffset(); + currentBPPosition += block.getYOffset(); + + handleBlockTraits(block); + + renderBlocks(block, children); + + // stacked and relative blocks effect stacking + currentBPPosition = saveBP + block.getHeight(); + } + currentIPPosition = saveIP; + } + } + + /** + * Renders a line area.+ * + * A line area may have grouped styling for its children such as underline, + * background.
+ * + * @param line The line area + */ + protected void renderLineArea(LineArea line) { + List children = line.getInlineAreas(); + + for (int count = 0; count < children.size(); count++) { + InlineArea inline = (InlineArea) children.get(count); + renderInlineArea(inline); + } + } + + protected void renderInlineArea(InlineArea inlineArea) { + if (inlineArea instanceof TextArea) { + renderText((TextArea) inlineArea); + } else if (inlineArea instanceof InlineParent) { + renderInlineParent((InlineParent) inlineArea); + } else if (inlineArea instanceof Space) { + renderInlineSpace((Space) inlineArea); + } else if (inlineArea instanceof Character) { + renderCharacter((Character) inlineArea); + } else if (inlineArea instanceof Viewport) { + renderViewport((Viewport) inlineArea); + } else if (inlineArea instanceof Leader) { + renderLeader((Leader) inlineArea); + } + } + + + /** @see org.apache.fop.render.Renderer */ + protected void renderCharacter(Character ch) { + currentBlockIPPosition += ch.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + protected void renderInlineSpace(Space space) { + // an inline space moves the inline progression position + // for the current block by the width or height of the space + // it may also have styling (only on this object) that needs + // handling + currentBlockIPPosition += space.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + protected void renderLeader(Leader area) { + currentBlockIPPosition += area.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + protected void renderText(TextArea text) { + currentBlockIPPosition += text.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + protected void renderInlineParent(InlineParent ip) { + int saveIP = currentBlockIPPosition; + Iterator iter = ip.getChildAreas().iterator(); + while (iter.hasNext()) { + renderInlineArea((InlineArea) iter.next()); + } + currentBlockIPPosition = saveIP + ip.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + protected void renderViewport(Viewport viewport) { + Area content = viewport.getContent(); + int saveBP = currentBPPosition; + currentBPPosition += viewport.getOffset(); + Rectangle2D contpos = viewport.getContentPosition(); + if (content instanceof Image) { + renderImage((Image) content, contpos); + } else if (content instanceof Container) { + renderContainer((Container) content); + } else if (content instanceof ForeignObject) { + renderForeignObject((ForeignObject) content, contpos); + } + currentBlockIPPosition += viewport.getWidth(); + currentBPPosition = saveBP; + } + + /** + * Renders an image area. + * + * @param image The image + * @param pos The target position of the image + * (todo) Make renderImage() protected + */ + public void renderImage(Image image, Rectangle2D pos) { + // Default: do nothing. + // Some renderers (ex. Text) don't support images. + } + + /** @see org.apache.fop.render.Renderer */ + public void renderContainer(Container cont) { + int saveIP = currentIPPosition; + currentIPPosition = currentBlockIPPosition; + int saveBlockIP = currentBlockIPPosition; + int saveBP = currentBPPosition; + + List blocks = cont.getBlocks(); + renderBlocks(null, blocks); + currentIPPosition = saveIP; + currentBlockIPPosition = saveBlockIP; + currentBPPosition = saveBP; + } + + /** + * Renders a foreign object area. + * + * @param fo The foreign object area + * @param pos The target position of the foreign object + * (todo) Make renderForeignObject() protected + */ + public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { + // Default: do nothing. + // Some renderers (ex. Text) don't support foreign objects. + } + + /** + * Set the default xml handler for the given mime type. + * @param mime MIME type + * @param handler XMLHandler to use + */ + public void setDefaultXMLHandler(FOUserAgent foua, String mime, + XMLHandler handler) { + foua.defaults.put(mime, handler); + } + + /** + * Add an xml handler for the given mime type and xml namespace. + * @param mime MIME type + * @param ns Namespace URI + * @param handler XMLHandler to use + */ + public void addXMLHandler(FOUserAgent foua, String mime, String ns, + XMLHandler handler) { + Map mh = (Map) foua.handlers.get(mime); + if (mh == null) { + mh = new java.util.HashMap(); + foua.handlers.put(mime, mh); + } + mh.put(ns, handler); + } + + /** + * Render the xml document with the given xml namespace. + * The Render Context is by the handle to render into the current + * rendering target. + * @param ctx rendering context + * @param doc DOM Document containing the source document + * @param namespace Namespace URI of the document + */ + public void renderXML(FOUserAgent foua, RendererContext ctx, Document doc, + String namespace) { + String mime = ctx.getMimeType(); + Map mh = (Map) foua.handlers.get(mime); + XMLHandler handler = null; + if (mh != null) { + handler = (XMLHandler) mh.get(namespace); + } + if (handler == null) { + handler = (XMLHandler) foua.defaults.get(mime); + } + if (handler != null) { + try { + handler.handleXML(ctx, doc, namespace); + } catch (Throwable t) { + // could not handle document + getLogger().error("Some XML content will be ignored. " + + "Could not render XML", t); + } + } else { + // no handler found for document + getLogger().warn("Some XML content will be ignored. " + + "No handler defined for XML: " + namespace); + } + } +} + diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java new file mode 100644 index 000000000..edeb1b542 --- /dev/null +++ b/src/java/org/apache/fop/render/PrintRenderer.java @@ -0,0 +1,48 @@ +/* + * Copyright 1999-2004 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; + +// FOP +import org.apache.fop.apps.Document; +import org.apache.fop.fo.FOTreeControl; +import org.apache.fop.fonts.FontSetup; + +// Java +import java.util.List; + +/** Abstract base class of "Print" type renderers. */ +public abstract class PrintRenderer extends AbstractRenderer { + + /** Font configuration */ + protected FOTreeControl fontInfo; + + /** list of fonts */ + protected List fontList = null; + + /** + * Set up the font info + * + * @param fontInfo font info to set up + */ + public void setupFontInfo(FOTreeControl foTreeControl) { + this.fontInfo = foTreeControl; + FontSetup.setup((Document)fontInfo, fontList); + } + +} diff --git a/src/java/org/apache/fop/render/Renderer.java b/src/java/org/apache/fop/render/Renderer.java new file mode 100644 index 000000000..ef5f4526f --- /dev/null +++ b/src/java/org/apache/fop/render/Renderer.java @@ -0,0 +1,190 @@ +/* + * Copyright 1999-2004 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; + +// Java +import java.io.OutputStream; +import java.io.IOException; +import java.util.Date; +import java.util.Map; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Title; +import org.apache.fop.area.TreeExt; +import org.apache.fop.area.inline.Container; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.inline.Leader; +import org.apache.fop.area.inline.Space; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.area.inline.TextArea; +import org.apache.fop.fo.FOTreeControl; +import org.apache.fop.apps.FOUserAgent; + +/** + * Interface implemented by all renderers. This interface is used to control + * the rendering of pages and to let block and inline level areas call the + * appropriate method to render themselves.+ * + * A Renderer implementation takes areas/spaces and produces output in some + * format.
+ * + * Typically, most renderers are subclassed from FOP's abstract implementations + * ({@link AbstractRenderer}, {@link PrintRenderer}) which already handle a lot + * of things letting you concentrate on the details of the output format. + */ +public interface Renderer { + + /** + * Role constant for Avalon. + */ + String ROLE = Renderer.class.getName(); + + + /** + * Initiates the rendering phase. + * This must only be called once for a rendering. If + * stopRenderer is called then this may be called again + * for a new document rendering. + * + * @param outputStream The OutputStream to use for output + * @exception IOException If an I/O error occurs + */ + void startRenderer(OutputStream outputStream) + throws IOException; + + /** + * Signals the end of the rendering phase. + * The renderer should reset to an initial state and dispose of + * any resources for the completed rendering. + * + * @exception IOException If an I/O error occurs + */ + void stopRenderer() + throws IOException; + + /** + * Set the User Agent. + * + * @param agent The User Agent + */ + void setUserAgent(FOUserAgent agent); + + /** + * Set up the given FontInfo. + * + * @param fontInfo The fonts + */ + void setupFontInfo(FOTreeControl foTreeControl); + + /** + * Set up renderer options. + * + * @param options The Configuration for the renderer + */ + void setOptions(Map options); + + /** + * Set the producer of the rendering. If this method isn't called the + * renderer uses a default. Note: Not all renderers support this feature. + * + * @param producer The name of the producer (normally "FOP") to be + * embedded in the generated file. + */ + void setProducer(String producer); + + /** + * Set the creator of the document to be rendered. + * If this method isn't called the renderer uses a default. + * Note: Not all renderers support this feature. + * + * @param creator The name of the document creator + */ + void setCreator(String creator); + + /** + * Set the creator date/timeof the document to be rendered. + * If this method isn't called the renderer uses the current date/time + * as default. + * Note: Not all renderers support this feature. + * + * @param date The name of the document creator + */ + void setCreationDate(Date date); + + /** + * Reports if out of order rendering is supported.
+ * + * Normally, all pages of a document are rendered in their natural order + * (page 1, page 2, page 3 etc.). Some output formats (such as PDF) allow + * pages to be output in random order. This is helpful to reduce resource + * strain on the system because a page that cannot be fully resolved + * doesn't block subsequent pages that are already fully resolved.
+ * + * @return True if this renderer supports out of order rendering. + */ + boolean supportsOutOfOrder(); + + /** + * Tells the renderer to render an extension element. + * + * @param ext The extension element to be rendered + */ + void renderExtension(TreeExt ext); + + /** + * This is called if the renderer supports out of order rendering. The + * renderer should prepare the page so that a page further on in the set of + * pages can be rendered. The body of the page should not be rendered. The + * page will be rendered at a later time by the call to {@link + * #renderPage(PageViewport)}. + * + * @param page The page viewport to use + */ + void preparePage(PageViewport page); + + /** + * Tells the renderer that a new page sequence starts. + * + * @param seqTitle The title of the page sequence + */ + void startPageSequence(Title seqTitle); + + /** + * Tells the renderer to render a particular page. A renderer typically + * reponds by packing up the current page and writing it immediately to the + * output device. + * + * @param page The page to be rendered + * @exception IOException if an I/O error occurs + * @exception FOPException if a FOP interal error occurs. + */ + void renderPage(PageViewport page) + throws IOException, FOPException; + + /** + * Tells the renderer to render an inline container. + * + * @param cont The inline container area + */ + void renderContainer(Container cont); + +} + diff --git a/src/java/org/apache/fop/render/RendererContext.java b/src/java/org/apache/fop/render/RendererContext.java new file mode 100644 index 000000000..998a53701 --- /dev/null +++ b/src/java/org/apache/fop/render/RendererContext.java @@ -0,0 +1,95 @@ +/* + * Copyright 1999-2004 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; + +//Java +import java.util.Map; + +//FOP +import org.apache.fop.apps.FOUserAgent; + +/** + * The Render Context for external handlers. This provides a rendering context + * so that external handlers can get information to be able to render to the + * render target. + */ +public class RendererContext { + + private String mime; + private FOUserAgent userAgent; + private Map props = new java.util.HashMap(); + + /** + * Contructor for this class. It takes a MIME type as parameter. + * + * @param m The MIME type of the output that's generated. + */ + public RendererContext(String m) { + mime = m; + } + + /** + * Returns the MIME type associated with this RendererContext. + * + * @return The MIME type (ex. application/pdf) + */ + public String getMimeType() { + return mime; + } + + /** + * Sets the user agent. + * + * @param ua The user agent + */ + public void setUserAgent(FOUserAgent ua) { + userAgent = ua; + } + + /** + * Returns the user agent. + * + * @return The user agent + */ + public FOUserAgent getUserAgent() { + return userAgent; + } + + /** + * Sets a property on the RendererContext. + * + * @param name The key of the property + * @param val The value of the property + */ + public void setProperty(String name, Object val) { + props.put(name, val); + } + + /** + * Returns a property from the RendererContext. + * + * @param prop The key of the property to return. + * @return The requested value,null
if it doesn't exist.
+ */
+ public Object getProperty(String prop) {
+ return props.get(prop);
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/render/XMLHandler.java b/src/java/org/apache/fop/render/XMLHandler.java
new file mode 100644
index 000000000..4942a5ae3
--- /dev/null
+++ b/src/java/org/apache/fop/render/XMLHandler.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 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;
+
+import org.w3c.dom.Document;
+
+/**
+ * This interface is implemented by classes that can handle a certain type
+ * of foreign objects.
+ */
+public interface XMLHandler {
+
+ /**
+ * Handle an external xml document inside a Foreign Object Area. + * + * This may throw an exception if for some reason it cannot be handled. The + * caller is expected to deal with this exception.
+ * + * @param context The RendererContext (contains the user agent) + * @param doc A DOM containing the foreign object to be + * processed + * @param ns The Namespace of the foreign object + * @exception Exception If an error occurs during processing. + */ + void handleXML(RendererContext context, Document doc, String ns) + throws Exception; + +} + diff --git a/src/java/org/apache/fop/render/awt/AWTFontMetrics.java b/src/java/org/apache/fop/render/awt/AWTFontMetrics.java new file mode 100644 index 000000000..4d0ec8d08 --- /dev/null +++ b/src/java/org/apache/fop/render/awt/AWTFontMetrics.java @@ -0,0 +1,283 @@ +/* + * Copyright 1999-2004 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; + +// Java +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.awt.FontMetrics; +import java.awt.font.TextLayout; + +/** + * This is a FontMetrics to be used for AWT rendering. + * It instanciates a font, depening on family and style + * values. The java.awt.FontMetrics for this font is then + * created to be used for the actual measurement. + * Since layout is word by word and since it is expected that + * two subsequent words often share the same style, the + * Font and FontMetrics is buffered and only changed if needed. + *
+ * Since FontState and FontInfo multiply all factors by
+ * size, we assume a "standard" font of FONT_SIZE.
+ */
+public class AWTFontMetrics {
+
+ /**
+ * Font size standard used for metric measurements
+ */
+ public static final int FONT_SIZE = 1;
+
+ /**
+ * This factor multiplies the calculated values to scale
+ * to FOP internal measurements
+ */
+ public static final int FONT_FACTOR = (1000 * 1000) / FONT_SIZE;
+
+ /**
+ * The width of all 256 character, if requested
+ */
+ private int width[] = null;
+
+ /**
+ * The typical height of a small cap latter
+ */
+ private int xHeight = 0;
+
+ /**
+ * Buffered font.
+ * f1 is bufferd for metric measurements during layout.
+ * fSized is buffered for display purposes
+ */
+ private Font f1 = null; // , fSized = null;
+
+ /**
+ * The family type of the font last used
+ */
+ private String family = "";
+
+ /**
+ * The style of the font last used
+ */
+ private int style = 0;
+
+ /**
+ * The size of the font last used
+ */
+ private float size = 0;
+
+ /**
+ * The FontMetrics object used to calculate character width etc.
+ */
+ private FontMetrics fmt = null;
+
+ /**
+ * Temp graphics object needed to get the font metrics
+ */
+ private Graphics2D graphics;
+
+ /**
+ * Constructs a new Font-metrics.
+ * @param graphics a temp graphics object - this is needed so
+ * that we can get an instance of java.awt.FontMetrics
+ */
+ public AWTFontMetrics(Graphics2D graphics) {
+ this.graphics = graphics;
+ }
+
+ /**
+ * Determines the font ascent of the Font described by this
+ * FontMetrics object
+ * @param family font family (java name) to use
+ * @param style font style (java def.) to use
+ * @param size font size
+ * @return ascent in milliponts
+ */
+ public int getAscender(String family, int style, int size) {
+ setFont(family, style, size);
+ // return (int)(FONT_FACTOR * fmt.getAscent());
+
+ // workaround for sun bug on FontMetrics.getAscent()
+ // http://developer.java.sun.com/developer/bugParade/bugs/4399887.html
+ int realAscent = fmt.getAscent()
+ - (fmt.getDescent() + fmt.getLeading());
+ return FONT_FACTOR * realAscent;
+ }
+
+
+ /**
+ * The size of a capital letter measured from the font's baseline
+ * @param family font family
+ * @param style font style
+ * @param size font size
+ * @return capital height in millipoints
+ */
+ public int getCapHeight(String family, int style, int size) {
+ // currently just gets Ascent value but maybe should use
+ // getMaxAcent() at some stage
+ return getAscender(family, style, size);
+ }
+
+ /**
+ * Determines the font descent of the Font described by this
+ * FontMetrics object
+ * @param family font family (jave name) to use
+ * @param style font style (jave def.) to use
+ * @param size font size
+ * @return descent in milliponts
+ */
+ public int getDescender(String family, int style, int size) {
+ setFont(family, style, size);
+ return (-1 * FONT_FACTOR * fmt.getDescent());
+ }
+
+ /**
+ * Determines the typical font height of a small cap letter
+ * FontMetrics object
+ * @param family font family (jave name) to use
+ * @param style font style (jave def.) to use
+ * @param size font size
+ * @return font height in milliponts
+ */
+ public int getXHeight(String family, int style, int size) {
+ setFont(family, style, size);
+ return (int)(FONT_FACTOR * xHeight);
+ }
+
+ /**
+ * Returns width (in 1/1000ths of point size) of character at
+ * code point i
+ * @param i the character for which to get the width
+ * @param family font family (jave name) to use
+ * @param style font style (jave def.) to use
+ * @param size font size
+ * @return character width in millipoints
+ */
+ public int width(int i, String family, int style, int size) {
+ int w;
+ setFont(family, style, size);
+ // the output seems to look a little better if the
+ // space is rendered larger than given by
+ // the FontMetrics object
+ if (i <= 32) {
+ w = (int)(1.4 * fmt.charWidth(i) * FONT_FACTOR);
+ } else {
+ w = (int)(fmt.charWidth(i) * FONT_FACTOR);
+ }
+ return w;
+ }
+
+ /**
+ * Return widths (in 1/1000ths of point size) of all
+ * characters
+ * @param family font family (jave name) to use
+ * @param style font style (jave def.) to use
+ * @param size font size
+ * @return array of character widths in millipoints
+ */
+ public int[] getWidths(String family, int style, int size) {
+ int i;
+
+ if (width == null) {
+ width = new int[256];
+ }
+ setFont(family, style, size);
+ for (i = 0; i < 256; i++) {
+ width[i] = FONT_FACTOR * fmt.charWidth(i);
+ }
+ return width;
+ }
+
+ /**
+ * Checks whether the font for which values are
+ * requested is the one used immediately before or
+ * whether it is a new one
+ * @param family font family (jave name) to use
+ * @param style font style (jave def.) to use
+ * @param size font size
+ * @return true if the font was changed, false otherwise
+ */
+ private boolean setFont(String family, int style, int size) {
+ boolean changed = false;
+ Rectangle2D rect;
+ TextLayout layout;
+ int s = (int)(size / 1000f);
+
+ if (f1 == null) {
+ f1 = new Font(family, style, s);
+ fmt = graphics.getFontMetrics(f1);
+ changed = true;
+ } else {
+ if ((this.style != style) || !this.family.equals(family)
+ || this.size != s) {
+ if (family.equals(this.family)) {
+ f1 = f1.deriveFont(style, (float)s);
+ } else {
+ f1 = new Font(family, style, s);
+ }
+ fmt = graphics.getFontMetrics(f1);
+ changed = true;
+ }
+ // else the font is unchanged from last time
+ }
+ if (changed) {
+ layout = new TextLayout("m", f1, graphics.getFontRenderContext());
+ rect = layout.getBounds();
+ xHeight = (int)rect.getHeight();
+ }
+ // save the family and style for later comparison
+ this.family = family;
+ this.style = style;
+ this.size = s;
+ return changed;
+ }
+
+
+ /**
+ * Returns a java.awt.Font instance for the desired
+ * family, style and size type.
+ * This is here, so that the font-mapping
+ * of FOP-defined fonts to java-fonts can be done
+ * in one place and does not need to occur in
+ * AWTFontRenderer.
+ * @param family font family (jave name) to use
+ * @param style font style (jave def.) to use
+ * @param size font size
+ * @return font with the desired characeristics.
+ */
+ public java.awt.Font getFont(String family, int style, int size) {
+ setFont(family, style, size);
+ return f1;
+ /*
+ * if( setFont(family,style, size) ) fSized = null;
+ * if( fSized == null || this.size != size ) {
+ * fSized = f1.deriveFont( size / 1000f );
+ * }
+ * this.size = size;
+ * return fSized;
+ */
+ }
+
+}
+
+
+
+
+
+
diff --git a/src/java/org/apache/fop/render/awt/AWTPrintRenderer.java b/src/java/org/apache/fop/render/awt/AWTPrintRenderer.java
new file mode 100644
index 000000000..5b057959a
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/AWTPrintRenderer.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 1999-2004 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.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.io.IOException;
+import java.util.Vector;
+
+public class AWTPrintRenderer extends AWTRenderer {
+
+ private static final int EVEN_AND_ALL = 0;
+ private static final int EVEN = 1;
+ private static final int ODD = 2;
+
+ private int startNumber;
+ private int endNumber;
+ private int mode = EVEN_AND_ALL;
+ private int copies = 1;
+ private PrinterJob printerJob;
+
+ public AWTPrintRenderer() {
+ initialize();
+ }
+
+ private void initialize() throws IllegalArgumentException {
+ // read from command-line options
+ copies = getIntProperty("copies", 1);
+ startNumber = getIntProperty("start", 1) - 1;
+ endNumber = getIntProperty("end", -1);
+ String str = System.getProperty("even");
+ if (str != null) {
+ mode = Boolean.valueOf(str).booleanValue() ? EVEN : ODD;
+ }
+
+ printerJob = PrinterJob.getPrinterJob();
+ printerJob.setJobName("FOP Document");
+ printerJob.setCopies(copies);
+ if (System.getProperty("dialog") != null) {
+ if (!printerJob.printDialog()) {
+ throw new IllegalArgumentException("Printing cancelled by operator");
+ }
+ }
+ printerJob.setPageable(this);
+ }
+
+ public void stopRenderer() throws IOException {
+ super.stopRenderer();
+
+ if (endNumber == -1) {
+ endNumber = getNumberOfPages();
+ }
+
+ Vector numbers = getInvalidPageNumbers();
+ for (int i = numbers.size() - 1; i > -1; i--) {
+ // removePage(Integer.parseInt((String)numbers.elementAt(i)));
+ }
+
+ try {
+ printerJob.print();
+ } catch (PrinterException e) {
+ e.printStackTrace();
+ throw new IOException("Unable to print: "
+ + e.getClass().getName()
+ + ": " + e.getMessage());
+ }
+ }
+
+ public static int getIntProperty(String name, int def) {
+ String propValue = System.getProperty(name);
+ if (propValue != null) {
+ try {
+ return Integer.parseInt(propValue);
+ } catch (Exception e) {
+ return def;
+ }
+ } else {
+ return def;
+ }
+ }
+
+ private Vector getInvalidPageNumbers() {
+ Vector vec = new Vector();
+ int max = getNumberOfPages();
+ boolean isValid;
+ for (int i = 0; i < max; i++) {
+ isValid = true;
+ if (i < startNumber || i > endNumber) {
+ isValid = false;
+ } else if (mode != EVEN_AND_ALL) {
+ if (mode == EVEN && ((i + 1) % 2 != 0)) {
+ isValid = false;
+ } else if (mode == ODD && ((i + 1) % 2 != 1)) {
+ isValid = false;
+ }
+ }
+
+ if (!isValid) {
+ vec.add(i + "");
+ }
+ }
+ return vec;
+ }
+} // class AWTPrintRenderer
+
diff --git a/src/java/org/apache/fop/render/awt/AWTRenderer.java b/src/java/org/apache/fop/render/awt/AWTRenderer.java
new file mode 100644
index 000000000..684c2a549
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/AWTRenderer.java
@@ -0,0 +1,465 @@
+/*
+ * Copyright 1999-2004 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;
+
+/*
+ * 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.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Toolkit;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Printable;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.fop.apps.Document;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.InputHandler;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Page;
+import org.apache.fop.area.PageViewport;
+import org.apache.fop.area.RegionViewport;
+import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.TextArea;
+import org.apache.fop.datatypes.ColorType;
+import org.apache.fop.fo.FOTreeControl;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.image.ImageFactory;
+import org.apache.fop.render.AbstractRenderer;
+import org.apache.fop.traits.BorderProps;
+import org.apache.fop.render.awt.FontMetricsMapper;
+import org.apache.fop.render.awt.viewer.PreviewDialog;
+import org.apache.fop.render.awt.viewer.Translator;
+
+/**
+ * This is FOP's AWT renderer.
+ */
+public class AWTRenderer extends AbstractRenderer implements Printable, Pageable {
+
+ protected double scaleFactor = 100.0;
+ protected int pageNumber = 0;
+ private int pageWidth = 0;
+ private int pageHeight = 0;
+ private Vector pageViewportList = new java.util.Vector();
+ private Vector pageList = new java.util.Vector();
+ private Vector bufferedImageList = new java.util.Vector();
+ private BufferedImage currentPageImage = null;
+
+ /** Font configuration */
+ protected Document fontInfo;
+
+ /**
+ The InputHandler associated with this Renderer.
+ Sent to the PreviewDialog for document reloading.
+ */
+ private InputHandler inputHandler;
+
+ /**
+ * The resource bundle used for AWT messages.
+ */
+ protected Translator translator = null;
+
+ private Map fontNames = new java.util.Hashtable();
+ private Map fontStyles = new java.util.Hashtable();
+ private Color saveColor = null;
+
+ /**
+ * The preview dialog frame used for display of the documents.
+ * Also used as the AWT Component for FontSetup in generating
+ * valid font measures.
+ */
+ protected PreviewDialog frame;
+
+ public AWTRenderer(InputHandler handler) {
+ inputHandler = handler;
+ translator = new Translator();
+ createPreviewDialog(inputHandler);
+ }
+
+ public AWTRenderer() {
+ translator = new Translator();
+ createPreviewDialog(null);
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer
+ */
+ public boolean supportsOutOfOrder() {
+ return false;
+ }
+
+ public Translator getTranslator() {
+ return translator;
+ }
+
+ public void setupFontInfo(FOTreeControl foTreeControl) {
+ // create a temp Image to test font metrics on
+ fontInfo = (Document) foTreeControl;
+ BufferedImage fontImage =
+ new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
+ FontSetup.setup(fontInfo, fontImage.createGraphics());
+ }
+
+ public int getPageNumber() {
+ return pageNumber;
+ }
+
+ public void setPageNumber(int aValue) {
+ pageNumber = aValue;
+ }
+
+ public void setScaleFactor(double newScaleFactor) {
+ scaleFactor = newScaleFactor;
+ }
+
+ public double getScaleFactor() {
+ return scaleFactor;
+ }
+
+ public void startRenderer(OutputStream out)
+ throws IOException {
+ // empty pageViewportList, in case of a reload from PreviewDialog
+ pageViewportList.removeAllElements();
+ pageList.removeAllElements();
+ bufferedImageList.removeAllElements();
+ System.out.println("\nRegion Types: 0-Before/Top, 1-Start/Left, 2-Body, 3-End/Right, 4-After/Bottom");
+ }
+
+ public void stopRenderer()
+ throws IOException {
+ frame.setStatus(translator.getString("Status.Show"));
+ frame.showPage();
+ }
+
+ // Printable Interface
+ public PageFormat getPageFormat(int pos) {
+ return null;
+ }
+
+ public Printable getPrintable(int pos) {
+ return null;
+ }
+
+ public int getNumberOfPages() {
+ return pageViewportList.size();
+ }
+
+ public int print(Graphics g, PageFormat format, int pos) {
+ return 0;
+ }
+
+ private PreviewDialog createPreviewDialog(InputHandler handler) {
+ frame = new PreviewDialog(this, handler);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosed(WindowEvent we) {
+ System.exit(0);
+ }
+ });
+
+ //Centers the window
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension frameSize = frame.getSize();
+ if (frameSize.height > screenSize.height) {
+ frameSize.height = screenSize.height;
+ }
+ if (frameSize.width > screenSize.width) {
+ frameSize.width = screenSize.width;
+ }
+ frame.setLocation((screenSize.width - frameSize.width) / 2,
+ (screenSize.height - frameSize.height) / 2);
+ frame.setVisible(true);
+ frame.setStatus(translator.getString("Status.Build.FO.tree"));
+ return frame;
+ }
+
+ /** This method override only stores the PageViewport in a vector.
+ * No actual rendering performed -- this is done by getPageImage(pageNum) instead.
+ * @param pageViewport the PageViewport
object supplied by the Area Tree
+ * @see org.apache.fop.render.Renderer
+ */
+ public void renderPage(PageViewport pageViewport) throws IOException, FOPException {
+ pageViewportList.add(pageViewport);
+ pageList.add(pageViewport.getPage().clone());
+ bufferedImageList.add(getPageImage(pageViewport));
+ }
+
+ public BufferedImage getBufferedPageImage(int pageNum) throws FOPException {
+ return (BufferedImage) bufferedImageList.get(pageNum);
+ }
+
+ /** Generates a desired page from the renderer's page viewport vector.
+ * @param pageNum the 0-based page number to generate
+ * @return the java.awt.image.BufferedImage
corresponding to the page
+ * @throws FOPException in case of an out-of-range page number requested
+ */
+ public BufferedImage getPageImage(PageViewport pageViewport) throws FOPException {
+ Page page = pageViewport.getPage();
+
+ Rectangle2D bounds = pageViewport.getViewArea();
+ pageWidth = (int) Math.round(bounds.getWidth() / 1000f );
+ pageHeight = (int) Math.round(bounds.getHeight() / 1000f );
+/*
+ System.out.println("(Page) X, Y, Width, Height: " + bounds.getX()
+ + " " + bounds.getY()
+ + " " + bounds.getWidth()
+ + " " + bounds.getHeight());
+*/
+ currentPageImage =
+ new BufferedImage((int)((pageWidth * (int)scaleFactor) / 100),
+ (int)((pageHeight * (int)scaleFactor) / 100),
+ BufferedImage.TYPE_INT_RGB);
+
+ Graphics2D graphics = currentPageImage.createGraphics();
+ graphics.setRenderingHint (RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ // transform page based on scale factor supplied
+ AffineTransform at = graphics.getTransform();
+ at.scale(scaleFactor / 100.0, scaleFactor / 100.0);
+ graphics.setTransform(at);
+
+ // draw page frame
+ graphics.setColor(Color.white);
+ graphics.fillRect(0, 0, pageWidth, pageHeight);
+ graphics.setColor(Color.black);
+ graphics.drawRect(-1, -1, pageWidth + 2, pageHeight + 2);
+ graphics.drawLine(pageWidth + 2, 0, pageWidth + 2, pageHeight + 2);
+ graphics.drawLine(pageWidth + 3, 1, pageWidth + 3, pageHeight + 3);
+ graphics.drawLine(0, pageHeight + 2, pageWidth + 2, pageHeight + 2);
+ graphics.drawLine(1, pageHeight + 3, pageWidth + 3, pageHeight + 3);
+
+ renderPageAreas(page);
+ return currentPageImage;
+ }
+
+ /** Generates a desired page from the renderer's page viewport vector.
+ * @param pageNum the 0-based page number to generate
+ * @return the java.awt.image.BufferedImage
corresponding to the page
+ * @throws FOPException in case of an out-of-range page number requested
+ */
+ public BufferedImage getPageImage(int pageNum) throws FOPException {
+ if (pageNum < 0 || pageNum >= pageViewportList.size()) {
+ throw new FOPException("out-of-range page number (" + pageNum
+ + ") requested; only " + pageViewportList.size()
+ + " page(s) available.");
+ }
+ PageViewport pageViewport = (PageViewport) pageViewportList.get(pageNum);
+ Page page = (Page) pageList.get(pageNum);
+
+ Rectangle2D bounds = pageViewport.getViewArea();
+ pageWidth = (int) Math.round(bounds.getWidth() / 1000f );
+ pageHeight = (int) Math.round(bounds.getHeight() / 1000f );
+/*
+ System.out.println("(Page) X, Y, Width, Height: " + bounds.getX()
+ + " " + bounds.getY()
+ + " " + bounds.getWidth()
+ + " " + bounds.getHeight());
+*/
+ currentPageImage =
+ new BufferedImage((int)((pageWidth * (int)scaleFactor) / 100),
+ (int)((pageHeight * (int)scaleFactor) / 100),
+ BufferedImage.TYPE_INT_RGB);
+
+ Graphics2D graphics = currentPageImage.createGraphics();
+ graphics.setRenderingHint (RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ // transform page based on scale factor supplied
+ AffineTransform at = graphics.getTransform();
+ at.scale(scaleFactor / 100.0, scaleFactor / 100.0);
+ graphics.setTransform(at);
+
+ // draw page frame
+ graphics.setColor(Color.white);
+ graphics.fillRect(0, 0, pageWidth, pageHeight);
+ graphics.setColor(Color.black);
+ graphics.drawRect(-1, -1, pageWidth + 2, pageHeight + 2);
+ graphics.drawLine(pageWidth + 2, 0, pageWidth + 2, pageHeight + 2);
+ graphics.drawLine(pageWidth + 3, 1, pageWidth + 3, pageHeight + 3);
+ graphics.drawLine(0, pageHeight + 2, pageWidth + 2, pageHeight + 2);
+ graphics.drawLine(1, pageHeight + 3, pageWidth + 3, pageHeight + 3);
+
+ renderPageAreas(page);
+ return currentPageImage;
+ }
+
+ /**
+ * Handle the traits for a region
+ * This is used to draw the traits for the given page region.
+ * (See Sect. 6.4.1.2 of XSL-FO spec.)
+ * @param region the RegionViewport whose region is to be drawn
+ */
+ protected void handleRegionTraits(RegionViewport region) {
+ Rectangle2D viewArea = region.getViewArea();
+
+ int startX = (int) Math.round((viewArea.getX() / 1000f)
+ * (scaleFactor / 100f));
+ int startY = (int) Math.round((viewArea.getY() / 1000f)
+ * (scaleFactor / 100f));
+ // for rounding to work correctly, need to take into account
+ // fractional portion of X and Y.
+ int width = (int) Math.round(((viewArea.getX() + viewArea.getWidth()) / 1000f)
+ * (scaleFactor / 100f)) - startX;
+ int height = (int) Math.round(((viewArea.getY() + viewArea.getHeight()) / 1000f)
+ * (scaleFactor / 100f)) - startY;
+
+ if (region.getRegion() != null) {
+ System.out.print("\nRegion type = " + region.getRegion().getRegionClass());
+ }
+
+ System.out.println(" X, Width, Y, Height: " + startX
+ + " " + width
+ + " " + startY
+ + " " + height
+ );
+
+ drawBackAndBorders(region, startX, startY, width, height);
+ }
+
+ /**
+ * Draw the background and borders.
+ * This draws the background and border traits for an area given
+ * the position.
+ *
+ * @param block 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 block,
+ int startx, int starty,
+ int width, int height) {
+
+ // draw background then border
+ Graphics2D graphics = currentPageImage.createGraphics();
+ Trait.Background back;
+ back = (Trait.Background) block.getTrait(Trait.BACKGROUND);
+ if (back != null) {
+
+ if (back.getColor() != null) {
+ graphics.setColor(back.getColor().getAWTColor());
+ graphics.fillRect(startx, starty, width, height);
+ }
+ if (back.getURL() != null) { // TODO: implement
+ ImageFactory fact = ImageFactory.getInstance();
+ FopImage fopimage = fact.getImage(back.getURL(), userAgent);
+ if (fopimage != null && fopimage.load(FopImage.DIMENSIONS, userAgent.getLogger())) {
+ if (back.getRepeat() == BackgroundRepeat.REPEAT) {
+ // create a pattern for the image
+ } else {
+ // place once
+ Rectangle2D pos;
+ pos = new Rectangle2D.Float((startx + back.getHoriz()) * 1000,
+ (starty + back.getVertical()) * 1000,
+ fopimage.getWidth() * 1000,
+ fopimage.getHeight() * 1000);
+// putImage(back.getURL(), pos);
+ }
+ }
+ }
+ }
+
+ BorderProps bps = (BorderProps) block.getTrait(Trait.BORDER_BEFORE);
+ if (bps != null) {
+ int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f));
+ graphics.setColor(bps.color.getAWTColor());
+ graphics.fillRect(startx, starty, width, borderWidth);
+ }
+ bps = (BorderProps) block.getTrait(Trait.BORDER_AFTER);
+ if (bps != null) {
+ int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f));
+ int sy = starty + height;
+ graphics.setColor(bps.color.getAWTColor());
+ graphics.fillRect(startx, starty + height - borderWidth,
+ width, borderWidth);
+ }
+ bps = (BorderProps) block.getTrait(Trait.BORDER_START);
+ if (bps != null) {
+ int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f));
+ graphics.setColor(bps.color.getAWTColor());
+ graphics.fillRect(startx, starty, borderWidth, height);
+ }
+ bps = (BorderProps) block.getTrait(Trait.BORDER_END);
+ if (bps != null) {
+ int borderWidth = (int) Math.round((bps.width / 1000f) * (scaleFactor / 100f));
+ int sx = startx + width;
+ graphics.setColor(bps.color.getAWTColor());
+ graphics.fillRect(startx + width - borderWidth, starty,
+ borderWidth, height);
+ }
+
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#renderText(TextArea)
+ */
+ public void renderText(TextArea text) {
+ System.out.println("In render text: " + text.getTextArea());
+
+ Graphics2D graphics = currentPageImage.createGraphics();
+ String fontName = (String) text.getTrait(Trait.FONT_NAME);
+ int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
+// Typeface f = (Typeface) fontInfo.getFonts().get(fontName);
+ ColorType ct = (ColorType) text.getTrait(Trait.COLOR);
+
+ FontMetricsMapper mapper = (FontMetricsMapper)
+ fontInfo.getMetricsFor(fontName);
+ if (mapper == null) {
+ mapper = new FontMetricsMapper("MonoSpaced", java.awt.Font.PLAIN,
+ graphics);
+ }
+
+// graphics.setColor(ct.getAWTColor());
+// graphics.setFont(mapper.getFont(size));
+ graphics.setColor(java.awt.Color.black);
+ graphics.setFont(new java.awt.Font("monospaced", java.awt.Font.PLAIN,
+ 10));
+
+ int rx = currentBlockIPPosition;
+ int bl = currentBPPosition + text.getOffset();
+
+ int newx = (int) (rx + 500) / 1000;
+ int newy = (int) (pageHeight - (bl + 500) / 1000);
+
+ String s = text.getTextArea();
+// graphics.drawString(s, newx, newy);
+ graphics.drawString(s, 220, 200);
+
+ // TODO: render text decorations
+ currentBlockIPPosition += text.getWidth();
+ }
+}
diff --git a/src/java/org/apache/fop/render/awt/FontMetricsMapper.java b/src/java/org/apache/fop/render/awt/FontMetricsMapper.java
new file mode 100644
index 000000000..6e0df2c66
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/FontMetricsMapper.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 1999-2004 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;
+
+// Java
+import java.awt.Graphics2D;
+import java.util.Map;
+
+// FOP
+import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.FontType;
+
+
+/**
+ * This class implements org.apache.fop.layout.FontMetrics and
+ * is added to the hash table in FontInfo. It deferes the
+ * actual calculation of the metrics to
+ * AWTFontMetrics. It only keeps the java name and
+ * style as member varibles
+ */
+
+public class FontMetricsMapper implements FontMetrics {
+
+ /**
+ * The first and last non space-character
+ */
+ private static final int FIRST_CHAR = 32;
+ private static final int LAST_CHAR = 255;
+
+ /**
+ * This is a AWTFontMetrics that does the real calculation.
+ * It is only one class that dynamically determines the font-size.
+ */
+ private static AWTFontMetrics metric = null;
+
+ /**
+ * The java name of the font.
+ * # Make the family name immutable.
+ */
+ private final String family;
+
+ /**
+ * The java style of the font.
+ * # Make the style immutable.
+ */
+ private final int style;
+
+ /**
+ * Constructs a new Font-metrics.
+ * @param family the family name of the font (java value)
+ * @param style the java type style value of the font
+ * @param graphics a Graphics2D object - this is needed so
+ * that we can get an instance of java.awt.FontMetrics
+ */
+ public FontMetricsMapper(String family, int style, Graphics2D graphics) {
+ this.family = family;
+ this.style = style;
+ if (metric == null) {
+ metric = new AWTFontMetrics(graphics);
+ }
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getFontName()
+ */
+ public String getFontName() {
+ return family;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getFontType()
+ */
+ public FontType getFontType() {
+ return FontType.OTHER;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getAscender(int)
+ */
+ public int getAscender(int size) {
+ return metric.getAscender(family, style, size);
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getCapHeight(int)
+ */
+ public int getCapHeight(int size) {
+ return metric.getCapHeight(family, style, size);
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getDescender(int)
+ */
+ public int getDescender(int size) {
+ return metric.getDescender(family, style, size);
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getXHeight(int)
+ */
+ public int getXHeight(int size) {
+ return metric.getXHeight(family, style, size);
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getWidth(int, int)
+ */
+ public int getWidth(int i, int size) {
+ return metric.width(i, family, style, size);
+ }
+
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getWidths()
+ */
+ public int[] getWidths() {
+ return metric.getWidths(family, style, AWTFontMetrics.FONT_SIZE);
+ }
+
+ /**
+ * Gets a Font instance of the Font that this
+ * FontMetrics describes in the desired size.
+ * @param size font size
+ * @return font with the desired characeristics.
+ */
+ public java.awt.Font getFont(int size) {
+ return metric.getFont(family, style, size);
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#getKerningInfo()
+ */
+ public Map getKerningInfo() {
+ return java.util.Collections.EMPTY_MAP;
+ }
+
+ /**
+ * @see org.apache.fop.fonts.FontMetrics#hasKerningInfo()
+ */
+ public boolean hasKerningInfo() {
+ return false;
+ }
+
+
+}
+
+
+
+
+
diff --git a/src/java/org/apache/fop/render/awt/FontSetup.java b/src/java/org/apache/fop/render/awt/FontSetup.java
new file mode 100644
index 000000000..cdac2ddb8
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/FontSetup.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 1999-2004 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;
+
+// FOP
+import org.apache.fop.apps.Document;
+import org.apache.fop.fonts.Font;
+
+// Java
+import java.awt.Graphics2D;
+
+/**
+ * Sets up the AWT fonts. It is similar to
+ * org.apache.fop.render.pdf.FontSetup.
+ * Assigns the font (with metrics) to internal names like "F1" and
+ * assigns family-style-weight triplets to the fonts.
+ */
+public class FontSetup {
+
+
+ /**
+ * Sets up the font info object.
+ *
+ * Adds metrics for basic fonts and useful family-style-weight
+ * triplets for lookup.
+ *
+ * @param fontInfo the font info object to set up
+ * @param graphics needed for acces to font metrics
+ */
+ public static void setup(Document fontInfo, Graphics2D graphics) {
+ FontMetricsMapper metric;
+ int normal, bold, bolditalic, italic;
+
+ /*
+ * available java fonts are:
+ * Serif - bold, normal, italic, bold-italic
+ * SansSerif - bold, normal, italic, bold-italic
+ * MonoSpaced - bold, normal, italic, bold-italic
+ */
+ normal = java.awt.Font.PLAIN;
+ bold = java.awt.Font.BOLD;
+ italic = java.awt.Font.ITALIC;
+ bolditalic = java.awt.Font.BOLD + java.awt.Font.ITALIC;
+
+ metric = new FontMetricsMapper("SansSerif", normal, graphics);
+ // --> goes to F1
+ fontInfo.addMetrics("F1", metric);
+ metric = new FontMetricsMapper("SansSerif", italic, graphics);
+ // --> goes to F2
+ fontInfo.addMetrics("F2", metric);
+ metric = new FontMetricsMapper("SansSerif", bold, graphics);
+ // --> goes to F3
+ fontInfo.addMetrics("F3", metric);
+ metric = new FontMetricsMapper("SansSerif", bolditalic, graphics);
+ // --> goes to F4
+ fontInfo.addMetrics("F4", metric);
+
+
+ metric = new FontMetricsMapper("Serif", normal, graphics);
+ // --> goes to F5
+ fontInfo.addMetrics("F5", metric);
+ metric = new FontMetricsMapper("Serif", italic, graphics);
+ // --> goes to F6
+ fontInfo.addMetrics("F6", metric);
+ metric = new FontMetricsMapper("Serif", bold, graphics);
+ // --> goes to F7
+ fontInfo.addMetrics("F7", metric);
+ metric = new FontMetricsMapper("Serif", bolditalic, graphics);
+ // --> goes to F8
+ fontInfo.addMetrics("F8", metric);
+
+ metric = new FontMetricsMapper("MonoSpaced", normal, graphics);
+ // --> goes to F9
+ fontInfo.addMetrics("F9", metric);
+ metric = new FontMetricsMapper("MonoSpaced", italic, graphics);
+ // --> goes to F10
+ fontInfo.addMetrics("F10", metric);
+ metric = new FontMetricsMapper("MonoSpaced", bold, graphics);
+ // --> goes to F11
+ fontInfo.addMetrics("F11", metric);
+ metric = new FontMetricsMapper("MonoSpaced", bolditalic, graphics);
+ // --> goes to F12
+ fontInfo.addMetrics("F12", metric);
+
+ metric = new FontMetricsMapper("Symbol", bolditalic, graphics);
+ // --> goes to F13 and F14
+ fontInfo.addMetrics("F13", metric);
+ fontInfo.addMetrics("F14", metric);
+
+ // Custom type 1 fonts step 1/2
+ // fontInfo.addMetrics("F15", new OMEP());
+ // fontInfo.addMetrics("F16", new GaramondLightCondensed());
+ // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic());
+
+ /* any is treated as serif */
+ fontInfo.addFontProperties("F5", "any", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "any", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "any", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F7", "any", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F8", "any", "italic", Font.BOLD);
+ fontInfo.addFontProperties("F8", "any", "oblique", Font.BOLD);
+
+ fontInfo.addFontProperties("F1", "sans-serif", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F2", "sans-serif", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F2", "sans-serif", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F3", "sans-serif", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F4", "sans-serif", "oblique", Font.BOLD);
+ fontInfo.addFontProperties("F4", "sans-serif", "italic", Font.BOLD);
+ fontInfo.addFontProperties("F5", "serif", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "serif", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "serif", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F7", "serif", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F8", "serif", "oblique", Font.BOLD);
+ fontInfo.addFontProperties("F8", "serif", "italic", Font.BOLD);
+ fontInfo.addFontProperties("F9", "monospace", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F10", "monospace", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F10", "monospace", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F11", "monospace", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F12", "monospace", "oblique", Font.BOLD);
+ fontInfo.addFontProperties("F12", "monospace", "italic", Font.BOLD);
+
+ fontInfo.addFontProperties("F1", "Helvetica", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F2", "Helvetica", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F2", "Helvetica", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F3", "Helvetica", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F4", "Helvetica", "oblique", Font.BOLD);
+ fontInfo.addFontProperties("F4", "Helvetica", "italic", Font.BOLD);
+ fontInfo.addFontProperties("F5", "Times", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "Times", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "Times", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F7", "Times", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F8", "Times", "oblique", Font.BOLD);
+ fontInfo.addFontProperties("F8", "Times", "italic", Font.BOLD);
+ fontInfo.addFontProperties("F9", "Courier", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F10", "Courier", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F10", "Courier", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F11", "Courier", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F12", "Courier", "oblique", Font.BOLD);
+ fontInfo.addFontProperties("F12", "Courier", "italic", Font.BOLD);
+ fontInfo.addFontProperties("F13", "Symbol", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", Font.NORMAL);
+
+ // Custom type 1 fonts step 2/2
+ // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL);
+ // fontInfo.addFontProperties("F16", "Garamond-LightCondensed", "normal", FontInfo.NORMAL);
+ // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD);
+
+ /* for compatibility with PassiveTex */
+ fontInfo.addFontProperties("F5", "Times-Roman", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "Times-Roman", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "Times-Roman", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F7", "Times-Roman", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F8", "Times-Roman", "oblique", Font.BOLD);
+ fontInfo.addFontProperties("F8", "Times-Roman", "italic", Font.BOLD);
+ fontInfo.addFontProperties("F5", "Times Roman", "normal", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "Times Roman", "oblique", Font.NORMAL);
+ fontInfo.addFontProperties("F6", "Times Roman", "italic", Font.NORMAL);
+ fontInfo.addFontProperties("F7", "Times Roman", "normal", Font.BOLD);
+ fontInfo.addFontProperties("F8", "Times Roman", "oblique", Font.BOLD);
+ fontInfo.addFontProperties("F8", "Times Roman", "italic", Font.BOLD);
+ fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter",
+ "normal", Font.NORMAL);
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/render/awt/viewer/Command.java b/src/java/org/apache/fop/render/awt/viewer/Command.java
new file mode 100644
index 000000000..725255a0e
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/viewer/Command.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 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.viewer;
+
+//Java
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.ImageIcon;
+import java.net.URL;
+
+/**
+ * This class represents UI-commands, which can be used as menu or toolbar
+ * items
.
+ * When the Command
object receives action event, that object's
+ * doit
method is invoked. doit
method by default
+ * does nothing and the class customer have to override it to implement
+ * any action handling logic.
+ * Originally contributed by:
+ * Juergen Verwohlt: Juergen.Verwohlt@jcatalog.com,
+ * Rainer Steinkuhle: Rainer.Steinkuhle@jcatalog.com,
+ * Stanislav Gorkhover: Stanislav.Gorkhover@jcatalog.com
+ */
+public class Command extends AbstractAction {
+
+ private static final String IMAGE_DIR = "images/";
+
+ /**
+ * Creates Command
object with a given name and
+ * sets the name as a tooltip text. No associated icon image.
+ * @param name of the command
+ */
+ public Command(String name) {
+ super(name);
+ putValue(SHORT_DESCRIPTION, name);
+ }
+
+ /**
+ * Creates Command
object with a given name, the same
+ * tooltip text and icon image if appropriate image file is found.
+ * @param name name of the command
+ * @param iconName name of the icon
+ */
+ public Command(String name, String iconName) {
+ super(name);
+ putValue(SHORT_DESCRIPTION, name);
+ URL url = getClass().getResource(IMAGE_DIR + iconName + ".gif");
+ if (url != null) {
+ putValue(SMALL_ICON, new ImageIcon(url));
+ }
+ }
+
+ /**
+ * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
+ */
+ public void actionPerformed(ActionEvent e) {
+ doit();
+ }
+
+ /**
+ * Action handler, have to be overrided by subclasses.
+ */
+ public void doit() {
+ //Do nothing
+ }
+}
+
diff --git a/src/java/org/apache/fop/render/awt/viewer/GoToPageDialog.java b/src/java/org/apache/fop/render/awt/viewer/GoToPageDialog.java
new file mode 100644
index 000000000..d3db6979b
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/viewer/GoToPageDialog.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 1999-2004 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.viewer;
+
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * Go to Page Dialog.
+ * Originally contributed by:
+ * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com,
+ * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com,
+ * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com
+ */
+public class GoToPageDialog extends JDialog {
+
+ private JTextField pgNbField;
+ private int pageNumber = -1;
+
+ /**
+ * Creates modal dialog with a given title, attached to a given frame.
+ * @param frame Frame to attach to
+ * @param title dialog title
+ * @param translator translator for localization
+ */
+ public GoToPageDialog(Frame frame, String title, Translator translator) {
+ super(frame, title, true);
+ jbInit(translator);
+ pack();
+ }
+
+ private void jbInit(Translator translator) {
+ JPanel panel1 = new JPanel();
+ GridBagLayout gridBagLayout1 = new GridBagLayout();
+ JLabel pgNbLabel = new JLabel();
+ pgNbField = new JTextField();
+ JButton okButton = new JButton();
+ JButton cancelButton = new JButton();
+ panel1.setLayout(gridBagLayout1);
+ pgNbLabel.setText(translator.getString("Label.Page.number"));
+ okButton.setText(translator.getString("Button.Ok"));
+ okButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ okButtonActionPerformed(e);
+ }
+ });
+ cancelButton.setText(translator.getString("Button.Cancel"));
+ cancelButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ cancelButtonActionPerformed(e);
+ }
+ });
+ panel1.setMinimumSize(new Dimension(250, 78));
+ getContentPane().add(panel1);
+ panel1.add(pgNbLabel,
+ new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
+ GridBagConstraints.WEST,
+ GridBagConstraints.NONE,
+ new Insets(10, 10, 10, 5), 0, 0));
+ panel1.add(pgNbField,
+ new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0,
+ GridBagConstraints.WEST,
+ GridBagConstraints.BOTH,
+ new Insets(10, 5, 10, 10), 0, 0));
+ panel1.add(okButton,
+ new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST,
+ GridBagConstraints.NONE,
+ new Insets(0, 0, 10, 5), 0, 0));
+ panel1.add(cancelButton,
+ new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.WEST,
+ GridBagConstraints.NONE,
+ new Insets(0, 10, 10, 10), 0, 0));
+ }
+
+ private void okButtonActionPerformed(ActionEvent e) {
+ try {
+ pageNumber = Integer.parseInt(pgNbField.getText());
+ dispose();
+ } catch (NumberFormatException nfe) {
+ pgNbField.setText("???");
+ }
+
+ }
+
+ private void cancelButtonActionPerformed(ActionEvent e) {
+ pageNumber = -1;
+ dispose();
+ }
+
+ /**
+ * Returns page number, entered by user.
+ * @return the page number
+ */
+ public int getPageNumber() {
+ return pageNumber;
+ }
+}
+
diff --git a/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java b/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java
new file mode 100644
index 000000000..c1d06615c
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright 1999-2004 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.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;
+import java.awt.Graphics;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Point;
+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;
+
+//FOP
+import org.apache.fop.apps.Driver;
+import org.apache.fop.apps.InputHandler;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.render.awt.AWTRenderer;
+
+/**
+ * AWT Viewer main window.
+ * Originally contributed by:
+ * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com,
+ * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com,
+ * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com
+ */
+public class PreviewDialog extends JFrame {
+
+ /** The Translator for localization */
+ protected Translator translator;
+ /** The AWT renderer */
+ protected AWTRenderer renderer;
+ /** The InputHandler associated with this window */
+ protected InputHandler inputHandler;
+ /** The Driver used for refreshing/reloading the view */
+ protected Driver driver;
+
+ private int currentPage = 0;
+ private int pageCount = 0;
+ private Reloader reloader;
+ private JComboBox scale;
+ private JLabel processStatus;
+ private JLabel pageLabel;
+ private JLabel infoStatus;
+
+ /**
+ * Creates a new PreviewDialog that uses the given renderer.
+ * @param aRenderer the to use renderer
+ */
+ public PreviewDialog(AWTRenderer aRenderer, InputHandler handler) {
+ renderer = aRenderer;
+ inputHandler = handler;
+ translator = renderer.getTranslator();
+
+ //Commands aka Actions
+ Command printAction = new Command(translator.getString("Menu.Print"), "Print") {
+ public void doit() {
+ print();
+ }
+ };
+ Command firstPageAction = new Command(translator.getString("Menu.First.page"),
+ "firstpg") {
+ public void doit() {
+ goToFirstPage();
+ }
+ };
+ Command previousPageAction = new Command(translator.getString("Menu.Prev.page"),
+ "prevpg") {
+ public void doit() {
+ goToPreviousPage();
+ }
+ };
+ Command nextPageAction = new Command(translator.getString("Menu.Next.page"), "nextpg") {
+ public void doit() {
+ goToNextPage();
+ }
+
+ };
+ Command lastPageAction = new Command(translator.getString("Menu.Last.page"), "lastpg") {
+ public void doit() {
+ goToLastPage();
+ }
+ };
+ Command reloadAction = new Command(translator.getString("Menu.Reload"), "reload") {
+ public void doit() {
+ reload();
+ }
+ };
+
+ setTitle("FOP: AWT-" + translator.getString("Title.Preview"));
+ setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+
+ //Sets size to be 61%x90% of the screen size
+ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ //Rather frivolous size - fits A4 page width in 1024x768 screen on my desktop
+ setSize(screen.width * 61 / 100, screen.height * 9 / 10);
+
+ //Page view stuff
+ pageLabel = new JLabel();
+ JScrollPane previewArea = new JScrollPane(pageLabel);
+ previewArea.getViewport().setBackground(Color.gray);
+ previewArea.setMinimumSize(new Dimension(50, 50));
+ getContentPane().add(previewArea, BorderLayout.CENTER);
+
+ //Scaling combobox
+ scale = new JComboBox();
+ scale.addItem("25%");
+ scale.addItem("50%");
+ scale.addItem("75%");
+ scale.addItem("100%");
+ scale.addItem("150%");
+ scale.addItem("200%");
+ scale.setMaximumSize(new Dimension(80, 24));
+ scale.setPreferredSize(new Dimension(80, 24));
+ scale.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ scaleActionPerformed(e);
+ }
+ });
+ scale.setSelectedItem("100%");
+ renderer.setScaleFactor(100.0);
+
+ //Menu
+ setJMenuBar(setupMenu());
+
+ //Toolbar
+ JToolBar toolBar = new JToolBar();
+ toolBar.add(printAction);
+ toolBar.add(reloadAction);
+ toolBar.addSeparator();
+ toolBar.add(firstPageAction);
+ toolBar.add(previousPageAction);
+ toolBar.add(nextPageAction);
+ toolBar.add(lastPageAction);
+ toolBar.addSeparator();
+ toolBar.add(new JLabel(translator.getString("Menu.Zoom")));
+ toolBar.addSeparator();
+ toolBar.add(scale);
+ getContentPane().add(toolBar, BorderLayout.NORTH);
+ //Status bar
+ JPanel statusBar = new JPanel();
+ processStatus = new JLabel();
+ processStatus.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createEtchedBorder(),
+ BorderFactory.createEmptyBorder(0, 3, 0, 0)));
+ infoStatus = new JLabel();
+ infoStatus.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createEtchedBorder(),
+ BorderFactory.createEmptyBorder(0, 3, 0, 0)));
+
+ statusBar.setLayout(new GridBagLayout());
+
+ processStatus.setPreferredSize(new Dimension(200, 21));
+ processStatus.setMinimumSize(new Dimension(200, 21));
+
+ infoStatus.setPreferredSize(new Dimension(100, 21));
+ infoStatus.setMinimumSize(new Dimension(100, 21));
+ statusBar.add(processStatus,
+ new GridBagConstraints(0, 0, 1, 0, 2.0, 0.0,
+ GridBagConstraints.CENTER,
+ GridBagConstraints.HORIZONTAL,
+ new Insets(0, 0, 0, 3), 0, 0));
+ statusBar.add(infoStatus,
+ new GridBagConstraints(1, 0, 1, 0, 1.0, 0.0,
+ GridBagConstraints.CENTER,
+ GridBagConstraints.HORIZONTAL,
+ new Insets(0, 0, 0, 0), 0, 0));
+ getContentPane().add(statusBar, BorderLayout.SOUTH);
+ }
+
+ /**
+ * Creates a new menubar to be shown in this window.
+ * @return the newly created menubar
+ */
+ private JMenuBar setupMenu() {
+ JMenuBar menuBar = new JMenuBar();
+ JMenu menu = new JMenu(translator.getString("Menu.File"));
+
+ //Adds mostly the same actions, but without icons
+ menu.add(new Command(translator.getString("Menu.Print")) {
+ public void doit() {
+ print();
+ }
+ });
+ // inputHandler must be set to allow reloading
+ if (inputHandler != null) {
+ menu.add(new Command(translator.getString("Menu.Reload")) {
+ public void doit() {
+ reload();
+ }
+ });
+ }
+ menu.addSeparator();
+ menu.add(new Command(translator.getString("Menu.Exit")) {
+ public void doit() {
+ dispose();
+ }
+ });
+ menuBar.add(menu);
+ menu = new JMenu(translator.getString("Menu.View"));
+ menu.add(new Command(translator.getString("Menu.First.page")) {
+ public void doit() {
+ goToFirstPage();
+ }
+ });
+ menu.add(new Command(translator.getString("Menu.Prev.page")) {
+ public void doit() {
+ goToPreviousPage();
+ }
+ });
+ menu.add(new Command(translator.getString("Menu.Next.page")) {
+ public void doit() {
+ goToNextPage();
+ }
+ });
+ menu.add(new Command(translator.getString("Menu.Last.page")) {
+ public void doit() {
+ goToLastPage();
+ }
+ });
+ menu.add(new Command(translator.getString("Menu.Go.to.Page") + " ...") {
+ public void doit() {
+ showGoToPageDialog();
+ }
+ });
+ menu.addSeparator();
+ JMenu subMenu = new JMenu(translator.getString("Menu.Zoom"));
+ subMenu.add(new Command("25%") {
+ public void doit() {
+ setScale(25.0);
+ }
+ });
+ subMenu.add(new Command("50%") {
+ public void doit() {
+ setScale(50.0);
+ }
+ });
+ subMenu.add(new Command("75%") {
+ public void doit() {
+ setScale(75.0);
+ }
+ });
+ subMenu.add(new Command("100%") {
+ public void doit() {
+ setScale(100.0);
+ }
+ });
+ subMenu.add(new Command("150%") {
+ public void doit() {
+ setScale(150.0);
+ }
+ });
+ subMenu.add(new Command("200%") {
+ public void doit() {
+ setScale(200.0);
+ }
+ });
+ menu.add(subMenu);
+ menu.addSeparator();
+ menu.add(new Command(translator.getString("Menu.Default.zoom")) {
+ public void doit() {
+ setScale(100.0);
+ }
+ });
+ menuBar.add(menu);
+ menu = new JMenu(translator.getString("Menu.Help"));
+ menu.add(new Command(translator.getString("Menu.About")) {
+ public void doit() {
+ startHelpAbout();
+ }
+ });
+ menuBar.add(menu);
+ return menuBar;
+ }
+
+ /**
+ * Shows the About box
+ */
+ private void startHelpAbout() {
+ PreviewDialogAboutBox dlg = new PreviewDialogAboutBox(this, translator);
+ //Centers the box
+ Dimension dlgSize = dlg.getPreferredSize();
+ Dimension frmSize = getSize();
+ Point loc = getLocation();
+ dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x,
+ (frmSize.height - dlgSize.height) / 2 + loc.y);
+ dlg.setVisible(true);
+ }
+
+ /**
+ * Changes the current visible page
+ * @param number the page number to go to
+ */
+ private void goToPage(int number) {
+ currentPage = number;
+ renderer.setPageNumber(number);
+ showPage();
+ }
+
+ /**
+ * Shows the previous page.
+ */
+ private void goToPreviousPage() {
+ if (currentPage <= 0) {
+ return;
+ }
+ currentPage--;
+ goToPage(currentPage);
+ }
+
+
+ /**
+ * Shows the next page.
+ */
+ private void goToNextPage() {
+ if (currentPage >= pageCount - 1) {
+ return;
+ }
+ currentPage++;
+ goToPage(currentPage);
+ }
+
+ /**
+ * Shows the last page.
+ */
+ private void goToLastPage() {
+ if (currentPage == pageCount - 1) {
+ return;
+ }
+ currentPage = pageCount - 1;
+ goToPage(currentPage);
+ }
+
+ /**
+ * Reloads and reformats document.
+ */
+ private synchronized void reload() {
+ if (reloader == null || !reloader.isAlive()) {
+ reloader = new Reloader();
+ reloader.start();
+ }
+ }
+
+ /**
+ * This class is used to reload document in
+ * a thread safe way.
+ */
+ private class Reloader extends Thread {
+ public void run() {
+ if (driver == null) {
+ driver = new Driver();
+ driver.setRenderer(renderer);
+ } else {
+ driver.reset();
+ }
+
+ pageLabel.setIcon(null);
+ infoStatus.setText("");
+ currentPage = 0;
+
+ try {
+ setStatus(translator.getString("Status.Build.FO.tree"));
+ driver.render(inputHandler);
+ setStatus(translator.getString("Status.Show"));
+ } catch (FOPException e) {
+ reportException(e);
+ }
+ }
+ }
+
+ /**
+ * Shows "go to page" dialog and then goes to the selected page
+ */
+ private void showGoToPageDialog() {
+ GoToPageDialog d = new GoToPageDialog(this,
+ translator.getString("Menu.Go.to.Page"), translator);
+ d.setLocation((int)getLocation().getX() + 50,
+ (int)getLocation().getY() + 50);
+ d.setVisible(true);
+ currentPage = d.getPageNumber();
+ if (currentPage < 1 || currentPage > pageCount) {
+ return;
+ }
+ currentPage--;
+ goToPage(currentPage);
+ }
+
+ /**
+ * Shows the first page.
+ */
+ private void goToFirstPage() {
+ if (currentPage == 0) {
+ return;
+ }
+ currentPage = 0;
+ goToPage(currentPage);
+ }
+
+ /**
+ * Prints the document
+ */
+ private void print() {
+ PrinterJob pj = PrinterJob.getPrinterJob();
+ pj.setPageable(renderer);
+ if (pj.printDialog()) {
+ try {
+ pj.print();
+ } catch (PrinterException pe) {
+ pe.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Scales page image
+ */
+ private void setScale(double scaleFactor) {
+ if (scaleFactor == 25.0) {
+ scale.setSelectedIndex(0);
+ } else if (scaleFactor == 50.0) {
+ scale.setSelectedIndex(1);
+ } else if (scaleFactor == 75.0) {
+ scale.setSelectedIndex(2);
+ } else if (scaleFactor == 100.0) {
+ scale.setSelectedIndex(3);
+ } else if (scaleFactor == 150.0) {
+ scale.setSelectedIndex(4);
+ } else if (scaleFactor == 200.0) {
+ scale.setSelectedIndex(5);
+ }
+ renderer.setScaleFactor(scaleFactor);
+ if (renderer.getNumberOfPages() != 0) {
+ showPage();
+ }
+ }
+
+ private void scaleActionPerformed(ActionEvent e) {
+ String item = (String)scale.getSelectedItem();
+ setScale(Double.parseDouble(item.substring(0, item.indexOf('%'))));
+ }
+
+ /**
+ * Sets message to be shown in the status bar in a thread safe way.
+ * @param message the message
+ */
+ public void setStatus(String message) {
+ SwingUtilities.invokeLater(new ShowStatus(message));
+ }
+
+ /**
+ * This class is used to show status in a thread safe way.
+ */
+ private class ShowStatus implements Runnable {
+ /**
+ * The message to display
+ */
+ private String message;
+ /**
+ * Constructs ShowStatus thread
+ * @param message message to display
+ */
+ public ShowStatus(String message) {
+ this.message = message;
+ }
+
+ public void run() {
+ processStatus.setText(message.toString());
+ }
+ }
+
+ /**
+ * Starts rendering process and shows the current page.
+ */
+ public void showPage() {
+ ShowPageImage viewer = new ShowPageImage();
+ if (SwingUtilities.isEventDispatchThread()) {
+ viewer.run();
+ } else {
+ SwingUtilities.invokeLater(viewer);
+ }
+ }
+
+
+ /**
+ * This class is used to update the page image
+ * in a thread safe way.
+ */
+ private class ShowPageImage implements Runnable {
+ /**
+ * The run method that does the actual updating
+ */
+ public void run() {
+ try {
+ BufferedImage pageImage = null;
+ Graphics graphics = null;
+
+ pageImage = renderer.getPageImage(currentPage);
+ if (pageImage == null)
+ return;
+ graphics = pageImage.getGraphics();
+ graphics.setColor(Color.black);
+ graphics.drawRect(0, 0, pageImage.getWidth() - 1,
+ pageImage.getHeight() - 1);
+
+ pageLabel.setIcon(new ImageIcon(pageImage));
+ pageCount = renderer.getNumberOfPages();
+
+ // Update status bar
+ infoStatus.setText(translator.getString("Status.Page") + " "
+ + (currentPage + 1) + " "
+ + translator.getString("Status.of") + " " + pageCount);
+ } catch (FOPException e) {
+ reportException(e);
+ }
+ }
+ }
+
+ /**
+ * Opens standard Swing error dialog box and reports given exception details.
+ * @param e the Exception
+ */
+ public void reportException(Exception e) {
+ String msg = translator.getString("Exception.Occured");
+ setStatus(msg);
+ JOptionPane.showMessageDialog(
+ getContentPane(),
+ "" + msg + ":
"
+ + e.getClass().getName() + "
"
+ + e.getMessage() + "",
+ translator.getString("Exception.Error"),
+ JOptionPane.ERROR_MESSAGE
+ );
+ }
+}
+
diff --git a/src/java/org/apache/fop/render/awt/viewer/PreviewDialogAboutBox.java b/src/java/org/apache/fop/render/awt/viewer/PreviewDialogAboutBox.java
new file mode 100644
index 000000000..f7052d9a4
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/viewer/PreviewDialogAboutBox.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 1999-2004 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.viewer;
+
+//Java
+import java.awt.AWTEvent;
+import java.awt.BorderLayout;
+import java.awt.Dialog;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.GridLayout;
+
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.ActionEvent;
+
+//FOP
+import org.apache.fop.apps.Version;
+
+/**
+ * AWT Viewer's "About" dialog.
+ * Originally contributed by:
+ * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com,
+ * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com,
+ * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com
+ */
+public class PreviewDialogAboutBox extends Dialog implements ActionListener {
+ private JButton okButton;
+
+ /**
+ * Creates modal "About" dialog, attached to a given parent frame.
+ * @param parent parent frame
+ * @param translator Translator for localization
+ */
+ public PreviewDialogAboutBox(Frame parent, Translator translator) {
+ super(parent, true);
+ enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+ setTitle(translator.getString("About.Title"));
+ setResizable(false);
+ JPanel panel1 = new JPanel();
+ JPanel panel2 = new JPanel();
+ JPanel insetsPanel1 = new JPanel();
+ JPanel insetsPanel2 = new JPanel();
+ JPanel insetsPanel3 = new JPanel();
+ okButton = new JButton();
+ JLabel imageControl1 = new JLabel();
+ imageControl1.setIcon(new ImageIcon(getClass().getResource("images/fop.gif")));
+ JLabel label1 = new JLabel(translator.getString("About.Product"));
+ JLabel label2 = new JLabel(translator.getString("About.Version")
+ + " " + Version.getVersion());
+ JLabel label3 = new JLabel(translator.getString("About.Copyright"));
+ panel1.setLayout(new BorderLayout());
+ panel2.setLayout(new BorderLayout());
+ insetsPanel1.setLayout(new FlowLayout());
+ insetsPanel2.setLayout(new FlowLayout());
+ insetsPanel2.setBorder(new EmptyBorder(10, 10, 10, 10));
+ insetsPanel3.setLayout(new GridLayout(3, 1));
+ insetsPanel3.setBorder(new EmptyBorder(10, 10, 10, 10));
+ okButton.setText(translator.getString("Button.Ok"));
+ okButton.addActionListener(this);
+ insetsPanel2.add(imageControl1, null);
+ panel2.add(insetsPanel2, BorderLayout.WEST);
+ insetsPanel3.add(label1);
+ insetsPanel3.add(label2);
+ insetsPanel3.add(label3);
+ panel2.add(insetsPanel3, BorderLayout.CENTER);
+ insetsPanel1.add(okButton);
+ panel1.add(insetsPanel1, BorderLayout.SOUTH);
+ panel1.add(panel2, BorderLayout.NORTH);
+ add(panel1);
+ pack();
+ }
+
+ /**
+ * @see java.awt.Window#processWindowEvent(WindowEvent)
+ */
+ protected void processWindowEvent(WindowEvent e) {
+ if (e.getID() == WindowEvent.WINDOW_CLOSING) {
+ cancel();
+ }
+ super.processWindowEvent(e);
+ }
+
+ private void cancel() {
+ dispose();
+ }
+
+ /**
+ * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
+ */
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == okButton) {
+ cancel();
+ }
+ }
+}
+
diff --git a/src/java/org/apache/fop/render/awt/viewer/Translator.java b/src/java/org/apache/fop/render/awt/viewer/Translator.java
new file mode 100644
index 000000000..b9498fcc3
--- /dev/null
+++ b/src/java/org/apache/fop/render/awt/viewer/Translator.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1999-2004 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.viewer;
+
+//Java
+import java.util.ResourceBundle;
+import java.util.Locale;
+
+/**
+ * AWT Viewer's localization class, backed up by java.util.ResourceBundle
.
+ * Originally contributed by:
+ * Stanislav.Gorkhover@jCatalog.com
+ */
+public class Translator {
+
+ private ResourceBundle bundle;
+ private static String bundleBaseName = "org/apache/fop/render/awt/viewer/resources/Viewer";
+
+ /**
+ * Default constructor, default Locale
is used.
+ */
+ public Translator() {
+ this(Locale.getDefault());
+ }
+
+ /**
+ * Constructor for a given Locale
.
+ * @param locale Locale to use
+ */
+ public Translator(Locale locale) {
+ bundle = ResourceBundle.getBundle(bundleBaseName, locale);
+ }
+
+ /**
+ * Returns localized String
for a given key.
+ * @param key the key
+ * @return the localized String
+ */
+ public String getString(String key) {
+ return bundle.getString(key);
+ }
+}
+
--
2.39.5