| /* |
| * 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.table; |
| |
| import org.apache.fop.area.Area; |
| import org.apache.fop.area.Block; |
| import org.apache.fop.fo.flow.table.TableCaption; |
| import org.apache.fop.layoutmgr.BlockStackingLayoutManager; |
| import org.apache.fop.layoutmgr.Keep; |
| import org.apache.fop.layoutmgr.LayoutContext; |
| import org.apache.fop.layoutmgr.PositionIterator; |
| |
| /** |
| * LayoutManager for a table-caption FO. |
| * The table caption contains blocks that are placed beside the |
| * table. |
| * TODO Implement getNextKnuthElements() |
| */ |
| public class TableCaptionLayoutManager extends BlockStackingLayoutManager { |
| |
| private Block curBlockArea; |
| |
| //private List childBreaks = new ArrayList(); |
| |
| /** |
| * Create a new Caption layout manager. |
| * @param node table-caption FO |
| */ |
| public TableCaptionLayoutManager(TableCaption node) { |
| super(node); |
| } |
| |
| /** @return the table-caption FO */ |
| public TableCaption getTableCaptionFO() { |
| return (TableCaption)this.fobj; |
| } |
| |
| /** |
| * Get the next break position for the caption. |
| * |
| * @param context the layout context for finding breaks |
| * @return the next break possibility |
| */ |
| /* |
| public BreakPoss getNextBreakPoss(LayoutContext context) { |
| LayoutManager curLM; // currently active LM |
| |
| MinOptMax stackSize = new MinOptMax(); |
| // if starting add space before |
| // stackSize.add(spaceBefore); |
| BreakPoss lastPos = null; |
| |
| // if there is a caption then get the side and work out when |
| // to handle it |
| |
| while ((curLM = getChildLM()) != null) { |
| // Make break positions and return blocks! |
| // Set up a LayoutContext |
| int ipd = context.getRefIPD(); |
| BreakPoss bp; |
| |
| LayoutContext childLC = LayoutContext.newInstance(); |
| // if line layout manager then set stack limit to ipd |
| // line LM actually generates a LineArea which is a block |
| childLC.setStackLimit( |
| MinOptMax.subtract(context.getStackLimit(), |
| stackSize)); |
| childLC.setRefIPD(ipd); |
| |
| boolean over = false; |
| |
| while (!curLM.isFinished()) { |
| if ((bp = curLM.getNextBreakPoss(childLC)) != null) { |
| if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { |
| // reset to last break |
| if (lastPos != null) { |
| LayoutManager lm = lastPos.getLayoutManager(); |
| lm.resetPosition(lastPos.getPosition()); |
| if (lm != curLM) { |
| curLM.resetPosition(null); |
| } |
| } else { |
| curLM.resetPosition(null); |
| } |
| over = true; |
| break; |
| } |
| stackSize.add(bp.getStackingSize()); |
| lastPos = bp; |
| childBreaks.add(bp); |
| |
| if (bp.nextBreakOverflows()) { |
| over = true; |
| break; |
| } |
| |
| childLC.setStackLimit(MinOptMax.subtract( |
| context.getStackLimit(), stackSize)); |
| } |
| } |
| BreakPoss breakPoss = new BreakPoss( |
| new LeafPosition(this, childBreaks.size() - 1)); |
| if (over) { |
| breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); |
| } |
| breakPoss.setStackingSize(stackSize); |
| return breakPoss; |
| } |
| setFinished(true); |
| return null; |
| }*/ |
| |
| /** |
| * Add the areas to the parent. |
| * |
| * @param parentIter the position iterator of the breaks |
| * @param layoutContext the layout context for adding areas |
| */ |
| public void addAreas(PositionIterator parentIter, |
| LayoutContext layoutContext) { |
| getParentArea(null); |
| addId(); |
| |
| /* TODO: Reimplement using Knuth approach |
| LayoutManager childLM; |
| int iStartPos = 0; |
| LayoutContext lc = LayoutContext.newInstance(); |
| while (parentIter.hasNext()) { |
| LeafPosition lfp = (LeafPosition) parentIter.next(); |
| // Add the block areas to Area |
| PositionIterator breakPosIter = new BreakPossPosIter( |
| childBreaks, iStartPos, lfp.getLeafPos() + 1); |
| iStartPos = lfp.getLeafPos() + 1; |
| while ((childLM = breakPosIter.getNextChildLM()) != null) { |
| childLM.addAreas(breakPosIter, lc); |
| } |
| }*/ |
| |
| flush(); |
| |
| //childBreaks.clear(); |
| curBlockArea = null; |
| } |
| |
| /** |
| * Return an Area which can contain the passed childArea. The childArea |
| * may not yet have any content, but it has essential traits set. |
| * In general, if the LayoutManager already has an Area it simply returns |
| * it. Otherwise, it makes a new Area of the appropriate class. |
| * It gets a parent area for its area by calling its parent LM. |
| * Finally, based on the dimensions of the parent area, it initializes |
| * its own area. This includes setting the content IPD and the maximum |
| * BPD. |
| * |
| * @param childArea the child area |
| * @return the parent area from this caption |
| */ |
| 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); |
| int referenceIPD = parentArea.getIPD(); |
| curBlockArea.setIPD(referenceIPD); |
| curBlockArea.setBidiLevel(getTableCaptionFO().getBidiLevel()); |
| // Get reference IPD from parentArea |
| setCurrentArea(curBlockArea); // ??? for generic operations |
| } |
| return curBlockArea; |
| } |
| |
| /** |
| * Add the child to the caption area. |
| * |
| * @param childArea the child area to add |
| */ |
| public void addChildArea(Area childArea) { |
| if (curBlockArea != null) { |
| curBlockArea.addBlock((Block) childArea); |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| public Keep getKeepWithNext() { |
| return Keep.KEEP_AUTO; |
| /* TODO Complete me! |
| return KeepUtil.getCombinedBlockLevelKeepStrength( |
| getTableCaptionFO().getKeepWithNext()); |
| */ |
| } |
| |
| /** {@inheritDoc} */ |
| public Keep getKeepWithPrevious() { |
| return Keep.KEEP_AUTO; |
| /* TODO Complete me! |
| return KeepUtil.getCombinedBlockLevelKeepStrength( |
| getTableCaptionFO().getKeepWithPrevious()); |
| */ |
| } |
| |
| } |
| |