/*
 * 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: ListItemContentLayoutManager.java 1642793 2014-12-02 00:29:57Z lbernardo $ */

package org.apache.fop.layoutmgr.list;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.fo.flow.AbstractListItemPart;
import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.BreakOpportunity;
import org.apache.fop.layoutmgr.Keep;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.ListElement;
import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.SpaceResolver.SpaceHandlingBreakPosition;
import org.apache.fop.layoutmgr.TraitSetter;

LayoutManager for a list-item-label or list-item-body FO.
/** * LayoutManager for a list-item-label or list-item-body FO. */
public class ListItemContentLayoutManager extends BlockStackingLayoutManager implements BreakOpportunity { private Block curBlockArea; private int xOffset; // private int itemIPD; // FIXME: never written!
Create a new Cell layout manager.
Params:
  • node – list-item-label node
/** * Create a new Cell layout manager. * @param node list-item-label node */
public ListItemContentLayoutManager(ListItemLabel node) { super(node); }
Create a new Cell layout manager.
Params:
  • node – list-item-body node
/** * Create a new Cell layout manager. * @param node list-item-body node */
public ListItemContentLayoutManager(ListItemBody node) { super(node); }
Convenience method.
Returns:the ListBlock node
/** * Convenience method. * @return the ListBlock node */
protected AbstractListItemPart getPartFO() { return (AbstractListItemPart)fobj; }
Set the x offset of this list item. This offset is used to set the absolute position of the list item within the parent block area.
Params:
  • off – the x offset
/** * Set the x offset of this list item. * This offset is used to set the absolute position * of the list item within the parent block area. * * @param off the x offset */
public void setXOffset(int off) { xOffset = off; }
Add the areas for the break points. The list item contains block stacking layout managers that add block areas.
Params:
  • parentIter – the iterator of the break positions
  • layoutContext – the layout context for adding the areas
/** * Add the areas for the break points. * The list item contains block stacking layout managers * that add block areas. * * @param parentIter the iterator of the break positions * @param layoutContext the layout context for adding the areas */
@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 == 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 ListBlockLM 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 ListBlockLM, so it must be ignored } } registerMarkers(true, isFirst(firstPos), isLast(lastPos)); PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); while ((childLM = childPosIter.getNextChildLM()) != null) { // 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()); lc.setStackLimitBP(layoutContext.getStackLimitBP()); childLM.addAreas(childPosIter, lc); } registerMarkers(false, isFirst(firstPos), isLast(lastPos)); flush(); curBlockArea = null; checkEndOfLayout(lastPos); }
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.
Params:
  • childArea – the child area to get the parent for
Returns:the parent area
/** * 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 to get the parent for * @return the parent area */
@Override public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); curBlockArea.setPositioning(Block.ABSOLUTE); // set position curBlockArea.setXOffset(xOffset); // FIXME - itemIPD is never written! curBlockArea.setIPD(/*itemIPD*/0); //curBlockArea.setHeight(); curBlockArea.setBidiLevel(getPartFO().getBidiLevel()); TraitSetter.setProducerID(curBlockArea, getPartFO().getId()); // Set up dimensions Area parentArea = parentLayoutManager.getParentArea(curBlockArea); int referenceIPD = parentArea.getIPD(); curBlockArea.setIPD(referenceIPD); // Get reference IPD from parentArea setCurrentArea(curBlockArea); // ??? for generic operations } return curBlockArea; }
Add the child to the list item area.
Params:
  • childArea – the child to add to the cell
/** * Add the child to the list item area. * * @param childArea the child to add to the cell */
@Override public void addChildArea(Area childArea) { if (curBlockArea != null) { curBlockArea.addBlock((Block) childArea); } }
{@inheritDoc}
/** {@inheritDoc} */
@Override public KeepProperty getKeepTogetherProperty() { return getPartFO().getKeepTogether(); }
{@inheritDoc}
/** {@inheritDoc} */
@Override public Keep getKeepWithNext() { return Keep.KEEP_AUTO; }
{@inheritDoc}
/** {@inheritDoc} */
@Override public Keep getKeepWithPrevious() { return Keep.KEEP_AUTO; }
{@inheritDoc}
/** {@inheritDoc} */
public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack, Position restartPosition, LayoutManager restartAtLM) { List<ListElement> elements = new LinkedList<ListElement>(); do { elements.addAll(super.getNextKnuthElements(context, alignment, lmStack, restartPosition, restartAtLM)); } while (!isFinished()); return elements; } }