/* * 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.inline; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.Constants; import org.apache.fop.fo.pagination.Title; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthPossPosIter; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.PageSequenceLayoutManager; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; import org.apache.fop.layoutmgr.SpaceSpecifier; 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 and its * PageSequenceLayoutManager parent. */ public ContentLayoutManager(Title foTitle, PageSequenceLayoutManager pslm) { // get breaks then add areas to title this.parentLM = pslm; 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 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 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 resetPosition(Position position) { //to be done } /** * @see org.apache.fop.layoutmgr.LayoutManager#createNextChildLMs */ public boolean createNextChildLMs(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); 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(); } }