/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id$ */ package org.apache.fop.layoutmgr; import java.util.List; import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.area.RegionReference; import org.apache.fop.fo.Constants; import org.apache.fop.fo.pagination.PageSequence; import org.apache.fop.fo.pagination.SideRegion; import org.apache.fop.fo.pagination.StaticContent; /** * LayoutManager for an fo:flow object. * Its parent LM is the PageSequenceLayoutManager. * This LM is responsible for getting columns of the appropriate size * and filling them with block-level areas generated by its children. */ public class StaticContentLayoutManager extends BlockStackingLayoutManager { private RegionReference targetRegion; private Block targetBlock; private SideRegion regionFO; private int contentAreaIPD; private int contentAreaBPD = -1; /** * Creates a new StaticContentLayoutManager. * @param pslm PageSequenceLayoutManager this layout manager belongs to * @param node static-content FO * @param reg side region to layout into */ public StaticContentLayoutManager(PageSequenceLayoutManager pslm, StaticContent node, SideRegion reg) { super(node); setParent(pslm); regionFO = reg; targetRegion = getCurrentPV().getRegionReference(regionFO.getNameId()); } /** * Creates a new StaticContentLayoutManager. * @param pslm PageSequenceLayoutManager this layout manager belongs to * @param node static-content FO * @param block the block to layout into */ public StaticContentLayoutManager(PageSequenceLayoutManager pslm, StaticContent node, Block block) { super(node); setParent(pslm); targetBlock = block; } /** {@inheritDoc} */ public List getNextKnuthElements(LayoutContext context, int alignment) { throw new IllegalStateException(); } /** * {@inheritDoc} */ public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { AreaAdditionUtil.addAreas(this, parentIter, layoutContext); flush(); targetRegion = null; } /** * Add child area to a the correct container, depending on its * area class. A Flow can fill at most one area container of any class * at any one time. The actual work is done by BlockStackingLM. * {@inheritDoc} */ public void addChildArea(Area childArea) { if (getStaticContentFO().getFlowName().equals("xsl-footnote-separator")) { targetBlock.addBlock((Block)childArea); } else { targetRegion.addBlock((Block)childArea); } } /** * {@inheritDoc} */ public Area getParentArea(Area childArea) { if (getStaticContentFO().getFlowName().equals("xsl-footnote-separator")) { return targetBlock; } else { return targetRegion; } } /** * Does the layout for a side region. Called by PageSequenceLayoutManager. */ public void doLayout() { int targetIPD = 0; int targetBPD = 0; int targetAlign = EN_AUTO; boolean autoHeight = false; StaticContentBreaker breaker; if (getStaticContentFO().getFlowName().equals("xsl-footnote-separator")) { targetIPD = targetBlock.getIPD(); targetBPD = targetBlock.getBPD(); if (targetBPD == 0) { autoHeight = true; } targetAlign = EN_BEFORE; } else { targetIPD = targetRegion.getIPD(); targetBPD = targetRegion.getBPD(); targetAlign = regionFO.getDisplayAlign(); } setContentAreaIPD(targetIPD); setContentAreaBPD(targetBPD); breaker = new StaticContentBreaker(this, targetIPD, targetAlign); breaker.doLayout(targetBPD, autoHeight); if (breaker.isOverflow()) { if (!autoHeight) { String page = getPSLM().getCurrentPage().getPageViewport().getPageNumberString(); BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get( getStaticContentFO().getUserAgent().getEventBroadcaster()); boolean canRecover = (regionFO.getOverflow() != EN_ERROR_IF_OVERFLOW); boolean needClip = (regionFO.getOverflow() == Constants.EN_HIDDEN || regionFO.getOverflow() == Constants.EN_ERROR_IF_OVERFLOW); eventProducer.staticRegionOverflow(this, regionFO.getName(), page, breaker.getOverflowAmount(), needClip, canRecover, getStaticContentFO().getLocator()); } } } /** * Convenience method that returns the Static Content node. * @return the static content node */ protected StaticContent getStaticContentFO() { return (StaticContent) fobj; } private class StaticContentBreaker extends LocalBreaker { public StaticContentBreaker(StaticContentLayoutManager lm, int ipd, int displayAlign) { super(lm, ipd, displayAlign); } /** {@inheritDoc} */ protected void observeElementList(List elementList) { String elementListID = getStaticContentFO().getFlowName(); String pageSequenceID = ((PageSequence) lm.getParent().getFObj()).getId(); if (pageSequenceID != null && pageSequenceID.length() > 0) { elementListID += "-" + pageSequenceID; } ElementListObserver.observe(elementList, "static-content", elementListID); } } /** * Returns the IPD of the content area * @return the IPD of the content area */ public int getContentAreaIPD() { return contentAreaIPD; } /** {@inheritDoc} */ protected void setContentAreaIPD(int contentAreaIPD) { this.contentAreaIPD = contentAreaIPD; } /** * Returns the BPD of the content area * @return the BPD of the content area */ public int getContentAreaBPD() { return contentAreaBPD; } private void setContentAreaBPD(int contentAreaBPD) { this.contentAreaBPD = contentAreaBPD; } /** {@inheritDoc} */ public Keep getKeepTogether() { return Keep.KEEP_AUTO; } /** {@inheritDoc} */ public Keep getKeepWithNext() { return Keep.KEEP_AUTO; } /** {@inheritDoc} */ public Keep getKeepWithPrevious() { return Keep.KEEP_AUTO; } }