diff options
Diffstat (limited to 'src/java')
88 files changed, 1998 insertions, 2733 deletions
diff --git a/src/java/org/apache/fop/afp/DataStream.java b/src/java/org/apache/fop/afp/DataStream.java index a437c3004..2794ae932 100644 --- a/src/java/org/apache/fop/afp/DataStream.java +++ b/src/java/org/apache/fop/afp/DataStream.java @@ -595,7 +595,13 @@ public class DataStream { * byte data */ public void createNoOperation(String content) { - currentPage.createNoOperation(content); + if (currentPage != null) { + currentPage.createNoOperation(content); + } else if (currentPageGroup != null) { + currentPageGroup.createNoOperation(content); + } else { + document.createNoOperation(content); + } } /** @@ -639,9 +645,9 @@ public class DataStream { currentPageGroup.endPageGroup(); tleSequence = currentPageGroup.getTleSequence(); document.addPageGroup(currentPageGroup); - document.writeToStream(outputStream); currentPageGroup = null; } + document.writeToStream(outputStream); //Flush objects } /** diff --git a/src/java/org/apache/fop/afp/modca/AbstractPageObject.java b/src/java/org/apache/fop/afp/modca/AbstractPageObject.java index 1454cf96d..99afd322a 100644 --- a/src/java/org/apache/fop/afp/modca/AbstractPageObject.java +++ b/src/java/org/apache/fop/afp/modca/AbstractPageObject.java @@ -57,11 +57,8 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen /** The current presentation text object */ private PresentationTextObject currentPresentationTextObject = null; - /** The list of tag logical elements */ - protected List/*<TagLogicalElement>*/ tagLogicalElements = null; - /** The list of objects within this resource container */ - protected List/*<AbstractStructuredAFPObject>*/ objects = new java.util.ArrayList(); + protected List/*<AbstractStructuredObject>*/ objects = new java.util.ArrayList(); /** The page width */ private int width; @@ -217,10 +214,10 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen * @return the TLEs */ protected List getTagLogicalElements() { - if (tagLogicalElements == null) { - this.tagLogicalElements = new java.util.ArrayList/*<TagLogicalElement>*/(); + if (objects == null) { + this.objects = new java.util.ArrayList/*<AbstractStructuredObject>*/(); } - return this.tagLogicalElements; + return this.objects; } /** diff --git a/src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java b/src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java index 2c5e02328..f8c5a38d3 100644 --- a/src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java +++ b/src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java @@ -126,6 +126,7 @@ implements Streamable { // } /** {@inheritDoc} */ + @Override public void writeToStream(OutputStream os) throws IOException { if (!started) { writeStart(os); @@ -140,6 +141,7 @@ implements Streamable { } /** {@inheritDoc} */ + @Override protected void writeObjects(Collection/*<AbstractAFPObject>*/ objects, OutputStream os) throws IOException { writeObjects(objects, os, false); @@ -176,7 +178,7 @@ implements Streamable { * @return true if this object can be written */ protected boolean canWrite(AbstractAFPObject obj) { - if (obj instanceof AbstractPageObject) { + if (obj instanceof Completable) { return ((Completable)obj).isComplete(); } else { diff --git a/src/java/org/apache/fop/afp/modca/NoOperation.java b/src/java/org/apache/fop/afp/modca/NoOperation.java index cb5841346..cb6f4d60b 100644 --- a/src/java/org/apache/fop/afp/modca/NoOperation.java +++ b/src/java/org/apache/fop/afp/modca/NoOperation.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.OutputStream; import org.apache.fop.afp.AFPConstants; +import org.apache.fop.afp.Completable; import org.apache.fop.afp.util.BinaryUtils; /** @@ -35,7 +36,7 @@ import org.apache.fop.afp.util.BinaryUtils; * No Operation structured fields, no semantics should be attached to * the data carried by the No Operation structured field in interchange */ -public class NoOperation extends AbstractAFPObject { +public class NoOperation extends AbstractAFPObject implements Completable { /** Up to 32759 bytes of data with no architectural definition */ private static final int MAX_DATA_LEN = 32759; @@ -81,7 +82,7 @@ public class NoOperation extends AbstractAFPObject { data[1] = rl1[0]; data[2] = rl1[1]; - // Structured field ID for a TLE + // Structured field ID for a NOP data[3] = (byte) 0xD3; data[4] = (byte) 0xEE; data[5] = (byte) 0xEE; @@ -97,4 +98,20 @@ public class NoOperation extends AbstractAFPObject { os.write(data); } + /** {@inheritDoc} */ + public boolean isComplete() { + return true; //always complete + } + + /** {@inheritDoc} */ + public void setComplete(boolean complete) { + //ignore + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return "NOP: " + content.substring(0, Math.min(64, content.length())); + } + }
\ No newline at end of file diff --git a/src/java/org/apache/fop/afp/modca/Overlay.java b/src/java/org/apache/fop/afp/modca/Overlay.java index 0179c94a7..2793e93f5 100644 --- a/src/java/org/apache/fop/afp/modca/Overlay.java +++ b/src/java/org/apache/fop/afp/modca/Overlay.java @@ -72,7 +72,6 @@ public class Overlay extends PageObject { getActiveEnvironmentGroup().writeToStream(os); - writeObjects(tagLogicalElements, os); writeObjects(objects, os); } diff --git a/src/java/org/apache/fop/afp/modca/PageGroup.java b/src/java/org/apache/fop/afp/modca/PageGroup.java index 895ec1259..aceb0ff80 100644 --- a/src/java/org/apache/fop/afp/modca/PageGroup.java +++ b/src/java/org/apache/fop/afp/modca/PageGroup.java @@ -76,12 +76,6 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { } /** {@inheritDoc} */ - protected void writeContent(OutputStream os) throws IOException { - writeObjects(tagLogicalElements, os, true); - super.writeContent(os); - } - - /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { byte[] data = new byte[17]; copySF(data, Type.BEGIN, Category.PAGE_GROUP); diff --git a/src/java/org/apache/fop/afp/modca/PageObject.java b/src/java/org/apache/fop/afp/modca/PageObject.java index 6c2547f0b..33bfe0997 100644 --- a/src/java/org/apache/fop/afp/modca/PageObject.java +++ b/src/java/org/apache/fop/afp/modca/PageObject.java @@ -185,7 +185,6 @@ public class PageObject extends AbstractResourceGroupContainer { getActiveEnvironmentGroup().writeToStream(os); - writeObjects(tagLogicalElements, os); writeObjects(objects, os); } diff --git a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java index 9de00cd85..9097f23e3 100644 --- a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java +++ b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java @@ -378,15 +378,9 @@ public class FopFactoryConfigurator { private void setBaseURI() throws FOPException { String loc = cfg.getLocation(); - String[] locationParts = (loc != null ? cfg.getLocation().split(":") : null); try { - if (locationParts != null && locationParts.length >= 2 - && "file".equals(locationParts[0])) { - StringBuilder sb = new StringBuilder(locationParts[1]); - for (int idx = 2; idx < locationParts.length; idx++) { - sb.append(":").append(locationParts[idx]); - } - baseURI = new URI(locationParts[0], sb.toString(), null); + if (loc != null && loc.startsWith("file:")) { + baseURI = new URI(loc); baseURI = baseURI.resolve(".").normalize(); } if (baseURI == null) { diff --git a/src/java/org/apache/fop/area/Area.java b/src/java/org/apache/fop/area/Area.java index f94c68454..1f14ed740 100644 --- a/src/java/org/apache/fop/area/Area.java +++ b/src/java/org/apache/fop/area/Area.java @@ -132,7 +132,7 @@ public class Area extends AreaTreeObject implements Serializable { /** * Traits for this area stored in a HashMap */ - protected Map props = null; + protected Map<Integer, Object> props = null; /** * logging instance @@ -239,7 +239,7 @@ public class Area extends AreaTreeObject implements Serializable { Integer padWidth = (Integer) getTrait(Trait.PADDING_BEFORE); if (padWidth != null) { - margin += padWidth.intValue(); + margin += padWidth; } return margin; @@ -260,7 +260,7 @@ public class Area extends AreaTreeObject implements Serializable { Integer padWidth = (Integer) getTrait(Trait.PADDING_AFTER); if (padWidth != null) { - margin += padWidth.intValue(); + margin += padWidth; } return margin; @@ -280,7 +280,7 @@ public class Area extends AreaTreeObject implements Serializable { Integer padWidth = (Integer) getTrait(Trait.PADDING_START); if (padWidth != null) { - margin += padWidth.intValue(); + margin += padWidth; } return margin; @@ -300,7 +300,7 @@ public class Area extends AreaTreeObject implements Serializable { Integer padWidth = (Integer) getTrait(Trait.PADDING_END); if (padWidth != null) { - margin += padWidth.intValue(); + margin += padWidth; } return margin; @@ -315,7 +315,7 @@ public class Area extends AreaTreeObject implements Serializable { int margin = 0; Integer space = (Integer) getTrait(Trait.SPACE_BEFORE); if (space != null) { - margin = space.intValue(); + margin = space; } return margin; } @@ -329,7 +329,7 @@ public class Area extends AreaTreeObject implements Serializable { int margin = 0; Integer space = (Integer) getTrait(Trait.SPACE_AFTER); if (space != null) { - margin = space.intValue(); + margin = space; } return margin; } @@ -343,7 +343,7 @@ public class Area extends AreaTreeObject implements Serializable { int margin = 0; Integer space = (Integer) getTrait(Trait.SPACE_START); if (space != null) { - margin = space.intValue(); + margin = space; } return margin; } @@ -357,7 +357,7 @@ public class Area extends AreaTreeObject implements Serializable { int margin = 0; Integer space = (Integer) getTrait(Trait.SPACE_END); if (space != null) { - margin = space.intValue(); + margin = space; } return margin; } @@ -378,9 +378,9 @@ public class Area extends AreaTreeObject implements Serializable { * @param traitCode the trait key * @param prop the value of the trait */ - public void addTrait(Object traitCode, Object prop) { + public void addTrait(Integer traitCode, Object prop) { if (props == null) { - props = new java.util.HashMap(20); + props = new java.util.HashMap<Integer, Object>(20); } props.put(traitCode, prop); } @@ -390,7 +390,7 @@ public class Area extends AreaTreeObject implements Serializable { * * @return the map of traits */ - public Map getTraits() { + public Map<Integer, Object> getTraits() { return this.props; } @@ -402,44 +402,44 @@ public class Area extends AreaTreeObject implements Serializable { /** * Get a trait from this area. * - * @param oTraitCode the trait key + * @param traitCode the trait key * @return the trait value */ - public Object getTrait(Object oTraitCode) { - return (props != null ? props.get(oTraitCode) : null); + public Object getTrait(Integer traitCode) { + return (props != null ? props.get(traitCode) : null); } /** * Checks whether a certain trait is set on this area. - * @param oTraitCode the trait key + * @param traitCode the trait key * @return true if the trait is set */ - public boolean hasTrait(Object oTraitCode) { - return (getTrait(oTraitCode) != null); + public boolean hasTrait(Integer traitCode) { + return (getTrait(traitCode) != null); } /** * Get a boolean trait from this area. - * @param oTraitCode the trait key + * @param traitCode the trait key * @return the trait value */ - public boolean getTraitAsBoolean(Object oTraitCode) { - return Boolean.TRUE.equals(getTrait(oTraitCode)); + public boolean getTraitAsBoolean(Integer traitCode) { + return Boolean.TRUE.equals(getTrait(traitCode)); } /** * Get a trait from this area as an integer. * - * @param oTraitCode the trait key + * @param traitCode the trait key * @return the trait value */ - public int getTraitAsInteger(Object oTraitCode) { - final Object obj = getTrait(oTraitCode); + public int getTraitAsInteger(Integer traitCode) { + final Object obj = getTrait(traitCode); if (obj instanceof Integer) { - return ((Integer)obj).intValue(); + return (Integer) obj; } else { throw new IllegalArgumentException("Trait " - + oTraitCode.getClass().getName() + + traitCode.getClass().getName() + " could not be converted to an integer"); } } @@ -447,7 +447,8 @@ public class Area extends AreaTreeObject implements Serializable { /** * {@inheritDoc} * @return ipd and bpd of area - * */ + */ + @Override public String toString() { StringBuffer sb = new StringBuffer(super.toString()); sb.append(" {ipd=").append(Integer.toString(getIPD())); diff --git a/src/java/org/apache/fop/area/AreaTreeHandler.java b/src/java/org/apache/fop/area/AreaTreeHandler.java index 87c681ed6..0e2b8bf71 100644 --- a/src/java/org/apache/fop/area/AreaTreeHandler.java +++ b/src/java/org/apache/fop/area/AreaTreeHandler.java @@ -21,7 +21,6 @@ package org.apache.fop.area; // Java import java.io.OutputStream; -import java.util.Iterator; import java.util.List; import org.xml.sax.SAXException; @@ -175,6 +174,7 @@ public class AreaTreeHandler extends FOEventHandler { * @throws SAXException * if there is an error */ + @Override public void startDocument() throws SAXException { // Initialize statistics if (statistics != null) { @@ -194,26 +194,31 @@ public class AreaTreeHandler extends FOEventHandler { } /** {@inheritDoc} */ + @Override public void startPageSequence(PageSequence pageSequence) { startAbstractPageSequence(pageSequence); } private void startAbstractPageSequence(AbstractPageSequence pageSequence) { rootFObj = pageSequence.getRoot(); + + //Before the first page-sequence... + if (this.prevPageSeqLM == null) { + // extension attachments from fo:root + wrapAndAddExtensionAttachments(rootFObj.getExtensionAttachments()); + // extension attachments from fo:declarations + if (rootFObj.getDeclarations() != null) { + wrapAndAddExtensionAttachments( + rootFObj.getDeclarations().getExtensionAttachments()); + } + } + finishPrevPageSequence(pageSequence.getInitialPageNumber()); pageSequence.initPageNumber(); - // extension attachments from fo:root - wrapAndAddExtensionAttachments(rootFObj.getExtensionAttachments()); - // extension attachments from fo:declarations - if (rootFObj.getDeclarations() != null) { - wrapAndAddExtensionAttachments(rootFObj.getDeclarations().getExtensionAttachments()); - } } - private void wrapAndAddExtensionAttachments(List list) { - Iterator it = list.iterator(); - while (it.hasNext()) { - ExtensionAttachment attachment = (ExtensionAttachment) it.next(); + private void wrapAndAddExtensionAttachments(List<ExtensionAttachment> list) { + for (ExtensionAttachment attachment : list) { addOffDocumentItem(new OffDocumentExtensionAttachment(attachment)); } } @@ -224,6 +229,7 @@ public class AreaTreeHandler extends FOEventHandler { * * @param pageSequence the page sequence ending */ + @Override public void endPageSequence(PageSequence pageSequence) { if (statistics != null) { @@ -243,11 +249,13 @@ public class AreaTreeHandler extends FOEventHandler { } /** {@inheritDoc} */ + @Override public void startExternalDocument(ExternalDocument document) { startAbstractPageSequence(document); } /** {@inheritDoc} */ + @Override public void endExternalDocument(ExternalDocument document) { if (statistics != null) { statistics.end(); @@ -282,15 +290,16 @@ public class AreaTreeHandler extends FOEventHandler { * * @throws SAXException if there is some error */ + @Override public void endDocument() throws SAXException { finishPrevPageSequence(null); // process fox:destination elements if (rootFObj != null) { - List destinationList = rootFObj.getDestinationList(); + List<Destination> destinationList = rootFObj.getDestinationList(); if (destinationList != null) { while (destinationList.size() > 0) { - Destination destination = (Destination) destinationList.remove(0); + Destination destination = destinationList.remove(0); DestinationData destinationData = new DestinationData(destination); addOffDocumentItem(destinationData); } @@ -325,15 +334,15 @@ public class AreaTreeHandler extends FOEventHandler { if (odi instanceof Resolvable) { Resolvable res = (Resolvable) odi; String[] ids = res.getIDRefs(); - for (int count = 0; count < ids.length; count++) { - List pageVPList = idTracker.getPageViewportsContainingID(ids[count]); + for (String id : ids) { + List<PageViewport> pageVPList = idTracker.getPageViewportsContainingID(id); if (pageVPList != null) { - res.resolveIDRef(ids[count], pageVPList); + res.resolveIDRef(id, pageVPList); } else { AreaEventProducer eventProducer = AreaEventProducer.Provider.get( getUserAgent().getEventBroadcaster()); - eventProducer.unresolvedIDReference(this, odi.getName(), ids[count]); - idTracker.addUnresolvedIDRef(ids[count], res); + eventProducer.unresolvedIDReference(this, odi.getName(), id); + idTracker.addUnresolvedIDRef(id, res); } } // check to see if ODI is now fully resolved, if so process it @@ -364,6 +373,7 @@ public class AreaTreeHandler extends FOEventHandler { * @param pv a page viewport that contains the area with this ID * @deprecated use getIDTracker().associateIDWithPageViewport(id, pv) instead */ + @Deprecated public void associateIDWithPageViewport(String id, PageViewport pv) { idTracker.associateIDWithPageViewport(id, pv); } @@ -376,6 +386,7 @@ public class AreaTreeHandler extends FOEventHandler { * @param id the id of the object being processed * @deprecated use getIDTracker().signalPendingID(id) instead */ + @Deprecated public void signalPendingID(String id) { idTracker.signalPendingID(id); } @@ -388,6 +399,7 @@ public class AreaTreeHandler extends FOEventHandler { * @param id the id of the formatting object which was just finished * @deprecated use getIDTracker().signalIDProcessed(id) instead */ + @Deprecated public void signalIDProcessed(String id) { idTracker.signalIDProcessed(id); } @@ -399,6 +411,7 @@ public class AreaTreeHandler extends FOEventHandler { * @return true if the ID has been resolved * @deprecated use getIDTracker().alreadyResolvedID(id) instead */ + @Deprecated public boolean alreadyResolvedID(String id) { return idTracker.alreadyResolvedID(id); } @@ -409,18 +422,20 @@ public class AreaTreeHandler extends FOEventHandler { * @param pv page viewport whose ID refs to resolve * @deprecated use getIDTracker().tryIDResolution(pv) instead */ + @Deprecated public void tryIDResolution(PageViewport pv) { idTracker.tryIDResolution(pv); } /** - * Get the list of page viewports that have an area with a given id. + * Get the set 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) { + @Deprecated + public List<PageViewport> getPageViewportsContainingID(String id) { return idTracker.getPageViewportsContainingID(id); } @@ -431,6 +446,7 @@ public class AreaTreeHandler extends FOEventHandler { * @param res the Resolvable object needing the idref to be resolved * @deprecated use getIDTracker().addUnresolvedIDRef(idref, res) instead */ + @Deprecated public void addUnresolvedIDRef(String idref, Resolvable res) { idTracker.addUnresolvedIDRef(idref, res); } diff --git a/src/java/org/apache/fop/area/AreaTreeModel.java b/src/java/org/apache/fop/area/AreaTreeModel.java index 8659b4cca..2a1f14ab5 100644 --- a/src/java/org/apache/fop/area/AreaTreeModel.java +++ b/src/java/org/apache/fop/area/AreaTreeModel.java @@ -36,11 +36,11 @@ import org.apache.commons.logging.LogFactory; * the life of the area tree model. */ public class AreaTreeModel { - private List/*<PageSequence>*/ pageSequenceList = null; - private int currentPageSequenceIndex = -1; + private List<PageSequence> pageSequenceList = null; + private int currentPageIndex = 0; + /** the current page sequence */ protected PageSequence currentPageSequence; -// private List offDocumentItems = new java.util.ArrayList(); /** logger instance */ protected static final Log log = LogFactory.getLog(AreaTreeModel.class); @@ -48,7 +48,7 @@ public class AreaTreeModel { * Create a new store pages model */ public AreaTreeModel() { - pageSequenceList = new java.util.ArrayList/*<PageSequence>*/(); + pageSequenceList = new java.util.ArrayList<PageSequence>(); } /** @@ -59,9 +59,11 @@ public class AreaTreeModel { if (pageSequence == null) { throw new NullPointerException("pageSequence must not be null"); } + if (currentPageSequence != null) { + currentPageIndex += currentPageSequence.getPageCount(); + } this.currentPageSequence = pageSequence; pageSequenceList.add(currentPageSequence); - currentPageSequenceIndex = pageSequenceList.size() - 1; } /** @@ -70,12 +72,8 @@ public class AreaTreeModel { */ public void addPage(PageViewport page) { currentPageSequence.addPage(page); - int pageIndex = 0; - for (int i = 0; i < currentPageSequenceIndex; i++) { - pageIndex += ((PageSequence)pageSequenceList.get(i)).getPageCount(); - } - pageIndex += currentPageSequence.getPageCount() - 1; - page.setPageIndex(pageIndex); + page.setPageIndex(currentPageIndex + + currentPageSequence.getPageCount() - 1); page.setPageSequence(currentPageSequence); } @@ -113,8 +111,7 @@ public class AreaTreeModel { * @return returns the number of pages in a page sequence */ public int getPageCount(int seq) { - PageSequence sequence = (PageSequence)pageSequenceList.get(seq - 1); - return sequence.getPageCount(); + return pageSequenceList.get(seq - 1).getPageCount(); } /** @@ -124,7 +121,6 @@ public class AreaTreeModel { * @return the PageViewport for the particular page */ public PageViewport getPage(int seq, int count) { - PageSequence sequence = (PageSequence)pageSequenceList.get(seq - 1); - return sequence.getPage(count); + return pageSequenceList.get(seq - 1).getPage(count); } } diff --git a/src/java/org/apache/fop/area/AreaTreeObject.java b/src/java/org/apache/fop/area/AreaTreeObject.java index bab27f411..dbbfc5744 100644 --- a/src/java/org/apache/fop/area/AreaTreeObject.java +++ b/src/java/org/apache/fop/area/AreaTreeObject.java @@ -34,10 +34,10 @@ import org.apache.fop.fo.extensions.ExtensionAttachment; public abstract class AreaTreeObject { /** Foreign attributes */ - protected Map foreignAttributes = null; + protected Map<QName, String> foreignAttributes = null; /** Extension attachments */ - protected List/*<ExtensionAttachment>*/ extensionAttachments = null; + protected List<ExtensionAttachment> extensionAttachments = null; /** * Sets a foreign attribute. @@ -46,25 +46,22 @@ public abstract class AreaTreeObject { */ public void setForeignAttribute(QName name, String value) { if (this.foreignAttributes == null) { - this.foreignAttributes = new java.util.HashMap(); + this.foreignAttributes = new java.util.HashMap<QName, String>(); } this.foreignAttributes.put(name, value); } /** - * Set foreign attributes from a Map. + * Add foreign attributes from a Map. + * * @param atts a Map with attributes (keys: QName, values: String) */ - public void setForeignAttributes(Map atts) { - if (atts.size() == 0) { + public void setForeignAttributes(Map<QName, String> atts) { + if (atts == null || atts.size() == 0) { return; } - Iterator iter = atts.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry)iter.next(); - String value = (String)entry.getValue(); - //The casting is only to ensure type safety (too bad we can't use generics, yet) - setForeignAttribute((QName)entry.getKey(), value); + for (Map.Entry<QName, String> e : atts.entrySet()) { + setForeignAttribute(e.getKey(), e.getValue()); } } @@ -75,24 +72,24 @@ public abstract class AreaTreeObject { */ public String getForeignAttributeValue(QName name) { if (this.foreignAttributes != null) { - return (String)this.foreignAttributes.get(name); + return this.foreignAttributes.get(name); } else { return null; } } /** @return the foreign attributes associated with this area */ - public Map getForeignAttributes() { + public Map<QName, String> getForeignAttributes() { if (this.foreignAttributes != null) { return Collections.unmodifiableMap(this.foreignAttributes); } else { - return Collections.EMPTY_MAP; + return Collections.emptyMap(); } } private void prepareExtensionAttachmentContainer() { if (this.extensionAttachments == null) { - this.extensionAttachments = new java.util.ArrayList/*<ExtensionAttachment>*/(); + this.extensionAttachments = new java.util.ArrayList<ExtensionAttachment>(); } } @@ -109,17 +106,17 @@ public abstract class AreaTreeObject { * Set extension attachments from a List * @param extensionAttachments a List with extension attachments */ - public void setExtensionAttachments(List extensionAttachments) { + public void setExtensionAttachments(List<ExtensionAttachment> extensionAttachments) { prepareExtensionAttachmentContainer(); this.extensionAttachments.addAll(extensionAttachments); } /** @return the extension attachments associated with this area */ - public List getExtensionAttachments() { + public List<ExtensionAttachment> getExtensionAttachments() { if (this.extensionAttachments != null) { return Collections.unmodifiableList(this.extensionAttachments); } else { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } } diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java index ae7c0a7c3..6c82257f3 100644 --- a/src/java/org/apache/fop/area/AreaTreeParser.java +++ b/src/java/org/apache/fop/area/AreaTreeParser.java @@ -75,7 +75,6 @@ import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.Viewport; import org.apache.fop.area.inline.WordArea; -import org.apache.fop.fo.Constants; import org.apache.fop.fo.ElementMappingRegistry; import org.apache.fop.fo.expr.PropertyException; import org.apache.fop.fo.extensions.ExtensionAttachment; @@ -91,6 +90,12 @@ import org.apache.fop.util.DelegatingContentHandler; import org.apache.fop.util.XMLConstants; import org.apache.fop.util.XMLUtil; +import static org.apache.fop.fo.Constants.FO_REGION_AFTER; +import static org.apache.fop.fo.Constants.FO_REGION_BEFORE; +import static org.apache.fop.fo.Constants.FO_REGION_BODY; +import static org.apache.fop.fo.Constants.FO_REGION_END; +import static org.apache.fop.fo.Constants.FO_REGION_START; + /** * This is a parser for the area tree XML (intermediate format) which is used to reread an area * tree (or part of it) into memory again for rendering to the final output format. @@ -136,7 +141,7 @@ public class AreaTreeParser { private static class Handler extends DefaultHandler { - private Map makers = new java.util.HashMap(); + private Map<String, AbstractMaker> makers = new java.util.HashMap<String, AbstractMaker>(); private AreaTreeModel treeModel; private FOUserAgent userAgent; @@ -148,14 +153,15 @@ public class AreaTreeParser { private boolean ignoreCharacters = true; private PageViewport currentPageViewport; - private Map pageViewportsByKey = new java.util.HashMap(); + private Map<String, PageViewport> pageViewportsByKey + = new java.util.HashMap<String, PageViewport>(); // set of "ID firsts" that have already been assigned to a PV: - private Set idFirstsAssigned = new java.util.HashSet(); + private Set<String> idFirstsAssigned = new java.util.HashSet<String>(); - private Stack areaStack = new Stack(); + private Stack<Object> areaStack = new Stack<Object>(); private boolean firstFlow; - private Stack delegateStack = new Stack(); + private Stack<String> delegateStack = new Stack<String>(); private ContentHandler delegate; private DOMImplementation domImplementation; private Locator locator; @@ -228,9 +234,9 @@ public class AreaTreeParser { if (areaStack.size() > 0) { int pos = areaStack.size() - 1; Object obj = null; - while ( pos >= 0 ) { + while (pos >= 0) { obj = areaStack.get(pos); - if ( clazz.isInstance ( obj ) ) { + if (clazz.isInstance(obj)) { break; } else { pos--; @@ -358,7 +364,7 @@ public class AreaTreeParser { private boolean startAreaTreeElement(String localName, Attributes attributes) throws SAXException { lastAttributes = new AttributesImpl(attributes); - Maker maker = (Maker)makers.get(localName); + Maker maker = makers.get(localName); content.clear(); ignoreCharacters = true; if (maker != null) { @@ -387,7 +393,7 @@ public class AreaTreeParser { } } else { if ("".equals(uri)) { - Maker maker = (Maker)makers.get(localName); + Maker maker = makers.get(localName); if (maker != null) { maker.endElement(); content.clear(); @@ -525,7 +531,7 @@ public class AreaTreeParser { private class RegionBeforeMaker extends AbstractMaker { public void startElement(Attributes attributes) { - pushNewRegionReference(attributes, Constants.FO_REGION_BEFORE); + pushNewRegionReference(attributes, FO_REGION_BEFORE); } public void endElement() { @@ -536,7 +542,7 @@ public class AreaTreeParser { private class RegionAfterMaker extends AbstractMaker { public void startElement(Attributes attributes) { - pushNewRegionReference(attributes, Constants.FO_REGION_AFTER); + pushNewRegionReference(attributes, FO_REGION_AFTER); } public void endElement() { @@ -547,7 +553,7 @@ public class AreaTreeParser { private class RegionStartMaker extends AbstractMaker { public void startElement(Attributes attributes) { - pushNewRegionReference(attributes, Constants.FO_REGION_START); + pushNewRegionReference(attributes, FO_REGION_START); } public void endElement() { @@ -558,7 +564,7 @@ public class AreaTreeParser { private class RegionEndMaker extends AbstractMaker { public void startElement(Attributes attributes) { - pushNewRegionReference(attributes, Constants.FO_REGION_END); + pushNewRegionReference(attributes, FO_REGION_END); } public void endElement() { @@ -577,15 +583,13 @@ public class AreaTreeParser { int columnCount = XMLUtil.getAttributeAsInt(attributes, "columnCount", 1); int columnGap = XMLUtil.getAttributeAsInt(attributes, "columnGap", 0); RegionViewport rv = getCurrentRegionViewport(); - body = new BodyRegion(Constants.FO_REGION_BODY, - regionName, rv, columnCount, columnGap); + body = new BodyRegion(FO_REGION_BODY, regionName, rv, columnCount, columnGap); transferForeignObjects(attributes, body); body.setCTM(getAttributeAsCTM(attributes, "ctm")); setAreaAttributes(attributes, body); setTraits(attributes, body, SUBSET_BORDER_PADDING); rv.setRegionReference(body); - currentPageViewport.getPage().setRegionViewport( - Constants.FO_REGION_BODY, rv); + currentPageViewport.getPage().setRegionViewport(FO_REGION_BODY, rv); areaStack.push(body); } @@ -982,7 +986,7 @@ public class AreaTreeParser { attributes, "show-children", false); String[] linkdata = InternalLink.parseXMLAttribute(attributes.getValue("internal-link")); - PageViewport pv = (PageViewport) pageViewportsByKey.get(linkdata[0]); + PageViewport pv = pageViewportsByKey.get(linkdata[0]); BookmarkData bm = new BookmarkData(title, showChildren, pv, linkdata[1]); Object tos = areaStack.peek(); if (tos instanceof BookmarkData) { @@ -1002,9 +1006,9 @@ public class AreaTreeParser { public void startElement(Attributes attributes) { String[] linkdata = InternalLink.parseXMLAttribute(lastAttributes.getValue("internal-link")); - PageViewport pv = (PageViewport) pageViewportsByKey.get(linkdata[0]); + PageViewport pv = pageViewportsByKey.get(linkdata[0]); DestinationData dest = new DestinationData(linkdata[1]); - List pages = new java.util.ArrayList(); + List<PageViewport> pages = new java.util.ArrayList<PageViewport>(); pages.add(pv); dest.resolveIDRef(linkdata[1], pages); areaStack.push(dest); @@ -1096,7 +1100,7 @@ public class AreaTreeParser { private void setTraits(Attributes attributes, Area area, Object[] traitSubset) { for (int i = traitSubset.length; --i >= 0;) { - Object trait = traitSubset[i]; + Integer trait = (Integer) traitSubset[i]; String traitName = Trait.getTraitName(trait); String value = attributes.getValue(traitName); if (value != null) { @@ -1107,7 +1111,7 @@ public class AreaTreeParser { area.addTrait(trait, Boolean.valueOf(value)); } else if (cl == String.class) { area.addTrait(trait, value); - if (trait == Trait.PROD_ID + if (Trait.PROD_ID.equals(trait) && !idFirstsAssigned.contains(value) && currentPageViewport != null) { currentPageViewport.setFirstWithID(value); @@ -1173,7 +1177,7 @@ public class AreaTreeParser { area.addTrait(trait, BorderProps.valueOf(this.userAgent, value)); } } else { - if (trait == Trait.FONT) { + if (Trait.FONT.equals(trait)) { String fontName = attributes.getValue("font-name"); if (fontName != null) { String fontStyle = attributes.getValue("font-style"); diff --git a/src/java/org/apache/fop/area/BeforeFloat.java b/src/java/org/apache/fop/area/BeforeFloat.java index b64eff556..c4d7e21d6 100644 --- a/src/java/org/apache/fop/area/BeforeFloat.java +++ b/src/java/org/apache/fop/area/BeforeFloat.java @@ -57,6 +57,7 @@ public class BeforeFloat extends BlockParent { * * @return the height of the before float including separator */ + @Override public int getBPD() { int h = super.getBPD(); if (separator != null) { @@ -66,6 +67,7 @@ public class BeforeFloat extends BlockParent { } /** {@inheritDoc} */ + @Override public boolean isEmpty() { return true; // before floats are not yet implemented } diff --git a/src/java/org/apache/fop/area/BlockParent.java b/src/java/org/apache/fop/area/BlockParent.java index 18f9056da..5a64d52cf 100644 --- a/src/java/org/apache/fop/area/BlockParent.java +++ b/src/java/org/apache/fop/area/BlockParent.java @@ -50,15 +50,13 @@ public class BlockParent extends Area { /** * The children of this block parent area. */ - protected List children = null; - - // orientation if reference area -// private int orientation = ORIENT_0; + protected List<Area> children = null; /** {@inheritDoc} */ + @Override public void addChildArea(Area childArea) { if (children == null) { - children = new ArrayList(); + children = new ArrayList<Area>(); } children.add(childArea); } diff --git a/src/java/org/apache/fop/area/BookmarkData.java b/src/java/org/apache/fop/area/BookmarkData.java index 28ee2c23e..727040a3c 100644 --- a/src/java/org/apache/fop/area/BookmarkData.java +++ b/src/java/org/apache/fop/area/BookmarkData.java @@ -19,8 +19,6 @@ package org.apache.fop.area; -import java.util.Collection; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -34,13 +32,13 @@ import org.apache.fop.fo.pagination.bookmarks.BookmarkTree; */ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable { - private List subData = new java.util.ArrayList(); + private List<BookmarkData> subData = new java.util.ArrayList<BookmarkData>(); // bookmark-title for this fo:bookmark private String bookmarkTitle = null; // indicator of whether to initially display/hide child bookmarks of this object - private boolean bShow = true; + private boolean showChildren = true; // ID Reference for this bookmark private String idRef; @@ -49,7 +47,8 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable private PageViewport pageRef = null; // unresolved idrefs by this bookmark and child bookmarks below it - private Map unresolvedIDRefs = new java.util.HashMap(); + private Map<String, List<Resolvable>> unresolvedIDRefs + = new java.util.HashMap<String, List<Resolvable>>(); /** * Create a new bookmark data object. @@ -59,10 +58,10 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable * @param bookmarkTree fo:bookmark-tree for this document */ public BookmarkData(BookmarkTree bookmarkTree) { - idRef = null; - whenToProcess = END_OF_DOC; + this.idRef = null; + this.whenToProcess = END_OF_DOC; // top level defined in Rec to show all child bookmarks - bShow = true; + this.showChildren = true; for (int count = 0; count < bookmarkTree.getBookmarks().size(); count++) { Bookmark bkmk = (Bookmark)(bookmarkTree.getBookmarks()).get(count); @@ -79,15 +78,15 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable * @param bookmark the fo:bookmark object */ public BookmarkData(Bookmark bookmark) { - bookmarkTitle = bookmark.getBookmarkTitle(); - bShow = bookmark.showChildItems(); + this.bookmarkTitle = bookmark.getBookmarkTitle(); + this.showChildren = bookmark.showChildItems(); this.idRef = bookmark.getInternalDestination(); } private void putUnresolved(String id, BookmarkData bd) { - List refs = (List)unresolvedIDRefs.get(id); + List<Resolvable> refs = unresolvedIDRefs.get(id); if (refs == null) { - refs = new java.util.ArrayList(); + refs = new java.util.ArrayList<Resolvable>(); unresolvedIDRefs.put(id, refs); } refs.add(bd); @@ -101,7 +100,7 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable public BookmarkData() { idRef = null; whenToProcess = END_OF_DOC; - bShow = true; + showChildren = true; } /** @@ -116,7 +115,7 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable */ public BookmarkData(String title, boolean showChildren, PageViewport pv, String idRef) { bookmarkTitle = title; - bShow = showChildren; + this.showChildren = showChildren; pageRef = pv; this.idRef = idRef; } @@ -138,11 +137,11 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable */ public void addSubData(BookmarkData sub) { subData.add(sub); - if (sub.pageRef == null || sub.pageRef.equals("")) { + if (sub.pageRef == null) { putUnresolved(sub.getIDRef(), sub); String[] ids = sub.getIDRefs(); - for (int count = 0; count < ids.length; count++) { - putUnresolved(ids[count], sub); + for (String id : ids) { + putUnresolved(id, sub); } } } @@ -162,7 +161,7 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable * @return true to initially display child bookmarks, false otherwise */ public boolean showChildItems() { - return bShow; + return showChildren; } /** @@ -181,7 +180,7 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable * @return the child bookmark data */ public BookmarkData getSubData(int count) { - return (BookmarkData) subData.get(count); + return subData.get(count); } /** @@ -208,7 +207,8 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable * {@inheritDoc} */ public String[] getIDRefs() { - return (String[])unresolvedIDRefs.keySet().toArray(new String[] {}); + return unresolvedIDRefs.keySet().toArray( + new String[unresolvedIDRefs.keySet().size()]); } /** @@ -217,22 +217,20 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable * resolves id references of child elements that have the same * id reference. * - * {@inheritDoc} List) + * {@inheritDoc} */ - public void resolveIDRef(String id, List pages) { + public void resolveIDRef(String id, List<PageViewport> pages) { if (id.equals(idRef)) { //Own ID has been resolved, so note the page - pageRef = (PageViewport) pages.get(0); + pageRef = pages.get(0); //Note: Determining the placement inside the page is the renderer's job. } //Notify all child bookmarks - Collection refs = (Collection)unresolvedIDRefs.get(id); + List<Resolvable> refs = unresolvedIDRefs.get(id); if (refs != null) { - Iterator iter = refs.iterator(); - while (iter.hasNext()) { - BookmarkData bd = (BookmarkData)iter.next(); - bd.resolveIDRef(id, pages); + for (Resolvable res : refs) { + res.resolveIDRef(id, pages); } } unresolvedIDRefs.remove(id); diff --git a/src/java/org/apache/fop/area/CTM.java b/src/java/org/apache/fop/area/CTM.java index eb6207c42..07c3bbc02 100644 --- a/src/java/org/apache/fop/area/CTM.java +++ b/src/java/org/apache/fop/area/CTM.java @@ -25,7 +25,10 @@ import java.awt.geom.Rectangle2D; import java.io.Serializable; import org.apache.fop.datatypes.FODimension; -import org.apache.fop.fo.Constants; + +import static org.apache.fop.fo.Constants.EN_LR_TB; +import static org.apache.fop.fo.Constants.EN_RL_TB; +import static org.apache.fop.fo.Constants.EN_TB_RL; /** * Describe a PDF or PostScript style coordinate transformation matrix (CTM). @@ -133,14 +136,14 @@ public class CTM implements Serializable { public static CTM getWMctm(int wm, int ipd, int bpd) { CTM wmctm; switch (wm) { - case Constants.EN_LR_TB: + case EN_LR_TB: return new CTM(CTM_LRTB); - case Constants.EN_RL_TB: + case EN_RL_TB: wmctm = new CTM(CTM_RLTB); wmctm.e = ipd; return wmctm; //return CTM_RLTB.translate(ipd, 0); - case Constants.EN_TB_RL: // CJK + case EN_TB_RL: // CJK wmctm = new CTM(CTM_TBRL); wmctm.e = bpd; return wmctm; @@ -157,13 +160,12 @@ public class CTM implements Serializable { * @return CTM The result of multiplying premult * this. */ public CTM multiply(CTM premult) { - CTM result = new CTM ((premult.a * a) + (premult.b * c), + return new CTM ((premult.a * a) + (premult.b * c), (premult.a * b) + (premult.b * d), (premult.c * a) + (premult.d * c), (premult.c * b) + (premult.d * d), (premult.e * a) + (premult.f * c) + e, (premult.e * b) + (premult.f * d) + f); - return result; } /** @@ -249,6 +251,7 @@ public class CTM implements Serializable { * * @return a string with the transform values */ + @Override public String toString() { return "[" + a + " " + b + " " + c + " " + d + " " + e + " " + f + "]"; @@ -332,7 +335,7 @@ public class CTM implements Serializable { * can set ipd and bpd appropriately based on the writing mode. */ - if (writingMode == Constants.EN_LR_TB || writingMode == Constants.EN_RL_TB) { + if (writingMode == EN_LR_TB || writingMode == EN_RL_TB) { reldims.ipd = width; reldims.bpd = height; } else { diff --git a/src/java/org/apache/fop/area/CachedRenderPagesModel.java b/src/java/org/apache/fop/area/CachedRenderPagesModel.java index 729ca0c65..288884a55 100644 --- a/src/java/org/apache/fop/area/CachedRenderPagesModel.java +++ b/src/java/org/apache/fop/area/CachedRenderPagesModel.java @@ -48,7 +48,8 @@ import org.apache.fop.fonts.FontInfo; * the contents are reloaded. */ public class CachedRenderPagesModel extends RenderPagesModel { - private Map pageMap = new HashMap(); + + private Map<PageViewport, String> pageMap = new HashMap<PageViewport, String>(); /** Base directory to save temporary file in, typically points to the user's temp dir. */ protected File baseDir; @@ -64,12 +65,12 @@ public class CachedRenderPagesModel extends RenderPagesModel { public CachedRenderPagesModel (FOUserAgent userAgent, String outputFormat, FontInfo fontInfo, OutputStream stream) throws FOPException { super(userAgent, outputFormat, fontInfo, stream); + //TODO: Avoid System.getProperty()? this.baseDir = new File(System.getProperty("java.io.tmpdir")); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override protected boolean checkPreparedPages(PageViewport newpage, boolean renderUnresolved) { for (Iterator iter = prepared.iterator(); iter.hasNext();) { PageViewport pageViewport = (PageViewport)iter.next(); @@ -77,7 +78,7 @@ public class CachedRenderPagesModel extends RenderPagesModel { if (pageViewport != newpage) { try { // load page from cache - String name = (String)pageMap.get(pageViewport); + String name = pageMap.get(pageViewport); File tempFile = new File(baseDir, name); log.debug("Loading page from: " + tempFile); ObjectInputStream in = new ObjectInputStream( @@ -152,6 +153,7 @@ public class CachedRenderPagesModel extends RenderPagesModel { } /** {@inheritDoc} */ + @Override public void endDocument() throws SAXException { super.endDocument(); } diff --git a/src/java/org/apache/fop/area/DestinationData.java b/src/java/org/apache/fop/area/DestinationData.java index f8d906b91..5797e41df 100644 --- a/src/java/org/apache/fop/area/DestinationData.java +++ b/src/java/org/apache/fop/area/DestinationData.java @@ -66,9 +66,7 @@ public class DestinationData extends AbstractOffDocumentItem implements Resolvab return idRef; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String[] getIDRefs() { return idRefs; } @@ -97,12 +95,12 @@ public class DestinationData extends AbstractOffDocumentItem implements Resolvab * Resolves the idref of this object by getting the PageViewport * object that corresponds to the IDRef * - * {@inheritDoc} List) + * {@inheritDoc} * TODO check to make sure it works if multiple bookmark-items * have the same idref */ - public void resolveIDRef(String id, List pages) { - pageRef = (PageViewport) pages.get(0); + public void resolveIDRef(String id, List<PageViewport> pages) { + pageRef = pages.get(0); // TODO get rect area of id on page } diff --git a/src/java/org/apache/fop/area/Footnote.java b/src/java/org/apache/fop/area/Footnote.java index 72b9f2ed0..bc9f27b24 100644 --- a/src/java/org/apache/fop/area/Footnote.java +++ b/src/java/org/apache/fop/area/Footnote.java @@ -80,6 +80,7 @@ public class Footnote extends BlockParent { * * @param child the block area. */ + @Override public void addBlock(Block child) { addChildArea(child); this.setBPD(this.getBPD() + child.getBPD()); diff --git a/src/java/org/apache/fop/area/IDTracker.java b/src/java/org/apache/fop/area/IDTracker.java index 829c8c58d..0986891f8 100644 --- a/src/java/org/apache/fop/area/IDTracker.java +++ b/src/java/org/apache/fop/area/IDTracker.java @@ -19,8 +19,7 @@ package org.apache.fop.area; -import java.util.ArrayList; -import java.util.Iterator; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -36,18 +35,20 @@ public class IDTracker { private static final 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 + // Map of ID's whose area is located on one or more consecutive + // PageViewports. Each ID has a list of PageViewports that // form the defined area of this ID - private Map idLocations = new java.util.HashMap(); + private Map<String, List<PageViewport>> idLocations + = new java.util.HashMap<String, List<PageViewport>>(); // 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 java.util.HashMap(); + private Map<String, Set<Resolvable>> unresolvedIDRefs + = new java.util.HashMap<String, Set<Resolvable>>(); - private Set unfinishedIDs = new java.util.HashSet(); + private Set<String> unfinishedIDs = new java.util.HashSet<String>(); - private Set alreadyResolvedIDs = new java.util.HashSet(); + private Set<String> alreadyResolvedIDs = new java.util.HashSet<String>(); /** * Tie a PageViewport with an ID found on a child area of the PV. Note that @@ -61,9 +62,9 @@ public class IDTracker { if (LOG.isDebugEnabled()) { LOG.debug("associateIDWithPageViewport(" + id + ", " + pv + ")"); } - List pvList = (List) idLocations.get(id); + List<PageViewport> pvList = idLocations.get(id); if (pvList == null) { // first time ID located - pvList = new ArrayList(); + pvList = new java.util.ArrayList<PageViewport>(); idLocations.put(id, pvList); pvList.add(pv); // signal the PageViewport that it is the first PV to contain this id: @@ -73,7 +74,7 @@ public class IDTracker { * Resolvable objects tied to it. */ if (!unfinishedIDs.contains(id)) { - tryIDResolution(id, pv, pvList); + tryIDResolution(id, pvList); } } else { /* TODO: The check is a quick-fix to avoid a waste @@ -116,12 +117,11 @@ public class IDTracker { } unfinishedIDs.remove(id); - List pvList = (List) idLocations.get(id); - Set todo = (Set) unresolvedIDRefs.get(id); + List<PageViewport> idLocs = idLocations.get(id); + Set<Resolvable> todo = unresolvedIDRefs.get(id); if (todo != null) { - for (Iterator iter = todo.iterator(); iter.hasNext();) { - Resolvable res = (Resolvable) iter.next(); - res.resolveIDRef(id, pvList); + for (Resolvable res : todo) { + res.resolveIDRef(id, idLocs); } unresolvedIDRefs.remove(id); } @@ -138,17 +138,15 @@ public class IDTracker { } /** - * Tries to resolve all unresolved ID references on the given page. + * Tries to resolve all unresolved ID references on the given set of pages. * * @param id ID to resolve - * @param pv page viewport whose ID refs to resolve - * @param pvList of PageViewports + * @param pvList list of PageViewports */ - private void tryIDResolution(String id, PageViewport pv, List pvList) { - Set todo = (Set) unresolvedIDRefs.get(id); + private void tryIDResolution(String id, List<PageViewport> pvList) { + Set<Resolvable> todo = unresolvedIDRefs.get(id); if (todo != null) { - for (Iterator iter = todo.iterator(); iter.hasNext();) { - Resolvable res = (Resolvable) iter.next(); + for (Resolvable res : todo) { if (!unfinishedIDs.contains(id)) { res.resolveIDRef(id, pvList); } else { @@ -168,10 +166,10 @@ public class IDTracker { 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); + for (String id : ids) { + List<PageViewport> pvList = idLocations.get(id); + if (!(pvList == null || pvList.isEmpty())) { + tryIDResolution(id, pvList); } } } @@ -183,8 +181,46 @@ public class IDTracker { * @param id the id to lookup * @return the list of PageViewports */ - public List getPageViewportsContainingID(String id) { - return (List) idLocations.get(id); + public List<PageViewport> getPageViewportsContainingID(String id) { + if (!(idLocations == null || idLocations.isEmpty())) { + List<PageViewport> idLocs = idLocations.get(id); + if (idLocs != null) { + return idLocs; + } + } + return Collections.emptyList(); + } + + /** + * Get the first {@link PageViewport} containing content generated + * by the FO with the given {@code id}. + * + * @param id the id + * @return the first {@link PageViewport} for the id; {@code null} if + * no matching {@link PageViewport} was found + */ + public PageViewport getFirstPageViewportContaining(String id) { + List<PageViewport> list = getPageViewportsContainingID(id); + if (!(list == null || list.isEmpty())) { + return list.get(0); + } + return null; + } + + /** + * Get the last {@link PageViewport} containing content generated + * by the FO with the given {@code id}. + * + * @param id the id + * @return the last {@link PageViewport} for the id; {@code null} if + * no matching {@link PageViewport} was found + */ + public PageViewport getLastPageViewportContaining(String id) { + List<PageViewport> list = getPageViewportsContainingID(id); + if (!(list == null || list.isEmpty())) { + return list.get(list.size() - 1); + } + return null; } /** @@ -194,9 +230,9 @@ public class IDTracker { * @param res the Resolvable object needing the idref to be resolved */ public void addUnresolvedIDRef(String idref, Resolvable res) { - Set todo = (Set) unresolvedIDRefs.get(idref); + Set<Resolvable> todo = unresolvedIDRefs.get(idref); if (todo == null) { - todo = new java.util.HashSet(); + todo = new java.util.HashSet<Resolvable>(); unresolvedIDRefs.put(idref, todo); } // add Resolvable object to this HashSet diff --git a/src/java/org/apache/fop/area/LineArea.java b/src/java/org/apache/fop/area/LineArea.java index b33b5da14..edf60578a 100644 --- a/src/java/org/apache/fop/area/LineArea.java +++ b/src/java/org/apache/fop/area/LineArea.java @@ -24,7 +24,11 @@ import java.util.ArrayList; import java.util.List; import org.apache.fop.area.inline.InlineArea; -import org.apache.fop.fo.Constants; + +import static org.apache.fop.fo.Constants.EN_START; +import static org.apache.fop.fo.Constants.EN_CENTER; +import static org.apache.fop.fo.Constants.EN_END; +import static org.apache.fop.fo.Constants.EN_JUSTIFY; /** * The line area. @@ -75,7 +79,7 @@ public class LineArea extends Area { // this class can contain the dominant char styling info // this means that many renderers can optimise a bit - private List inlineAreas = new ArrayList(); + private List<InlineArea> inlineAreas = new ArrayList<InlineArea>(); /** * default constructor: @@ -102,11 +106,12 @@ public class LineArea extends Area { * * @param childArea the inline child area to add */ + @Override public void addChildArea(Area childArea) { if (childArea instanceof InlineArea) { addInlineArea((InlineArea)childArea); // set the parent area for the child area - ((InlineArea) childArea).setParentArea(this); + ((InlineArea)childArea).setParentArea(this); } } @@ -150,8 +155,8 @@ public class LineArea extends Area { int ipd = 0; int bpd = 0; for (int i = 0, len = inlineAreas.size(); i < len; i++) { - ipd = Math.max(ipd, ((InlineArea)inlineAreas.get(i)).getAllocIPD()); - bpd += ((InlineArea)inlineAreas.get(i)).getAllocBPD(); + ipd = Math.max(ipd, inlineAreas.get(i).getAllocIPD()); + bpd += inlineAreas.get(i).getAllocBPD(); } setIPD(ipd); setBPD(bpd); @@ -174,18 +179,18 @@ public class LineArea extends Area { */ public void handleIPDVariation(int ipdVariation) { switch (adjustingInfo.lineAlignment) { - case Constants.EN_START: + case EN_START: // nothing to do in this case break; - case Constants.EN_CENTER: + case EN_CENTER: // re-compute indent - addTrait(Trait.START_INDENT, new Integer(getStartIndent() - ipdVariation / 2)); + addTrait(Trait.START_INDENT, getStartIndent() - ipdVariation / 2); break; - case Constants.EN_END: + case EN_END: // re-compute indent - addTrait(Trait.START_INDENT, new Integer(getStartIndent() - ipdVariation)); + addTrait(Trait.START_INDENT, getStartIndent() - ipdVariation); break; - case Constants.EN_JUSTIFY: + case EN_JUSTIFY: // compute variation factor adjustingInfo.variationFactor *= (float) (adjustingInfo.difference - ipdVariation) / adjustingInfo.difference; @@ -207,7 +212,7 @@ public class LineArea extends Area { * no UnresolvedAreas left */ public void finalise() { - if (adjustingInfo.lineAlignment == Constants.EN_JUSTIFY) { + if (adjustingInfo.lineAlignment == EN_JUSTIFY) { if (log.isTraceEnabled()) { log.trace("Applying variation factor to justified line: " + adjustingInfo); } diff --git a/src/java/org/apache/fop/area/LinkResolver.java b/src/java/org/apache/fop/area/LinkResolver.java index 70bdfdf91..1e135701f 100644 --- a/src/java/org/apache/fop/area/LinkResolver.java +++ b/src/java/org/apache/fop/area/LinkResolver.java @@ -23,12 +23,6 @@ package org.apache.fop.area; import java.util.List; import java.io.Serializable; -// FOP -import org.apache.fop.area.Trait; -import org.apache.fop.area.Resolvable; -import org.apache.fop.area.PageViewport; -import org.apache.fop.area.Area; - /** * Link resolving for resolving internal links. */ @@ -72,8 +66,8 @@ public class LinkResolver implements Resolvable, Serializable { * * {@inheritDoc} */ - public void resolveIDRef(String id, List pages) { - resolveIDRef(id, (PageViewport)pages.get(0)); + public void resolveIDRef(String id, List<PageViewport> pages) { + resolveIDRef(id, pages.get(0)); } /** diff --git a/src/java/org/apache/fop/area/MainReference.java b/src/java/org/apache/fop/area/MainReference.java index 87e594169..a6112011d 100644 --- a/src/java/org/apache/fop/area/MainReference.java +++ b/src/java/org/apache/fop/area/MainReference.java @@ -34,7 +34,7 @@ public class MainReference extends Area { private static final long serialVersionUID = 7635126485620012448L; private BodyRegion parent; - private List spanAreas = new java.util.ArrayList(); + private List<Span> spanAreas = new java.util.ArrayList<Span>(); private boolean isEmpty = true; /** @@ -59,7 +59,7 @@ public class MainReference extends Area { spanAreas.remove(spanAreas.size() - 1); } RegionViewport rv = parent.getRegionViewport(); - int ipdWidth = (int) parent.getIPD() + int ipdWidth = parent.getIPD() - rv.getBorderAndPaddingWidthStart() - rv.getBorderAndPaddingWidthEnd(); Span newSpan = new Span(((spanAll) ? 1 : getColumnCount()), @@ -84,8 +84,8 @@ public class MainReference extends Area { * * @param spans content already laid out */ - public void setSpans(List spans) { - spanAreas = new ArrayList(spans); + public void setSpans(List<Span> spans) { + spanAreas = new ArrayList<Span>(spans); } /** @@ -93,7 +93,7 @@ public class MainReference extends Area { * @return the active span. */ public Span getCurrentSpan() { - return (Span) spanAreas.get(spanAreas.size() - 1); + return spanAreas.get(spanAreas.size() - 1); } /** @@ -103,16 +103,13 @@ public class MainReference extends Area { * @return true if no child areas have been added yet. */ public boolean isEmpty() { - if (isEmpty) { - boolean nonEmptyFound = false; - if (spanAreas != null) { - for (Iterator spaniter = spanAreas.iterator(); spaniter.hasNext();) { - Span spanArea = (Span) spaniter.next(); - nonEmptyFound |= !spanArea.isEmpty(); + if (isEmpty && spanAreas != null) { + for (Span spanArea : spanAreas) { + if (!spanArea.isEmpty()) { + isEmpty = false; + break; } } - - isEmpty = !nonEmptyFound; } return isEmpty; } diff --git a/src/java/org/apache/fop/area/Page.java b/src/java/org/apache/fop/area/Page.java index 715bcfe85..a1d9e389f 100644 --- a/src/java/org/apache/fop/area/Page.java +++ b/src/java/org/apache/fop/area/Page.java @@ -22,19 +22,26 @@ package org.apache.fop.area; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import java.io.Serializable; -import java.util.Iterator; +import java.util.List; import java.util.Map; import org.apache.fop.datatypes.FODimension; import org.apache.fop.datatypes.LengthBase; import org.apache.fop.datatypes.SimplePercentBaseContext; -import org.apache.fop.fo.Constants; import org.apache.fop.fo.pagination.Region; import org.apache.fop.fo.pagination.RegionBody; import org.apache.fop.fo.pagination.SimplePageMaster; import org.apache.fop.fo.properties.CommonMarginBlock; import org.apache.fop.layoutmgr.TraitSetter; +import static org.apache.fop.fo.Constants.FO_REGION_AFTER; +import static org.apache.fop.fo.Constants.FO_REGION_BEFORE; +import static org.apache.fop.fo.Constants.FO_REGION_BODY; +import static org.apache.fop.fo.Constants.FO_REGION_END; +import static org.apache.fop.fo.Constants.FO_REGION_START; +import static org.apache.fop.fo.Constants.EN_ERROR_IF_OVERFLOW; +import static org.apache.fop.fo.Constants.EN_HIDDEN; + /** * The page. * This holds the contents of the page. Each region is added. @@ -58,7 +65,7 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { private RegionViewport regionAfter = null; // temporary map of unresolved objects used when serializing the page - private Map unresolved = null; + private Map<String, List<Resolvable>> unresolved = null; /** Set to true to make this page behave as if it were not empty. */ private boolean fakeNonEmpty = false; @@ -119,12 +126,10 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { spm.getWritingMode(), pageRefRect, reldims); // Create a RegionViewport/ reference area pair for each page region - RegionReference rr = null; - for (Iterator regenum = spm.getRegions().values().iterator(); - regenum.hasNext();) { - Region r = (Region)regenum.next(); + RegionReference rr; + for (Region r : spm.getRegions().values()) { RegionViewport rvp = makeRegionViewport(r, reldims, pageCTM); - if (r.getNameId() == Constants.FO_REGION_BODY) { + if (r.getNameId() == FO_REGION_BODY) { rr = new BodyRegion((RegionBody) r, rvp); } else { rr = new RegionReference(r, rvp); @@ -155,7 +160,7 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { * @param pageCTM page coordinate transformation matrix * @return the new region viewport */ - private RegionViewport makeRegionViewport(Region r, FODimension reldims, CTM pageCTM) { + private static RegionViewport makeRegionViewport(Region r, FODimension reldims, CTM pageCTM) { Rectangle2D relRegionRect = r.getViewportRectangle(reldims); Rectangle2D absRegionRect = pageCTM.transform(relRegionRect); // Get the region viewport rectangle in absolute coords by @@ -164,8 +169,8 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { rv.setBPD((int)relRegionRect.getHeight()); rv.setIPD((int)relRegionRect.getWidth()); TraitSetter.addBackground(rv, r.getCommonBorderPaddingBackground(), null); - rv.setClip(r.getOverflow() == Constants.EN_HIDDEN - || r.getOverflow() == Constants.EN_ERROR_IF_OVERFLOW); + rv.setClip(r.getOverflow() == EN_HIDDEN + || r.getOverflow() == EN_ERROR_IF_OVERFLOW); return rv; } @@ -180,7 +185,7 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { * where x=distance from left, y=distance from bottom, width=right-left * height=top-bottom */ - private void setRegionReferencePosition(RegionReference rr, Region r, + private static void setRegionReferencePosition(RegionReference rr, Region r, Rectangle2D absRegVPRect) { FODimension reldims = new FODimension(0, 0); rr.setCTM(CTM.getCTMandRelDims(r.getReferenceOrientation(), @@ -200,15 +205,15 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { * @param port the region viewport to set */ public void setRegionViewport(int areaclass, RegionViewport port) { - if (areaclass == Constants.FO_REGION_BEFORE) { + if (areaclass == FO_REGION_BEFORE) { regionBefore = port; - } else if (areaclass == Constants.FO_REGION_START) { + } else if (areaclass == FO_REGION_START) { regionStart = port; - } else if (areaclass == Constants.FO_REGION_BODY) { + } else if (areaclass == FO_REGION_BODY) { regionBody = port; - } else if (areaclass == Constants.FO_REGION_END) { + } else if (areaclass == FO_REGION_END) { regionEnd = port; - } else if (areaclass == Constants.FO_REGION_AFTER) { + } else if (areaclass == FO_REGION_AFTER) { regionAfter = port; } } @@ -221,15 +226,15 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { */ public RegionViewport getRegionViewport(int areaClass) { switch (areaClass) { - case Constants.FO_REGION_BEFORE: + case FO_REGION_BEFORE: return regionBefore; - case Constants.FO_REGION_START: + case FO_REGION_START: return regionStart; - case Constants.FO_REGION_BODY: + case FO_REGION_BODY: return regionBody; - case Constants.FO_REGION_END: + case FO_REGION_END: return regionEnd; - case Constants.FO_REGION_AFTER: + case FO_REGION_AFTER: return regionAfter; default: throw new IllegalArgumentException("No such area class with ID = " + areaClass); @@ -284,7 +289,7 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { * * @param unres the Map of unresolved objects */ - public void setUnresolvedReferences(Map unres) { + public void setUnresolvedReferences(Map<String, List<Resolvable>> unres) { unresolved = unres; } @@ -295,7 +300,7 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { * * @return the de-serialized HashMap of unresolved objects */ - public Map getUnresolvedReferences() { + public Map<String, List<Resolvable>> getUnresolvedReferences() { return unresolved; } diff --git a/src/java/org/apache/fop/area/PageSequence.java b/src/java/org/apache/fop/area/PageSequence.java index 8fd3cd571..1f0411b00 100644 --- a/src/java/org/apache/fop/area/PageSequence.java +++ b/src/java/org/apache/fop/area/PageSequence.java @@ -26,7 +26,7 @@ import java.util.List; */ public class PageSequence extends AreaTreeObject { - private List pages = new java.util.ArrayList(); + private List<PageViewport> pages = new java.util.ArrayList<PageViewport>(); private LineArea title; private String language; private String country; @@ -75,7 +75,7 @@ public class PageSequence extends AreaTreeObject { * @return the requested page or null if it was not found */ public PageViewport getPage(int idx) { - return (PageViewport)this.pages.get(idx); + return this.pages.get(idx); } /** diff --git a/src/java/org/apache/fop/area/PageViewport.java b/src/java/org/apache/fop/area/PageViewport.java index a4fcb61a8..ff4b2fdaa 100644 --- a/src/java/org/apache/fop/area/PageViewport.java +++ b/src/java/org/apache/fop/area/PageViewport.java @@ -25,7 +25,6 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -33,9 +32,15 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fop.fo.Constants; +import org.apache.fop.fo.flow.Marker; import org.apache.fop.fo.pagination.SimplePageMaster; +import static org.apache.fop.fo.Constants.FO_REGION_BODY; +import static org.apache.fop.fo.Constants.EN_FSWP; +import static org.apache.fop.fo.Constants.EN_FIC; +import static org.apache.fop.fo.Constants.EN_LSWP; +import static org.apache.fop.fo.Constants.EN_LEWP; + /** * Page viewport that specifies the viewport area and holds the page contents. * This is the top level object for a page and remains valid for the life @@ -63,26 +68,24 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl private transient PageSequence pageSequence; - // list of id references and the rectangle on the page - //private Map idReferences = null; - // set of IDs that appear first (or exclusively) on this page: - private Set idFirsts = new java.util.HashSet(); + private Set<String> idFirsts = new java.util.HashSet<String>(); // this keeps a list of currently unresolved areas or extensions // once an idref is resolved it is removed // when this is empty the page can be rendered - private Map unresolvedIDRefs = new java.util.HashMap(); + private Map<String, List<Resolvable>> unresolvedIDRefs + = new java.util.HashMap<String, List<Resolvable>>(); - private Map pendingResolved = null; + private Map<String, List<PageViewport>> pendingResolved = null; // hashmap of markers for this page // start and end are added by the fo that contains the markers - private Map markerFirstStart = null; - private Map markerLastStart = null; - private Map markerFirstAny = null; - private Map markerLastEnd = null; - private Map markerLastAny = null; + private Map<String, Marker> markerFirstStart = null; + private Map<String, Marker> markerLastStart = null; + private Map<String, Marker> markerFirstAny = null; + private Map<String, Marker> markerLastEnd = null; + private Map<String, Marker> markerLastAny = null; /** * logging instance @@ -254,8 +257,8 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl /** * Add an "ID-first" to this page. - * This is typically called by the AreaTreeHandler when associating - * an ID with a PageViewport. + * This is typically called by the {@link AreaTreeHandler} when associating + * an ID with a {@link PageViewport}. * * @param id the id to be registered as first appearing on this page */ @@ -277,9 +280,9 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl /** * Add an idref to this page. - * All idrefs found for child areas of this PageViewport are added - * to unresolvedIDRefs, for subsequent resolution by AreaTreeHandler - * calls to this object's resolveIDRef(). + * All idrefs found for child areas of this {@link PageViewport} are added + * to unresolvedIDRefs, for subsequent resolution by {@link AreaTreeHandler} + * calls to this object's {@code resolveIDRef()}. * * @param idref the idref * @param res the child element of this page that needs this @@ -287,14 +290,14 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl */ public void addUnresolvedIDRef(String idref, Resolvable res) { if (unresolvedIDRefs == null) { - unresolvedIDRefs = new HashMap(); + unresolvedIDRefs = new HashMap<String, List<Resolvable>>(); } - List list = (List)unresolvedIDRefs.get(idref); - if (list == null) { - list = new ArrayList(); - unresolvedIDRefs.put(idref, list); + List<Resolvable> pageViewports = unresolvedIDRefs.get(idref); + if (pageViewports == null) { + pageViewports = new ArrayList<Resolvable>(); + unresolvedIDRefs.put(idref, pageViewports); } - list.add(res); + pageViewports.add(res); } /** @@ -312,24 +315,22 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl */ public String[] getIDRefs() { return (unresolvedIDRefs == null) ? null - : (String[]) unresolvedIDRefs.keySet().toArray(new String[] {}); + : unresolvedIDRefs.keySet().toArray( + new String[unresolvedIDRefs.keySet().size()]); } - /** - * {@inheritDoc} - */ - public void resolveIDRef(String id, List pages) { + /** {@inheritDoc} */ + public void resolveIDRef(String id, List<PageViewport> pages) { if (page == null) { if (pendingResolved == null) { - pendingResolved = new HashMap(); + pendingResolved = new HashMap<String, List<PageViewport>>(); } pendingResolved.put(id, pages); } else { if (unresolvedIDRefs != null) { - List todo = (List)unresolvedIDRefs.get(id); + List<Resolvable> todo = unresolvedIDRefs.get(id); if (todo != null) { - for (int count = 0; count < todo.size(); count++) { - Resolvable res = (Resolvable)todo.get(count); + for (Resolvable res : todo) { res.resolveIDRef(id, pages); } } @@ -363,7 +364,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl * @param isfirst if the area being added has is-first trait * @param islast if the area being added has is-last trait */ - public void addMarkers(Map marks, boolean starting, + public void addMarkers(Map<String, Marker> marks, boolean starting, boolean isfirst, boolean islast) { if (marks == null) { @@ -380,14 +381,13 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl if (starting) { if (isfirst) { if (markerFirstStart == null) { - markerFirstStart = new HashMap(); + markerFirstStart = new HashMap<String, Marker>(); } if (markerFirstAny == null) { - markerFirstAny = new HashMap(); + markerFirstAny = new HashMap<String, Marker>(); } // first on page: only put in new values, leave current - for (Iterator iter = marks.keySet().iterator(); iter.hasNext();) { - Object key = iter.next(); + for (String key : marks.keySet()) { if (!markerFirstStart.containsKey(key)) { markerFirstStart.put(key, marks.get(key)); if (log.isTraceEnabled()) { @@ -404,7 +404,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl } } if (markerLastStart == null) { - markerLastStart = new HashMap(); + markerLastStart = new HashMap<String, Marker>(); } // last on page: replace all markerLastStart.putAll(marks); @@ -414,11 +414,10 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl } } else { if (markerFirstAny == null) { - markerFirstAny = new HashMap(); + markerFirstAny = new HashMap<String, Marker>(); } // first on page: only put in new values, leave current - for (Iterator iter = marks.keySet().iterator(); iter.hasNext();) { - Object key = iter.next(); + for (String key : marks.keySet()) { if (!markerFirstAny.containsKey(key)) { markerFirstAny.put(key, marks.get(key)); if (log.isTraceEnabled()) { @@ -432,7 +431,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl // at the end of the area, register is-last and any areas if (islast) { if (markerLastEnd == null) { - markerLastEnd = new HashMap(); + markerLastEnd = new HashMap<String, Marker>(); } // last on page: replace all markerLastEnd.putAll(marks); @@ -442,7 +441,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl } } if (markerLastAny == null) { - markerLastAny = new HashMap(); + markerLastAny = new HashMap<String, Marker>(); } // last on page: replace all markerLastAny.putAll(marks); @@ -462,11 +461,11 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl * @param pos the position to retrieve * @return Object the marker found or null */ - public Object getMarker(String name, int pos) { - Object mark = null; + public Marker getMarker(String name, int pos) { + Marker mark = null; String posName = null; switch (pos) { - case Constants.EN_FSWP: + case EN_FSWP: if (markerFirstStart != null) { mark = markerFirstStart.get(name); posName = "FSWP"; @@ -476,13 +475,13 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl posName = "FirstAny after " + posName; } break; - case Constants.EN_FIC: + case EN_FIC: if (markerFirstAny != null) { mark = markerFirstAny.get(name); posName = "FIC"; } break; - case Constants.EN_LSWP: + case EN_LSWP: if (markerLastStart != null) { mark = markerLastStart.get(name); posName = "LSWP"; @@ -492,7 +491,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl posName = "LastAny after " + posName; } break; - case Constants.EN_LEWP: + case EN_LEWP: if (markerLastEnd != null) { mark = markerLastEnd.get(name); posName = "LEWP"; @@ -503,7 +502,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl } break; default: - throw new RuntimeException(); + assert false; } if (log.isTraceEnabled()) { log.trace("page " + pageNumberString + ": " + "Retrieving marker " + name @@ -550,10 +549,8 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl page = (Page) in.readObject(); unresolvedIDRefs = page.getUnresolvedReferences(); if (unresolvedIDRefs != null && pendingResolved != null) { - for (Iterator iter = pendingResolved.keySet().iterator(); - iter.hasNext();) { - String id = (String) iter.next(); - resolveIDRef(id, (List)pendingResolved.get(id)); + for (String id : pendingResolved.keySet()) { + resolveIDRef(id, pendingResolved.get(id)); } pendingResolved = null; } @@ -577,9 +574,8 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl page = null; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public String toString() { StringBuffer sb = new StringBuffer(64); sb.append("PageViewport: page="); @@ -602,8 +598,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl * @return BodyRegion object */ public BodyRegion getBodyRegion() { - return (BodyRegion) getPage().getRegionViewport( - Constants.FO_REGION_BODY).getRegionReference(); + return (BodyRegion) getPage().getRegionViewport(FO_REGION_BODY).getRegionReference(); } /** @@ -659,5 +654,4 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl public RegionReference getRegionReference(int id) { return getPage().getRegionViewport(id).getRegionReference(); } - } diff --git a/src/java/org/apache/fop/area/RegionReference.java b/src/java/org/apache/fop/area/RegionReference.java index a727f9029..4158f924a 100644 --- a/src/java/org/apache/fop/area/RegionReference.java +++ b/src/java/org/apache/fop/area/RegionReference.java @@ -38,7 +38,7 @@ public class RegionReference extends Area implements Cloneable { private CTM ctm; // the list of block areas from the static flow - private ArrayList blocks = new ArrayList(); + private ArrayList<Area> blocks = new ArrayList<Area>(); /** the parent {@link RegionViewport} for this object */ protected RegionViewport regionViewport; @@ -68,6 +68,7 @@ public class RegionReference extends Area implements Cloneable { } /** {@inheritDoc} */ + @Override public void addChildArea(Area child) { blocks.add(child); } @@ -106,7 +107,7 @@ public class RegionReference extends Area implements Cloneable { * * @return the list of blocks in this region */ - public List getBlocks() { + public List<Area> getBlocks() { return blocks; } @@ -143,11 +144,12 @@ public class RegionReference extends Area implements Cloneable { RegionReference rr = new RegionReference(regionClass, regionName, regionViewport); rr.ctm = ctm; rr.setIPD(getIPD()); - rr.blocks = (ArrayList)blocks.clone(); + rr.blocks = (ArrayList<Area>)blocks.clone(); return rr; } /** {@inheritDoc} */ + @Override public String toString() { StringBuffer sb = new StringBuffer(super.toString()); sb.append(" {regionName=").append(regionName); diff --git a/src/java/org/apache/fop/area/RenderPagesModel.java b/src/java/org/apache/fop/area/RenderPagesModel.java index 13995b099..afec850f8 100644 --- a/src/java/org/apache/fop/area/RenderPagesModel.java +++ b/src/java/org/apache/fop/area/RenderPagesModel.java @@ -50,9 +50,10 @@ public class RenderPagesModel extends AreaTreeModel { /** * Pages that have been prepared but not rendered yet. */ - protected List/*<PageViewport>*/ prepared = new java.util.ArrayList/*<PageViewport>*/(); - private List/*<OffDocumentItem>*/ pendingODI = new java.util.ArrayList/*<OffDocumentItem>*/(); - private List/*<OffDocumentItem>*/ endDocODI = new java.util.ArrayList/*<OffDocumentItem>*/(); + protected List<PageViewport> prepared = new java.util.ArrayList<PageViewport>(); + + private List<OffDocumentItem> pendingODI = new java.util.ArrayList<OffDocumentItem>(); + private List<OffDocumentItem> endDocODI = new java.util.ArrayList<OffDocumentItem>(); /** * Create a new render pages model with the given renderer. @@ -83,6 +84,7 @@ public class RenderPagesModel extends AreaTreeModel { } /** {@inheritDoc} */ + @Override public void startPageSequence(PageSequence pageSequence) { super.startPageSequence(pageSequence); if (renderer.supportsOutOfOrder()) { @@ -98,6 +100,7 @@ public class RenderPagesModel extends AreaTreeModel { * the page is added to a queue. * @param page the page to add to the model */ + @Override public void addPage(PageViewport page) { super.addPage(page); @@ -152,14 +155,15 @@ public class RenderPagesModel extends AreaTreeModel { * false if the renderer doesn't support out of order * rendering and there are pending pages */ - protected boolean checkPreparedPages(PageViewport newPageViewport, boolean - renderUnresolved) { + protected boolean checkPreparedPages(PageViewport newPageViewport, + boolean renderUnresolved) { + for (Iterator iter = prepared.iterator(); iter.hasNext();) { PageViewport pageViewport = (PageViewport)iter.next(); if (pageViewport.isResolved() || renderUnresolved) { if (!renderer.supportsOutOfOrder() && pageViewport.getPageSequence().isFirstPage(pageViewport)) { - renderer.startPageSequence(getCurrentPageSequence()); + renderer.startPageSequence(pageViewport.getPageSequence()); } renderPage(pageViewport); pageViewport.clear(); @@ -183,11 +187,11 @@ public class RenderPagesModel extends AreaTreeModel { renderer.renderPage(pageViewport); if (!pageViewport.isResolved()) { String[] idrefs = pageViewport.getIDRefs(); - for (int count = 0; count < idrefs.length; count++) { + for (String idref : idrefs) { AreaEventProducer eventProducer = AreaEventProducer.Provider.get( renderer.getUserAgent().getEventBroadcaster()); eventProducer.unresolvedIDReferenceOnPage(this, - pageViewport.getPageNumberString(), idrefs[count]); + pageViewport.getPageNumberString(), idref); } } } catch (Exception e) { @@ -214,9 +218,8 @@ public class RenderPagesModel extends AreaTreeModel { prepared.add(page); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public void handleOffDocumentItem(OffDocumentItem oDI) { switch(oDI.getWhenToProcess()) { case OffDocumentItem.IMMEDIATELY: @@ -233,9 +236,8 @@ public class RenderPagesModel extends AreaTreeModel { } } - private void processOffDocumentItems(List list) { - for (int count = 0; count < list.size(); count++) { - OffDocumentItem oDI = (OffDocumentItem)list.get(count); + private void processOffDocumentItems(List<OffDocumentItem> list) { + for (OffDocumentItem oDI : list) { renderer.processOffDocumentItem(oDI); } } @@ -244,6 +246,7 @@ public class RenderPagesModel extends AreaTreeModel { * End the document. Render any end document OffDocumentItems * {@inheritDoc} */ + @Override public void endDocument() throws SAXException { // render any pages that had unresolved ids checkPreparedPages(null, true); diff --git a/src/java/org/apache/fop/area/Resolvable.java b/src/java/org/apache/fop/area/Resolvable.java index cc2569e8a..3ab3ef309 100644 --- a/src/java/org/apache/fop/area/Resolvable.java +++ b/src/java/org/apache/fop/area/Resolvable.java @@ -59,5 +59,5 @@ public interface Resolvable { * @param pages the list of PageViewports with the given ID * */ - void resolveIDRef(String id, List pages); + void resolveIDRef(String id, List<PageViewport> pages); } diff --git a/src/java/org/apache/fop/area/Span.java b/src/java/org/apache/fop/area/Span.java index e2ef90432..c2fd4679c 100644 --- a/src/java/org/apache/fop/area/Span.java +++ b/src/java/org/apache/fop/area/Span.java @@ -34,7 +34,7 @@ public class Span extends Area { private static final long serialVersionUID = -5551430053660081549L; // the list of flow reference areas in this span area - private List flowAreas; + private List<NormalFlow> flowAreas; private int colCount; private int colGap; private int colWidth; // width for each normal flow, calculated value @@ -60,7 +60,7 @@ public class Span extends Area { * Create the normal flows for this Span */ private void createNormalFlows() { - flowAreas = new java.util.ArrayList(colCount); + flowAreas = new java.util.ArrayList<NormalFlow>(colCount); colWidth = (ipd - ((colCount - 1) * colGap)) / colCount; for (int i = 0; i < colCount; i++) { @@ -105,7 +105,7 @@ public class Span extends Area { */ public NormalFlow getNormalFlow(int colRequested) { if (colRequested >= 0 && colRequested < colCount) { - return (NormalFlow) flowAreas.get(colRequested); + return flowAreas.get(colRequested); } else { // internal error throw new IllegalArgumentException("Invalid column number " + colRequested + " requested; only 0-" + (colCount - 1) @@ -184,6 +184,7 @@ public class Span extends Area { } /** {@inheritDoc} */ + @Override public String toString() { StringBuffer sb = new StringBuffer(super.toString()); if (colCount > 1) { diff --git a/src/java/org/apache/fop/area/Trait.java b/src/java/org/apache/fop/area/Trait.java index a8e1db186..042b65337 100644 --- a/src/java/org/apache/fop/area/Trait.java +++ b/src/java/org/apache/fop/area/Trait.java @@ -24,11 +24,15 @@ import java.io.Serializable; import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.fop.fo.Constants; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.traits.BorderProps; import org.apache.fop.util.ColorUtil; +import static org.apache.fop.fo.Constants.EN_REPEAT; +import static org.apache.fop.fo.Constants.EN_REPEATX; +import static org.apache.fop.fo.Constants.EN_REPEATY; +import static org.apache.fop.fo.Constants.EN_NOREPEAT; + // properties should be serialized by the holder /** * Area traits used for rendering. @@ -142,8 +146,10 @@ public final class Trait implements Serializable { /** Trait for color of underline decorations when rendering inline parent. */ public static final Integer UNDERLINE_COLOR = 34; + /** Trait for color of overline decorations when rendering inline parent. */ public static final Integer OVERLINE_COLOR = 35; + /** Trait for color of linethrough decorations when rendering inline parent. */ public static final Integer LINETHROUGH_COLOR = 36; @@ -367,6 +373,7 @@ public final class Trait implements Serializable { * Return the human-friendly string for debugging. * {@inheritDoc} */ + @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("pvKey=").append(pvKey); @@ -441,6 +448,7 @@ public final class Trait implements Serializable { * @return a <code>String</code> of the form * "org.apache.fop.area.Trait.ExternalLink[dest=someURL,newWindow=false]" */ + @Override public String toString() { StringBuffer sb = new StringBuffer(64); sb.append("newWindow=").append(newWindow); @@ -581,23 +589,23 @@ public final class Trait implements Serializable { private String getRepeatString() { switch (getRepeat()) { - case Constants.EN_REPEAT: return "repeat"; - case Constants.EN_REPEATX: return "repeat-x"; - case Constants.EN_REPEATY: return "repeat-y"; - case Constants.EN_NOREPEAT: return "no-repeat"; + case EN_REPEAT: return "repeat"; + case EN_REPEATX: return "repeat-x"; + case EN_REPEATY: return "repeat-y"; + case EN_NOREPEAT: return "no-repeat"; default: throw new IllegalStateException("Illegal repeat style: " + getRepeat()); } } private static int getConstantForRepeat(String repeat) { if ("repeat".equalsIgnoreCase(repeat)) { - return Constants.EN_REPEAT; + return EN_REPEAT; } else if ("repeat-x".equalsIgnoreCase(repeat)) { - return Constants.EN_REPEATX; + return EN_REPEATX; } else if ("repeat-y".equalsIgnoreCase(repeat)) { - return Constants.EN_REPEATY; + return EN_REPEATY; } else if ("no-repeat".equalsIgnoreCase(repeat)) { - return Constants.EN_NOREPEAT; + return EN_NOREPEAT; } else { throw new IllegalStateException("Illegal repeat style: " + repeat); } @@ -607,6 +615,7 @@ public final class Trait implements Serializable { * Return the string for debugging. * {@inheritDoc} */ + @Override public String toString() { StringBuffer sb = new StringBuffer(); if (color != null) { diff --git a/src/java/org/apache/fop/area/inline/Container.java b/src/java/org/apache/fop/area/inline/Container.java index f6dbf3a15..9267b92d0 100644 --- a/src/java/org/apache/fop/area/inline/Container.java +++ b/src/java/org/apache/fop/area/inline/Container.java @@ -38,7 +38,7 @@ public class Container extends Area { /** * The list of block areas stacked inside this container */ - protected List blocks = new ArrayList(); + protected List<Block> blocks = new ArrayList<Block>(); /** * The width of this container diff --git a/src/java/org/apache/fop/area/inline/FilledArea.java b/src/java/org/apache/fop/area/inline/FilledArea.java index 06d0d3aa3..858951f75 100644 --- a/src/java/org/apache/fop/area/inline/FilledArea.java +++ b/src/java/org/apache/fop/area/inline/FilledArea.java @@ -39,9 +39,7 @@ public class FilledArea extends InlineParent { private int unitWidth; - /** - * Create a new filled area. - */ + /** Create a new filled area. */ public FilledArea() { } @@ -88,13 +86,11 @@ public class FilledArea extends InlineParent { return this.unitWidth; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public int getBPD() { int bpd = 0; - for (Iterator childAreaIt = getChildAreas().iterator(); childAreaIt.hasNext();) { - InlineArea area = (InlineArea)childAreaIt.next(); + for (InlineArea area : getChildAreas()) { if (bpd < area.getBPD()) { bpd = area.getBPD(); } @@ -110,9 +106,10 @@ public class FilledArea extends InlineParent { * * @return the list of child areas copied to fill the width */ - public List getChildAreas() { - int units = (int)(getIPD() / unitWidth); - List newList = new ArrayList(); + @Override + public List<InlineArea> getChildAreas() { + int units = getIPD() / unitWidth; + List<InlineArea> newList = new ArrayList<InlineArea>(); for (int count = 0; count < units; count++) { newList.addAll(inlines); } @@ -126,6 +123,7 @@ public class FilledArea extends InlineParent { * @param lineShrink the total shrink of the line * @return true if there is an UnresolvedArea descendant */ + @Override public boolean applyVariationFactor(double variationFactor, int lineStretch, int lineShrink) { setIPD(getIPD() + adjustingInfo.applyVariationFactor(variationFactor)); diff --git a/src/java/org/apache/fop/area/inline/InlineArea.java b/src/java/org/apache/fop/area/inline/InlineArea.java index 3450b99be..515f45b68 100644 --- a/src/java/org/apache/fop/area/inline/InlineArea.java +++ b/src/java/org/apache/fop/area/inline/InlineArea.java @@ -178,6 +178,7 @@ public class InlineArea extends Area { * * {@inheritDoc} */ + @Override public void addChildArea(Area childArea) { super.addChildArea(childArea); if (childArea instanceof InlineArea) { @@ -185,9 +186,7 @@ public class InlineArea extends Area { } } - /** - *@return true if the inline area is underlined. - */ + /** @return true if the inline area is underlined. */ public boolean hasUnderline() { return getTraitAsBoolean(Trait.UNDERLINE); } diff --git a/src/java/org/apache/fop/area/inline/InlineBlockParent.java b/src/java/org/apache/fop/area/inline/InlineBlockParent.java index fe024ac0f..982e8848f 100644 --- a/src/java/org/apache/fop/area/inline/InlineBlockParent.java +++ b/src/java/org/apache/fop/area/inline/InlineBlockParent.java @@ -48,6 +48,7 @@ public class InlineBlockParent extends InlineArea { * * @param childArea the child area to add */ + @Override public void addChildArea(Area childArea) { if (child != null) { throw new IllegalStateException("InlineBlockParent may have only one child area."); diff --git a/src/java/org/apache/fop/area/inline/SpaceArea.java b/src/java/org/apache/fop/area/inline/SpaceArea.java index 9c698b305..ebfcc5ec8 100644 --- a/src/java/org/apache/fop/area/inline/SpaceArea.java +++ b/src/java/org/apache/fop/area/inline/SpaceArea.java @@ -48,9 +48,7 @@ public class SpaceArea extends InlineArea { isAdjustable = a; } - /** - * @return Returns the space. - */ + /** @return Returns the space. */ public String getSpace() { return String.valueOf(space); } diff --git a/src/java/org/apache/fop/area/inline/TextArea.java b/src/java/org/apache/fop/area/inline/TextArea.java index 8fb9455ad..15d005025 100644 --- a/src/java/org/apache/fop/area/inline/TextArea.java +++ b/src/java/org/apache/fop/area/inline/TextArea.java @@ -99,20 +99,19 @@ public class TextArea extends AbstractTextArea { */ public String getText() { StringBuffer text = new StringBuffer(); - InlineArea child; // assemble the text - for (int i = 0; i < inlines.size(); i++) { - child = (InlineArea) inlines.get(i); - if (child instanceof WordArea) { - text.append(((WordArea) child).getWord()); + for (InlineArea inline : inlines) { + if (inline instanceof WordArea) { + text.append(((WordArea) inline).getWord()); } else { - text.append(((SpaceArea) child).getSpace()); + text.append(((SpaceArea) inline).getSpace()); } } return text.toString(); } /** {@inheritDoc} */ + @Override public String toString() { return "TextArea{text=" + getText() + "}"; } diff --git a/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java b/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java index 3457ad698..d3bb91045 100644 --- a/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java +++ b/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java @@ -92,18 +92,14 @@ public class UnresolvedPageNumber extends TextArea implements Resolvable { * @param id an id whose PageViewports have been determined * @param pages the list of PageViewports associated with this ID */ - public void resolveIDRef(String id, List pages) { + public void resolveIDRef(String id, List<PageViewport> pages) { if (!resolved && pageIDRef.equals(id) && pages != null) { if (log.isDebugEnabled()) { log.debug("Resolving pageNumber: " + id); } resolved = true; - PageViewport page; - if (pageType == FIRST) { - page = (PageViewport)pages.get(0); - } else { - page = (PageViewport)pages.get(pages.size() - 1); - } + int pageIndex = pageType ? 0 : pages.size() - 1; + PageViewport page = pages.get(pageIndex); // replace the text removeText(); text = page.getPageNumberString(); @@ -136,6 +132,7 @@ public class UnresolvedPageNumber extends TextArea implements Resolvable { * @param lineShrink the total shrink of the line * @return true if there is an UnresolvedArea descendant */ + @Override public boolean applyVariationFactor(double variationFactor, int lineStretch, int lineShrink) { return true; diff --git a/src/java/org/apache/fop/area/inline/WordArea.java b/src/java/org/apache/fop/area/inline/WordArea.java index 8bb6888ce..7f62fe8d7 100644 --- a/src/java/org/apache/fop/area/inline/WordArea.java +++ b/src/java/org/apache/fop/area/inline/WordArea.java @@ -47,22 +47,18 @@ public class WordArea extends InlineArea { this.letterAdjust = la; } - /** - * @return Returns the word. - */ + /** @return Returns the word. */ public String getWord() { return word; } - /** - * @return Returns the offset. - */ + /** @return Returns the offset. */ + @Override public int getOffset() { return offset; } - /** - * @param o The offset to set. - */ + /** @param o The offset to set. */ + @Override public void setOffset(int o) { offset = o; } diff --git a/src/java/org/apache/fop/fo/Constants.java b/src/java/org/apache/fop/fo/Constants.java index 5f23502f3..726d4d89e 100644 --- a/src/java/org/apache/fop/fo/Constants.java +++ b/src/java/org/apache/fop/fo/Constants.java @@ -778,9 +778,11 @@ public interface Constants { * Used for accessibility. */ int PR_X_ALT_TEXT = 275; + /** Property constant - FOP proprietary prototype (in XSL-FO 2.0 Requirements) */ + int PR_X_XML_BASE = 276; /** Number of property constants defined */ - int PROPERTY_COUNT = 275; + int PROPERTY_COUNT = 276; // compound property constants diff --git a/src/java/org/apache/fop/fo/FOPropertyMapping.java b/src/java/org/apache/fop/fo/FOPropertyMapping.java index c711a76c0..cf4eef3a5 100644 --- a/src/java/org/apache/fop/fo/FOPropertyMapping.java +++ b/src/java/org/apache/fop/fo/FOPropertyMapping.java @@ -62,8 +62,9 @@ import org.apache.fop.fo.properties.SpacePropertyMaker; import org.apache.fop.fo.properties.SpacingPropertyMaker; import org.apache.fop.fo.properties.StringProperty; import org.apache.fop.fo.properties.TableBorderPrecedence; -import org.apache.fop.fo.properties.TextDecorationProperty; +import org.apache.fop.fo.properties.TextDecorationMaker; import org.apache.fop.fo.properties.ToBeImplementedProperty; +import org.apache.fop.fo.properties.URIProperty; import org.apache.fop.fo.properties.VerticalAlignShorthandParser; import org.apache.fop.fo.properties.WhiteSpaceShorthandParser; import org.apache.fop.fo.properties.XMLLangShorthandParser; @@ -79,11 +80,11 @@ public final class FOPropertyMapping implements Constants { private FOPropertyMapping() { } - private static Map propNames = new HashMap(); // CSOK: VisibilityModifier - private static Map subPropNames = new HashMap(); // CSOK: VisibilityModifier - private static Map propIds = new HashMap(); // CSOK: VisibilityModifier + private static Map<String, Integer> propNames = new HashMap<String, Integer>(); + private static Map<String, Integer> subPropNames = new HashMap<String, Integer>(); + private static Map<Integer, String> propIds = new HashMap<Integer, String>(); - private static PropertyMaker[] generics = null; // CSOK: VisibilityModifier + private static PropertyMaker[] generics = null; // The rest is only used during the building of the generics array. private Property[] enums = null; @@ -246,8 +247,8 @@ public final class FOPropertyMapping implements Constants { */ private static void addPropertyMaker(String name, PropertyMaker maker) { generics[maker.getPropId()] = maker; - propNames.put(name, new Integer(maker.getPropId())); - propIds.put(new Integer(maker.getPropId()), name); + propNames.put(name, maker.getPropId()); + propIds.put(maker.getPropId(), name); } /** @@ -256,8 +257,8 @@ public final class FOPropertyMapping implements Constants { * @param id Id for the subproperty from CP_* in Constants.java. */ private static void addSubpropMakerName(String name, int id) { - subPropNames.put(name, new Integer(id)); - propIds.put(new Integer(id), name); + subPropNames.put(name, id); + propIds.put(id, name); } /** @@ -342,9 +343,9 @@ public final class FOPropertyMapping implements Constants { */ public static int getPropertyId(String name) { if (name != null) { - Integer i = (Integer) propNames.get(name); + Integer i = propNames.get(name); if (i != null) { - return i.intValue(); + return i; } } return -1; @@ -357,9 +358,9 @@ public final class FOPropertyMapping implements Constants { */ public static int getSubPropertyId(String name) { if (name != null) { - Integer i = (Integer) subPropNames.get(name); + Integer i = subPropNames.get(name); if (i != null) { - return i.intValue(); + return i; } } return -1; @@ -373,10 +374,10 @@ public final class FOPropertyMapping implements Constants { public static String getPropertyName(int id) { if (((id & Constants.COMPOUND_MASK) == 0) || ((id & Constants.PROPERTY_MASK) == 0)) { - return (String) propIds.get(new Integer(id)); + return propIds.get(id); } else { - return propIds.get(new Integer(id & Constants.PROPERTY_MASK)) - + "." + propIds.get(new Integer(id & Constants.COMPOUND_MASK)); + return propIds.get(id & Constants.PROPERTY_MASK) + + "." + propIds.get(id & Constants.COMPOUND_MASK); } } @@ -1694,7 +1695,7 @@ public final class FOPropertyMapping implements Constants { // text-decoration //m = new EnumProperty.Maker(PR_TEXT_DECORATION); - m = new TextDecorationProperty.Maker(PR_TEXT_DECORATION); + m = new TextDecorationMaker(PR_TEXT_DECORATION); m.setInherited(false); m.addEnum("none", getEnumProperty(EN_NONE, "NONE")); m.addEnum("underline", getEnumProperty(EN_UNDERLINE, "UNDERLINE")); @@ -2572,7 +2573,7 @@ public final class FOPropertyMapping implements Constants { addPropertyMaker("score-spaces", m); // src - m = new StringProperty.Maker(PR_SRC); + m = new URIProperty.Maker(PR_SRC); m.setInherited(false); m.setDefault(""); addPropertyMaker("src", m); @@ -2819,6 +2820,12 @@ public final class FOPropertyMapping implements Constants { m.setDatatypeParser(new XMLLangShorthandParser()); addPropertyMaker("xml:lang", m); + // xml:base + m = new URIProperty.Maker(PR_X_XML_BASE); + m.setInherited(true); + m.setDefault(""); + addPropertyMaker("xml:base", m); + } } diff --git a/src/java/org/apache/fop/fo/FOValidationEventProducer.xml b/src/java/org/apache/fop/fo/FOValidationEventProducer.xml index c3e4b6b61..509f7c1d3 100644 --- a/src/java/org/apache/fop/fo/FOValidationEventProducer.xml +++ b/src/java/org/apache/fop/fo/FOValidationEventProducer.xml @@ -9,6 +9,7 @@ <message key="rule.childOfSPM">The element must be a child of fo:simple-page-master.</message> <message key="rule.childOfDeclarations">The element must be a child of fo:declarations.</message> <message key="rule.childOfSPMorDeclarations">The element must be a child of fo:declarations or fo:simple-page-master.</message> + <message key="rule.childOfSPMorPSorDeclarations">The element must be a child of fo:declarations, fo:simple-page-master or fo:page-sequence.</message> <message key="rule.childOfInstreamForeignObjectorExternalGraphic">The element must be a child of fo:instream-foreign-object or fo:external-graphic.</message> <message key="rule.childOfPageSequence">The element must be a child of fo:page-sequence.</message> <message key="rule.childOfPageSequenceOrSPM">The element must be a child of fo:page-sequence or fo:simple-page-master.</message> diff --git a/src/java/org/apache/fop/fo/FObj.java b/src/java/org/apache/fop/fo/FObj.java index 34e29a58a..98661b8b6 100644 --- a/src/java/org/apache/fop/fo/FObj.java +++ b/src/java/org/apache/fop/fo/FObj.java @@ -47,16 +47,17 @@ public abstract class FObj extends FONode implements Constants { private static final PropertyMaker[] PROPERTY_LIST_TABLE = FOPropertyMapping.getGenericMappings(); - /** - * pointer to the descendant subtree - */ + /** pointer to the descendant subtree */ protected FONode firstChild; + /** pointer to the end of the descendant subtree */ + protected FONode lastChild; + /** The list of extension attachments, null if none */ - private List/*<ExtensionAttachment>*/ extensionAttachments = null; + private List<ExtensionAttachment> extensionAttachments = null; /** The map of foreign attributes, null if none */ - private Map/*<QName,String>*/ foreignAttributes = null; + private Map<QName, String> foreignAttributes = null; /** Used to indicate if this FO is either an Out Of Line FO (see rec) * or a descendant of one. Used during FO validation. @@ -197,13 +198,19 @@ public abstract class FObj extends FONode implements Constants { } else { if (firstChild == null) { firstChild = child; + lastChild = child; } else { - FONode prevChild = firstChild; - while (prevChild.siblings != null - && prevChild.siblings[1] != null) { - prevChild = prevChild.siblings[1]; + if (lastChild == null) { + FONode prevChild = firstChild; + while (prevChild.siblings != null + && prevChild.siblings[1] != null) { + prevChild = prevChild.siblings[1]; + } + FONode.attachSiblings(prevChild, child); + } else { + FONode.attachSiblings(lastChild, child); + lastChild = child; } - FONode.attachSiblings(prevChild, child); } } } @@ -238,6 +245,13 @@ public abstract class FObj extends FONode implements Constants { nextChild.siblings[0] = prevChild; } } + if (child == lastChild) { + if (child.siblings != null) { + lastChild = siblings[0]; + } else { + lastChild = null; + } + } } /** @@ -421,6 +435,7 @@ public abstract class FObj extends FONode implements Constants { * Convenience method for validity checking. Checks if the * incoming node is a member of the "%block;" parameter entity * as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations + * * @param nsURI namespace URI of incoming node * @param lName local name (i.e., no prefix) of incoming node * @return true if a member, false if not @@ -440,6 +455,7 @@ public abstract class FObj extends FONode implements Constants { * Convenience method for validity checking. Checks if the * incoming node is a member of the "%inline;" parameter entity * as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations + * * @param nsURI namespace URI of incoming node * @param lName local name (i.e., no prefix) of incoming node * @return true if a member, false if not @@ -529,7 +545,7 @@ public abstract class FObj extends FONode implements Constants { /** @return whether this object has an id set */ public boolean hasId() { - return id != null && id.length() > 0; + return (id != null && id.length() > 0); } /** {@inheritDoc} */ @@ -554,7 +570,7 @@ public abstract class FObj extends FONode implements Constants { "Parameter attachment must not be null"); } if (extensionAttachments == null) { - extensionAttachments = new java.util.ArrayList/*<ExtensionAttachment>*/(); + extensionAttachments = new java.util.ArrayList<ExtensionAttachment>(); } if (log.isDebugEnabled()) { log.debug("ExtensionAttachment of category " @@ -591,7 +607,7 @@ public abstract class FObj extends FONode implements Constants { throw new NullPointerException("Parameter attributeName must not be null"); } if (foreignAttributes == null) { - foreignAttributes = new java.util.HashMap/*<QName,String>*/(); + foreignAttributes = new java.util.HashMap<QName, String>(); } foreignAttributes.put(attributeName, value); } @@ -679,6 +695,9 @@ public abstract class FObj extends FONode implements Constants { && currentNode.siblings[1] != null) { FONode.attachSiblings(newNode, currentNode.siblings[1]); } + if (currentNode == parentNode.lastChild) { + parentNode.lastChild = newNode; + } } else { throw new IllegalStateException(); } @@ -694,12 +713,18 @@ public abstract class FObj extends FONode implements Constants { parentNode.firstChild = newNode; currentIndex = 0; currentNode = newNode; + if (parentNode.lastChild == null) { + parentNode.lastChild = newNode; + } } else { if (currentNode.siblings != null && currentNode.siblings[1] != null) { FONode.attachSiblings((FONode) o, currentNode.siblings[1]); } FONode.attachSiblings(currentNode, (FONode) o); + if (currentNode == parentNode.lastChild) { + parentNode.lastChild = newNode; + } } flags &= F_NONE_ALLOWED; } diff --git a/src/java/org/apache/fop/fo/PropertyList.java b/src/java/org/apache/fop/fo/PropertyList.java index 709c4303b..a1634e868 100644 --- a/src/java/org/apache/fop/fo/PropertyList.java +++ b/src/java/org/apache/fop/fo/PropertyList.java @@ -264,6 +264,13 @@ public abstract class PropertyList { return -1; } + private String addAttributeToList(Attributes attributes, + String attributeName) throws ValidationException { + String attributeValue = attributes.getValue(attributeName); + convertAttributeToProperty(attributes, attributeName, attributeValue); + return attributeValue; + } + /** * Adds the attributes, passed in by the parser to the PropertyList * @@ -278,44 +285,35 @@ public abstract class PropertyList { * need them before all others (possible from-table-column() on any * other property further in the list... */ - String attributeName = "column-number"; - String attributeValue = attributes.getValue(attributeName); - convertAttributeToProperty(attributes, attributeName, - attributeValue); - attributeName = "number-columns-spanned"; - attributeValue = attributes.getValue(attributeName); - convertAttributeToProperty(attributes, attributeName, - attributeValue); + addAttributeToList(attributes, "column-number"); + addAttributeToList(attributes, "number-columns-spanned"); /* * If font-size is set on this FO, must set it first, since * other attributes specified in terms of "ems" depend on it. */ - attributeName = "font"; - attributeValue = attributes.getValue(attributeName); - convertAttributeToProperty(attributes, attributeName, - attributeValue); - if (attributeValue == null) { + String checkValue = addAttributeToList(attributes, "font"); + if (checkValue == null || "".equals(checkValue)) { /* * font shorthand wasn't specified, so still need to process * explicit font-size */ - attributeName = "font-size"; - attributeValue = attributes.getValue(attributeName); - convertAttributeToProperty(attributes, attributeName, - attributeValue); + addAttributeToList(attributes, "font-size"); } + String attributeName; + String attributeValue; String attributeNS; FopFactory factory = getFObj().getUserAgent().getFactory(); for (int i = 0; i < attributes.getLength(); i++) { /* convert all attributes with the same namespace as the fo element - * the "xml:lang" property is a special case */ + * the "xml:lang" and "xml:base" properties are special cases */ attributeNS = attributes.getURI(i); attributeName = attributes.getQName(i); attributeValue = attributes.getValue(i); if (attributeNS == null || attributeNS.length() == 0 - || "xml:lang".equals(attributeName)) { + || "xml:lang".equals(attributeName) + || "xml:base".equals(attributeName)) { convertAttributeToProperty(attributes, attributeName, attributeValue); } else if (!factory.isNamespaceIgnored(attributeNS)) { ElementMapping mapping = factory.getElementMappingRegistry().getElementMapping( @@ -368,15 +366,14 @@ public abstract class PropertyList { String attributeValue) throws ValidationException { - if (attributeValue != null) { - - if (attributeName.startsWith("xmlns:") - || "xmlns".equals(attributeName)) { - //Ignore namespace declarations if the XML parser/XSLT processor - //reports them as 'regular' attributes - return; - } + if (attributeName.startsWith("xmlns:") + || "xmlns".equals(attributeName)) { + /* Ignore namespace declarations if the XML parser/XSLT processor + * reports them as 'regular' attributes */ + return; + } + if (attributeValue != null) { /* Handle "compound" properties, ex. space-before.minimum */ String basePropertyName = findBasePropertyName(attributeName); String subPropertyName = findSubPropertyName(attributeName); diff --git a/src/java/org/apache/fop/fo/properties/ListProperty.java b/src/java/org/apache/fop/fo/properties/ListProperty.java index 4c5208505..6b1ffcea0 100644 --- a/src/java/org/apache/fop/fo/properties/ListProperty.java +++ b/src/java/org/apache/fop/fo/properties/ListProperty.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; /** * Superclass for properties that are lists of other properties @@ -30,22 +31,23 @@ import org.apache.fop.fo.PropertyList; public class ListProperty extends Property { /** - * Inner class for creating instances of ListProperty + * Inner class for creating instances of {@code ListProperty} */ public static class Maker extends PropertyMaker { /** + * Create a maker for the given property id. * @param propId ID of the property for which Maker should be created */ public Maker(int propId) { super(propId); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public Property convertProperty(Property p, - PropertyList propertyList, FObj fo) { + PropertyList propertyList, FObj fo) + throws PropertyException { if (p instanceof ListProperty) { return p; } else { @@ -56,7 +58,7 @@ public class ListProperty extends Property { } /** Vector containing the list of sub-properties */ - protected List list = new java.util.Vector(); + protected final List<Property> list = new java.util.Vector<Property>(); /** * Simple constructor used by subclasses to do some special processing. @@ -66,7 +68,9 @@ public class ListProperty extends Property { } /** - * @param prop the first Property to be added to the list + * Create a new instance, using the given {@link Property} as the first + * element in the list. + * @param prop the first property to be added to the list */ public ListProperty(Property prop) { this(); @@ -82,15 +86,21 @@ public class ListProperty extends Property { } /** - * @return this.list + * Return the {@code java.util.List} of {@link Property} instances + * contained in this property. + * @return the list of properties contained in this instance */ - public List getList() { + @Override + public List<Property> getList() { return list; } /** + * Return the {@code java.util.List} of {@link Property} instances, + * cast as a {@code java.lang.Object}. * @return this.list cast as an Object */ + @Override public Object getObject() { return list; } diff --git a/src/java/org/apache/fop/fo/properties/TextDecorationMaker.java b/src/java/org/apache/fop/fo/properties/TextDecorationMaker.java new file mode 100644 index 000000000..de26934a0 --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/TextDecorationMaker.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.properties; + +import java.util.List; + +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.NCnameProperty; +import org.apache.fop.fo.expr.PropertyException; + +/** + * Dedicated {@link org.apache.fop.fo.properties.PropertyMaker} for handling the + * <a href="http://www.w3.org/TR/xsl/#text-decoration"><code>text-decoration</code></a> + * property. + */ +public class TextDecorationMaker extends ListProperty.Maker { + + /** + * Create a maker for the given property id. + * @param propId id of the property for which a maker should be created + */ + public TextDecorationMaker(int propId) { + super(propId); + } + + /** + * {@inheritDoc} + * Add validation rules for the <code>text-decoration</code> property. + */ + @Override + public Property convertProperty(Property p, + PropertyList propertyList, + FObj fo) + throws PropertyException { + + ListProperty listProp = (ListProperty) super.convertProperty(p, propertyList, fo); + List lst = listProp.getList(); + boolean none = false; + boolean under = false; + boolean over = false; + boolean through = false; + boolean blink = false; + int enumValue; + for (int i = lst.size(); --i >= 0;) { + Property prop = (Property)lst.get(i); + if (prop instanceof NCnameProperty) { + prop = checkEnumValues(prop.getString()); + lst.set(i, prop); + } + enumValue = prop.getEnum(); + switch (enumValue) { + case Constants.EN_NONE: + if (under | over | through | blink) { + throw new PropertyException("Invalid combination of values"); + } + none = true; + break; + case Constants.EN_UNDERLINE: + case Constants.EN_NO_UNDERLINE: + case Constants.EN_OVERLINE: + case Constants.EN_NO_OVERLINE: + case Constants.EN_LINE_THROUGH: + case Constants.EN_NO_LINE_THROUGH: + case Constants.EN_BLINK: + case Constants.EN_NO_BLINK: + if (none) { + throw new PropertyException + ("'none' specified, no additional values allowed"); + } + switch (enumValue) { + case Constants.EN_UNDERLINE: + case Constants.EN_NO_UNDERLINE: + if (!under) { + under = true; + continue; + } + case Constants.EN_OVERLINE: + case Constants.EN_NO_OVERLINE: + if (!over) { + over = true; + continue; + } + case Constants.EN_LINE_THROUGH: + case Constants.EN_NO_LINE_THROUGH: + if (!through) { + through = true; + continue; + } + case Constants.EN_BLINK: + case Constants.EN_NO_BLINK: + if (!blink) { + blink = true; + continue; + } + default: + throw new PropertyException("Invalid combination of values"); + } + default: + throw new PropertyException("Invalid value specified: " + prop); + } + } + return listProp; + } +} diff --git a/src/java/org/apache/fop/fo/properties/TextDecorationProperty.java b/src/java/org/apache/fop/fo/properties/TextDecorationProperty.java deleted file mode 100644 index bcd41fb20..000000000 --- a/src/java/org/apache/fop/fo/properties/TextDecorationProperty.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.fo.properties; - -import java.util.Iterator; -import java.util.List; - -import org.apache.fop.fo.Constants; -import org.apache.fop.fo.FObj; -import org.apache.fop.fo.PropertyList; -import org.apache.fop.fo.expr.NCnameProperty; -import org.apache.fop.fo.expr.PropertyException; - -/** - * Special list property for text-decoration. - */ -public class TextDecorationProperty extends ListProperty { - - /** - * Inner class for creating instances of ListProperty - */ - public static class Maker extends PropertyMaker { - - /** - * @param propId ID of the property for which Maker should be created - */ - public Maker(int propId) { - super(propId); - } - - /** - * {@inheritDoc} - */ - public Property convertProperty(Property p, - PropertyList propertyList, FObj fo) - throws PropertyException { - if (p instanceof TextDecorationProperty) { - return p; - } else { - if (p instanceof ListProperty) { - ListProperty lst = (ListProperty)p; - lst = checkEnums(lst); - return new TextDecorationProperty((ListProperty)p); - } else if (p instanceof EnumProperty) { - ListProperty lst = new ListProperty(p); - return new TextDecorationProperty(lst); - } else { - throw new PropertyException("Cannot convert anything other " - + "than a list property, got a " + p.getClass().getName()); - } - } - } - - private ListProperty checkEnums(ListProperty lst) throws PropertyException { - List l = lst.getList(); - for (int i = 0; i < l.size(); i++) { - Property prop = (Property)l.get(i); - if (prop instanceof EnumProperty) { - //skip - } else if (prop instanceof NCnameProperty) { - Property propEnum = checkEnumValues(((NCnameProperty)prop).getString()); - if (propEnum == null) { - throw new PropertyException("Illegal enum value: " + prop.getString()); - } - l.set(i, propEnum); - } else { - throw new PropertyException("Invalid content for text-decoration " - + "property: " + prop); - } - } - return lst; - } - - } - - /** - * Constructs a new instance by converting a ListProperty. - * @param listProp the ListProperty to be converted - * @throws PropertyException in case the conversion fails - */ - public TextDecorationProperty(ListProperty listProp) throws PropertyException { - List lst = listProp.getList(); - boolean none = false; - boolean under = false; - boolean over = false; - boolean through = false; - boolean blink = false; - Iterator i = lst.iterator(); - while (i.hasNext()) { - Property prop = (Property)i.next(); - switch (prop.getEnum()) { - case Constants.EN_NONE: - if (under | over | through | blink) { - throw new PropertyException( - "Invalid combination of values"); - } - none = true; - break; - case Constants.EN_UNDERLINE: - case Constants.EN_NO_UNDERLINE: - if (none) { - throw new PropertyException - ("'none' specified, no additional values allowed"); - } - if (under) { - throw new PropertyException("Invalid combination of values"); - } - under = true; - break; - case Constants.EN_OVERLINE: - case Constants.EN_NO_OVERLINE: - if (none) { - throw new PropertyException - ("'none' specified, no additional values allowed"); - } - if (over) { - throw new PropertyException("Invalid combination of values"); - } - over = true; - break; - case Constants.EN_LINE_THROUGH: - case Constants.EN_NO_LINE_THROUGH: - if (none) { - throw new PropertyException - ("'none' specified, no additional values allowed"); - } - if (through) { - throw new PropertyException("Invalid combination of values"); - } - through = true; - break; - case Constants.EN_BLINK: - case Constants.EN_NO_BLINK: - if (none) { - throw new PropertyException - ("'none' specified, no additional values allowed"); - } - if (blink) { - throw new PropertyException("Invalid combination of values"); - } - blink = true; - break; - default: - throw new PropertyException("Invalid value specified: " + prop); - } - addProperty(prop); - } - } - -} diff --git a/src/java/org/apache/fop/fo/properties/URIProperty.java b/src/java/org/apache/fop/fo/properties/URIProperty.java new file mode 100644 index 000000000..6465fafdb --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/URIProperty.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.properties; + +import org.apache.fop.datatypes.URISpecification; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; + +import java.net.URI; +import java.net.URISyntaxException; + +import static org.apache.fop.fo.Constants.PR_X_XML_BASE; + +/** + * Class modeling a property that has a value of type <uri-specification>. + * The purpose is mainly to support resolution of a specified + * relative URI against a specified or inherited <code>xml:base</code> + * during the property refinement stage. + * If no <code>xml:base</code> has been specified, only the original URI, as + * it appears in the source document, is stored as the property's specified + * value. + */ +public class URIProperty extends Property { + + /** will be null if the URI is not resolved against an xml:base */ + private URI resolvedURI; + + /** + * Default constructor, to create a {@link URIProperty} from a + * {@code java.net.URI} directly. + * @param uri a resolved {@code java.net.URI} + */ + protected URIProperty(URI uri) { + this.resolvedURI = uri; + } + + /** + * Alternate constructor, to create a {@link URIProperty} from a + * string representation. + * @param uri a {@code java.lang.String} representing the URI + * @param resolve flag indicating whether this URI was the result of resolution + * @throws IllegalArgumentException if the URI should be resolved, but is not valid. + */ + private URIProperty(String uri, boolean resolve) { + if (resolve && !(uri == null || "".equals(uri))) { + this.resolvedURI = URI.create(uri); + } else { + setSpecifiedValue(uri); + } + } + + /** + * Return a string representing the resolved URI, or the + * specified value if the URI is not resolved against + * an <code>xml:base</code> + * @return a string representing the URI + */ + @Override + public String getString() { + if (resolvedURI == null) { + return getSpecifiedValue(); + } else { + return resolvedURI.toString(); + } + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return this.getString(); + } + + /** + * Inner {@link PropertyMaker} subclass responsible + * for making instances of this type. + */ + public static class Maker extends PropertyMaker { + + /** + * Create a maker for the given property id + * + * @param propId the id of the property for which a Maker should be created + */ + public Maker(int propId) { + super(propId); + } + + /** + * {@inheritDoc} + * Check if {@code xml:base} has been specified and whether the + * given {@code value} represents a relative URI. If so, create + * a property representing the resolved URI. + */ + @Override + public Property make(PropertyList propertyList, String value, + FObj fo) throws PropertyException { + + Property p = null; + //special treament for data: URIs + if (value.matches("(?s)^(url\\(('|\")?)?data:.*$")) { + p = new URIProperty(value, false); + } else { + try { + URI specifiedURI = new URI(URISpecification.escapeURI(value)); + URIProperty xmlBase = (URIProperty)propertyList.get(PR_X_XML_BASE, true, false); + if (xmlBase == null) { + //xml:base undefined + if (this.propId == PR_X_XML_BASE) { + //if current property is xml:base, define a new one + p = new URIProperty(specifiedURI); + p.setSpecifiedValue(value); + } else { + //otherwise, just store the specified value (for backward compatibility) + p = new URIProperty(value, false); + } + } else { + //xml:base defined, so resolve + p = new URIProperty(xmlBase.resolvedURI.resolve(specifiedURI)); + p.setSpecifiedValue(value); + } + } catch (URISyntaxException use) { + // Let PropertyList propagate the exception + throw new PropertyException("Invalid URI specified"); + } + } + return p; + } + } + +} diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java index d798db1bb..b832eec2b 100644 --- a/src/java/org/apache/fop/fonts/SingleByteFont.java +++ b/src/java/org/apache/fop/fonts/SingleByteFont.java @@ -29,6 +29,8 @@ import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.xmlgraphics.fonts.Glyphs; + /** * Generic SingleByte font */ @@ -44,6 +46,7 @@ public class SingleByteFont extends CustomFont { private Map<Character, UnencodedCharacter> unencodedCharacters; private List<SimpleSingleByteEncoding> additionalEncodings; + private Map<Character, Character> alternativeCodes; /** @@ -99,19 +102,69 @@ public class SingleByteFont extends CustomFont { return arr; } - /** {@inheritDoc} */ - @Override - public char mapChar(char c) { - notifyMapOperation(); + /** + * Lookup a character using its alternative names. If found, cache it so we + * can speed up lookups. + * @param c the character + * @return the suggested alternative character present in the font + */ + private char findAlternative(char c) { + char d; + if (alternativeCodes == null) { + alternativeCodes = new java.util.HashMap<Character, Character>(); + } else { + Character alternative = alternativeCodes.get(c); + if (alternative != null) { + return alternative; + } + } + String charName = Glyphs.charToGlyphName(c); + String[] charNameAlternatives = Glyphs.getCharNameAlternativesFor(charName); + if (charNameAlternatives != null && charNameAlternatives.length > 0) { + for (int i = 0; i < charNameAlternatives.length; i++) { + if (log.isDebugEnabled()) { + log.debug("Checking alternative for char " + c + " (charname=" + + charName + "): " + charNameAlternatives[i]); + } + String s = Glyphs.getUnicodeSequenceForGlyphName(charNameAlternatives[i]); + if (s != null) { + d = lookupChar(s.charAt(0)); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + alternativeCodes.put(c, d); + return d; + } + } + } + } + + return SingleByteEncoding.NOT_FOUND_CODE_POINT; + } + + private char lookupChar(char c) { char d = mapping.mapChar(c); if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { return d; } - //Check unencoded characters which are available in the font by character name + // Check unencoded characters which are available in the font by + // character name d = mapUnencodedChar(c); + return d; + } + + /** {@inheritDoc} */ + @Override + public char mapChar(char c) { + notifyMapOperation(); + char d = lookupChar(c); if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { return d; + } else { + // Check for alternative + d = findAlternative(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return d; + } } this.warnMissingGlyph(c); return Typeface.NOT_FOUND; @@ -162,6 +215,11 @@ public class SingleByteFont extends CustomFont { if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { return true; } + // Check if an alternative exists + d = findAlternative(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return true; + } return false; } diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index ae230e261..8e96f3eb1 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -20,7 +20,6 @@ package org.apache.fop.layoutmgr; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; @@ -34,27 +33,27 @@ 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.flow.Marker; import org.apache.fop.fo.flow.RetrieveMarker; +import org.apache.xmlgraphics.util.QName; /** * The base class for most LayoutManagers. */ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager - implements Constants { + implements Constants { - /** - * logging instance - */ + /** logging instance */ private static Log log = LogFactory.getLog(AbstractLayoutManager.class); /** Parent LayoutManager for this LayoutManager */ protected LayoutManager parentLayoutManager; /** List of child LayoutManagers */ - protected List childLMs; + protected List<LayoutManager> childLMs; /** Iterator for child LayoutManagers */ protected ListIterator fobjIter; /** Marker map for markers related to this LayoutManager */ - private Map markers; + private Map<String, Marker> markers; /** True if this LayoutManager has handled all of its content. */ private boolean isFinished; @@ -63,7 +62,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager protected LayoutManager curChildLM; /** child LM iterator during getNextKnuthElement phase */ - protected ListIterator childLMiter; + protected ListIterator<LayoutManager> childLMiter; private int lastGeneratedPosition = -1; private int smallestPosNumberChecked = Integer.MAX_VALUE; @@ -116,7 +115,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager return curChildLM; } if (childLMiter.hasNext()) { - curChildLM = (LayoutManager) childLMiter.next(); + curChildLM = childLMiter.next(); curChildLM.initialize(); return curChildLM; } @@ -131,7 +130,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager curChildLM = childLM; childLMiter = new LMiter(this); do { - curChildLM = (LayoutManager) childLMiter.next(); + curChildLM = childLMiter.next(); } while (curChildLM != childLM); } @@ -165,16 +164,14 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager } /** {@inheritDoc} */ - public List getNextKnuthElements(LayoutContext context, - int alignment) { + public List getNextKnuthElements(LayoutContext context, int alignment) { log.warn("null implementation of getNextKnuthElements() called!"); setFinished(true); return null; } /** {@inheritDoc} */ - public List getChangedKnuthElements(List oldList, - int alignment) { + public List getChangedKnuthElements(List oldList, int alignment) { log.warn("null implementation of getChangeKnuthElement() called!"); return null; } @@ -210,11 +207,11 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager * @param size the requested number of child LMs * @return the list with the preloaded child LMs */ - protected List createChildLMs(int size) { + protected List<LayoutManager> createChildLMs(int size) { if (fobjIter == null) { return null; } - List newLMs = new ArrayList(size); + List<LayoutManager> newLMs = new ArrayList<LayoutManager>(size); while (fobjIter.hasNext() && newLMs.size() < size ) { Object theobj = fobjIter.next(); if (theobj instanceof FONode) { @@ -250,35 +247,29 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager return getPSLM().getCurrentPage().getPageViewport(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean createNextChildLMs(int pos) { - List newLMs = createChildLMs(pos + 1 - childLMs.size()); + List<LayoutManager> newLMs = createChildLMs(pos + 1 - childLMs.size()); addChildLMs(newLMs); return pos < childLMs.size(); } - /** - * {@inheritDoc} - */ - public List getChildLMs() { + /** {@inheritDoc} */ + public List<LayoutManager> getChildLMs() { if (childLMs == null) { - childLMs = new java.util.ArrayList(10); + childLMs = new java.util.ArrayList<LayoutManager>(10); } return childLMs; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void addChildLM(LayoutManager lm) { if (lm == null) { return; } lm.setParent(this); if (childLMs == null) { - childLMs = new java.util.ArrayList(10); + childLMs = new java.util.ArrayList<LayoutManager>(10); } childLMs.add(lm); if (log.isTraceEnabled()) { @@ -287,17 +278,14 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void addChildLMs(List newLMs) { if (newLMs == null || newLMs.size() == 0) { return; } - ListIterator iter = newLMs.listIterator(); + ListIterator<LayoutManager> iter = newLMs.listIterator(); while (iter.hasNext()) { - LayoutManager lm = (LayoutManager) iter.next(); - addChildLM(lm); + addChildLM(iter.next()); } } @@ -312,8 +300,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager throw new IllegalStateException("Position already got its index"); } - lastGeneratedPosition++; - pos.setIndex(lastGeneratedPosition); + pos.setIndex(++lastGeneratedPosition); return pos; } @@ -358,7 +345,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager * @param targetArea the area to set the attributes on */ protected void transferForeignAttributes(AreaTreeObject targetArea) { - Map atts = fobj.getForeignAttributes(); + Map<QName, String> atts = fobj.getForeignAttributes(); targetArea.setForeignAttributes(atts); } @@ -459,18 +446,20 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager } /** {@inheritDoc} */ + @Override public String toString() { return (super.toString() + (fobj != null ? "[fobj=" + fobj.toString() + "]" : "")); } /** {@inheritDoc} */ + @Override public void reset() { isFinished = false; curChildLM = null; childLMiter = new LMiter(this); /* Reset all the children LM that have been created so far. */ - for (Iterator iter = getChildLMs().iterator(); iter.hasNext();) { - ((LayoutManager) iter.next()).reset(); + for (LayoutManager childLM : getChildLMs()) { + childLM.reset(); } if (fobj != null) { markers = fobj.getMarkers(); diff --git a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java index 755be91d1..1bacbd29b 100644 --- a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java +++ b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java @@ -19,7 +19,6 @@ package org.apache.fop.layoutmgr; -import java.util.Iterator; import java.util.LinkedList; import org.apache.fop.layoutmgr.SpaceResolver.SpaceHandlingBreakPosition; @@ -32,20 +31,6 @@ public final class AreaAdditionUtil { private AreaAdditionUtil() { } - private static class StackingIter extends PositionIterator { - StackingIter(Iterator parentIter) { - super(parentIter); - } - - protected LayoutManager getLM(Object nextObj) { - return ((Position) nextObj).getLM(); - } - - protected Position getPos(Object nextObj) { - return ((Position) nextObj); - } - } - /** * Creates the child areas for the given layout manager. * @param bslm the BlockStackingLayoutManager instance for which "addAreas" is performed. @@ -54,19 +39,23 @@ public final class AreaAdditionUtil { */ public static void addAreas(BlockStackingLayoutManager bslm, PositionIterator parentIter, LayoutContext layoutContext) { - LayoutManager childLM = null; + LayoutManager childLM; LayoutContext lc = new LayoutContext(0); LayoutManager firstLM = null; LayoutManager lastLM = null; Position firstPos = null; Position lastPos = null; + if (bslm != null) { + bslm.addId(); + } + // "unwrap" the NonLeafPositions stored in parentIter // and put them in a new list; - LinkedList positionList = new LinkedList(); + LinkedList<Position> positionList = new LinkedList<Position>(); Position pos; while (parentIter.hasNext()) { - pos = (Position)parentIter.next(); + pos = parentIter.next(); if (pos == null) { continue; } @@ -78,8 +67,8 @@ public final class AreaAdditionUtil { } if (pos instanceof NonLeafPosition) { // pos was created by a child of this FlowLM - positionList.add(((NonLeafPosition) pos).getPosition()); - lastLM = ((NonLeafPosition) pos).getPosition().getLM(); + positionList.add(pos.getPosition()); + lastLM = (pos.getPosition().getLM()); if (firstLM == null) { firstLM = lastLM; } @@ -104,7 +93,7 @@ public final class AreaAdditionUtil { bslm.isLast(lastPos)); } - StackingIter childPosIter = new StackingIter(positionList.listIterator()); + PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); while ((childLM = childPosIter.getNextChildLM()) != null) { // TODO vh: the test above might be problematic in some cases. See comment in @@ -129,6 +118,7 @@ public final class AreaAdditionUtil { false, bslm.isFirst(firstPos), bslm.isLast(lastPos)); + bslm.checkEndOfLayout(lastPos); } diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index 877da13dd..34403a956 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -23,7 +23,6 @@ import java.awt.Point; import java.awt.geom.Rectangle2D; import java.util.LinkedList; import java.util.List; -import java.util.ListIterator; import java.util.Stack; import org.apache.commons.logging.Log; @@ -41,7 +40,6 @@ import org.apache.fop.fo.properties.CommonAbsolutePosition; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; -import org.apache.fop.util.ListUtil; /** * LayoutManager for a block-container FO. @@ -88,6 +86,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager private MinOptMax effSpaceBefore; private MinOptMax effSpaceAfter; + private double contentRectOffsetX = 0; + private double contentRectOffsetY = 0; /** * Create a new block container layout manager. @@ -98,6 +98,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public void initialize() { abProps = getBlockContainerFO().getCommonAbsolutePosition(); foBlockSpaceBefore = new SpaceVal(getBlockContainerFO().getCommonMarginBlock() @@ -119,20 +120,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager .getOptimum(this).getLength(); } - bpUnit = 0; //layoutProps.blockProgressionUnit; - if (bpUnit == 0) { - // use optimum space values - adjustedSpaceBefore = getBlockContainerFO().getCommonMarginBlock() - .spaceBefore.getSpace().getOptimum(this).getLength().getValue(this); - adjustedSpaceAfter = getBlockContainerFO().getCommonMarginBlock() - .spaceAfter.getSpace().getOptimum(this).getLength().getValue(this); - } else { - // use minimum space values - adjustedSpaceBefore = getBlockContainerFO().getCommonMarginBlock() - .spaceBefore.getSpace().getMinimum(this).getLength().getValue(this); - adjustedSpaceAfter = getBlockContainerFO().getCommonMarginBlock() - .spaceAfter.getSpace().getMinimum(this).getLength().getValue(this); - } + // use optimum space values + adjustedSpaceBefore = getBlockContainerFO().getCommonMarginBlock() + .spaceBefore.getSpace().getOptimum(this).getLength().getValue(this); + adjustedSpaceAfter = getBlockContainerFO().getCommonMarginBlock() + .spaceAfter.getSpace().getOptimum(this).getLength().getValue(this); } private void resetSpaces() { @@ -169,8 +161,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } private boolean isAbsoluteOrFixed() { - return (abProps.absolutePosition == EN_ABSOLUTE) - || (abProps.absolutePosition == EN_FIXED); + return (abProps.absolutePosition == EN_ABSOLUTE + || abProps.absolutePosition == EN_FIXED); } private boolean isFixed() { @@ -178,6 +170,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public int getContentAreaBPD() { if (autoHeight) { return -1; @@ -187,126 +180,104 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public List getNextKnuthElements // CSOK: MethodLength - (LayoutContext context, int alignment) { - resetSpaces(); - if (isAbsoluteOrFixed()) { - return getNextKnuthElementsAbsolute(context, alignment); - } - - autoHeight = false; - //boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); - int maxbpd = context.getStackLimitBP().getOpt(); - int allocBPD; - if (height.getEnum() == EN_AUTO - || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) { - //auto height when height="auto" or "if that dimension is not specified explicitly - //(i.e., it depends on content's block-progression-dimension)" (XSL 1.0, 7.14.1) - allocBPD = maxbpd; - autoHeight = true; - if (getBlockContainerFO().getReferenceOrientation() == 0) { - //Cannot easily inline element list when ref-or="180" - inlineElementList = true; - } - } else { - allocBPD = height.getValue(this); //this is the content-height - allocBPD += getBPIndents(); - } - vpContentBPD = allocBPD - getBPIndents(); - - referenceIPD = context.getRefIPD(); - if (width.getEnum() == EN_AUTO) { - updateContentAreaIPDwithOverconstrainedAdjust(); - } else { - int contentWidth = width.getValue(this); - updateContentAreaIPDwithOverconstrainedAdjust(contentWidth); - } + @Override + public List getNextKnuthElements(LayoutContext context, int alignment) { + return getNextKnuthElements(context, alignment, null, null, null); + } - double contentRectOffsetX = 0; - contentRectOffsetX += getBlockContainerFO() - .getCommonMarginBlock().startIndent.getValue(this); - double contentRectOffsetY = 0; - contentRectOffsetY += getBlockContainerFO() - .getCommonBorderPaddingBackground().getBorderBeforeWidth(false); - contentRectOffsetY += getBlockContainerFO() - .getCommonBorderPaddingBackground().getPaddingBefore(false, this); + /** + * Overridden to handle writing-mode, and different stack limit + * setup. + * {@inheritDoc} + */ + @Override + protected LayoutContext makeChildLayoutContext(LayoutContext context) { + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimitBP( + context.getStackLimitBP().minus(MinOptMax.getInstance(relDims.bpd))); + childLC.setRefIPD(relDims.ipd); + childLC.setWritingMode(getBlockContainerFO().getWritingMode()); + return childLC; + } - updateRelDims(contentRectOffsetX, contentRectOffsetY, autoHeight); + /** {@inheritDoc} */ + @Override + public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack, + Position restartPosition, LayoutManager restartAtLM) { - int availableIPD = referenceIPD - getIPIndents(); - if (getContentAreaIPD() > availableIPD) { - BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get( - getBlockContainerFO().getUserAgent().getEventBroadcaster()); - eventProducer.objectTooWide(this, getBlockContainerFO().getName(), - getContentAreaIPD(), context.getRefIPD(), - getBlockContainerFO().getLocator()); + resetSpaces(); + // special treatment for position="absolute|fixed" + if (isAbsoluteOrFixed()) { + return getNextKnuthElementsAbsolute(context); } - MinOptMax stackLimit = MinOptMax.getInstance(relDims.bpd); + boolean isRestart = (lmStack != null); + boolean emptyStack = (!isRestart || lmStack.isEmpty()); - List returnedList; - List contentList = new LinkedList(); - List returnList = new LinkedList(); + setupAreaDimensions(context); - if (!breakBeforeServed) { - breakBeforeServed = true; - if (!context.suppressBreakBefore()) { - if (addKnuthElementsForBreakBefore(returnList, context)) { - return returnList; - } - } - } + List<ListElement> returnedList; + List<ListElement> contentList = new LinkedList<ListElement>(); + List<ListElement> returnList = new LinkedList<ListElement>(); - if (!firstVisibleMarkServed) { - addKnuthElementsForSpaceBefore(returnList, alignment); - context.updateKeepWithPreviousPending(getKeepWithPrevious()); + if (!breakBeforeServed(context, returnList)) { + return returnList; } - addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); - firstVisibleMarkServed = true; + addFirstVisibleMarks(returnList, context, alignment); if (autoHeight && inlineElementList) { - //Spaces, border and padding to be repeated at each break - addPendingMarks(context); LayoutManager curLM; // currently active LM LayoutManager prevLM = null; // previously active LM - while ((curLM = getChildLM()) != null) { - LayoutContext childLC = new LayoutContext(0); - childLC.copyPendingMarksFrom(context); - // curLM is a ? - childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit)); - childLC.setRefIPD(relDims.ipd); - childLC.setWritingMode(getBlockContainerFO().getWritingMode()); - if (curLM == this.childLMs.get(0)) { - childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE); - //Handled already by the parent (break collapsing, see above) + + LayoutContext childLC; + boolean doReset = isRestart; + if (isRestart) { + if (emptyStack) { + assert restartAtLM != null && restartAtLM.getParent() == this; + curLM = restartAtLM; + } else { + curLM = (LayoutManager) lmStack.pop(); + // make sure the initial LM is not reset + doReset = false; + } + setCurrentChildLM(curLM); + } else { + curLM = getChildLM(); + } + + while (curLM != null) { + if (doReset) { + curLM.reset(); } + childLC = makeChildLayoutContext(context); + // get elements from curLM - returnedList = curLM.getNextKnuthElements(childLC, alignment); + if (!isRestart || emptyStack) { + returnedList = getNextChildElements(curLM, context, childLC, alignment, + null, null, null); + } else { + returnedList = getNextChildElements(curLM, context, childLC, alignment, + lmStack, restartPosition, restartAtLM); + // once encountered, irrelevant for following child LMs + emptyStack = true; + // force reset as of the next child + doReset = true; + } if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) { //Propagate keep-with-previous up from the first child context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); childLC.clearKeepWithPreviousPending(); } if (returnedList.size() == 1 - && ((ListElement)returnedList.get(0)).isForcedBreak()) { + && ElementListUtils.startsWithForcedBreak(returnedList)) { // a descendant of this block has break-before - /* - if (returnList.size() == 0) { - // the first child (or its first child ...) has - // break-before; - // all this block, including space before, will be put in - // the - // following page - bSpaceBeforeServed = false; - }*/ contentList.addAll(returnedList); // "wrap" the Position inside each element // moving the elements from contentList to returnList - returnedList = new LinkedList(); wrapPositionElements(contentList, returnList); return returnList; @@ -329,9 +300,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager setFinished(true); } - returnedList = new LinkedList(); wrapPositionElements(contentList, returnList); - return returnList; } } @@ -339,20 +308,15 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); childLC.clearKeepsPending(); prevLM = curLM; + curLM = getChildLM(); } - - returnedList = new LinkedList(); wrapPositionElements(contentList, returnList); - } else { - returnList.add(refactoredBecauseOfDuplicateCode(contentRectOffsetX, - contentRectOffsetY)); + returnList.add(generateNonInlinedBox()); } - addKnuthElementsForBorderPaddingAfter(returnList, true); - addKnuthElementsForSpaceAfter(returnList, alignment); - //All child content is processed. Only break-after can occur now, so... - context.clearPendingMarks(); + addLastVisibleMarks(returnList, context, alignment); + addKnuthElementsForBreakAfter(returnList, context); context.updateKeepWithNextPending(getKeepWithNext()); @@ -361,72 +325,19 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager return returnList; } - private KnuthBox refactoredBecauseOfDuplicateCode(double contentRectOffsetX, - double contentRectOffsetY) { - - MinOptMax range = MinOptMax.getInstance(relDims.ipd); - BlockContainerBreaker breaker = new BlockContainerBreaker(this, range); - breaker.doLayout(relDims.bpd, autoHeight); - boolean contentOverflows = breaker.isOverflow(); - if (autoHeight) { - //Update content BPD now that it is known - int newHeight = breaker.deferredAlg.totalWidth; - if (blockProgressionDirectionChanges()) { - setContentAreaIPD(newHeight); - } else { - vpContentBPD = newHeight; - } - updateRelDims(contentRectOffsetX, contentRectOffsetY, false); - } - - Position bcPosition = new BlockContainerPosition(this, breaker); - KnuthBox knuthBox = new KnuthBox(vpContentBPD, notifyPos(bcPosition), false); - //TODO Handle min/opt/max for block-progression-dimension - /* These two elements will be used to add stretchability to the above box - returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, - false, returnPosition, false)); - returnList.add(new KnuthGlue(0, 1 * constantLineHeight, 0, - LINE_NUMBER_ADJUSTMENT, returnPosition, false)); - */ - - if (contentOverflows) { - BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get( - getBlockContainerFO().getUserAgent().getEventBroadcaster()); - boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW); - eventProducer.viewportOverflow(this, getBlockContainerFO().getName(), - breaker.getOverflowAmount(), needClip(), canRecover, - getBlockContainerFO().getLocator()); - } - return knuthBox; - } - - private boolean blockProgressionDirectionChanges() { - return getBlockContainerFO().getReferenceOrientation() % 180 != 0; - } - - /** {@inheritDoc} */ - public List getNextKnuthElements // CSOK: MethodLength - (LayoutContext context, int alignment, Stack lmStack, - Position restartPosition, LayoutManager restartAtLM) { - resetSpaces(); - if (isAbsoluteOrFixed()) { - return getNextKnuthElementsAbsolute(context, alignment); - } - + private void setupAreaDimensions(LayoutContext context) { autoHeight = false; - //boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); int maxbpd = context.getStackLimitBP().getOpt(); int allocBPD; + BlockContainer fo = getBlockContainerFO(); if (height.getEnum() == EN_AUTO || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) { //auto height when height="auto" or "if that dimension is not specified explicitly //(i.e., it depends on content's block-progression-dimension)" (XSL 1.0, 7.14.1) allocBPD = maxbpd; autoHeight = true; - if (getBlockContainerFO().getReferenceOrientation() == 0) { - //Cannot easily inline element list when ref-or="180" - inlineElementList = true; - } + //Cannot easily inline element list when ref-or<>"0" + inlineElementList = (fo.getReferenceOrientation() == 0); } else { allocBPD = height.getValue(this); //this is the content-height allocBPD += getBPIndents(); @@ -441,243 +352,71 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager updateContentAreaIPDwithOverconstrainedAdjust(contentWidth); } - double contentRectOffsetX = 0; - contentRectOffsetX += getBlockContainerFO() - .getCommonMarginBlock().startIndent.getValue(this); - double contentRectOffsetY = 0; - contentRectOffsetY += getBlockContainerFO() - .getCommonBorderPaddingBackground().getBorderBeforeWidth(false); - contentRectOffsetY += getBlockContainerFO() - .getCommonBorderPaddingBackground().getPaddingBefore(false, this); + contentRectOffsetX += fo.getCommonMarginBlock().startIndent.getValue(this); + contentRectOffsetY += fo.getCommonBorderPaddingBackground().getBorderBeforeWidth(false); + contentRectOffsetY += fo.getCommonBorderPaddingBackground().getPaddingBefore(false, this); - updateRelDims(contentRectOffsetX, contentRectOffsetY, autoHeight); + updateRelDims(); int availableIPD = referenceIPD - getIPIndents(); if (getContentAreaIPD() > availableIPD) { BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get( - getBlockContainerFO().getUserAgent().getEventBroadcaster()); - eventProducer.objectTooWide(this, getBlockContainerFO().getName(), + fo.getUserAgent().getEventBroadcaster()); + eventProducer.objectTooWide(this, fo.getName(), getContentAreaIPD(), context.getRefIPD(), - getBlockContainerFO().getLocator()); - } - - MinOptMax stackLimit = MinOptMax.getInstance(relDims.bpd); - - List returnedList; - List contentList = new LinkedList(); - List returnList = new LinkedList(); - - if (!breakBeforeServed) { - breakBeforeServed = true; - if (!context.suppressBreakBefore()) { - if (addKnuthElementsForBreakBefore(returnList, context)) { - return returnList; - } - } + fo.getLocator()); } + } - if (!firstVisibleMarkServed) { - addKnuthElementsForSpaceBefore(returnList, alignment); - context.updateKeepWithPreviousPending(getKeepWithPrevious()); - } - - addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); - firstVisibleMarkServed = true; - - if (autoHeight && inlineElementList) { - //Spaces, border and padding to be repeated at each break - addPendingMarks(context); - - BlockLevelLayoutManager curLM; // currently active LM - BlockLevelLayoutManager prevLM = null; // previously active LM - - LayoutContext childLC = new LayoutContext(0); - if (lmStack.isEmpty()) { - assert restartAtLM != null && restartAtLM.getParent() == this; - curLM = (BlockLevelLayoutManager) restartAtLM; - curLM.reset(); - setCurrentChildLM(curLM); - - childLC.copyPendingMarksFrom(context); - childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit)); - childLC.setRefIPD(relDims.ipd); - childLC.setWritingMode(getBlockContainerFO().getWritingMode()); - if (curLM == this.childLMs.get(0)) { - childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE); - //Handled already by the parent (break collapsing, see above) - } - - // get elements from curLM - returnedList = curLM.getNextKnuthElements(childLC, alignment); - } else { - curLM = (BlockLevelLayoutManager) lmStack.pop(); - setCurrentChildLM(curLM); - - childLC.copyPendingMarksFrom(context); - childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit)); - childLC.setRefIPD(relDims.ipd); - childLC.setWritingMode(getBlockContainerFO().getWritingMode()); - if (curLM == this.childLMs.get(0)) { - childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE); - //Handled already by the parent (break collapsing, see above) - } + private KnuthBox generateNonInlinedBox() { - // get elements from curLM - returnedList = curLM.getNextKnuthElements(childLC, alignment, lmStack, - restartPosition, restartAtLM); - } - if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) { - //Propagate keep-with-previous up from the first child - context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); - childLC.clearKeepWithPreviousPending(); - } - if (returnedList.size() == 1 - && ((ListElement)returnedList.get(0)).isForcedBreak()) { - // a descendant of this block has break-before - /* - if (returnList.size() == 0) { - // the first child (or its first child ...) has - // break-before; - // all this block, including space before, will be put in - // the - // following page - bSpaceBeforeServed = false; - }*/ - contentList.addAll(returnedList); - - // "wrap" the Position inside each element - // moving the elements from contentList to returnList - returnedList = new LinkedList(); - wrapPositionElements(contentList, returnList); - - return returnList; + MinOptMax range = MinOptMax.getInstance(relDims.ipd); + BlockContainerBreaker breaker = new BlockContainerBreaker(this, range); + breaker.doLayout(relDims.bpd, autoHeight); + boolean contentOverflows = breaker.isOverflow(); + if (autoHeight) { + //Update content BPD now that it is known + int newHeight = breaker.deferredAlg.totalWidth; + if (blockProgressionDirectionChanges()) { + setContentAreaIPD(newHeight); } else { - if (prevLM != null) { - // there is a block handled by prevLM - // before the one handled by curLM - addInBetweenBreak(contentList, context, childLC); - } - contentList.addAll(returnedList); - if (!returnedList.isEmpty()) { - if (((ListElement) ListUtil.getLast(returnedList)) - .isForcedBreak()) { - // a descendant of this block has break-after - if (curLM.isFinished()) { - // there is no other content in this block; - // it's useless to add space after before a page break - setFinished(true); - } - - returnedList = new LinkedList(); - wrapPositionElements(contentList, returnList); - - return returnList; - } - } - } - // propagate and clear - context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); - childLC.clearKeepsPending(); - prevLM = curLM; - - while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) { - curLM.reset(); - childLC = new LayoutContext(0); - childLC.copyPendingMarksFrom(context); - // curLM is a ? - childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit)); - childLC.setRefIPD(relDims.ipd); - childLC.setWritingMode(getBlockContainerFO().getWritingMode()); - if (curLM == this.childLMs.get(0)) { - childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE); - //Handled already by the parent (break collapsing, see above) - } - - // get elements from curLM - returnedList = curLM.getNextKnuthElements(childLC, alignment); - if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) { - //Propagate keep-with-previous up from the first child - context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); - childLC.clearKeepWithPreviousPending(); - } - if (returnedList.size() == 1 - && ((ListElement)returnedList.get(0)).isForcedBreak()) { - // a descendant of this block has break-before - /* - if (returnList.size() == 0) { - // the first child (or its first child ...) has - // break-before; - // all this block, including space before, will be put in - // the - // following page - bSpaceBeforeServed = false; - }*/ - contentList.addAll(returnedList); - - // "wrap" the Position inside each element - // moving the elements from contentList to returnList - returnedList = new LinkedList(); - wrapPositionElements(contentList, returnList); - - return returnList; - } else { - if (prevLM != null) { - // there is a block handled by prevLM - // before the one handled by curLM - addInBetweenBreak(contentList, context, childLC); - } - contentList.addAll(returnedList); - if (returnedList.isEmpty()) { - //Avoid NoSuchElementException below (happens with empty blocks) - continue; - } - if (((ListElement) ListUtil.getLast(returnedList)) - .isForcedBreak()) { - // a descendant of this block has break-after - if (curLM.isFinished()) { - // there is no other content in this block; - // it's useless to add space after before a page break - setFinished(true); - } - - returnedList = new LinkedList(); - wrapPositionElements(contentList, returnList); - - return returnList; - } - } - // propagate and clear - context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); - childLC.clearKeepsPending(); - prevLM = curLM; + vpContentBPD = newHeight; } - - returnedList = new LinkedList(); - wrapPositionElements(contentList, returnList); - - } else { - returnList.add(refactoredBecauseOfDuplicateCode(contentRectOffsetX, - contentRectOffsetY)); + updateRelDims(); } - addKnuthElementsForBorderPaddingAfter(returnList, true); - addKnuthElementsForSpaceAfter(returnList, alignment); - //All child content is processed. Only break-after can occur now, so... - context.clearPendingMarks(); - addKnuthElementsForBreakAfter(returnList, context); + Position bcPosition = new BlockContainerPosition(this, breaker); + KnuthBox knuthBox = new KnuthBox(vpContentBPD, notifyPos(bcPosition), false); + //TODO Handle min/opt/max for block-progression-dimension + /* These two elements will be used to add stretchability to the above box + returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, + false, returnPosition, false)); + returnList.add(new KnuthGlue(0, 1 * constantLineHeight, 0, + LINE_NUMBER_ADJUSTMENT, returnPosition, false)); + */ - context.updateKeepWithNextPending(getKeepWithNext()); + if (contentOverflows) { + BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get( + getBlockContainerFO().getUserAgent().getEventBroadcaster()); + boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW); + eventProducer.viewportOverflow(this, getBlockContainerFO().getName(), + breaker.getOverflowAmount(), needClip(), canRecover, + getBlockContainerFO().getLocator()); + } + return knuthBox; + } - setFinished(true); - return returnList; + private boolean blockProgressionDirectionChanges() { + return getBlockContainerFO().getReferenceOrientation() % 180 != 0; } /** {@inheritDoc} */ + @Override public boolean isRestartable() { return true; } - private List getNextKnuthElementsAbsolute(LayoutContext context, int alignment) { + private List<ListElement> getNextKnuthElementsAbsolute(LayoutContext context) { autoHeight = false; boolean bpDirectionChanges = blockProgressionDirectionChanges(); @@ -783,7 +522,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager vpContentBPD = allocBPD - getBPIndents(); setContentAreaIPD(allocIPD - getIPIndents()); - updateRelDims(0, 0, autoHeight); + contentRectOffsetX = 0; + contentRectOffsetY = 0; + updateRelDims(); MinOptMax range = MinOptMax.getInstance(relDims.ipd); BlockContainerBreaker breaker = new BlockContainerBreaker(this, range); @@ -797,9 +538,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } else { vpContentBPD = newHeight; } - updateRelDims(0, 0, false); + updateRelDims(); } - List returnList = new LinkedList(); + List<ListElement> returnList = new LinkedList<ListElement>(); if (!breaker.isEmpty()) { Position bcPosition = new BlockContainerPosition(this, breaker); returnList.add(new KnuthBox(0, notifyPos(bcPosition), false)); @@ -819,9 +560,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager return returnList; } - private void updateRelDims(double xOffset, double yOffset, boolean skipAutoHeight) { + private void updateRelDims() { Rectangle2D rect = new Rectangle2D.Double( - xOffset, yOffset, + contentRectOffsetX, contentRectOffsetY, getContentAreaIPD(), this.vpContentBPD); relDims = new FODimension(0, 0); @@ -879,7 +620,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } public int getDifferenceOfFirstPart() { - PageBreakPosition pbp = (PageBreakPosition)this.deferredAlg.getPageBreaks().getFirst(); + PageBreakPosition pbp = this.deferredAlg.getPageBreaks().getFirst(); return pbp.difference; } @@ -908,13 +649,10 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager protected List getNextKnuthElements(LayoutContext context, int alignment) { LayoutManager curLM; // currently active LM - List returnList = new LinkedList(); + List<ListElement> returnList = new LinkedList<ListElement>(); while ((curLM = getChildLM()) != null) { - LayoutContext childLC = new LayoutContext(0); - childLC.setStackLimitBP(context.getStackLimitBP()); - childLC.setRefIPD(context.getRefIPD()); - childLC.setWritingMode(getBlockContainerFO().getWritingMode()); + LayoutContext childLC = makeChildLayoutContext(context); List returnedList = null; if (!curLM.isFinished()) { @@ -992,8 +730,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public void addAreas // CSOK: MethodLength - (PositionIterator parentIter, LayoutContext layoutContext) { + @Override + public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { getParentArea(null); // if this will create the first block area in a page @@ -1015,14 +753,12 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager // "unwrap" the NonLeafPositions stored in parentIter // and put them in a new list; - List positionList = new LinkedList(); + List<Position> positionList = new LinkedList<Position>(); Position pos; - boolean bSpaceBefore = false; - boolean bSpaceAfter = false; Position firstPos = null; Position lastPos = null; while (parentIter.hasNext()) { - pos = (Position) parentIter.next(); + pos = parentIter.next(); if (pos.getIndex() >= 0) { if (firstPos == null) { firstPos = pos; @@ -1041,20 +777,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager //Add child areas inside the reference area //bcpos.getBreaker().addContainedAreas(); } else if (innerPosition == null) { - if (pos instanceof NonLeafPosition) { - // pos was created by this BCLM and was inside an element - // representing space before or after - // this means the space was not discarded - if (positionList.isEmpty() && bcpos == null) { - // pos was in the element representing space-before - bSpaceBefore = true; - } else { - // pos was in the element representing space-after - bSpaceAfter = true; - } - } else { - //ignore (probably a Position for a simple penalty between blocks) - } + //ignore (probably a Position for a simple penalty between blocks) } else if (innerPosition.getLM() == this && !(innerPosition instanceof MappingPosition)) { // pos was created by this BlockLM and was inside a penalty @@ -1072,86 +795,15 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager addMarkersToPage(true, isFirst(firstPos), isLast(lastPos)); if (bcpos == null) { - if (bpUnit == 0) { - // the Positions in positionList were inside the elements - // created by the LineLM - childPosIter = new StackingIter(positionList.listIterator()); - } else { - // the Positions in positionList were inside the elements - // created by the BCLM in the createUnitElements() method - //if (((Position) positionList.getLast()) instanceof - // LeafPosition) { - // // the last item inside positionList is a LeafPosition - // // (a LineBreakPosition, more precisely); this means that - // // the whole paragraph is on the same page - // childPosIter = new KnuthPossPosIter(storedList, 0, - // storedList.size()); - //} else { - // // the last item inside positionList is a Position; - // // this means that the paragraph has been split - // // between consecutive pages - List splitList = new LinkedList(); - int splitLength = 0; - int iFirst = ((MappingPosition) positionList.get(0)) - .getFirstIndex(); - int iLast = ((MappingPosition) ListUtil.getLast(positionList)) - .getLastIndex(); - // copy from storedList to splitList all the elements from - // iFirst to iLast - ListIterator storedListIterator = storedList.listIterator(iFirst); - while (storedListIterator.nextIndex() <= iLast) { - KnuthElement element = (KnuthElement) storedListIterator - .next(); - // some elements in storedList (i.e. penalty items) were created - // by this BlockLM, and must be ignored - if (element.getLayoutManager() != this) { - splitList.add(element); - splitLength += element.getWidth(); - lastLM = element.getLayoutManager(); - } - } - //log.debug("Adding areas from " + iFirst + " to " + iLast); - //log.debug("splitLength= " + splitLength - // + " (" + neededUnits(splitLength) + " units') " - // + (neededUnits(splitLength) * bpUnit - splitLength) - // + " spacing"); - // add space before and / or after the paragraph - // to reach a multiple of bpUnit - if (bSpaceBefore && bSpaceAfter) { - foBlockSpaceBefore = new SpaceVal(getBlockContainerFO() - .getCommonMarginBlock().spaceBefore, this).getSpace(); - foBlockSpaceAfter = new SpaceVal(getBlockContainerFO() - .getCommonMarginBlock().spaceAfter, this).getSpace(); - adjustedSpaceBefore = (neededUnits(splitLength - + foBlockSpaceBefore.getMin() - + foBlockSpaceAfter.getMin()) - * bpUnit - splitLength) / 2; - adjustedSpaceAfter = neededUnits(splitLength - + foBlockSpaceBefore.getMin() - + foBlockSpaceAfter.getMin()) - * bpUnit - splitLength - adjustedSpaceBefore; - } else if (bSpaceBefore) { - adjustedSpaceBefore = neededUnits(splitLength - + foBlockSpaceBefore.getMin()) - * bpUnit - splitLength; - } else { - adjustedSpaceAfter = neededUnits(splitLength - + foBlockSpaceAfter.getMin()) - * bpUnit - splitLength; - } - //log.debug("space before = " + adjustedSpaceBefore - // + " space after = " + adjustedSpaceAfter + " total = " + - // (adjustedSpaceBefore + adjustedSpaceAfter + splitLength)); - childPosIter = new KnuthPossPosIter(splitList, 0, splitList - .size()); - //} - } + // the Positions in positionList were inside the elements + // created by the LineLM + childPosIter = new PositionIterator(positionList.listIterator()); while ((childLM = childPosIter.getNextChildLM()) != null) { // set last area flag lc.setFlags(LayoutContext.LAST_AREA, (layoutContext.isLastArea() && childLM == lastLM)); - /*LF*/lc.setStackLimitBP(layoutContext.getStackLimitBP()); + lc.setStackLimitBP(layoutContext.getStackLimitBP()); // Add the line areas to Area childLM.addAreas(childPosIter, lc); } @@ -1180,6 +832,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager * * {@inheritDoc} */ + @Override public Area getParentArea(Area childArea) { if (referenceArea == null) { boolean switchedProgressionDirection = blockProgressionDirectionChanges(); @@ -1203,9 +856,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager TraitSetter.addPadding(viewportBlockArea, getBlockContainerFO().getCommonBorderPaddingBackground(), discardPaddingBefore, discardPaddingAfter, false, false, this); - // TraitSetter.addBackground(viewportBlockArea, - // getBlockContainerFO().getCommonBorderPaddingBackground(), - // this); TraitSetter.addMargins(viewportBlockArea, getBlockContainerFO().getCommonBorderPaddingBackground(), startIndent, endIndent, @@ -1213,13 +863,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager viewportBlockArea.setCTM(absoluteCTM); viewportBlockArea.setClip(needClip()); - /* - if (getSpaceBefore() != 0) { - viewportBlockArea.addTrait(Trait.SPACE_BEFORE, new Integer(getSpaceBefore())); - } - if (foBlockSpaceAfter.opt != 0) { - viewportBlockArea.addTrait(Trait.SPACE_AFTER, new Integer(foBlockSpaceAfter.opt)); - }*/ if (abProps.absolutePosition == EN_ABSOLUTE || abProps.absolutePosition == EN_FIXED) { @@ -1256,6 +899,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager * * {@inheritDoc} */ + @Override public void addChildArea(Area childArea) { if (referenceArea != null) { referenceArea.addBlock((Block) childArea); @@ -1266,6 +910,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager * Force current area to be added to parent area. * {@inheritDoc} */ + @Override protected void flush() { viewportBlockArea.addBlock(referenceArea, autoHeight); @@ -1277,28 +922,32 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) { // TODO Auto-generated method stub return 0; } /** {@inheritDoc} */ + @Override public void discardSpace(KnuthGlue spaceGlue) { // TODO Auto-generated method stub - } /** {@inheritDoc} */ + @Override public KeepProperty getKeepTogetherProperty() { return getBlockContainerFO().getKeepTogether(); } /** {@inheritDoc} */ + @Override public KeepProperty getKeepWithPreviousProperty() { return getBlockContainerFO().getKeepWithPrevious(); } /** {@inheritDoc} */ + @Override public KeepProperty getKeepWithNextProperty() { return getBlockContainerFO().getKeepWithNext(); } @@ -1313,11 +962,13 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager // --------- Property Resolution related functions --------- // /** {@inheritDoc} */ + @Override public boolean getGeneratesReferenceArea() { return true; } /** {@inheritDoc} */ + @Override public boolean getGeneratesBlockArea() { return true; } diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index 62e89bdb0..55c5cfd66 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -46,15 +46,13 @@ import org.apache.fop.traits.SpaceVal; public class BlockLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener { - /** - * logging instance - */ + /** logging instance */ private static Log log = LogFactory.getLog(BlockLayoutManager.class); private Block curBlockArea; /** Iterator over the child layout managers. */ - protected ListIterator proxyLMiter; + protected ListIterator<LayoutManager> proxyLMiter; private int lead = 12000; private Length lineHeight; @@ -78,52 +76,77 @@ public class BlockLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public void initialize() { super.initialize(); - FontInfo fi = getBlockFO().getFOEventHandler().getFontInfo(); - FontTriplet[] fontkeys = getBlockFO().getCommonFont().getFontState(fi); + org.apache.fop.fo.flow.Block fo = getBlockFO(); + FontInfo fi = fo.getFOEventHandler().getFontInfo(); + FontTriplet[] fontkeys = fo.getCommonFont().getFontState(fi); Font initFont = fi.getFontInstance(fontkeys[0], getBlockFO().getCommonFont().fontSize.getValue(this)); lead = initFont.getAscender(); follow = -initFont.getDescender(); //middleShift = -fs.getXHeight() / 2; - lineHeight = getBlockFO().getLineHeight().getOptimum(this).getLength(); - startIndent = getBlockFO().getCommonMarginBlock().startIndent.getValue(this); - endIndent = getBlockFO().getCommonMarginBlock().endIndent.getValue(this); - foSpaceBefore = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceBefore, this) - .getSpace(); - foSpaceAfter = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceAfter, this) - .getSpace(); - bpUnit = 0; // non-standard extension - if (bpUnit == 0) { - // use optimum space values - adjustedSpaceBefore = getBlockFO().getCommonMarginBlock().spaceBefore.getSpace() - .getOptimum(this).getLength().getValue(this); - adjustedSpaceAfter = getBlockFO().getCommonMarginBlock().spaceAfter.getSpace() - .getOptimum(this).getLength().getValue(this); - } else { - // use minimum space values - adjustedSpaceBefore = getBlockFO().getCommonMarginBlock().spaceBefore.getSpace() - .getMinimum(this).getLength().getValue(this); - adjustedSpaceAfter = getBlockFO().getCommonMarginBlock().spaceAfter.getSpace() - .getMinimum(this).getLength().getValue(this); - } + lineHeight = fo.getLineHeight().getOptimum(this).getLength(); + startIndent = fo.getCommonMarginBlock().startIndent.getValue(this); + endIndent = fo.getCommonMarginBlock().endIndent.getValue(this); + foSpaceBefore = new SpaceVal(fo.getCommonMarginBlock().spaceBefore, this).getSpace(); + foSpaceAfter = new SpaceVal(fo.getCommonMarginBlock().spaceAfter, this).getSpace(); + // use optimum space values + adjustedSpaceBefore = fo.getCommonMarginBlock().spaceBefore.getSpace() + .getOptimum(this).getLength().getValue(this); + adjustedSpaceAfter = fo.getCommonMarginBlock().spaceAfter.getSpace() + .getOptimum(this).getLength().getValue(this); } /** {@inheritDoc} */ + @Override public List getNextKnuthElements(LayoutContext context, int alignment) { return getNextKnuthElements(context, alignment, null, null, null); } /** {@inheritDoc} */ + @Override public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack, Position restartPosition, LayoutManager restartAtLM) { resetSpaces(); + return super.getNextKnuthElements( + context, alignment, lmStack, restartPosition, restartAtLM); + } + + /** + * Overridden to take into account that the childLM may be the block's + * {@link LineLayoutManager}. + * {@inheritDoc} + */ + @Override + protected List<ListElement> getNextChildElements(LayoutManager childLM, LayoutContext context, + LayoutContext childLC, int alignment, Stack lmStack, Position restartPosition, + LayoutManager restartAtLM) { + + childLC.copyPendingMarksFrom(context); + + if (childLM instanceof LineLayoutManager) { + childLC.setRefIPD(getContentAreaIPD()); + } else { + // nop; will have been properly set by makeChildLayoutContext() + } + + if (childLM == this.childLMs.get(0)) { + childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE); + //Handled already by the parent (break collapsing, see above) + } + if (lmStack == null) { - return super.getNextKnuthElements(context, alignment); + return childLM.getNextKnuthElements(childLC, alignment); } else { - return super.getNextKnuthElements(context, alignment, lmStack, restartPosition, - restartAtLM); + if (childLM instanceof LineLayoutManager) { + return ((LineLayoutManager) childLM).getNextKnuthElements(childLC, alignment, + (LeafPosition) restartPosition); + } else { + return childLM.getNextKnuthElements(childLC, alignment, + lmStack, restartPosition, restartAtLM); + } } } @@ -151,7 +174,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager */ public ProxyLMiter() { super(BlockLayoutManager.this); - listLMs = new java.util.ArrayList(10); + listLMs = new java.util.ArrayList<LayoutManager>(10); } /** @@ -166,7 +189,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager * @return true if new child lms were added */ protected boolean createNextChildLMs(int pos) { - List newLMs = createChildLMs(pos + 1 - listLMs.size()); + List<LayoutManager> newLMs = createChildLMs(pos + 1 - listLMs.size()); if (newLMs != null) { listLMs.addAll(newLMs); } @@ -174,13 +197,12 @@ public class BlockLayoutManager extends BlockStackingLayoutManager } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public boolean createNextChildLMs(int pos) { while (proxyLMiter.hasNext()) { - LayoutManager lm = (LayoutManager) proxyLMiter.next(); + LayoutManager lm = proxyLMiter.next(); if (lm instanceof InlineLevelLayoutManager) { LineLayoutManager lineLM = createLineManager(lm); addChildLM(lineLM); @@ -203,10 +225,10 @@ public class BlockLayoutManager extends BlockStackingLayoutManager private LineLayoutManager createLineManager(LayoutManager firstlm) { LineLayoutManager llm; llm = new LineLayoutManager(getBlockFO(), lineHeight, lead, follow); - List inlines = new java.util.ArrayList(); + List<LayoutManager> inlines = new java.util.ArrayList<LayoutManager>(); inlines.add(firstlm); while (proxyLMiter.hasNext()) { - LayoutManager lm = (LayoutManager) proxyLMiter.next(); + LayoutManager lm = proxyLMiter.next(); if (lm instanceof InlineLevelLayoutManager) { inlines.add(lm); } else { @@ -219,23 +241,26 @@ public class BlockLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public KeepProperty getKeepTogetherProperty() { return getBlockFO().getKeepTogether(); } /** {@inheritDoc} */ + @Override public KeepProperty getKeepWithPreviousProperty() { return getBlockFO().getKeepWithPrevious(); } /** {@inheritDoc} */ + @Override public KeepProperty getKeepWithNextProperty() { return getBlockFO().getKeepWithNext(); } /** {@inheritDoc} */ - public void addAreas // CSOK: MethodLength - (PositionIterator parentIter, LayoutContext layoutContext) { + @Override + public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { getParentArea(null); // if this will create the first block area in a page @@ -256,14 +281,12 @@ public class BlockLayoutManager extends BlockStackingLayoutManager // "unwrap" the NonLeafPositions stored in parentIter // and put them in a new list; - LinkedList positionList = new LinkedList(); + LinkedList<Position> positionList = new LinkedList<Position>(); Position pos; - boolean spaceBefore = false; - boolean spaceAfter = false; Position firstPos = null; Position lastPos = null; while (parentIter.hasNext()) { - pos = (Position) parentIter.next(); + pos = parentIter.next(); //log.trace("pos = " + pos.getClass().getName() + "; " + pos); if (pos.getIndex() >= 0) { if (firstPos == null) { @@ -276,30 +299,13 @@ public class BlockLayoutManager extends BlockStackingLayoutManager //Not all elements are wrapped innerPosition = pos.getPosition(); } - if (innerPosition == null) { - // pos was created by this BlockLM and was inside an element - // representing space before or after - // this means the space was not discarded - if (positionList.size() == 0) { - // pos was in the element representing space-before - spaceBefore = true; - //log.trace(" space before"); - } else { - // pos was in the element representing space-after - spaceAfter = true; - //log.trace(" space-after"); - } - } else if (innerPosition.getLM() == this - && !(innerPosition instanceof MappingPosition)) { - // pos was created by this BlockLM and was inside a penalty - // allowing or forbidding a page break - // nothing to do - //log.trace(" penalty"); - } else { + + if (innerPosition != null + && (innerPosition.getLM() != this + || innerPosition instanceof MappingPosition)) { // innerPosition was created by another LM positionList.add(innerPosition); lastLM = innerPosition.getLM(); - //log.trace(" " + innerPosition.getClass().getName()); } } @@ -307,78 +313,9 @@ public class BlockLayoutManager extends BlockStackingLayoutManager addMarkersToPage(true, isFirst(firstPos), isLast(lastPos)); - if (bpUnit == 0) { - // the Positions in positionList were inside the elements - // created by the LineLM - childPosIter = new StackingIter(positionList.listIterator()); - } else { - // the Positions in positionList were inside the elements - // created by the BlockLM in the createUnitElements() method - //if (((Position) positionList.getLast()) instanceof - // LeafPosition) { - // // the last item inside positionList is a LeafPosition - // // (a LineBreakPosition, more precisely); this means that - // // the whole paragraph is on the same page - // childPosIter = new KnuthPossPosIter(storedList, 0, - // storedList.size()); - //} else { - // // the last item inside positionList is a Position; - // // this means that the paragraph has been split - // // between consecutive pages - LinkedList splitList = new LinkedList(); - int splitLength = 0; - int iFirst = ((MappingPosition) positionList.getFirst()).getFirstIndex(); - int iLast = ((MappingPosition) positionList.getLast()).getLastIndex(); - // copy from storedList to splitList all the elements from - // iFirst to iLast - ListIterator storedListIterator = storedList.listIterator(iFirst); - while (storedListIterator.nextIndex() <= iLast) { - KnuthElement element = (KnuthElement) storedListIterator - .next(); - // some elements in storedList (i.e. penalty items) were created - // by this BlockLM, and must be ignored - if (element.getLayoutManager() != this) { - splitList.add(element); - splitLength += element.getWidth(); - lastLM = element.getLayoutManager(); - } - } - //log.debug("Adding areas from " + iFirst + " to " + iLast); - //log.debug("splitLength= " + splitLength - // + " (" + neededUnits(splitLength) + " units') " - // + (neededUnits(splitLength) * bpUnit - splitLength) - // + " spacing"); - // add space before and / or after the paragraph - // to reach a multiple of bpUnit - if (spaceBefore && spaceAfter) { - foSpaceBefore = new SpaceVal(getBlockFO() - .getCommonMarginBlock().spaceBefore, this).getSpace(); - foSpaceAfter = new SpaceVal(getBlockFO() - .getCommonMarginBlock().spaceAfter, this).getSpace(); - adjustedSpaceBefore = (neededUnits(splitLength - + foSpaceBefore.getMin() - + foSpaceAfter.getMin()) - * bpUnit - splitLength) / 2; - adjustedSpaceAfter = neededUnits(splitLength - + foSpaceBefore.getMin() - + foSpaceAfter.getMin()) - * bpUnit - splitLength - adjustedSpaceBefore; - } else if (spaceBefore) { - adjustedSpaceBefore = neededUnits(splitLength - + foSpaceBefore.getMin()) - * bpUnit - splitLength; - } else { - adjustedSpaceAfter = neededUnits(splitLength - + foSpaceAfter.getMin()) - * bpUnit - splitLength; - } - //log.debug("spazio prima = " + adjustedSpaceBefore - // + " spazio dopo = " + adjustedSpaceAfter + " totale = " + - // (adjustedSpaceBefore + adjustedSpaceAfter + splitLength)); - childPosIter = new KnuthPossPosIter(splitList, 0, splitList - .size()); - //} - } + // the Positions in positionList were inside the elements + // created by the LineLM + childPosIter = new PositionIterator(positionList.listIterator()); while ((childLM = childPosIter.getNextChildLM()) != null) { // set last area flag @@ -415,6 +352,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager * @param childArea area to get the parent area for * @return the parent area */ + @Override public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); @@ -446,9 +384,8 @@ public class BlockLayoutManager extends BlockStackingLayoutManager return curBlockArea; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public void addChildArea(Area childArea) { if (curBlockArea != null) { if (childArea instanceof LineArea) { @@ -463,6 +400,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager * Force current area to be added to parent area. * {@inheritDoc} */ + @Override protected void flush() { if (curBlockArea != null) { TraitSetter.addBackground(curBlockArea, @@ -486,6 +424,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager * Returns the IPD of the content area * @return the IPD of the content area */ + @Override public int getContentAreaIPD() { if (curBlockArea != null) { return curBlockArea.getIPD(); @@ -498,6 +437,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager * Returns the BPD of the content area * @return the BPD of the content area */ + @Override public int getContentAreaBPD() { if (curBlockArea != null) { return curBlockArea.getBPD(); @@ -505,9 +445,8 @@ public class BlockLayoutManager extends BlockStackingLayoutManager return -1; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public boolean getGeneratesBlockArea() { return true; } @@ -558,6 +497,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public boolean isRestartable() { return true; } diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index fd9f2a822..f5cb983b2 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -19,7 +19,6 @@ package org.apache.fop.layoutmgr; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; @@ -38,7 +37,6 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.SpaceProperty; import org.apache.fop.layoutmgr.inline.InlineLayoutManager; -import org.apache.fop.layoutmgr.inline.LineLayoutManager; import org.apache.fop.traits.MinOptMax; import org.apache.fop.util.BreakUtil; import org.apache.fop.util.ListUtil; @@ -50,9 +48,7 @@ import org.apache.fop.util.ListUtil; public abstract class BlockStackingLayoutManager extends AbstractLayoutManager implements BlockLevelLayoutManager { - /** - * logging instance - */ + /** logging instance */ private static Log log = LogFactory.getLog(BlockStackingLayoutManager.class); /** parent area */ @@ -65,7 +61,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager /** space-after value adjusted for block-progression-unit handling */ protected int adjustedSpaceAfter; /** Only used to store the original list when createUnitElements is called */ - protected List storedList; + protected List<KnuthElement> storedList; /** Indicates whether break before has been served or not */ protected boolean breakBeforeServed; /** Indicates whether the first visible mark has been returned by this LM, yet */ @@ -162,17 +158,11 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * If so, add it. Otherwise initiate breaking. * @param childArea the area to add: will be some block-stacked Area. */ + @Override public void addChildArea(Area childArea) { addChildToArea(childArea, getCurrentArea()); } - /** {@inheritDoc} */ - protected void notifyEndOfLayout() { - super.notifyEndOfLayout(); - // Free memory of the area tree - //this.parentArea = null; - } - /** * Force current area to be added to parent area. */ @@ -244,108 +234,143 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } /** {@inheritDoc} */ + @Override public List getNextKnuthElements(LayoutContext context, int alignment) { + return getNextKnuthElements(context, alignment, null, null, null); + } + + /** {@inheritDoc} */ + @Override + public List getNextKnuthElements(LayoutContext context, int alignment, + Stack lmStack, Position restartPosition, LayoutManager restartAtLM) { referenceIPD = context.getRefIPD(); updateContentAreaIPDwithOverconstrainedAdjust(); - List contentList = new LinkedList(); - List elements = new LinkedList(); + boolean isRestart = (lmStack != null); + boolean emptyStack = (!isRestart || lmStack.isEmpty()); + List<ListElement> contentList = new LinkedList<ListElement>(); + List<ListElement> elements = new LinkedList<ListElement>(); - if (!breakBeforeServed) { - breakBeforeServed = true; - if (!context.suppressBreakBefore()) { - if (addKnuthElementsForBreakBefore(elements, context)) { - return elements; - } - } + if (!breakBeforeServed(context, elements)) { + // if this FO has break-before specified, and it + // has not yet been processed, return now + return elements; } - if (!firstVisibleMarkServed) { - addKnuthElementsForSpaceBefore(elements, alignment); - context.updateKeepWithPreviousPending(getKeepWithPrevious()); - } - - addKnuthElementsForBorderPaddingBefore(elements, !firstVisibleMarkServed); - firstVisibleMarkServed = true; - - //Spaces, border and padding to be repeated at each break - addPendingMarks(context); + addFirstVisibleMarks(elements, context, alignment); //Used to indicate a special break-after case when all content has already been generated. BreakElement forcedBreakAfterLast = null; + LayoutContext childLC; + List<ListElement> childElements; LayoutManager currentChildLM; - while ((currentChildLM = (LayoutManager) getChildLM()) != null) { - LayoutContext childLC = new LayoutContext(0); + // always reset in case of a restart (exception: see below) + boolean doReset = isRestart; + if (isRestart) { + if (emptyStack) { + assert restartAtLM != null && restartAtLM.getParent() == this; + currentChildLM = restartAtLM; + } else { + currentChildLM = (LayoutManager) lmStack.pop(); + // make sure the initial child LM is not reset + doReset = false; + } + setCurrentChildLM(currentChildLM); + } else { + currentChildLM = getChildLM(); + } - List childrenElements = getNextChildElements(currentChildLM, context, childLC, - alignment); + while (currentChildLM != null) { + if (doReset) { + currentChildLM.reset(); // TODO won't work with forced breaks + } + + childLC = makeChildLayoutContext(context); + + if (!isRestart || emptyStack) { + childElements = getNextChildElements(currentChildLM, context, childLC, alignment, + null, null, null); + } else { + // restart && non-empty LM stack + childElements = getNextChildElements(currentChildLM, context, childLC, alignment, + lmStack, restartPosition, restartAtLM); + // once encountered, irrelevant for following child LMs + emptyStack = true; + // force reset as of the next child + doReset = true; + } if (contentList.isEmpty()) { - //Propagate keep-with-previous up from the first child + // propagate keep-with-previous up from the first child context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); } - if (childrenElements != null && !childrenElements.isEmpty()) { + + // handle non-empty child + if (childElements != null && !childElements.isEmpty()) { if (!contentList.isEmpty() - && !ElementListUtils.startsWithForcedBreak(childrenElements)) { + && !ElementListUtils.startsWithForcedBreak(childElements)) { // there is a block handled by prevLM before the one // handled by curLM, and the one handled // by the current LM does not begin with a break addInBetweenBreak(contentList, context, childLC); } - if (childrenElements.size() == 1 - && ElementListUtils.startsWithForcedBreak(childrenElements)) { - + if (childElements.size() == 1 + && ElementListUtils.startsWithForcedBreak(childElements)) { + // a descendant of this block has break-before if (currentChildLM.isFinished() && !hasNextChildLM()) { - // a descendant of this block has break-before - forcedBreakAfterLast = (BreakElement) childrenElements.get(0); + // if there is no more content, make sure pending + // marks are cleared + forcedBreakAfterLast = (BreakElement) childElements.get(0); context.clearPendingMarks(); + // break without adding the child elements break; } - if (contentList.isEmpty()) { - // Empty fo:block, zero-length box makes sure the IDs and/or markers + // empty fo:block: zero-length box makes sure the IDs and/or markers // are registered and borders/padding are painted. - elements.add(new KnuthBox(0, notifyPos(new Position(this)), false)); + elements.add(makeAuxiliaryZeroWidthBox()); } - // a descendant of this block has break-before - contentList.addAll(childrenElements); - + // add the forced break + contentList.addAll(childElements); + // wrap position and return wrapPositionElements(contentList, elements); - return elements; } else { - contentList.addAll(childrenElements); - if (ElementListUtils.endsWithForcedBreak(childrenElements)) { + // add all accumulated child elements + contentList.addAll(childElements); + if (ElementListUtils.endsWithForcedBreak(childElements)) { // a descendant of this block has break-after if (currentChildLM.isFinished() && !hasNextChildLM()) { + // if there is no more content, make sure any + // pending marks are cleared forcedBreakAfterLast = (BreakElement) ListUtil.removeLast(contentList); context.clearPendingMarks(); break; } - + //wrap positions and return wrapPositionElements(contentList, elements); - return elements; } } context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); } + currentChildLM = getChildLM(); } - if (!contentList.isEmpty()) { + if (contentList.isEmpty()) { + if (forcedBreakAfterLast == null) { + // empty fo:block: zero-length box makes sure the IDs and/or markers + // are registered. + elements.add(makeAuxiliaryZeroWidthBox()); + } + } else { + // wrap child positions wrapPositionElements(contentList, elements); - } else if (forcedBreakAfterLast == null) { - // Empty fo:block, zero-length box makes sure the IDs and/or markers - // are registered. - elements.add(new KnuthBox(0, notifyPos(new Position(this)), true)); } - addKnuthElementsForBorderPaddingAfter(elements, true); - addKnuthElementsForSpaceAfter(elements, alignment); + addLastVisibleMarks(elements, context, alignment); - //All child content is processed. Only break-after can occur now, so... - context.clearPendingMarks(); if (forcedBreakAfterLast == null) { addKnuthElementsForBreakAfter(elements, context); } else { @@ -354,231 +379,131 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } context.updateKeepWithNextPending(getKeepWithNext()); - setFinished(true); - return elements; } - /** {@inheritDoc} */ - public List getNextKnuthElements // CSOK: MethodLength - (LayoutContext context, int alignment, Stack lmStack, - Position restartPosition, LayoutManager restartAtLM) { - referenceIPD = context.getRefIPD(); - updateContentAreaIPDwithOverconstrainedAdjust(); - - List contentList = new LinkedList(); - List elements = new LinkedList(); - - if (!breakBeforeServed) { - breakBeforeServed = true; - if (!context.suppressBreakBefore()) { - if (addKnuthElementsForBreakBefore(elements, context)) { - return elements; - } - } - } + /** + * Creates and initializes a {@link LayoutContext} to pass to the child LM + * @param context the parent {@link LayoutContext} + * @return a new child layout context + */ + protected LayoutContext makeChildLayoutContext(LayoutContext context) { + LayoutContext childLC = new LayoutContext(0); + childLC.copyPendingMarksFrom(context); + childLC.setStackLimitBP(context.getStackLimitBP()); + childLC.setRefIPD(referenceIPD); + return childLC; + } + /** + * Checks if this LM's first "visible marks" (= borders, padding, spaces) have + * already been processed, and if necessary, adds corresponding elements to + * the specified list, and updates the given layout context accordingly. + * @param elements the element list + * @param context the layout context + * @param alignment the vertical alignment + */ + protected void addFirstVisibleMarks(List<ListElement> elements, + LayoutContext context, int alignment) { if (!firstVisibleMarkServed) { addKnuthElementsForSpaceBefore(elements, alignment); context.updateKeepWithPreviousPending(getKeepWithPrevious()); } - addKnuthElementsForBorderPaddingBefore(elements, !firstVisibleMarkServed); firstVisibleMarkServed = true; //Spaces, border and padding to be repeated at each break addPendingMarks(context); + } - //Used to indicate a special break-after case when all content has already been generated. - BreakElement forcedBreakAfterLast = null; - - LayoutContext childLC = new LayoutContext(0); - List childrenElements; - LayoutManager currentChildLM; - if (lmStack.isEmpty()) { - assert restartAtLM != null && restartAtLM.getParent() == this; - currentChildLM = restartAtLM; - currentChildLM.reset(); - setCurrentChildLM(currentChildLM); - - childrenElements = getNextChildElements(currentChildLM, context, childLC, - alignment); - } else { - currentChildLM = (BlockLevelLayoutManager) lmStack.pop(); - setCurrentChildLM(currentChildLM); - childrenElements = getNextChildElements(currentChildLM, context, childLC, alignment, - lmStack, restartPosition, restartAtLM); - } - - if (contentList.isEmpty()) { - //Propagate keep-with-previous up from the first child - context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); - } - if (childrenElements != null && !childrenElements.isEmpty()) { - if (!contentList.isEmpty() - && !ElementListUtils.startsWithForcedBreak(childrenElements)) { - // there is a block handled by prevLM before the one - // handled by curLM, and the one handled - // by the current LM does not begin with a break - addInBetweenBreak(contentList, context, childLC); - } - if (childrenElements.size() == 1 - && ElementListUtils.startsWithForcedBreak(childrenElements)) { - - if (currentChildLM.isFinished() && !hasNextChildLM()) { - // a descendant of this block has break-before - forcedBreakAfterLast = (BreakElement) childrenElements.get(0); - context.clearPendingMarks(); -// break; TODO - } - - if (contentList.isEmpty()) { - // Empty fo:block, zero-length box makes sure the IDs and/or markers - // are registered and borders/padding are painted. - elements.add(new KnuthBox(0, notifyPos(new Position(this)), false)); - } - // a descendant of this block has break-before - contentList.addAll(childrenElements); - - wrapPositionElements(contentList, elements); - - return elements; - } else { - contentList.addAll(childrenElements); - if (ElementListUtils.endsWithForcedBreak(childrenElements)) { - // a descendant of this block has break-after - if (currentChildLM.isFinished() && !hasNextChildLM()) { - forcedBreakAfterLast = (BreakElement) ListUtil.removeLast(contentList); - context.clearPendingMarks(); -// break; TODO - } - - wrapPositionElements(contentList, elements); - - return elements; - } - } - context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); - } - - while ((currentChildLM = (LayoutManager) getChildLM()) != null) { - currentChildLM.reset(); // TODO won't work with forced breaks - - childLC = new LayoutContext(0); - - childrenElements = getNextChildElements(currentChildLM, context, childLC, - alignment); - - if (contentList.isEmpty()) { - //Propagate keep-with-previous up from the first child - context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); - } - if (childrenElements != null && !childrenElements.isEmpty()) { - if (!contentList.isEmpty() - && !ElementListUtils.startsWithForcedBreak(childrenElements)) { - // there is a block handled by prevLM before the one - // handled by curLM, and the one handled - // by the current LM does not begin with a break - addInBetweenBreak(contentList, context, childLC); - } - if (childrenElements.size() == 1 - && ElementListUtils.startsWithForcedBreak(childrenElements)) { - - if (currentChildLM.isFinished() && !hasNextChildLM()) { - // a descendant of this block has break-before - forcedBreakAfterLast = (BreakElement) childrenElements.get(0); - context.clearPendingMarks(); - break; - } - - if (contentList.isEmpty()) { - // Empty fo:block, zero-length box makes sure the IDs and/or markers - // are registered and borders/padding are painted. - elements.add(new KnuthBox(0, notifyPos(new Position(this)), false)); - } - // a descendant of this block has break-before - contentList.addAll(childrenElements); - - wrapPositionElements(contentList, elements); - - return elements; - } else { - contentList.addAll(childrenElements); - if (ElementListUtils.endsWithForcedBreak(childrenElements)) { - // a descendant of this block has break-after - if (currentChildLM.isFinished() && !hasNextChildLM()) { - forcedBreakAfterLast = (BreakElement) ListUtil.removeLast(contentList); - context.clearPendingMarks(); - break; - } - - wrapPositionElements(contentList, elements); - - return elements; - } - } - context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); - } - } - - if (!contentList.isEmpty()) { - wrapPositionElements(contentList, elements); - } else if (forcedBreakAfterLast == null) { - // Empty fo:block, zero-length box makes sure the IDs and/or markers - // are registered. - elements.add(new KnuthBox(0, notifyPos(new Position(this)), true)); - } - + /** + * Adds elements the LM's last/closing marks to the specified list, and + * updates the layout context accordingly. + * @param elements the element list + * @param context the layout context + * @param alignment the vertical alignment + */ + protected void addLastVisibleMarks(List<ListElement> elements, + LayoutContext context, int alignment) { addKnuthElementsForBorderPaddingAfter(elements, true); addKnuthElementsForSpaceAfter(elements, alignment); - //All child content is processed. Only break-after can occur now, so... + // All child content processed. Only break-after can occur now, so... context.clearPendingMarks(); - if (forcedBreakAfterLast == null) { - addKnuthElementsForBreakAfter(elements, context); - } else { - forcedBreakAfterLast.clearPendingMarks(); - elements.add(forcedBreakAfterLast); + } + + /** + * Check whether there is a break-before condition. If so, and + * the specified {@code context} allows it, add the necessary elements + * to the given {@code elements} list. + * @param context the layout context + * @param elements the element list + * @return {@code false} if there is a break-before condition, and it has not been served; + * {@code true} otherwise + */ + protected boolean breakBeforeServed(LayoutContext context, List<ListElement> elements) { + if (!breakBeforeServed) { + breakBeforeServed = true; + if (!context.suppressBreakBefore()) { + if (addKnuthElementsForBreakBefore(elements, context)) { + return false; + } + } } + return breakBeforeServed; + } - context.updateKeepWithNextPending(getKeepWithNext()); + private KnuthBox makeZeroWidthBox() { + return new KnuthBox(0, new NonLeafPosition(this, null), false); + } - setFinished(true); + private KnuthBox makeAuxiliaryZeroWidthBox() { + return new KnuthBox(0, notifyPos(new Position(this)), true); + } - return elements; + private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) { + return new KnuthPenalty(0, penaltyValue, false, new NonLeafPosition(this, null), false); } - private List getNextChildElements(LayoutManager childLM, LayoutContext context, - LayoutContext childLC, int alignment) { - return getNextChildElements(childLM, context, childLC, alignment, null, null, null); + private KnuthGlue makeSpaceAdjustmentGlue(int width, Adjustment adjustmentClass, + boolean isAuxiliary) { + return new KnuthGlue(width, 0, 0, + adjustmentClass, + new NonLeafPosition(this, null), + isAuxiliary); } - private List getNextChildElements(LayoutManager childLM, LayoutContext context, - LayoutContext childLC, int alignment, Stack lmStack, Position restartPosition, - LayoutManager restartAtLM) { - childLC.copyPendingMarksFrom(context); - childLC.setStackLimitBP(context.getStackLimitBP()); - if (childLM instanceof LineLayoutManager) { - childLC.setRefIPD(getContentAreaIPD()); - } else { - childLC.setRefIPD(referenceIPD); - } + /** + * Gets the next set of child elements for the given childLM. + * The default implementation basically copies the pending marks to the child layout context, + * and subsequently calls the appropriate variant of {@code childLM.getNextKnuthElements()}, + * passing it all relevant parameters. + * @param childLM the current child LM + * @param context the layout context + * @param childLC the child layout context + * @param alignment the vertical alignment + * @param lmStack the stack of currently active LMs (if any) + * @param restartPosition the position to restart from (if any) + * @param restartAtLM the LM to restart from (if any) + * @return list of elements corresponding to the content generated by childLM + */ + protected List<ListElement> getNextChildElements(LayoutManager childLM, LayoutContext context, + LayoutContext childLC, int alignment, Stack<LayoutManager> lmStack, + Position restartPosition, LayoutManager restartAtLM) { + if (childLM == this.childLMs.get(0)) { childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE); //Handled already by the parent (break collapsing, see above) } if (lmStack == null) { + // route to default implementation, in case childLM does not provide + // an override similar to this class return childLM.getNextKnuthElements(childLC, alignment); } else { - if (childLM instanceof LineLayoutManager) { - return ((LineLayoutManager) childLM).getNextKnuthElements(childLC, alignment, - (LeafPosition) restartPosition); - } else { - return childLM.getNextKnuthElements(childLC, alignment, - lmStack, restartPosition, restartAtLM); - } + return childLM.getNextKnuthElements(childLC, alignment, lmStack, + restartPosition, restartAtLM); } } @@ -588,7 +513,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * @param parentLC the parent layout context * @param childLC the currently active child layout context */ - protected void addInBetweenBreak(List contentList, LayoutContext parentLC, + protected void addInBetweenBreak(List<ListElement> contentList, LayoutContext parentLC, LayoutContext childLC) { if (mustKeepTogether() @@ -612,7 +537,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager return; } - ListElement last = (ListElement) ListUtil.getLast(contentList); + ListElement last = ListUtil.getLast(contentList); if (last.isGlue()) { // the last element in contentList is a glue; // it is a feasible breakpoint, there is no need to add @@ -643,15 +568,9 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) { -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> " + adj); -/*LF*/ //log.debug(" lastElement e' " + (lastElement.isPenalty() - // ? "penalty" : (lastElement.isGlue() ? "glue" : "box" ))); -/*LF*/ //log.debug(" position e' " + lastElement.getPosition().getClass().getName()); -/*LF*/ //log.debug(" " + (bpUnit > 0 ? "unit" : "")); + assert (lastElement != null && lastElement.getPosition() != null); Position innerPosition = lastElement.getPosition().getPosition(); if (innerPosition == null && lastElement.isGlue()) { @@ -660,11 +579,9 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager == Adjustment.SPACE_BEFORE_ADJUSTMENT) { // this adjustment applies to space-before adjustedSpaceBefore += adj; -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> spazio prima: " + adj); } else { // this adjustment applies to space-after adjustedSpaceAfter += adj; -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> spazio dopo: " + adj); } return adj; } else if (innerPosition instanceof MappingPosition) { @@ -674,7 +591,6 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager MappingPosition mappingPos = (MappingPosition)innerPosition; if (lastElement.isGlue()) { // lastElement is a glue -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> bpunit con glue"); ListIterator storedListIterator = storedList.listIterator( mappingPos.getFirstIndex()); int newAdjustment = 0; @@ -684,8 +600,6 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager newAdjustment += ((BlockLevelLayoutManager)storedElement .getLayoutManager()).negotiateBPDAdjustment( adj - newAdjustment, storedElement); -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> (progressivo) righe: " - // + newAdjustment); } } newAdjustment = (newAdjustment > 0 ? bpUnit * neededUnits(newAdjustment) @@ -695,30 +609,26 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager // lastElement is a penalty: this means that the paragraph // has been split between consecutive pages: // this may involve a change in the number of lines -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> bpunit con penalty"); KnuthPenalty storedPenalty = (KnuthPenalty) storedList.get(mappingPos.getLastIndex()); if (storedPenalty.getWidth() > 0) { // the original penalty has width > 0 -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> chiamata passata"); return ((BlockLevelLayoutManager)storedPenalty.getLayoutManager()) .negotiateBPDAdjustment(storedPenalty.getWidth(), storedPenalty); } else { // the original penalty has width = 0 // the adjustment involves only the spaces before and after -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> chiamata gestita"); return adj; } } - } else if (innerPosition.getLM() != this) { + } else if (innerPosition != null && innerPosition.getLM() != this) { // this adjustment concerns another LM NonLeafPosition savedPos = (NonLeafPosition) lastElement.getPosition(); lastElement.setPosition(innerPosition); int returnValue = ((BlockLevelLayoutManager)lastElement.getLayoutManager()) .negotiateBPDAdjustment(adj, lastElement); lastElement.setPosition(savedPos); -/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> righe: " + returnValue); return returnValue; } else { // this should never happen @@ -727,12 +637,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void discardSpace(KnuthGlue spaceGlue) { - //log.debug(" BLM.discardSpace> " + spaceGlue.getPosition().getClass().getName()); - Position innerPosition = ((NonLeafPosition) spaceGlue.getPosition()).getPosition(); + assert (spaceGlue != null && spaceGlue.getPosition() != null); + Position innerPosition = spaceGlue.getPosition().getPosition(); if (innerPosition == null || innerPosition.getLM() == this) { // if this block has block-progression-unit > 0, innerPosition can be @@ -757,36 +665,27 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } } - /** - * {@inheritDoc} - */ - public List getChangedKnuthElements(List oldList, int alignment) { // CSOK: MethodLength -/*LF*/ //log.debug(""); -/*LF*/ //log.debug(" BLM.getChangedKnuthElements> inizio: oldList.size() = " - // + oldList.size()); - ListIterator oldListIterator = oldList.listIterator(); - KnuthElement returnedElement; + /** {@inheritDoc} */ + @Override + public List getChangedKnuthElements(List oldList, int alignment) { + ListIterator<KnuthElement> oldListIterator = oldList.listIterator(); KnuthElement currElement = null; KnuthElement prevElement = null; - List returnedList = new LinkedList(); - List returnList = new LinkedList(); + List<KnuthElement> returnedList = new LinkedList<KnuthElement>(); + List<KnuthElement> returnList = new LinkedList<KnuthElement>(); int fromIndex = 0; // "unwrap" the Positions stored in the elements - KnuthElement oldElement = null; + KnuthElement oldElement; while (oldListIterator.hasNext()) { - oldElement = (KnuthElement)oldListIterator.next(); - Position innerPosition = ((NonLeafPosition) oldElement.getPosition()).getPosition(); - //log.debug(" BLM> unwrapping: " - // + (oldElement.isBox() ? "box " : (oldElement.isGlue() ? "glue " : "penalty")) - // + " creato da " + oldElement.getLayoutManager().getClass().getName()); - //log.debug(" BLM> unwrapping: " - // + oldElement.getPosition().getClass().getName()); + oldElement = oldListIterator.next(); + assert oldElement.getPosition() != null; + Position innerPosition = oldElement.getPosition().getPosition(); if (innerPosition != null) { - // oldElement was created by a descendant of this BlockLM + // oldElement was created by a descendant oldElement.setPosition(innerPosition); } else { - // thisElement was created by this BlockLM + // oldElement was created by this LM: // modify its position in order to recognize it was not created // by a child oldElement.setPosition(new Position(this)); @@ -794,63 +693,25 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } // create the iterator - List workList; - if (bpUnit == 0) { - workList = oldList; - } else { - // the storedList must be used instead of oldList; - // find the index of the first element of returnedList - // corresponding to the first element of oldList - oldListIterator = oldList.listIterator(); - KnuthElement el = (KnuthElement) oldListIterator.next(); - while (!(el.getPosition() instanceof MappingPosition)) { - el = (KnuthElement) oldListIterator.next(); - } - int iFirst = ((MappingPosition) el.getPosition()).getFirstIndex(); - - // find the index of the last element of returnedList - // corresponding to the last element of oldList - oldListIterator = oldList.listIterator(oldList.size()); - el = (KnuthElement) oldListIterator.previous(); - while (!(el.getPosition() instanceof MappingPosition)) { - el = (KnuthElement) oldListIterator.previous(); - } - int iLast = ((MappingPosition) el.getPosition()).getLastIndex(); - - //log-debug(" si usa storedList da " + iFirst + " a " + iLast - // + " compresi su " + storedList.size() + " elementi totali"); - workList = storedList.subList(iFirst, iLast + 1); - } - ListIterator workListIterator = workList.listIterator(); - - //log.debug(" BLM.getChangedKnuthElements> workList.size() = " - // + workList.size() + " da 0 a " + (workList.size() - 1)); - + ListIterator<KnuthElement> workListIterator = oldList.listIterator(); while (workListIterator.hasNext()) { - currElement = (KnuthElement) workListIterator.next(); - //log.debug("elemento n. " + workListIterator.previousIndex() - // + " nella workList"); + currElement = workListIterator.next(); if (prevElement != null && prevElement.getLayoutManager() != currElement.getLayoutManager()) { // prevElement is the last element generated by the same LM - BlockLevelLayoutManager prevLM = (BlockLevelLayoutManager) - prevElement.getLayoutManager(); - BlockLevelLayoutManager currLM = (BlockLevelLayoutManager) - currElement.getLayoutManager(); - boolean bSomethingAdded = false; + BlockLevelLayoutManager prevLM + = (BlockLevelLayoutManager)prevElement.getLayoutManager(); + BlockLevelLayoutManager currLM + = (BlockLevelLayoutManager)currElement.getLayoutManager(); + boolean somethingAdded = false; if (prevLM != this) { - //log.debug(" BLM.getChangedKnuthElements> chiamata da " - // + fromIndex + " a " + workListIterator.previousIndex() + " su " - // + prevLM.getClass().getName()); - returnedList.addAll(prevLM.getChangedKnuthElements(workList.subList( - fromIndex, workListIterator.previousIndex()), alignment)); - bSomethingAdded = true; + returnedList.addAll( + prevLM.getChangedKnuthElements( + oldList.subList(fromIndex, workListIterator.previousIndex()), + alignment)); + somethingAdded = true; } else { - // prevLM == this // do nothing - //log.debug(" BLM.getChangedKnuthElements> elementi propri, " - // + "ignorati, da " + fromIndex + " a " + workListIterator.previousIndex() - // + " su " + prevLM.getClass().getName()); } fromIndex = workListIterator.previousIndex(); @@ -859,116 +720,77 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * while in getNextKE they were changed to BreakElements? */ // there is another block after this one - if (bSomethingAdded + if (somethingAdded && (this.mustKeepTogether() || prevLM.mustKeepWithNext() || currLM.mustKeepWithPrevious())) { // add an infinite penalty to forbid a break between blocks - returnedList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, - new Position(this), false)); - } else if (bSomethingAdded - && !((KnuthElement) ListUtil.getLast(returnedList)) - .isGlue()) { + returnedList.add(makeZeroWidthPenalty(KnuthPenalty.INFINITE)); + } else if (somethingAdded + && !ListUtil.getLast(returnedList).isGlue()) { // add a null penalty to allow a break between blocks - returnedList.add(new KnuthPenalty(0, 0, false, new Position(this), false)); + returnedList.add(makeZeroWidthPenalty(KnuthPenalty.INFINITE)); } } prevElement = currElement; } if (currElement != null) { - BlockLevelLayoutManager currLM = (BlockLevelLayoutManager) - currElement.getLayoutManager(); + LayoutManager currLM = currElement.getLayoutManager(); if (currLM != this) { - //log.debug(" BLM.getChangedKnuthElements> chiamata da " + fromIndex - // + " a " + oldList.size() + " su " + currLM.getClass().getName()); returnedList.addAll(currLM.getChangedKnuthElements( - workList.subList(fromIndex, workList.size()), alignment)); + oldList.subList(fromIndex, oldList.size()), alignment)); } else { - // currLM == this // there are no more elements to add // remove the last penalty added to returnedList if (!returnedList.isEmpty()) { ListUtil.removeLast(returnedList); } - //log.debug(" BLM.getChangedKnuthElements> elementi propri, ignorati, da " - // + fromIndex + " a " + workList.size()); } } // append elements representing space-before boolean spaceBeforeIsConditional = true; if (fobj instanceof org.apache.fop.fo.flow.Block) { - spaceBeforeIsConditional = ((org.apache.fop.fo.flow.Block)fobj) - .getCommonMarginBlock().spaceBefore.getSpace().isDiscard(); + spaceBeforeIsConditional = getSpaceBeforeProperty().isDiscard(); } - if (bpUnit > 0 - || adjustedSpaceBefore != 0) { + if (adjustedSpaceBefore != 0) { if (!spaceBeforeIsConditional) { // add elements to prevent the glue to be discarded - returnList.add(new KnuthBox(0, - new NonLeafPosition(this, null), false)); - returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, - new NonLeafPosition(this, null), false)); + returnList.add(makeZeroWidthBox()); + returnList.add(makeZeroWidthPenalty(KnuthPenalty.INFINITE)); } - if (bpUnit > 0) { - returnList.add(new KnuthGlue(0, 0, 0, - Adjustment.SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(this, null), true)); - } else { - returnList.add(new KnuthGlue(adjustedSpaceBefore, 0, 0, - Adjustment.SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(this, null), true)); - } - } - //log.debug(" BLM.getChangedKnuthElements> intermedio: returnedList.size() = " - // + returnedList.size()); - -/* estensione: conversione complessiva */ -/*LF*/ if (bpUnit > 0) { -/*LF*/ storedList = returnedList; -/*LF*/ returnedList = createUnitElements(returnedList); -/*LF*/ } -/* estensione */ + returnList.add(makeSpaceAdjustmentGlue(adjustedSpaceBefore, + Adjustment.SPACE_BEFORE_ADJUSTMENT, + false)); + } // "wrap" the Position stored in each element of returnedList // and add elements to returnList - ListIterator listIter = returnedList.listIterator(); - while (listIter.hasNext()) { - returnedElement = (KnuthElement)listIter.next(); - returnedElement.setPosition(new NonLeafPosition(this, returnedElement.getPosition())); - returnList.add(returnedElement); + for (KnuthElement el : returnedList) { + el.setPosition(new NonLeafPosition(this, el.getPosition())); + returnList.add(el); } // append elements representing space-after boolean spaceAfterIsConditional = true; if (fobj instanceof org.apache.fop.fo.flow.Block) { - spaceAfterIsConditional = ((org.apache.fop.fo.flow.Block)fobj) - .getCommonMarginBlock().spaceAfter.getSpace().isDiscard(); + spaceAfterIsConditional = getSpaceAfterProperty().isDiscard(); } - if (bpUnit > 0 || adjustedSpaceAfter != 0) { + if (adjustedSpaceAfter != 0) { if (!spaceAfterIsConditional) { - returnList.add(new KnuthPenalty(0, - KnuthElement.INFINITE, false, - new NonLeafPosition(this, null), false)); - } - if (bpUnit > 0) { - returnList.add(new KnuthGlue(0, 0, 0, - Adjustment.SPACE_AFTER_ADJUSTMENT, - new NonLeafPosition(this, null), - spaceAfterIsConditional)); - } else { - returnList.add(new KnuthGlue(adjustedSpaceAfter, 0, 0, - Adjustment.SPACE_AFTER_ADJUSTMENT, - new NonLeafPosition(this, null), - spaceAfterIsConditional)); + returnList.add(makeZeroWidthPenalty(KnuthPenalty.INFINITE)); } + + returnList.add(makeSpaceAdjustmentGlue(adjustedSpaceAfter, + Adjustment.SPACE_AFTER_ADJUSTMENT, + spaceAfterIsConditional)); + if (!spaceAfterIsConditional) { - returnList.add(new KnuthBox(0, - new NonLeafPosition(this, null), true)); + returnList.add(makeZeroWidthBox()); } } - //log.debug(" BLM.getChangedKnuthElements> finished: returnList.size() = " - // + returnList.size()); return returnList; } @@ -1115,7 +937,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } /** @return the space-before property */ - private SpaceProperty getSpaceBeforeProperty() { + protected SpaceProperty getSpaceBeforeProperty() { if (fobj instanceof org.apache.fop.fo.flow.Block) { return ((org.apache.fop.fo.flow.Block)fobj) .getCommonMarginBlock().spaceBefore; @@ -1137,7 +959,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } /** @return the space-after property */ - private SpaceProperty getSpaceAfterProperty() { + protected SpaceProperty getSpaceAfterProperty() { if (fobj instanceof org.apache.fop.fo.flow.Block) { return ((org.apache.fop.fo.flow.Block)fobj) .getCommonMarginBlock().spaceAfter; @@ -1218,8 +1040,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * @param context the layout context * @return true if an element has been added due to a break-before. */ - protected boolean addKnuthElementsForBreakBefore(List returnList, - LayoutContext context) { + protected boolean addKnuthElementsForBreakBefore(List returnList, LayoutContext context) { int breakBefore = getBreakBefore(); if (breakBefore == EN_PAGE || breakBefore == EN_COLUMN @@ -1261,8 +1082,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * @param context the layout context * @return true if an element has been added due to a break-after. */ - protected boolean addKnuthElementsForBreakAfter(List returnList, - LayoutContext context) { + protected boolean addKnuthElementsForBreakAfter(List returnList, LayoutContext context) { int breakAfter = -1; if (fobj instanceof BreakPropertySet) { breakAfter = ((BreakPropertySet)fobj).getBreakAfter(); @@ -1285,8 +1105,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * @param returnList return list to add the additional elements to * @param alignment vertical alignment */ - protected void addKnuthElementsForSpaceBefore(List returnList/*, - Position returnPosition*/, int alignment) { + protected void addKnuthElementsForSpaceBefore(List returnList, int alignment) { SpaceProperty spaceBefore = getSpaceBeforeProperty(); // append elements representing space-before if (spaceBefore != null @@ -1296,37 +1115,6 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager RelSide.BEFORE, true, false, this)); } - /* - if (bpUnit > 0 - || spaceBefore != null - && !(spaceBefore.getMinimum(this).getLength().getValue(this) == 0 - && spaceBefore.getMaximum(this).getLength().getValue(this) == 0)) { - if (spaceBefore != null && !spaceBefore.getSpace().isDiscard()) { - // add elements to prevent the glue to be discarded - returnList.add(new KnuthBox(0, getAuxiliaryPosition(), false)); - returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, - false, getAuxiliaryPosition(), false)); - } - if (bpUnit > 0) { - returnList.add(new KnuthGlue(0, 0, 0, - BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, - getAuxiliaryPosition(), true)); - } else { //if (alignment == EN_JUSTIFY) { - returnList.add(new KnuthGlue( - spaceBefore.getOptimum(this).getLength().getValue(this), - spaceBefore.getMaximum(this).getLength().getValue(this) - - spaceBefore.getOptimum(this).getLength().getValue(this), - spaceBefore.getOptimum(this).getLength().getValue(this) - - spaceBefore.getMinimum(this).getLength().getValue(this), - BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, - getAuxiliaryPosition(), true)); -// } else { -// returnList.add(new KnuthGlue( -// spaceBefore.getOptimum().getLength().getValue(this), -// 0, 0, BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, -// returnPosition, true)); - } - }*/ } /** @@ -1334,8 +1122,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * @param returnList return list to add the additional elements to * @param alignment vertical alignment */ - protected void addKnuthElementsForSpaceAfter(List returnList/*, Position returnPosition*/, - int alignment) { + protected void addKnuthElementsForSpaceAfter(List returnList, int alignment) { SpaceProperty spaceAfter = getSpaceAfterProperty(); // append elements representing space-after if (spaceAfter != null @@ -1345,394 +1132,13 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager RelSide.AFTER, false, true, this)); } - /* - if (bpUnit > 0 - || spaceAfter != null - && !(spaceAfter.getMinimum(this).getLength().getValue(this) == 0 - && spaceAfter.getMaximum(this).getLength().getValue(this) == 0)) { - if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) { - returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, - false, getAuxiliaryPosition(), false)); - } - if (bpUnit > 0) { - returnList.add(new KnuthGlue(0, 0, 0, - BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, - getAuxiliaryPosition(), true)); - } else { //if (alignment == EN_JUSTIFY) { - returnList.add(new KnuthGlue( - spaceAfter.getOptimum(this).getLength().getValue(this), - spaceAfter.getMaximum(this).getLength().getValue(this) - - spaceAfter.getOptimum(this).getLength().getValue(this), - spaceAfter.getOptimum(this).getLength().getValue(this) - - spaceAfter.getMinimum(this).getLength().getValue(this), - BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, getAuxiliaryPosition(), - (!spaceAfter.getSpace().isDiscard()) ? false : true)); -// } else { -// returnList.add(new KnuthGlue( -// spaceAfter.getOptimum().getLength().getValue(this), 0, 0, -// BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, returnPosition, -// (!spaceAfter.getSpace().isDiscard()) ? false : true)); - } - if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) { - returnList.add(new KnuthBox(0, getAuxiliaryPosition(), true)); - } - }*/ - } - - /** - * Create unit elements. - * @param oldList the old list - * @return the new list - */ - protected List createUnitElements(List oldList) { // CSOK: MethodLength - //log.debug("Start conversion: " + oldList.size() - // + " elements, space-before.min=" + layoutProps.spaceBefore.getSpace().min - // + " space-after.min=" + layoutProps.spaceAfter.getSpace().min); - // add elements at the beginning and at the end of oldList - // representing minimum spaces - LayoutManager lm = ((KnuthElement)oldList.get(0)).getLayoutManager(); - boolean bAddedBoxBefore = false; - boolean bAddedBoxAfter = false; - if (adjustedSpaceBefore > 0) { - oldList.add(0, new KnuthBox(adjustedSpaceBefore, - new Position(lm), true)); - bAddedBoxBefore = true; - } - if (adjustedSpaceAfter > 0) { - oldList.add(new KnuthBox(adjustedSpaceAfter, - new Position(lm), true)); - bAddedBoxAfter = true; - } - - MinOptMax totalLength = MinOptMax.ZERO; - LinkedList newList = new LinkedList(); - - //log.debug(" Prima scansione"); - // scan the list once to compute total min, opt and max length - ListIterator oldListIterator = oldList.listIterator(); - while (oldListIterator.hasNext()) { - KnuthElement element = (KnuthElement) oldListIterator.next(); - if (element.isBox()) { - totalLength = totalLength.plus(element.getWidth()); - //log.debug("box " + element.getWidth()); - } else if (element.isGlue()) { - totalLength = totalLength.minusMin(element.getShrink()); - totalLength = totalLength.plusMax(element.getStretch()); - //leafValue = ((LeafPosition) element.getPosition()).getLeafPos(); - //log.debug("glue " + element.getWidth() + " + " - // + ((KnuthGlue) element).getStretch() + " - " - // + ((KnuthGlue) element).getShrink()); - } else { - //log.debug((((KnuthPenalty)element).getPenalty() == KnuthElement.INFINITE - // ? "PENALTY " : "penalty ") + element.getWidth()); - } - } - // compute the total amount of "units" - MinOptMax totalUnits = MinOptMax.getInstance(neededUnits(totalLength.getMin()), - neededUnits(totalLength.getOpt()), - neededUnits(totalLength.getMax())); - //log.debug(" totalLength= " + totalLength); - //log.debug(" unita'= " + totalUnits); - - //log.debug(" Seconda scansione"); - // scan the list once more, stopping at every breaking point - // in order to compute partial min, opt and max length - // and create the new elements - oldListIterator = oldList.listIterator(); - boolean prevIsBox; - MinOptMax lengthBeforeBreak = MinOptMax.ZERO; - MinOptMax lengthAfterBreak = totalLength; - MinOptMax unitsBeforeBreak; - MinOptMax unitsAfterBreak; - MinOptMax unsuppressibleUnits = MinOptMax.ZERO; - int firstIndex = 0; - int lastIndex = -1; - while (oldListIterator.hasNext()) { - KnuthElement element = (KnuthElement) oldListIterator.next(); - lastIndex++; - if (element.isBox()) { - lengthBeforeBreak = lengthBeforeBreak.plus(element.getWidth()); - lengthAfterBreak = lengthAfterBreak.minus(element.getWidth()); - prevIsBox = true; - } else if (element.isGlue()) { - lengthBeforeBreak = lengthBeforeBreak.minusMin(element.getShrink()); - lengthAfterBreak = lengthAfterBreak.plusMin(element.getShrink()); - lengthBeforeBreak = lengthBeforeBreak.plusMax(element.getStretch()); - lengthAfterBreak = lengthAfterBreak.minusMax(element.getStretch()); - prevIsBox = false; - } else { - lengthBeforeBreak = lengthBeforeBreak.plus(element.getWidth()); - prevIsBox = false; - } - - // create the new elements - if (element.isPenalty() && element.getPenalty() < KnuthElement.INFINITE - || element.isGlue() && prevIsBox - || !oldListIterator.hasNext()) { - // suppress elements after the breaking point - int iStepsForward = 0; - while (oldListIterator.hasNext()) { - KnuthElement el = (KnuthElement) oldListIterator.next(); - iStepsForward++; - if (el.isGlue()) { - // suppressed glue - lengthAfterBreak = lengthAfterBreak.plusMin(el.getShrink()); - lengthAfterBreak = lengthAfterBreak.minusMax(el.getStretch()); - } else if (el.isPenalty()) { - // suppressed penalty, do nothing - } else { - // box, end of suppressions - break; - } - } - // compute the partial amount of "units" before and after the break - unitsBeforeBreak = MinOptMax.getInstance(neededUnits(lengthBeforeBreak.getMin()), - neededUnits(lengthBeforeBreak.getOpt()), - neededUnits(lengthBeforeBreak.getMax())); - unitsAfterBreak = MinOptMax.getInstance(neededUnits(lengthAfterBreak.getMin()), - neededUnits(lengthAfterBreak.getOpt()), - neededUnits(lengthAfterBreak.getMax())); - - // rewind the iterator and lengthAfterBreak - for (int i = 0; i < iStepsForward; i++) { - KnuthElement el = (KnuthElement) oldListIterator.previous(); - if (el.isGlue()) { - lengthAfterBreak = lengthAfterBreak.minusMin(el.getShrink()); - lengthAfterBreak = lengthAfterBreak.plusMax(el.getStretch()); - } - } - - // compute changes in length, stretch and shrink - int uLengthChange = unitsBeforeBreak.getOpt() + unitsAfterBreak.getOpt() - - totalUnits.getOpt(); - int uStretchChange = unitsBeforeBreak.getStretch() - + unitsAfterBreak.getStretch() - totalUnits.getStretch(); - int uShrinkChange = unitsBeforeBreak.getShrink() - + unitsAfterBreak.getShrink() - totalUnits.getShrink(); - - // compute the number of normal, stretch and shrink unit - // that must be added to the new sequence - int uNewNormal = unitsBeforeBreak.getOpt() - unsuppressibleUnits.getOpt(); - int uNewStretch = unitsBeforeBreak.getStretch() - - unsuppressibleUnits.getStretch(); - int uNewShrink = unitsBeforeBreak.getShrink() - - unsuppressibleUnits.getShrink(); - - //log.debug("(" - // + unsuppressibleUnits.min + "-" + unsuppressibleUnits.opt + "-" - // + unsuppressibleUnits.max + ") " - // + " -> " + unitsBeforeBreak.min + "-" + unitsBeforeBreak.opt + "-" - // + unitsBeforeBreak.max - // + " + " + unitsAfterBreak.min + "-" + unitsAfterBreak.opt + "-" - // + unitsAfterBreak.max - // + (uLengthChange != 0 ? " [length " + uLengthChange + "] " : "") - // + (uStretchChange != 0 ? " [stretch " + uStretchChange + "] " : "") - // + (uShrinkChange != 0 ? " [shrink " + uShrinkChange + "]" : "")); - - // create the MappingPosition which will be stored in the new elements - // correct firstIndex and lastIndex - int firstIndexCorrection = 0; - int lastIndexCorrection = 0; - if (bAddedBoxBefore) { - if (firstIndex != 0) { - firstIndexCorrection++; - } - lastIndexCorrection++; - } - if (bAddedBoxAfter && lastIndex == (oldList.size() - 1)) { - lastIndexCorrection++; - } - MappingPosition mappingPos = new MappingPosition(this, - firstIndex - firstIndexCorrection, - lastIndex - lastIndexCorrection); - - // new box - newList.add(new KnuthBox((uNewNormal - uLengthChange) * bpUnit, mappingPos, false)); - unsuppressibleUnits = unsuppressibleUnits.plus(uNewNormal - uLengthChange); - //log.debug(" box " + (uNewNormal - uLengthChange)); - - // new infinite penalty, glue and box, if necessary - if (uNewStretch - uStretchChange > 0 - || uNewShrink - uShrinkChange > 0) { - int iStretchUnits = (uNewStretch - uStretchChange > 0 - ? (uNewStretch - uStretchChange) : 0); - int iShrinkUnits = (uNewShrink - uShrinkChange > 0 - ? (uNewShrink - uShrinkChange) : 0); - newList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, - mappingPos, - false)); - newList.add(new KnuthGlue(0, - iStretchUnits * bpUnit, - iShrinkUnits * bpUnit, - Adjustment.LINE_NUMBER_ADJUSTMENT, - mappingPos, - false)); - //log.debug(" PENALTY"); - //log.debug(" glue 0 " + iStretchUnits + " " + iShrinkUnits); - unsuppressibleUnits = unsuppressibleUnits.plusMax(iStretchUnits); - unsuppressibleUnits = unsuppressibleUnits.minusMin(iShrinkUnits); - if (!oldListIterator.hasNext()) { - newList.add(new KnuthBox(0, mappingPos, false)); - //log.debug(" box 0"); - } - } - - // new breaking sequence - if (uStretchChange != 0 - || uShrinkChange != 0) { - // new infinite penalty, glue, penalty and glue - newList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, - mappingPos, - false)); - newList.add(new KnuthGlue(0, - uStretchChange * bpUnit, - uShrinkChange * bpUnit, - Adjustment.LINE_NUMBER_ADJUSTMENT, - mappingPos, - false)); - newList.add(new KnuthPenalty(uLengthChange * bpUnit, - 0, false, element.getPosition(), false)); - newList.add(new KnuthGlue(0, - -uStretchChange * bpUnit, - -uShrinkChange * bpUnit, - Adjustment.LINE_NUMBER_ADJUSTMENT, - mappingPos, - false)); - //log.debug(" PENALTY"); - //log.debug(" glue 0 " + uStretchChange + " " + uShrinkChange); - //log.debug(" penalty " + uLengthChange + " * unit"); - //log.debug(" glue 0 " + (- uStretchChange) + " " - // + (- uShrinkChange)); - } else if (oldListIterator.hasNext()) { - // new penalty - newList.add(new KnuthPenalty(uLengthChange * bpUnit, - 0, false, - mappingPos, - false)); - //log.debug(" penalty " + uLengthChange + " * unit"); - } - // update firstIndex - firstIndex = lastIndex + 1; - } - - if (element.isPenalty()) { - lengthBeforeBreak = lengthBeforeBreak.minus(element.getWidth()); - } - - } - - // remove elements at the beginning and at the end of oldList - // representing minimum spaces - if (adjustedSpaceBefore > 0) { - oldList.remove(0); - } - if (adjustedSpaceAfter > 0) { - ListUtil.removeLast(oldList); - } - - // if space-before.conditionality is "discard", correct newList - boolean correctFirstElement = false; - if (fobj instanceof org.apache.fop.fo.flow.Block) { - correctFirstElement = ((org.apache.fop.fo.flow.Block)fobj) - .getCommonMarginBlock().spaceBefore.getSpace().isDiscard(); - } - if (correctFirstElement) { - // remove the wrong element - KnuthBox wrongBox = (KnuthBox) newList.removeFirst(); - // if this paragraph is at the top of a page, the space before - // must be ignored; compute the length change - int decreasedLength = (neededUnits(totalLength.getOpt()) - - neededUnits(totalLength.getOpt() - adjustedSpaceBefore)) - * bpUnit; - // insert the correct elements - newList.addFirst(new KnuthBox(wrongBox.getWidth() - decreasedLength, - wrongBox.getPosition(), false)); - newList.addFirst(new KnuthGlue(decreasedLength, 0, 0, - Adjustment.SPACE_BEFORE_ADJUSTMENT, - wrongBox.getPosition(), false)); - //log.debug(" rimosso box " + neededUnits(wrongBox.getWidth())); - //log.debug(" aggiunto glue " + neededUnits(decreasedLength) + " 0 0"); - //log.debug(" aggiunto box " + neededUnits( - // wrongBox.getWidth() - decreasedLength)); - } - - // if space-after.conditionality is "discard", correct newList - boolean correctLastElement = false; - if (fobj instanceof org.apache.fop.fo.flow.Block) { - correctLastElement = ((org.apache.fop.fo.flow.Block)fobj) - .getCommonMarginBlock().spaceAfter.getSpace().isDiscard(); - } - if (correctLastElement) { - // remove the wrong element - KnuthBox wrongBox = (KnuthBox) newList.removeLast(); - // if the old sequence is box(h) penalty(inf) glue(x,y,z) box(0) - // (it cannot be parted and has some stretch or shrink) - // the wrong box is the first one, not the last one - LinkedList preserveList = new LinkedList(); - if (wrongBox.getWidth() == 0) { - preserveList.add(wrongBox); - preserveList.addFirst((KnuthGlue) newList.removeLast()); - preserveList.addFirst((KnuthPenalty) newList.removeLast()); - wrongBox = (KnuthBox) newList.removeLast(); - } - - // if this paragraph is at the bottom of a page, the space after - // must be ignored; compute the length change - int decreasedLength = (neededUnits(totalLength.getOpt()) - - neededUnits(totalLength.getOpt() - adjustedSpaceAfter)) - * bpUnit; - // insert the correct box - newList.addLast(new KnuthBox(wrongBox.getWidth() - decreasedLength, - wrongBox.getPosition(), false)); - // add preserved elements - if (!preserveList.isEmpty()) { - newList.addAll(preserveList); - } - // insert the correct glue - newList.addLast(new KnuthGlue(decreasedLength, 0, 0, Adjustment.SPACE_AFTER_ADJUSTMENT, - wrongBox.getPosition(), false)); - //log.debug(" rimosso box " + neededUnits(wrongBox.getWidth())); - //log.debug(" aggiunto box " + neededUnits( - // wrongBox.getWidth() - decreasedLength)); - //log.debug(" aggiunto glue " + neededUnits(decreasedLength) + " 0 0"); - } - - return newList; - } - - /** A stack iterator. */ - protected static class StackingIter extends PositionIterator { - - /** - * Construct a stacking iterator. - * @param parentIter the parent iterator - */ - StackingIter(Iterator parentIter) { - super(parentIter); - } - - /** - * @param nextObj the next position - * @return the layout manager of the next position - */ - protected LayoutManager getLM(Object nextObj) { - return ((Position) nextObj).getLM(); - } - - /** - * @param nextObj the next position - * @return the next position - */ - protected Position getPos(Object nextObj) { - return ((Position) nextObj); - } } /** A mapping position. */ protected static class MappingPosition extends Position { - private int iFirstIndex; - private int iLastIndex; + private int firstIndex; + private int lastIndex; /** * Construct mapping position. @@ -1742,18 +1148,18 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager */ public MappingPosition(LayoutManager lm, int first, int last) { super(lm); - iFirstIndex = first; - iLastIndex = last; + firstIndex = first; + lastIndex = last; } /** @return first index */ public int getFirstIndex() { - return iFirstIndex; + return firstIndex; } /** @return last index */ public int getLastIndex() { - return iLastIndex; + return lastIndex; } } @@ -1817,6 +1223,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * Returns the IPD of the content area * @return the IPD of the content area */ + @Override public int getContentAreaIPD() { return contentAreaIPD; } @@ -1833,11 +1240,13 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * Returns the BPD of the content area * @return the BPD of the content area */ + @Override public int getContentAreaBPD() { return -1; } /** {@inheritDoc} */ + @Override public void reset() { super.reset(); breakBeforeServed = false; diff --git a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java index b38874606..d807aee2d 100644 --- a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java @@ -92,7 +92,7 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan FOUserAgent userAgent = pageSeq.getUserAgent(); ImageManager imageManager = userAgent.getFactory().getImageManager(); - String uri = getExternalDocument().getSrc(); + String uri = URISpecification.getURL(getExternalDocument().getSrc()); Integer firstPageIndex = ImageUtil.getPageIndexFromURI(uri); boolean hasPageIndex = (firstPageIndex != null); @@ -146,7 +146,6 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan } catch (URISyntaxException e) { getResourceEventProducer().uriError(this, uri, e, getExternalDocument().getLocator()); - return; } } } catch (FileNotFoundException fnfe) { diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java index a29398b93..5357565a7 100644 --- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.area.Area; import org.apache.fop.area.BlockParent; import org.apache.fop.fo.pagination.Flow; +import org.apache.fop.util.ListUtil; /** * LayoutManager for an fo:flow object. @@ -61,22 +62,9 @@ public class FlowLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public List getNextKnuthElements(LayoutContext context, int alignment) { - - List elements = new LinkedList(); - - LayoutManager currentChildLM; - while ((currentChildLM = getChildLM()) != null) { - if (addChildElements(elements, currentChildLM, context, alignment) != null) { - return elements; - } - } - - SpaceResolver.resolveElementList(elements); - setFinished(true); - - assert !elements.isEmpty(); - return elements; + return getNextKnuthElements(context, alignment, null, null); } /** @@ -84,43 +72,50 @@ public class FlowLayoutManager extends BlockStackingLayoutManager * of the node assigned to the LM. * @param context the LayoutContext used to store layout information * @param alignment the desired text alignment - * @param positionAtIPDChange position at ipd change - * @param restartAtLM restart at this layout manager + * @param restartPosition {@link Position} to restart from + * @param restartLM {@link LayoutManager} to restart from * @return the list of KnuthElements * @see LayoutManager#getNextKnuthElements(LayoutContext,int) */ - public List getNextKnuthElements(LayoutContext context, int alignment, - Position positionAtIPDChange, LayoutManager restartAtLM) { + List getNextKnuthElements(LayoutContext context, int alignment, + Position restartPosition, LayoutManager restartLM) { - List elements = new LinkedList(); + List<ListElement> elements = new LinkedList<ListElement>(); - LayoutManager currentChildLM = positionAtIPDChange.getLM(); - if (currentChildLM == null) { - throw new IllegalStateException( - "Cannot find layout manager from where to re-start layout after IPD change"); - } - if (restartAtLM != null && restartAtLM.getParent() == this) { - currentChildLM = restartAtLM; - setCurrentChildLM(currentChildLM); - currentChildLM.reset(); - if (addChildElements(elements, currentChildLM, context, alignment) != null) { - return elements; - } - } else { - Stack lmStack = new Stack(); - while (currentChildLM.getParent() != this) { - lmStack.push(currentChildLM); - currentChildLM = currentChildLM.getParent(); + boolean isRestart = (restartPosition != null); + LayoutManager currentChildLM; + if (isRestart) { + currentChildLM = restartPosition.getLM(); + if (currentChildLM == null) { + throw new IllegalStateException( + "Cannot find layout manager from where to re-start " + + "layout after IPD change"); } - setCurrentChildLM(currentChildLM); - if (addChildElements(elements, currentChildLM, context, alignment, lmStack, - positionAtIPDChange, restartAtLM) != null) { - return elements; + if (restartLM != null && restartLM.getParent() == this) { + currentChildLM = restartLM; + setCurrentChildLM(currentChildLM); + currentChildLM.reset(); + if (addChildElements(elements, currentChildLM, context, alignment) != null) { + return elements; + } + } else { + Stack<LayoutManager> lmStack = new Stack<LayoutManager>(); + while (currentChildLM.getParent() != this) { + lmStack.push(currentChildLM); + currentChildLM = currentChildLM.getParent(); + } + setCurrentChildLM(currentChildLM); + if (addChildElements(elements, currentChildLM, context, alignment, lmStack, + restartPosition, restartLM) != null) { + return elements; + } } } while ((currentChildLM = getChildLM()) != null) { - currentChildLM.reset(); // TODO won't work with forced breaks + if (isRestart) { + currentChildLM.reset(); // TODO won't work with forced breaks + } if (addChildElements(elements, currentChildLM, context, alignment) != null) { return elements; } @@ -133,31 +128,33 @@ public class FlowLayoutManager extends BlockStackingLayoutManager return elements; } - private List addChildElements(List elements, LayoutManager childLM, LayoutContext context, - int alignment) { + private List<ListElement> addChildElements(List<ListElement> elements, + LayoutManager childLM, LayoutContext context, int alignment) { return addChildElements(elements, childLM, context, alignment, null, null, null); } - private List addChildElements(List elements, LayoutManager childLM, LayoutContext context, - int alignment, Stack lmStack, Position position, LayoutManager restartAtLM) { - if (handleSpanChange(childLM, elements, context)) { + private List<ListElement> addChildElements(List<ListElement> elements, + LayoutManager childLM, LayoutContext context, int alignment, + Stack<LayoutManager> lmStack, Position position, LayoutManager restartAtLM) { + if (handleSpanChange(childLM, context)) { SpaceResolver.resolveElementList(elements); return elements; } - LayoutContext childLC = new LayoutContext(0); - List childrenElements = getNextChildElements(childLM, context, childLC, alignment, lmStack, - position, restartAtLM); + LayoutContext childLC = makeChildLayoutContext(context); + List<ListElement> childElements + = getNextChildElements(childLM, context, childLC, alignment, lmStack, + position, restartAtLM); if (elements.isEmpty()) { context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); } if (!elements.isEmpty() - && !ElementListUtils.startsWithForcedBreak(childrenElements)) { + && !ElementListUtils.startsWithForcedBreak(childElements)) { addInBetweenBreak(elements, context, childLC); } context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); - elements.addAll(childrenElements); + elements.addAll(childElements); if (ElementListUtils.endsWithForcedBreak(elements)) { // a descendant of this flow has break-before or break-after @@ -170,7 +167,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager return null; } - private boolean handleSpanChange(LayoutManager childLM, List elements, LayoutContext context) { + private boolean handleSpanChange(LayoutManager childLM, LayoutContext context) { int span = EN_NONE; int disableColumnBalancing = EN_FALSE; if (childLM instanceof BlockLayoutManager) { @@ -196,32 +193,47 @@ public class FlowLayoutManager extends BlockStackingLayoutManager } } - private List getNextChildElements(LayoutManager childLM, LayoutContext context, - LayoutContext childLC, int alignment, Stack lmStack, Position restartPosition, - LayoutManager restartLM) { + /** + * Overridden to take into account the current page-master's + * writing-mode + * {@inheritDoc} + */ + @Override + protected LayoutContext makeChildLayoutContext(LayoutContext context) { + LayoutContext childLC = new LayoutContext(0); childLC.setStackLimitBP(context.getStackLimitBP()); childLC.setRefIPD(context.getRefIPD()); childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode()); + return childLC; + } - List childrenElements; + /** + * Overridden to wrap the child positions before returning the list + * {@inheritDoc} + */ + @Override + protected List<ListElement> getNextChildElements(LayoutManager childLM, LayoutContext context, + LayoutContext childLC, int alignment, Stack<LayoutManager> lmStack, + Position restartPosition, LayoutManager restartLM) { + + List<ListElement> childElements; if (lmStack == null) { - childrenElements = childLM.getNextKnuthElements(childLC, alignment); + childElements = childLM.getNextKnuthElements(childLC, alignment); } else { - childrenElements = childLM.getNextKnuthElements(childLC, - alignment, lmStack, restartPosition, restartLM); + childElements = childLM.getNextKnuthElements(childLC, alignment, + lmStack, restartPosition, restartLM); } - assert !childrenElements.isEmpty(); + assert !childElements.isEmpty(); // "wrap" the Position inside each element - List tempList = childrenElements; - childrenElements = new LinkedList(); - wrapPositionElements(tempList, childrenElements); - return childrenElements; + List tempList = childElements; + childElements = new LinkedList<ListElement>(); + wrapPositionElements(tempList, childElements); + return childElements; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) { log.debug(" FLM.negotiateBPDAdjustment> " + adj); @@ -239,9 +251,8 @@ public class FlowLayoutManager extends BlockStackingLayoutManager } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public void discardSpace(KnuthGlue spaceGlue) { log.debug(" FLM.discardSpace> "); @@ -255,26 +266,30 @@ public class FlowLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public Keep getKeepTogether() { return Keep.KEEP_AUTO; } /** {@inheritDoc} */ + @Override public Keep getKeepWithNext() { return Keep.KEEP_AUTO; } /** {@inheritDoc} */ + @Override public Keep getKeepWithPrevious() { return Keep.KEEP_AUTO; } /** {@inheritDoc} */ - public List getChangedKnuthElements(List oldList, /*int flaggedPenalty,*/ int alignment) { - ListIterator oldListIterator = oldList.listIterator(); + @Override + public List<KnuthElement> getChangedKnuthElements(List oldList, int alignment) { + ListIterator<KnuthElement> oldListIterator = oldList.listIterator(); KnuthElement returnedElement; - List returnedList = new LinkedList(); - List returnList = new LinkedList(); + List<KnuthElement> returnedList = new LinkedList<KnuthElement>(); + List<KnuthElement> returnList = new LinkedList<KnuthElement>(); KnuthElement prevElement = null; KnuthElement currElement = null; int fromIndex = 0; @@ -282,7 +297,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager // "unwrap" the Positions stored in the elements KnuthElement oldElement; while (oldListIterator.hasNext()) { - oldElement = (KnuthElement)oldListIterator.next(); + oldElement = oldListIterator.next(); if (oldElement.getPosition() instanceof NonLeafPosition) { // oldElement was created by a descendant of this FlowLM oldElement.setPosition((oldElement.getPosition()).getPosition()); @@ -296,7 +311,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager while (oldListIterator.hasNext()) { - currElement = (KnuthElement) oldListIterator.next(); + currElement = oldListIterator.next(); if (prevElement != null && prevElement.getLayoutManager() != currElement.getLayoutManager()) { // prevElement is the last element generated by the same LM @@ -314,8 +329,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager // add an infinite penalty to forbid a break between blocks returnedList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, new Position(this), false)); - } else if (!((KnuthElement) returnedList.get(returnedList - .size() - 1)).isGlue()) { + } else if (!ListUtil.getLast(returnedList).isGlue()) { // add a null penalty to allow a break between blocks returnedList.add(new KnuthPenalty(0, 0, false, new Position(this), false)); } @@ -331,9 +345,9 @@ public class FlowLayoutManager extends BlockStackingLayoutManager // "wrap" the Position stored in each element of returnedList // and add elements to returnList - ListIterator listIter = returnedList.listIterator(); + ListIterator<KnuthElement> listIter = returnedList.listIterator(); while (listIter.hasNext()) { - returnedElement = (KnuthElement)listIter.next(); + returnedElement = listIter.next(); if (returnedElement.getLayoutManager() != this) { returnedElement.setPosition( new NonLeafPosition(this, returnedElement.getPosition())); @@ -344,9 +358,8 @@ public class FlowLayoutManager extends BlockStackingLayoutManager return returnList; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { AreaAdditionUtil.addAreas(this, parentIter, layoutContext); flush(); @@ -359,15 +372,15 @@ public class FlowLayoutManager extends BlockStackingLayoutManager * * @param childArea the area to add */ + @Override public void addChildArea(Area childArea) { getParentArea(childArea); addChildToArea(childArea, this.currentAreas[childArea.getAreaClass()]); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public Area getParentArea(Area childArea) { BlockParent parentArea = null; int aclass = childArea.getAreaClass(); @@ -392,6 +405,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager * Returns the IPD of the content area * @return the IPD of the content area */ + @Override public int getContentAreaIPD() { return getCurrentPV().getCurrentSpan().getColumnWidth(); } @@ -400,11 +414,13 @@ public class FlowLayoutManager extends BlockStackingLayoutManager * Returns the BPD of the content area * @return the BPD of the content area */ + @Override public int getContentAreaBPD() { return getCurrentPV().getBodyRegion().getBPD(); } /** {@inheritDoc} */ + @Override public boolean isRestartable() { return true; } diff --git a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java index 4f6cfa9d5..078b7c451 100644 --- a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java @@ -38,38 +38,36 @@ public class FootnoteBodyLayoutManager extends BlockStackingLayoutManager { } /** {@inheritDoc} */ + @Override public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { - LayoutManager childLM = null; + LayoutManager childLM; LayoutManager lastLM = null; LayoutContext lc = new LayoutContext(0); // "unwrap" the NonLeafPositions stored in parentIter // and put them in a new list; - LinkedList positionList = new LinkedList(); + LinkedList<Position> positionList = new LinkedList<Position>(); Position pos; while (parentIter.hasNext()) { - pos = (Position) parentIter.next(); - //log.trace("pos = " + pos.getClass().getName() + "; " + pos); - Position innerPosition = pos; + pos = parentIter.next(); + Position innerPosition; if (pos instanceof NonLeafPosition) { - innerPosition = ((NonLeafPosition) pos).getPosition(); + innerPosition = pos.getPosition(); if (innerPosition.getLM() == this) { // pos was created by this LM and was inside a penalty // allowing or forbidding a page break // nothing to do - //log.trace(" penalty"); } else { // innerPosition was created by another LM positionList.add(innerPosition); lastLM = innerPosition.getLM(); - //log.trace(" " + innerPosition.getClass().getName()); } } } // the Positions in positionList were inside the elements // created by the LineLM - StackingIter childPosIter = new StackingIter(positionList.listIterator()); + PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); while ((childLM = childPosIter.getNextChildLM()) != null) { // set last area flag @@ -81,6 +79,7 @@ public class FootnoteBodyLayoutManager extends BlockStackingLayoutManager { } /** {@inheritDoc} */ + @Override public void addChildArea(Area childArea) { childArea.setAreaClass(Area.CLASS_FOOTNOTE); parentLayoutManager.addChildArea(childArea); @@ -92,16 +91,19 @@ public class FootnoteBodyLayoutManager extends BlockStackingLayoutManager { } /** {@inheritDoc} */ + @Override public Keep getKeepTogether() { return getParentKeepTogether(); } /** {@inheritDoc} */ + @Override public Keep getKeepWithNext() { return Keep.KEEP_AUTO; } /** {@inheritDoc} */ + @Override public Keep getKeepWithPrevious() { return Keep.KEEP_AUTO; } diff --git a/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java b/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java index e69b991b3..71790ec82 100644 --- a/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java +++ b/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java @@ -22,7 +22,8 @@ package org.apache.fop.layoutmgr; import java.util.List; /** - * A Knuth element position iterator. + * A dedicated {@link PositionIterator} that is backed by an iterator + * over a list of {@link KnuthElement}s. */ public class KnuthPossPosIter extends PositionIterator { @@ -50,6 +51,7 @@ public class KnuthPossPosIter extends PositionIterator { // Check position < endPos /** {@inheritDoc} */ + @Override protected boolean checkNext() { if (iterCount > 0) { return super.checkNext(); @@ -60,7 +62,8 @@ public class KnuthPossPosIter extends PositionIterator { } /** {@inheritDoc} */ - public Object next() { + @Override + public Position next() { --iterCount; return super.next(); } @@ -74,11 +77,13 @@ public class KnuthPossPosIter extends PositionIterator { } /** {@inheritDoc} */ + @Override protected LayoutManager getLM(Object nextObj) { return ((ListElement) nextObj).getLayoutManager(); } /** {@inheritDoc} */ + @Override protected Position getPos(Object nextObj) { return ((ListElement) nextObj).getPosition(); } diff --git a/src/java/org/apache/fop/layoutmgr/LMiter.java b/src/java/org/apache/fop/layoutmgr/LMiter.java index 9f437df6a..d3ad30485 100644 --- a/src/java/org/apache/fop/layoutmgr/LMiter.java +++ b/src/java/org/apache/fop/layoutmgr/LMiter.java @@ -24,10 +24,10 @@ import java.util.ListIterator; import java.util.NoSuchElementException; /** An iterator for layout managers. */ -public class LMiter implements ListIterator { +public class LMiter implements ListIterator<LayoutManager> { /** list of layout managers */ - protected List listLMs; + protected List<LayoutManager> listLMs; /** current position in iteration */ protected int curPos = 0; /** The LayoutManager to which this LMiter is attached **/ @@ -44,7 +44,7 @@ public class LMiter implements ListIterator { /** {@inheritDoc} */ public boolean hasNext() { - return (curPos < listLMs.size()) ? true : lp.createNextChildLMs(curPos); + return (curPos < listLMs.size()) || lp.createNextChildLMs(curPos); } /** {@inheritDoc} */ @@ -53,7 +53,7 @@ public class LMiter implements ListIterator { } /** {@inheritDoc} */ - public Object previous() throws NoSuchElementException { + public LayoutManager previous() throws NoSuchElementException { if (curPos > 0) { return listLMs.get(--curPos); } else { @@ -62,7 +62,7 @@ public class LMiter implements ListIterator { } /** {@inheritDoc} */ - public Object next() throws NoSuchElementException { + public LayoutManager next() throws NoSuchElementException { if (curPos < listLMs.size()) { return listLMs.get(curPos++); } else { @@ -82,12 +82,12 @@ public class LMiter implements ListIterator { /** {@inheritDoc} */ - public void add(Object o) throws UnsupportedOperationException { + public void add(LayoutManager lm) throws UnsupportedOperationException { throw new UnsupportedOperationException("LMiter doesn't support add"); } /** {@inheritDoc} */ - public void set(Object o) throws UnsupportedOperationException { + public void set(LayoutManager lm) throws UnsupportedOperationException { throw new UnsupportedOperationException("LMiter doesn't support set"); } diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java index 7e54cbe43..4b6638300 100644 --- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java +++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java @@ -43,16 +43,16 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { private PageProvider pageProvider; private PageBreakingLayoutListener layoutListener; /** List of PageBreakPosition elements. */ - private LinkedList pageBreaks = null; + private LinkedList<PageBreakPosition> pageBreaks = null; /** Footnotes which are cited between the currently considered active node (previous * break) and the current considered break. Its type is * List<List<KnuthElement>>, it contains the sequences of KnuthElement * representing the footnotes bodies. */ - private List footnotesList = null; + private List<List<KnuthElement>> footnotesList = null; /** Cumulated bpd of unhandled footnotes. */ - private List lengthList = null; + private List<Integer> lengthList = null; /** Length of all the footnotes which will be put on the current page. */ private int totalFootnotesLength = 0; /** @@ -64,13 +64,9 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { /** True if footnote citations have been met since the beginning of the page sequence. */ private boolean footnotesPending = false; - /** - * True if the elements met after the previous break point contain footnote citations. - */ + /** True if the elements met after the previous break point contain footnote citations. */ private boolean newFootnotes = false; - /** - * Index of the first footnote met after the previous break point. - */ + /** Index of the first footnote met after the previous break point. */ private int firstNewFootnoteIndex = 0; /** Index of the last footnote inserted on the current page. */ private int footnoteListIndex = 0; @@ -206,6 +202,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected void initialize() { super.initialize(); insertedFootnotesLength = 0; @@ -214,11 +211,12 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** - * {@inheritDoc} * Overridden to defer a part to the next page, if it * must be kept within one page, but is too large to fit in * the last column. + * {@inheritDoc} */ + @Override protected KnuthNode recoverFromTooLong(KnuthNode lastTooLong) { if (log.isDebugEnabled()) { @@ -256,6 +254,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { * @param node2 The other knuth node. * @return the node with the least demerit. */ + @Override protected KnuthNode compareNodes(KnuthNode node1, KnuthNode node2) { /* if either node is null, return the other one */ @@ -281,6 +280,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected KnuthNode createNode(int position, // CSOK: ParameterNumber int line, int fitness, int totalWidth, int totalStretch, int totalShrink, @@ -294,6 +294,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected KnuthNode createNode(int position, int line, int fitness, int totalWidth, int totalStretch, int totalShrink) { return new KnuthPageNode(position, line, fitness, @@ -307,11 +308,11 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** - * {@inheritDoc} * Page-breaking specific handling of the given box. Currently it adds the footnotes * cited in the given box to the list of to-be-handled footnotes. - * @param box a block-level element possibly containing foonotes citations + * {@inheritDoc} */ + @Override protected void handleBox(KnuthBox box) { super.handleBox(box); if (box instanceof KnuthBlockBox @@ -325,11 +326,12 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** - * {@inheritDoc} * Overridden to consider penalties with value {@link KnuthElement#INFINITE} * as legal break-points, if the current keep-context allows this * (a keep-*.within-page="always" constraint still permits column-breaks) + * {@inheritDoc} */ + @Override protected void handlePenaltyAt(KnuthPenalty penalty, int position, int allowedBreaks) { super.handlePenaltyAt(penalty, position, allowedBreaks); @@ -352,12 +354,12 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { * @param elementLists list of KnuthElement sequences corresponding to the footnotes * bodies */ - private void handleFootnotes(List elementLists) { + private void handleFootnotes(List<List<KnuthElement>> elementLists) { // initialization if (!footnotesPending) { footnotesPending = true; - footnotesList = new ArrayList(); - lengthList = new ArrayList(); + footnotesList = new ArrayList<List<KnuthElement>>(); + lengthList = new ArrayList<Integer>(); totalFootnotesLength = 0; } if (!newFootnotes) { @@ -366,9 +368,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } // compute the total length of the footnotes - for (Iterator elementListsIterator = elementLists.iterator(); - elementListsIterator.hasNext();) { - final List noteList = (List) elementListsIterator.next(); + for (List<KnuthElement> noteList : elementLists) { //Space resolution (Note: this does not respect possible stacking constraints //between footnotes!) @@ -376,23 +376,23 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { int noteLength = 0; footnotesList.add(noteList); - for (Iterator noteListIterator = noteList.iterator(); - noteListIterator.hasNext();) { - final KnuthElement element = (KnuthElement) noteListIterator.next(); + for (KnuthElement element : noteList) { if (element.isBox() || element.isGlue()) { noteLength += element.getWidth(); } } int prevLength = (lengthList == null || lengthList.isEmpty()) ? 0 - : ((Integer) ListUtil.getLast(lengthList)).intValue(); - //TODO: replace with Integer.valueOf() once we switch to Java 5 - lengthList.add(new Integer(prevLength + noteLength)); + : ListUtil.getLast(lengthList); + if (lengthList != null) { + lengthList.add(prevLength + noteLength); + } totalFootnotesLength += noteLength; } } /** {@inheritDoc} */ + @Override protected int restartFrom(KnuthNode restartingNode, int currentIndex) { int returnValue = super.restartFrom(restartingNode, currentIndex); newFootnotes = false; @@ -410,14 +410,14 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { return returnValue; } - private void resetFootnotes(List elementLists) { + private void resetFootnotes(List<List<KnuthElement>> elementLists) { for (int i = 0; i < elementLists.size(); i++) { - /*LinkedList removedList = (LinkedList)*/ListUtil.removeLast(footnotesList); + ListUtil.removeLast(footnotesList); ListUtil.removeLast(lengthList); // update totalFootnotesLength if (!lengthList.isEmpty()) { - totalFootnotesLength = ((Integer) ListUtil.getLast(lengthList)).intValue(); + totalFootnotesLength = ListUtil.getLast(lengthList); } else { totalFootnotesLength = 0; } @@ -429,6 +429,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected void considerLegalBreak(KnuthElement element, int elementIdx) { if (element.isPenalty()) { int breakClass = ((KnuthPenalty) element).getBreakClass(); @@ -457,6 +458,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected boolean elementCanEndLine(KnuthElement element, int line, int difference) { if (!(element.isPenalty()) || pageProvider == null) { return true; @@ -489,11 +491,12 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected int computeDifference(KnuthNode activeNode, KnuthElement element, int elementIndex) { KnuthPageNode pageNode = (KnuthPageNode) activeNode; int actualWidth = totalWidth - pageNode.totalWidth; - int footnoteSplit = 0; + int footnoteSplit; boolean canDeferOldFN; if (element.isPenalty()) { actualWidth += element.getWidth(); @@ -562,6 +565,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { * @param node active node for the preceding page break * @param contentElementIndex index of the Knuth element considered for the * current page break + * @return true if footnotes can be deferred */ private boolean canDeferOldFootnotes(KnuthPageNode node, int contentElementIndex) { return (noBreakBetween(node.position, contentElementIndex) @@ -668,8 +672,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { // together with all previous, not yet inserted footnotes; // but if this is not possible, try adding as much content as possible int splitLength = 0; - ListIterator noteListIterator = null; - KnuthElement element = null; + ListIterator<KnuthElement> noteListIterator; + KnuthElement element; boolean somethingAdded = false; // prevListIndex and prevElementIndex points to the last footnote element @@ -687,16 +691,14 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { if (footnotesList.size() - 1 > listIndex) { // add the previous footnotes: these cannot be broken or deferred if (!canDeferOldFootnotes && newFootnotes && firstNewFootnoteIndex > 0) { - splitLength = ((Integer) lengthList.get(firstNewFootnoteIndex - 1)).intValue() - - prevLength; + splitLength = lengthList.get(firstNewFootnoteIndex - 1) - prevLength; listIndex = firstNewFootnoteIndex; elementIndex = 0; } // try adding the new footnotes - while (((Integer) lengthList.get(listIndex)).intValue() - prevLength + while (lengthList.get(listIndex) - prevLength <= availableLength) { - splitLength = ((Integer) lengthList.get(listIndex)).intValue() - - prevLength; + splitLength = lengthList.get(listIndex) - prevLength; somethingAdded = true; listIndex++; elementIndex = 0; @@ -727,7 +729,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { // all footnotes, and we have already tried (and failed) to insert // this whole footnote, the while loop will never reach the end // of the note sequence - element = (KnuthElement) noteListIterator.next(); + element = noteListIterator.next(); if (element.isBox()) { // element is a box splitLength += element.getWidth(); @@ -774,6 +776,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected double computeAdjustmentRatio(KnuthNode activeNode, int difference) { // compute the adjustment ratio if (difference > 0) { @@ -804,6 +807,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected double computeDemerits(KnuthNode activeNode, KnuthElement element, int fitnessClass, double r) { double demerits = 0; @@ -856,6 +860,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { return demerits; } + /** {@inheritDoc} */ + @Override protected void finish() { for (int i = startLine; i < endLine; i++) { for (KnuthPageNode node = (KnuthPageNode) getNode(i); @@ -880,7 +886,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { // create pages containing the remaining footnote bodies while (insertedFootnotesLength < totalFootnotesLength) { - final int tmpLength = ((Integer) lengthList.get(footnoteListIndex)).intValue(); + final int tmpLength = lengthList.get(footnoteListIndex); // try adding some more content if ((tmpLength - insertedFootnotesLength) <= availableBPD) { // add a whole footnote @@ -925,7 +931,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { * @return a list of {@link PageBreakPosition} elements * corresponding to the computed page- and column-breaks */ - public LinkedList getPageBreaks() { + public LinkedList<PageBreakPosition> getPageBreaks() { return pageBreaks; } @@ -937,7 +943,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { */ public void insertPageBreakAsFirst(PageBreakPosition pageBreak) { if (pageBreaks == null) { - pageBreaks = new LinkedList(); + pageBreaks = new LinkedList<PageBreakPosition>(); } pageBreaks.addFirst(pageBreak); } @@ -948,19 +954,19 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { * whole content should be painted as one part. */ public void removeAllPageBreaks() { - if (pageBreaks == null) { + if (pageBreaks == null || pageBreaks.isEmpty()) { return; } - while (pageBreaks.size() > 1) { - pageBreaks.removeFirst(); - } + pageBreaks.subList(0, pageBreaks.size() - 1).clear(); } /** {@inheritDoc} */ + @Override public void updateData1(int total, double demerits) { } /** {@inheritDoc} */ + @Override public void updateData2(KnuthNode bestActiveNode, KnuthSequence sequence, int total) { @@ -1029,6 +1035,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected int filterActiveNodes() { // leave only the active node with fewest total demerits KnuthNode bestActiveNode = null; @@ -1058,8 +1065,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { * @param index the index in the list of footnotes * @return the element-list */ - protected final List getFootnoteList(int index) { - return (List) footnotesList.get(index); + protected final List<KnuthElement> getFootnoteList(int index) { + return footnotesList.get(index); } /** @return the associated top-level formatting object. */ @@ -1068,6 +1075,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected int getLineWidth(int line) { int bpd; if (pageProvider != null) { @@ -1097,11 +1105,13 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } /** {@inheritDoc} */ + @Override protected int getIPDdifference() { return ipdDifference; } /** {@inheritDoc} */ + @Override protected int handleIpdChange() { log.trace("Best node for ipd change:" + bestNodeForIPDChange); // TODO finish() @@ -1123,6 +1133,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { * @param line number of the line ending at the node's corresponding breakpoint * @param node the active node to add */ + @Override protected void addNode(int line, KnuthNode node) { if (node.position < par.size() - 1 && line > 0 && (ipdDifference = compareIPDs(line - 1)) != 0) { // CSOK: InnerAssignment @@ -1153,5 +1164,4 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } return pageProvider.compareIPDs(line); } - } diff --git a/src/java/org/apache/fop/layoutmgr/PositionIterator.java b/src/java/org/apache/fop/layoutmgr/PositionIterator.java index 63ff8461a..b2bf404ff 100644 --- a/src/java/org/apache/fop/layoutmgr/PositionIterator.java +++ b/src/java/org/apache/fop/layoutmgr/PositionIterator.java @@ -22,20 +22,29 @@ package org.apache.fop.layoutmgr; import java.util.Iterator; import java.util.NoSuchElementException; -/** A position iterator. */ -public abstract class PositionIterator implements Iterator { +/** + * An iterator over {@link Position} instances, that is wrapped around + * another 'parent' {@link Iterator}. The parent can be either another + * {@code PositionIterator}, or an iterator over {@link KnuthElement}s, + * for example.<br/> + * The {@link #next()} method always returns a {@link Position}. The + * {@link #getPos(Object)} method can be overridden in subclasses + * to take care of obtaining the {@link LayoutManager} or {@link Position} + * from the object returned by the parent iterator's {@code next()} method. + */ +public class PositionIterator implements Iterator<Position> { private Iterator parentIter; private Object nextObj; private LayoutManager childLM; - private boolean bHasNext; + private boolean hasNext; /** * Construct position iterator. - * @param pIter an iterator to use as parent + * @param parentIter an iterator to use as parent */ - protected PositionIterator(Iterator pIter) { - parentIter = pIter; + public PositionIterator(Iterator parentIter) { + this.parentIter = parentIter; lookAhead(); //checkNext(); } @@ -45,7 +54,7 @@ public abstract class PositionIterator implements Iterator { // Move to next "segment" of iterator, ie: new childLM if (childLM == null && nextObj != null) { childLM = getLM(nextObj); - bHasNext = true; + hasNext = true; } return childLM; } @@ -54,17 +63,29 @@ public abstract class PositionIterator implements Iterator { * @param nextObj next object from which to obtain position * @return layout manager */ - protected abstract LayoutManager getLM(Object nextObj); + protected LayoutManager getLM(Object nextObj) { + return getPos(nextObj).getLM(); + } /** + * Default implementation assumes that the passed + * {@code nextObj} is itself a {@link Position}, and just returns it. + * Subclasses for which this is not the case, <em>must</em> provide a + * suitable override this method. * @param nextObj next object from which to obtain position - * @return position of next object + * @return position of next object. */ - protected abstract Position getPos(Object nextObj); + protected Position getPos(Object nextObj) { + if (nextObj instanceof Position) { + return (Position)nextObj; + } + throw new IllegalArgumentException( + "Cannot obtain Position from the given object."); + } private void lookAhead() { if (parentIter.hasNext()) { - bHasNext = true; + hasNext = true; nextObj = parentIter.next(); } else { endIter(); @@ -78,7 +99,7 @@ public abstract class PositionIterator implements Iterator { childLM = lm; } else if (childLM != lm && lm != null) { // End of this sub-sequence with same child LM - bHasNext = false; + hasNext = false; childLM = null; return false; } @@ -87,23 +108,23 @@ public abstract class PositionIterator implements Iterator { /** end (reset) iterator */ protected void endIter() { - bHasNext = false; + hasNext = false; nextObj = null; childLM = null; } /** {@inheritDoc} */ public boolean hasNext() { - return (bHasNext && checkNext()); + return (hasNext && checkNext()); } /** {@inheritDoc} */ - public Object next() throws NoSuchElementException { - if (bHasNext) { - Object retObj = getPos(nextObj); + public Position next() throws NoSuchElementException { + if (hasNext) { + Position retPos = getPos(nextObj); lookAhead(); - return retObj; + return retPos; } else { throw new NoSuchElementException("PosIter"); } @@ -119,4 +140,3 @@ public abstract class PositionIterator implements Iterator { throw new UnsupportedOperationException("PositionIterator doesn't support remove"); } } - diff --git a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java index 6890d4ebc..31bdaebbf 100644 --- a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java +++ b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java @@ -136,7 +136,7 @@ public final class SpaceResolver { private String toString(Object[] arr1, Object[] arr2) { if (arr1.length != arr2.length) { - new IllegalArgumentException("The length of both arrays must be equal"); + throw new IllegalArgumentException("The length of both arrays must be equal"); } StringBuffer sb = new StringBuffer("["); for (int i = 0; i < arr1.length; i++) { @@ -647,7 +647,7 @@ public final class SpaceResolver { } } //last = !iter.hasNext(); - if (breakPoss == null && unresolvedSecond.size() == 0 && !last) { + if (breakPoss == null && unresolvedSecond.isEmpty() && !last) { LOG.trace("Swap first and second parts in no-break condition," + " second part is empty."); //The first list is reversed, so swap if this shouldn't happen diff --git a/src/java/org/apache/fop/layoutmgr/TraitSetter.java b/src/java/org/apache/fop/layoutmgr/TraitSetter.java index 6039ad941..c0e451577 100644 --- a/src/java/org/apache/fop/layoutmgr/TraitSetter.java +++ b/src/java/org/apache/fop/layoutmgr/TraitSetter.java @@ -52,36 +52,36 @@ public final class TraitSetter { * * @param area area to set the traits on * @param bpProps border and padding properties - * @param bNotFirst True if the area is not the first area - * @param bNotLast True if the area is not the last area + * @param isNotFirst True if the area is not the first area + * @param isNotLast True if the area is not the last area * @param context Property evaluation context */ public static void setBorderPaddingTraits(Area area, - CommonBorderPaddingBackground bpProps, boolean bNotFirst, boolean bNotLast, + CommonBorderPaddingBackground bpProps, boolean isNotFirst, boolean isNotLast, PercentBaseContext context) { - int iBP; - iBP = bpProps.getPadding(CommonBorderPaddingBackground.START, bNotFirst, context); - if (iBP > 0) { - area.addTrait(Trait.PADDING_START, new Integer(iBP)); + int padding; + padding = bpProps.getPadding(CommonBorderPaddingBackground.START, isNotFirst, context); + if (padding > 0) { + area.addTrait(Trait.PADDING_START, padding); } - iBP = bpProps.getPadding(CommonBorderPaddingBackground.END, bNotLast, context); - if (iBP > 0) { - area.addTrait(Trait.PADDING_END, new Integer(iBP)); + padding = bpProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, context); + if (padding > 0) { + area.addTrait(Trait.PADDING_END, padding); } - iBP = bpProps.getPadding(CommonBorderPaddingBackground.BEFORE, false, context); - if (iBP > 0) { - area.addTrait(Trait.PADDING_BEFORE, new Integer(iBP)); + padding = bpProps.getPadding(CommonBorderPaddingBackground.BEFORE, false, context); + if (padding > 0) { + area.addTrait(Trait.PADDING_BEFORE, padding); } - iBP = bpProps.getPadding(CommonBorderPaddingBackground.AFTER, false, context); - if (iBP > 0) { - area.addTrait(Trait.PADDING_AFTER, new Integer(iBP)); + padding = bpProps.getPadding(CommonBorderPaddingBackground.AFTER, false, context); + if (padding > 0) { + area.addTrait(Trait.PADDING_AFTER, padding); } - addBorderTrait(area, bpProps, bNotFirst, + addBorderTrait(area, bpProps, isNotFirst, CommonBorderPaddingBackground.START, BorderProps.SEPARATE, Trait.BORDER_START); - addBorderTrait(area, bpProps, bNotLast, + addBorderTrait(area, bpProps, isNotLast, CommonBorderPaddingBackground.END, BorderProps.SEPARATE, Trait.BORDER_END); @@ -94,7 +94,7 @@ public final class TraitSetter { BorderProps.SEPARATE, Trait.BORDER_AFTER); } - /** + /* * Sets border traits on an area. * * @param area area to set the traits on @@ -103,13 +103,13 @@ public final class TraitSetter { */ private static void addBorderTrait(Area area, CommonBorderPaddingBackground bpProps, - boolean bDiscard, int iSide, int mode, - Object oTrait) { - int iBP = bpProps.getBorderWidth(iSide, bDiscard); - if (iBP > 0) { - area.addTrait(oTrait, - new BorderProps(bpProps.getBorderStyle(iSide), - iBP, bpProps.getBorderColor(iSide), + boolean discard, int side, int mode, + Integer trait) { + int borderWidth = bpProps.getBorderWidth(side, discard); + if (borderWidth > 0) { + area.addTrait(trait, + new BorderProps(bpProps.getBorderStyle(side), + borderWidth, bpProps.getBorderColor(side), mode)); } } @@ -119,30 +119,30 @@ public final class TraitSetter { * Layout managers that create areas with borders can use this to * add the borders to the area. * @param area the area to set the traits on. - * @param bordProps border properties + * @param borderProps border properties * @param context Property evaluation context * @deprecated Call the other addBorders() method and addPadding separately. */ - public static void addBorders(Area area, CommonBorderPaddingBackground bordProps, + public static void addBorders(Area area, CommonBorderPaddingBackground borderProps, PercentBaseContext context) { - BorderProps bps = getBorderProps(bordProps, CommonBorderPaddingBackground.BEFORE); + BorderProps bps = getBorderProps(borderProps, CommonBorderPaddingBackground.BEFORE); if (bps != null) { area.addTrait(Trait.BORDER_BEFORE, bps); } - bps = getBorderProps(bordProps, CommonBorderPaddingBackground.AFTER); + bps = getBorderProps(borderProps, CommonBorderPaddingBackground.AFTER); if (bps != null) { area.addTrait(Trait.BORDER_AFTER, bps); } - bps = getBorderProps(bordProps, CommonBorderPaddingBackground.START); + bps = getBorderProps(borderProps, CommonBorderPaddingBackground.START); if (bps != null) { area.addTrait(Trait.BORDER_START, bps); } - bps = getBorderProps(bordProps, CommonBorderPaddingBackground.END); + bps = getBorderProps(borderProps, CommonBorderPaddingBackground.END); if (bps != null) { area.addTrait(Trait.BORDER_END, bps); } - addPadding(area, bordProps, context); + addPadding(area, borderProps, context); } /** @@ -150,30 +150,31 @@ public final class TraitSetter { * Layout managers that create areas with borders can use this to * add the borders to the area. * @param area the area to set the traits on. - * @param bordProps border properties + * @param borderProps border properties * @param discardBefore true if the before border should be discarded * @param discardAfter true if the after border should be discarded * @param discardStart true if the start border should be discarded * @param discardEnd true if the end border should be discarded * @param context Property evaluation context */ - public static void addBorders(Area area, CommonBorderPaddingBackground bordProps, + //TODO: remove evaluation context; unused, since border-widths are always absolute lengths + public static void addBorders(Area area, CommonBorderPaddingBackground borderProps, boolean discardBefore, boolean discardAfter, boolean discardStart, boolean discardEnd, PercentBaseContext context) { - BorderProps bps = getBorderProps(bordProps, CommonBorderPaddingBackground.BEFORE); + BorderProps bps = getBorderProps(borderProps, CommonBorderPaddingBackground.BEFORE); if (bps != null && !discardBefore) { area.addTrait(Trait.BORDER_BEFORE, bps); } - bps = getBorderProps(bordProps, CommonBorderPaddingBackground.AFTER); + bps = getBorderProps(borderProps, CommonBorderPaddingBackground.AFTER); if (bps != null && !discardAfter) { area.addTrait(Trait.BORDER_AFTER, bps); } - bps = getBorderProps(bordProps, CommonBorderPaddingBackground.START); + bps = getBorderProps(borderProps, CommonBorderPaddingBackground.START); if (bps != null && !discardStart) { area.addTrait(Trait.BORDER_START, bps); } - bps = getBorderProps(bordProps, CommonBorderPaddingBackground.END); + bps = getBorderProps(borderProps, CommonBorderPaddingBackground.END); if (bps != null && !discardEnd) { area.addTrait(Trait.BORDER_END, bps); } @@ -237,25 +238,25 @@ public final class TraitSetter { int padding = bordProps.getPadding(CommonBorderPaddingBackground.BEFORE, discardBefore, context); if (padding != 0) { - area.addTrait(Trait.PADDING_BEFORE, new java.lang.Integer(padding)); + area.addTrait(Trait.PADDING_BEFORE, padding); } padding = bordProps.getPadding(CommonBorderPaddingBackground.AFTER, discardAfter, context); if (padding != 0) { - area.addTrait(Trait.PADDING_AFTER, new java.lang.Integer(padding)); + area.addTrait(Trait.PADDING_AFTER, padding); } padding = bordProps.getPadding(CommonBorderPaddingBackground.START, discardStart, context); if (padding != 0) { - area.addTrait(Trait.PADDING_START, new java.lang.Integer(padding)); + area.addTrait(Trait.PADDING_START, padding); } padding = bordProps.getPadding(CommonBorderPaddingBackground.END, discardEnd, context); if (padding != 0) { - area.addTrait(Trait.PADDING_END, new java.lang.Integer(padding)); + area.addTrait(Trait.PADDING_END, padding); } } @@ -278,9 +279,8 @@ public final class TraitSetter { assert borderInfo != null; int width = borderInfo.getRetainedWidth(); if (width != 0) { - BorderProps bps = new BorderProps(borderInfo.getStyle(), width, borderInfo.getColor(), + return new BorderProps(borderInfo.getStyle(), width, borderInfo.getColor(), (outer ? BorderProps.COLLAPSE_OUTER : BorderProps.COLLAPSE_INNER)); - return bps; } else { return null; } @@ -460,24 +460,24 @@ public final class TraitSetter { int startIndent, int endIndent, PercentBaseContext context) { if (startIndent != 0) { - area.addTrait(Trait.START_INDENT, new Integer(startIndent)); + area.addTrait(Trait.START_INDENT, startIndent); } int spaceStart = startIndent - bpProps.getBorderStartWidth(false) - bpProps.getPaddingStart(false, context); if (spaceStart != 0) { - area.addTrait(Trait.SPACE_START, new Integer(spaceStart)); + area.addTrait(Trait.SPACE_START, spaceStart); } if (endIndent != 0) { - area.addTrait(Trait.END_INDENT, new Integer(endIndent)); + area.addTrait(Trait.END_INDENT, endIndent); } int spaceEnd = endIndent - bpProps.getBorderEndWidth(false) - bpProps.getPaddingEnd(false, context); if (spaceEnd != 0) { - area.addTrait(Trait.SPACE_END, new Integer(spaceEnd)); + area.addTrait(Trait.SPACE_END, spaceEnd); } } @@ -537,7 +537,7 @@ public final class TraitSetter { MinOptMax space, double adjust) { int effectiveSpace = getEffectiveSpace(adjust, space); if (effectiveSpace != 0) { - area.addTrait(spaceTrait, new Integer(effectiveSpace)); + area.addTrait(spaceTrait, effectiveSpace); } } @@ -561,7 +561,7 @@ public final class TraitSetter { */ public static void addFontTraits(Area area, Font font) { area.addTrait(Trait.FONT, font.getFontTriplet()); - area.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize())); + area.addTrait(Trait.FONT_SIZE, font.getFontSize()); } /** diff --git a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java index 66e162692..2178b2e77 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java @@ -60,6 +60,7 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { } /** {@inheritDoc} */ + @Override public void initialize() { Character fobj = (Character)this.fobj; font = FontSelector.selectFontForCharacter(fobj, this); @@ -91,6 +92,7 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { } /** {@inheritDoc} */ + @Override public List getNextKnuthElements(LayoutContext context, int alignment) { MinOptMax ipd; curArea = get(context); @@ -147,23 +149,25 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { addKnuthElementsForBorderPaddingEnd(seq); - LinkedList returnList = new LinkedList(); + LinkedList<KnuthSequence> returnList = new LinkedList<KnuthSequence>(); returnList.add(seq); setFinished(true); return returnList; } /** {@inheritDoc} */ + @Override public String getWordChars(Position pos) { return ((TextArea) curArea).getText(); } /** {@inheritDoc} */ + @Override public void hyphenate(Position pos, HyphContext hc) { if (hc.getNextHyphPoint() == 1) { // the character ends a syllable - areaInfo.bHyphenated = true; - isSomethingChanged = true; + areaInfo.isHyphenated = true; + somethingChanged = true; } else { // hc.getNextHyphPoint() returned -1 (no more hyphenation points) // or a number > 1; @@ -173,42 +177,44 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { } /** {@inheritDoc} */ + @Override public boolean applyChanges(List oldList) { setFinished(false); - return isSomethingChanged; + return somethingChanged; } /** {@inheritDoc} */ + @Override public List getChangedKnuthElements(List oldList, int alignment) { if (isFinished()) { return null; } - LinkedList returnList = new LinkedList(); + LinkedList<KnuthElement> returnList = new LinkedList<KnuthElement>(); addKnuthElementsForBorderPaddingStart(returnList); - if (letterSpaceIPD.isStiff() || areaInfo.iLScount == 0) { + if (letterSpaceIPD.isStiff() || areaInfo.letterSpaces == 0) { // constant letter space, or no letter space returnList.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(), areaInfo.alignmentContext, notifyPos(new LeafPosition(this, 0)), false)); - if (areaInfo.bHyphenated) { + if (areaInfo.isHyphenated) { returnList.add(new KnuthPenalty(hyphIPD, KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); } } else { // adjustable letter space returnList.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt() - - areaInfo.iLScount * letterSpaceIPD.getOpt(), areaInfo.alignmentContext, + - areaInfo.letterSpaces * letterSpaceIPD.getOpt(), areaInfo.alignmentContext, notifyPos(new LeafPosition(this, 0)), false)); returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, new LeafPosition(this, -1), true)); - returnList.add(new KnuthGlue(letterSpaceIPD.mult(areaInfo.iLScount), + returnList.add(new KnuthGlue(letterSpaceIPD.mult(areaInfo.letterSpaces), new LeafPosition(this, -1), true)); returnList.add ( new KnuthInlineBox(0, null, notifyPos(new LeafPosition(this, -1)), true)); - if (areaInfo.bHyphenated) { + if (areaInfo.isHyphenated) { returnList.add(new KnuthPenalty(hyphIPD, KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java index efa6f880a..d5d62dd4b 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java @@ -34,6 +34,7 @@ import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.NonLeafPosition; +import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; /** @@ -62,6 +63,7 @@ public class FootnoteLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override public void initialize() { // create an InlineStackingLM handling the fo:inline child of fo:footnote citationLM = new InlineLayoutManager(footnote.getFootnoteCitation()); @@ -71,6 +73,7 @@ public class FootnoteLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override public List getNextKnuthElements(LayoutContext context, int alignment) { // for the moment, this LM is set as the citationLM's parent @@ -119,9 +122,8 @@ public class FootnoteLayoutManager extends InlineStackingLayoutManager { return returnedList; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public List getChangedKnuthElements(List oldList, int alignment, int depth) { List returnedList = super.getChangedKnuthElements(oldList, alignment, depth); addAnchor(returnedList); @@ -129,16 +131,15 @@ public class FootnoteLayoutManager extends InlineStackingLayoutManager { } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + @Override public void addAreas(PositionIterator posIter, LayoutContext context) { // "Unwrap" the NonLeafPositions stored in posIter and put // them in a new list, that will be given to the citationLM - LinkedList positionList = new LinkedList(); - NonLeafPosition pos = null; + LinkedList<Position> positionList = new LinkedList<Position>(); + Position pos; while (posIter.hasNext()) { - pos = (NonLeafPosition) posIter.next(); + pos = posIter.next(); if (pos != null && pos.getPosition() != null) { positionList.add(pos.getPosition()); } @@ -150,7 +151,7 @@ public class FootnoteLayoutManager extends InlineStackingLayoutManager { // make the citationLM add its areas LayoutContext childContext = new LayoutContext(context); - StackingIter childPosIter = new StackingIter(positionList.listIterator()); + PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); LayoutManager childLM; while ((childLM = childPosIter.getNextChildLM()) != null) { childLM.addAreas(childPosIter, childContext); diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java index 1d3233112..985094edd 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java @@ -77,8 +77,6 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { private boolean areaCreated = false; private LayoutManager lastChildLM = null; // Set when return last breakposs; - private Position auxiliaryPosition; - private Font font; /** The alignment adjust property */ @@ -113,6 +111,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override public void initialize() { InlineLevel fobj = (InlineLevel) this.fobj; @@ -150,6 +149,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override protected MinOptMax getExtraIPD(boolean isNotFirst, boolean isNotLast) { int borderAndPadding = 0; if (borderProps != null) { @@ -167,6 +167,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { /** {@inheritDoc} */ + @Override protected boolean hasLeadingFence(boolean isNotFirst) { return borderProps != null && (borderProps.getPadding(CommonBorderPaddingBackground.START, isNotFirst, this) > 0 @@ -175,6 +176,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override protected boolean hasTrailingFence(boolean isNotLast) { return borderProps != null && (borderProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, this) > 0 @@ -183,10 +185,12 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override protected SpaceProperty getSpaceStart() { return inlineProps != null ? inlineProps.spaceStart : null; } /** {@inheritDoc} */ + @Override protected SpaceProperty getSpaceEnd() { return inlineProps != null ? inlineProps.spaceEnd : null; } @@ -212,6 +216,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override protected void setTraits(boolean isNotFirst, boolean isNotLast) { if (borderProps != null) { // Add border and padding to current area and set flags (FIRST, LAST ...) @@ -239,15 +244,16 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ - public List getNextKnuthElements // CSOK: MethodLength + @Override // CSOK: MethodLength + public List getNextKnuthElements (LayoutContext context, int alignment) { LayoutManager curLM; // the list returned by child LM - List returnedList; + List<KnuthSequence> returnedList; // the list which will be returned to the parent LM - List returnList = new LinkedList(); + List<KnuthSequence> returnList = new LinkedList<KnuthSequence>(); KnuthSequence lastSequence = null; if (fobj instanceof Title) { @@ -328,16 +334,16 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { sequence.wrapPositions(this); } int insertionStartIndex = 0; - if (lastSequence != null && lastSequence.appendSequenceOrClose - ((KnuthSequence) returnedList.get(0))) { + if (lastSequence != null + && lastSequence.appendSequenceOrClose(returnedList.get(0))) { insertionStartIndex = 1; } // add border and padding to the first complete sequence of this LM if (!borderAdded && !returnedList.isEmpty()) { - addKnuthElementsForBorderPaddingStart((KnuthSequence) returnedList.get(0)); + addKnuthElementsForBorderPaddingStart(returnedList.get(0)); borderAdded = true; } - for (Iterator iter = returnedList.listIterator(insertionStartIndex); + for (Iterator<KnuthSequence> iter = returnedList.listIterator(insertionStartIndex); iter.hasNext();) { returnList.add(iter.next()); } @@ -368,7 +374,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); childLC.clearKeepsPending(); } - lastSequence = (KnuthSequence) ListUtil.getLast(returnList); + lastSequence = ListUtil.getLast(returnList); lastChildLM = curLM; } @@ -408,6 +414,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { * by this LayoutManager. * @param context layout context. */ + @Override public void addAreas(PositionIterator parentIter, LayoutContext context) { @@ -433,21 +440,18 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { // set in the layout context, it must be also set in the // layout context given to lastLM, but must be cleared in the // layout context given to the other LMs. - List positionList = new LinkedList(); - NonLeafPosition pos; + List<Position> positionList = new LinkedList<Position>(); + Position pos; LayoutManager lastLM = null; // last child LM in this iterator Position lastPos = null; while (parentIter.hasNext()) { - pos = (NonLeafPosition) parentIter.next(); + pos = parentIter.next(); if (pos != null && pos.getPosition() != null) { positionList.add(pos.getPosition()); lastLM = pos.getPosition().getLM(); lastPos = pos; } } - /*if (pos != null) { - lastLM = pos.getPosition().getLM(); - }*/ addMarkersToPage( true, @@ -469,8 +473,8 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } setCurrentArea(parent); - StackingIter childPosIter - = new StackingIter(positionList.listIterator()); + PositionIterator childPosIter + = new PositionIterator(positionList.listIterator()); LayoutManager prevLM = null; LayoutManager childLM; @@ -522,6 +526,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override public void addChildArea(Area childArea) { Area parent = getCurrentArea(); if (getContext().resolveLeadingSpace()) { @@ -532,6 +537,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } /** {@inheritDoc} */ + @Override public List getChangedKnuthElements(List oldList, int alignment, int depth) { List returnedList = new LinkedList(); addKnuthElementsForBorderPaddingStart(returnedList); @@ -546,7 +552,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { */ protected void addKnuthElementsForBorderPaddingStart(List returnList) { //Border and Padding (start) - /** + /* * If the returnlist is a BlockKnuthSequence, the border and padding should be added * to the first paragraph inside it, but it is too late to do that now. * At least, avoid adding it to the bpd sequence. @@ -571,7 +577,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { */ protected void addKnuthElementsForBorderPaddingEnd(List returnList) { //Border and Padding (after) - /** + /* * If the returnlist is a BlockKnuthSequence, the border and padding should be added * to the last paragraph inside it, but it is too late to do that now. * At least, avoid adding it to the bpd sequence. @@ -590,13 +596,8 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } } - /** @return a cached auxiliary Position instance used for things like spaces. */ + /** @return an auxiliary {@link Position} instance used for things like spaces. */ protected Position getAuxiliaryPosition() { - //if (this.auxiliaryPosition == null) { - //this.auxiliaryPosition = new NonLeafPosition(this, new LeafPosition(this, -1)); - this.auxiliaryPosition = new NonLeafPosition(this, null); - //} - return this.auxiliaryPosition; + return new NonLeafPosition(this, null); } - } diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java index d8c4966d0..b15f0f8db 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java @@ -19,7 +19,6 @@ package org.apache.fop.layoutmgr.inline; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; @@ -31,10 +30,8 @@ import org.apache.fop.fo.properties.SpaceProperty; import org.apache.fop.layoutmgr.AbstractLayoutManager; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.LayoutContext; -import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; -import org.apache.fop.layoutmgr.PositionIterator; import org.apache.fop.traits.MinOptMax; /** @@ -45,33 +42,6 @@ import org.apache.fop.traits.MinOptMax; public abstract class InlineStackingLayoutManager extends AbstractLayoutManager implements InlineLevelLayoutManager { - - /** - * A stacking iterator. - */ - protected static class StackingIter extends PositionIterator { - - StackingIter(Iterator parentIter) { - super(parentIter); - } - - /** - * @param nextObj the next object - * @return layout manager of next object - */ - protected LayoutManager getLM(Object nextObj) { - return ((Position) nextObj).getLM(); - } - - /** - * @param nextObj the next object - * @return position of next object - */ - protected Position getPos(Object nextObj) { - return ((Position) nextObj); - } - } - /** * Size of border and padding in BPD (ie, before and after). */ @@ -296,6 +266,7 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager } else { currLM = (InlineLevelLayoutManager) pos.getLM(depth); } + // initialize prevLM if (prevLM == null) { prevLM = currLM; diff --git a/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java index f3749f2ed..5e3464da7 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java @@ -48,19 +48,14 @@ import org.apache.fop.traits.MinOptMax; * an exception to this rule.) * This class can be extended to handle the creation and adding of the * inline area. - * TODO [GA] replace use of hungarian notation with normalized java naming */ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager implements InlineLevelLayoutManager { - /** - * logging instance - */ + /** logging instance */ protected static final Log log = LogFactory.getLog(LeafNodeLayoutManager.class); - /** - * The inline area that this leafnode will add. - */ + /** The inline area that this leafnode will add. */ protected InlineArea curArea = null; /** Any border, padding and background properties applying to this area */ protected CommonBorderPaddingBackground commonBorderPaddingBackground = null; @@ -68,7 +63,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager protected AlignmentContext alignmentContext = null; /** Flag to indicate if something was changed as part of the getChangeKnuthElements sequence */ - protected boolean isSomethingChanged = false; + protected boolean somethingChanged = false; /** Our area info for the Knuth elements */ protected AreaInfo areaInfo = null; @@ -77,32 +72,31 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager */ protected class AreaInfo { /** letter space count */ - protected short iLScount; + protected short letterSpaces; /** ipd of area */ protected MinOptMax ipdArea; /** true if hyphenated */ - protected boolean bHyphenated; + protected boolean isHyphenated; /** alignment context */ protected AlignmentContext alignmentContext; /** * Construct an area information item. - * @param iLS letter space count + * @param letterSpaces letter space count * @param ipd inline progression dimension - * @param bHyph true if hyphenated + * @param isHyphenated true if hyphenated * @param alignmentContext an alignment context */ - public AreaInfo(short iLS, MinOptMax ipd, boolean bHyph, + public AreaInfo(short letterSpaces, MinOptMax ipd, boolean isHyphenated, AlignmentContext alignmentContext) { - iLScount = iLS; - ipdArea = ipd; - bHyphenated = bHyph; + this.letterSpaces = letterSpaces; + this.ipdArea = ipd; + this.isHyphenated = isHyphenated; this.alignmentContext = alignmentContext; } } - /** * Create a Leaf node layout manager. * @param node the FObj to attach to this LM. @@ -145,18 +139,22 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager } /** - * This is a leaf-node, so this method is never called. + * This is a leaf-node, so this method should never be called. * @param childArea the childArea to add */ + @Override public void addChildArea(Area childArea) { + assert false; } /** - * This is a leaf-node, so this method is never called. + * This is a leaf-node, so this method should never be called. * @param childArea the childArea to get the parent for * @return the parent area */ + @Override public Area getParentArea(Area childArea) { + assert false; return null; } @@ -185,6 +183,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager * @param posIter the position iterator * @param context the layout context for adding the area */ + @Override public void addAreas(PositionIterator posIter, LayoutContext context) { addId(); @@ -260,6 +259,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager } /** {@inheritDoc} */ + @Override public List getNextKnuthElements(LayoutContext context, int alignment) { curArea = get(context); @@ -336,6 +336,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager } /** {@inheritDoc} */ + @Override public List getChangedKnuthElements(List oldList, int alignment) { if (isFinished()) { return null; diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index 2611a8cd5..1decfeb14 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -875,7 +875,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager */ private List postProcessLineBreaks(int alignment, LayoutContext context) { - List returnList = new LinkedList(); + List<ListElement> returnList = new LinkedList<ListElement>(); int endIndex = -1; for (int p = 0; p < knuthParagraphs.size(); p++) { @@ -893,7 +893,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager KnuthSequence seq = (KnuthSequence) knuthParagraphs.get(p); if (!seq.isInlineSequence()) { - List targetList = new LinkedList(); + List<ListElement> targetList = new LinkedList<ListElement>(); ListIterator listIter = seq.listIterator(); while (listIter.hasNext()) { ListElement tempElement; @@ -933,10 +933,10 @@ public class LineLayoutManager extends InlineStackingLayoutManager endIndex = ((LineBreakPosition) llPoss.getChosenPosition(i)).getLeafPos(); // create a list of the FootnoteBodyLM handling footnotes // whose citations are in this line - List footnoteList = new LinkedList(); - ListIterator elementIterator = seq.listIterator(startIndex); + List<LayoutManager> footnoteList = new LinkedList<LayoutManager>(); + ListIterator<KnuthElement> elementIterator = seq.listIterator(startIndex); while (elementIterator.nextIndex() <= endIndex) { - KnuthElement element = (KnuthElement) elementIterator.next(); + KnuthElement element = elementIterator.next(); if (element instanceof KnuthInlineBox && ((KnuthInlineBox) element).isAnchor()) { footnoteList.add(((KnuthInlineBox) element).getFootnoteBodyLM()); @@ -949,15 +949,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager returnList.add(new KnuthBlockBox (lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter, footnoteList, lbp, false)); - /* // add stretch and shrink to the returnlist - if (!seq.isInlineSequence() - && lbp.availableStretch != 0 || lbp.availableShrink != 0) { - returnList.add(new KnuthPenalty(0, -KnuthElement.INFINITE, - false, new Position(this), false)); - returnList.add(new KnuthGlue(0, lbp.availableStretch, lbp.availableShrink, - new Position(this), false)); - } - */ } } } @@ -965,7 +956,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager return returnList; } - private void createElements(List list, LineLayoutPossibilities llPoss, + private void createElements(List<ListElement> list, LineLayoutPossibilities llPoss, Position elementPosition) { /* number of normal, inner lines */ int innerLines = 0; @@ -984,36 +975,27 @@ public class LineLayoutManager extends InlineStackingLayoutManager /* number of the last unbreakable lines */ int lastLines = fobj.getWidows(); /* sub-sequence used to separate the elements representing different lines */ - List breaker = new LinkedList(); + List<KnuthElement> breaker = new LinkedList<KnuthElement>(); /* comment out the next lines in order to test particular situations */ if (fobj.getOrphans() + fobj.getWidows() <= llPoss.getMinLineCount()) { - innerLines = llPoss.getMinLineCount() - - (fobj.getOrphans() + fobj.getWidows()); - optionalLines = llPoss.getMaxLineCount() - - llPoss.getOptLineCount(); - eliminableLines = llPoss.getOptLineCount() - - llPoss.getMinLineCount(); + innerLines = llPoss.getMinLineCount() - (fobj.getOrphans() + fobj.getWidows()); + optionalLines = llPoss.getMaxLineCount() - llPoss.getOptLineCount(); + eliminableLines = llPoss.getOptLineCount() - llPoss.getMinLineCount(); } else if (fobj.getOrphans() + fobj.getWidows() <= llPoss.getOptLineCount()) { - optionalLines = llPoss.getMaxLineCount() - - llPoss.getOptLineCount(); - eliminableLines = llPoss.getOptLineCount() - - (fobj.getOrphans() + fobj.getWidows()); - conditionalEliminableLines = (fobj.getOrphans() + fobj.getWidows()) - - llPoss.getMinLineCount(); + optionalLines = llPoss.getMaxLineCount() - llPoss.getOptLineCount(); + eliminableLines = llPoss.getOptLineCount() - (fobj.getOrphans() + fobj.getWidows()); + conditionalEliminableLines + = (fobj.getOrphans() + fobj.getWidows()) - llPoss.getMinLineCount(); } else if (fobj.getOrphans() + fobj.getWidows() <= llPoss.getMaxLineCount()) { - optionalLines = llPoss.getMaxLineCount() - - (fobj.getOrphans() + fobj.getWidows()); - conditionalOptionalLines = (fobj.getOrphans() + fobj.getWidows()) - - llPoss.getOptLineCount(); - conditionalEliminableLines = llPoss.getOptLineCount() - - llPoss.getMinLineCount(); + optionalLines = llPoss.getMaxLineCount() - (fobj.getOrphans() + fobj.getWidows()); + conditionalOptionalLines + = (fobj.getOrphans() + fobj.getWidows()) - llPoss.getOptLineCount(); + conditionalEliminableLines = llPoss.getOptLineCount() - llPoss.getMinLineCount(); firstLines -= conditionalOptionalLines; } else { - conditionalOptionalLines = llPoss.getMaxLineCount() - - llPoss.getOptLineCount(); - conditionalEliminableLines = llPoss.getOptLineCount() - - llPoss.getMinLineCount(); + conditionalOptionalLines = llPoss.getMaxLineCount() - llPoss.getOptLineCount(); + conditionalEliminableLines = llPoss.getOptLineCount() - llPoss.getMinLineCount(); firstLines = llPoss.getOptLineCount(); lastLines = 0; } @@ -1044,12 +1026,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager breaker.add(new KnuthPenalty(0, 0, false, elementPosition, false)); } - //log.debug("first=" + firstLines + " inner=" + innerLines - // + " optional=" + optionalLines + " eliminable=" + eliminableLines - // + " last=" + lastLines - // + " (condOpt=" + conditionalOptionalLines - // + " condEl=" + conditionalEliminableLines + ")"); - // creation of the elements: // first group of lines list.add(new KnuthBox(firstLines * constantLineHeight, elementPosition, @@ -1562,7 +1538,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager lc.setAlignmentContext(alignmentContext); setChildContext(lc); - PositionIterator childPosIter = new StackingIter(positionList.listIterator()); + PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); LayoutContext blocklc = new LayoutContext(0); blocklc.setLeadingSpace(new SpaceSpecifier(true)); blocklc.setTrailingSpace(new SpaceSpecifier(false)); diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index 8ab79d2c4..9ffe015d3 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -65,20 +65,6 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager private MinOptMax effSpaceBefore; private MinOptMax effSpaceAfter; - private static class StackingIter extends PositionIterator { - StackingIter(Iterator parentIter) { - super(parentIter); - } - - protected LayoutManager getLM(Object nextObj) { - return ((Position) nextObj).getLM(); - } - - protected Position getPos(Object nextObj) { - return ((Position) nextObj); - } - } - /** * Create a new list block layout manager. * @param node list-block to create the layout manager for @@ -96,6 +82,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public void initialize() { foSpaceBefore = new SpaceVal( getListBlockFO().getCommonMarginBlock().spaceBefore, this).getSpace(); @@ -115,6 +102,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public List getNextKnuthElements(LayoutContext context, int alignment) { resetSpaces(); List returnList = super.getNextKnuthElements(context, alignment); @@ -135,6 +123,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ + @Override public List getChangedKnuthElements(List oldList, int alignment) { //log.debug("LBLM.getChangedKnuthElements>"); return super.getChangedKnuthElements(oldList, alignment); @@ -147,6 +136,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager * @param parentIter the position iterator * @param layoutContext the layout context for adding areas */ + @Override public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { getParentArea(null); @@ -170,10 +160,10 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager // "unwrap" the NonLeafPositions stored in parentIter // and put them in a new list; - LinkedList positionList = new LinkedList(); + LinkedList<Position> positionList = new LinkedList<Position>(); Position pos; while (parentIter.hasNext()) { - pos = (Position)parentIter.next(); + pos = parentIter.next(); if (pos.getIndex() >= 0) { if (firstPos == null) { firstPos = pos; @@ -194,7 +184,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager addMarkersToPage(true, isFirst(firstPos), isLast(lastPos)); - StackingIter childPosIter = new StackingIter(positionList.listIterator()); + PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); while ((childLM = childPosIter.getNextChildLM()) != null) { // Add the block areas to Area // set the space adjustment ratio @@ -235,6 +225,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager * @param childArea the child area * @return the parent area of the child */ + @Override public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java index 246c57094..f2e3b7d95 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java @@ -19,7 +19,6 @@ package org.apache.fop.layoutmgr.list; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -49,20 +48,6 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { private int xoffset; private int itemIPD; - private static class StackingIter extends PositionIterator { - StackingIter(Iterator parentIter) { - super(parentIter); - } - - protected LayoutManager getLM(Object nextObj) { - return ((Position) nextObj).getLM(); - } - - protected Position getPos(Object nextObj) { - return ((Position) nextObj); - } - } - /** * Create a new Cell layout manager. * @param node list-item-label node @@ -99,6 +84,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { } /** {@inheritDoc} */ + @Override public List getChangedKnuthElements(List oldList, int alignment) { //log.debug(" ListItemContentLayoutManager.getChanged>"); return super.getChangedKnuthElements(oldList, alignment); @@ -112,6 +98,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { * @param parentIter the iterator of the break positions * @param layoutContext the layout context for adding the areas */ + @Override public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { getParentArea(null); @@ -127,10 +114,10 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { // "unwrap" the NonLeafPositions stored in parentIter // and put them in a new list; - LinkedList positionList = new LinkedList(); + LinkedList<Position> positionList = new LinkedList<Position>(); Position pos; while (parentIter.hasNext()) { - pos = (Position)parentIter.next(); + pos = parentIter.next(); if (pos == null) { continue; } @@ -156,7 +143,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { addMarkersToPage(true, isFirst(firstPos), isLast(lastPos)); - StackingIter childPosIter = new StackingIter(positionList.listIterator()); + PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); while ((childLM = childPosIter.getNextChildLM()) != null) { // Add the block areas to Area lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM); @@ -189,6 +176,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { * @param childArea the child area to get the parent for * @return the parent area */ + @Override public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); @@ -215,6 +203,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { * * @param childArea the child to add to the cell */ + @Override public void addChildArea(Area childArea) { if (curBlockArea != null) { curBlockArea.addBlock((Block) childArea); diff --git a/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java b/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java index 7511bc20d..4d473bb7c 100644 --- a/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java +++ b/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; import org.apache.commons.io.IOUtils; +import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil; /** * Represents an ICCBased color space in PDF. @@ -134,21 +135,19 @@ public class PDFICCBasedColorSpace extends PDFObject implements PDFColorSpace { public static PDFICCStream setupsRGBColorProfile(PDFDocument pdfDoc) { ICC_Profile profile; PDFICCStream sRGBProfile = pdfDoc.getFactory().makePDFICCStream(); - synchronized (PDFICCBasedColorSpace.class) { - InputStream in = PDFDocument.class.getResourceAsStream("sRGB Color Space Profile.icm"); - if (in != null) { - try { - profile = ICC_Profile.getInstance(in); - } catch (IOException ioe) { - throw new RuntimeException( - "Unexpected IOException loading the sRGB profile: " + ioe.getMessage()); - } finally { - IOUtils.closeQuietly(in); - } - } else { - // Fallback: Use the sRGB profile from the JRE (about 140KB) - profile = ICC_Profile.getInstance(ColorSpace.CS_sRGB); + InputStream in = PDFDocument.class.getResourceAsStream("sRGB Color Space Profile.icm"); + if (in != null) { + try { + profile = ColorProfileUtil.getICC_Profile(in); + } catch (IOException ioe) { + throw new RuntimeException( + "Unexpected IOException loading the sRGB profile: " + ioe.getMessage()); + } finally { + IOUtils.closeQuietly(in); } + } else { + // Fallback: Use the sRGB profile from the JRE (about 140KB) + profile = ColorProfileUtil.getICC_Profile(ColorSpace.CS_sRGB); } sRGBProfile.setColorSpace(profile, null); return sRGBProfile; diff --git a/src/java/org/apache/fop/pdf/PDFResources.java b/src/java/org/apache/fop/pdf/PDFResources.java index 46462bbd7..317f703e1 100644 --- a/src/java/org/apache/fop/pdf/PDFResources.java +++ b/src/java/org/apache/fop/pdf/PDFResources.java @@ -27,12 +27,12 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil; import org.apache.fop.fonts.FontDescriptor; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.Typeface; import org.apache.fop.fonts.base14.Symbol; import org.apache.fop.fonts.base14.ZapfDingbats; -import org.apache.fop.util.ColorProfileUtil; /** * Class representing a /Resources object. diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java index c37e0c37c..87651defd 100644 --- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java @@ -77,17 +77,17 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler private DataStream dataStream; /** the map of page segments */ - private Map/*<String,PageSegmentDescriptor>*/pageSegmentMap - = new java.util.HashMap/*<String,PageSegmentDescriptor>*/(); + private Map<String, PageSegmentDescriptor> pageSegmentMap + = new java.util.HashMap<String, PageSegmentDescriptor>(); /** Medium Map referenced on previous page **/ private String lastMediumMap; - private static final int LOC_ELSEWHERE = 0; - private static final int LOC_FOLLOWING_PAGE_SEQUENCE = 1; - private static final int LOC_IN_PAGE_HEADER = 2; + private static enum Location { + ELSEWHERE, IN_DOCUMENT_HEADER, FOLLOWING_PAGE_SEQUENCE, IN_PAGE_HEADER + } - private int location = LOC_ELSEWHERE; + private Location location = Location.ELSEWHERE; /** the shading mode for filled rectangles */ private AFPShadingMode shadingMode = AFPShadingMode.COLOR; @@ -117,6 +117,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void setDefaultFontInfo(FontInfo fontInfo) { FontManager fontManager = getUserAgent().getFactory().getFontManager(); FontCollection[] fontCollections = new FontCollection[] { @@ -152,6 +153,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void startDocument() throws IFException { super.startDocument(); try { @@ -165,11 +167,23 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } } + + /** {@inheritDoc} */ + @Override + public void startDocumentHeader() throws IFException { + super.startDocumentHeader(); + this.location = Location.IN_DOCUMENT_HEADER; + } + /** {@inheritDoc} */ + @Override public void endDocumentHeader() throws IFException { + super.endDocumentHeader(); + this.location = Location.ELSEWHERE; } /** {@inheritDoc} */ + @Override public void endDocument() throws IFException { try { this.dataStream.endDocument(); @@ -189,7 +203,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } catch (IOException ioe) { throw new IFException("I/O error in startPageSequence()", ioe); } - this.location = LOC_FOLLOWING_PAGE_SEQUENCE; + this.location = Location.FOLLOWING_PAGE_SEQUENCE; } /** {@inheritDoc} */ @@ -212,7 +226,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler /** {@inheritDoc} */ public void startPage(int index, String name, String pageMasterName, Dimension size) throws IFException { - this.location = LOC_ELSEWHERE; + this.location = Location.ELSEWHERE; paintingState.clear(); AffineTransform baseTransform = getBaseTransform(); @@ -232,14 +246,16 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void startPageHeader() throws IFException { super.startPageHeader(); - this.location = LOC_IN_PAGE_HEADER; + this.location = Location.IN_PAGE_HEADER; } /** {@inheritDoc} */ + @Override public void endPageHeader() throws IFException { - this.location = LOC_ELSEWHERE; + this.location = Location.ELSEWHERE; super.endPageHeader(); } @@ -272,17 +288,36 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler AFPPageSetup aps = (AFPPageSetup)extension; String element = aps.getElementName(); if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(element)) { - if (this.location != LOC_IN_PAGE_HEADER - && this.location != LOC_FOLLOWING_PAGE_SEQUENCE) { + switch (this.location) { + case FOLLOWING_PAGE_SEQUENCE: + case IN_PAGE_HEADER: + String name = aps.getName(); + String value = aps.getValue(); + dataStream.createTagLogicalElement(name, value); + break; + default: throw new IFException( "TLE extension must be in the page header or between page-sequence" + " and the first page: " + aps, null); } - String name = aps.getName(); - String value = aps.getValue(); - dataStream.createTagLogicalElement(name, value); + } else if (AFPElementMapping.NO_OPERATION.equals(element)) { + switch (this.location) { + case IN_DOCUMENT_HEADER: + case FOLLOWING_PAGE_SEQUENCE: + case IN_PAGE_HEADER: + String content = aps.getContent(); + if (content != null) { + dataStream.createNoOperation(content); + } + break; + default: + throw new IFException( + "NOP extension must be in the document header, the page header" + + " or between page-sequence" + + " and the first page: " + aps, null); + } } else { - if (this.location != LOC_IN_PAGE_HEADER) { + if (this.location != Location.IN_PAGE_HEADER) { throw new IFException( "AFP page setup extension encountered outside the page header: " + aps, null); @@ -294,16 +329,11 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler String source = apse.getValue(); String uri = apse.getResourceSrc(); pageSegmentMap.put(source, new PageSegmentDescriptor(name, uri)); - } else if (AFPElementMapping.NO_OPERATION.equals(element)) { - String content = aps.getContent(); - if (content != null) { - dataStream.createNoOperation(content); - } } } } else if (extension instanceof AFPPageOverlay) { AFPPageOverlay ipo = (AFPPageOverlay)extension; - if (this.location != LOC_IN_PAGE_HEADER) { + if (this.location != Location.IN_PAGE_HEADER) { throw new IFException( "AFP page overlay extension encountered outside the page header: " + ipo, null); @@ -313,8 +343,8 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler dataStream.createIncludePageOverlay(overlay, ipo.getX(), ipo.getY()); } } else if (extension instanceof AFPInvokeMediumMap) { - if (this.location != LOC_FOLLOWING_PAGE_SEQUENCE - && this.location != LOC_IN_PAGE_HEADER) { + if (this.location != Location.FOLLOWING_PAGE_SEQUENCE + && this.location != Location.IN_PAGE_HEADER) { throw new IFException( "AFP IMM extension must be between page-sequence" @@ -401,7 +431,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler * @return the page segment descriptor or null if there's no page segment for the given URI */ PageSegmentDescriptor getPageSegmentNameFor(String uri) { - return (PageSegmentDescriptor)pageSegmentMap.get(uri); + return pageSegmentMap.get(uri); } } diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java index ca0544542..c38af8fac 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java @@ -24,8 +24,10 @@ import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; +import java.awt.image.MultiPixelPackedSampleModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; +import java.awt.image.SampleModel; import java.io.IOException; import java.io.OutputStream; @@ -254,6 +256,12 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima if (tiles > 1) { return false; } + SampleModel sampleModel = renderedImage.getSampleModel(); + SampleModel expectedSampleModel = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, + renderedImage.getWidth(), renderedImage.getHeight(), 1); + if (!expectedSampleModel.equals(sampleModel)) { + return false; //Pixels are not packed + } imageObjectInfo.setBitsPerPixel(1); @@ -290,6 +298,7 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima } /** {@inheritDoc} */ + @Override protected AFPDataObjectInfo createDataObjectInfo() { return new AFPImageObjectInfo(); } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java index 19f98f32a..b5b05191a 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java @@ -54,6 +54,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { } /** {@inheritDoc} */ + @Override protected void startOfNode() throws FOPException { super.startOfNode(); if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(getLocalName())) { @@ -63,14 +64,17 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { "rule.childOfPageSequenceOrSPM"); } } else { - if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) { + if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER + && parent.getNameId() != Constants.FO_PAGE_SEQUENCE + && parent.getNameId() != Constants.FO_DECLARATIONS) { invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), - "rule.childOfSPM"); + "rule.childOfSPMorPSorDeclarations"); } } } /** {@inheritDoc} */ + @Override protected void characters(char[] data, int start, int length, PropertyList pList, Locator locator) throws FOPException { StringBuffer sb = new StringBuffer(); @@ -83,6 +87,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { } /** {@inheritDoc} */ + @Override public void processNode(String elementName, Locator locator, Attributes attlist, PropertyList propertyList) throws FOPException { @@ -106,6 +111,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { } /** {@inheritDoc} */ + @Override protected ExtensionAttachment instantiateExtensionAttachment() { return new AFPPageSetup(getLocalName()); } diff --git a/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java b/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java index ff0d5c9de..5af0fd179 100644 --- a/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java +++ b/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java @@ -88,6 +88,7 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void setContext(IFContext context) { super.setContext(context); this.pclUtil = new PCLRenderingUtil(context.getUserAgent()); @@ -99,6 +100,7 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void setDefaultFontInfo(FontInfo fontInfo) { FontInfo fi = Java2DUtil.buildDefaultJava2DBasedFontInfo(fontInfo, getUserAgent()); setFontInfo(fi); @@ -114,7 +116,7 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler /** @return the target resolution */ protected int getResolution() { - int resolution = (int)Math.round(getUserAgent().getTargetResolution()); + int resolution = Math.round(getUserAgent().getTargetResolution()); if (resolution <= 300) { return 300; } else { @@ -125,10 +127,12 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler //---------------------------------------------------------------------------------------------- /** {@inheritDoc} */ + @Override public void startDocument() throws IFException { super.startDocument(); try { this.gen = new PCLGenerator(this.outputStream, getResolution()); + this.gen.setDitheringQuality(pclUtil.getDitheringQuality()); if (!pclUtil.isPJLDisabled()) { gen.universalEndOfLanguage(); @@ -148,10 +152,12 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void endDocumentHeader() throws IFException { } /** {@inheritDoc} */ + @Override public void endDocument() throws IFException { try { gen.separateJobs(); diff --git a/src/java/org/apache/fop/render/pcl/PCLGenerator.java b/src/java/org/apache/fop/render/pcl/PCLGenerator.java index f89c03add..29fe77323 100644 --- a/src/java/org/apache/fop/render/pcl/PCLGenerator.java +++ b/src/java/org/apache/fop/render/pcl/PCLGenerator.java @@ -49,7 +49,6 @@ import org.apache.xmlgraphics.util.UnitConv; import org.apache.fop.util.bitmap.BitmapImageUtil; import org.apache.fop.util.bitmap.DitherUtil; -import org.apache.fop.util.bitmap.MonochromeBitmapConverter; /** * This class provides methods for generating PCL print files. @@ -76,6 +75,7 @@ public class PCLGenerator { private boolean currentPatternTransparency = true; private int maxBitmapResolution = PCL_RESOLUTIONS[PCL_RESOLUTIONS.length - 1]; + private float ditheringQuality = 0.5f; /** * true: Standard PCL shades are used (poor quality). false: user-defined pattern are used @@ -541,13 +541,31 @@ public class PCLGenerator { } /** + * Sets the dithering quality used when encoding gray or color images. If not explicitely + * set a medium setting (0.5f) is used. + * @param quality a quality setting between 0.0f (worst/fastest) and 1.0f (best/slowest) + */ + public void setDitheringQuality(float quality) { + quality = Math.min(Math.max(0f, quality), 1.0f); + this.ditheringQuality = quality; + } + + /** + * Returns the dithering quality used when encoding gray or color images. + * @return the quality setting between 0.0f (worst/fastest) and 1.0f (best/slowest) + */ + public float getDitheringQuality() { + return this.ditheringQuality; + } + + /** * Indicates whether an image is a monochrome (b/w) image. * @param img the image * @return true if it's a monochrome image */ public static boolean isMonochromeImage(RenderedImage img) { return BitmapImageUtil.isMonochromeImage(img); - } + } /** * Indicates whether an image is a grayscale image. @@ -618,18 +636,6 @@ public class PCLGenerator { return resolution == calculatePCLResolution(resolution); } - private Dimension getAdjustedDimension(Dimension orgDim, double orgResolution, - int pclResolution) { - if (orgResolution == pclResolution) { - return orgDim; - } else { - Dimension result = new Dimension(); - result.width = (int)Math.round((double)orgDim.width * pclResolution / orgResolution); - result.height = (int)Math.round((double)orgDim.height * pclResolution / orgResolution); - return result; - } - } - //Threshold table to convert an alpha channel (8-bit) into a clip mask (1-bit) private static final byte[] THRESHOLD_TABLE = new byte[256]; static { // Initialize the arrays @@ -724,34 +730,8 @@ public class PCLGenerator { popCursorPos(); } - BufferedImage src = null; - if (img instanceof BufferedImage && !scaled) { - if (!isGrayscaleImage(img) || img.getColorModel().hasAlpha()) { - /* Disabled as this doesn't work reliably, use the fallback below - src = new BufferedImage(effDim.width, effDim.height, - BufferedImage.TYPE_BYTE_GRAY); - Graphics2D g2d = src.createGraphics(); - try { - clearBackground(g2d, effDim); - } finally { - g2d.dispose(); - } - ColorConvertOp op = new ColorConvertOp( - ColorSpace.getInstance(ColorSpace.CS_GRAY), null); - op.filter((BufferedImage)img, src); - */ - } else { - src = (BufferedImage)img; - } - } - if (src == null) { - src = BitmapImageUtil.convertToGrayscale(img, effDim); - } - MonochromeBitmapConverter converter - = BitmapImageUtil.createDefaultMonochromeBitmapConverter(); - converter.setHint("quality", "false"); - - RenderedImage red = converter.convertToMonochrome(src); + RenderedImage red = BitmapImageUtil.convertToMonochrome( + img, effDim, this.ditheringQuality); selectCurrentPattern(0, 0); //Solid black setTransparencyMode(sourceTransparency || mask != null, true); paintMonochromeBitmap(red, effResolution); @@ -766,12 +746,6 @@ public class PCLGenerator { } } - private void clearBackground(Graphics2D g2d, Dimension effDim) { - //white background - g2d.setBackground(Color.WHITE); - g2d.clearRect(0, 0, effDim.width, effDim.height); - } - private int toGray(int rgb) { // see http://www.jguru.com/faq/view.jsp?EID=221919 double greyVal = 0.072169d * (rgb & 0xff); diff --git a/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java index f7bb33f68..25249caf6 100644 --- a/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java +++ b/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java @@ -85,6 +85,7 @@ public class PCLImageHandlerGraphics2D implements ImageHandler { boolean painted = false; ByteArrayOutputStream baout = new ByteArrayOutputStream(); PCLGenerator tempGen = new PCLGenerator(baout, gen.getMaximumBitmapResolution()); + tempGen.setDitheringQuality(gen.getDitheringQuality()); try { GraphicContext ctx = (GraphicContext)pclContext.getGraphicContext().clone(); diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java b/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java index 2fac1d13f..6201197cf 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java +++ b/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java @@ -30,23 +30,26 @@ public final class PCLRenderingMode implements Serializable { private static final long serialVersionUID = 6359884255324755026L; /** "Quality" rendering (mixed native and bitmap for improved quality) */ - public static final PCLRenderingMode QUALITY = new PCLRenderingMode("quality"); + public static final PCLRenderingMode QUALITY = new PCLRenderingMode("quality", 1.0f); /** "Speed" rendering (maximum speed with native rendering, reduced visual quality) */ - public static final PCLRenderingMode SPEED = new PCLRenderingMode("speed"); + public static final PCLRenderingMode SPEED = new PCLRenderingMode("speed", 0.25f); /** * "Bitmap" rendering (pages are painted entirely as bitmaps, maximum quality, * reduced performance) */ - public static final PCLRenderingMode BITMAP = new PCLRenderingMode("bitmap"); + public static final PCLRenderingMode BITMAP = new PCLRenderingMode("bitmap", 1.0f); private String name; + private float defaultDitheringQuality; /** * Constructor to add a new named item. * @param name Name of the item. + * @param defaultDitheringQuality the default dithering quality (0.0f..1.0f) */ - private PCLRenderingMode(String name) { + private PCLRenderingMode(String name, float defaultDitheringQuality) { this.name = name; + this.defaultDitheringQuality = defaultDitheringQuality; } /** @return the name of the enum */ @@ -55,6 +58,14 @@ public final class PCLRenderingMode implements Serializable { } /** + * Returns the default dithering quality for this rendering mode. + * @return the default dithering quality (0.0f..1.0f) + */ + public float getDefaultDitheringQuality() { + return this.defaultDitheringQuality; + } + + /** * Returns the enumeration/singleton object based on its name. * @param name the name of the enumeration value * @return the enumeration object @@ -76,6 +87,7 @@ public final class PCLRenderingMode implements Serializable { } /** {@inheritDoc} */ + @Override public String toString() { return "PCLRenderingMode:" + name; } diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java b/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java index a02a64717..e01bcdc5f 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java +++ b/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java @@ -47,6 +47,9 @@ public class PCLRenderingUtil { */ private PCLRenderingMode renderingMode = PCLRenderingMode.SPEED; + /** Controls the dithering quality when rendering gray or color images. */ + private float ditheringQuality = 0.5f; + /** * Controls whether all text should be painted as text. This is a fallback setting in case * the mixture of native and bitmapped text does not provide the necessary quality. @@ -88,6 +91,7 @@ public class PCLRenderingUtil { */ public void setRenderingMode(PCLRenderingMode mode) { this.renderingMode = mode; + this.ditheringQuality = mode.getDefaultDitheringQuality(); } /** @@ -99,6 +103,14 @@ public class PCLRenderingUtil { } /** + * Returns the dithering quality to be used when encoding gray or color images. + * @return the quality (0.0f..1.0f) + */ + public float getDitheringQuality() { + return this.ditheringQuality; + } + + /** * Controls whether PJL commands shall be generated by the PCL renderer. * @param disable true to disable PJL commands */ diff --git a/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java b/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java index d3cc554c8..d076e6ab9 100644 --- a/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java +++ b/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java @@ -25,6 +25,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.Image; +import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil; import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.PDFConformanceException; @@ -36,7 +37,6 @@ import org.apache.fop.pdf.PDFICCStream; import org.apache.fop.pdf.PDFImage; import org.apache.fop.pdf.PDFName; import org.apache.fop.pdf.PDFReference; -import org.apache.fop.util.ColorProfileUtil; /** * Abstract PDFImage implementation for the PDF renderer. diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java b/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java index ae205a1e5..e63059472 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java @@ -35,6 +35,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.util.ImageUtil; +import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil; import org.apache.xmlgraphics.xmp.Metadata; import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; @@ -64,7 +65,6 @@ import org.apache.fop.pdf.PDFReference; import org.apache.fop.pdf.PDFText; import org.apache.fop.pdf.PDFXMode; import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileExtensionAttachment; -import org.apache.fop.util.ColorProfileUtil; /** * Utility class which enables all sorts of features that are not directly connected to the @@ -294,7 +294,7 @@ class PDFRenderingUtil implements PDFConfigurationConstants { in = new URL(src.getSystemId()).openStream(); } try { - profile = ICC_Profile.getInstance(in); + profile = ColorProfileUtil.getICC_Profile(in); } finally { IOUtils.closeQuietly(in); } diff --git a/src/java/org/apache/fop/util/ColorProfileUtil.java b/src/java/org/apache/fop/util/ColorProfileUtil.java index 35b6660dc..9ee34d2b6 100644 --- a/src/java/org/apache/fop/util/ColorProfileUtil.java +++ b/src/java/org/apache/fop/util/ColorProfileUtil.java @@ -19,13 +19,11 @@ package org.apache.fop.util; -import java.awt.color.ColorSpace; -import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_Profile; -import java.io.UnsupportedEncodingException; /** * Helper methods for handling color profiles. + * @deprecated use org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil directly */ public final class ColorProfileUtil { @@ -36,21 +34,11 @@ public final class ColorProfileUtil { * Returns the profile description of an ICC profile * @param profile the profile * @return the description + * @deprecated use org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil directly */ public static String getICCProfileDescription(ICC_Profile profile) { - byte[] data = profile.getData(ICC_Profile.icSigProfileDescriptionTag); - if (data == null) { - return null; - } else { - //Info on the data format: http://www.color.org/ICC-1_1998-09.PDF - int length = (data[8] << 3 * 8) | (data[9] << 2 * 8) | (data[10] << 8) | data[11]; - length--; //Remove trailing NUL character - try { - return new String(data, 12, length, "US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new UnsupportedOperationException("Incompatible VM"); - } - } + return org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil + .getICCProfileDescription(profile); } /** @@ -58,14 +46,10 @@ public final class ColorProfileUtil { * provided by the Java class library. * @param profile the color profile to check * @return true if it is the default sRGB profile + * @deprecated use org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil directly */ public static boolean isDefaultsRGB(ICC_Profile profile) { - ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); - ICC_Profile sRGBProfile = null; - if (sRGB instanceof ICC_ColorSpace) { - sRGBProfile = ((ICC_ColorSpace)sRGB).getProfile(); - } - return profile == sRGBProfile; + return org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil + .isDefaultsRGB(profile); } - } diff --git a/src/java/org/apache/fop/util/ColorSpaceCache.java b/src/java/org/apache/fop/util/ColorSpaceCache.java index 645245003..63db937a0 100644 --- a/src/java/org/apache/fop/util/ColorSpaceCache.java +++ b/src/java/org/apache/fop/util/ColorSpaceCache.java @@ -30,6 +30,7 @@ import javax.xml.transform.stream.StreamSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil; import org.apache.xmlgraphics.java2d.color.ICCColorSpaceWithIntent; import org.apache.xmlgraphics.java2d.color.RenderingIntent; @@ -81,7 +82,7 @@ public class ColorSpaceCache { if (src != null && src instanceof StreamSource) { // FOP URI resolver found ICC profile - create ICC profile // from the Source - iccProfile = ICC_Profile.getInstance(((StreamSource) src) + iccProfile = ColorProfileUtil.getICC_Profile(((StreamSource) src) .getInputStream()); } else { // TODO - Would it make sense to fall back on VM ICC diff --git a/src/java/org/apache/fop/util/ListUtil.java b/src/java/org/apache/fop/util/ListUtil.java index d97457510..8e88e4cbf 100644 --- a/src/java/org/apache/fop/util/ListUtil.java +++ b/src/java/org/apache/fop/util/ListUtil.java @@ -34,22 +34,22 @@ public final class ListUtil { /** * Retrieve the last element from a list. * - * @param list - * The list to work on + * @param <T> the type of objects stored in the list + * @param list the list to work on * @return last element */ - public static Object getLast(List list) { + public static <T> T getLast(List<T> list) { return list.get(list.size() - 1); } /** * Retrieve and remove the last element from a list. * - * @param list - * The list to work on + * @param <T> the type of objects stored in the list + * @param list the list to work on * @return previous last element */ - public static Object removeLast(List list) { + public static <T> T removeLast(List<T> list) { return list.remove(list.size() - 1); } } diff --git a/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java b/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java index b2706c5c2..4bfc74a39 100644 --- a/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java +++ b/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java @@ -213,7 +213,9 @@ public final class BitmapImageUtil { WritableRaster wr = img.getColorModel().createCompatibleWritableRaster( img.getWidth(), img.getHeight()); boolean premult = img.getColorModel().isAlphaPremultiplied(); - return new BufferedImage(img.getColorModel(), wr, premult, null); + BufferedImage buf = new BufferedImage(img.getColorModel(), wr, premult, null); + transferImage(img, buf); + return buf; } } |