/*
 * 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: AreaAdditionUtil.java 1562429 2014-01-29 12:52:26Z vhennebert $ */

package org.apache.fop.layoutmgr;

import java.util.LinkedList;

import org.apache.fop.layoutmgr.SpaceResolver.SpaceHandlingBreakPosition;

Utility class which provides common code for the addAreas stage.
/** * Utility class which provides common code for the addAreas stage. */
public final class AreaAdditionUtil { private AreaAdditionUtil() { }
Creates the child areas for the given layout manager.
Params:
  • parentLM – the parent layout manager
  • parentIter – the position iterator
  • layoutContext – the layout context
/** * Creates the child areas for the given layout manager. * @param parentLM the parent layout manager * @param parentIter the position iterator * @param layoutContext the layout context */
public static void addAreas(AbstractLayoutManager parentLM, PositionIterator parentIter, LayoutContext layoutContext) { LayoutManager childLM; LayoutContext lc = LayoutContext.offspringOf(layoutContext); LayoutManager firstLM = null; LayoutManager lastLM = null; Position firstPos = null; Position lastPos = null; if (parentLM != null) { parentLM.addId(); } // "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 == null) { continue; } if (pos.getIndex() >= 0) { if (firstPos == null) { firstPos = pos; } lastPos = pos; } if (pos instanceof NonLeafPosition) { // pos was created by a child of this FlowLM positionList.add(pos.getPosition()); lastLM = (pos.getPosition().getLM()); if (firstLM == null) { firstLM = lastLM; } } else if (pos instanceof SpaceHandlingBreakPosition) { positionList.add(pos); } else { // pos was created by this LM, so it must be ignored } } if (firstPos == null) { return; //Nothing to do, return early //TODO This is a hack to avoid an NPE in the code block below. //If there's no firstPos/lastPos there's currently no way to //correctly determine first and last conditions. The Iterator //doesn't give us that info. } if (parentLM != null) { parentLM.registerMarkers( true, parentLM.isFirst(firstPos), parentLM.isLast(lastPos)); } 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 // the TableCellLM.getNextKnuthElements method // Add the block areas to Area lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM); lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM); // set the space adjustment ratio lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); // set space before for the first LM, in order to implement // display-align = center or after lc.setSpaceBefore((childLM == firstLM ? layoutContext.getSpaceBefore() : 0)); // set space after for each LM, in order to implement // display-align = distribute lc.setSpaceAfter(layoutContext.getSpaceAfter()); lc.setStackLimitBP(layoutContext.getStackLimitBP()); childLM.addAreas(childPosIter, lc); } if (parentLM != null) { parentLM.registerMarkers( false, parentLM.isFirst(firstPos), parentLM.isLast(lastPos)); } } }