Pārlūkot izejas kodu

Bugzilla 42089: Cleanup and restructuring (suggested by Adrian Cumiskey)

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@554094 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_94
Andreas L. Delmelle pirms 17 gadiem
vecāks
revīzija
9263449d44
42 mainītis faili ar 1305 papildinājumiem un 1283 dzēšanām
  1. 118
    181
      src/java/org/apache/fop/area/AreaTreeHandler.java
  2. 203
    0
      src/java/org/apache/fop/area/IDTracker.java
  3. 11
    10
      src/java/org/apache/fop/area/RenderPagesModel.java
  4. 26
    2
      src/java/org/apache/fop/fo/FObj.java
  5. 1
    15
      src/java/org/apache/fop/fo/flow/AbstractListItemPart.java
  6. 14
    0
      src/java/org/apache/fop/fo/flow/BasicLink.java
  7. 4
    30
      src/java/org/apache/fop/fo/flow/Block.java
  8. 2
    10
      src/java/org/apache/fop/fo/flow/BlockContainer.java
  9. 2
    10
      src/java/org/apache/fop/fo/flow/Character.java
  10. 1
    1
      src/java/org/apache/fop/fo/flow/ExternalGraphic.java
  11. 1
    8
      src/java/org/apache/fop/fo/flow/InitialPropertySet.java
  12. 3
    12
      src/java/org/apache/fop/fo/flow/Inline.java
  13. 1
    16
      src/java/org/apache/fop/fo/flow/InlineContainer.java
  14. 1
    0
      src/java/org/apache/fop/fo/flow/InlineLevel.java
  15. 0
    7
      src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
  16. 0
    17
      src/java/org/apache/fop/fo/flow/Leader.java
  17. 2
    8
      src/java/org/apache/fop/fo/flow/ListBlock.java
  18. 2
    10
      src/java/org/apache/fop/fo/flow/ListItem.java
  19. 1
    8
      src/java/org/apache/fop/fo/flow/MultiCase.java
  20. 0
    23
      src/java/org/apache/fop/fo/flow/MultiProperties.java
  21. 1
    14
      src/java/org/apache/fop/fo/flow/MultiPropertySet.java
  22. 1
    13
      src/java/org/apache/fop/fo/flow/MultiSwitch.java
  23. 2
    8
      src/java/org/apache/fop/fo/flow/PageNumber.java
  24. 2
    8
      src/java/org/apache/fop/fo/flow/PageNumberCitation.java
  25. 2
    9
      src/java/org/apache/fop/fo/flow/Table.java
  26. 0
    20
      src/java/org/apache/fop/fo/flow/TableAndCaption.java
  27. 1
    14
      src/java/org/apache/fop/fo/flow/TableCaption.java
  28. 3
    13
      src/java/org/apache/fop/fo/flow/TableCell.java
  29. 1
    0
      src/java/org/apache/fop/fo/flow/TableFObj.java
  30. 1
    10
      src/java/org/apache/fop/fo/flow/TableRow.java
  31. 0
    20
      src/java/org/apache/fop/fo/flow/Wrapper.java
  32. 2
    8
      src/java/org/apache/fop/fo/pagination/PageSequence.java
  33. 1
    14
      src/java/org/apache/fop/fo/pagination/PageSequenceWrapper.java
  34. 8
    10
      src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
  35. 1
    2
      src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java
  36. 542
    0
      src/java/org/apache/fop/layoutmgr/PageBreaker.java
  37. 2
    2
      src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
  38. 279
    0
      src/java/org/apache/fop/layoutmgr/PageProvider.java
  39. 49
    740
      src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
  40. 6
    9
      src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java
  41. 1
    1
      src/java/org/apache/fop/render/rtf/RTFHandler.java
  42. 7
    0
      status.xml

+ 118
- 181
src/java/org/apache/fop/area/AreaTreeHandler.java Parādīt failu

@@ -21,12 +21,7 @@ package org.apache.fop.area;

// Java
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;

