KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jasperreports > engine > fill > TextMeasurer


1 /*
2  * ============================================================================
3  * GNU Lesser General Public License
4  * ============================================================================
5  *
6  * JasperReports - Free Java report-generating library.
7  * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * JasperSoft Corporation
24  * 303 Second Street, Suite 450 North
25  * San Francisco, CA 94107
26  * http://www.jaspersoft.com
27  */

28 package net.sf.jasperreports.engine.fill;
29
30 import java.awt.font.FontRenderContext JavaDoc;
31 import java.awt.font.LineBreakMeasurer JavaDoc;
32 import java.awt.font.TextLayout JavaDoc;
33 import java.text.AttributedCharacterIterator JavaDoc;
34 import java.text.AttributedString JavaDoc;
35 import java.util.StringTokenizer JavaDoc;
36
37 import net.sf.jasperreports.engine.JRTextElement;
38 import net.sf.jasperreports.engine.export.TextRenderer;
39 import net.sf.jasperreports.engine.util.JRStyledText;
40 import net.sf.jasperreports.engine.util.MaxFontSizeFinder;
41
42
43 /**
44  * @author Teodor Danciu (teodord@users.sourceforge.net)
45  * @version $Id: TextMeasurer.java 1444 2006-10-24 17:04:48 +0300 (Tue, 24 Oct 2006) ionut $
46  */

