KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > layoutmgr > inline > LeaderLayoutManager


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: LeaderLayoutManager.java 462812 2006-10-11 14:19:28Z spepping $ */
19
20 package org.apache.fop.layoutmgr.inline;
21
22 import org.apache.fop.area.Trait;
23 import org.apache.fop.area.inline.FilledArea;
24 import org.apache.fop.area.inline.InlineArea;
25 import org.apache.fop.area.inline.Space;
26 import org.apache.fop.area.inline.TextArea;
27 import org.apache.fop.fo.flow.Leader;
28 import org.apache.fop.fonts.Font;
29 import org.apache.fop.layoutmgr.InlineKnuthSequence;
30 import org.apache.fop.layoutmgr.KnuthElement;
31 import org.apache.fop.layoutmgr.KnuthGlue;
32 import org.apache.fop.layoutmgr.KnuthPenalty;
33 import org.apache.fop.layoutmgr.KnuthPossPosIter;
34 import org.apache.fop.layoutmgr.KnuthSequence;
35 import org.apache.fop.layoutmgr.LayoutContext;
36 import org.apache.fop.layoutmgr.LeafPosition;
37 import org.apache.fop.layoutmgr.Position;
38 import org.apache.fop.layoutmgr.PositionIterator;
39 import org.apache.fop.layoutmgr.TraitSetter;
40 import org.apache.fop.traits.MinOptMax;
41
42 import java.util.List JavaDoc;
43 import java.util.LinkedList JavaDoc;
44 import org.apache.fop.fo.FObj;
45
46 /**
47  * LayoutManager for the fo:leader formatting object
48  */

