You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2007/12/27 11:34:18 UTC

svn commit: r607032 [1/2] - in /xmlgraphics/fop/trunk: ./ src/documentation/content/xdocs/trunk/ src/java/org/apache/fop/apps/ src/java/org/apache/fop/area/ src/java/org/apache/fop/fo/ src/java/org/apache/fop/fo/extensions/ src/java/org/apache/fop/fo/f...

Author: jeremias
Date: Thu Dec 27 02:34:15 2007
New Revision: 607032

URL: http://svn.apache.org/viewvc?rev=607032&view=rev
Log:
Added new extension element: fox:external-document. It allows to add whole documents such as multi-page TIFF images to be inserted as peers to a page-sequence. Each image will make up an entire page. See the documentation for details. ATM, only single pages are possible. Multi-page images will be supported with the new image package.

Some preparations for page-position="only" but the implementation is incomplete and "only" has no effect, yet. (Just uploaded some stuff I once started)
Some javadoc cleanups.

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/GraphicsProperties.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExternalDocument.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/TopLevelLayoutManager.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java   (with props)
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/fox_external-document_1.xml   (with props)
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/fox_external-document_2.xml   (with props)
Modified:
    xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FormattingResults.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeHandler.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOEventHandler.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractGraphics.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequence.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Root.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMaker.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/Page.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java
    xmlgraphics/fop/trunk/status.xml

Modified: xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml (original)
+++ xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml Thu Dec 27 02:34:15 2007
@@ -115,6 +115,79 @@
           or list-block.
         </p>
       </section>
+      <section id="external-document">
+        <title>fox:external-document</title>
+        <note>
+          This feature is incomplete. Support for multi-page documents will be added shortly.
+          At the moment, only single-page images will work. And this will not work with RTF output.
+        </note>
+        <p>
+          This is a proprietary extension element which allows to add whole images as pages to
+          an FO document. For example, if you have a scanned document or a fax as multi-page TIFF
+          file, you can append or insert this document using the <code>fox:external-document</code>
+          element. Each page of the external document will create one full page in the target
+          format.
+        </p>
+        <p>
+          The <code>fox:external-document</code> element is structurally a peer to
+          <code>fo:page-sequence</code>, so wherever you can put an <code>fo:page-sequence</code>
+          you could also place a <code>fox:external-document</code>.
+          Therefore, the specified contents for <code>fo:root</code> change to: 
+        </p>
+        <p>
+          <code>
+            (layout-master-set, declarations?, bookmark-tree?, (page-sequence|page-sequence-wrapper|fox:external-document)+)
+          </code>
+        </p>
+        <section>
+          <title>Specification</title>
+          <p>
+            The <code>fox:external-document</code> extension formatting object is used to specify
+            how to create a (sub-)sequence of pages within a document. The content of these pages
+            comes from the individual subimages/pages of an image or paged document (for example:
+            multi-page TIFF in the form of faxes or scanned documents, or PDF files). The
+            formatting object creates the necessary areas to display one image per page.
+          </p>
+          <p>
+            In terms of page numbers, the behaviour is the same as for
+            <code>fo:page-sequence</code>. The placement of the image inside the page is similar
+            to that of <code>fo:external-graphic</code> or <code>fo:instream-foreign-object</code>,
+            i.e. the viewport (and therefore the page size) is defined by either the intrinsic
+            size of the image or by the size properties that apply to this formatting object.
+          </p>
+          <p>Content: EMPTY</p>
+          <p>The following properties apply to this formatting object:</p>
+          <ul>
+            <li>(Common Accessibility Properties) (not implemented, yet)</li>
+            <li>(Common Aural Properties) (not implemented, yet)</li>
+            <li>block-progression-dimension</li>
+            <li>content-height</li>
+            <li>content-type</li>
+            <li>content-width</li>
+            <li>display-align</li>
+            <li>height</li>
+            <li>id</li>
+            <li>inline-progression-dimension</li>
+            <li>overflow</li>
+            <li>pages: &lt;page-set&gt; (see below) (not implemented, yet)</li>
+            <li>reference-orientation</li>
+            <li>scaling</li>
+            <li>scaling-method</li>
+            <li>src</li>
+            <li>text-align</li>
+            <li>width</li>
+          </ul>
+          <p>
+            Datatype "page-set": Value: auto | &lt;integer-range&gt;,
+            Default: "auto" which means all pages/subimages of the document.
+            &lt;integer-range&gt; allows values such as "7" or "1-3"
+          </p>
+          <note>
+            <code>fox:external-document</code> is not suitable for concatenating FO documents.
+            For this, XInclude is recommended.
+          </note>
+        </section>
+      </section>
     </section>
   </body>
 </document>

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FormattingResults.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FormattingResults.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FormattingResults.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FormattingResults.java Thu Dec 27 02:34:15 2007
@@ -21,7 +21,7 @@
 
 import java.util.List;
 
-import org.apache.fop.fo.pagination.PageSequence;
+import org.apache.fop.fo.pagination.AbstractPageSequence;
 
 /**
  * Class for reporting back formatting results to the calling application.
@@ -69,10 +69,10 @@
      * Reports the result of one page sequence rendering
      * back into this object.
      *
-     * @param pageSequence  the PageSequence which just completed rendering
+     * @param pageSequence  the page sequence which just completed rendering
      * @param pageCount     the number of pages rendered for that PageSequence
      */