// XML
@@ -65,34 +60,24 @@ import org.apache.fop.fo.extensions.destination.Destination;
* type of renderer.
*/
public class AreaTreeHandler extends FOEventHandler {
private static Log log = LogFactory.getLog(AreaTreeHandler.class);

/** debug statistics */
// Recorder of debug statistics
private Statistics statistics = null;

private static Log log = LogFactory.getLog(AreaTreeHandler.class);

// the LayoutManager maker
// The LayoutManager maker
private LayoutManagerMaker lmMaker;

/** AreaTreeModel in use */
/** The AreaTreeModel in use */
protected AreaTreeModel model;

// Keeps track of all meaningful id references
private IDTracker idTracker;

// The fo:root node of the document
private Root rootFObj;

// HashMap of ID's whose area is located on one or more consecutive
// PageViewports. Each ID has an arraylist of PageViewports that
// form the defined area of this ID
private Map idLocations = new HashMap();

// idref's whose target PageViewports have yet to be identified
// Each idref has a HashSet of Resolvable objects containing that idref
private Map unresolvedIDRefs = new HashMap();

private Set unfinishedIDs = new HashSet();

private Set alreadyResolvedIDs = new HashSet();

// The formatting results to be handed back to the caller.
private FormattingResults results = new FormattingResults();

@@ -120,6 +105,8 @@ public class AreaTreeHandler extends FOEventHandler {
lmMaker = new LayoutManagerMapping();
}

idTracker = new IDTracker();
if (log.isDebugEnabled()) {
statistics = new Statistics();
}
@@ -159,137 +146,12 @@ public class AreaTreeHandler extends FOEventHandler {
}

/**
* Tie a PageViewport with an ID found on a child area of the PV. Note that
* an area with a given ID may be on more than one PV, hence an ID may have
* more than one PV associated with it.
* Get the IDTracker for this area tree.
*
* @param id the property ID of the area
* @param pv a page viewport that contains the area with this ID
* @return IDTracker used to track reference ids for items in this area tree
*/
public void associateIDWithPageViewport(String id, PageViewport pv) {
if (log.isDebugEnabled()) {
log.debug("associateIDWithPageViewport(" + id + ", " + pv + ")");
}
List pvList = (List) idLocations.get(id);
if (pvList == null) { // first time ID located
pvList = new ArrayList();
idLocations.put(id, pvList);
pvList.add(pv);
// signal the PageViewport that it is the first PV to contain this id:
pv.setFirstWithID(id);
/*
* See if this ID is in the unresolved idref list, if so resolve
* Resolvable objects tied to it.
*/
if (!unfinishedIDs.contains(id)) {
tryIDResolution(id, pv, pvList);
}
} else {
pvList.add(pv);
}
}

/**
* This method tie an ID to the areaTreeHandler until this one is ready to
* be processed. This is used in page-number-citation-last processing so we
* know when an id can be resolved.
*
* @param id the id of the object being processed
*/
public void signalPendingID(String id) {
if (log.isDebugEnabled()) {
log.debug("signalPendingID(" + id + ")");
}
unfinishedIDs.add(id);
}

/**
* Signals that all areas for the formatting object with the given ID have
* been generated. This is used to determine when page-number-citation-last
* ref-ids can be resolved.
*
* @param id the id of the formatting object which was just finished
*/
public void signalIDProcessed(String id) {
if (log.isDebugEnabled()) {
log.debug("signalIDProcessed(" + id + ")");
}

alreadyResolvedIDs.add(id);
if (!unfinishedIDs.contains(id)) {
return;
}
unfinishedIDs.remove(id);

List pvList = (List) idLocations.get(id);
Set todo = (Set) unresolvedIDRefs.get(id);
if (todo != null) {
for (Iterator iter = todo.iterator(); iter.hasNext();) {
Resolvable res = (Resolvable) iter.next();
res.resolveIDRef(id, pvList);
}
unresolvedIDRefs.remove(id);
}
}

/**
* Check if an ID has already been resolved
*
* @param id the id to check
* @return true if the ID has been resolved
*/
public boolean alreadyResolvedID(String id) {
return (alreadyResolvedIDs.contains(id));
}

/**
* Tries to resolve all unresolved ID references on the given page.
*
* @param id ID to resolve
* @param pv page viewport whose ID refs to resolve
* @param List of PageViewports
*/
private void tryIDResolution(String id, PageViewport pv, List pvList) {
Set todo = (Set) unresolvedIDRefs.get(id);
if (todo != null) {
for (Iterator iter = todo.iterator(); iter.hasNext();) {
Resolvable res = (Resolvable) iter.next();
if (!unfinishedIDs.contains(id)) {
res.resolveIDRef(id, pvList);
} else {
return;
}
}
alreadyResolvedIDs.add(id);
unresolvedIDRefs.remove(id);
}
}

/**
* Tries to resolve all unresolved ID references on the given page.
*
* @param pv page viewport whose ID refs to resolve
*/
public void tryIDResolution(PageViewport pv) {
String[] ids = pv.getIDRefs();
if (ids != null) {
for (int i = 0; i < ids.length; i++) {
List pvList = (List) idLocations.get(ids[i]);
if (pvList != null) {
tryIDResolution(ids[i], pv, pvList);
}
}
}
}

/**
* Get the list of page viewports that have an area with a given id.
*
* @param id the id to lookup
* @return the list of PageViewports
*/
public List getPageViewportsContainingID(String id) {
return (List) idLocations.get(id);
public IDTracker getIDTracker() {
return idTracker;
}

/**
@@ -301,22 +163,6 @@ public class AreaTreeHandler extends FOEventHandler {
return this.results;
}

/**
* Add an Resolvable object with an unresolved idref
*
* @param idref the idref whose target id has not yet been located
* @param res the Resolvable object needing the idref to be resolved
*/
public void addUnresolvedIDRef(String idref, Resolvable res) {
Set todo = (Set) unresolvedIDRefs.get(idref);
if (todo == null) {
todo = new HashSet();
unresolvedIDRefs.put(idref, todo);
}
// add Resolvable object to this HashSet
todo.add(res);
}

/**
* Prepare AreaTreeHandler for document processing This is called from
* FOTreeBuilder.startDocument()
@@ -453,12 +299,13 @@ public class AreaTreeHandler extends FOEventHandler {
Resolvable res = (Resolvable) odi;
String[] ids = res.getIDRefs();
for (int count = 0; count < ids.length; count++) {
if (idLocations.containsKey(ids[count])) {
res.resolveIDRef(ids[count], (List) idLocations.get(ids[count]));
List pageVPList = idTracker.getPageViewportsContainingID(ids[count]);
if (pageVPList != null) {
res.resolveIDRef(ids[count], pageVPList);
} else {
log.warn(odi.getName() + ": Unresolved id reference \""
+ ids[count] + "\" found.");
addUnresolvedIDRef(ids[count], res);
idTracker.addUnresolvedIDRef(ids[count], res);
}
}
// check to see if ODI is now fully resolved, if so process it
@@ -481,9 +328,86 @@ public class AreaTreeHandler extends FOEventHandler {
}

/**
* Gather statistics when log is debug
* Tie a PageViewport with an ID found on a child area of the PV. Note that
* an area with a given ID may be on more than one PV, hence an ID may have
* more than one PV associated with it.
*
* @param id the property ID of the area
* @param pv a page viewport that contains the area with this ID
* @deprecated use getIdTracker().associateIDWithPageViewport(id, pv) instead
*/
public void associateIDWithPageViewport(String id, PageViewport pv) {
idTracker.associateIDWithPageViewport(id, pv);
}

/**
* This method tie an ID to the areaTreeHandler until this one is ready to
* be processed. This is used in page-number-citation-last processing so we
* know when an id can be resolved.
*
* @param id the id of the object being processed
* @deprecated use getIdTracker().signalPendingID(id) instead
*/
public void signalPendingID(String id) {
idTracker.signalPendingID(id);
}

/**
* Signals that all areas for the formatting object with the given ID have
* been generated. This is used to determine when page-number-citation-last
* ref-ids can be resolved.
*
* @param id the id of the formatting object which was just finished
* @deprecated use getIdTracker().signalIDProcessed(id) instead
*/
public void signalIDProcessed(String id) {
idTracker.signalIDProcessed(id);
}

/**
* Check if an ID has already been resolved
*
* @param id the id to check
* @return true if the ID has been resolved
* @deprecated use getIdTracker().alreadyResolvedID(id) instead
*/
public boolean alreadyResolvedID(String id) {
return idTracker.alreadyResolvedID(id);
}

/**
* Tries to resolve all unresolved ID references on the given page.
*
* @param pv page viewport whose ID refs to resolve
* @deprecated use getIdTracker().tryIDResolution(pv) instead
*/
public void tryIDResolution(PageViewport pv) {
idTracker.tryIDResolution(pv);
}

/**
* Get the list of page viewports that have an area with a given id.
*
* @param id the id to lookup
* @return the list of PageViewports
* @deprecated use getIdTracker().getPageViewportsContainingID(id) instead
*/
public List getPageViewportsContainingID(String id) {
return idTracker.getPageViewportsContainingID(id);
}

/**
* Add an Resolvable object with an unresolved idref
*
* @param idref the idref whose target id has not yet been located
* @param res the Resolvable object needing the idref to be resolved
* @deprecated use getIdTracker().addUnresolvedIDRef(idref, res) instead
*/
private final class Statistics {
public void addUnresolvedIDRef(String idref, Resolvable res) {
idTracker.addUnresolvedIDRef(idref, res);
}
private class Statistics {
// for statistics gathering
private Runtime runtime;

@@ -493,21 +417,34 @@ public class AreaTreeHandler extends FOEventHandler {
// time used in rendering (for statistics)
private long startTime;

private Statistics() {
runtime = Runtime.getRuntime();
/**
* Default constructor
* @param areaTreeHandler area tree handler
*/
protected Statistics() {
this.runtime = Runtime.getRuntime();
}

public void start() {
initialMemory = runtime.totalMemory() - runtime.freeMemory();
startTime = System.currentTimeMillis();
/**
* starts the area tree handler statistics gathering
*/
protected void start() {
this.initialMemory = runtime.totalMemory() - runtime.freeMemory();
this.startTime = System.currentTimeMillis();
}

public void end() {
/**
* ends the area tree handler statistics gathering
*/
protected void end() {
long memoryNow = runtime.totalMemory() - runtime.freeMemory();
log.debug("Current heap size: " + (memoryNow / 1024L) + "KB");
}

public void logResults() {
/**
* logs the results of the area tree handler statistics gathering
*/
protected void logResults() {
long memoryNow = runtime.totalMemory() - runtime.freeMemory();
long memoryUsed = (memoryNow - initialMemory) / 1024L;
long timeUsed = System.currentTimeMillis() - startTime;

+ 203
- 0
src/java/org/apache/fop/area/IDTracker.java Parādīt failu

@@ -0,0 +1,203 @@
/*
* 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.area;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Used by the AreaTreeHandler to keep track of ID reference usage
* on a PageViewport level.
*/
public class IDTracker {
private static Log log = LogFactory.getLog(IDTracker.class);

// HashMap of ID's whose area is located on one or more consecutive
// PageViewports. Each ID has an arraylist of PageViewports that
// form the defined area of this ID
private Map idLocations = new HashMap();

// idref's whose target PageViewports have yet to be identified
// Each idref has a HashSet of Resolvable objects containing that idref
private Map unresolvedIDRefs = new HashMap();

private Set unfinishedIDs = new HashSet();

private Set alreadyResolvedIDs = new HashSet();
/**
* Tie a PageViewport with an ID found on a child area of the PV. Note that
* an area with a given ID may be on more than one PV, hence an ID may have
* more than one PV associated with it.
*
* @param id the property ID of the area
* @param pv a page viewport that contains the area with this ID
*/
public void associateIDWithPageViewport(String id, PageViewport pv) {
if (log.isDebugEnabled()) {
log.debug("associateIDWithPageViewport(" + id + ", " + pv + ")");
}
List pvList = (List) idLocations.get(id);
if (pvList == null) { // first time ID located
pvList = new ArrayList();
idLocations.put(id, pvList);
pvList.add(pv);
// signal the PageViewport that it is the first PV to contain this id:
pv.setFirstWithID(id);
/*
* See if this ID is in the unresolved idref list, if so resolve
* Resolvable objects tied to it.
*/
if (!unfinishedIDs.contains(id)) {
tryIDResolution(id, pv, pvList);
}
} else {
pvList.add(pv);
}
}

/**
* This method tie an ID to the areaTreeHandler until this one is ready to
* be processed. This is used in page-number-citation-last processing so we
* know when an id can be resolved.
*
* @param id the id of the object being processed
*/
public void signalPendingID(String id) {
if (log.isDebugEnabled()) {
log.debug("signalPendingID(" + id + ")");
}
unfinishedIDs.add(id);
}

/**
* Signals that all areas for the formatting object with the given ID have
* been generated. This is used to determine when page-number-citation-last
* ref-ids can be resolved.
*
* @param id the id of the formatting object which was just finished
*/
public void signalIDProcessed(String id) {
if (log.isDebugEnabled()) {
log.debug("signalIDProcessed(" + id + ")");
}

alreadyResolvedIDs.add(id);
if (!unfinishedIDs.contains(id)) {
return;
}
unfinishedIDs.remove(id);

List pvList = (List) idLocations.get(id);
Set todo = (Set) unresolvedIDRefs.get(id);
if (todo != null) {
for (Iterator iter = todo.iterator(); iter.hasNext();) {
Resolvable res = (Resolvable) iter.next();
res.resolveIDRef(id, pvList);
}
unresolvedIDRefs.remove(id);
}
}
/**
* Check if an ID has already been resolved
*
* @param id the id to check
* @return true if the ID has been resolved
*/
public boolean alreadyResolvedID(String id) {
return (alreadyResolvedIDs.contains(id));
}
/**
* Tries to resolve all unresolved ID references on the given page.
*
* @param id ID to resolve
* @param pv page viewport whose ID refs to resolve
* @param List of PageViewports
*/
private void tryIDResolution(String id, PageViewport pv, List pvList) {
Set todo = (Set) unresolvedIDRefs.get(id);
if (todo != null) {
for (Iterator iter = todo.iterator(); iter.hasNext();) {
Resolvable res = (Resolvable) iter.next();
if (!unfinishedIDs.contains(id)) {
res.resolveIDRef(id, pvList);
} else {
return;
}
}
alreadyResolvedIDs.add(id);
unresolvedIDRefs.remove(id);
}
}

/**
* Tries to resolve all unresolved ID references on the given page.
*
* @param pv page viewport whose ID refs to resolve
*/
public void tryIDResolution(PageViewport pv) {
String[] ids = pv.getIDRefs();
if (ids != null) {
for (int i = 0; i < ids.length; i++) {
List pvList = (List) idLocations.get(ids[i]);
if (pvList != null) {
tryIDResolution(ids[i], pv, pvList);
}
}
}
}
/**
* Get the list of page viewports that have an area with a given id.
*
* @param id the id to lookup
* @return the list of PageViewports
*/
public List getPageViewportsContainingID(String id) {
return (List) idLocations.get(id);
}
/**
* Add an Resolvable object with an unresolved idref
*
* @param idref the idref whose target id has not yet been located
* @param res the Resolvable object needing the idref to be resolved
*/
public void addUnresolvedIDRef(String idref, Resolvable res) {
Set todo = (Set) unresolvedIDRefs.get(idref);
if (todo == null) {
todo = new HashSet();
unresolvedIDRefs.put(idref, todo);
}
// add Resolvable object to this HashSet
todo.add(res);
}
}

+ 11
- 10
src/java/org/apache/fop/area/RenderPagesModel.java Parādīt failu

@@ -145,27 +145,28 @@ public class RenderPagesModel extends AreaTreeModel {
/**
* Check prepared pages
*
* @param newpage the new page being added
* @param newPageViewport the new page being added
* @param renderUnresolved render pages with unresolved idref's
* (done at end-of-document processing)
* @return true if the current page should be rendered
* false if the renderer doesn't support out of order
* rendering and there are pending pages
*/
protected boolean checkPreparedPages(PageViewport newpage, boolean
protected boolean checkPreparedPages(PageViewport newPageViewport, boolean
renderUnresolved) {
for (Iterator iter = prepared.iterator(); iter.hasNext();) {
PageViewport p = (PageViewport)iter.next();
if (p.isResolved() || renderUnresolved) {
if (!renderer.supportsOutOfOrder() && p.getPageSequence().isFirstPage(p)) {
PageViewport pageViewport = (PageViewport)iter.next();
if (pageViewport.isResolved() || renderUnresolved) {
if (!renderer.supportsOutOfOrder()
&& pageViewport.getPageSequence().isFirstPage(pageViewport)) {
renderer.startPageSequence(this.currentPageSequence.getTitle());
}
try {
renderer.renderPage(p);
if (!p.isResolved()) {
String[] idrefs = p.getIDRefs();
renderer.renderPage(pageViewport);
if (!pageViewport.isResolved()) {
String[] idrefs = pageViewport.getIDRefs();
for (int count = 0; count < idrefs.length; count++) {
log.warn("Page " + p.getPageNumberString()
log.warn("Page " + pageViewport.getPageNumberString()
+ ": Unresolved id reference \"" + idrefs[count]
+ "\" found.");
}
@@ -174,7 +175,7 @@ public class RenderPagesModel extends AreaTreeModel {
// use error handler to handle this FOP or IO Exception
log.error(e);
}
p.clear();
pageViewport.clear();
iter.remove();
} else {
// if keeping order then stop at first page not resolved

+ 26
- 2
src/java/org/apache/fop/fo/FObj.java Parādīt failu

@@ -60,6 +60,10 @@ public abstract class FObj extends FONode implements Constants {
/** Markers added to this element. */
private Map markers = null;
// The value of properties relevant for all fo objects
private String id = null;
// End of property values

/**
* Create a new formatting object.
* All formatting object classes extend this class.
@@ -136,6 +140,17 @@ public abstract class FObj extends FONode implements Constants {
* @throws FOPException if there is a problem binding the values
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
* @throws FOPException FOP Exception
*/
protected void startOfNode() throws FOPException {
if (id != null) {
checkId(id);
}
}

/**
@@ -147,7 +162,7 @@ public abstract class FObj extends FONode implements Constants {
* @throws ValidationException if the ID is already defined elsewhere
* (strict validation only)
*/
protected void checkId(String id) throws ValidationException {
private void checkId(String id) throws ValidationException {
if (!inMarker() && !id.equals("")) {
Set idrefs = getFOEventHandler().getIDReferences();
if (!idrefs.contains(id)) {
@@ -190,7 +205,7 @@ public abstract class FObj extends FONode implements Constants {
protected void addChildNode(FONode child) throws FOPException {
if (canHaveMarkers() && child.getNameId() == FO_MARKER) {
addMarker((Marker) child);
} else {
} else {
ExtensionAttachment attachment = child.getExtensionAttachment();
if (attachment != null) {
/* This removes the element from the normal children,
@@ -469,7 +484,16 @@ public abstract class FObj extends FONode implements Constants {
return -1;
}
/** @return the "id" property. */
public String getId() {
return id;
}
/** @return whether this object has an id set */
public boolean hasId() {
return id != null && id.length() > 0;
}

/** @see org.apache.fop.fo.FONode#getNamespaceURI() */
public String getNamespaceURI() {
return FOElementMapping.URI;

+ 1
- 15
src/java/org/apache/fop/fo/flow/AbstractListItemPart.java Parādīt failu

@@ -34,7 +34,6 @@ import org.apache.fop.fo.properties.KeepProperty;
*/
public abstract class AbstractListItemPart extends FObj {
// The value of properties relevant for fo:list-item-label and fo:list-item-body.
private String id;
private KeepProperty keepTogether;
// Valid properties, commented out for performance:
// private CommonAccessibility commonAccessibility;
@@ -54,17 +53,10 @@ public abstract class AbstractListItemPart extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
super.bind(pList);
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
* XSL Content Model: marker* (%block;)+
@@ -106,11 +98,5 @@ public abstract class AbstractListItemPart extends FObj {
public KeepProperty getKeepTogether() {
return keepTogether;
}

/** @return the "id" property. */
public String getId() {
return id;
}
}


+ 14
- 0
src/java/org/apache/fop/fo/flow/BasicLink.java Parādīt failu

@@ -128,6 +128,20 @@ public class BasicLink extends Inline {
return externalDestination;
}

/**
* @return whether or not this basic link has an internal destination or not
*/
public boolean hasInternalDestination() {
return internalDestination != null && internalDestination.length() > 0;
}

/**
* @return whether or not this basic link has an external destination or not
*/
public boolean hasExternalDestination() {
return externalDestination != null && externalDestination.length() > 0;
}

/** @see org.apache.fop.fo.FObj#getLocalName() */
public String getLocalName() {
return "basic-link";

+ 4
- 30
src/java/org/apache/fop/fo/flow/Block.java Parādīt failu

@@ -32,8 +32,6 @@ import org.apache.fop.fo.FObjMixed;
import org.apache.fop.fo.NullCharIterator;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.properties.CommonAccessibility;
import org.apache.fop.fo.properties.CommonAural;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.CommonFont;
import org.apache.fop.fo.properties.CommonHyphenation;
@@ -52,8 +50,6 @@ public class Block extends FObjMixed {
private boolean initialPropertySetFound = false;

// The value of properties relevant for fo:block.
private CommonAccessibility commonAccessibility;
private CommonAural commonAural;
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private CommonFont commonFont;
private CommonHyphenation commonHyphenation;
@@ -64,7 +60,6 @@ public class Block extends FObjMixed {
private Color color;
private int hyphenationKeep;
private Numeric hyphenationLadderCount;
private String id;
private int intrusionDisplace;
private KeepProperty keepTogether;
private KeepProperty keepWithNext;
@@ -84,6 +79,8 @@ public class Block extends FObjMixed {
private Numeric widows;
private int wrapOption;
// Unused but valid items, commented out for performance:
// private CommonAccessibility commonAccessibility;
// private CommonAural commonAural;
// private Length textDepth;
// private Length textAltitude;
// private int visibility;
@@ -101,8 +98,7 @@ public class Block extends FObjMixed {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
commonAccessibility = pList.getAccessibilityProps();
commonAural = pList.getAuralProps();
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonFont = pList.getFontProps();
commonHyphenation = pList.getHyphenationProps();
@@ -114,7 +110,6 @@ public class Block extends FObjMixed {
color = pList.get(PR_COLOR).getColor(getUserAgent());
hyphenationKeep = pList.get(PR_HYPHENATION_KEEP).getEnum();
hyphenationLadderCount = pList.get(PR_HYPHENATION_LADDER_COUNT).getNumeric();
id = pList.get(PR_ID).getString();
intrusionDisplace = pList.get(PR_INTRUSION_DISPLACE).getEnum();
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
@@ -139,7 +134,7 @@ public class Block extends FObjMixed {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().startBlock(this);
}

@@ -231,13 +226,6 @@ public class Block extends FObjMixed {
return color;
}

/**
* @return the "id" property.
*/
public String getId() {
return id;
}

/**
* @return the "line-height" property.
*/
@@ -347,20 +335,6 @@ public class Block extends FObjMixed {
return whiteSpaceCollapse;
}
/**
* @return Returns the commonAccessibility.
*/
public CommonAccessibility getCommonAccessibility() {
return this.commonAccessibility;
}

/**
* @return Returns the commonAural.
*/
public CommonAural getCommonAural() {
return this.commonAural;
}

/**
* @return Returns the commonRelativePosition.
*/

+ 2
- 10
src/java/org/apache/fop/fo/flow/BlockContainer.java Parādīt failu

@@ -48,7 +48,6 @@ public class BlockContainer extends FObj {
// private ToBeImplementedProperty clip;
private int displayAlign;
private Length height;
private String id;
private LengthRangeProperty inlineProgressionDimension;
private KeepProperty keepTogether;
private KeepProperty keepWithNext;
@@ -77,6 +76,7 @@ public class BlockContainer extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonAbsolutePosition = pList.getAbsolutePositionProps();
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonMarginBlock = pList.getMarginBlockProps();
@@ -86,7 +86,6 @@ public class BlockContainer extends FObj {
// clip = pList.get(PR_CLIP);
displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum();
height = pList.get(PR_HEIGHT).getLength();
id = pList.get(PR_ID).getString();
inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
@@ -102,7 +101,7 @@ public class BlockContainer extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().startBlockContainer(this);
}

@@ -203,13 +202,6 @@ public class BlockContainer extends FObj {
return keepTogether;
}

/**
* @return the "id" property.
*/
public String getId() {
return id;
}

/**
* @return the "inline-progression-dimension" property.
*/

+ 2
- 10
src/java/org/apache/fop/fo/flow/Character.java Parādīt failu

@@ -68,7 +68,6 @@ public class Character extends FObj {
private int dominantBaseline;
// private ToBeImplementedProperty glyphOrientationHorizontal;
// private ToBeImplementedProperty glyphOrientationVertical;
private String id;
private Property letterSpacing;
private SpaceProperty lineHeight;
/** Holds the text decoration values. May be null */
@@ -106,6 +105,7 @@ public class Character extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonFont = pList.getFontProps();
commonHyphenation = pList.getHyphenationProps();
@@ -118,7 +118,6 @@ public class Character extends FObj {
dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
// glyphOrientationHorizontal = pList.get(PR_GLYPH_ORIENTATION_HORIZONTAL);
// glyphOrientationVertical = pList.get(PR_GLYPH_ORIENTATION_VERTICAL);
id = pList.get(PR_ID).getString();
letterSpacing = pList.get(PR_LETTER_SPACING);
lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
textDecoration = pList.getTextDecorationProps();
@@ -130,7 +129,7 @@ public class Character extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().character(this);
}

@@ -213,13 +212,6 @@ public class Character extends FObj {
return dominantBaseline;
}
/**
* @return the "id" property.
*/
public String getId() {
return id;
}

/**
* @return the "letter-spacing" property.
*/

+ 1
- 1
src/java/org/apache/fop/fo/flow/ExternalGraphic.java Parādīt failu

@@ -83,7 +83,7 @@ public class ExternalGraphic extends AbstractGraphics {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(getId());
super.startOfNode();
getFOEventHandler().image(this);
}


+ 1
- 8
src/java/org/apache/fop/fo/flow/InitialPropertySet.java Parādīt failu

@@ -69,19 +69,12 @@ public class InitialPropertySet extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
super.bind(pList);
// letterSpacing = pList.get(PR_LETTER_SPACING);
lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
// textShadow = pList.get(PR_TEXT_SHADOW);
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
* XSL Content Model: empty

+ 3
- 12
src/java/org/apache/fop/fo/flow/Inline.java Parādīt failu

@@ -42,7 +42,6 @@ public class Inline extends InlineLevel {
private int alignmentBaseline;
private Length baselineShift;
private int dominantBaseline;
private String id;
// Unused but valid items, commented out for performance:
// private CommonRelativePosition commonRelativePosition;
// private LengthRangeProperty blockProgressionDimension;
@@ -74,13 +73,14 @@ public class Inline extends InlineLevel {
alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum();
baselineShift = pList.get(PR_BASELINE_SHIFT).getLength();
dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
id = pList.get(PR_ID).getString();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
super.startOfNode();
/* Check to see if this node can have block-level children.
* See validateChildNode() below.
*/
@@ -99,9 +99,7 @@ public class Inline extends InlineLevel {
}
}

checkId(id);
getFOEventHandler().startInline(this);
getFOEventHandler().startInline(this);
}

/**
@@ -140,13 +138,6 @@ public class Inline extends InlineLevel {
}
}

/**
* Return the "id" property.
*/
public String getId() {
return id;
}

/**
* @return the "alignment-adjust" property
*/

+ 1
- 16
src/java/org/apache/fop/fo/flow/InlineContainer.java Parādīt failu

@@ -46,7 +46,6 @@ public class InlineContainer extends FObj {
private Length baselineShift;
// private ToBeImplementedProperty clip;
private int dominantBaseline;
private String id;
private SpaceProperty lineHeight;
// Unused but valid items, commented out for performance:
// private CommonBorderPaddingBackground commonBorderPaddingBackground;
@@ -79,22 +78,15 @@ public class InlineContainer extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength();
alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum();
baselineShift = pList.get(PR_BASELINE_SHIFT).getLength();
// clip = pList.get(PR_CLIP);
dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
id = pList.get(PR_ID).getString();
lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
* XSL Content Model: marker* (%block;)+
@@ -156,13 +148,6 @@ public class InlineContainer extends FObj {
return lineHeight;
}

/**
* @return the "id" property.
*/
public String getId() {
return id;
}

/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {
return "inline-container";

+ 1
- 0
src/java/org/apache/fop/fo/flow/InlineLevel.java Parādīt failu

@@ -60,6 +60,7 @@ public abstract class InlineLevel extends FObjMixed {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonAccessibility = pList.getAccessibilityProps();
commonMarginInline = pList.getMarginInlineProps();

+ 0
- 7
src/java/org/apache/fop/fo/flow/InstreamForeignObject.java Parādīt failu

@@ -49,13 +49,6 @@ public class InstreamForeignObject extends AbstractGraphics {
super(parent);
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(getId());
}

/**
* Make sure content model satisfied, if so then tell the
* FOEventHandler that we are at the end of the flow.

+ 0
- 17
src/java/org/apache/fop/fo/flow/Leader.java Parādīt failu

@@ -41,7 +41,6 @@ public class Leader extends InlineLevel {
private int alignmentBaseline;
private Length baselineShift;
private int dominantBaseline;
private String id;
private int leaderAlignment;
private LengthRangeProperty leaderLength;
private int leaderPattern;
@@ -75,7 +74,6 @@ public class Leader extends InlineLevel {
alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum();
baselineShift = pList.get(PR_BASELINE_SHIFT).getLength();
dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
id = pList.get(PR_ID).getString();
leaderAlignment = pList.get(PR_LEADER_ALIGNMENT).getEnum();
leaderLength = pList.get(PR_LEADER_LENGTH).getLengthRange();
leaderPattern = pList.get(PR_LEADER_PATTERN).getEnum();
@@ -103,21 +101,6 @@ public class Leader extends InlineLevel {
// textShadow = pList.get(PR_TEXT_SHADOW);
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}


/**
* @return the "id" property.
*/
public String getId() {
return id;
}

/**
* @return the "rule-style" property.
*/

+ 2
- 8
src/java/org/apache/fop/fo/flow/ListBlock.java Parādīt failu

@@ -43,7 +43,6 @@ public class ListBlock extends FObj {
private CommonMarginBlock commonMarginBlock;
private int breakAfter;
private int breakBefore;
private String id;
private KeepProperty keepTogether;
private KeepProperty keepWithNext;
private KeepProperty keepWithPrevious;
@@ -74,11 +73,11 @@ public class ListBlock extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonMarginBlock = pList.getMarginBlockProps();
breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
id = pList.get(PR_ID).getString();
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
@@ -91,7 +90,7 @@ public class ListBlock extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().startList(this);
}
@@ -177,11 +176,6 @@ public class ListBlock extends FObj {
return orphanContentLimit;
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {
return "list-block";

+ 2
- 10
src/java/org/apache/fop/fo/flow/ListItem.java Parādīt failu

@@ -42,7 +42,6 @@ public class ListItem extends FObj {
private CommonMarginBlock commonMarginBlock;
private int breakAfter;
private int breakBefore;
private String id;
private KeepProperty keepTogether;
private KeepProperty keepWithNext;
private KeepProperty keepWithPrevious;
@@ -68,11 +67,11 @@ public class ListItem extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonMarginBlock = pList.getMarginBlockProps();
breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
id = pList.get(PR_ID).getString();
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
@@ -82,7 +81,7 @@ public class ListItem extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().startListItem(this);
}

@@ -183,13 +182,6 @@ public class ListItem extends FObj {
return keepTogether;
}

/**
* @return the "id" property.
*/
public String getId() {
return id;
}

/**
* @return the label of the list item
*/

+ 1
- 8
src/java/org/apache/fop/fo/flow/MultiCase.java Parādīt failu

@@ -57,19 +57,12 @@ public class MultiCase extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
super.bind(pList);
startingState = pList.get(PR_STARTING_STATE).getEnum();
// caseName = pList.get(PR_CASE_NAME);
// caseTitle = pList.get(PR_CASE_TITLE);
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* Return the "starting-state" property.
*/

+ 0
- 23
src/java/org/apache/fop/fo/flow/MultiProperties.java Parādīt failu

@@ -25,7 +25,6 @@ import org.xml.sax.Locator;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.properties.CommonAccessibility;

@@ -34,7 +33,6 @@ import org.apache.fop.fo.properties.CommonAccessibility;
*/
public class MultiProperties extends FObj {
// The value of properties relevant for fo:multi-properties.
private String id;
// Unused but valid items, commented out for performance:
// private CommonAccessibility commonAccessibility;
// End of property values
@@ -57,20 +55,6 @@ public class MultiProperties extends FObj {
}
}

/**
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* Make sure content model satisfied, if so then tell the
* FOEventHandler that we are at the end of the flow.
@@ -104,13 +88,6 @@ public class MultiProperties extends FObj {
invalidChildError(loc, nsURI, localName);
}
}

/**
* Return the "id" property.
*/
public String getId() {
return id;
}
/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {

+ 1
- 14
src/java/org/apache/fop/fo/flow/MultiPropertySet.java Parādīt failu

@@ -33,7 +33,6 @@ import org.apache.fop.fo.ValidationException;
*/
public class MultiPropertySet extends FObj {
// The value of properties relevant for fo:multi-property-set.
private String id;
// private ToBeImplementedProperty activeState;
// End of property values

@@ -55,17 +54,10 @@ public class MultiPropertySet extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
super.bind(pList);
// activeState = pList.get(PR_ACTIVE_STATE);
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
* XSL Content Model: empty
@@ -75,11 +67,6 @@ public class MultiPropertySet extends FObj {
invalidChildError(loc, nsURI, localName);
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {
return "multi-property-set";

+ 1
- 13
src/java/org/apache/fop/fo/flow/MultiSwitch.java Parādīt failu

@@ -36,7 +36,6 @@ import org.apache.fop.fo.properties.CommonAccessibility;
public class MultiSwitch extends FObj {
// The value of properties relevant for fo:multi-switch.
// private ToBeImplementedProperty autoRestore;
private String id;
// Unused but valid items, commented out for performance:
// private CommonAccessibility commonAccessibility;
// End of property values
@@ -59,16 +58,10 @@ public class MultiSwitch extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
// autoRestore = pList.get(PR_AUTO_RESTORE);
id = pList.get(PR_ID).getString();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* Make sure content model satisfied.
@@ -91,11 +84,6 @@ public class MultiSwitch extends FObj {
}
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {
return "multi-switch";

+ 2
- 8
src/java/org/apache/fop/fo/flow/PageNumber.java Parādīt failu

@@ -51,7 +51,6 @@ public class PageNumber extends FObj {
private int alignmentBaseline;
private Length baselineShift;
private int dominantBaseline;
private String id;
// private ToBeImplementedProperty letterSpacing;
private SpaceProperty lineHeight;
/** Holds the text decoration values. May be null */
@@ -87,13 +86,13 @@ public class PageNumber extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonFont = pList.getFontProps();
alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength();
alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum();
baselineShift = pList.get(PR_BASELINE_SHIFT).getLength();
dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
id = pList.get(PR_ID).getString();
// letterSpacing = pList.get(PR_LETTER_SPACING);
lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
textDecoration = pList.getTextDecorationProps();
@@ -107,7 +106,7 @@ public class PageNumber extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().startPageNumber(this);
}

@@ -142,11 +141,6 @@ public class PageNumber extends FObj {
return commonBorderPaddingBackground;
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @return the "text-decoration" property. */
public CommonTextDecoration getTextDecoration() {
return textDecoration;

+ 2
- 8
src/java/org/apache/fop/fo/flow/PageNumberCitation.java Parādīt failu

@@ -54,7 +54,6 @@ public class PageNumberCitation extends FObj {
private int alignmentBaseline;
private Length baselineShift;
private int dominantBaseline;
private String id;
// private ToBeImplementedProperty letterSpacing;
private SpaceProperty lineHeight;
private String refId;
@@ -91,13 +90,13 @@ public class PageNumberCitation extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonFont = pList.getFontProps();
alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength();
alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum();
baselineShift = pList.get(PR_BASELINE_SHIFT).getLength();
dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
id = pList.get(PR_ID).getString();
// letterSpacing = pList.get(PR_LETTER_SPACING);
lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
refId = pList.get(PR_REF_ID).getString();
@@ -112,7 +111,7 @@ public class PageNumberCitation extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
if (refId.equals("")) {
missingPropertyError("ref-id");
}
@@ -182,11 +181,6 @@ public class PageNumberCitation extends FObj {
return lineHeight;
}
/** @return the "id" property. */
public String getId() {
return id;
}

/** @return the "ref-id" property. */
public String getRefId() {
return refId;

+ 2
- 9
src/java/org/apache/fop/fo/flow/Table.java Parādīt failu

@@ -54,7 +54,6 @@ public class Table extends TableFObj {
private LengthPairProperty borderSeparation;
private int breakAfter;
private int breakBefore;
private String id;
private LengthRangeProperty inlineProgressionDimension;
private KeepProperty keepTogether;
private KeepProperty keepWithNext;
@@ -110,6 +109,7 @@ public class Table extends TableFObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonMarginBlock = pList.getMarginBlockProps();
blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
@@ -117,7 +117,6 @@ public class Table extends TableFObj {
borderSeparation = pList.get(PR_BORDER_SEPARATION).getLengthPair();
breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
id = pList.get(PR_ID).getString();
inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
@@ -125,7 +124,6 @@ public class Table extends TableFObj {
tableLayout = pList.get(PR_TABLE_LAYOUT).getEnum();
tableOmitFooterAtBreak = pList.get(PR_TABLE_OMIT_FOOTER_AT_BREAK).getEnum();
tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum();
super.bind(pList);

//Bind extension properties
widowContentLimit = pList.get(PR_X_WIDOW_CONTENT_LIMIT).getLength();
@@ -161,7 +159,7 @@ public class Table extends TableFObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().startTable(this);
}
@@ -466,11 +464,6 @@ public class Table extends TableFObj {
return orphanContentLimit;
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {
return "table";

+ 0
- 20
src/java/org/apache/fop/fo/flow/TableAndCaption.java Parādīt failu

@@ -40,7 +40,6 @@ import org.apache.fop.fo.properties.KeepProperty;
*/
public class TableAndCaption extends FObj {
// The value of properties relevant for fo:table-and-caption.
private String id;
// Unused but valid items, commented out for performance:
// private CommonAccessibility commonAccessibility;
// private CommonAural commonAural;
@@ -75,20 +74,6 @@ public class TableAndCaption extends FObj {
}
}

/**
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* Make sure content model satisfied, if so then tell the
* FOEventHandler that we are at the end of the flow.
@@ -132,11 +117,6 @@ public class TableAndCaption extends FObj {
}
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {
return "table-and-caption";

+ 1
- 14
src/java/org/apache/fop/fo/flow/TableCaption.java Parādīt failu

@@ -44,7 +44,6 @@ public class TableCaption extends FObj {
// The value of properties relevant for fo:table-caption.
private CommonAccessibility commonAccessibility;
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private String id;
// Unused but valid items, commented out for performance:
// private CommonAural commonAural;
// private CommonRelativePosition commonRelativePosition;
@@ -77,16 +76,9 @@ public class TableCaption extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonAccessibility = pList.getAccessibilityProps();
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
id = pList.get(PR_ID).getString();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
@@ -124,11 +116,6 @@ public class TableCaption extends FObj {
}
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {
return "table-caption";

+ 3
- 13
src/java/org/apache/fop/fo/flow/TableCell.java Parādīt failu

@@ -46,7 +46,6 @@ public class TableCell extends TableFObj {
private int displayAlign;
private int emptyCells;
private int endsRow;
private String id;
private int numberColumnsSpanned;
private int numberRowsSpanned;
private int startsRow;
@@ -77,26 +76,24 @@ public class TableCell extends TableFObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum();
emptyCells = pList.get(PR_EMPTY_CELLS).getEnum();
endsRow = pList.get(PR_ENDS_ROW).getEnum();
id = pList.get(PR_ID).getString();
columnNumber = pList.get(PR_COLUMN_NUMBER).getNumeric().getValue();
numberColumnsSpanned = pList.get(PR_NUMBER_COLUMNS_SPANNED).getNumeric().getValue();
numberRowsSpanned = pList.get(PR_NUMBER_ROWS_SPANNED).getNumeric().getValue();
startsRow = pList.get(PR_STARTS_ROW).getEnum();
width = pList.get(PR_WIDTH).getLength();
super.bind(pList);
width = pList.get(PR_WIDTH).getLength();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().startCell(this);
}

@@ -163,13 +160,6 @@ public class TableCell extends TableFObj {
return (this.emptyCells == EN_SHOW);
}
/**
* @return the "id" property.
*/
public String getId() {
return id;
}

/**
* @return the "number-columns-spanned" property.
*/

+ 1
- 0
src/java/org/apache/fop/fo/flow/TableFObj.java Parādīt failu

@@ -83,6 +83,7 @@ public abstract class TableFObj extends FObj {
* @see FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();

+ 1
- 10
src/java/org/apache/fop/fo/flow/TableRow.java Parādīt failu

@@ -47,7 +47,6 @@ public class TableRow extends TableFObj {
private int breakAfter;
private int breakBefore;
private Length height;
private String id;
private KeepProperty keepTogether;
private KeepProperty keepWithNext;
private KeepProperty keepWithPrevious;
@@ -80,7 +79,6 @@ public class TableRow extends TableFObj {
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
id = pList.get(PR_ID).getString();
height = pList.get(PR_HEIGHT).getLength();
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
@@ -162,7 +160,7 @@ public class TableRow extends TableFObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
super.startOfNode();
getFOEventHandler().startRow(this);
}

@@ -192,13 +190,6 @@ public class TableRow extends TableFObj {
}
}
/**
* @return the "id" property.
*/
public String getId() {
return id;
}

/** @return the "break-after" property. */
public int getBreakAfter() {
return breakAfter;

+ 0
- 20
src/java/org/apache/fop/fo/flow/Wrapper.java Parādīt failu

@@ -34,7 +34,6 @@ import org.xml.sax.Locator;
*/
public class Wrapper extends FObjMixed {
// The value of properties relevant for fo:wrapper.
private String id;
// End of property values
// used for FO validation
@@ -47,20 +46,6 @@ public class Wrapper extends FObjMixed {
super(parent);
}

/**
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
* XSL Content Model: marker* (#PCDATA|%inline;|%block;)*
@@ -82,11 +67,6 @@ public class Wrapper extends FObjMixed {
}
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @see org.apache.fop.fo.FONode#getLocalName() */
public String getLocalName() {
return "wrapper";

+ 2
- 8
src/java/org/apache/fop/fo/pagination/PageSequence.java Parādīt failu

@@ -43,7 +43,6 @@ public class PageSequence extends FObj {
private int letterValue;
private char groupingSeparator;
private int groupingSize;
private String id;
private Numeric initialPageNumber;
private int forcePageCount;
private String masterReference;
@@ -96,13 +95,13 @@ public class PageSequence extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
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();
id = pList.get(PR_ID).getString();
initialPageNumber = pList.get(PR_INITIAL_PAGE_NUMBER).getNumeric();
forcePageCount = pList.get(PR_FORCE_PAGE_COUNT).getEnum();
masterReference = pList.get(PR_MASTER_REFERENCE).getString();
@@ -116,6 +115,7 @@ public class PageSequence extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode()
*/
protected void startOfNode() throws FOPException {
super.startOfNode();
this.root = (Root) parent;
flowMap = new java.util.HashMap();

@@ -133,7 +133,6 @@ public class PageSequence extends FObj {
this.pageNumberGenerator = new PageNumberGenerator(
format, groupingSeparator, groupingSize, letterValue);

checkId(id);
getFOEventHandler().startPageSequence(this);
}

@@ -394,11 +393,6 @@ public class PageSequence extends FObj {
return (StaticContent) flowMap.get(name);
}

/** @return the "id" property. */
public String getId() {
return id;
}

/**
* Accessor method for titleFO
* @return titleFO for this object

+ 1
- 14
src/java/org/apache/fop/fo/pagination/PageSequenceWrapper.java Parādīt failu

@@ -34,7 +34,6 @@ import org.apache.fop.fo.ValidationException;
*/
public class PageSequenceWrapper extends FObj {
// The value of properties relevant for this FO
private String id;
private String indexClass;
private String indexKey;
// End of property values
@@ -50,18 +49,11 @@ public class PageSequenceWrapper extends FObj {
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
id = pList.get(PR_ID).getString();
super.bind(pList);
indexClass = pList.get(PR_INDEX_CLASS).getString();
indexKey = pList.get(PR_INDEX_KEY).getString();
}

/**
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
checkId(id);
}

/**
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
XSL/FOP: (bookmark+)
@@ -74,11 +66,6 @@ public class PageSequenceWrapper extends FObj {
}
}

/** @return the "id" property. */
public String getId() {
return id;
}

/** @return the "index-class" property. */
public String getIndexClass() {
return indexClass;

+ 8
- 10
src/java/org/apache/fop/layoutmgr/AbstractBreaker.java Parādīt failu

@@ -192,7 +192,7 @@ public abstract class AbstractBreaker {
* algorithm.
* @return the applicable PageProvider, or null if not applicable
*/
protected PageSequenceLayoutManager.PageProvider getPageProvider() {
protected PageProvider getPageProvider() {
return null;
}
@@ -214,7 +214,7 @@ public abstract class AbstractBreaker {

/** @return true if there's no content that could be handled. */
public boolean isEmpty() {
return (blockLists.size() == 0);
return (this.blockLists.size() == 0);
}
protected void startPart(BlockSequence list, int breakClass) {
@@ -289,7 +289,7 @@ public abstract class AbstractBreaker {
childLC.setBPAlignment(alignment);

BlockSequence blockList;
blockLists = new java.util.ArrayList();
this.blockLists = new java.util.ArrayList();

log.debug("PLM> flow BPD =" + flowBPD);
@@ -298,7 +298,7 @@ public abstract class AbstractBreaker {
while (hasMoreContent()) {
blockLists.clear();

nextSequenceStartsOn = getNextBlockList(childLC, nextSequenceStartsOn, blockLists);
nextSequenceStartsOn = getNextBlockList(childLC, nextSequenceStartsOn);

//*** Phase 2: Alignment and breaking ***
log.debug("PLM> blockLists.size() = " + blockLists.size());
@@ -539,19 +539,17 @@ public abstract class AbstractBreaker {
* Gets the next block list (sequence) and adds it to a list of block lists if it's not empty.
* @param childLC LayoutContext to use
* @param nextSequenceStartsOn indicates on what page the next sequence should start
* @param blockLists list of block lists (sequences)
* @return the page on which the next content should appear after a hard break
*/
protected int getNextBlockList(LayoutContext childLC,
int nextSequenceStartsOn,
List blockLists) {
int nextSequenceStartsOn) {
updateLayoutContext(childLC);
//Make sure the span change signal is reset
childLC.signalSpanChange(Constants.NOT_SET);
LinkedList returnedList;
BlockSequence blockList;
if ((returnedList = getNextKnuthElements(childLC, alignment)) != null) {
LinkedList returnedList = getNextKnuthElements(childLC, alignment);
if (returnedList != null) {
if (returnedList.size() == 0) {
nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn);
return nextSequenceStartsOn;
@@ -594,7 +592,7 @@ public abstract class AbstractBreaker {
BlockSequence seq = null;
seq = blockList.endBlockSequence(breakPosition);
if (seq != null) {
blockLists.add(seq);
this.blockLists.add(seq);
}
}
return nextSequenceStartsOn;

+ 1
- 2
src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java Parādīt failu

@@ -21,7 +21,6 @@ package org.apache.fop.layoutmgr;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
import org.apache.fop.traits.MinOptMax;
/**
@@ -37,7 +36,7 @@ public class BalancingColumnBreakingAlgorithm extends PageBreakingAlgorithm {
private int idealPartLen;
public BalancingColumnBreakingAlgorithm(LayoutManager topLevelLM,
PageSequenceLayoutManager.PageProvider pageProvider,
PageProvider pageProvider,
PageBreakingLayoutListener layoutListener,
int alignment, int alignmentLast,
MinOptMax footnoteSeparatorLength,

+ 542
- 0
src/java/org/apache/fop/layoutmgr/PageBreaker.java Parādīt failu

@@ -0,0 +1,542 @@
/*
* 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.LinkedList;
import java.util.List;
import java.util.ListIterator;

import org.apache.fop.area.Block;
import org.apache.fop.area.Footnote;
import org.apache.fop.area.PageViewport;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.Region;
import org.apache.fop.fo.pagination.RegionBody;
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
import org.apache.fop.traits.MinOptMax;

/**
* Handles the breaking of pages in an fo:flow
*/
public class PageBreaker extends AbstractBreaker {
private PageSequenceLayoutManager pslm;
private boolean firstPart = true;
private boolean pageBreakHandled;
private boolean needColumnBalancing;
private PageProvider pageProvider;
private Block separatorArea;
/**
* The FlowLayoutManager object, which processes
* the single fo:flow of the fo:page-sequence
*/
private FlowLayoutManager childFLM = null;

private StaticContentLayoutManager footnoteSeparatorLM = null;

public PageBreaker(PageSequenceLayoutManager pslm) {
this.pslm = pslm;
this.pageProvider = pslm.getPageProvider();
this.childFLM = pslm.getLayoutManagerMaker().makeFlowLayoutManager(
pslm, pslm.getPageSequence().getMainFlow());
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker */
protected void updateLayoutContext(LayoutContext context) {
int flowIPD = pslm.getCurrentPV().getCurrentSpan().getColumnWidth();
context.setRefIPD(flowIPD);
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker#getTopLevelLM() */
protected LayoutManager getTopLevelLM() {
return pslm;
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker#getPageProvider() */
protected PageProvider getPageProvider() {
return pslm.getPageProvider();
}
/**
* @see org.apache.fop.layoutmgr.AbstractBreaker#getLayoutListener()
*/
protected PageBreakingLayoutListener getLayoutListener() {
return new PageBreakingLayoutListener() {

public void notifyOverflow(int part, FObj obj) {
Page p = pageProvider.getPage(
false, part, PageProvider.RELTO_CURRENT_ELEMENT_LIST);
RegionBody body = (RegionBody)p.getSimplePageMaster().getRegion(
Region.FO_REGION_BODY);
String err = FONode.decorateWithContextInfo(
"Content of the region-body on page "
+ p.getPageViewport().getPageNumberString()
+ " overflows the available area in block-progression dimension.",
obj);
if (body.getOverflow() == Constants.EN_ERROR_IF_OVERFLOW) {
throw new RuntimeException(err);
} else {
log.warn(err);
}
}
};
}

/** @see org.apache.fop.layoutmgr.AbstractBreaker */
protected int handleSpanChange(LayoutContext childLC, int nextSequenceStartsOn) {
needColumnBalancing = false;
if (childLC.getNextSpan() != Constants.NOT_SET) {
//Next block list will have a different span.
nextSequenceStartsOn = childLC.getNextSpan();
needColumnBalancing = (childLC.getNextSpan() == Constants.EN_ALL);
}
if (needColumnBalancing) {
AbstractBreaker.log.debug(
"Column balancing necessary for the next element list!!!");
}
return nextSequenceStartsOn;
}

/** @see org.apache.fop.layoutmgr.AbstractBreaker */
protected int getNextBlockList(LayoutContext childLC,
int nextSequenceStartsOn) {
if (!firstPart) {
// if this is the first page that will be created by
// the current BlockSequence, it could have a break
// condition that must be satisfied;
// otherwise, we may simply need a new page
handleBreakTrait(nextSequenceStartsOn);
}
firstPart = false;
pageBreakHandled = true;
pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(),
pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
return super.getNextBlockList(childLC, nextSequenceStartsOn);
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker */
protected LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
LinkedList contentList = null;
while (!childFLM.isFinished() && contentList == null) {
contentList = childFLM.getNextKnuthElements(context, alignment);
}

// scan contentList, searching for footnotes
boolean bFootnotesPresent = false;
if (contentList != null) {
ListIterator contentListIterator = contentList.listIterator();
while (contentListIterator.hasNext()) {
ListElement element = (ListElement) contentListIterator.next();
if (element instanceof KnuthBlockBox
&& ((KnuthBlockBox) element).hasAnchors()) {
// element represents a line with footnote citations
bFootnotesPresent = true;
LayoutContext footnoteContext = new LayoutContext(context);
footnoteContext.setStackLimit(context.getStackLimit());
footnoteContext.setRefIPD(pslm.getCurrentPV()
.getRegionReference(Constants.FO_REGION_BODY).getIPD());
LinkedList footnoteBodyLMs = ((KnuthBlockBox) element).getFootnoteBodyLMs();
ListIterator footnoteBodyIterator = footnoteBodyLMs.listIterator();
// store the lists of elements representing the footnote bodies
// in the box representing the line containing their references
while (footnoteBodyIterator.hasNext()) {
FootnoteBodyLayoutManager fblm
= (FootnoteBodyLayoutManager) footnoteBodyIterator.next();
fblm.setParent(childFLM);
fblm.initialize();
((KnuthBlockBox) element).addElementList(
fblm.getNextKnuthElements(footnoteContext, alignment));
}
}
}
}

if (bFootnotesPresent) {
// handle the footnote separator
StaticContent footnoteSeparator;
footnoteSeparator = pslm.getPageSequence().getStaticContent("xsl-footnote-separator");
if (footnoteSeparator != null) {
// the footnote separator can contain page-dependent content such as
// page numbers or retrieve markers, so its areas cannot simply be
// obtained now and repeated in each page;
// we need to know in advance the separator bpd: the actual separator
// could be different from page to page, but its bpd would likely be
// always the same

// create a Block area that will contain the separator areas
separatorArea = new Block();
separatorArea.setIPD(pslm.getCurrentPV()
.getRegionReference(Constants.FO_REGION_BODY).getIPD());
// create a StaticContentLM for the footnote separator
footnoteSeparatorLM = (StaticContentLayoutManager)
pslm.getLayoutManagerMaker().makeStaticContentLayoutManager(
pslm, footnoteSeparator, separatorArea);
footnoteSeparatorLM.doLayout();

footnoteSeparatorLength = new MinOptMax(separatorArea.getBPD());
}
}
return contentList;
}
/**
* @return current display alignment
*/
protected int getCurrentDisplayAlign() {
return pslm.getCurrentPage().getSimplePageMaster().getRegion(
Constants.FO_REGION_BODY).getDisplayAlign();
}
/**
* @return whether or not this flow has more page break opportunities
*/
protected boolean hasMoreContent() {
return !childFLM.isFinished();
}
/**
* Adds an area to the flow layout manager
* @param posIter the position iterator
* @param context the layout context
*/
protected void addAreas(PositionIterator posIter, LayoutContext context) {
if (footnoteSeparatorLM != null) {
StaticContent footnoteSeparator = pslm.getPageSequence().getStaticContent(
"xsl-footnote-separator");
// create a Block area that will contain the separator areas
separatorArea = new Block();
separatorArea.setIPD(
pslm.getCurrentPV().getRegionReference(Constants.FO_REGION_BODY).getIPD());
// create a StaticContentLM for the footnote separator
footnoteSeparatorLM = (StaticContentLayoutManager)
pslm.getLayoutManagerMaker().makeStaticContentLayoutManager(
pslm, footnoteSeparator, separatorArea);
footnoteSeparatorLM.doLayout();
}

childFLM.addAreas(posIter, context);
}
/**
* Performs phase 3 operation
*
* @param alg page breaking algorithm
* @param partCount part count
* @param originalList the block sequence original list
* @param effectiveList the block sequence effective list
*/
protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
if (needColumnBalancing) {
doPhase3WithColumnBalancing(alg, partCount, originalList, effectiveList);
} else {
if (!hasMoreContent() && pslm.getPageSequence().hasPagePositionLast()) {
//last part is reached and we have a "last page" condition
doPhase3WithLastPage(alg, partCount, originalList, effectiveList);
} else {
//Directly add areas after finding the breaks
addAreas(alg, partCount, originalList, effectiveList);
}
}
}

private void doPhase3WithLastPage(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
int newStartPos;
int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
if (restartPoint > 0) {
//Add definitive areas before last page
addAreas(alg, restartPoint, originalList, effectiveList);
//Get page break from which we restart
PageBreakPosition pbp = (PageBreakPosition)
alg.getPageBreaks().get(restartPoint - 1);
newStartPos = pbp.getLeafPos();
//Handle page break right here to avoid any side-effects
if (newStartPos > 0) {
handleBreakTrait(Constants.EN_PAGE);
}
} else {
newStartPos = 0;
}
AbstractBreaker.log.debug("Last page handling now!!!");
AbstractBreaker.log.debug("===================================================");
AbstractBreaker.log.debug("Restarting at " + restartPoint
+ ", new start position: " + newStartPos);

pageBreakHandled = true;
//Update so the available BPD is reported correctly
int currentPageNum = pslm.getCurrentPageNum();
pageProvider.setStartOfNextElementList(currentPageNum,
pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
pageProvider.setLastPageIndex(currentPageNum);

//Restart last page
PageBreakingAlgorithm algRestart = new PageBreakingAlgorithm(
getTopLevelLM(),
getPageProvider(), getLayoutListener(),
alg.getAlignment(), alg.getAlignmentLast(),
footnoteSeparatorLength,
isPartOverflowRecoveryActivated(), false, false);
//alg.setConstantLineWidth(flowBPD);
int iOptPageCount = algRestart.findBreakingPoints(effectiveList,
newStartPos,
1, true, BreakingAlgorithm.ALL_BREAKS);
AbstractBreaker.log.debug("restart: iOptPageCount= " + iOptPageCount
+ " pageBreaks.size()= " + algRestart.getPageBreaks().size());
boolean replaceLastPage
= iOptPageCount <= pslm.getCurrentPV().getBodyRegion().getColumnCount();
if (replaceLastPage) {
//Replace last page
pslm.setCurrentPage(pageProvider.getPage(false, currentPageNum));
//Make sure we only add the areas we haven't added already
effectiveList.ignoreAtStart = newStartPos;
addAreas(algRestart, iOptPageCount, originalList, effectiveList);
} else {
effectiveList.ignoreAtStart = newStartPos;
addAreas(alg, restartPoint, partCount - restartPoint, originalList, effectiveList);
//Add blank last page
pageProvider.setLastPageIndex(currentPageNum + 1);
pslm.setCurrentPage(pslm.makeNewPage(true, true));
}
AbstractBreaker.log.debug("===================================================");
}

private void doPhase3WithColumnBalancing(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
AbstractBreaker.log.debug("Column balancing now!!!");
AbstractBreaker.log.debug("===================================================");
int newStartPos;
int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
if (restartPoint > 0) {
//Add definitive areas
addAreas(alg, restartPoint, originalList, effectiveList);
//Get page break from which we restart
PageBreakPosition pbp = (PageBreakPosition)
alg.getPageBreaks().get(restartPoint - 1);
newStartPos = pbp.getLeafPos();
//Handle page break right here to avoid any side-effects
if (newStartPos > 0) {
handleBreakTrait(Constants.EN_PAGE);
}
} else {
newStartPos = 0;
}
AbstractBreaker.log.debug("Restarting at " + restartPoint
+ ", new start position: " + newStartPos);

pageBreakHandled = true;
//Update so the available BPD is reported correctly
pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(),
pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex());

//Restart last page
PageBreakingAlgorithm algRestart = new BalancingColumnBreakingAlgorithm(
getTopLevelLM(),
getPageProvider(), getLayoutListener(),
alignment, Constants.EN_START, footnoteSeparatorLength,
isPartOverflowRecoveryActivated(),
pslm.getCurrentPV().getBodyRegion().getColumnCount());
//alg.setConstantLineWidth(flowBPD);
int iOptPageCount = algRestart.findBreakingPoints(effectiveList,
newStartPos,
1, true, BreakingAlgorithm.ALL_BREAKS);
AbstractBreaker.log.debug("restart: iOptPageCount= " + iOptPageCount
+ " pageBreaks.size()= " + algRestart.getPageBreaks().size());
if (iOptPageCount > pslm.getCurrentPV().getBodyRegion().getColumnCount()) {
AbstractBreaker.log.warn(
"Breaking algorithm produced more columns than are available.");
/* reenable when everything works
throw new IllegalStateException(
"Breaking algorithm must not produce more columns than available.");
*/
}
//Make sure we only add the areas we haven't added already
effectiveList.ignoreAtStart = newStartPos;
addAreas(algRestart, iOptPageCount, originalList, effectiveList);
AbstractBreaker.log.debug("===================================================");
}
protected void startPart(BlockSequence list, int breakClass) {
AbstractBreaker.log.debug("startPart() breakClass=" + breakClass);
if (pslm.getCurrentPage() == null) {
throw new IllegalStateException("curPage must not be null");
}
if (!pageBreakHandled) {
//firstPart is necessary because we need the first page before we start the
//algorithm so we have a BPD and IPD. This may subject to change later when we
//start handling more complex cases.
if (!firstPart) {
// if this is the first page that will be created by
// the current BlockSequence, it could have a break
// condition that must be satisfied;
// otherwise, we may simply need a new page
handleBreakTrait(breakClass);
}
pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(),
pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
}
pageBreakHandled = false;
// add static areas and resolve any new id areas
// finish page and add to area tree
firstPart = false;
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker#handleEmptyContent() */
protected void handleEmptyContent() {
pslm.getCurrentPV().getPage().fakeNonEmpty();
}
protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) {
// add footnote areas
if (pbp.footnoteFirstListIndex < pbp.footnoteLastListIndex
|| pbp.footnoteFirstElementIndex <= pbp.footnoteLastElementIndex) {
// call addAreas() for each FootnoteBodyLM
for (int i = pbp.footnoteFirstListIndex; i <= pbp.footnoteLastListIndex; i++) {
LinkedList elementList = alg.getFootnoteList(i);
int firstIndex = (i == pbp.footnoteFirstListIndex
? pbp.footnoteFirstElementIndex : 0);
int lastIndex = (i == pbp.footnoteLastListIndex
? pbp.footnoteLastElementIndex : elementList.size() - 1);

SpaceResolver.performConditionalsNotification(elementList,
firstIndex, lastIndex, -1);
LayoutContext childLC = new LayoutContext(0);
AreaAdditionUtil.addAreas(null,
new KnuthPossPosIter(elementList, firstIndex, lastIndex + 1),
childLC);
}
// set the offset from the top margin
Footnote parentArea = (Footnote) pslm.getCurrentPV().getBodyRegion().getFootnote();
int topOffset = (int) pslm.getCurrentPV().getBodyRegion().getBPD() - parentArea.getBPD();
if (separatorArea != null) {
topOffset -= separatorArea.getBPD();
}
parentArea.setTop(topOffset);
parentArea.setSeparator(separatorArea);
}
pslm.getCurrentPV().getCurrentSpan().notifyFlowsFinished();
}
/**
* @return the current child flow layout manager
*/
protected LayoutManager getCurrentChildLM() {
return childFLM;
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker#observeElementList(java.util.List) */
protected void observeElementList(List elementList) {
ElementListObserver.observe(elementList, "breaker",
((PageSequence)pslm.getFObj()).getId());
}
/**
* Depending on the kind of break condition, move to next column
* or page. May need to make an empty page if next page would
* not have the desired "handedness".
* @param breakVal - value of break-before or break-after trait.
*/
private void handleBreakTrait(int breakVal) {
Page curPage = pslm.getCurrentPage();
if (breakVal == Constants.EN_ALL) {
//break due to span change in multi-column layout
curPage.getPageViewport().createSpan(true);
return;
} else if (breakVal == Constants.EN_NONE) {
curPage.getPageViewport().createSpan(false);
return;
} else if (breakVal == Constants.EN_COLUMN || breakVal <= 0) {
PageViewport pv = curPage.getPageViewport();
//Check if previous page was spanned
boolean forceNewPageWithSpan = false;
RegionBody rb = (RegionBody)curPage.getSimplePageMaster().getRegion(
Constants.FO_REGION_BODY);
if (breakVal < 0
&& rb.getColumnCount() > 1
&& pv.getCurrentSpan().getColumnCount() == 1) {
forceNewPageWithSpan = true;
}
if (forceNewPageWithSpan) {
curPage = pslm.makeNewPage(false, false);
curPage.getPageViewport().createSpan(true);
} else if (pv.getCurrentSpan().hasMoreFlows()) {
pv.getCurrentSpan().moveToNextFlow();
} else {
curPage = pslm.makeNewPage(false, false);
}
return;
}
log.debug("handling break-before after page " + pslm.getCurrentPageNum()
+ " breakVal=" + breakVal);
if (needBlankPageBeforeNew(breakVal)) {
curPage = pslm.makeNewPage(true, false);
}
if (needNewPage(breakVal)) {
curPage = pslm.makeNewPage(false, false);
}
}
/**
* Check if a blank page is needed to accomodate
* desired even or odd page number.
* @param breakVal - value of break-before or break-after trait.
*/
private boolean needBlankPageBeforeNew(int breakVal) {
if (breakVal == Constants.EN_PAGE || (pslm.getCurrentPage().getPageViewport().getPage().isEmpty())) {
// any page is OK or we already have an empty page
return false;
} else {
/* IF we are on the kind of page we need, we'll need a new page. */
if (pslm.getCurrentPageNum() % 2 == 0) { // even page
return (breakVal == Constants.EN_EVEN_PAGE);
} else { // odd page
return (breakVal == Constants.EN_ODD_PAGE);
}
}
}
/**
* See if need to generate a new page
* @param breakVal - value of break-before or break-after trait.
*/
private boolean needNewPage(int breakVal) {
if (pslm.getCurrentPage().getPageViewport().getPage().isEmpty()) {
if (breakVal == Constants.EN_PAGE) {
return false;
} else if (pslm.getCurrentPageNum() % 2 == 0) { // even page
return (breakVal == Constants.EN_ODD_PAGE);
} else { // odd page
return (breakVal == Constants.EN_EVEN_PAGE);
}
} else {
return true;
}
}
}

+ 2
- 2
src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java Parādīt failu

@@ -38,7 +38,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
private static Log log = LogFactory.getLog(PageBreakingAlgorithm.class);

private LayoutManager topLevelLM;
private PageSequenceLayoutManager.PageProvider pageProvider;
private PageProvider pageProvider;
private PageBreakingLayoutListener layoutListener;
/** List of PageBreakPosition elements. */
private LinkedList pageBreaks = null;
@@ -94,7 +94,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
private boolean favorSinglePart = false;
public PageBreakingAlgorithm(LayoutManager topLevelLM,
PageSequenceLayoutManager.PageProvider pageProvider,
PageProvider pageProvider,
PageBreakingLayoutListener layoutListener,
int alignment, int alignmentLast,
MinOptMax footnoteSeparatorLength,

+ 279
- 0
src/java/org/apache/fop/layoutmgr/PageProvider.java Parādīt failu

@@ -0,0 +1,279 @@
/*
* 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.apps.FOPException;
import org.apache.fop.area.AreaTreeHandler;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.Region;
import org.apache.fop.fo.pagination.SimplePageMaster;

/**
* <p>This class delivers Page instances. It also caches them as necessary.
* </p>
* <p>Additional functionality makes sure that surplus instances that are requested by the
* page breaker are properly discarded, especially in situations where hard breaks cause
* blank pages. The reason for that: The page breaker sometimes needs to preallocate
* additional pages since it doesn't know exactly until the end how many pages it really needs.
* </p>
*/
public class PageProvider implements Constants {
private Log log = LogFactory.getLog(PageProvider.class);

/** Indices are evaluated relative to the first page in the page-sequence. */
public static final int RELTO_PAGE_SEQUENCE = 0;
/** Indices are evaluated relative to the first page in the current element list. */
public static final int RELTO_CURRENT_ELEMENT_LIST = 1;
private int startPageOfPageSequence;
private int startPageOfCurrentElementList;
private int startColumnOfCurrentElementList;
private List cachedPages = new java.util.ArrayList();
private int lastPageIndex = -1;
private int indexOfCachedLastPage = -1;
//Cache to optimize getAvailableBPD() calls
private int lastRequestedIndex = -1;
private int lastReportedBPD = -1;

/**
* AreaTreeHandler which activates the PSLM and controls
* the rendering of its pages.
*/
private AreaTreeHandler areaTreeHandler;

/**
* fo:page-sequence formatting object being
* processed by this class
*/
private PageSequence pageSeq;

/**
* Main constructor.
* @param ps The page-sequence the provider operates on
*/
public PageProvider(AreaTreeHandler ath, PageSequence ps) {
this.areaTreeHandler = ath;
this.pageSeq = ps;
this.startPageOfPageSequence = ps.getStartingPageNumber();
}
/**
* The page breaker notifies the provider about the page number an element list starts
* on so it can later retrieve PageViewports relative to this first page.
* @param startPage the number of the first page for the element list.
* @param startColumn the starting column number for the element list.
*/
public void setStartOfNextElementList(int startPage, int startColumn) {
log.debug("start of the next element list is:"
+ " page=" + startPage + " col=" + startColumn);
this.startPageOfCurrentElementList = startPage - startPageOfPageSequence + 1;
this.startColumnOfCurrentElementList = startColumn;
//Reset Cache
this.lastRequestedIndex = -1;
this.lastReportedBPD = -1;
}
/**
* Sets the index of the last page. This is done as soon as the position of the last page
* is known or assumed.
* @param index the index relative to the first page in the page-sequence
*/
public void setLastPageIndex(int index) {
this.lastPageIndex = index;
}
/**
* Returns the available BPD for the part/page indicated by the index parameter.
* The index is the part/page relative to the start of the current element list.
* This method takes multiple columns into account.
* @param index zero-based index of the requested part/page
* @return the available BPD
*/
public int getAvailableBPD(int index) {
//Special optimization: There may be many equal calls by the BreakingAlgorithm
if (this.lastRequestedIndex == index) {
if (log.isTraceEnabled()) {
log.trace("getAvailableBPD(" + index + ") -> (cached) " + lastReportedBPD);
}
return this.lastReportedBPD;
}
int c = index;
int pageIndex = 0;
int colIndex = startColumnOfCurrentElementList;
Page page = getPage(
false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
while (c > 0) {
colIndex++;
if (colIndex >= page.getPageViewport().getCurrentSpan().getColumnCount()) {
colIndex = 0;
pageIndex++;
page = getPage(
false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
}
c--;
}
this.lastRequestedIndex = index;
this.lastReportedBPD = page.getPageViewport().getBodyRegion().getRemainingBPD();
if (log.isTraceEnabled()) {
log.trace("getAvailableBPD(" + index + ") -> " + lastReportedBPD);
}
return this.lastReportedBPD;
}
/**
* Returns the part index (0<x<partCount) which denotes the first part on the last page
* generated by the current element list.
* @param partCount Number of parts determined by the breaking algorithm
* @return the requested part index
*/
public int getStartingPartIndexForLastPage(int partCount) {
int result = 0;
int idx = 0;
int pageIndex = 0;
int colIndex = startColumnOfCurrentElementList;
Page page = getPage(
false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
while (idx < partCount) {
if ((colIndex >= page.getPageViewport().getCurrentSpan().getColumnCount())) {
colIndex = 0;
pageIndex++;
page = getPage(
false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
result = idx;
}
colIndex++;
idx++;
}
return result;
}

/**
* Returns a Page.
* @param isBlank true if this page is supposed to be blank.
* @param index Index of the page (see relativeTo)
* @param relativeTo Defines which value the index parameter should be evaluated relative
* to. (One of PageProvider.RELTO_*)
* @return the requested Page
*/
public Page getPage(boolean isBlank, int index, int relativeTo) {
if (relativeTo == RELTO_PAGE_SEQUENCE) {
return getPage(isBlank, index);
} else if (relativeTo == RELTO_CURRENT_ELEMENT_LIST) {
int effIndex = startPageOfCurrentElementList + index;
effIndex += startPageOfPageSequence - 1;
return getPage(isBlank, effIndex);
} else {
throw new IllegalArgumentException(
"Illegal value for relativeTo: " + relativeTo);
}
}
/**
*
* @param isBlank
* @param index
* @return
*/
protected Page getPage(boolean isBlank, int index) {
boolean isLastPage = (lastPageIndex >= 0) && (index == lastPageIndex);
if (log.isTraceEnabled()) {
log.trace("getPage(" + index + " " + (isBlank ? "blank" : "non-blank")
+ (isLastPage ? " <LAST>" : "") + ")");
}
int intIndex = index - startPageOfPageSequence;
if (log.isTraceEnabled()) {
if (isBlank) {
log.trace("blank page requested: " + index);
}
if (isLastPage) {
log.trace("last page requested: " + index);
}
}
while (intIndex >= cachedPages.size()) {
if (log.isTraceEnabled()) {
log.trace("Caching " + index);
}
cacheNextPage(index, isBlank, isLastPage);
}
Page page = (Page)cachedPages.get(intIndex);
boolean replace = false;
if (page.getPageViewport().isBlank() != isBlank) {
log.debug("blank condition doesn't match. Replacing PageViewport.");
replace = true;
}
if ((isLastPage && indexOfCachedLastPage != intIndex)
|| (!isLastPage && indexOfCachedLastPage >= 0)) {
log.debug("last page condition doesn't match. Replacing PageViewport.");
replace = true;
indexOfCachedLastPage = (isLastPage ? intIndex : -1);
}
if (replace) {
disardCacheStartingWith(intIndex);
page = cacheNextPage(index, isBlank, isLastPage);
}
return page;
}

private void disardCacheStartingWith(int index) {
while (index < cachedPages.size()) {
this.cachedPages.remove(cachedPages.size() - 1);
if (!pageSeq.goToPreviousSimplePageMaster()) {
log.warn("goToPreviousSimplePageMaster() on the first page called!");
}
}
}
private Page cacheNextPage(int index, boolean isBlank, boolean isLastPage) {
try {
String pageNumberString = pageSeq.makeFormattedPageNumber(index);
SimplePageMaster spm = pageSeq.getNextSimplePageMaster(
index, (startPageOfPageSequence == index), isLastPage, isBlank);
Region body = spm.getRegion(FO_REGION_BODY);
if (!pageSeq.getMainFlow().getFlowName().equals(body.getRegionName())) {
// this is fine by the XSL Rec (fo:flow's flow-name can be mapped to
// any region), but we don't support it yet.
throw new FOPException("Flow '" + pageSeq.getMainFlow().getFlowName()
+ "' does not map to the region-body in page-master '"
+ spm.getMasterName() + "'. FOP presently "
+ "does not support this.");
}
Page page = new Page(spm, index, pageNumberString, isBlank);
//Set unique key obtained from the AreaTreeHandler
page.getPageViewport().setKey(areaTreeHandler.generatePageViewportKey());
page.getPageViewport().setForeignAttributes(spm.getForeignAttributes());
cachedPages.add(page);
return page;
} catch (FOPException e) {
//TODO Maybe improve. It'll mean to propagate this exception up several
//methods calls.
throw new IllegalStateException(e.getMessage());
}
}
}

+ 49
- 740
src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java Parādīt failu

@@ -21,39 +21,26 @@ package org.apache.fop.layoutmgr;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Numeric;

import org.apache.fop.area.AreaTreeHandler;
import org.apache.fop.area.AreaTreeModel;
import org.apache.fop.area.Block;
import org.apache.fop.area.Footnote;
import org.apache.fop.area.IDTracker;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.Resolvable;

import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.flow.Marker;
import org.apache.fop.fo.flow.RetrieveMarker;

import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.PageSequenceMaster;
import org.apache.fop.fo.pagination.Region;
import org.apache.fop.fo.pagination.RegionBody;
import org.apache.fop.fo.pagination.SideRegion;
import org.apache.fop.fo.pagination.SimplePageMaster;
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
import org.apache.fop.layoutmgr.inline.ContentLayoutManager;

import org.apache.fop.traits.MinOptMax;

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

/**
* LayoutManager for a PageSequence. This class is instantiated by
@@ -77,23 +64,17 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
private PageSequence pageSeq;

private PageProvider pageProvider;

private IDTracker idTracker;

/**
* Current page with page-viewport-area being filled by
* the PSLM.
*/
private Page curPage = null;

/**
* The FlowLayoutManager object, which processes
* the single fo:flow of the fo:page-sequence
*/
private FlowLayoutManager childFLM = null;
private Page curPage;

private int startPageNum = 0;
private int currentPageNum = 0;

private Block separatorArea = null;
/**
* Constructor
@@ -104,8 +85,9 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
public PageSequenceLayoutManager(AreaTreeHandler ath, PageSequence pseq) {
super(pseq);
this.areaTreeHandler = ath;
this.idTracker = ath.getIDTracker();
this.pageSeq = pseq;
this.pageProvider = new PageProvider(this.pageSeq);
this.pageProvider = new PageProvider(ath, pseq);
}

/**
@@ -121,6 +103,13 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
return this.pageProvider;
}
/**
* @return the PageSequence being managed by this layout manager
*/
protected PageSequence getPageSequence() {
return pageSeq;
}

/**
* Activate the layout of this page sequence.
* PageViewports corresponding to each page generated by this
@@ -150,10 +139,6 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {

curPage = makeNewPage(false, false);
Flow mainFlow = pageSeq.getMainFlow();
childFLM = getLayoutManagerMaker().
makeFlowLayoutManager(this, mainFlow);

PageBreaker breaker = new PageBreaker(this);
int flowBPD = (int)getCurrentPV().getBodyRegion().getRemainingBPD();
breaker.doLayout(flowBPD);
@@ -165,8 +150,8 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
* Finished the page-sequence and notifies everyone about it.
*/
public void finishPageSequence() {
if (!pageSeq.getId().equals("")) {
areaTreeHandler.signalIDProcessed(pageSeq.getId());
if (pageSeq.hasId()) {
idTracker.signalIDProcessed(pageSeq.getId());
}

pageSeq.getRoot().notifyPageSequenceFinished(currentPageNum,
@@ -188,392 +173,6 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
log.debug("Ending layout");
}
}


private class PageBreaker extends AbstractBreaker {
private PageSequenceLayoutManager pslm;
private boolean firstPart = true;
private boolean pageBreakHandled;
private boolean needColumnBalancing;
private StaticContentLayoutManager footnoteSeparatorLM = null;

public PageBreaker(PageSequenceLayoutManager pslm) {
this.pslm = pslm;
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker */
protected void updateLayoutContext(LayoutContext context) {
int flowIPD = getCurrentPV().getCurrentSpan().getColumnWidth();
context.setRefIPD(flowIPD);
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker#getTopLevelLM() */
protected LayoutManager getTopLevelLM() {
return pslm;
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker#getPageProvider() */
protected PageSequenceLayoutManager.PageProvider getPageProvider() {
return pageProvider;
}
/**
* @see org.apache.fop.layoutmgr.AbstractBreaker#getLayoutListener()
*/
protected PageBreakingLayoutListener getLayoutListener() {
return new PageBreakingLayoutListener() {

public void notifyOverflow(int part, FObj obj) {
Page p = pageProvider.getPage(
false, part, PageProvider.RELTO_CURRENT_ELEMENT_LIST);
RegionBody body = (RegionBody)p.getSimplePageMaster().getRegion(
Region.FO_REGION_BODY);
String err = FONode.decorateWithContextInfo(
"Content of the region-body on page "
+ p.getPageViewport().getPageNumberString()
+ " overflows the available area in block-progression dimension.",
obj);
if (body.getOverflow() == Constants.EN_ERROR_IF_OVERFLOW) {
throw new RuntimeException(err);
} else {
PageSequenceLayoutManager.log.warn(err);
}
}
};
}

/** @see org.apache.fop.layoutmgr.AbstractBreaker */
protected int handleSpanChange(LayoutContext childLC, int nextSequenceStartsOn) {
needColumnBalancing = false;
if (childLC.getNextSpan() != Constants.NOT_SET) {
//Next block list will have a different span.
nextSequenceStartsOn = childLC.getNextSpan();
needColumnBalancing = (childLC.getNextSpan() == Constants.EN_ALL);
}
if (needColumnBalancing) {
AbstractBreaker.log.debug(
"Column balancing necessary for the next element list!!!");
}
return nextSequenceStartsOn;
}

/** @see org.apache.fop.layoutmgr.AbstractBreaker */
protected int getNextBlockList(LayoutContext childLC,
int nextSequenceStartsOn,
List blockLists) {
if (!firstPart) {
// if this is the first page that will be created by
// the current BlockSequence, it could have a break
// condition that must be satisfied;
// otherwise, we may simply need a new page
handleBreakTrait(nextSequenceStartsOn);
}
firstPart = false;
pageBreakHandled = true;
pageProvider.setStartOfNextElementList(currentPageNum,
getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
return super.getNextBlockList(childLC, nextSequenceStartsOn, blockLists);
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker */
protected LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
LinkedList contentList = null;
while (!childFLM.isFinished() && contentList == null) {
contentList = childFLM.getNextKnuthElements(context, alignment);
}

// scan contentList, searching for footnotes
boolean bFootnotesPresent = false;
if (contentList != null) {
ListIterator contentListIterator = contentList.listIterator();
while (contentListIterator.hasNext()) {
ListElement element = (ListElement) contentListIterator.next();
if (element instanceof KnuthBlockBox
&& ((KnuthBlockBox) element).hasAnchors()) {
// element represents a line with footnote citations
bFootnotesPresent = true;
LayoutContext footnoteContext = new LayoutContext(context);
footnoteContext.setStackLimit(context.getStackLimit());
footnoteContext.setRefIPD(getCurrentPV()
.getRegionReference(Constants.FO_REGION_BODY).getIPD());
LinkedList footnoteBodyLMs = ((KnuthBlockBox) element).getFootnoteBodyLMs();
ListIterator footnoteBodyIterator = footnoteBodyLMs.listIterator();
// store the lists of elements representing the footnote bodies
// in the box representing the line containing their references
while (footnoteBodyIterator.hasNext()) {
FootnoteBodyLayoutManager fblm
= (FootnoteBodyLayoutManager) footnoteBodyIterator.next();
fblm.setParent(childFLM);
fblm.initialize();
((KnuthBlockBox) element).addElementList(
fblm.getNextKnuthElements(footnoteContext, alignment));
}
}
}
}

// handle the footnote separator
StaticContent footnoteSeparator;
if (bFootnotesPresent
&& (footnoteSeparator = pageSeq.getStaticContent(
"xsl-footnote-separator")) != null) {
// the footnote separator can contain page-dependent content such as
// page numbers or retrieve markers, so its areas cannot simply be
// obtained now and repeated in each page;
// we need to know in advance the separator bpd: the actual separator
// could be different from page to page, but its bpd would likely be
// always the same

// create a Block area that will contain the separator areas
separatorArea = new Block();
separatorArea.setIPD(pslm.getCurrentPV()
.getRegionReference(Constants.FO_REGION_BODY).getIPD());
// create a StaticContentLM for the footnote separator
footnoteSeparatorLM = (StaticContentLayoutManager)
getLayoutManagerMaker().makeStaticContentLayoutManager(
pslm, footnoteSeparator, separatorArea);
footnoteSeparatorLM.doLayout();

footnoteSeparatorLength = new MinOptMax(separatorArea.getBPD());
}
return contentList;
}
protected int getCurrentDisplayAlign() {
return curPage.getSimplePageMaster().getRegion(
Constants.FO_REGION_BODY).getDisplayAlign();
}
protected boolean hasMoreContent() {
return !childFLM.isFinished();
}
protected void addAreas(PositionIterator posIter, LayoutContext context) {
if (footnoteSeparatorLM != null) {
StaticContent footnoteSeparator = pageSeq.getStaticContent(
"xsl-footnote-separator");
// create a Block area that will contain the separator areas
separatorArea = new Block();
separatorArea.setIPD(
getCurrentPV().getRegionReference(Constants.FO_REGION_BODY).getIPD());
// create a StaticContentLM for the footnote separator
footnoteSeparatorLM = (StaticContentLayoutManager)
getLayoutManagerMaker().makeStaticContentLayoutManager(
pslm, footnoteSeparator, separatorArea);
footnoteSeparatorLM.doLayout();
}

childFLM.addAreas(posIter, context);
}
protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
if (needColumnBalancing) {
doPhase3WithColumnBalancing(alg, partCount, originalList, effectiveList);
} else {
if (!hasMoreContent() && pageSeq.hasPagePositionLast()) {
//last part is reached and we have a "last page" condition
doPhase3WithLastPage(alg, partCount, originalList, effectiveList);
} else {
//Directly add areas after finding the breaks
addAreas(alg, partCount, originalList, effectiveList);
}
}
}

private void doPhase3WithLastPage(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
int newStartPos;
int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
if (restartPoint > 0) {
//Add definitive areas before last page
addAreas(alg, restartPoint, originalList, effectiveList);
//Get page break from which we restart
PageBreakPosition pbp = (PageBreakPosition)
alg.getPageBreaks().get(restartPoint - 1);
newStartPos = pbp.getLeafPos();
//Handle page break right here to avoid any side-effects
if (newStartPos > 0) {
handleBreakTrait(EN_PAGE);
}
} else {
newStartPos = 0;
}
AbstractBreaker.log.debug("Last page handling now!!!");
AbstractBreaker.log.debug("===================================================");
AbstractBreaker.log.debug("Restarting at " + restartPoint
+ ", new start position: " + newStartPos);

pageBreakHandled = true;
//Update so the available BPD is reported correctly
pageProvider.setStartOfNextElementList(currentPageNum,
getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
pageProvider.setLastPageIndex(currentPageNum);

//Restart last page
PageBreakingAlgorithm algRestart = new PageBreakingAlgorithm(
getTopLevelLM(),
getPageProvider(), getLayoutListener(),
alg.getAlignment(), alg.getAlignmentLast(),
footnoteSeparatorLength,
isPartOverflowRecoveryActivated(), false, false);
//alg.setConstantLineWidth(flowBPD);
int iOptPageCount = algRestart.findBreakingPoints(effectiveList,
newStartPos,
1, true, BreakingAlgorithm.ALL_BREAKS);
AbstractBreaker.log.debug("restart: iOptPageCount= " + iOptPageCount
+ " pageBreaks.size()= " + algRestart.getPageBreaks().size());
boolean replaceLastPage
= iOptPageCount <= getCurrentPV().getBodyRegion().getColumnCount();
if (replaceLastPage) {

//Replace last page
pslm.curPage = pageProvider.getPage(false, currentPageNum);
//Make sure we only add the areas we haven't added already
effectiveList.ignoreAtStart = newStartPos;
addAreas(algRestart, iOptPageCount, originalList, effectiveList);
} else {
effectiveList.ignoreAtStart = newStartPos;
addAreas(alg, restartPoint, partCount - restartPoint, originalList, effectiveList);
//Add blank last page
pageProvider.setLastPageIndex(currentPageNum + 1);
pslm.curPage = makeNewPage(true, true);
}
AbstractBreaker.log.debug("===================================================");
}

private void doPhase3WithColumnBalancing(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
AbstractBreaker.log.debug("Column balancing now!!!");
AbstractBreaker.log.debug("===================================================");
int newStartPos;
int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
if (restartPoint > 0) {
//Add definitive areas
addAreas(alg, restartPoint, originalList, effectiveList);
//Get page break from which we restart
PageBreakPosition pbp = (PageBreakPosition)
alg.getPageBreaks().get(restartPoint - 1);
newStartPos = pbp.getLeafPos();
//Handle page break right here to avoid any side-effects
if (newStartPos > 0) {
handleBreakTrait(EN_PAGE);
}
} else {
newStartPos = 0;
}
AbstractBreaker.log.debug("Restarting at " + restartPoint
+ ", new start position: " + newStartPos);

pageBreakHandled = true;
//Update so the available BPD is reported correctly
pageProvider.setStartOfNextElementList(currentPageNum,
getCurrentPV().getCurrentSpan().getCurrentFlowIndex());

//Restart last page
PageBreakingAlgorithm algRestart = new BalancingColumnBreakingAlgorithm(
getTopLevelLM(),
getPageProvider(), getLayoutListener(),
alignment, Constants.EN_START, footnoteSeparatorLength,
isPartOverflowRecoveryActivated(),
getCurrentPV().getBodyRegion().getColumnCount());
//alg.setConstantLineWidth(flowBPD);
int iOptPageCount = algRestart.findBreakingPoints(effectiveList,
newStartPos,
1, true, BreakingAlgorithm.ALL_BREAKS);
AbstractBreaker.log.debug("restart: iOptPageCount= " + iOptPageCount
+ " pageBreaks.size()= " + algRestart.getPageBreaks().size());
if (iOptPageCount > getCurrentPV().getBodyRegion().getColumnCount()) {
AbstractBreaker.log.warn(
"Breaking algorithm produced more columns than are available.");
/* reenable when everything works
throw new IllegalStateException(
"Breaking algorithm must not produce more columns than available.");
*/
}
//Make sure we only add the areas we haven't added already
effectiveList.ignoreAtStart = newStartPos;
addAreas(algRestart, iOptPageCount, originalList, effectiveList);
AbstractBreaker.log.debug("===================================================");
}
protected void startPart(BlockSequence list, int breakClass) {
AbstractBreaker.log.debug("startPart() breakClass=" + breakClass);
if (curPage == null) {
throw new IllegalStateException("curPage must not be null");
}
if (!pageBreakHandled) {
//firstPart is necessary because we need the first page before we start the
//algorithm so we have a BPD and IPD. This may subject to change later when we
//start handling more complex cases.
if (!firstPart) {
// if this is the first page that will be created by
// the current BlockSequence, it could have a break
// condition that must be satisfied;
// otherwise, we may simply need a new page
handleBreakTrait(breakClass);
}
pageProvider.setStartOfNextElementList(currentPageNum,
getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
}
pageBreakHandled = false;
// add static areas and resolve any new id areas
// finish page and add to area tree
firstPart = false;
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker#handleEmptyContent() */
protected void handleEmptyContent() {
getCurrentPV().getPage().fakeNonEmpty();
}
protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) {
// add footnote areas
if (pbp.footnoteFirstListIndex < pbp.footnoteLastListIndex
|| pbp.footnoteFirstElementIndex <= pbp.footnoteLastElementIndex) {
// call addAreas() for each FootnoteBodyLM
for (int i = pbp.footnoteFirstListIndex; i <= pbp.footnoteLastListIndex; i++) {
LinkedList elementList = alg.getFootnoteList(i);
int firstIndex = (i == pbp.footnoteFirstListIndex
? pbp.footnoteFirstElementIndex : 0);
int lastIndex = (i == pbp.footnoteLastListIndex
? pbp.footnoteLastElementIndex : elementList.size() - 1);

SpaceResolver.performConditionalsNotification(elementList,
firstIndex, lastIndex, -1);
LayoutContext childLC = new LayoutContext(0);
AreaAdditionUtil.addAreas(null,
new KnuthPossPosIter(elementList, firstIndex, lastIndex + 1),
childLC);
}
// set the offset from the top margin
Footnote parentArea = (Footnote) getCurrentPV().getBodyRegion().getFootnote();
int topOffset = (int) getCurrentPV().getBodyRegion().getBPD() - parentArea.getBPD();
if (separatorArea != null) {
topOffset -= separatorArea.getBPD();
}
parentArea.setTop(topOffset);
parentArea.setSeparator(separatorArea);
}
getCurrentPV().getCurrentSpan().notifyFlowsFinished();
}
protected LayoutManager getCurrentChildLM() {
return childFLM;
}
/** @see org.apache.fop.layoutmgr.AbstractBreaker#observeElementList(java.util.List) */
protected void observeElementList(List elementList) {
ElementListObserver.observe(elementList, "breaker",
((PageSequence)pslm.getFObj()).getId());
}
}
/**
* Provides access to the current page.
@@ -583,6 +182,22 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
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;
}

/**
* Provides access to the current page viewport.
* @return the current PageViewport
@@ -607,7 +222,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
* @return the first PageViewport that contains the ID trait
*/
public PageViewport getFirstPVWithID(String idref) {
List list = areaTreeHandler.getPageViewportsContainingID(idref);
List list = idTracker.getPageViewportsContainingID(idref);
if (list != null && list.size() > 0) {
return (PageViewport) list.get(0);
}
@@ -622,7 +237,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
* @return the last PageViewport that contains the ID trait
*/
public PageViewport getLastPVWithID(String idref) {
List list = areaTreeHandler.getPageViewportsContainingID(idref);
List list = idTracker.getPageViewportsContainingID(idref);
if (list != null && list.size() > 0) {
return (PageViewport) list.get(list.size() - 1);
}
@@ -639,7 +254,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
*/
public void addIDToPage(String id) {
if (id != null && id.length() > 0) {
areaTreeHandler.associateIDWithPageViewport(id, curPage.getPageViewport());
idTracker.associateIDWithPageViewport(id, curPage.getPageViewport());
}
}
@@ -654,8 +269,8 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
if (log.isDebugEnabled()) {
log.debug("associateLayoutManagerID(" + id + ")");
}
if (!areaTreeHandler.alreadyResolvedID(id)) {
areaTreeHandler.signalPendingID(id);
if (!idTracker.alreadyResolvedID(id)) {
idTracker.signalPendingID(id);
return false;
} else {
return true;
@@ -668,7 +283,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
* @param id the id for which layout has finished
*/
public void notifyEndOfLayout(String id) {
areaTreeHandler.signalIDProcessed(id);
idTracker.signalIDProcessed(id);
}
/**
@@ -676,7 +291,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
* resolved, e.g. the internal-destination of an fo:basic-link)
* for both the AreaTreeHandler and PageViewport object.
*
* The AreaTreeHandler keeps a document-wide list of idref's
* 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.
*
@@ -689,7 +304,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
*/
public void addUnresolvedArea(String id, Resolvable res) {
curPage.getPageViewport().addUnresolvedIDRef(id, res);
areaTreeHandler.addUnresolvedIDRef(id, curPage.getPageViewport());
idTracker.addUnresolvedIDRef(id, curPage.getPageViewport());
}

/**
@@ -750,7 +365,14 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
}
}

private Page makeNewPage(boolean bIsBlank, boolean bIsLast) {
/**
* 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 bIsBlank, boolean bIsLast) {
if (curPage != null) {
finishPage();
}
@@ -797,7 +419,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
// Try to resolve any unresolved IDs for the current page.
//
areaTreeHandler.tryIDResolution(curPage.getPageViewport());
idTracker.tryIDResolution(curPage.getPageViewport());
// Queue for ID resolution and rendering
areaTreeHandler.getAreaTreeModel().addPage(curPage.getPageViewport());
if (log.isDebugEnabled()) {
@@ -806,320 +428,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
}
curPage = null;
}
/**
* Depending on the kind of break condition, move to next column
* or page. May need to make an empty page if next page would
* not have the desired "handedness".
* @param breakVal - value of break-before or break-after trait.
*/
private void handleBreakTrait(int breakVal) {
if (breakVal == Constants.EN_ALL) {
//break due to span change in multi-column layout
curPage.getPageViewport().createSpan(true);
return;
} else if (breakVal == Constants.EN_NONE) {
curPage.getPageViewport().createSpan(false);
return;
} else if (breakVal == Constants.EN_COLUMN || breakVal <= 0) {
PageViewport pv = curPage.getPageViewport();
//Check if previous page was spanned
boolean forceNewPageWithSpan = false;
RegionBody rb = (RegionBody)curPage.getSimplePageMaster().getRegion(
Constants.FO_REGION_BODY);
if (breakVal < 0
&& rb.getColumnCount() > 1
&& pv.getCurrentSpan().getColumnCount() == 1) {
forceNewPageWithSpan = true;
}
if (forceNewPageWithSpan) {
curPage = makeNewPage(false, false);
curPage.getPageViewport().createSpan(true);
} else if (pv.getCurrentSpan().hasMoreFlows()) {
pv.getCurrentSpan().moveToNextFlow();
} else {
curPage = makeNewPage(false, false);
}
return;
}
log.debug("handling break-before after page " + currentPageNum
+ " breakVal=" + breakVal);
if (needBlankPageBeforeNew(breakVal)) {
curPage = makeNewPage(true, false);
}
if (needNewPage(breakVal)) {
curPage = makeNewPage(false, false);
}
}

/**
* Check if a blank page is needed to accomodate
* desired even or odd page number.
* @param breakVal - value of break-before or break-after trait.
*/
private boolean needBlankPageBeforeNew(int breakVal) {
if (breakVal == Constants.EN_PAGE || (curPage.getPageViewport().getPage().isEmpty())) {
// any page is OK or we already have an empty page
return false;
} else {
/* IF we are on the kind of page we need, we'll need a new page. */
if (currentPageNum % 2 == 0) { // even page
return (breakVal == Constants.EN_EVEN_PAGE);
} else { // odd page
return (breakVal == Constants.EN_ODD_PAGE);
}
}
}

/**
* See if need to generate a new page
* @param breakVal - value of break-before or break-after trait.
*/
private boolean needNewPage(int breakVal) {
if (curPage.getPageViewport().getPage().isEmpty()) {
if (breakVal == Constants.EN_PAGE) {
return false;
} else if (currentPageNum % 2 == 0) { // even page
return (breakVal == Constants.EN_ODD_PAGE);
} else { // odd page
return (breakVal == Constants.EN_EVEN_PAGE);
}
} else {
return true;
}
}
/**
* <p>This class delivers Page instances. It also caches them as necessary.
* </p>
* <p>Additional functionality makes sure that surplus instances that are requested by the
* page breaker are properly discarded, especially in situations where hard breaks cause
* blank pages. The reason for that: The page breaker sometimes needs to preallocate
* additional pages since it doesn't know exactly until the end how many pages it really needs.
* </p>
*/
public class PageProvider {
private Log log = LogFactory.getLog(PageProvider.class);

/** Indices are evaluated relative to the first page in the page-sequence. */
public static final int RELTO_PAGE_SEQUENCE = 0;
/** Indices are evaluated relative to the first page in the current element list. */
public static final int RELTO_CURRENT_ELEMENT_LIST = 1;
private int startPageOfPageSequence;
private int startPageOfCurrentElementList;
private int startColumnOfCurrentElementList;
private List cachedPages = new java.util.ArrayList();
private int lastPageIndex = -1;
private int indexOfCachedLastPage = -1;
//Cache to optimize getAvailableBPD() calls
private int lastRequestedIndex = -1;
private int lastReportedBPD = -1;
/**
* Main constructor.
* @param ps The page-sequence the provider operates on
*/
public PageProvider(PageSequence ps) {
this.startPageOfPageSequence = ps.getStartingPageNumber();
}
/**
* The page breaker notifies the provider about the page number an element list starts
* on so it can later retrieve PageViewports relative to this first page.
* @param startPage the number of the first page for the element list.
* @param startColumn the starting column number for the element list.
*/
public void setStartOfNextElementList(int startPage, int startColumn) {
log.debug("start of the next element list is:"
+ " page=" + startPage + " col=" + startColumn);
this.startPageOfCurrentElementList = startPage - startPageOfPageSequence + 1;
this.startColumnOfCurrentElementList = startColumn;
//Reset Cache
this.lastRequestedIndex = -1;
this.lastReportedBPD = -1;
}
/**
* Sets the index of the last page. This is done as soon as the position of the last page
* is known or assumed.
* @param index the index relative to the first page in the page-sequence
*/
public void setLastPageIndex(int index) {
this.lastPageIndex = index;
}
/**
* Returns the available BPD for the part/page indicated by the index parameter.
* The index is the part/page relative to the start of the current element list.
* This method takes multiple columns into account.
* @param index zero-based index of the requested part/page
* @return the available BPD
*/
public int getAvailableBPD(int index) {
//Special optimization: There may be many equal calls by the BreakingAlgorithm
if (this.lastRequestedIndex == index) {
if (log.isTraceEnabled()) {
log.trace("getAvailableBPD(" + index + ") -> (cached) " + lastReportedBPD);
}
return this.lastReportedBPD;
}
int c = index;
int pageIndex = 0;
int colIndex = startColumnOfCurrentElementList;
Page page = getPage(
false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
while (c > 0) {
colIndex++;
if (colIndex >= page.getPageViewport().getCurrentSpan().getColumnCount()) {
colIndex = 0;
pageIndex++;
page = getPage(
false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
}
c--;
}
this.lastRequestedIndex = index;
this.lastReportedBPD = page.getPageViewport().getBodyRegion().getRemainingBPD();
if (log.isTraceEnabled()) {
log.trace("getAvailableBPD(" + index + ") -> " + lastReportedBPD);
}
return this.lastReportedBPD;
}
/**
* Returns the part index (0<x<partCount) which denotes the first part on the last page
* generated by the current element list.
* @param partCount Number of parts determined by the breaking algorithm
* @return the requested part index
*/
public int getStartingPartIndexForLastPage(int partCount) {
int result = 0;
int idx = 0;
int pageIndex = 0;
int colIndex = startColumnOfCurrentElementList;
Page page = getPage(
false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
while (idx < partCount) {
if ((colIndex >= page.getPageViewport().getCurrentSpan().getColumnCount())) {
colIndex = 0;
pageIndex++;
page = getPage(
false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
result = idx;
}
colIndex++;
idx++;
}
return result;
}

/**
* Returns a Page.
* @param isBlank true if this page is supposed to be blank.
* @param index Index of the page (see relativeTo)
* @param relativeTo Defines which value the index parameter should be evaluated relative
* to. (One of PageProvider.RELTO_*)
* @return the requested Page
*/
public Page getPage(boolean isBlank, int index, int relativeTo) {
if (relativeTo == RELTO_PAGE_SEQUENCE) {
return getPage(isBlank, index);
} else if (relativeTo == RELTO_CURRENT_ELEMENT_LIST) {
int effIndex = startPageOfCurrentElementList + index;
effIndex += startPageOfPageSequence - 1;
return getPage(isBlank, effIndex);
} else {
throw new IllegalArgumentException(
"Illegal value for relativeTo: " + relativeTo);
}
}
private Page getPage(boolean isBlank, int index) {
boolean isLastPage = (lastPageIndex >= 0) && (index == lastPageIndex);
if (log.isTraceEnabled()) {
log.trace("getPage(" + index + " " + (isBlank ? "blank" : "non-blank")
+ (isLastPage ? " <LAST>" : "") + ")");
}
int intIndex = index - startPageOfPageSequence;
if (log.isTraceEnabled()) {
if (isBlank) {
log.trace("blank page requested: " + index);
}
if (isLastPage) {
log.trace("last page requested: " + index);
}
}
while (intIndex >= cachedPages.size()) {
if (log.isTraceEnabled()) {
log.trace("Caching " + index);
}
cacheNextPage(index, isBlank, isLastPage);
}
Page page = (Page)cachedPages.get(intIndex);
boolean replace = false;
if (page.getPageViewport().isBlank() != isBlank) {
log.debug("blank condition doesn't match. Replacing PageViewport.");
replace = true;
}
if ((isLastPage && indexOfCachedLastPage != intIndex)
|| (!isLastPage && indexOfCachedLastPage >= 0)) {
log.debug("last page condition doesn't match. Replacing PageViewport.");
replace = true;
indexOfCachedLastPage = (isLastPage ? intIndex : -1);
}
if (replace) {
disardCacheStartingWith(intIndex);
page = cacheNextPage(index, isBlank, isLastPage);
}
return page;
}

private void disardCacheStartingWith(int index) {
while (index < cachedPages.size()) {
this.cachedPages.remove(cachedPages.size() - 1);
if (!pageSeq.goToPreviousSimplePageMaster()) {
log.warn("goToPreviousSimplePageMaster() on the first page called!");
}
}
}
private Page cacheNextPage(int index, boolean isBlank, boolean isLastPage) {
try {
String pageNumberString = pageSeq.makeFormattedPageNumber(index);
SimplePageMaster spm = pageSeq.getNextSimplePageMaster(
index, (startPageOfPageSequence == index), isLastPage, isBlank);
Region body = spm.getRegion(FO_REGION_BODY);
if (!pageSeq.getMainFlow().getFlowName().equals(body.getRegionName())) {
// this is fine by the XSL Rec (fo:flow's flow-name can be mapped to
// any region), but we don't support it yet.
throw new FOPException("Flow '" + pageSeq.getMainFlow().getFlowName()
+ "' does not map to the region-body in page-master '"
+ spm.getMasterName() + "'. FOP presently "
+ "does not support this.");
}
Page page = new Page(spm, index, pageNumberString, isBlank);
//Set unique key obtained from the AreaTreeHandler
page.getPageViewport().setKey(areaTreeHandler.generatePageViewportKey());
page.getPageViewport().setForeignAttributes(spm.getForeignAttributes());
cachedPages.add(page);
return page;
} catch (FOPException e) {
//TODO Maybe improve. It'll mean to propagate this exception up several
//methods calls.
throw new IllegalStateException(e.getMessage());
}
}
}

/**
* Act upon the force-page-count trait,
* in relation to the initial-page-number trait of the following page-sequence.

+ 6
- 9
src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java Parādīt failu

@@ -58,8 +58,8 @@ public class BasicLinkLayoutManager extends InlineLayoutManager {
*/
private void setupBasicLinkArea(LayoutManager parentLM, InlineArea area) {
// internal destinations take precedence:
String idref = fobj.getInternalDestination();
if (idref != null && idref.length() > 0) {
if (fobj.hasInternalDestination()) {
String idref = fobj.getInternalDestination();
PageSequenceLayoutManager pslm = getPSLM();
// the INTERNAL_LINK trait is added by the LinkResolver
// if and when the link is resolved:
@@ -68,13 +68,10 @@ public class BasicLinkLayoutManager extends InlineLayoutManager {
if (!res.isResolved()) {
pslm.addUnresolvedArea(idref, res);
}
} else {
String extdest = fobj.getExternalDestination();
if (extdest != null) {
String url = URISpecification.getURL(extdest);
if (url.length() > 0) {
area.addTrait(Trait.EXTERNAL_LINK, url);
}
} else if (fobj.hasExternalDestination()) {
String url = URISpecification.getURL(fobj.getExternalDestination());
if (url.length() > 0) {
area.addTrait(Trait.EXTERNAL_LINK, url);
}
}
}

+ 1
- 1
src/java/org/apache/fop/render/rtf/RTFHandler.java Parādīt failu

@@ -1093,7 +1093,7 @@ public class RTFHandler extends FOEventHandler {

RtfHyperLink link = textrun.addHyperlink(new RtfAttributes());

if (basicLink.getExternalDestination() != null) {
if (basicLink.hasExternalDestination()) {
link.setExternalURL(basicLink.getExternalDestination());
} else {
link.setInternalURL(basicLink.getInternalDestination());

+ 7
- 0
status.xml Parādīt failu

@@ -28,6 +28,13 @@

<changes>
<release version="FOP Trunk">
<action context="code" dev="AD" type="update" fixes-bug="42089" due-to="Adrian Cumiskey">
Code cleanup and restructuring.
</action>
<action context="Code" dev="AD" type="add">
Slight improvement of relative font-weight handling in the properties
package.
</action>
<action context="Code" dev="JM" type="update">
Updated PDF/A-1b support according to ISO-19005-1:2005/Cor.1:2007.
</action>

Notiek ielāde…
Atcelt
Saglabāt