blob: 626532fa44bf8af9a429cc505b6b9f0b7fb468f1 [file] [log] [blame]
/*
* Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed 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 org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.pagination.Title;
import org.apache.fop.area.Area;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.inline.InlineArea;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.ArrayList;
import org.apache.fop.traits.MinOptMax;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Content Layout Manager.
* For use with objects that contain inline areas such as
* leader use-content and title.
*/
public class ContentLayoutManager implements InlineLevelLayoutManager {
private FOUserAgent userAgent;
private Area holder;
private int stackSize;
private LayoutManager parentLM;
private InlineLevelLayoutManager childLM = null;
/**
* logging instance
*/
protected static Log log = LogFactory.getLog(LayoutManager.class);
/**
* Constructs a new ContentLayoutManager
*
* @param area The parent area
*/
public ContentLayoutManager(Area area, LayoutManager parentLM) {
holder = area;
this.parentLM = parentLM;
}
/**
* Constructor using a fo:title formatting object
*/
public ContentLayoutManager(Title foTitle, LayoutManager parentLM) {
// get breaks then add areas to title
this.parentLM = parentLM;
holder = new LineArea();
setUserAgent(foTitle.getUserAgent());
// use special layout manager to add the inline areas
// to the Title.
InlineLayoutManager lm;
lm = new InlineLayoutManager(foTitle);
addChildLM(lm);
fillArea(lm);
}
public void fillArea(LayoutManager curLM) {
int ipd = 1000000;
LayoutContext childLC = new LayoutContext(LayoutContext.NEW_AREA);
childLC.setLeadingSpace(new SpaceSpecifier(false));
childLC.setTrailingSpace(new SpaceSpecifier(false));
// set stackLimit for lines
childLC.setStackLimit(new MinOptMax(ipd));
childLC.setRefIPD(ipd);
int lineHeight = 14000;
int lead = 12000;
int follow = 2000;
int halfLeading = (lineHeight - lead - follow) / 2;
// height before baseline
int lineLead = lead + halfLeading;
// maximum size of top and bottom alignment
int maxtb = follow + halfLeading;
// max size of middle alignment below baseline
int middlefollow = maxtb;
stackSize = 0;
LinkedList contentList =
getNextKnuthElements(childLC, Constants.EN_START);
ListIterator contentIter = contentList.listIterator();
while (contentIter.hasNext()) {
KnuthElement element = (KnuthElement) contentIter.next();
if (element.isBox()) {
KnuthInlineBox box = (KnuthInlineBox) element;
if (box.getLead() > lineLead) {
lineLead = box.getLead();
}
if (box.getTotal() > maxtb) {
maxtb = box.getTotal();
}
// Is this needed? cf. LineLM.makeLineBreakPosition
// if (box.getMiddle() > lineLead) {
// lineLead = box.getMiddle();
// }
if (box.getMiddle() > middlefollow) {
middlefollow = box.getMiddle();
}
}
}
if (maxtb - lineLead > middlefollow) {
middlefollow = maxtb - lineLead;
}
LayoutContext lc = new LayoutContext(0);
lc.setBaseline(lineLead);
lc.setLineHeight(lineHeight);
lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
lc.setLeadingSpace(new SpaceSpecifier(false));
lc.setTrailingSpace(new SpaceSpecifier(false));
KnuthPossPosIter contentPosIter =
new KnuthPossPosIter(contentList, 0, contentList.size());
curLM.addAreas(contentPosIter, lc);
}
public void addAreas(PositionIterator posIter, LayoutContext context) {
// add the content areas
// the area width has already been adjusted, and it must remain unchanged
// so save its value before calling addAreas, and set it again afterwards
int savedIPD = ((InlineArea)holder).getIPD();
// set to zero the ipd adjustment ratio, to avoid spaces in the pattern
// to be modified
LayoutContext childContext = new LayoutContext(context);
childContext.setIPDAdjust(0.0);
childLM.addAreas(posIter, childContext);
((InlineArea)holder).setIPD(savedIPD);
}
public int getStackingSize() {
return stackSize;
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public boolean generatesInlineAreas() {
return true;
}
/** @see org.apache.fop.layoutmgr.LayoutManager#isBogus() */
public boolean isBogus() {
return false;
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public Area getParentArea(Area childArea) {
return holder;
}
/**
* @see org.apache.fop.layoutmgr.LayoutManager#addChildArea(Area)
**/
public void addChildArea(Area childArea) {
holder.addChildArea(childArea);
}
/**
* Set the user agent.
*
* @param ua the user agent
*/
public void setUserAgent(FOUserAgent ua) {
userAgent = ua;
}
/**
* @see org.apache.fop.layoutmgr.LayoutManager#getUserAgent()
*/
public FOUserAgent getUserAgent() {
return userAgent;
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public void setParent(LayoutManager lm) {
parentLM = lm;
}
public LayoutManager getParent() {
return this.parentLM;
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public boolean canBreakBefore(LayoutContext lc) {
return false;
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public BreakPoss getNextBreakPoss(LayoutContext context) {
return null;
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public boolean isFinished() {
return false;
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public void setFinished(boolean isFinished) {
//to be done
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public void initialize() {
//to be done
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public void resetPosition(Position position) {
//to be done
}
/** @see org.apache.fop.layoutmgr.LayoutManager */
public void getWordChars(StringBuffer sbChars, Position bp1,
Position bp2) { }
/**
* @see org.apache.fop.layoutmgr.LayoutManager#preLoadNext
*/
public boolean preLoadNext(int pos) {
return false;
}
/**
* @see org.apache.fop.layoutmgr.LayoutManager#getChildLMs
*/
public List getChildLMs() {
List childLMs = new ArrayList(1);
childLMs.add(childLM);
return childLMs;
}
/**
* @see org.apache.fop.layoutmgr.LayoutManager#addChildLM
*/
public void addChildLM(LayoutManager lm) {
if (lm == null) {
return;
}
lm.setParent(this);
lm.initialize();
childLM = (InlineLevelLayoutManager)lm;
log.trace(this.getClass().getName()
+ ": Adding child LM " + lm.getClass().getName());
}
/**
* @see org.apache.fop.layoutmgr.LayoutManager#addChildLMs
*/
public void addChildLMs(List newLMs) {
if (newLMs == null || newLMs.size() == 0) {
return;
}
ListIterator iter = newLMs.listIterator();
while (iter.hasNext()) {
LayoutManager lm = (LayoutManager) iter.next();
addChildLM(lm);
}
}
public LinkedList getNextKnuthElements(LayoutContext context,
int alignment) {
LinkedList contentList = new LinkedList();
LinkedList returnedList;
while (!childLM.isFinished()) {
// get KnuthElements from childLM
returnedList = childLM.getNextKnuthElements(context, alignment);
if (returnedList != null) {
// move elements to contentList, and accumulate their size
KnuthElement contentElement;
while (returnedList.size() > 0) {
contentElement = (KnuthElement)returnedList.removeFirst();
stackSize += contentElement.getW();
contentList.add(contentElement);
}
}
}
setFinished(true);
return contentList;
}
public List addALetterSpaceTo(List oldList) {
return oldList;
}
public void getWordChars(StringBuffer sbChars, Position pos) {
}
public void hyphenate(Position pos, HyphContext hc) {
}
public boolean applyChanges(List oldList) {
return false;
}
public LinkedList getChangedKnuthElements(List oldList,
/*int flaggedPenalty,*/
int alignment) {
return null;
}
public PageSequenceLayoutManager getPSLM() {
return parentLM.getPSLM();
}
}