47 public class TextMeasurer
48 {
49
50     /**
51      *
52      */

53     private static final FontRenderContext JavaDoc FONT_RENDER_CONTEXT = TextRenderer.LINE_BREAK_FONT_RENDER_CONTEXT;
54
55     /**
56      *
57      */

58     private JRTextElement textElement = null;
59
60
61     /**
62      *
63      */

64     private MaxFontSizeFinder maxFontSizeFinder = null;
65
66     private int width = 0;
67     private int height = 0;
68     private int topPadding = 0;
69     private int leftPadding = 0;
70     private int bottomPadding = 0;
71     private int rightPadding = 0;
72     private float lineSpacing = 0;
73
74     private float formatWidth = 0;
75     private int maxHeight = 0;
76     private int textOffset = 0;
77     private int lines = 0;
78     private int fontSizeSum = 0;
79     private int firstLineMaxFontSize = 0;
80     private float textHeight = 0;
81     private float firstLineLeading = 0;
82     private boolean isLeftToRight = true;
83     private boolean isMaxHeightReached = false;
84     
85     
86     /**
87      *
88      */

89     public TextMeasurer(JRTextElement textElement)
90     {
91         this.textElement = textElement;
92     }
93     
94     /**
95      *
96      */

97     private void initialize(int availableStretchHeight)
98     {
99         width = textElement.getWidth();
100         height = textElement.getHeight();
101         
102         topPadding = textElement.getTopPadding();
103         leftPadding = textElement.getLeftPadding();
104         bottomPadding = textElement.getBottomPadding();
105         rightPadding = textElement.getRightPadding();
106
107         switch (textElement.getRotation())
108         {
109             case JRTextElement.ROTATION_LEFT :
110             {
111                 width = textElement.getHeight();
112                 height = textElement.getWidth();
113                 int tmpPadding = topPadding;
114                 topPadding = leftPadding;
115                 leftPadding = bottomPadding;
116                 bottomPadding = rightPadding;
117                 rightPadding = tmpPadding;
118                 break;
119             }
120             case JRTextElement.ROTATION_RIGHT :
121             {
122                 width = textElement.getHeight();
123                 height = textElement.getWidth();
124                 int tmpPadding = topPadding;
125                 topPadding = rightPadding;
126                 rightPadding = bottomPadding;
127                 bottomPadding = leftPadding;
128                 leftPadding = tmpPadding;
129                 break;
130             }
131             case JRTextElement.ROTATION_UPSIDE_DOWN :
132             {
133                 int tmpPadding = topPadding;
134                 topPadding = bottomPadding;
135                 bottomPadding = tmpPadding;
136                 tmpPadding = leftPadding;
137                 leftPadding = rightPadding;
138                 rightPadding = tmpPadding;
139                 break;
140             }
141             case JRTextElement.ROTATION_NONE :
142             default :
143             {
144             }
145         }
146         
147         /* */
148         switch (textElement.getLineSpacing())
149         {
150             case JRTextElement.LINE_SPACING_SINGLE :
151             {
152                 lineSpacing = 1f;
153                 break;
154             }
155             case JRTextElement.LINE_SPACING_1_1_2 :
156             {
157                 lineSpacing = 1.5f;
158                 break;
159             }
160             case JRTextElement.LINE_SPACING_DOUBLE :
161             {
162                 lineSpacing = 2f;
163                 break;
164             }
165             default :
166             {
167                 lineSpacing = 1f;
168             }
169         }
170
171         maxFontSizeFinder = MaxFontSizeFinder.getInstance(textElement.isStyledText());
172
173         formatWidth = width - leftPadding - rightPadding;
174         formatWidth = formatWidth < 0 ? 0 : formatWidth;
175         maxHeight = height + availableStretchHeight - topPadding - bottomPadding;
176         maxHeight = maxHeight < 0 ? 0 : maxHeight;
177         textOffset = 0;
178         lines = 0;
179         fontSizeSum = 0;
180         firstLineMaxFontSize = 0;
181         textHeight = 0;
182         firstLineLeading = 0;
183         isLeftToRight = true;
184         isMaxHeightReached = false;
185     }
186
187     /**
188      *
189      */

190     public void measure(
191         JRStyledText styledText,
192         String JavaDoc remainingText,
193         int remainingTextStart,
194         int availableStretchHeight
195         )
196     {
197         /* */
198         initialize(availableStretchHeight);
199
200         AttributedCharacterIterator JavaDoc allParagraphs = styledText.getAttributedString().getIterator();
201
202         int tokenPosition = remainingTextStart;
203         int lastParagraphStart = remainingTextStart;
204         String JavaDoc lastParagraphText = null;
205
206         StringTokenizer JavaDoc tkzer = new StringTokenizer JavaDoc(remainingText, "\n", true);
207
208         while(tkzer.hasMoreTokens() && !isMaxHeightReached)
209         {
210             String JavaDoc token = tkzer.nextToken();
211
212             if ("\n".equals(token))
213             {
214                 renderParagraph(allParagraphs, lastParagraphStart, lastParagraphText);
215
216                 lastParagraphStart = tokenPosition + (tkzer.hasMoreTokens() || tokenPosition == 0 ? 1 : 0);
217                 lastParagraphText = null;
218             }
219             else
220             {
221                 lastParagraphStart = tokenPosition;
222                 lastParagraphText = token;
223             }
224
225             tokenPosition += token.length();
226         }
227
228         if (!isMaxHeightReached && lastParagraphStart < remainingTextStart + remainingText.length())
229         {
230             renderParagraph(allParagraphs, lastParagraphStart, lastParagraphText);
231         }
232     }
233
234     /**
235      *
236      */

237     private void renderParagraph(
238         AttributedCharacterIterator JavaDoc allParagraphs,
239         int lastParagraphStart,
240         String JavaDoc lastParagraphText
241         )
242     {
243         AttributedCharacterIterator JavaDoc paragraph = null;
244         
245         if (lastParagraphText == null)
246         {
247             paragraph =
248                 new AttributedString JavaDoc(
249                     " ",
250                     new AttributedString JavaDoc(
251                         allParagraphs,
252                         lastParagraphStart,
253                         lastParagraphStart + 1
254                         ).getIterator().getAttributes()
255                     ).getIterator();
256         }
257         else
258         {
259             paragraph =
260                 new AttributedString JavaDoc(
261                     allParagraphs,
262                     lastParagraphStart,
263                     lastParagraphStart + lastParagraphText.length()
264                     ).getIterator();
265         }
266
267         int positionWithinParagraph = 0;
268
269         LineBreakMeasurer JavaDoc lineMeasurer = new LineBreakMeasurer JavaDoc(paragraph, FONT_RENDER_CONTEXT);
270         
271         while (lineMeasurer.getPosition() < paragraph.getEndIndex() && !isMaxHeightReached)
272         {
273             int lineStartPosition = lineMeasurer.getPosition();
274
275             TextLayout JavaDoc layout = lineMeasurer.nextLayout(formatWidth);
276
277             isLeftToRight = isLeftToRight && layout.isLeftToRight();
278             
279             textHeight += layout.getLeading() + lineSpacing * layout.getAscent();
280             
281             if (textHeight + layout.getDescent() <= maxHeight)
282             {
283                 lines++;
284
285                 fontSizeSum +=
286                     maxFontSizeFinder.findMaxFontSize(
287                         new AttributedString JavaDoc(
288                             paragraph,
289                             lineStartPosition,
290                             lineStartPosition + layout.getCharacterCount()
291                             ).getIterator(),
292                         textElement.getFontSize()
293                         );
294                         
295                 if (lines == 1)
296                 {
297                     firstLineLeading = textHeight;
298                     firstLineMaxFontSize = fontSizeSum;
299                 }
300
301                 positionWithinParagraph = lineMeasurer.getPosition();
302                 // here is the Y offset where we would draw the line
303
//lastDrawPosY = drawPosY;
304
//
305
textHeight += layout.getDescent();
306             }
307             else
308             {
309                 textHeight -= layout.getLeading() + lineSpacing * layout.getAscent();
310                 isMaxHeightReached = true;
311             }
312         }
313         
314         textOffset = lastParagraphStart + positionWithinParagraph;//(lastParagraphText == null ? 0 : positionWithinParagraph);
315
}
316     
317     
318     /**
319      *
320      */

321     protected boolean isLeftToRight()
322     {
323         return isLeftToRight;
324     }
325     
326     /**
327      *
328      */

329     protected int getTextOffset()
330     {
331         return textOffset;
332     }
333     
334     /**
335      *
336      */

337     public float getTextHeight()
338     {
339         return textHeight;
340     }
341     
342     /**
343      *
344      */

345     public float getLineSpacingFactor()
346     {
347         if (lines > 0)
348         {
349             return textHeight / fontSizeSum;
350         }
351         return 0;
352     }
353     
354     /**
355      *
356      */

357     public float getLeadingOffset()
358     {
359         return firstLineLeading - firstLineMaxFontSize * getLineSpacingFactor();
360     }
361     
362 }
363
Popular Tags