KickJava   Java API By Example, From Geeks To Geeks.

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


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: CharacterLayoutManager.java 426576 2006-07-28 15:44:37Z jeremias $ */
19
20 package org.apache.fop.layoutmgr.inline;
21
22 import org.apache.fop.fo.flow.Character;
23 import org.apache.fop.fonts.Font;
24 import org.apache.fop.layoutmgr.InlineKnuthSequence;
25 import org.apache.fop.layoutmgr.KnuthElement;
26 import org.apache.fop.layoutmgr.KnuthGlue;
27 import org.apache.fop.layoutmgr.KnuthPenalty;
28 import org.apache.fop.layoutmgr.KnuthSequence;
29 import org.apache.fop.layoutmgr.LayoutContext;
30 import org.apache.fop.layoutmgr.LeafPosition;
31 import org.apache.fop.layoutmgr.Position;
32 import org.apache.fop.layoutmgr.TraitSetter;
33 import org.apache.fop.area.Trait;
34 import org.apache.fop.traits.MinOptMax;
35 import org.apache.fop.traits.SpaceVal;
36 import org.apache.fop.util.CharUtilities;
37
38 import java.util.List JavaDoc;
39 import java.util.LinkedList JavaDoc;
40 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
41 import org.apache.fop.layoutmgr.inline.AlignmentContext;
42
43 /**
44  * LayoutManager for the fo:character formatting object
45  */

