KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > it > stefanochizzolini > clown > documents > contents > composition > TextFitter


1 /*
2   Copyright © 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
3
4   Contributors:
5     * Stefano Chizzolini (original code developer, info@stefanochizzolini.it):
6       contributed code is Copyright © 2007 by Stefano Chizzolini.
7
8   This file should be part of the source code distribution of "PDF Clown library"
9   (the Program): see the accompanying README files for more info.
10
11   This Program is free software; you can redistribute it and/or modify it under
12   the terms of the GNU General Public License as published by the Free Software
13   Foundation; either version 2 of the License, or (at your option) any later version.
14
15   This Program is distributed in the hope that it will be useful, but WITHOUT ANY
16   WARRANTY, either expressed or implied; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
18
19   You should have received a copy of the GNU General Public License along with this
20   Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
21
22   Redistribution and use, with or without modification, are permitted provided that such
23   redistributions retain the above copyright notice, license and disclaimer, along with
24   this list of conditions.
25 */

26
27 package it.stefanochizzolini.clown.documents.contents.composition;
28
29 import it.stefanochizzolini.clown.documents.contents.fonts.Font;
30
31 /**
32   Text fitter.
33
34   @author Stefano Chizzolini
35   @version 0.0.3.42, 04/30/07
36   @since 0.0.3
37 */

38 final class TextFitter
39 {
40   // <class>
41
// <dynamic>
42
// <fields>
43
private Font font;
44   private double fontSize;
45   private boolean hyphenation;
46   private String JavaDoc text;
47   private double width;
48
49   private int beginIndex = 0;
50   private int endIndex = -1;
51   private String JavaDoc fittedText;
52   private double fittedWidth;
53   // </fields>
54

55   // <constructors>
56
TextFitter(
57     String JavaDoc text,
58     double width,
59     Font font,
60     double fontSize,
61     boolean hyphenation
62     )
63   {
64     this.text = text;
65     this.width = width;
66     this.font = font;
67     this.fontSize = fontSize;
68     this.hyphenation = hyphenation;
69   }
70   // </constructors>
71

72   // <interface>
73
// <public>
74
/**
75     Fits the text inside the specified width.
76     @return Whether the operation was successful.
77   */

78   public boolean fit(
79     )
80   {
81     return fit(
82       endIndex + 1,
83       width
84       );
85     }
86
87   /**
88     Fits the text inside the specified width.
89     @param index Beginning index, inclusive.
90     @param width Available width.
91     @return Whether the operation was successful.
92   */

93   public boolean fit(
94     int index,
95     double width
96     )
97   {
98     beginIndex = index;
99     this.width = width;
100     fittedText = null;
101     fittedWidth = 0;
102
103     while(true)
104     {
105       // Find the limit of the current word!
106
int foundIndex = text.indexOf(' ',index + 1);
107       if(foundIndex == -1)
108       {foundIndex = text.length();}
109
110       // Add the current word!
111
double wordWidth = font.getKernedWidth(
112         text.substring(index,foundIndex),
113         fontSize
114         ); // Current word's width.
115
fittedWidth += wordWidth;
116       // Does the fitted text's width exceed the available width?
117
if(fittedWidth > width)
118       {
119         // Remove the current word!
120
fittedWidth -= wordWidth;
121         foundIndex = index;
122         if(foundIndex == 0)
123           break;
124         if(!hyphenation)
125         {
126           fittedText = text.substring(beginIndex,index);
127           break;
128         }
129
130         /*
131           NOTE: We need to hyphenate the current (unfitting) word.
132         */

133         /*
134           TODO: This hyphenation algorithm is quite primitive (to improve!).
135         */

136         while(true)
137         {
138           // Add the current character!
139
char textChar = text.charAt(foundIndex); // Current character.
140
wordWidth = (font.getKerning(text.charAt(foundIndex - 1),textChar) + font.getWidth(textChar)) * font.getScalingFactor(fontSize); // Current character's width.
141
foundIndex++;
142           fittedWidth += wordWidth;
143           // Does the fitted text's width exceed the available width?
144
if(fittedWidth > width)
145           {
146             // Remove the current character!
147
fittedWidth -= wordWidth;
148             foundIndex--;
149             // Is hyphenation to be applied?
150
if(foundIndex > index + 4) // Long-enough word chunk.
151
{
152               // Make room for the hyphen character!
153
foundIndex--;
154               index = foundIndex;
155               textChar = text.charAt(foundIndex);
156               fittedWidth -= (font.getKerning(text.charAt(foundIndex - 1),textChar) + font.getWidth(textChar)) * font.getScalingFactor(fontSize);
157
158               // Add the hyphen character!
159
textChar = '-'; // hyphen.
160
fittedWidth += (font.getKerning(text.charAt(foundIndex - 1),textChar) + font.getWidth(textChar)) * font.getScalingFactor(fontSize);
161
162               fittedText = text.substring(beginIndex,index) + textChar;
163             }
164             else // No hyphenation.
165
{
166               // Removing the current word chunk...
167
while(foundIndex > index)
168               {
169                 foundIndex--;
170                 textChar = text.charAt(foundIndex);
171                 fittedWidth -= (font.getKerning(text.charAt(foundIndex - 1),textChar) + font.getWidth(textChar)) * font.getScalingFactor(fontSize);
172               }
173
174               fittedText = text.substring(beginIndex,index);
175             }
176             break;
177           }
178         }
179         break;
180       }
181
182       index = foundIndex;
183       if(index == text.length())
184       {
185         fittedText = text.substring(beginIndex,index);
186         break;
187       }
188     }
189
190     endIndex = index;
191
192     return (fittedWidth > 0);
193   }
194
195   /**
196     Gets the begin index of the fitted text inside the available text.
197   */

198   public int getBeginIndex(
199     )
200   {return beginIndex;}
201
202   /**
203     Gets the end index of the fitted text inside the available text.
204   */

205   public int getEndIndex(
206     )
207   {return endIndex;}
208
209   /**
210     Gets the fitted text.
211   */

212   public String JavaDoc getFittedText(
213     )
214   {return fittedText;}
215
216   /**
217     Gets the fitted text's width.
218   */

219   public double getFittedWidth(
220     )
221   {return fittedWidth;}
222
223   /**
224     Gets the font used to fit the text.
225   */

226   public Font getFont(
227     )
228   {return font;}
229
230   /**
231     Gets the size of the font used to fit the text.
232   */

233   public double getFontSize(
234     )
235   {return fontSize;}
236
237   /**
238     Gets whether the hyphenation algorithm has to be applied.
239   */

240   public boolean getHyphenation(
241     )
242   {return hyphenation;}
243
244   /**
245     Gets the available text.
246   */

247   public String JavaDoc getText(
248     )
249   {return text;}
250
251   /**
252     Gets the available width.
253   */

254   public double getWidth(
255     )
256   {return width;}
257   // </public>
258
// </interface>
259
// </dynamic>
260
// </class>
261
}
Popular Tags