KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > pdmodel > font > PDSimpleFont


1 /**
2  * Copyright (c) 2003-2006, www.pdfbox.org
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * 3. Neither the name of pdfbox; nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * http://www.pdfbox.org
29  *
30  */

31 package org.pdfbox.pdmodel.font;
32
33 import java.awt.Graphics JavaDoc;
34
35 import java.io.IOException JavaDoc;
36
37 import java.util.HashMap JavaDoc;
38
39 import org.fontbox.afm.FontMetric;
40
41 import org.pdfbox.cos.COSArray;
42 import org.pdfbox.cos.COSDictionary;
43 import org.pdfbox.cos.COSName;
44 import org.pdfbox.cos.COSNumber;
45 import org.pdfbox.cos.COSInteger;
46 import org.pdfbox.encoding.Encoding;
47
48 import org.pdfbox.pdmodel.common.PDRectangle;
49 import org.pdfbox.pdmodel.common.PDStream;
50
51 /**
52  * This class contains implementation details of the simple pdf fonts.
53  *
54  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
55  * @version $Revision: 1.17 $
56  */

57 public abstract class PDSimpleFont extends PDFont
58 {
59     private HashMap JavaDoc mFontSizes = new HashMap JavaDoc(128);
60     private float avgFontWidth = 0.0f;
61     
62     /**
63      * Constructor.
64      */

65     public PDSimpleFont()
66     {
67         super();
68     }
69
70     /**
71      * Constructor.
72      *
73      * @param fontDictionary The font dictionary according to the PDF specification.
74      */

75     public PDSimpleFont( COSDictionary fontDictionary )
76     {
77         super( fontDictionary );
78     }
79
80     /**
81      * {@inheritDoc}
82      */

83     public void drawString( String JavaDoc string, Graphics JavaDoc g, float fontSize,
84         float xScale, float yScale, float x, float y ) throws IOException JavaDoc
85     {
86         System.err.println( "Not yet implemented:" + getClass().getName() );
87     }
88     
89     /**
90      * This will get the font width for a character.
91      *
92      * @param c The character code to get the width for.
93      * @param offset The offset into the array.
94      * @param length The length of the data.
95      *
96      * @return The width is in 1000 unit of text space, ie 333 or 777
97      *
98      * @throws IOException If an error occurs while parsing.
99      */

100     public float getFontHeight( byte[] c, int offset, int length ) throws IOException JavaDoc
101     {
102         float retval = 0;
103         int code = getCodeFromArray( c, offset, length );
104         FontMetric metric = getAFM();
105         if( metric != null )
106         {
107             Encoding encoding = getEncoding();
108             COSName characterName = encoding.getName( code );
109             retval = metric.getCharacterHeight( characterName.getName() );
110         }
111         else
112         {
113             PDFontDescriptor desc = getFontDescriptor();
114             if( desc != null )
115             {
116                 float xHeight = desc.getXHeight();
117                 float capHeight = desc.getCapHeight();
118                 if( xHeight != 0f && capHeight != 0 )
119                 {
120                     //do an average of these two. Can we do better???
121
retval = (xHeight + capHeight)/2f;
122                 }
123                 else if( xHeight != 0 )
124                 {
125                     retval = xHeight;
126                 }
127                 else if( capHeight != 0 )
128                 {
129                     retval = capHeight;
130                 }
131                 else
132                 {
133                     retval = 0;
134                 }
135             }
136         }
137         return retval;
138     }
139
140     /**
141      * This will get the font width for a character.
142      *
143      * @param c The character code to get the width for.
144      * @param offset The offset into the array.
145      * @param length The length of the data.
146      *
147      * @return The width is in 1000 unit of text space, ie 333 or 777
148      *
149      * @throws IOException If an error occurs while parsing.
150      */

151     public float getFontWidth( byte[] c, int offset, int length ) throws IOException JavaDoc
152     {
153         float fontWidth = 0;
154         int code = getCodeFromArray( c, offset, length );
155
156         Integer JavaDoc codeI = new Integer JavaDoc(code);
157         if (mFontSizes.containsKey(codeI))
158         {
159             Float JavaDoc fontWidthF = (Float JavaDoc) mFontSizes.get(codeI);
160             fontWidth = fontWidthF.floatValue();
161         }
162         else
163         {
164             //hmm should this be in a subclass??
165
COSInteger firstChar = (COSInteger)font.getDictionaryObject( COSName.FIRST_CHAR );
166             COSInteger lastChar = (COSInteger)font.getDictionaryObject( COSName.LAST_CHAR );
167             if( firstChar != null && lastChar != null )
168             {
169                 long first = firstChar.intValue();
170                 long last = lastChar.intValue();
171                 if( code >= first && code <= last && font.getDictionaryObject( COSName.WIDTHS ) != null )
172                 {
173                     COSArray widthArray = (COSArray)font.getDictionaryObject( COSName.WIDTHS );
174                     COSNumber fontWidthObject = (COSNumber)widthArray.getObject( (int)(code - first) );
175                     fontWidth = fontWidthObject.floatValue();
176                 }
177                 else
178                 {
179                     fontWidth = getFontWidthFromAFMFile( code );
180                 }
181             }
182             else
183             {
184                 fontWidth = getFontWidthFromAFMFile( code );
185             }
186             mFontSizes.put(codeI, new Float JavaDoc(fontWidth));
187         }
188         return fontWidth;
189     }
190
191     /**
192      * This will get the average font width for all characters.
193      *
194      * @return The width is in 1000 unit of text space, ie 333 or 777
195      *
196      * @throws IOException If an error occurs while parsing.
197      */

198     public float getAverageFontWidth() throws IOException JavaDoc
199     {
200         float average = 0.0f;
201
202         //AJW
203
if (avgFontWidth != 0.0f)
204         {
205             average = avgFontWidth;
206         }
207         else
208         {
209             float totalWidth = 0.0f;
210             float characterCount = 0.0f;
211             COSArray widths = (COSArray)font.getDictionaryObject( COSName.WIDTHS );
212             if( widths != null )
213             {
214                 for( int i=0; i<widths.size(); i++ )
215                 {
216                     COSNumber fontWidth = (COSNumber)widths.getObject( i );
217                     if( fontWidth.floatValue() > 0 )
218                     {
219                         totalWidth += fontWidth.floatValue();
220                         characterCount += 1;
221                     }
222                 }
223             }
224
225             if( totalWidth > 0 )
226             {
227                 average = totalWidth / characterCount;
228             }
229             else
230             {
231                 average = getAverageFontWidthFromAFMFile();
232             }
233             avgFontWidth = average;
234         }
235         return average;
236     }
237
238     /**
239      * This will get the font descriptor for this font.
240      *
241      * @return The font descriptor for this font.
242      *
243      * @throws IOException If there is an error parsing an AFM file, or unable to
244      * create a PDFontDescriptor object.
245      */

246     public PDFontDescriptor getFontDescriptor() throws IOException JavaDoc
247     {
248         PDFontDescriptor retval = null;
249         COSDictionary fd = (COSDictionary)font.getDictionaryObject( COSName.getPDFName( "FontDescriptor" ) );
250         if( fd == null )
251         {
252             FontMetric afm = getAFM();
253             if( afm != null )
254             {
255                 retval = new PDFontDescriptorAFM( afm );
256             }
257         }
258         else
259         {
260             retval = new PDFontDescriptorDictionary( fd );
261         }
262
263         return retval;
264     }
265
266     /**
267      * This will set the font descriptor.
268      *
269      * @param fontDescriptor The font descriptor.
270      */

271     public void setFontDescriptor( PDFontDescriptorDictionary fontDescriptor )
272     {
273         COSDictionary dic = null;
274         if( fontDescriptor != null )
275         {
276             dic = fontDescriptor.getCOSDictionary();
277         }
278         font.setItem( COSName.getPDFName( "FontDescriptor" ), dic );
279     }
280     
281     /**
282      * This will get the ToUnicode stream.
283      *
284      * @return The ToUnicode stream.
285      * @throws IOException If there is an error getting the stream.
286      */

287     public PDStream getToUnicode() throws IOException JavaDoc
288     {
289         return PDStream.createFromCOS( font.getDictionaryObject( "ToUnicode" ) );
290     }
291     
292     /**
293      * This will set the ToUnicode stream.
294      *
295      * @param unicode The unicode stream.
296      */

297     public void setToUnicode( PDStream unicode )
298     {
299         font.setItem( "ToUnicode", unicode );
300     }
301     
302     /**
303      * This will get the fonts bounding box.
304      *
305      * @return The fonts bouding box.
306      *
307      * @throws IOException If there is an error getting the bounding box.
308      */

309     public PDRectangle getFontBoundingBox() throws IOException JavaDoc
310     {
311         return getFontDescriptor().getFontBoundingBox();
312     }
313 }
Popular Tags