| /* |
| * 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 org.apache.fop.fo.FObj; |
| import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener; |
| import org.apache.fop.layoutmgr.inline.TextLayoutManager; |
| |
| public abstract class LocalBreaker extends AbstractBreaker { |
| protected BlockStackingLayoutManager lm; |
| private int displayAlign; |
| private int ipd; |
| private int overflow; |
| private boolean repeatedHeader; |
| private boolean isDescendantOfTableFooter; |
| private boolean repeatedFooter; |
| |
| public void setRepeatedFooter(boolean repeatedFooter) { |
| this.repeatedFooter = repeatedFooter; |
| } |
| |
| public void setDescendantOfTableFooter(boolean isDescendantOfTableFooter) { |
| this.isDescendantOfTableFooter = isDescendantOfTableFooter; |
| } |
| |
| public LocalBreaker(BlockStackingLayoutManager lm, int ipd, int displayAlign) { |
| this.lm = lm; |
| this.ipd = ipd; |
| this.displayAlign = displayAlign; |
| } |
| |
| public void setRepeatedHeader(boolean repeatedHeader) { |
| this.repeatedHeader = repeatedHeader; |
| } |
| |
| /** {@inheritDoc} */ |
| protected boolean isPartOverflowRecoveryActivated() { |
| // For side regions, this must be disabled because of wanted overflow. |
| return false; |
| } |
| |
| public boolean isOverflow() { |
| return (this.overflow != 0); |
| } |
| |
| public int getOverflowAmount() { |
| return this.overflow; |
| } |
| |
| /** {@inheritDoc} */ |
| protected PageBreakingLayoutListener createLayoutListener() { |
| return new PageBreakingLayoutListener() { |
| |
| public void notifyOverflow(int part, int amount, FObj obj) { |
| if (LocalBreaker.this.overflow == 0) { |
| LocalBreaker.this.overflow = amount; |
| } |
| } |
| |
| }; |
| } |
| |
| protected LayoutManager getTopLevelLM() { |
| return lm; |
| } |
| |
| protected LayoutContext createLayoutContext() { |
| LayoutContext lc = super.createLayoutContext(); |
| lc.setRefIPD(ipd); |
| return lc; |
| } |
| |
| protected List getNextKnuthElements(LayoutContext context, int alignment) { |
| LayoutManager curLM; // currently active LM |
| List returnList = new LinkedList(); |
| |
| while ((curLM = lm.getChildLM()) != null) { |
| LayoutContext childLC = LayoutContext.newInstance(); |
| childLC.setStackLimitBP(context.getStackLimitBP()); |
| childLC.setRefIPD(context.getRefIPD()); |
| childLC.setWritingMode(context.getWritingMode()); |
| |
| List returnedList = null; |
| // The following is a HACK! Ignore leading and trailing white space |
| boolean ignore = curLM instanceof TextLayoutManager; |
| if (!curLM.isFinished()) { |
| returnedList = curLM.getNextKnuthElements(childLC, alignment); |
| } |
| if (returnedList != null && !ignore) { |
| lm.wrapPositionElements(returnedList, returnList); |
| } |
| } |
| SpaceResolver.resolveElementList(returnList); |
| lm.setFinished(true); |
| return returnList; |
| } |
| |
| protected int getCurrentDisplayAlign() { |
| return displayAlign; |
| } |
| |
| protected boolean hasMoreContent() { |
| return !lm.isFinished(); |
| } |
| |
| protected void addAreas(PositionIterator posIter, LayoutContext context) { |
| if (isDescendantOfTableFooter) { |
| if (repeatedHeader) { |
| context.setTreatAsArtifact(true); |
| } |
| } else { |
| if (repeatedFooter) { |
| context.setTreatAsArtifact(true); |
| } |
| } |
| AreaAdditionUtil.addAreas(lm, posIter, context); |
| } |
| |
| protected void doPhase3(PageBreakingAlgorithm alg, int partCount, BlockSequence originalList, |
| BlockSequence effectiveList) { |
| if (partCount > 1) { |
| PageBreakPosition pos = alg.getPageBreaks().getFirst(); |
| int firstPartLength = ElementListUtils.calcContentLength(effectiveList, |
| effectiveList.ignoreAtStart, pos.getLeafPos()); |
| overflow += alg.totalWidth - firstPartLength; |
| } |
| // Rendering all parts (not just the first) at once for the case where the parts that |
| // overflow should be visible. |
| alg.removeAllPageBreaks(); |
| // Directly add areas after finding the breaks |
| this.addAreas(alg, 1, originalList, effectiveList); |
| } |
| |
| protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) { |
| // nop for static content |
| } |
| |
| protected LayoutManager getCurrentChildLM() { |
| return null; // TODO NYI |
| } |
| } |