KickJava   Java API By Example, From Geeks To Geeks.

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


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 import java.util.Map JavaDoc;
39
40 import org.pdfbox.cos.COSArray;
41 import org.pdfbox.cos.COSBase;
42 import org.pdfbox.cos.COSDictionary;
43 import org.pdfbox.cos.COSInteger;
44 import org.pdfbox.cos.COSName;
45 import org.pdfbox.cos.COSNumber;
46 import org.pdfbox.pdmodel.common.PDRectangle;
47
48 /**
49  * This is implementation for the CIDFontType0/CIDFontType2 Fonts.
50  *
51  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
52  * @version $Revision: 1.10 $
53  */

54 public abstract class PDCIDFont extends PDFont
55 {
56     private Map JavaDoc widthCache = new HashMap JavaDoc();
57
58     /**
59      * Constructor.
60      */

61     public PDCIDFont()
62     {
63         super();
64     }
65
66     /**
67      * Constructor.
68      *
69      * @param fontDictionary The font dictionary according to the PDF specification.
70      */

71     public PDCIDFont( COSDictionary fontDictionary )
72     {
73         super( fontDictionary );
74     }
75     
76     /**
77      * Get the font descriptor associated with this CID font.
78      *
79      * @return The font descriptor.
80      */

81     public PDFontDescriptor getFontDescriptor()
82     {
83         PDFontDescriptor desc = null;
84         COSDictionary dict = (COSDictionary)font.getDictionaryObject( "FontDescriptor" );
85         if( dict != null )
86         {
87             desc = new PDFontDescriptorDictionary( dict );
88         }
89         return desc;
90     }
91     
92     /**
93      * Set the font descriptor associated with this CID Font.
94      *
95      * @param desc The font descriptor.
96      */

97     public void setFontDescriptor( PDFontDescriptorDictionary desc )
98     {
99         font.setItem( "FontDescriptor", desc );
100     }
101
102     /**
103      * {@inheritDoc}
104      */

105     public void drawString( String JavaDoc string, Graphics JavaDoc g, float fontSize,
106         float xScale, float yScale, float x, float y )
107     {
108         throw new RuntimeException JavaDoc( "Not yet implemented" );
109     }
110     
111     /**
112      * This will get the fonts bouding box.
113      *
114      * @return The fonts bouding box.
115      *
116      * @throws IOException If there is an error getting the font bounding box.
117      */

118     public PDRectangle getFontBoundingBox() throws IOException JavaDoc
119     {
120         throw new RuntimeException JavaDoc( "Not yet implemented" );
121     }
122
123     /**
124      * This will get the default width. The default value for the default width is 1000.
125      *
126      * @return The default width for the glyphs in this font.
127      */

128     public long getDefaultWidth()
129     {
130         long dw = 1000;
131         COSNumber number = (COSNumber)font.getDictionaryObject( COSName.getPDFName( "DW" ) );
132         if( number != null )
133         {
134             dw = number.intValue();
135         }
136         return dw;
137     }
138
139     /**
140      * This will set the default width for the glyphs of this font.
141      *
142      * @param dw The default width.
143      */

144     public void setDefaultWidth( long dw )
145     {
146         font.setItem( COSName.getPDFName( "DW" ), new COSInteger( dw ) );
147     }
148
149     /**
150      * This will get the font width for a character.
151      *
152      * @param c The character code to get the width for.
153      * @param offset The offset into the array.
154      * @param length The length of the data.
155      *
156      * @return The width is in 1000 unit of text space, ie 333 or 777
157      *
158      * @throws IOException If an error occurs while parsing.
159      */

160     public float getFontWidth( byte[] c, int offset, int length ) throws IOException JavaDoc
161     {
162
163         float retval = 0.0f;
164         int code = getCodeFromArray( c, offset, length );
165
166         Float JavaDoc widthFloat = (Float JavaDoc)widthCache.get( new Integer JavaDoc( code ) );
167         if( widthFloat == null )
168         {
169             COSArray widths = (COSArray)font.getDictionaryObject( COSName.getPDFName( "W" ) );
170
171             if( widths != null )
172             {
173                 boolean foundWidth = false;
174                 for( int i=0; !foundWidth && i<widths.size(); i++ )
175                 {
176                     COSNumber firstCode = (COSNumber)widths.getObject( i++ );
177                     COSBase next = widths.getObject( i );
178                     if( next instanceof COSArray )
179                     {
180                         COSArray array = (COSArray)next;
181                         if( code >= firstCode.intValue() &&
182                             code < firstCode.intValue() + array.size() )
183                         {
184                             COSNumber rangeWidth =
185                                 (COSNumber)array.get( code - firstCode.intValue() );
186                             retval = rangeWidth.floatValue();
187                             foundWidth = true;
188                         }
189                     }
190                     else
191                     {
192                         COSNumber secondCode = (COSNumber)next;
193                         i++;
194                         COSNumber rangeWidth = (COSNumber)widths.getObject( i );
195                         if( code >= firstCode.intValue() &&
196                             code <= secondCode.intValue() )
197                         {
198                             retval = rangeWidth.floatValue();
199                             foundWidth = true;
200                         }
201                     }
202                 }
203                 widthCache.put( new Integer JavaDoc( code ), new Float JavaDoc( retval ) );
204             }
205         }
206         else
207         {
208             retval = widthFloat.floatValue();
209         }
210         return retval;
211     }
212     
213     /**
214      * This will get the font height for a character.
215      *
216      * @param c The character code to get the height for.
217      * @param offset The offset into the array.
218      * @param length The length of the data.
219      *
220      * @return The width is in 1000 unit of text space, ie 333 or 777
221      *
222      * @throws IOException If an error occurs while parsing.
223      */

224     public float getFontHeight( byte[] c, int offset, int length ) throws IOException JavaDoc
225     {
226         float retval = 0;
227         PDFontDescriptor desc = getFontDescriptor();
228         float xHeight = desc.getXHeight();
229         float capHeight = desc.getCapHeight();
230         if( xHeight != 0f && capHeight != 0 )
231         {
232             //do an average of these two. Can we do better???
233
retval = (xHeight + capHeight)/2f;
234         }
235         else if( xHeight != 0 )
236         {
237             retval = xHeight;
238         }
239         else if( capHeight != 0 )
240         {
241             retval = capHeight;
242         }
243         else
244         {
245             retval = 0;
246         }
247         return retval;
248     }
249
250     /**
251      * This will get the average font width for all characters.
252      *
253      * @return The width is in 1000 unit of text space, ie 333 or 777
254      *
255      * @throws IOException If an error occurs while parsing.
256      */

257     public float getAverageFontWidth() throws IOException JavaDoc
258     {
259         float totalWidths = 0.0f;
260         float characterCount = 0.0f;
261         float defaultWidth = getDefaultWidth();
262         COSArray widths = (COSArray)font.getDictionaryObject( COSName.getPDFName( "W" ) );
263
264         if( widths != null )
265         {
266             for( int i=0; i<widths.size(); i++ )
267             {
268                 COSNumber firstCode = (COSNumber)widths.getObject( i++ );
269                 COSBase next = widths.getObject( i );
270                 if( next instanceof COSArray )
271                 {
272                     COSArray array = (COSArray)next;
273                     for( int j=0; j<array.size(); j++ )
274                     {
275                         COSNumber width = (COSNumber)array.get( j );
276                         totalWidths+=width.floatValue();
277                         characterCount += 1;
278                     }
279                 }
280                 else
281                 {
282                     i++;
283                     COSNumber rangeWidth = (COSNumber)widths.getObject( i );
284                     if( rangeWidth.floatValue() > 0 )
285                     {
286                         totalWidths += rangeWidth.floatValue();
287                         characterCount += 1;
288                     }
289                 }
290             }
291         }
292         float average = totalWidths / characterCount;
293         if( average <= 0 )
294         {
295             average = defaultWidth;
296         }
297         return average;
298     }
299 }
Popular Tags