You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by vh...@apache.org on 2013/08/29 18:26:13 UTC
svn commit: r1518691 - in
/xmlgraphics/fop/branches/Temp_WhitespaceManagement:
src/java/org/apache/fop/fo/ src/java/org/apache/fop/fo/extensions/
src/java/org/apache/fop/layoutmgr/ test/java/org/apache/fop/
Author: vhennebert
Date: Thu Aug 29 16:26:12 2013
New Revision: 1518691
URL: http://svn.apache.org/r1518691
Log:
FOP-2292: First bits of a whitespace management extension
Patch by Seifeddine Dridi, applied with some modifications (mainly, Java compliance and Checkstyle)
Added:
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/AlternativeBlock.java (with props)
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/BestFit.java (with props)
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeBlockLayoutManager.java (with props)
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeManager.java (with props)
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitLayoutManager.java (with props)
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java (with props)
Modified:
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/Constants.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOPropertyMapping.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/ElementListUtils.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutContext.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
xmlgraphics/fop/branches/Temp_WhitespaceManagement/test/java/org/apache/fop/KnuthAlgorithmTestCase.java
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/Constants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/Constants.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/Constants.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/Constants.java Thu Aug 29 16:26:12 2013
@@ -815,9 +815,12 @@ public interface Constants {
/** Scope for table header */
int PR_X_HEADER_COLUMN = 290;
+
+ /** Property constant - FOP proprietary*/
+ int PR_X_FITTING_STRATEGY = 291;
/** Number of property constants defined */
- int PROPERTY_COUNT = 290;
+ int PROPERTY_COUNT = 291;
// compound property constants
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOPropertyMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOPropertyMapping.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOPropertyMapping.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOPropertyMapping.java Thu Aug 29 16:26:12 2013
@@ -2613,7 +2613,12 @@ public final class FOPropertyMapping imp
m.setInherited(false);
m.setDefault("");
addPropertyMaker("fox:alt-text", m);
-
+
+ //fox:fitting-strategy, used only in fox:best-fit
+ m = new StringProperty.Maker(PR_X_FITTING_STRATEGY);
+ m.setInherited(false);
+ m.setDefault("first-fit");
+ addPropertyMaker("fox:fitting-strategy", m);
// fox:border-*-radius-*
m = new CondLengthProperty.Maker(PR_X_BORDER_BEFORE_RADIUS_START);
Added: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/AlternativeBlock.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/AlternativeBlock.java?rev=1518691&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/AlternativeBlock.java (added)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/AlternativeBlock.java Thu Aug 29 16:26:12 2013
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.extensions;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.ValidationException;
+
+/**
+ * A class modeling fox:alternative-block
+ */
+
+public class AlternativeBlock extends FObj {
+
+ public static final String OBJECT_NAME = "alternative-block";
+
+ public AlternativeBlock(FONode parent) {
+ super(parent);
+ }
+
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList pList) throws FOPException {
+ if (log.isDebugEnabled()) {
+ log.debug("org.apache.fop.fo.extensions.AlternativeBlock: " + elementName
+ + (locator != null ? " at " + getLocatorString(locator) : ""));
+ }
+ }
+
+ public void startOfNode() throws FOPException {
+ if (log.isDebugEnabled())
+ log.debug("AlternativeBlock.startOfNode()");
+ }
+
+ public void endOfNode() throws FOPException {
+ if (log.isDebugEnabled())
+ log.debug("AlternativeBlock.endOfNode()");
+ }
+
+ /**
+ * Content model: see {@link Block}
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws ValidationException {
+ if (FOX_URI.equals(nsURI)) {
+ if ("best-fit".equals(localName) || "alternative-block".equals(localName)) {
+ invalidChildError(loc, FOX_URI, localName);
+ }
+ }
+ else if (FO_URI.equals(nsURI)) {
+ if (!isBlockOrInlineItem(nsURI, localName)) {
+ invalidChildError(loc, FO_URI, localName);
+ }
+ }
+ }
+
+ @Override
+ public String getLocalName() {
+ return OBJECT_NAME;
+ }
+
+ @Override
+ public String getNormalNamespacePrefix() {
+ return ExtensionElementMapping.STANDARD_PREFIX;
+ }
+
+ public String getNamespaceURI() {
+ return ExtensionElementMapping.URI;
+ }
+
+}
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/AlternativeBlock.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/AlternativeBlock.java
------------------------------------------------------------------------------
svn:keywords = Revision Id
Added: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/BestFit.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/BestFit.java?rev=1518691&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/BestFit.java (added)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/BestFit.java Thu Aug 29 16:26:12 2013
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.extensions;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.ValidationException;
+import org.apache.fop.layoutmgr.AlternativeManager.FittingStrategy;
+
+/**
+ * A class that holds a set of <fox:alternative-block> blocks where each one is examined,
+ * and the one that best matches the fitting strategy is selected.
+ * The selected alternative should have an occupied BPD that is less than
+ * the remaining BPD of the current page.
+ */
+public class BestFit extends FObj {
+
+ public static final String OBJECT_NAME = "best-fit";
+ private FittingStrategy strategy = FittingStrategy.FIRST_FIT;
+
+ public BestFit(FONode parent) {
+ super(parent);
+
+ }
+
+ /** {@inheritDoc} */
+ public void bind(PropertyList pList) throws FOPException {
+ super.bind(pList);
+ String strategyName = pList.get(PR_X_FITTING_STRATEGY).getString();
+ if (strategyName.equals("first-fit"))
+ strategy = FittingStrategy.FIRST_FIT;
+ else if (strategyName.equals("smallest-fit"))
+ strategy = FittingStrategy.SMALLEST_FIT;
+ else if (strategyName.equals("biggest-fit"))
+ strategy = FittingStrategy.BIGGEST_FIT;
+ else {
+ log.warn("Unrecognized strategy name => " + strategyName + ". Using default strategy (first-fit");
+ strategy = FittingStrategy.FIRST_FIT;
+ }
+
+ }
+
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList pList) throws FOPException {
+ if (log.isDebugEnabled()) {
+ log.debug("org.apache.fop.fo.extensions.BestFit: " + elementName
+ + (locator != null ? " at " + getLocatorString(locator) : ""));
+ }
+ pList.addAttributesToList(attlist);
+ bind(pList);
+ }
+
+ public void startOfNode() throws FOPException {
+ if (log.isDebugEnabled())
+ log.debug("BestFit.startOfNode()");
+ }
+
+ public void endOfNode() throws FOPException {
+ if (log.isDebugEnabled())
+ log.debug("BestFit.endOfNode()");
+ }
+
+ /**
+ * {@inheritDoc}
+ * Content model: (fox:alternative-block)+
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws ValidationException {
+ if (FO_URI.equals(nsURI)) {
+ if (!"alternative-block".equals(localName)) {
+ invalidChildError(loc, FO_URI, localName);
+ }
+ }
+ }
+
+ @Override
+ public String getLocalName() {
+ return OBJECT_NAME;
+ }
+
+ @Override
+ public String getNormalNamespacePrefix() {
+ return ExtensionElementMapping.STANDARD_PREFIX;
+ }
+
+ public String getNamespaceURI() {
+ return ExtensionElementMapping.URI;
+ }
+
+ public FittingStrategy getStrategy() {
+ return strategy;
+ }
+
+}
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/BestFit.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/BestFit.java
------------------------------------------------------------------------------
svn:keywords = Revision Id
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java Thu Aug 29 16:26:12 2013
@@ -49,6 +49,7 @@ public class ExtensionElementMapping ext
PROPERTY_ATTRIBUTES.add("orphan-content-limit");
PROPERTY_ATTRIBUTES.add("internal-destination");
PROPERTY_ATTRIBUTES.add("disable-column-balancing");
+ PROPERTY_ATTRIBUTES.add("fitting-strategy");
//These are FOP's extension properties for accessibility
PROPERTY_ATTRIBUTES.add("alt-text");
PROPERTY_ATTRIBUTES.add("header");
@@ -85,6 +86,8 @@ public class ExtensionElementMapping ext
foObjs.put("label", new UnknownXMLObj.Maker(URI));
foObjs.put("destination", new DestinationMaker());
foObjs.put("external-document", new ExternalDocumentMaker());
+ foObjs.put("best-fit", new BestFitMaker());
+ foObjs.put("alternative-block", new AlternativeBlockMaker());
}
}
@@ -99,6 +102,18 @@ public class ExtensionElementMapping ext
return new ExternalDocument(parent);
}
}
+
+ static class BestFitMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new BestFit(parent);
+ }
+ }
+
+ static class AlternativeBlockMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new AlternativeBlock(parent);
+ }
+ }
/** {@inheritDoc} */
public String getStandardPrefix() {
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java Thu Aug 29 16:26:12 2013
@@ -611,7 +611,7 @@ public abstract class AbstractBreaker {
// Handle SpaceHandling(Break)Positions, see SpaceResolver!
SpaceResolver.performConditionalsNotification(effectiveList,
startElementIndex, notificationEndElementIndex, lastBreak);
-
+ childLC.setAlternativeManager(alg.getAlternativeManager());
// Add areas now!
addAreas(new KnuthPossPosIter(effectiveList,
startElementIndex, endElementIndex + 1), childLC);
Added: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeBlockLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeBlockLayoutManager.java?rev=1518691&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeBlockLayoutManager.java (added)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeBlockLayoutManager.java Thu Aug 29 16:26:12 2013
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutmgr;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Stack;
+
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.LineArea;
+import org.apache.fop.fo.extensions.AlternativeBlock;
+
+/**
+ * Layout manager for {@link AlternativeBlock}
+ */
+
+public class AlternativeBlockLayoutManager extends AbstractLayoutManager {
+
+ private Block curBlockArea;
+
+ public AlternativeBlockLayoutManager(AlternativeBlock node) {
+ super(node);
+ setGeneratesBlockArea(true);
+ }
+
+ /**
+ * 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 = LayoutContext.newInstance();
+ childLC.copyPendingMarksFrom(context);
+ childLC.setStackLimitBP(context.getStackLimitBP());
+ childLC.setRefIPD(context.getRefIPD());
+ childLC.setWritingMode(context.getWritingMode());
+ return childLC;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List getNextKnuthElements(LayoutContext context, int alignment) {
+ return getNextKnuthElements(context, alignment, null, null, null);
+ }
+
+ /** {@inheritDoc} */
+ public List getNextKnuthElements(LayoutContext context, int alignment,
+ Stack lmStack, Position positionAtIPDChange,
+ LayoutManager restartAtLM) {
+ LayoutManager curLM;
+ List<ListElement> returnList = new LinkedList<ListElement>();
+ while ((curLM = getChildLM()) != null) {
+ LayoutContext childLC = makeChildLayoutContext(context);
+
+ List returnedList = null;
+ if (!curLM.isFinished()) {
+ returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ }
+ if (returnedList != null) {
+ wrapPositionElements(returnedList, returnList);
+ }
+ }
+ setFinished(true);
+ return returnList;
+ }
+
+ /**
+ * "wrap" the Position inside each element moving the elements from SourceList to targetList
+ *
+ * @param sourceList source list
+ * @param targetList target list receiving the wrapped position elements
+ */
+ protected void wrapPositionElements(List sourceList, List targetList) {
+ wrapPositionElements(sourceList, targetList, false);
+ }
+
+ /**
+ * "wrap" the Position inside each element moving the elements from
+ * SourceList to targetList
+ *
+ * @param sourceList source list
+ * @param targetList target list receiving the wrapped position elements
+ * @param force if true, every Position is wrapped regardless of its LM of origin
+ */
+ protected void wrapPositionElements(List sourceList, List targetList,
+ boolean force) {
+
+ ListIterator listIter = sourceList.listIterator();
+ Object tempElement;
+ while (listIter.hasNext()) {
+ tempElement = listIter.next();
+ if (tempElement instanceof ListElement) {
+ wrapPositionElement((ListElement) tempElement, targetList,
+ force);
+ } else if (tempElement instanceof List) {
+ wrapPositionElements((List) tempElement, targetList, force);
+ }
+ }
+ }
+
+ /**
+ * "wrap" the Position inside the given element and add it to the target list.
+ *
+ * @param el the list element
+ * @param targetList target list receiving the wrapped position elements
+ * @param force if true, every Position is wrapped regardless of its LM of origin
+ */
+ protected void wrapPositionElement(ListElement el, List targetList,
+ boolean force) {
+ if (force || el.getLayoutManager() != this) {
+ el.setPosition(notifyPos(new NonLeafPosition(this, el.getPosition())));
+ }
+ targetList.add(el);
+ }
+
+ @Override
+ public Area getParentArea(Area childArea) {
+ if (curBlockArea == null) {
+ curBlockArea = new Block();
+ // Set up dimensions
+ // Must get dimensions from parent area
+ /*Area parentArea = */parentLayoutManager.getParentArea(curBlockArea);
+ }
+ return curBlockArea;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void addChildArea(Area childArea) {
+ if (curBlockArea != null) {
+ if (childArea instanceof LineArea) {
+ curBlockArea.addLineArea((LineArea) childArea);
+ } else {
+ curBlockArea.addBlock((Block) childArea);
+ }
+ }
+ }
+
+ /**
+ * Force current area to be added to parent area.
+ */
+ protected void flush() {
+ if (getCurrentArea() != null) {
+ parentLayoutManager.addChildArea(getCurrentArea());
+ }
+ }
+
+ private Area getCurrentArea() {
+ return curBlockArea;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void addAreas(PositionIterator parentIter,
+ LayoutContext layoutContext) {
+
+ getParentArea(null);
+
+ addId();
+
+ LayoutManager childLM;
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
+ LayoutManager firstLM = null;
+ LayoutManager lastLM = null;
+ Position firstPos = null;
+ Position lastPos = null;
+
+ // "unwrap" the NonLeafPositions stored in parentIter
+ // and put them in a new list;
+ LinkedList<Position> positionList = new LinkedList<Position>();
+ Position pos;
+ while (parentIter.hasNext()) {
+ pos = parentIter.next();
+ if (pos.getIndex() >= 0) {
+ if (firstPos == null) {
+ firstPos = pos;
+ }
+ lastPos = pos;
+ }
+ if (pos instanceof NonLeafPosition && (pos.getPosition() != null)
+ && pos.getPosition().getLM() != this) {
+ // pos was created by a child of this BestFitBlockLM
+ positionList.add(pos.getPosition());
+ lastLM = pos.getPosition().getLM();
+ if (firstLM == null) {
+ firstLM = lastLM;
+ }
+ }
+ }
+
+ registerMarkers(true, isFirst(firstPos), isLast(lastPos));
+
+ PositionIterator childPosIter = new PositionIterator(
+ positionList.listIterator());
+ while ((childLM = childPosIter.getNextChildLM()) != null) {
+ // Add the block areas to Area
+ // set the space adjustment ratio
+ lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
+ lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM);
+ lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM);
+ lc.setStackLimitBP(layoutContext.getStackLimitBP());
+ childLM.addAreas(childPosIter, lc);
+ }
+
+ registerMarkers(false, isFirst(firstPos), isLast(lastPos));
+
+ flush();
+
+ curBlockArea = null;
+
+ checkEndOfLayout(lastPos);
+ }
+
+ /** {@inheritDoc} */
+ public boolean isRestartable() {
+ return true;
+ }
+
+}
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeBlockLayoutManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeBlockLayoutManager.java
------------------------------------------------------------------------------
svn:keywords = Revision Id
Added: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeManager.java?rev=1518691&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeManager.java (added)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeManager.java Thu Aug 29 16:26:12 2013
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutmgr;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A simple alternative manager that holds a set of {@link Alternative}
+ */
+public class AlternativeManager {
+
+ public static class Alternative {
+
+ /** remaining BPD after inserting the alternative */
+ private int remainingBPD;
+ /** width of the alternative in block-progressing-dimension */
+ private int width;
+ /** Knuth element list */
+ private List<ListElement> knuthList;
+
+ public Alternative(List<ListElement> knuthList, int width) {
+ this.knuthList = knuthList;
+ this.width = width;
+ this.remainingBPD = 0;
+ }
+ public List<ListElement> getKnuthList() {
+ return knuthList;
+ }
+ public int getRemainingBPD() {
+ return remainingBPD;
+ }
+ public int getWidth() {
+ return width;
+ }
+ public void setRemainingBPD(int remainingBPD) {
+ this.remainingBPD = remainingBPD;
+ }
+ }
+
+ public static enum FittingStrategy {
+
+ FIRST_FIT {
+
+ @Override
+ public Alternative filter(List<Alternative> alternatives) {
+ for (Alternative alt : alternatives) {
+ if (alt.getRemainingBPD() > 0) {
+ return alt;
+ }
+ }
+ return null;
+ }
+ },
+
+ SMALLEST_FIT {
+
+ @Override
+ public Alternative filter(List<Alternative> alternatives) {
+ Iterator<Alternative> iter = alternatives.iterator();
+ int biggestDiff = -Integer.MAX_VALUE;
+ Alternative bestAlt = null;
+
+ while (iter.hasNext()) {
+ Alternative alt = iter.next();
+ if (alt.getRemainingBPD() > biggestDiff) {
+ biggestDiff = alt.getRemainingBPD();
+ bestAlt = alt;
+ }
+ }
+ return bestAlt;
+ }
+ },
+
+ BIGGEST_FIT {
+
+ @Override
+ public Alternative filter(List<Alternative> alternatives) {
+ Iterator<Alternative> iter = alternatives.iterator();
+ int smallestDiff = Integer.MAX_VALUE;
+ Alternative bestAlt = null;
+
+ while (iter.hasNext()) {
+ Alternative alt = iter.next();
+ if (alt.getRemainingBPD() < smallestDiff) {
+ smallestDiff = alt.getRemainingBPD();
+ bestAlt = alt;
+ }
+ }
+ return bestAlt;
+ }
+ };
+
+ public abstract Alternative filter(List<Alternative> alternatives);
+
+ }
+
+ private LinkedList<Alternative> alternatives;
+ private LinkedList<Alternative> bestAlternatives;
+
+ public AlternativeManager() {
+ alternatives = new LinkedList<Alternative>();
+ bestAlternatives = new LinkedList<Alternative>();
+ }
+
+ public void addAlternative(Alternative alt) {
+ alternatives.add(alt);
+ }
+
+ public boolean hasAny() {
+ return bestAlternatives.size() > 0;
+ }
+
+ public Alternative getNextBestAlternative() {
+ return bestAlternatives.removeFirst();
+ }
+
+ public Alternative getBestAlternative(FittingStrategy strategy) {
+ try {
+ Alternative bestAlt = strategy.filter(alternatives);
+ if (bestAlt != null) {
+ bestAlternatives.add(bestAlt);
+ }
+ return bestAlt;
+ } catch (NullPointerException e) {
+ return null;
+ } finally {
+ // We don't need the store alternatives anymore
+ alternatives.clear();
+ }
+ }
+}
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/AlternativeManager.java
------------------------------------------------------------------------------
svn:keywords = Revision Id
Added: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitLayoutManager.java?rev=1518691&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitLayoutManager.java (added)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitLayoutManager.java Thu Aug 29 16:26:12 2013
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutmgr;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Stack;
+
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.LineArea;
+import org.apache.fop.fo.extensions.BestFit;
+import org.apache.fop.layoutmgr.AlternativeManager.Alternative;
+import org.apache.fop.layoutmgr.AlternativeManager.FittingStrategy;
+
+/**
+ * LayoutManager for a fox:best-fit. It selects the "best" alternative
+ * to render based on the chosen fitting strategy.
+ */
+public class BestFitLayoutManager extends AbstractLayoutManager {
+
+ private Block curBlockArea;
+
+ private static class BestFitPosition extends Position {
+
+ public BestFitPosition(LayoutManager lm) {
+ super(lm);
+ }
+
+ }
+
+ private FittingStrategy fittingStrategy;
+
+ public BestFitLayoutManager(BestFit node) {
+ super(node);
+ fittingStrategy = node.getStrategy();
+ setGeneratesBlockArea(true);
+ }
+
+ /**
+ * 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 = LayoutContext.newInstance();
+ childLC.copyPendingMarksFrom(context);
+ childLC.setStackLimitBP(context.getStackLimitBP());
+ childLC.setRefIPD(context.getRefIPD());
+ childLC.setWritingMode(context.getWritingMode());
+ return childLC;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List getNextKnuthElements(LayoutContext context, int alignment) {
+ return getNextKnuthElements(context, alignment, null, null, null);
+ }
+
+ /** {@inheritDoc} */
+ public List getNextKnuthElements(LayoutContext context, int alignment,
+ Stack lmStack, Position positionAtIPDChange,
+ LayoutManager restartAtLM) {
+ LayoutManager curLM; // currently active LM
+ BestFitPenalty bestFitPenalty =
+ new BestFitPenalty(fittingStrategy, new BestFitPosition(this));
+ while ((curLM = getChildLM()) != null) {
+ LayoutContext childLC = makeChildLayoutContext(context);
+
+ List returnedList = null;
+ if (!curLM.isFinished()) {
+ returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ }
+ if (returnedList != null) {
+ List<ListElement> returnList = new LinkedList<ListElement>();
+ this.wrapPositionElements(returnedList, returnList);
+ int contentLength = ElementListUtils.calcFullContentLength(returnList);
+ // Add a new variant
+ bestFitPenalty.addAlternative(new Alternative(returnList, contentLength));
+ }
+ }
+ setFinished(true);
+ List<ListElement> finalList = new LinkedList<ListElement>();
+ // Insert an empty Knuth box to prevent the layout engine from ignoring our penalty
+ finalList.add(new KnuthBox(0, new Position(this), false));
+ finalList.add(bestFitPenalty);
+ return finalList;
+ }
+
+ /**
+ * "wrap" the Position inside each element moving the elements from
+ * SourceList to targetList
+ *
+ * @param sourceList source list
+ * @param targetList target list receiving the wrapped position elements
+ */
+ protected void wrapPositionElements(List sourceList, List targetList) {
+ wrapPositionElements(sourceList, targetList, false);
+ }
+
+ /**
+ * "wrap" the Position inside each element moving the elements from
+ * SourceList to targetList
+ *
+ * @param sourceList source list
+ * @param targetList target list receiving the wrapped position elements
+ * @param force if true, every Position is wrapped regardless of its LM of origin
+ */
+ protected void wrapPositionElements(List sourceList, List targetList,
+ boolean force) {
+
+ ListIterator listIter = sourceList.listIterator();
+ Object tempElement;
+ while (listIter.hasNext()) {
+ tempElement = listIter.next();
+ if (tempElement instanceof ListElement) {
+ wrapPositionElement((ListElement) tempElement, targetList,
+ force);
+ } else if (tempElement instanceof List) {
+ wrapPositionElements((List) tempElement, targetList, force);
+ }
+ }
+ }
+
+ /**
+ * "wrap" the Position inside the given element and add it to the target list.
+ *
+ * @param el the list element
+ * @param targetList target list receiving the wrapped position elements
+ * @param force if true, every Position is wrapped regardless of its LM of origin
+ */
+ protected void wrapPositionElement(ListElement el, List targetList,
+ boolean force) {
+ if (force || el.getLayoutManager() != this) {
+ el.setPosition(notifyPos(new NonLeafPosition(this, el.getPosition())));
+ }
+ targetList.add(el);
+ }
+
+ @Override
+ public Area getParentArea(Area childArea) {
+ if (curBlockArea == null) {
+ curBlockArea = new Block();
+ // Set up dimensions
+ // Must get dimensions from parent area
+ /*Area parentArea = */parentLayoutManager.getParentArea(curBlockArea);
+ }
+ return curBlockArea;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void addChildArea(Area childArea) {
+ if (curBlockArea != null) {
+ if (childArea instanceof LineArea) {
+ curBlockArea.addLineArea((LineArea) childArea);
+ } else {
+ curBlockArea.addBlock((Block) childArea);
+ }
+ }
+ }
+
+ /**
+ * Force current area to be added to parent area.
+ */
+ protected void flush() {
+ if (getCurrentArea() != null) {
+ parentLayoutManager.addChildArea(getCurrentArea());
+ }
+ }
+
+ private Area getCurrentArea() {
+ return curBlockArea;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void addAreas(PositionIterator parentIter,
+ LayoutContext layoutContext) {
+
+ getParentArea(null);
+
+ addId();
+
+ LayoutManager childLM;
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
+ LayoutManager firstLM = null;
+ LayoutManager lastLM = null;
+ Position firstPos = null;
+ Position lastPos = null;
+
+ // "unwrap" the NonLeafPositions stored in parentIter
+ // and put them in a new list;
+ LinkedList<Position> positionList = new LinkedList<Position>();
+ Position pos;
+ AlternativeManager altManager = layoutContext.getAlternativeManager();
+ while (parentIter.hasNext()) {
+ pos = parentIter.next();
+ if (pos.getIndex() >= 0) {
+ if (firstPos == null) {
+ firstPos = pos;
+ }
+ lastPos = pos;
+ }
+ if (pos instanceof NonLeafPosition && (pos.getPosition() != null)
+ && pos.getPosition().getLM() != this) {
+ // pos was created by a child of this BestFitBlockLM
+ positionList.add(pos.getPosition());
+ lastLM = pos.getPosition().getLM();
+ if (firstLM == null) {
+ firstLM = lastLM;
+ }
+ }
+ else if (pos instanceof BestFitPosition) {
+ if (altManager.hasAny()) {
+ Alternative bestAlt = altManager.getNextBestAlternative();
+ Iterator<ListElement> it = bestAlt.getKnuthList().iterator();
+ while (it.hasNext()) {
+ positionList.add(it.next().getPosition());
+ }
+ }
+ lastLM = pos.getLM();
+ if (firstLM == null) {
+ firstLM = lastLM;
+ }
+ }
+ }
+
+ //registerMarkers(true, isFirst(firstPos), isLast(lastPos));
+
+ PositionIterator childPosIter = new PositionIterator(
+ positionList.listIterator());
+ while ((childLM = childPosIter.getNextChildLM()) != null) {
+ // Add the block areas to Area
+ // set the space adjustment ratio
+ lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
+ lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM);
+ lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM);
+ lc.setStackLimitBP(layoutContext.getStackLimitBP());
+ childLM.addAreas(childPosIter, lc);
+ }
+
+ //registerMarkers(false, isFirst(firstPos), isLast(lastPos));
+
+ flush();
+
+ curBlockArea = null;
+
+ checkEndOfLayout(lastPos);
+ }
+
+ /** {@inheritDoc} */
+ public boolean isRestartable() {
+ return true;
+ }
+
+}
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitLayoutManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitLayoutManager.java
------------------------------------------------------------------------------
svn:keywords = Revision Id
Added: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java?rev=1518691&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java (added)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java Thu Aug 29 16:26:12 2013
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutmgr;
+
+import java.util.LinkedList;
+
+import org.apache.fop.layoutmgr.AlternativeManager.Alternative;
+import org.apache.fop.layoutmgr.AlternativeManager.FittingStrategy;
+
+/**
+ * A dummy penalty used in {@link BestFitLayoutManager} to store
+ * the different alternatives in {@link fox:best-fit}
+ */
+
+public class BestFitPenalty extends KnuthPenalty {
+
+ private LinkedList<Alternative> alternatives;
+ private FittingStrategy strategy;
+
+ public BestFitPenalty(FittingStrategy strategy, Position pos) {
+ super(0, 0, false, pos, false);
+ this.strategy = strategy;
+ alternatives = new LinkedList<Alternative>();
+ }
+
+ public void addAlternative(Alternative alternative) {
+ alternatives.add(alternative);
+ }
+
+ public Alternative getAlternative(int index) {
+ return alternatives.get(index);
+ }
+
+ public int getAlternativeCount() {
+ return alternatives.size();
+ }
+
+ public FittingStrategy getStrategyType() {
+ return strategy;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ String str = super.toString();
+ StringBuffer buffer = new StringBuffer(64);
+ buffer.append(" number of alternatives = " + getAlternativeCount());
+ buffer.append(" fitting-strategy = " + strategy);
+ return str + buffer.toString();
+ }
+
+}
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java
------------------------------------------------------------------------------
svn:keywords = Revision Id
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java Thu Aug 29 16:26:12 2013
@@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.Constants;
+import org.apache.fop.layoutmgr.AlternativeManager.Alternative;
/**
* The set of nodes is sorted into lines indexed into activeLines.
@@ -192,6 +193,8 @@ public abstract class BreakingAlgorithm
private boolean partOverflowRecoveryActivated = true;
private KnuthNode lastRecovered;
+ private AlternativeManager altManager = new AlternativeManager();
+
/**
* Create a new instance.
*
@@ -822,6 +825,30 @@ public abstract class BreakingAlgorithm
}
}
+ private int handleBestFitPenalty(BestFitPenalty penalty, KnuthNode node,
+ int elementIdx) {
+ int difference;
+ // Find the alternatives that can be fitted inside the remaining space
+ for (int i = 0; i < penalty.getAlternativeCount(); ++i) {
+ Alternative alt = penalty.getAlternative(i);
+ difference = computeDifference(node, new KnuthPenalty(alt.getWidth(),
+ 0, false, null, false), elementIdx);
+ if (difference > 0) {
+ alt.setRemainingBPD(difference);
+ altManager.addAlternative(alt);
+ }
+ }
+ Alternative bestAlt = altManager.getBestAlternative(penalty.getStrategyType());
+ if (bestAlt != null) {
+ difference = bestAlt.getRemainingBPD();
+ return difference;
+ } else {
+ // No alternative can be fitted inside the remaining space
+ return computeDifference(node, new KnuthPenalty(0,
+ 0, false, null, false), elementIdx);
+ }
+ }
+
/**
* Replace the last too-long or too-short node by the last deactivated
* node, if applicable.
@@ -930,7 +957,13 @@ public abstract class BreakingAlgorithm
if (node.position == elementIdx) {
continue;
}
- int difference = computeDifference(node, element, elementIdx);
+ int difference;
+ if (element instanceof BestFitPenalty) {
+ BestFitPenalty penalty = (BestFitPenalty)element;
+ difference = handleBestFitPenalty(penalty, node, elementIdx);
+ } else {
+ difference = computeDifference(node, element, elementIdx);
+ }
if (!elementCanEndLine(element, endLine, difference)) {
log.trace("Skipping legal break");
break;
@@ -1451,4 +1484,9 @@ public abstract class BreakingAlgorithm
return this.alignmentLast;
}
+ /** @return the alternative manager (used by fox:best-fit) */
+ public AlternativeManager getAlternativeManager() {
+ return altManager;
+ }
+
}
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/ElementListUtils.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/ElementListUtils.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/ElementListUtils.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/ElementListUtils.java Thu Aug 29 16:26:12 2013
@@ -163,6 +163,37 @@ public final class ElementListUtils {
}
/**
+ * Calculates the full content length of the given element list. Warning: It doesn't take any
+ * stretch and shrink possibilities into account.
+ * @param elems the element list
+ * @return the content length
+ */
+ public static int calcFullContentLength(List elems) {
+ ListIterator iter = elems.listIterator(0);
+ int count = elems.size();
+ int len = 0;
+ while (iter.hasNext()) {
+ ListElement el = (ListElement)iter.next();
+ if (el.isBox()) {
+ len += ((KnuthElement)el).getWidth();
+ } else if (el.isGlue()) {
+ len += ((KnuthElement)el).getWidth();
+ }
+ else if (el.isUnresolvedElement() && (el instanceof BreakElement) == false) {
+ // Handle properties space-before and space-after
+ UnresolvedListElementWithLength uresolvedEl = (UnresolvedListElementWithLength)el;
+ if (uresolvedEl.isLast() || uresolvedEl.isFirst())
+ len += uresolvedEl.getLength().getOpt();
+ }
+ count--;
+ if (count == 0) {
+ break;
+ }
+ }
+ return len;
+ }
+
+ /**
* Calculates the content length of the given element list. Warning: It doesn't take any
* stretch and shrink possibilities into account.
* @param elems the element list
@@ -201,7 +232,7 @@ public final class ElementListUtils {
if (last.isPenalty() && ((KnuthPenalty)last).getPenalty() < KnuthElement.INFINITE) {
return true;
} else if (last instanceof BreakElement
- && ((BreakElement)last).getPenaltyValue() < KnuthElement.INFINITE) {
+ && ((BreakElement)last).getPenaltyValue() < KnuthElement.INFINITE) {
return true;
}
return false;
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java Thu Aug 29 16:26:12 2013
@@ -204,6 +204,7 @@ public class FlowLayoutManager extends B
childLC.setStackLimitBP(context.getStackLimitBP());
childLC.setRefIPD(context.getRefIPD());
childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode());
+ childLC.setAlternativeManager(context.getAlternativeManager());
return childLC;
}
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutContext.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutContext.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutContext.java Thu Aug 29 16:26:12 2013
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.List;
import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.extensions.AlternativeBlock;
import org.apache.fop.layoutmgr.inline.AlignmentContext;
import org.apache.fop.layoutmgr.inline.HyphContext;
import org.apache.fop.traits.MinOptMax;
@@ -35,6 +36,9 @@ import org.apache.fop.traits.WritingMode
*/
public final class LayoutContext {
+ /** Manager of @{link {@link AlternativeBlock} and only used by {@link BestFitLayoutManager}*/
+ private AlternativeManager altManager;
+
/** Generated break possibility is first in a new area */
public static final int NEW_AREA = 0x01;
@@ -142,6 +146,7 @@ public final class LayoutContext {
public static LayoutContext offspringOf(LayoutContext parent) {
LayoutContext offspring = new LayoutContext(0);
offspring.setTreatAsArtifact(parent.treatAsArtifact());
+ offspring.setAlternativeManager(parent.getAlternativeManager());
return offspring;
}
@@ -646,24 +651,24 @@ public final class LayoutContext {
/** {@inheritDoc} */
public String toString() {
return "Layout Context:"
- + "\nStack Limit BPD: \t"
- + (getStackLimitBP() == null ? "null" : getStackLimitBP().toString())
- + "\nTrailing Space: \t"
- + (getTrailingSpace() == null ? "null" : getTrailingSpace().toString())
- + "\nLeading Space: \t"
- + (getLeadingSpace() == null ? "null" : getLeadingSpace().toString())
- + "\nReference IPD: \t" + getRefIPD()
- + "\nSpace Adjust: \t" + getSpaceAdjust()
- + "\nIPD Adjust: \t" + getIPDAdjust()
- + "\nResolve Leading Space: \t" + resolveLeadingSpace()
- + "\nSuppress Break Before: \t" + suppressBreakBefore()
- + "\nIs First Area: \t" + isFirstArea()
- + "\nStarts New Area: \t" + startsNewArea()
- + "\nIs Last Area: \t" + isLastArea()
- + "\nKeeps: \t[keep-with-next=" + getKeepWithNextPending()
+ + "\nStack Limit BPD: \t"
+ + (getStackLimitBP() == null ? "null" : getStackLimitBP().toString())
+ + "\nTrailing Space: \t"
+ + (getTrailingSpace() == null ? "null" : getTrailingSpace().toString())
+ + "\nLeading Space: \t"
+ + (getLeadingSpace() == null ? "null" : getLeadingSpace().toString())
+ + "\nReference IPD: \t" + getRefIPD()
+ + "\nSpace Adjust: \t" + getSpaceAdjust()
+ + "\nIPD Adjust: \t" + getIPDAdjust()
+ + "\nResolve Leading Space: \t" + resolveLeadingSpace()
+ + "\nSuppress Break Before: \t" + suppressBreakBefore()
+ + "\nIs First Area: \t" + isFirstArea()
+ + "\nStarts New Area: \t" + startsNewArea()
+ + "\nIs Last Area: \t" + isLastArea()
+ + "\nKeeps: \t[keep-with-next=" + getKeepWithNextPending()
+ "][keep-with-previous=" + getKeepWithPreviousPending() + "] pending"
- + "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "]["
- + (breakAfter != Constants.EN_AUTO ? "break-after" : "") + "]";
+ + "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "]["
+ + (breakAfter != Constants.EN_AUTO ? "break-after" : "") + "]";
}
/**
@@ -692,5 +697,13 @@ public final class LayoutContext {
public void setTreatAsArtifact(boolean treatAsArtifact) {
setFlags(TREAT_AS_ARTIFACT, treatAsArtifact);
}
+
+ public void setAlternativeManager(AlternativeManager altManager) {
+ this.altManager = altManager;
+ }
+
+ public AlternativeManager getAlternativeManager() {
+ return altManager;
+ }
}
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java Thu Aug 29 16:26:12 2013
@@ -34,6 +34,8 @@ import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FONode.FONodeIterator;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.FObjMixed;
+import org.apache.fop.fo.extensions.AlternativeBlock;
+import org.apache.fop.fo.extensions.BestFit;
import org.apache.fop.fo.extensions.ExternalDocument;
import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.BidiOverride;
@@ -142,6 +144,8 @@ public class LayoutManagerMapping implem
registerMaker(TableHeader.class, new Maker());
registerMaker(Wrapper.class, new WrapperLayoutManagerMaker());
registerMaker(Title.class, new InlineLayoutManagerMaker());
+ registerMaker(BestFit.class, new BestFitLayoutManagerMaker());
+ registerMaker(AlternativeBlock.class, new AlternativeBlockLayoutManagerMaker());
}
/**
@@ -445,4 +449,20 @@ public class LayoutManagerMapping implem
}
}
+ /** a layout manager maker */
+ public class BestFitLayoutManagerMaker extends Maker {
+ /** {@inheritDoc} */
+ public void make(FONode node, List lms) {
+ lms.add(new BestFitLayoutManager((BestFit) node));
+ }
+ }
+
+ /** a layout manager maker */
+ public class AlternativeBlockLayoutManagerMaker extends Maker {
+ /** {@inheritDoc} */
+ public void make(FONode node, List lms) {
+ lms.add(new AlternativeBlockLayoutManager((AlternativeBlock) node));
+ }
+ }
+
}
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java Thu Aug 29 16:26:12 2013
@@ -26,7 +26,6 @@ import java.util.ListIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition;
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/test/java/org/apache/fop/KnuthAlgorithmTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/test/java/org/apache/fop/KnuthAlgorithmTestCase.java?rev=1518691&r1=1518690&r2=1518691&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/test/java/org/apache/fop/KnuthAlgorithmTestCase.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/test/java/org/apache/fop/KnuthAlgorithmTestCase.java Thu Aug 29 16:26:12 2013
@@ -19,10 +19,16 @@
package org.apache.fop;
-import static org.junit.Assert.assertEquals;
-
import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.fop.layoutmgr.AlternativeManager.Alternative;
+import org.apache.fop.layoutmgr.AlternativeManager.FittingStrategy;
+import org.apache.fop.layoutmgr.BestFitPenalty;
import org.apache.fop.layoutmgr.BlockKnuthSequence;
import org.apache.fop.layoutmgr.BreakingAlgorithm;
import org.apache.fop.layoutmgr.ElementListObserver;
@@ -30,8 +36,6 @@ import org.apache.fop.layoutmgr.KnuthBox
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.KnuthPenalty;
import org.apache.fop.layoutmgr.KnuthSequence;
-import org.junit.Before;
-import org.junit.Test;
/**
* Tests the Knuth algorithm implementation.
@@ -63,6 +67,27 @@ public class KnuthAlgorithmTestCase {
return seq;
}
+ private static class BestFitPenaltyTestCase {
+
+ private static KnuthSequence getKnuthSequence() {
+ KnuthSequence seq = new BlockKnuthSequence();
+ FittingStrategy strategies[] = {FittingStrategy.FIRST_FIT,
+ FittingStrategy.SMALLEST_FIT,
+ FittingStrategy.BIGGEST_FIT};
+ for (int i = 0; i < 3; ++i) {
+ BestFitPenalty bestFitPenalty = new BestFitPenalty(strategies[i], null);
+ bestFitPenalty.addAlternative(new Alternative(null, 25000));
+ bestFitPenalty.addAlternative(new Alternative(null, 5000));
+ bestFitPenalty.addAlternative(new Alternative(null, 29000));
+ seq.add(new KnuthBox(0, null, false));
+ seq.add(bestFitPenalty);
+ seq.add(new KnuthPenalty(0, -KnuthPenalty.INFINITE, false, null, false));
+ }
+ return seq;
+ }
+
+ }
+
/**
* Tests a special condition where a negative-length glue occurs directly after a break
* possibility.
@@ -79,6 +104,22 @@ public class KnuthAlgorithmTestCase {
assertEquals(5000, parts[0].difference);
assertEquals(5000, parts[1].difference);
}
+ /**
+ * Testcase for BestFitPenalty
+ * @throws Exception if an error occurs
+ */
+ @Test
+ public void test2() throws Exception {
+ MyBreakingAlgorithm algo = new MyBreakingAlgorithm(0, 0, true, true, 0);
+ algo.setConstantLineWidth(30000);
+ KnuthSequence seq = BestFitPenaltyTestCase.getKnuthSequence();
+ algo.findBreakingPoints(seq, 1, true, BreakingAlgorithm.ALL_BREAKS);
+ Part[] parts = algo.getParts();
+ assertEquals("Sequence must produce 3 parts", 3, parts.length);
+ assertEquals(5000, parts[0].difference);
+ assertEquals(25000, parts[1].difference);
+ assertEquals(1000, parts[2].difference);
+ }
private class Part {
private int difference;
@@ -88,7 +129,7 @@ public class KnuthAlgorithmTestCase {
private class MyBreakingAlgorithm extends BreakingAlgorithm {
- private List parts = new java.util.ArrayList();
+ private List<Part> parts = new java.util.ArrayList<Part>();
public MyBreakingAlgorithm(int align, int alignLast, boolean first,
boolean partOverflowRecovery, int maxFlagCount) {
@@ -96,7 +137,7 @@ public class KnuthAlgorithmTestCase {
}
public Part[] getParts() {
- return (Part[])parts.toArray(new Part[parts.size()]);
+ return parts.toArray(new Part[parts.size()]);
}
public void updateData1(int total, double demerits) {
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org