46 public class CharacterLayoutManager extends LeafNodeLayoutManager {
47     private Character JavaDoc fobj;
48     private MinOptMax letterSpaceIPD;
49     private int hyphIPD;
50     private Font font;
51     private CommonBorderPaddingBackground borderProps = null;
52
53     /**
54      * Constructor
55      *
56      * @param node the fo:character formatting object
57      */

58     public CharacterLayoutManager(Character JavaDoc node) {
59         // @todo better null checking of node
60
super(node);
61         fobj = node;
62     }
63     
64     /** @see org.apache.fop.layoutmgr.LayoutManager#initialize */
65     public void initialize() {
66         font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
67         SpaceVal ls = SpaceVal.makeLetterSpacing(fobj.getLetterSpacing());
68         letterSpaceIPD = ls.getSpace();
69         hyphIPD = font.getCharWidth(fobj.getCommonHyphenation().hyphenationCharacter);
70         borderProps = fobj.getCommonBorderPaddingBackground();
71         setCommonBorderPaddingBackground(borderProps);
72         org.apache.fop.area.inline.TextArea chArea = getCharacterInlineArea(fobj);
73         chArea.setBaselineOffset(font.getAscender());
74         setCurrentArea(chArea);
75     }
76
77     private org.apache.fop.area.inline.TextArea getCharacterInlineArea(Character JavaDoc node) {
78         org.apache.fop.area.inline.TextArea text
79             = new org.apache.fop.area.inline.TextArea();
80         char ch = node.getCharacter();
81         if (CharUtilities.isAnySpace(ch)) {
82             text.addSpace(ch, 0, CharUtilities.isAdjustableSpace(ch));
83         } else {
84             text.addWord(String.valueOf(ch), 0);
85         }
86         TraitSetter.setProducerID(text, node.getId());
87         TraitSetter.addTextDecoration(text, fobj.getTextDecoration());
88         return text;
89     }
90
91     /** @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(LayoutContext, int) */
92     public LinkedList JavaDoc getNextKnuthElements(LayoutContext context, int alignment) {
93         MinOptMax ipd;
94         curArea = get(context);
95         KnuthSequence seq = new InlineKnuthSequence();
96
97         if (curArea == null) {
98             setFinished(true);
99             return null;
100         }
101
102         ipd = new MinOptMax(font.getCharWidth(fobj.getCharacter()));
103
104         curArea.setIPD(ipd.opt);
105         curArea.setBPD(font.getAscender() - font.getDescender());
106
107         TraitSetter.addFontTraits(curArea, font);
108         curArea.addTrait(Trait.COLOR, fobj.getColor());
109
110         // TODO: may need some special handling for fo:character
111
alignmentContext = new AlignmentContext(font
112                                     , font.getFontSize()
113                                     , fobj.getAlignmentAdjust()
114                                     , fobj.getAlignmentBaseline()
115                                     , fobj.getBaselineShift()
116                                     , fobj.getDominantBaseline()
117                                     , context.getAlignmentContext());
118
119         addKnuthElementsForBorderPaddingStart(seq);
120         
121         // create the AreaInfo object to store the computed values
122
areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext);
123
124         // node is a fo:Character
125
if (letterSpaceIPD.min == letterSpaceIPD.max) {
126             // constant letter space, only return a box
127
seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
128                                         notifyPos(new LeafPosition(this, 0)), false));
129         } else {
130             // adjustable letter space, return a sequence of elements;
131
// at the moment the character is supposed to have no letter spaces,
132
// but returning this sequence allows us to change only one element
133
// if addALetterSpaceTo() is called
134
seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
135                                         notifyPos(new LeafPosition(this, 0)), false));
136             seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
137                                             new LeafPosition(this, -1), true));
138             seq.add(new KnuthGlue(0, 0, 0,
139                                          new LeafPosition(this, -1), true));
140             seq.add(new KnuthInlineBox(0, null,
141                                         notifyPos(new LeafPosition(this, -1)), true));
142         }
143
144         addKnuthElementsForBorderPaddingEnd(seq);
145
146         LinkedList JavaDoc returnList = new LinkedList JavaDoc();
147         returnList.add(seq);
148         setFinished(true);
149         return returnList;
150     }
151
152     /** @see InlineLevelLayoutManager#getWordChars(StringBuffer, Position) */
153     public void getWordChars(StringBuffer JavaDoc sbChars, Position bp) {
154         sbChars.append
155             (((org.apache.fop.area.inline.TextArea) curArea).getText());
156     }
157
158     /** @see InlineLevelLayoutManager#hyphenate(Position, HyphContext) */
159     public void hyphenate(Position pos, HyphContext hc) {
160         if (hc.getNextHyphPoint() == 1) {
161             // the character ends a syllable
162
areaInfo.bHyphenated = true;
163             isSomethingChanged = true;
164         } else {
165             // hc.getNextHyphPoint() returned -1 (no more hyphenation points)
166
// or a number > 1;
167
// the character does not end a syllable
168
}
169         hc.updateOffset(1);
170     }
171
172     /** @see InlineLevelLayoutManager#applyChanges(List) */
173     public boolean applyChanges(List JavaDoc oldList) {
174         setFinished(false);
175         if (isSomethingChanged) {
176             // there is nothing to do,
177
// possible changes have already been applied
178
// in the hyphenate() method
179
return true;
180         } else {
181             return false;
182         }
183     }
184
185     /** @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(List, int) */
186     public LinkedList JavaDoc getChangedKnuthElements(List JavaDoc oldList, int alignment) {
187         if (isFinished()) {
188             return null;
189         }
190
191         LinkedList JavaDoc returnList = new LinkedList JavaDoc();
192
193         addKnuthElementsForBorderPaddingStart(returnList);
194
195         if (letterSpaceIPD.min == letterSpaceIPD.max
196             || areaInfo.iLScount == 0) {
197             // constant letter space, or no letter space
198
returnList.add(new KnuthInlineBox(areaInfo.ipdArea.opt,
199                                         areaInfo.alignmentContext,
200                                         notifyPos(new LeafPosition(this, 0)), false));
201             if (areaInfo.bHyphenated) {
202                 returnList.add
203                     (new KnuthPenalty(hyphIPD, KnuthPenalty.FLAGGED_PENALTY, true,
204                                       new LeafPosition(this, -1), false));
205             }
206         } else {
207             // adjustable letter space
208
returnList.add
209                 (new KnuthInlineBox(areaInfo.ipdArea.opt
210                               - areaInfo.iLScount * letterSpaceIPD.opt,
211                               areaInfo.alignmentContext,
212                               notifyPos(new LeafPosition(this, 0)), false));
213             returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
214                                             new LeafPosition(this, -1), true));
215             returnList.add
216                 (new KnuthGlue(areaInfo.iLScount * letterSpaceIPD.opt,
217                                areaInfo.iLScount * letterSpaceIPD.max - letterSpaceIPD.opt,
218                                areaInfo.iLScount * letterSpaceIPD.opt - letterSpaceIPD.min,
219                                new LeafPosition(this, -1), true));
220             returnList.add(new KnuthInlineBox(0, null,
221                                         notifyPos(new LeafPosition(this, -1)), true));
222             if (areaInfo.bHyphenated) {
223                 returnList.add
224                     (new KnuthPenalty(hyphIPD, KnuthPenalty.FLAGGED_PENALTY, true,
225                                       new LeafPosition(this, -1), false));
226             }
227         }
228
229         addKnuthElementsForBorderPaddingEnd(returnList);
230
231         setFinished(true);
232         return returnList;
233     }
234
235     /** @see LeafNodeLayoutManager#addId */
236     protected void addId() {
237         getPSLM().addIDToPage(fobj.getId());
238     }
239
240 }
241
242
Popular Tags