49 public class LeaderLayoutManager extends LeafNodeLayoutManager {
50     private Leader fobj;
51     private Font font = null;
52     
53     private LinkedList JavaDoc contentList = null;
54     private ContentLayoutManager clm = null;
55     
56     private int contentAreaIPD = 0;
57
58     /**
59      * Constructor
60      *
61      * @param node the formatting object that creates this area
62      */

63     public LeaderLayoutManager(Leader node) {
64         super(node);
65         fobj = node;
66     }
67     
68     /** @see org.apache.fop.layoutmgr.LayoutManager#initialize */
69     public void initialize() {
70         font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
71         // the property leader-alignment does not affect vertical positioning
72
// (see section 7.21.1 in the XSL Recommendation)
73
// setAlignment(node.getLeaderAlignment());
74
setCommonBorderPaddingBackground(fobj.getCommonBorderPaddingBackground());
75     }
76
77     /**
78      * Return the inline area for this leader.
79      * @param context the layout context
80      * @return the inline area
81      */

82     public InlineArea get(LayoutContext context) {
83         return getLeaderInlineArea(context);
84     }
85
86     /**
87      * Return the allocated IPD for this area.
88      * @param refIPD the IPD of the reference area
89      * @return the allocated IPD
90      */

91     protected MinOptMax getAllocationIPD(int refIPD) {
92         return getLeaderAllocIPD(refIPD);
93     }
94
95     private MinOptMax getLeaderAllocIPD(int ipd) {
96         // length of the leader
97
int borderPaddingWidth = 0;
98         if (commonBorderPaddingBackground != null) {
99             borderPaddingWidth = commonBorderPaddingBackground.getIPPaddingAndBorder(false, this);
100         }
101         setContentAreaIPD(ipd - borderPaddingWidth);
102         int opt = fobj.getLeaderLength().getOptimum(this).getLength().getValue(this)
103                     - borderPaddingWidth;
104         int min = fobj.getLeaderLength().getMinimum(this).getLength().getValue(this)
105                     - borderPaddingWidth;
106         int max = fobj.getLeaderLength().getMaximum(this).getLength().getValue(this)
107                     - borderPaddingWidth;
108         return new MinOptMax(min, opt, max);
109     }
110
111     private InlineArea getLeaderInlineArea(LayoutContext context) {
112         InlineArea leaderArea = null;
113
114         if (fobj.getLeaderPattern() == EN_RULE) {
115             if (fobj.getRuleStyle() != EN_NONE) {
116                 org.apache.fop.area.inline.Leader leader
117                     = new org.apache.fop.area.inline.Leader();
118                 leader.setRuleStyle(fobj.getRuleStyle());
119                 leader.setRuleThickness(fobj.getRuleThickness().getValue(this));
120                 leader.setBPD(fobj.getRuleThickness().getValue(this));
121                 leaderArea = leader;
122             } else {
123                 leaderArea = new Space();
124                 leaderArea.setBPD(1);
125             }
126             leaderArea.addTrait(Trait.COLOR, fobj.getColor());
127         } else if (fobj.getLeaderPattern() == EN_SPACE) {
128             leaderArea = new Space();
129             leaderArea.setBPD(1);
130         } else if (fobj.getLeaderPattern() == EN_DOTS) {
131             TextArea t = new TextArea();
132             char dot = '.'; // userAgent.getLeaderDotCharacter();
133

134             int width = font.getCharWidth(dot);
135             t.addWord("" + dot, 0);
136             t.setIPD(width);
137             t.setBPD(width);
138             t.setBaselineOffset(width);
139             TraitSetter.addFontTraits(t, font);
140             t.addTrait(Trait.COLOR, fobj.getColor());
141             Space spacer = null;
142             if (fobj.getLeaderPatternWidth().getValue(this) > width) {
143                 spacer = new Space();
144                 spacer.setIPD(fobj.getLeaderPatternWidth().getValue(this) - width);
145                 width = fobj.getLeaderPatternWidth().getValue(this);
146             }
147             FilledArea fa = new FilledArea();
148             fa.setUnitWidth(width);
149             fa.addChildArea(t);
150             if (spacer != null) {
151                 fa.addChildArea(spacer);
152             }
153             fa.setBPD(t.getBPD());
154
155             leaderArea = fa;
156         } else if (fobj.getLeaderPattern() == EN_USECONTENT) {
157             if (fobj.getChildNodes() == null) {
158                 fobj.getLogger().error("Leader use-content with no content");
159                 return null;
160             }
161
162             // child FOs are assigned to the InlineStackingLM
163
fobjIter = null;
164             
165             // get breaks then add areas to FilledArea
166
FilledArea fa = new FilledArea();
167
168             clm = new ContentLayoutManager(fa, this);
169             addChildLM(clm);
170
171             InlineLayoutManager lm;
172             lm = new InlineLayoutManager(fobj);
173             clm.addChildLM(lm);
174             lm.initialize();
175
176             LayoutContext childContext = new LayoutContext(0);
177             childContext.setAlignmentContext(context.getAlignmentContext());
178             contentList = clm.getNextKnuthElements(childContext, 0);
179             int width = clm.getStackingSize();
180             Space spacer = null;
181             if (fobj.getLeaderPatternWidth().getValue(this) > width) {
182                 spacer = new Space();
183                 spacer.setIPD(fobj.getLeaderPatternWidth().getValue(this) - width);
184                 width = fobj.getLeaderPatternWidth().getValue(this);
185             }
186             fa.setUnitWidth(width);
187             if (spacer != null) {
188                 fa.addChildArea(spacer);
189             }
190             leaderArea = fa;
191         }
192         TraitSetter.setProducerID(leaderArea, fobj.getId());
193         return leaderArea;
194      }
195
196     /** @see LeafNodeLayoutManager#addAreas(PositionIterator, LayoutContext) */
197     public void addAreas(PositionIterator posIter, LayoutContext context) {
198         if (fobj.getLeaderPattern() != EN_USECONTENT) {
199             // use LeafNodeLayoutManager.addAreas()
200
super.addAreas(posIter, context);
201         } else {
202             addId();
203
204             widthAdjustArea(curArea, context);
205
206             if (commonBorderPaddingBackground != null) {
207                 // Add border and padding to area
208
TraitSetter.setBorderPaddingTraits(curArea,
209                                                    commonBorderPaddingBackground,
210                                                    false, false, this);
211                 TraitSetter.addBackground(curArea, commonBorderPaddingBackground, this);
212             }
213
214             // add content areas
215
KnuthPossPosIter contentIter = new KnuthPossPosIter(contentList, 0, contentList.size());
216             clm.addAreas(contentIter, context);
217
218             parentLM.addChildArea(curArea);
219
220             while (posIter.hasNext()) {
221                 posIter.next();
222             }
223         }
224     }
225
226     /** @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(LayoutContext, int) */
227     public LinkedList JavaDoc getNextKnuthElements(LayoutContext context,
228                                            int alignment) {
229         MinOptMax ipd;
230         curArea = get(context);
231         KnuthSequence seq = new InlineKnuthSequence();
232
233         if (curArea == null) {
234             setFinished(true);
235             return null;
236         }
237
238         alignmentContext = new AlignmentContext(curArea.getBPD()
239                                     , fobj.getAlignmentAdjust()
240                                     , fobj.getAlignmentBaseline()
241                                     , fobj.getBaselineShift()
242                                     , fobj.getDominantBaseline()
243                                     , context.getAlignmentContext());
244
245         ipd = getAllocationIPD(context.getRefIPD());
246         if (fobj.getLeaderPattern() == EN_USECONTENT && curArea instanceof FilledArea) {
247             // If we have user supplied content make it fit if we can
248
int unitWidth = ((FilledArea)curArea).getUnitWidth();
249             if (ipd.opt < unitWidth && ipd.max >= unitWidth) {
250                 ipd.opt = unitWidth;
251             }
252         }
253
254         // create the AreaInfo object to store the computed values
255
areaInfo = new AreaInfo((short) 0, ipd, false, context.getAlignmentContext());
256         curArea.setAdjustingInfo(ipd.max - ipd.opt, ipd.opt - ipd.min, 0);
257
258         addKnuthElementsForBorderPaddingStart(seq);
259         
260         // node is a fo:Leader
261
seq.add(new KnuthInlineBox(0, alignmentContext,
262                                     new LeafPosition(this, -1), true));
263         seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
264                                         new LeafPosition(this, -1), true));
265         if (alignment == EN_JUSTIFY || alignment == 0) {
266             seq.add
267                 (new KnuthGlue(areaInfo.ipdArea.opt,
268                                areaInfo.ipdArea.max - areaInfo.ipdArea.opt,
269                                areaInfo.ipdArea.opt - areaInfo.ipdArea.min,
270                                new LeafPosition(this, 0), false));
271         } else {
272             seq.add
273                 (new KnuthGlue(areaInfo.ipdArea.opt,
274                                0,
275                                0,
276                                new LeafPosition(this, 0), false));
277         }
278         seq.add(new KnuthInlineBox(0, alignmentContext,
279                                     new LeafPosition(this, -1), true));
280
281         addKnuthElementsForBorderPaddingEnd(seq);
282         
283         LinkedList JavaDoc returnList = new LinkedList JavaDoc();
284         returnList.add(seq);
285         setFinished(true);
286         return returnList;
287     }
288
289     /** @see InlineLevelLayoutManager#hyphenate(Position, HyphContext) */
290     public void hyphenate(Position pos, HyphContext hc) {
291         // use the AbstractLayoutManager.hyphenate() null implementation
292
super.hyphenate(pos, hc);
293     }
294
295     /** @see InlineLevelLayoutManager#applyChanges(List) */
296     public boolean applyChanges(List JavaDoc oldList) {
297         setFinished(false);
298         return false;
299     }
300
301     /** @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(List, int) */
302     public LinkedList JavaDoc getChangedKnuthElements(List JavaDoc oldList,
303                                               int alignment) {
304         if (isFinished()) {
305             return null;
306         }
307
308         LinkedList JavaDoc returnList = new LinkedList JavaDoc();
309
310         addKnuthElementsForBorderPaddingStart(returnList);
311         
312         returnList.add(new KnuthInlineBox(0, areaInfo.alignmentContext,
313                                     new LeafPosition(this, -1), true));
314         returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
315                                         new LeafPosition(this, -1), true));
316         if (alignment == EN_JUSTIFY || alignment == 0) {
317             returnList.add
318                 (new KnuthGlue(areaInfo.ipdArea.opt,
319                                areaInfo.ipdArea.max - areaInfo.ipdArea.opt,
320                                areaInfo.ipdArea.opt - areaInfo.ipdArea.min,
321                                new LeafPosition(this, 0), false));
322         } else {
323             returnList.add
324                 (new KnuthGlue(areaInfo.ipdArea.opt,
325                                0,
326                                0,
327                                new LeafPosition(this, 0), false));
328         }
329         returnList.add(new KnuthInlineBox(0, areaInfo.alignmentContext,
330                                     new LeafPosition(this, -1), true));
331
332         addKnuthElementsForBorderPaddingEnd(returnList);
333         
334         setFinished(true);
335         return returnList;
336     }
337
338     /** @see LeafNodeLayoutManager#addId */
339     protected void addId() {
340         getPSLM().addIDToPage(fobj.getId());
341     }
342
343     /**
344      * @see org.apache.fop.datatypes.PercentBaseContext#getBaseLength(int, FObj)
345      */

346     public int getBaseLength(int lengthBase, FObj fobj) {
347         return getParent().getBaseLength(lengthBase, getParent().getFObj());
348     }
349
350     /**
351      * Returns the IPD of the content area
352      * @return the IPD of the content area
353      */

354     public int getContentAreaIPD() {
355         return contentAreaIPD;
356     }
357    
358     private void setContentAreaIPD(int contentAreaIPD) {
359         this.contentAreaIPD = contentAreaIPD;
360     }
361     
362 }
363
Popular Tags