-    public void haveFormattedPageSequence(PageSequence pageSequence, int pageCount) {
+    public void haveFormattedPageSequence(AbstractPageSequence pageSequence, int pageCount) {
         this.pageCount += pageCount;
         if (this.pageSequences == null) {
             this.pageSequences = new java.util.ArrayList();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeHandler.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeHandler.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeHandler.java Thu Dec 27 02:34:15 2007
@@ -35,13 +35,17 @@
 import org.apache.fop.datatypes.Numeric;
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.fop.fo.extensions.ExternalDocument;
 import org.apache.fop.fo.extensions.destination.Destination;
+import org.apache.fop.fo.pagination.AbstractPageSequence;
 import org.apache.fop.fo.pagination.PageSequence;
 import org.apache.fop.fo.pagination.Root;
 import org.apache.fop.fo.pagination.bookmarks.BookmarkTree;
+import org.apache.fop.layoutmgr.ExternalDocumentLayoutManager;
 import org.apache.fop.layoutmgr.LayoutManagerMaker;
 import org.apache.fop.layoutmgr.LayoutManagerMapping;
 import org.apache.fop.layoutmgr.PageSequenceLayoutManager;
+import org.apache.fop.layoutmgr.TopLevelLayoutManager;
 
 /**
  * Area tree handler for formatting objects.
@@ -78,7 +82,7 @@
     // The formatting results to be handed back to the caller.
     private FormattingResults results = new FormattingResults();
 
-    private PageSequenceLayoutManager prevPageSeqLM;
+    private TopLevelLayoutManager prevPageSeqLM;
 
     private int idGen = 0;
 
@@ -235,13 +239,39 @@
     }
 
     /**
+     * @see org.apache.fop.fo.FOEventHandler#startExternalDocument(org.apache.fop.fo.extensions.ExternalDocument)
+     */
+    public void startExternalDocument(ExternalDocument document) {
+        rootFObj = document.getRoot();
+        finishPrevPageSequence(document.getInitialPageNumber());
+        document.initPageNumber();
+    }
+
+    /**
+     * @see org.apache.fop.fo.FOEventHandler#endExternalDocument(org.apache.fop.fo.extensions.ExternalDocument)
+     */
+    public void endExternalDocument(ExternalDocument document) {
+        if (statistics != null) {
+            statistics.end();
+        }
+        
+        ExternalDocumentLayoutManager edLM;
+        edLM = getLayoutManagerMaker().makeExternalDocumentLayoutManager(this, document);
+        edLM.activateLayout();
+        // preserve the current PageSequenceLayoutManger for the
+        // force-page-count check at the beginning of the next PageSequence
+        prevPageSeqLM = edLM;
+        
+    }
+
+    /**
      * Called by the PageSequenceLayoutManager when it is finished with a
      * page-sequence.
      * 
      * @param pageSequence the page-sequence just finished
      * @param pageCount The number of pages generated for the page-sequence
      */
-    public void notifyPageSequenceFinished(PageSequence pageSequence,
+    public void notifyPageSequenceFinished(AbstractPageSequence pageSequence,
             int pageCount) {
         this.results.haveFormattedPageSequence(pageSequence, pageCount);
         if (log.isDebugEnabled()) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RenderPagesModel.java Thu Dec 27 02:34:15 2007
@@ -173,7 +173,7 @@
                     }
                 } catch (Exception e) {
                     // use error handler to handle this FOP or IO Exception
-                    log.error(e);
+                    log.error("Error while rendering page " + pageViewport.getPageIndex(), e);
                     if (e instanceof RuntimeException) {
                         throw (RuntimeException)e;
                     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOEventHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOEventHandler.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOEventHandler.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOEventHandler.java Thu Dec 27 02:34:15 2007
@@ -25,6 +25,7 @@
 import org.xml.sax.SAXException;
 
 import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.extensions.ExternalDocument;
 import org.apache.fop.fo.flow.BasicLink;
 import org.apache.fop.fo.flow.Block;
 import org.apache.fop.fo.flow.BlockContainer;
@@ -555,6 +556,20 @@
      * @param length Portion of array to process.
      */
     public void characters(char data[], int start, int length) {
+    }
+
+    /**
+     * Process the start of the external-document extension.
+     * @param document the external-document node
+     */
+    public void startExternalDocument(ExternalDocument document) {
+    }
+
+    /**
+     * Process the end of the external-document extension.
+     * @param document the external-document node
+     */
+    public void endExternalDocument(ExternalDocument document) {
     }
 
 }

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/GraphicsProperties.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/GraphicsProperties.java?rev=607032&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/GraphicsProperties.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/GraphicsProperties.java Thu Dec 27 02:34:15 2007
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo;
+
+import org.apache.fop.datatypes.Length;
+import org.apache.fop.fo.properties.LengthRangeProperty;
+
+/**
+ * This interface provides access to properties necessary to calculate the size and positioning
+ * of images and graphics inside a viewport.
+ */
+public interface GraphicsProperties {
+
+    /**
+     * @return the "inline-progression-dimension" property.
+     */
+    LengthRangeProperty getInlineProgressionDimension();
+
+    /**
+     * @return the "block-progression-dimension" property.
+     */
+    LengthRangeProperty getBlockProgressionDimension();
+
+    /**
+     * @return the "height" property.
+     */
+    Length getHeight();
+
+    /**
+     * @return the "width" property.
+     */
+    Length getWidth();
+    
+    /**
+     * @return the "content-height" property.
+     */
+    Length getContentHeight();
+
+    /**
+     * @return the "content-width" property.
+     */
+    Length getContentWidth();
+
+    /**
+     * @return the "scaling" property.
+     */
+    int getScaling();
+
+    /**
+     * @return the "overflow" property.
+     */
+    int getOverflow();
+
+    /**
+     * @return the "display-align" property.
+     */
+    int getDisplayAlign();
+
+    /**
+     * @return the "text-align" property.
+     */
+    int getTextAlign();
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/GraphicsProperties.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/GraphicsProperties.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java Thu Dec 27 02:34:15 2007
@@ -20,6 +20,8 @@
 package org.apache.fop.fo;
 
 // Java
+import java.text.MessageFormat;
+
 import org.xml.sax.Attributes;
 
 import org.apache.commons.logging.Log;
@@ -355,9 +357,9 @@
         if (propId == -1 
                 || (subpropId == -1 
                         && findSubPropertyName(propertyName) != null)) {
-            StringBuffer errorMessage = new StringBuffer().append(
-                        "Invalid property name \'").append(propertyName);
-            handleInvalidProperty(errorMessage.toString(), propertyName);
+            String errorMessage = MessageFormat.format(
+                    "Invalid property name ''{0}''.", new Object[] {propertyName});
+            handleInvalidProperty(errorMessage, propertyName);
             return false;
         }
         return true;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java Thu Dec 27 02:34:15 2007
@@ -62,12 +62,19 @@
             foObjs.put("outline", new UnknownXMLObj.Maker(URI));
             foObjs.put("label", new UnknownXMLObj.Maker(URI));
             foObjs.put("destination", new DestinationMaker());
+            foObjs.put("external-document", new ExternalDocumentMaker());
         }
     }
     
     static class DestinationMaker extends ElementMapping.Maker {
         public FONode make(FONode parent) {
             return new Destination(parent);
+        }
+    }
+
+    static class ExternalDocumentMaker extends ElementMapping.Maker {
+        public FONode make(FONode parent) {
+            return new ExternalDocument(parent);
         }
     }
 

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExternalDocument.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExternalDocument.java?rev=607032&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExternalDocument.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExternalDocument.java Thu Dec 27 02:34:15 2007
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.extensions;
+
+import org.xml.sax.Locator;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.datatypes.Length;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.GraphicsProperties;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.pagination.AbstractPageSequence;
+import org.apache.fop.fo.properties.LengthRangeProperty;
+
+/**
+ * Class for the fox:external-document extenstion element.
+ */
+public class ExternalDocument extends AbstractPageSequence implements GraphicsProperties {
+
+    // The value of properties relevant for fox:external-document
+    private LengthRangeProperty blockProgressionDimension;
+    private Length contentHeight;
+    private Length contentWidth;
+    private int displayAlign;
+    private Length height;
+    private LengthRangeProperty inlineProgressionDimension;
+    private int overflow;
+    private int scaling;
+    private String src;
+    private int textAlign;
+    private Length width;
+    // Unused but valid items, commented out for performance:
+    //     private CommonAccessibility commonAccessibility;
+    //     private CommonAural commonAural;
+    //     private String contentType;
+    //     private int scalingMethod;
+    // End of property values
+
+    /**
+     * Constructs a ExternalDocument object (called by Maker).
+     * @param parent the parent formatting object
+     */
+    public ExternalDocument(FONode parent) {
+        super(parent);
+    }
+
+    /** {@inheritDoc} */
+    public void bind(PropertyList pList) throws FOPException {
+        super.bind(pList);
+        blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
+        contentHeight = pList.get(PR_CONTENT_HEIGHT).getLength();
+        contentWidth = pList.get(PR_CONTENT_WIDTH).getLength();
+        displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum();
+        height = pList.get(PR_HEIGHT).getLength();
+        inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
+        overflow = pList.get(PR_OVERFLOW).getEnum();
+        scaling = pList.get(PR_SCALING).getEnum();
+        textAlign = pList.get(PR_TEXT_ALIGN).getEnum();
+        width = pList.get(PR_WIDTH).getLength();
+        src = pList.get(PR_SRC).getString();
+        
+        if (this.src == null || this.src.length() == 0) {
+            missingPropertyError("src");
+        }
+    }
+
+    protected void startOfNode() throws FOPException {
+        super.startOfNode();
+        getFOEventHandler().startExternalDocument(this);
+    }
+
+    /**
+     * @see org.apache.fop.fo.FONode#endOfNode
+     */
+    protected void endOfNode() throws FOPException {
+        getFOEventHandler().endExternalDocument(this);
+        super.endOfNode();
+    }
+
+    /**
+     * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
+        XSL/FOP: empty
+     */
+    protected void validateChildNode(Locator loc, String nsURI, String localName)
+        throws ValidationException {
+            invalidChildError(loc, nsURI, localName);
+    }
+
+    /**
+     * Returns the src attribute (the URI to the embedded document).
+     * @return the src attribute
+     */
+    public String getSrc() {
+        return this.src;
+    }
+
+    /** {@inheritDoc} */
+    public LengthRangeProperty getInlineProgressionDimension() {
+        return inlineProgressionDimension;
+    }
+
+    /** {@inheritDoc} */
+    public LengthRangeProperty getBlockProgressionDimension() {
+        return blockProgressionDimension;
+    }
+
+    /** {@inheritDoc} */
+    public Length getHeight() {
+        return height;
+    }
+
+    /** {@inheritDoc} */
+    public Length getWidth() {
+        return width;
+    }
+
+    /** {@inheritDoc} */
+    public Length getContentHeight() {
+        return contentHeight;
+    }
+
+    /** {@inheritDoc} */
+    public Length getContentWidth() {
+        return contentWidth;
+    }
+
+    /** {@inheritDoc} */
+    public int getScaling() {
+        return scaling;
+    }
+
+    /** {@inheritDoc} */
+    public int getOverflow() {
+        return overflow;
+    }
+
+    /** {@inheritDoc} */
+    public int getDisplayAlign() {
+        return displayAlign;
+    }
+
+    /** {@inheritDoc} */
+    public int getTextAlign() {
+        return textAlign;
+    }
+
+    /** @see org.apache.fop.fo.FONode#getNamespaceURI() */
+    public String getNamespaceURI() {
+        return ExtensionElementMapping.URI;
+    }
+
+    /** @see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */
+    public String getNormalNamespacePrefix() {
+        return "fox";
+    }
+
+    /** @see org.apache.fop.fo.FONode#getLocalName() */
+    public String getLocalName() {
+        return "external-document";
+    }
+
+}
+

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExternalDocument.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExternalDocument.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractGraphics.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractGraphics.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractGraphics.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractGraphics.java Thu Dec 27 02:34:15 2007
@@ -23,6 +23,7 @@
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.GraphicsProperties;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.LengthRangeProperty;
@@ -32,7 +33,7 @@
  * Common base class for instream-foreign-object and external-graphics
  * flow formatting objects.
  */
-public abstract class AbstractGraphics extends FObj {
+public abstract class AbstractGraphics extends FObj implements GraphicsProperties {
     
     // The value of properties relevant for fo:instream-foreign-object
     // and external-graphics.
@@ -101,56 +102,6 @@
     }
 
     /**
-     * Given the ipd and the content width calculates the
-     * required x offset based on the text-align property
-     * @param ipd the inline-progression-dimension of the object
-     * @param cwidth the calculated content width of the object
-     * @return the X offset
-     */
-    public int computeXOffset (int ipd, int cwidth) {
-        int xoffset = 0;
-        switch (textAlign) {
-            case EN_CENTER:
-                xoffset = (ipd - cwidth) / 2;
-                break;
-            case EN_END:
-                xoffset = ipd - cwidth;
-                break;
-            case EN_START:
-                break;
-            case EN_JUSTIFY:
-            default:
-                break;
-        }
-        return xoffset;
-    }
-
-    /**
-     * Given the bpd and the content height calculates the
-     * required y offset based on the display-align property
-     * @param bpd the block-progression-dimension of the object
-     * @param cheight the calculated content height of the object
-     * @return the Y offset
-     */
-    public int computeYOffset(int bpd, int cheight) {
-        int yoffset = 0;
-        switch (displayAlign) {
-            case EN_BEFORE:
-                break;
-            case EN_AFTER:
-                yoffset = bpd - cheight;
-                break;
-            case EN_CENTER:
-                yoffset = (bpd - cheight) / 2;
-                break;
-            case EN_AUTO:
-            default:
-                break;
-        }
-        return yoffset;
-    }
-
-    /**
      * @return the "id" property.
      */
     public String getId() {
@@ -171,16 +122,12 @@
         return lineHeight;
     }
 
-    /**
-     * @return the "inline-progression-dimension" property.
-     */
+    /** {@inheritDoc} */
     public LengthRangeProperty getInlineProgressionDimension() {
         return inlineProgressionDimension;
     }
 
-    /**
-     * @return the "block-progression-dimension" property.
-     */
+    /** {@inheritDoc} */
     public LengthRangeProperty getBlockProgressionDimension() {
         return blockProgressionDimension;
     }
@@ -199,32 +146,34 @@
         return width;
     }
 
-    /**
-     * @return the "content-height" property.
-     */
+    /** {@inheritDoc} */
     public Length getContentHeight() {
         return contentHeight;
     }
 
-    /**
-     * @return the "content-width" property.
-     */
+    /** {@inheritDoc} */
     public Length getContentWidth() {
         return contentWidth;
     }
 
-    /**
-     * @return the "scaling" property.
-     */
+    /** {@inheritDoc} */
     public int getScaling() {
         return scaling;
     }
 
-    /**
-     * @return the "overflow" property.
-     */
+    /** {@inheritDoc} */
     public int getOverflow() {
         return overflow;
+    }
+
+    /** {@inheritDoc} */
+    public int getDisplayAlign() {
+        return displayAlign;
+    }
+
+    /** {@inheritDoc} */
+    public int getTextAlign() {
+        return textAlign;
     }
 
     /**

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java?rev=607032&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java Thu Dec 27 02:34:15 2007
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.pagination;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.datatypes.Numeric;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+
+/**
+ * Abstract base class for the fo:page-sequence formatting object and the fox:external-document
+ * extension object.
+ */
+public abstract class AbstractPageSequence extends FObj {
+    
+    // The value of properties relevant for fo:page-sequence.
+    protected Numeric initialPageNumber;
+    protected int forcePageCount;
+    private String format;
+    private int letterValue;
+    private char groupingSeparator;
+    private int groupingSize;
+    private Numeric referenceOrientation; //XSL 1.1
+    // End of property values
+
+    private PageNumberGenerator pageNumberGenerator;
+
+    protected int startingPageNumber = 0;
+
+    /**
+     * Create a page sequence FO node.
+     *
+     * @param parent the parent FO node
+     */
+    public AbstractPageSequence(FONode parent) {
+        super(parent);
+    }
+
+    /**
+     * @see org.apache.fop.fo.FObj#bind(PropertyList)
+     */
+    public void bind(PropertyList pList) throws FOPException {
+        super.bind(pList);
+        initialPageNumber = pList.get(PR_INITIAL_PAGE_NUMBER).getNumeric();
+        forcePageCount = pList.get(PR_FORCE_PAGE_COUNT).getEnum();
+        format = pList.get(PR_FORMAT).getString();
+        letterValue = pList.get(PR_LETTER_VALUE).getEnum();
+        groupingSeparator = pList.get(PR_GROUPING_SEPARATOR).getCharacter();
+        groupingSize = pList.get(PR_GROUPING_SIZE).getNumber().intValue();
+        referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric();
+    }
+
+    /**
+     * @see org.apache.fop.fo.FONode#startOfNode()
+     */
+    protected void startOfNode() throws FOPException {
+        this.pageNumberGenerator = new PageNumberGenerator(
+                format, groupingSeparator, groupingSize, letterValue);
+
+    }
+
+    /** @see org.apache.fop.fo.FONode#endOfNode() */
+    protected void endOfNode() throws FOPException {
+    }
+
+    /**
+     * Initialize the current page number for the start of the page sequence.
+     */
+    public void initPageNumber() {
+        int pageNumberType = 0;
+        
+        if (initialPageNumber.getEnum() != 0) {
+            // auto | auto-odd | auto-even.
+            startingPageNumber = getRoot().getEndingPageNumberOfPreviousSequence() + 1;
+            pageNumberType = initialPageNumber.getEnum();
+            if (pageNumberType == EN_AUTO_ODD) {
+                if (startingPageNumber % 2 == 0) {
+                    startingPageNumber++;
+                }
+            } else if (pageNumberType == EN_AUTO_EVEN) {
+                if (startingPageNumber % 2 == 1) {
+                    startingPageNumber++;
+                }
+            }
+        } else { // <integer> for explicit page number
+            int pageStart = initialPageNumber.getValue();
+            startingPageNumber = (pageStart > 0) ? pageStart : 1; // spec rule
+        }
+    }
+
+    /**
+     * Get the starting page number for this page sequence.
+     *
+     * @return the starting page number
+     */
+    public int getStartingPageNumber() {
+        return startingPageNumber;
+    }
+
+    /**
+     * Retrieves the string representation of a page number applicable
+     * for this page sequence
+     * @param pageNumber the page number
+     * @return string representation of the page number
+     */
+    public String makeFormattedPageNumber(int pageNumber) {
+        return pageNumberGenerator.makeFormattedPageNumber(pageNumber);
+    }
+
+    /**
+     * Public accessor for the ancestor Root.
+     * @return the ancestor Root
+     */
+    public Root getRoot() {
+        return (Root)this.getParent();
+    }
+
+    /** @return the force-page-count value */
+    public int getForcePageCount() {
+        return forcePageCount;
+    }
+
+    /** @return the initial-page-number property value */
+    public Numeric getInitialPageNumber() {
+        return initialPageNumber;
+    }
+    
+    /**
+     * @return the "reference-orientation" property.
+     * @since XSL 1.1
+     */
+    public int getReferenceOrientation() {
+        return referenceOrientation.getValue();
+    }
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java Thu Dec 27 02:34:15 2007
@@ -93,14 +93,20 @@
      * @param isFirstPage True if page is first page
      * @param isLastPage True if page is last page
      * @param isBlankPage True if page is blank
+     * @param isOnlyPage True if page is the only page
      * @return True if the conditions for this reference are met
      */
     protected boolean isValid(boolean isOddPage,
                               boolean isFirstPage,
                               boolean isLastPage,
+                              boolean isOnlyPage,
                               boolean isBlankPage) {
         // page-position
-        if (isFirstPage) {
+        if (isOnlyPage) {
+            if (pagePosition != EN_ONLY) {
+                return false;
+            }
+        } else if (isFirstPage) {
             if (pagePosition == EN_REST) {
                 return false;
             } else if (pagePosition == EN_LAST) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequence.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequence.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequence.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequence.java Thu Dec 27 02:34:15 2007
@@ -25,32 +25,22 @@
 import org.xml.sax.Locator;
 
 import org.apache.fop.apps.FOPException;
-import org.apache.fop.datatypes.Numeric;
 import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.ValidationException;
 
 /**
- * Implementation of the fo:page-sequence formatting object.
+ * Abstract base implementation for page sequences.
  */
-public class PageSequence extends FObj {
+public class PageSequence extends AbstractPageSequence {
     
     // The value of properties relevant for fo:page-sequence.
     private String country;
-    private String format;
     private String language;
-    private int letterValue;
-    private char groupingSeparator;
-    private int groupingSize;
-    private Numeric initialPageNumber;
-    private int forcePageCount;
     private String masterReference;
+    //private int writingMode; //XSL 1.1
     // End of property values
 
-    /** The parent root object */
-    private Root root;
-
     // There doesn't seem to be anything in the spec requiring flows
     // to be in the order given, only that they map to the regions
     // defined in the page sequence, so all we need is this one hashmap
@@ -59,9 +49,6 @@
     /** Map of flows to their flow name (flow-name, Flow) */
     private Map flowMap;
 
-    private int startingPageNumber = 0;
-    private PageNumberGenerator pageNumberGenerator;
-
     /**
      * The currentSimplePageMaster is either the page master for the
      * whole page sequence if master-reference refers to a simple-page-master,
@@ -97,14 +84,9 @@
     public void bind(PropertyList pList) throws FOPException {
         super.bind(pList);
         country = pList.get(PR_COUNTRY).getString();
-        format = pList.get(PR_FORMAT).getString();
         language = pList.get(PR_LANGUAGE).getString();
-        letterValue = pList.get(PR_LETTER_VALUE).getEnum();
-        groupingSeparator = pList.get(PR_GROUPING_SEPARATOR).getCharacter();
-        groupingSize = pList.get(PR_GROUPING_SIZE).getNumber().intValue();
-        initialPageNumber = pList.get(PR_INITIAL_PAGE_NUMBER).getNumeric();
-        forcePageCount = pList.get(PR_FORCE_PAGE_COUNT).getEnum();
         masterReference = pList.get(PR_MASTER_REFERENCE).getString();
+        //writingMode = pList.getWritingMode();
         
         if (masterReference == null || masterReference.equals("")) {
             missingPropertyError("master-reference");
@@ -116,13 +98,12 @@
      */
     protected void startOfNode() throws FOPException {
         super.startOfNode();
-        this.root = (Root) parent;
         flowMap = new java.util.HashMap();
 
-        this.simplePageMaster = root.getLayoutMasterSet().getSimplePageMaster(masterReference);
+        this.simplePageMaster = getRoot().getLayoutMasterSet().getSimplePageMaster(masterReference);
         if (this.simplePageMaster == null) {
             this.pageSequenceMaster
-                    = root.getLayoutMasterSet().getPageSequenceMaster(masterReference);
+                    = getRoot().getLayoutMasterSet().getPageSequenceMaster(masterReference);
             if (this.pageSequenceMaster == null) {
                 throw new ValidationException("master-reference '" + masterReference
                    + "' for fo:page-sequence matches no"
@@ -130,9 +111,6 @@
             }
         }
 
-        this.pageNumberGenerator = new PageNumberGenerator(
-                format, groupingSeparator, groupingSize, letterValue);
-
         getFOEventHandler().startPageSequence(this);
     }
 
@@ -211,7 +189,7 @@
                 + "\" found within fo:page-sequence", flow.getLocator());
         }
 
-        if (!root.getLayoutMasterSet().regionNameExists(flowName) 
+        if (!getRoot().getLayoutMasterSet().regionNameExists(flowName) 
             && !flowName.equals("xsl-before-float-separator") 
             && !flowName.equals("xsl-footnote-separator")) {
                 throw new ValidationException("flow-name \""
@@ -221,31 +199,6 @@
         }
     }
 
-    /**
-     * Initialize the current page number for the start of the page sequence.
-     */
-    public void initPageNumber() {
-        int pageNumberType = 0;
-        
-        if (initialPageNumber.getEnum() != 0) {
-            // auto | auto-odd | auto-even.
-            startingPageNumber = root.getEndingPageNumberOfPreviousSequence() + 1;
-            pageNumberType = initialPageNumber.getEnum();
-            if (pageNumberType == EN_AUTO_ODD) {
-                if (startingPageNumber % 2 == 0) {
-                    startingPageNumber++;
-                }
-            } else if (pageNumberType == EN_AUTO_EVEN) {
-                if (startingPageNumber % 2 == 1) {
-                    startingPageNumber++;
-                }
-            }
-        } else { // <integer> for explicit page number
-            int pageStart = initialPageNumber.getValue();
-            startingPageNumber = (pageStart > 0) ? pageStart : 1; // spec rule
-        }
-    }
-
 //     /**
 //      * Returns true when there is more flow elements left to lay out.
 //      */
@@ -306,15 +259,6 @@
 //          return false;
 //      }
 
-    /**
-     * Get the starting page number for this page sequence.
-     *
-     * @return the starting page number
-     */
-    public int getStartingPageNumber() {
-        return startingPageNumber;
-    }
-
 //     private void forcePage(AreaTree areaTree, int firstAvailPageNumber) {
 //         boolean makePage = false;
 //         if (this.forcePageCount == ForcePageCount.AUTO) {
@@ -433,6 +377,8 @@
      *      page sequence
      * @param isLastPage indicator whether this page is the last page of the
      *      page sequence
+     * @param isOnlyPage indicator whether this page is the only page of the
+     *      page sequence
      * @param isBlank indicator whether the page will be blank
      * @return the SimplePageMaster to use for this page
      * @throws FOPException if there's a problem determining the page master
@@ -440,6 +386,7 @@
     public SimplePageMaster getNextSimplePageMaster(int page, 
             boolean isFirstPage,  
             boolean isLastPage,  
+            boolean isOnlyPage,
             boolean isBlank) throws FOPException {
 
         if (pageSequenceMaster == null) {
@@ -450,11 +397,12 @@
             log.debug("getNextSimplePageMaster(page=" + page
                     + " isOdd=" + isOddPage 
                     + " isFirst=" + isFirstPage 
-                    + " isLast=" + isLastPage 
+                    + " isLast=" + isLastPage
+                    + " isOnly=" + isOnlyPage
                     + " isBlank=" + isBlank + ")");
         }
         return pageSequenceMaster.getNextSimplePageMaster(isOddPage, 
-            isFirstPage, isLastPage, isBlank);
+            isFirstPage, isLastPage, isOnlyPage, isBlank);
     }
 
     /**
@@ -478,24 +426,15 @@
         }
     }
     
-    /**
-     * Retrieves the string representation of a page number applicable
-     * for this page sequence
-     * @param pageNumber the page number
-     * @return string representation of the page number
-     */
-    public String makeFormattedPageNumber(int pageNumber) {
-        return pageNumberGenerator.makeFormattedPageNumber(pageNumber);
-    }
-
-    /**
-     * Public accessor for the ancestor Root.
-     * @return the ancestor Root
-     */
-    public Root getRoot() {
-        return root;
+    /** @return true if the page-sequence has a page-master with page-position="only" */
+    public boolean hasPagePositionOnly() {
+        if (pageSequenceMaster == null) {
+            return false;
+        } else {
+            return pageSequenceMaster.hasPagePositionOnly();
+        }
     }
-
+    
     /** @return the "master-reference" property. */
     public String getMasterReference() {
         return masterReference;
@@ -509,16 +448,6 @@
     /** {@inheritDoc} */
     public int getNameId() {
         return FO_PAGE_SEQUENCE;
-    }
-    
-    /** @return the force-page-count value */
-    public int getForcePageCount() {
-        return forcePageCount;
-    }
-
-    /** @return the initial-page-number property value */
-    public Numeric getInitialPageNumber() {
-        return initialPageNumber;
     }
     
     /** @return the country property value */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java Thu Dec 27 02:34:15 2007
@@ -171,11 +171,21 @@
         }
     }
     
+    /** @return true if the page-sequence-master has a page-master with page-position="only" */
+    public boolean hasPagePositionOnly() {
+        if (currentSubSequence != null) {
+            return currentSubSequence.hasPagePositionOnly();
+        } else {
+            return false;
+        }
+    }
+    
     /**
      * Returns the next simple-page-master.
      * @param isOddPage True if the next page number is odd
      * @param isFirstPage True if the next page is the first
      * @param isLastPage True if the next page is the last
+     * @param isOnlyPage True if the next page is the only page
      * @param isBlankPage True if the next page is blank
      * @return the requested page master
      * @throws FOPException if there's a problem determining the next page master
@@ -183,6 +193,7 @@
     public SimplePageMaster getNextSimplePageMaster(boolean isOddPage,
                                                     boolean isFirstPage,
                                                     boolean isLastPage,
+                                                    boolean isOnlyPage,
                                                     boolean isBlankPage)
                                                       throws FOPException {
         if (currentSubSequence == null) {
@@ -193,7 +204,7 @@
             }
         }
         String pageMasterName = currentSubSequence
-            .getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isBlankPage);
+            .getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage);
         boolean canRecover = true;
         while (pageMasterName == null) {
             SubSequenceSpecifier nextSubSequence = getNextSubSequence();
@@ -212,7 +223,7 @@
                 currentSubSequence = nextSubSequence;
             }
             pageMasterName = currentSubSequence
-                .getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isBlankPage);
+                .getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage);
         }
         SimplePageMaster pageMaster = this.layoutMasterSet
             .getSimplePageMaster(pageMasterName);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java Thu Dec 27 02:34:15 2007
@@ -49,6 +49,7 @@
 
     private List conditionalPageMasterRefs;
     private boolean hasPagePositionLast = false;
+    private boolean hasPagePositionOnly = false;
 
     /**
      * @see org.apache.fop.fo.FONode#FONode(FONode)
@@ -124,6 +125,7 @@
     public String getNextPageMasterName(boolean isOddPage,
                                         boolean isFirstPage,
                                         boolean isLastPage,
+                                        boolean isOnlyPage,
                                         boolean isBlankPage) {
         if (getMaximumRepeats() != INFINITE) {
             if (numberConsumed < getMaximumRepeats()) {
@@ -138,7 +140,7 @@
         for (int i = 0; i < conditionalPageMasterRefs.size(); i++) {
             ConditionalPageMasterReference cpmr
                 = (ConditionalPageMasterReference)conditionalPageMasterRefs.get(i);
-            if (cpmr.isValid(isOddPage, isFirstPage, isLastPage, isBlankPage)) {
+            if (cpmr.isValid(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage)) {
                 return cpmr.getMasterReference();
             }
         }
@@ -155,6 +157,9 @@
         if (cpmr.getPagePosition() == EN_LAST) {
             this.hasPagePositionLast = true;
         }
+        if (cpmr.getPagePosition() == EN_ONLY) {
+            this.hasPagePositionOnly = true;
+        }
     }
 
     /** {@inheritDoc} */
@@ -178,6 +183,12 @@
     }
     
     /** {@inheritDoc} */
+    /** @see org.apache.fop.fo.pagination.SubSequenceSpecifier#hasPagePositionOnly() */
+    public boolean hasPagePositionOnly() {
+        return this.hasPagePositionOnly;
+    }
+    
+    /** @see org.apache.fop.fo.FONode#getLocalName() */
     public String getLocalName() {
         return "repeatable-page-master-alternatives";
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java Thu Dec 27 02:34:15 2007
@@ -93,6 +93,7 @@
     public String getNextPageMasterName(boolean isOddPage,
                                         boolean isFirstPage,
                                         boolean isLastPage,
+                                        boolean isOnlyPage,
                                         boolean isEmptyPage) {
         if (getMaximumRepeats() != INFINITE) {
             if (numberConsumed < getMaximumRepeats()) {
@@ -141,6 +142,11 @@
     }
 
     /** {@inheritDoc} */
+    public boolean hasPagePositionOnly() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
     public String getLocalName() {
         return "repeatable-page-master-reference";
     }
@@ -149,5 +155,6 @@
     public int getNameId() {
         return FO_REPEATABLE_PAGE_MASTER_REFERENCE;
     }
+
 
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Root.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Root.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Root.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Root.java Thu Dec 27 02:34:15 2007
@@ -25,6 +25,7 @@
 import org.xml.sax.Locator;
 
 import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.ElementMapping;
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
@@ -85,7 +86,7 @@
     protected void endOfNode() throws FOPException {
         if (!pageSequenceFound || layoutMasterSet == null) {
             missingChildElementError("(layout-master-set, declarations?, " + 
-                "bookmark-tree?, page-sequence+)");
+                "bookmark-tree?, (page-sequence+|fox:external-document))");
         }
     }
 
@@ -129,7 +130,21 @@
                 invalidChildError(loc, nsURI, localName);
             }
         } else {
-            invalidChildError(loc, nsURI, localName);
+            if (FOX_URI.equals(nsURI)) {
+                if ("external-document".equals(localName)) {
+                    pageSequenceFound = true;
+                }
+            }
+            //invalidChildError(loc, nsURI, localName);
+            //Ignore non-FO elements under root
+        }
+    }
+    
+
+    /** @inheritDoc */
+    protected void validateChildNode(Locator loc, FONode child) throws ValidationException {
+        if (child instanceof AbstractPageSequence) {
+            pageSequenceFound = true;
         }
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java Thu Dec 27 02:34:15 2007
@@ -85,6 +85,7 @@
     public String getNextPageMasterName(boolean isOddPage,
                                         boolean isFirstPage,
                                         boolean isLastPage,
+                                        boolean isOnlyPage,
                                         boolean isEmptyPage) {
         if (this.state == FIRST) {
             this.state = DONE;
@@ -117,6 +118,11 @@
     }
 
     /** {@inheritDoc} */
+    public boolean hasPagePositionOnly() {
+        return false;
+    }
+    
+    /** {@inheritDoc} */
     public String getLocalName() {
         return "single-page-master-reference";
     }
@@ -125,5 +131,6 @@
     public int getNameId() {
         return FO_SINGLE_PAGE_MASTER_REFERENCE;
     }
+
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java Thu Dec 27 02:34:15 2007
@@ -32,6 +32,7 @@
      * @param isOddPage True if the next page number is odd
      * @param isFirstPage True if the next page is the first
      * @param isLastPage True if the next page is the last
+     * @param isOnlyPage True if the next page is the only page
      * @param isBlankPage True if the next page is blank
      * @return the page master name
      * @throws FOPException if there's a problem determining the next page master
@@ -39,6 +40,7 @@
     String getNextPageMasterName(boolean isOddPage,
                                  boolean isFirstPage,
                                  boolean isLastPage,
+                                 boolean isOnlyPage,
                                  boolean isBlankPage)
                                     throws FOPException;
 
@@ -56,6 +58,9 @@
 
     /** @return true if the subsequence has a page master for page-position "last" */
     boolean hasPagePositionLast();
+    
+    /** @return true if the subsequence has a page master for page-position "only" */
+    boolean hasPagePositionOnly();
     
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java Thu Dec 27 02:34:15 2007
@@ -224,9 +224,7 @@
         return newLMs;
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public PageSequenceLayoutManager getPSLM() {
         return parentLM.getPSLM();
     }

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java?rev=607032&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java Thu Dec 27 02:34:15 2007
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutmgr;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.area.AreaTreeHandler;
+import org.apache.fop.area.AreaTreeModel;
+import org.apache.fop.area.IDTracker;
+import org.apache.fop.area.PageViewport;
+import org.apache.fop.area.Resolvable;
+import org.apache.fop.datatypes.Numeric;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.flow.Marker;
+import org.apache.fop.fo.flow.RetrieveMarker;
+import org.apache.fop.fo.pagination.AbstractPageSequence;
+
+/**
+ * Abstract base class for a page sequence layout manager.
+ */
+public abstract class AbstractPageSequenceLayoutManager extends AbstractLayoutManager
+            implements TopLevelLayoutManager {
+
+    private static Log log = LogFactory.getLog(AbstractPageSequenceLayoutManager.class);
+
+    /** 
+     * AreaTreeHandler which activates the PSLM and controls
+     * the rendering of its pages.
+     */
+    protected AreaTreeHandler areaTreeHandler;
+    
+    /** ID tracker supplied by the AreaTreeHandler */
+    protected IDTracker idTracker;
+    
+    /** page sequence formatting object being processed by this class */
+    protected AbstractPageSequence pageSeq;
+
+    /** Current page with page-viewport-area being filled by the PSLM. */
+    protected Page curPage;
+
+    /** the current page number */
+    protected int currentPageNum = 0;
+    /** The stating page number */
+    protected int startPageNum = 0;
+    
+    /**
+     * Constructor
+     *
+     * @param ath the area tree handler object
+     * @param pseq fo:page-sequence to process
+     */
+    public AbstractPageSequenceLayoutManager(AreaTreeHandler ath, AbstractPageSequence pseq) {
+        super(pseq);
+        this.areaTreeHandler = ath;
+        this.idTracker = ath.getIDTracker();
+        this.pageSeq = pseq;
+    }
+
+    /**
+     * @return the LayoutManagerMaker object associated to the areaTreeHandler
+     */
+    public LayoutManagerMaker getLayoutManagerMaker() {
+        return areaTreeHandler.getLayoutManagerMaker();
+    }
+
+    /**
+     * Provides access to the current page.
+     * @return the current Page
+     */
+    public Page getCurrentPage() {
+        return curPage;
+    }
+
+    /**
+     * Provides access for setting the current page.
+     * @param currentPage the new current Page
+     */
+    protected void setCurrentPage(Page currentPage) {
+        this.curPage = currentPage;
+    }
+
+    /**
+     * Provides access to the current page number
+     * @return the current page number
+     */
+    protected int getCurrentPageNum() {
+        return currentPageNum;
+    }
+
+    /** {@inheritDoc} */
+    public void initialize() {
+        startPageNum = pageSeq.getStartingPageNumber();
+        currentPageNum = startPageNum - 1;
+    }
+    
+    /**
+     * This returns the first PageViewport that contains an id trait
+     * matching the idref argument, or null if no such PV exists.
+     *
+     * @param idref the idref trait needing to be resolved 
+     * @return the first PageViewport that contains the ID trait
+     */
+    public PageViewport getFirstPVWithID(String idref) {
+        List list = idTracker.getPageViewportsContainingID(idref);
+        if (list != null && list.size() > 0) {
+            return (PageViewport) list.get(0);
+        }
+        return null;
+    }
+
+    /**
+     * This returns the last PageViewport that contains an id trait
+     * matching the idref argument, or null if no such PV exists.
+     *
+     * @param idref the idref trait needing to be resolved 
+     * @return the last PageViewport that contains the ID trait
+     */
+    public PageViewport getLastPVWithID(String idref) {
+        List list = idTracker.getPageViewportsContainingID(idref);
+        if (list != null && list.size() > 0) {
+            return (PageViewport) list.get(list.size() - 1);
+        }
+        return null;
+    }
+    
+    /**
+     * Add an ID reference to the current page.
+     * When adding areas the area adds its ID reference.
+     * For the page layout manager it adds the id reference
+     * with the current page to the area tree.
+     *
+     * @param id the ID reference to add
+     */
+    public void addIDToPage(String id) {
+        if (id != null && id.length() > 0) {
+            idTracker.associateIDWithPageViewport(id, curPage.getPageViewport());
+        }
+    }
+    
+    /**
+     * Add an id reference of the layout manager in the AreaTreeHandler,
+     * if the id hasn't been resolved yet
+     * @param id the id to track
+     * @return a boolean indicating if the id has already been resolved
+     * TODO Maybe give this a better name
+     */
+    public boolean associateLayoutManagerID(String id) {
+        if (log.isDebugEnabled()) {
+            log.debug("associateLayoutManagerID(" + id + ")");
+        }
+        if (!idTracker.alreadyResolvedID(id)) {
+            idTracker.signalPendingID(id);
+            return false;
+        } else {
+            return true;
+        }
+    }
+    
+    /**
+     * Notify the areaTreeHandler that the LayoutManagers containing
+     * idrefs have finished creating areas
+     * @param id the id for which layout has finished
+     */
+    public void notifyEndOfLayout(String id) {
+        idTracker.signalIDProcessed(id);
+    }
+    
+    /**
+     * Identify an unresolved area (one needing an idref to be 
+     * resolved, e.g. the internal-destination of an fo:basic-link)
+     * for both the AreaTreeHandler and PageViewport object.
+     * 
+     * The IDTracker keeps a document-wide list of idref's
+     * and the PV's needing them to be resolved.  It uses this to  
+     * send notifications to the PV's when an id has been resolved.
+     * 
+     * The PageViewport keeps lists of id's needing resolving, along
+     * with the child areas (page-number-citation, basic-link, etc.)
+     * of the PV needing their resolution.
+     *
+     * @param id the ID reference to add
+     * @param res the resolvable object that needs resolving
+     */
+    public void addUnresolvedArea(String id, Resolvable res) {
+        curPage.getPageViewport().addUnresolvedIDRef(id, res);
+        idTracker.addUnresolvedIDRef(id, curPage.getPageViewport());
+    }
+
+    /**
+     * Bind the RetrieveMarker to the corresponding Marker subtree.
+     * If the boundary is page then it will only check the
+     * current page. For page-sequence and document it will
+     * lookup preceding pages from the area tree and try to find
+     * a marker.
+     * If we retrieve a marker from a preceding page,
+     * then the containing page does not have a qualifying area,
+     * and all qualifying areas have ended.
+     * Therefore we use last-ending-within-page (Constants.EN_LEWP)
+     * as the position. 
+     *
+     * @param rm the RetrieveMarker instance whose properties are to
+     * used to find the matching Marker.
+     * @return a bound RetrieveMarker instance, or null if no Marker
+     * could be found.
+     */
+    public RetrieveMarker resolveRetrieveMarker(RetrieveMarker rm) {
+        AreaTreeModel areaTreeModel = areaTreeHandler.getAreaTreeModel();
+        String name = rm.getRetrieveClassName();
+        int pos = rm.getRetrievePosition();
+        int boundary = rm.getRetrieveBoundary();               
+        
+        // get marker from the current markers on area tree
+        Marker mark = (Marker)getCurrentPV().getMarker(name, pos);
+        if (mark == null && boundary != EN_PAGE) {
+            // go back over pages until mark found
+            // if document boundary then keep going
+            boolean doc = boundary == EN_DOCUMENT;
+            int seq = areaTreeModel.getPageSequenceCount();
+            int page = areaTreeModel.getPageCount(seq) - 1;
+            while (page < 0 && doc && seq > 1) {
+                seq--;
+                page = areaTreeModel.getPageCount(seq) - 1;
+            }
+            while (page >= 0) {
+                PageViewport pv = areaTreeModel.getPage(seq, page);
+                mark = (Marker)pv.getMarker(name, Constants.EN_LEWP);
+                if (mark != null) {
+                    break;
+                }
+                page--;
+                if (page < 0 && doc && seq > 1) {
+                    seq--;
+                    page = areaTreeModel.getPageCount(seq) - 1;
+                }
+            }
+        }
+
+        if (mark == null) {
+            log.debug("found no marker with name: " + name);
+            return null;
+        } else {
+            rm.bindMarker(mark);
+            return rm;
+        }
+    }
+
+    /**
+     * Creates and returns a new page.
+     * @param pageNumber the page number
+     * @param isBlank true if it's a blank page
+     * @return the newly created page
+     */
+    protected abstract Page createPage(int pageNumber, boolean isBlank);
+    
+    /**
+     * Makes a new page
+     * 
+     * @param bIsBlank whether this page is blank or not
+     * @param bIsLast whether this page is the last page or not
+     * @return a new page
+     */
+    protected Page makeNewPage(boolean isBlank, boolean isLast) {
+        if (curPage != null) {
+            finishPage();
+        }
+
+        currentPageNum++;
+
+        curPage = createPage(currentPageNum, isBlank);
+
+        if (log.isDebugEnabled()) {
+            log.debug("[" + curPage.getPageViewport().getPageNumberString() 
+                    + (isBlank ? "*" : "") + "]");
+        }
+        
+        addIDToPage(pageSeq.getId());
+        return curPage;
+    }
+    
+    /**
+     * Finishes a page in preparation for a new page.
+     */
+    protected void finishPage() {
+        if (log.isTraceEnabled()) {
+            curPage.getPageViewport().dumpMarkers();
+        }
+        
+        // Try to resolve any unresolved IDs for the current page.
+        // 
+        idTracker.tryIDResolution(curPage.getPageViewport());
+        // Queue for ID resolution and rendering
+        areaTreeHandler.getAreaTreeModel().addPage(curPage.getPageViewport());
+        if (log.isDebugEnabled()) {
+            log.debug("page finished: " + curPage.getPageViewport().getPageNumberString() 
+                    + ", current num: " + currentPageNum);
+        }
+        curPage = null;
+    }
+    
+    /** {@inheritDoc} */
+    public void doForcePageCount(Numeric nextPageSeqInitialPageNumber) {
+
+        int forcePageCount = pageSeq.getForcePageCount();
+
+        // xsl-spec version 1.0   (15.oct 2001)
+        // auto | even | odd | end-on-even | end-on-odd | no-force | inherit
+        // auto:
+        // Force the last page in this page-sequence to be an odd-page 
+        // if the initial-page-number of the next page-sequence is even. 
+        // Force it to be an even-page 
+        // if the initial-page-number of the next page-sequence is odd. 
+        // If there is no next page-sequence 
+        // or if the value of its initial-page-number is "auto" do not force any page.
+            
+        // if force-page-count is auto then set the value of forcePageCount 
+        // depending on the initial-page-number of the next page-sequence
+        if (nextPageSeqInitialPageNumber != null && forcePageCount == Constants.EN_AUTO) {
+            if (nextPageSeqInitialPageNumber.getEnum() != 0) {
+                // auto | auto-odd | auto-even
+                int nextPageSeqPageNumberType = nextPageSeqInitialPageNumber.getEnum();
+                if (nextPageSeqPageNumberType == Constants.EN_AUTO_ODD) {
+                    forcePageCount = Constants.EN_END_ON_EVEN;
+                } else if (nextPageSeqPageNumberType == Constants.EN_AUTO_EVEN) {
+                    forcePageCount = Constants.EN_END_ON_ODD;
+                } else {   // auto
+                    forcePageCount = Constants.EN_NO_FORCE;
+                }
+            } else { // <integer> for explicit page number
+                int nextPageSeqPageStart = nextPageSeqInitialPageNumber.getValue();
+                // spec rule
+                nextPageSeqPageStart = (nextPageSeqPageStart > 0) ? nextPageSeqPageStart : 1;
+                if (nextPageSeqPageStart % 2 == 0) {   // explicit even startnumber
+                    forcePageCount = Constants.EN_END_ON_ODD;
+                } else {    // explicit odd startnumber
+                    forcePageCount = Constants.EN_END_ON_EVEN;
+                }
+            }
+        }
+
+        if (forcePageCount == Constants.EN_EVEN) {
+            if ((currentPageNum - startPageNum + 1) % 2 != 0) { // we have an odd number of pages
+                curPage = makeNewPage(true, false);
+            }
+        } else if (forcePageCount == Constants.EN_ODD) {
+            if ((currentPageNum - startPageNum + 1) % 2 == 0) { // we have an even number of pages
+                curPage = makeNewPage(true, false);
+            }
+        } else if (forcePageCount == Constants.EN_END_ON_EVEN) {
+            if (currentPageNum % 2 != 0) { // we are now on an odd page
+                curPage = makeNewPage(true, false);
+            }
+        } else if (forcePageCount == Constants.EN_END_ON_ODD) {
+            if (currentPageNum % 2 == 0) { // we are now on an even page
+                curPage = makeNewPage(true, false);
+            }
+        } else if (forcePageCount == Constants.EN_NO_FORCE) {
+            // i hope: nothing special at all
+        }
+
+        if (curPage != null) {
+            finishPage();
+        }
+    }
+    
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java?rev=607032&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java Thu Dec 27 02:34:15 2007
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutmgr;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.area.AreaTreeHandler;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.BodyRegion;
+import org.apache.fop.area.CTM;
+import org.apache.fop.area.LineArea;
+import org.apache.fop.area.PageViewport;
+import org.apache.fop.area.RegionViewport;
+import org.apache.fop.area.inline.Image;
+import org.apache.fop.area.inline.Viewport;
+import org.apache.fop.datatypes.FODimension;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.extensions.ExternalDocument;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.image.ImageFactory;
+import org.apache.fop.layoutmgr.inline.ImageLayout;
+
+/**
+ * LayoutManager for an external-document extension element.  This class is instantiated by
+ * area.AreaTreeHandler for each fo:external-document found in the
+ * input document.
+ */
+public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutManager {
+
+    private static Log log = LogFactory.getLog(ExternalDocumentLayoutManager.class);
+
+    private FopImage image;
+    private ImageLayout imageLayout; 
+    
+    /**
+     * Constructor
+     *
+     * @param ath the area tree handler object
+     * @param pseq fo:page-sequence to process
+     */
+    public ExternalDocumentLayoutManager(AreaTreeHandler ath, ExternalDocument document) {
+        super(ath, document);
+    }
+
+    /**
+     * @return the ExternalDocument being managed by this layout manager 
+     */
+    protected ExternalDocument getExternalDocument() {
+        return (ExternalDocument)pageSeq;
+    }
+
+    /** {@inheritDoc} */
+    public PageSequenceLayoutManager getPSLM() {
+        throw new IllegalStateException("getPSLM() is illegal for " + getClass().getName());
+    }
+    
+    /** {@inheritDoc} */
+    public void activateLayout() {
+        initialize();
+
+        String uri = getExternalDocument().getSrc();
+        FOUserAgent userAgent = pageSeq.getUserAgent();
+        ImageFactory fact = userAgent.getFactory().getImageFactory();
+        this.image = fact.getImage(uri, userAgent);
+        if (this.image == null) {
+            log.error("Image not available: " + uri);
+            return;
+        } else {
+            // load dimensions
+            if (!this.image.load(FopImage.DIMENSIONS)) {
+                log.error("Cannot read image dimensions: " + uri);
+                return;
+            }
+        }
+        Dimension intrinsicSize = new Dimension(
+                image.getIntrinsicWidth(),
+                image.getIntrinsicHeight());
+        this.imageLayout = new ImageLayout(getExternalDocument(), this, intrinsicSize);
+        
+        areaTreeHandler.getAreaTreeModel().startPageSequence(null);
+        if (log.isDebugEnabled()) {
+            log.debug("Starting layout");
+        }
+
+        curPage = makeNewPage(false, false);
+
+        fillPage(); //TODO Implement multi-page documents (using new image package)
+        
+        finishPage();
+    }
+
+    private void fillPage() {
+
+        Dimension imageSize = this.imageLayout.getViewportSize();
+        
+        Block blockArea = new Block();
+        blockArea.setIPD(imageSize.width);
+        LineArea lineArea = new LineArea();
+        
+        Image imageArea = new Image(getExternalDocument().getSrc());
+        TraitSetter.setProducerID(imageArea, fobj.getId());
+        transferForeignAttributes(imageArea);
+
+        Viewport vp = new Viewport(imageArea);
+        TraitSetter.setProducerID(vp, fobj.getId());
+        vp.setIPD(imageSize.width);
+        vp.setBPD(imageSize.height);
+        vp.setContentPosition(imageLayout.getPlacement());
+        vp.setOffset(0);
+        
+        //Link them all together...
+        lineArea.addInlineArea(vp);
+        lineArea.updateExtentsFromChildren();
+        blockArea.addLineArea(lineArea);
+        curPage.getPageViewport().getCurrentFlow().addBlock(blockArea);
+        curPage.getPageViewport().getCurrentSpan().notifyFlowsFinished();
+    }
+        
+    /** {@inheritDoc} */
+    public void finishPageSequence() {
+        if (pageSeq.hasId()) {
+            idTracker.signalIDProcessed(pageSeq.getId());
+        }
+
+        pageSeq.getRoot().notifyPageSequenceFinished(currentPageNum,
+                (currentPageNum - startPageNum) + 1);
+        areaTreeHandler.notifyPageSequenceFinished(pageSeq,
+                (currentPageNum - startPageNum) + 1);
+        
+        if (log.isDebugEnabled()) {
+            log.debug("Ending layout");
+        }
+    }
+
+    protected Page createPage(int pageNumber, boolean isBlank) {
+        String pageNumberString = pageSeq.makeFormattedPageNumber(pageNumber);
+        
+        Dimension imageSize = this.imageLayout.getViewportSize();
+        
+        // Set up the CTM on the page reference area based on writing-mode
+        // and reference-orientation
+        Rectangle referenceRect;
+        if (pageSeq.getReferenceOrientation() % 180 == 0) {
+            referenceRect = new Rectangle(0, 0, imageSize.width, imageSize.height);
+        } else {
+            referenceRect = new Rectangle(0, 0, imageSize.height, imageSize.width);
+        }
+        FODimension reldims = new FODimension(0, 0);
+        CTM pageCTM = CTM.getCTMandRelDims(pageSeq.getReferenceOrientation(),
+            Constants.EN_LR_TB, referenceRect, reldims);
+        
+        Page page = new Page(referenceRect, pageNumber, pageNumberString, isBlank);
+        
+        PageViewport pv = page.getPageViewport(); 
+        org.apache.fop.area.Page pageArea = new org.apache.fop.area.Page();
+        pv.setPage(pageArea);
+
+        RegionViewport rv = new RegionViewport(referenceRect);
+        rv.setIPD(referenceRect.width);
+        rv.setBPD(referenceRect.height);
+        rv.setClip(true);
+        
+        BodyRegion body = new BodyRegion(Constants.FO_REGION_BODY, 
+                "fop-image-region", rv, 1, 0);
+        body.setIPD(imageSize.width);
+        body.setBPD(imageSize.height);
+        body.setCTM(pageCTM);
+        rv.setRegionReference(body);
+        pageArea.setRegionViewport(
+                Constants.FO_REGION_BODY, rv);
+        //Set unique key obtained from the AreaTreeHandler
+        pv.setKey(areaTreeHandler.generatePageViewportKey());
+
+        //Also creates first normal flow region
+        pv.createSpan(false);
+        
+        return page;
+    }
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMaker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMaker.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMaker.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMaker.java Thu Dec 27 02:34:15 2007
@@ -20,6 +20,7 @@
 
 import java.util.List;
 import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.extensions.ExternalDocument;
 import org.apache.fop.fo.pagination.Flow;
 import org.apache.fop.fo.pagination.PageSequence;
 import org.apache.fop.fo.pagination.SideRegion;
@@ -60,6 +61,15 @@
      */
     public PageSequenceLayoutManager makePageSequenceLayoutManager(
         AreaTreeHandler ath, PageSequence ps);
+
+    /**
+     * Make a ExternalDocumentLayoutManager object for the fox:external-document extension.
+     * @param ath the AreaTreeHandler object the external-document interacts with
+     * @param ed the fox:external-document object to be processed
+     * @return The created ExternalDocumentLayoutManager object
+     */
+    public ExternalDocumentLayoutManager makeExternalDocumentLayoutManager(
+        AreaTreeHandler ath, ExternalDocument ed);
 
     /**
      * Make a FlowLayoutManager object.

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java Thu Dec 27 02:34:15 2007
@@ -32,6 +32,7 @@
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FOText;
 import org.apache.fop.fo.FObjMixed;
+import org.apache.fop.fo.extensions.ExternalDocument;
 import org.apache.fop.fo.flow.BasicLink;
 import org.apache.fop.fo.flow.BidiOverride;
 import org.apache.fop.fo.flow.Block;
@@ -403,6 +404,11 @@
                 makeLayoutManagers(child, lms);
             }
         }       
+    }
+
+    public ExternalDocumentLayoutManager makeExternalDocumentLayoutManager(
+        AreaTreeHandler ath, ExternalDocument ed) {
+        return new ExternalDocumentLayoutManager(ath, ed);
     }
 
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/Page.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/Page.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/Page.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/Page.java Thu Dec 27 02:34:15 2007
@@ -19,6 +19,8 @@
 
 package org.apache.fop.layoutmgr;
 
+import java.awt.geom.Rectangle2D;
+
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.fo.pagination.SimplePageMaster;
 
@@ -43,6 +45,18 @@
     public Page(SimplePageMaster spm, int pageNumber, String pageNumberStr, boolean blank) {
         this.spm = spm;
         this.pageViewport = new PageViewport(spm, pageNumber, pageNumberStr, blank);
+    }
+    
+    /**
+     * Auxiliary constructor used when there's no SimplePageMaster.
+     * @param viewArea the view area of the page
+     * @param pageNumber the page number (as an int)
+     * @param pageNumberStr the page number (as a String) 
+     * @param blank true if this is a blank page
+     */
+    public Page(Rectangle2D viewArea, int pageNumber, String pageNumberStr, boolean blank) {
+        this.spm = null;
+        this.pageViewport = new PageViewport(viewArea, pageNumber, pageNumberStr, null, blank);
     }
     
     /** @return the simple-page-master that created this page */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java?rev=607032&r1=607031&r2=607032&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java Thu Dec 27 02:34:15 2007
@@ -252,7 +252,7 @@
         try {
             String pageNumberString = pageSeq.makeFormattedPageNumber(index);
             SimplePageMaster spm = pageSeq.getNextSimplePageMaster(
-                    index, (startPageOfPageSequence == index), isLastPage, isBlank);
+                    index, (startPageOfPageSequence == index), isLastPage, false, isBlank);
                 
             Region body = spm.getRegion(FO_REGION_BODY);
             if (!pageSeq.getMainFlow().getFlowName().equals(body.getRegionName())) {



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org