1 /*
2 * $Id: FontFactoryImp.java 3548 2008-07-12 11:15:35Z blowagie $
3 *
4 * Copyright 2002 by Bruno Lowagie.
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * (the "License"); you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the License.
13 *
14 * The Original Code is 'iText, a free JAVA-PDF library'.
15 *
16 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18 * All Rights Reserved.
19 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21 *
22 * Contributor(s): all the names of the contributors are added in the source code
23 * where applicable.
24 *
25 * Alternatively, the contents of this file may be used under the terms of the
26 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27 * provisions of LGPL are applicable instead of those above. If you wish to
28 * allow use of your version of this file only under the terms of the LGPL
29 * License and not to allow others to use your version of this file under
30 * the MPL, indicate your decision by deleting the provisions above and
31 * replace them with the notice and other provisions required by the LGPL.
32 * If you do not delete the provisions above, a recipient may use your version
33 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34 *
35 * This library is free software; you can redistribute it and/or modify it
36 * under the terms of the MPL as stated above or under the terms of the GNU
37 * Library General Public License as published by the Free Software Foundation;
38 * either version 2 of the License, or any later version.
39 *
40 * This library is distributed in the hope that it will be useful, but WITHOUT
41 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43 * details.
44 *
45 * If you didn't download this code from the following link, you should check if
46 * you aren't using an obsolete version:
47 * http://www.lowagie.com/iText/
48 */
49
50 package com.lowagie.text;
51
52 import java.awt.Color;
53 import java.io.File;
54 import java.io.IOException;
55 import java.util.ArrayList;
56 import java.util.Enumeration;
57 import java.util.Hashtable;
58 import java.util.Iterator;
59 import java.util.Properties;
60 import java.util.Set;
61
62 import com.lowagie.text.html.Markup;
63 import com.lowagie.text.pdf.BaseFont;
64
65 /**
66 * If you are using True Type fonts, you can declare the paths of the different ttf- and ttc-files
67 * to this class first and then create fonts in your code using one of the getFont method
68 * without having to enter a path as parameter.
69 *
70 * @author Bruno Lowagie
71 */
72
73 public class FontFactoryImp {
74
75 /** This is a map of postscriptfontnames of True Type fonts and the path of their ttf- or ttc-file. */
76 private Properties trueTypeFonts = new Properties();
77
78 private static String[] TTFamilyOrder = {
79 "3", "1", "1033",
80 "3", "0", "1033",
81 "1", "0", "0",
82 "0", "3", "0"
83 };
84
85 /** This is a map of fontfamilies. */
86 private Hashtable fontFamilies = new Hashtable();
87
88 /** This is the default encoding to use. */
89 public String defaultEncoding = BaseFont.WINANSI;
90
91 /** This is the default value of the <VAR>embedded</VAR> variable. */
92 public boolean defaultEmbedding = BaseFont.NOT_EMBEDDED;
93
94 /** Creates new FontFactory */
95 public FontFactoryImp() {
96 trueTypeFonts.setProperty(FontFactory.COURIER.toLowerCase(), FontFactory.COURIER);
97 trueTypeFonts.setProperty(FontFactory.COURIER_BOLD.toLowerCase(), FontFactory.COURIER_BOLD);
98 trueTypeFonts.setProperty(FontFactory.COURIER_OBLIQUE.toLowerCase(), FontFactory.COURIER_OBLIQUE);
99 trueTypeFonts.setProperty(FontFactory.COURIER_BOLDOBLIQUE.toLowerCase(), FontFactory.COURIER_BOLDOBLIQUE);
100 trueTypeFonts.setProperty(FontFactory.HELVETICA.toLowerCase(), FontFactory.HELVETICA);
101 trueTypeFonts.setProperty(FontFactory.HELVETICA_BOLD.toLowerCase(), FontFactory.HELVETICA_BOLD);
102 trueTypeFonts.setProperty(FontFactory.HELVETICA_OBLIQUE.toLowerCase(), FontFactory.HELVETICA_OBLIQUE);
103 trueTypeFonts.setProperty(FontFactory.HELVETICA_BOLDOBLIQUE.toLowerCase(), FontFactory.HELVETICA_BOLDOBLIQUE);
104 trueTypeFonts.setProperty(FontFactory.SYMBOL.toLowerCase(), FontFactory.SYMBOL);
105 trueTypeFonts.setProperty(FontFactory.TIMES_ROMAN.toLowerCase(), FontFactory.TIMES_ROMAN);
106 trueTypeFonts.setProperty(FontFactory.TIMES_BOLD.toLowerCase(), FontFactory.TIMES_BOLD);
107 trueTypeFonts.setProperty(FontFactory.TIMES_ITALIC.toLowerCase(), FontFactory.TIMES_ITALIC);
108 trueTypeFonts.setProperty(FontFactory.TIMES_BOLDITALIC.toLowerCase(), FontFactory.TIMES_BOLDITALIC);
109 trueTypeFonts.setProperty(FontFactory.ZAPFDINGBATS.toLowerCase(), FontFactory.ZAPFDINGBATS);
110
111 ArrayList tmp;
112 tmp = new ArrayList();
113 tmp.add(FontFactory.COURIER);
114 tmp.add(FontFactory.COURIER_BOLD);
115 tmp.add(FontFactory.COURIER_OBLIQUE);
116 tmp.add(FontFactory.COURIER_BOLDOBLIQUE);
117 fontFamilies.put(FontFactory.COURIER.toLowerCase(), tmp);
118 tmp = new ArrayList();
119 tmp.add(FontFactory.HELVETICA);
120 tmp.add(FontFactory.HELVETICA_BOLD);
121 tmp.add(FontFactory.HELVETICA_OBLIQUE);
122 tmp.add(FontFactory.HELVETICA_BOLDOBLIQUE);
123 fontFamilies.put(FontFactory.HELVETICA.toLowerCase(), tmp);
124 tmp = new ArrayList();
125 tmp.add(FontFactory.SYMBOL);
126 fontFamilies.put(FontFactory.SYMBOL.toLowerCase(), tmp);
127 tmp = new ArrayList();
128 tmp.add(FontFactory.TIMES_ROMAN);
129 tmp.add(FontFactory.TIMES_BOLD);
130 tmp.add(FontFactory.TIMES_ITALIC);
131 tmp.add(FontFactory.TIMES_BOLDITALIC);
132 fontFamilies.put(FontFactory.TIMES.toLowerCase(), tmp);
133 fontFamilies.put(FontFactory.TIMES_ROMAN.toLowerCase(), tmp);
134 tmp = new ArrayList();
135 tmp.add(FontFactory.ZAPFDINGBATS);
136 fontFamilies.put(FontFactory.ZAPFDINGBATS.toLowerCase(), tmp);
137 }
138
139 /**
140 * Constructs a <CODE>Font</CODE>-object.
141 *
142 * @param fontname the name of the font
143 * @param encoding the encoding of the font
144 * @param embedded true if the font is to be embedded in the PDF
145 * @param size the size of this font
146 * @param style the style of this font
147 * @param color the <CODE>Color</CODE> of this font.
148 * @return the Font constructed based on the parameters
149 */
150 public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color) {
151 return getFont(fontname, encoding, embedded, size, style, color, true);
152 }
153
154
155
156 /**
157 * Constructs a <CODE>Font</CODE>-object.
158 *
159 * @param fontname the name of the font
160 * @param encoding the encoding of the font
161 * @param embedded true if the font is to be embedded in the PDF
162 * @param size the size of this font
163 * @param style the style of this font
164 * @param color the <CODE>Color</CODE> of this font.
165 * @param cached true if the font comes from the cache or is added to
166 * the cache if new, false if the font is always created new
167 * @return the Font constructed based on the parameters
168 */
169 public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color, boolean cached) {
170 if (fontname == null) return new Font(Font.UNDEFINED, size, style, color);
171 String lowercasefontname = fontname.toLowerCase();
172 ArrayList tmp = (ArrayList) fontFamilies.get(lowercasefontname);
173 if (tmp != null) {
174 // some bugs were fixed here by Daniel Marczisovszky
175 int s = style == Font.UNDEFINED ? Font.NORMAL : style;
176 int fs = Font.NORMAL;
177 boolean found = false;
178 for (Iterator i = tmp.iterator(); i.hasNext(); ) {
179 String f = (String) i.next();
180 String lcf = f.toLowerCase();
181 fs = Font.NORMAL;
182 if (lcf.toLowerCase().indexOf("bold") != -1) fs |= Font.BOLD;
183 if (lcf.toLowerCase().indexOf("italic") != -1 || lcf.toLowerCase().indexOf("oblique") != -1) fs |= Font.ITALIC;
184 if ((s & Font.BOLDITALIC) == fs) {
185 fontname = f;
186 found = true;
187 break;
188 }
189 }
190 if (style != Font.UNDEFINED && found) {
191 style &= ~fs;
192 }
193 }
194 BaseFont basefont = null;
195 try {
196 try {
197 // the font is a type 1 font or CJK font
198 basefont = BaseFont.createFont(fontname, encoding, embedded, cached, null, null, true);
199 }
200 catch(DocumentException de) {
201 }
202 if (basefont == null) {
203 // the font is a true type font or an unknown font
204 fontname = trueTypeFonts.getProperty(fontname.toLowerCase());
205 // the font is not registered as truetype font
206 if (fontname == null) return new Font(Font.UNDEFINED, size, style, color);
207 // the font is registered as truetype font
208 basefont = BaseFont.createFont(fontname, encoding, embedded, cached, null, null);
209 }
210 }
211 catch(DocumentException de) {
212 // this shouldn't happen
213 throw new ExceptionConverter(de);
214 }
215 catch(IOException ioe) {
216 // the font is registered as a true type font, but the path was wrong
217 return new Font(Font.UNDEFINED, size, style, color);
218 }
219 catch(NullPointerException npe) {
220 // null was entered as fontname and/or encoding
221 return new Font(Font.UNDEFINED, size, style, color);
222 }
223 return new Font(basefont, size, style, color);
224 }
225
226
227 /**
228 * Constructs a <CODE>Font</CODE>-object.
229 *
230 * @param attributes the attributes of a <CODE>Font</CODE> object.
231 * @return the Font constructed based on the attributes
232 */
233
234 public Font getFont(Properties attributes) {
235 String fontname = null;
236 String encoding = defaultEncoding;
237 boolean embedded = defaultEmbedding;
238 float size = Font.UNDEFINED;
239 int style = Font.NORMAL;
240 Color color = null;
241 String value = attributes.getProperty(Markup.HTML_ATTR_STYLE);
242 if (value != null && value.length() > 0) {
243 Properties styleAttributes = Markup.parseAttributes(value);
244 if (styleAttributes.isEmpty()) {
245 attributes.put(Markup.HTML_ATTR_STYLE, value);
246 }
247 else {
248 fontname = styleAttributes.getProperty(Markup.CSS_KEY_FONTFAMILY);
249 if (fontname != null) {
250 String tmp;
251 while (fontname.indexOf(',') != -1) {
252 tmp = fontname.substring(0, fontname.indexOf(','));
253 if (isRegistered(tmp)) {
254 fontname = tmp;
255 }
256 else {
257 fontname = fontname.substring(fontname.indexOf(',') + 1);
258 }
259 }
260 }
261 if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTSIZE)) != null) {
262 size = Markup.parseLength(value);
263 }
264 if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTWEIGHT)) != null) {
265 style |= Font.getStyleValue(value);
266 }
267 if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTSTYLE)) != null) {
268 style |= Font.getStyleValue(value);
269 }
270 if ((value = styleAttributes.getProperty(Markup.CSS_KEY_COLOR)) != null) {
271 color = Markup.decodeColor(value);
272 }
273 attributes.putAll(styleAttributes);
274 for (Enumeration e = styleAttributes.keys(); e.hasMoreElements();) {
275 Object o = e.nextElement();
276 attributes.put(o, styleAttributes.get(o));
277 }
278 }
279 }
280 if ((value = attributes.getProperty(ElementTags.ENCODING)) != null) {
281 encoding = value;
282 }
283 if ("true".equals(attributes.getProperty(ElementTags.EMBEDDED))) {
284 embedded = true;
285 }
286 if ((value = attributes.getProperty(ElementTags.FONT)) != null) {
287 fontname = value;
288 }
289 if ((value = attributes.getProperty(ElementTags.SIZE)) != null) {
290 size = Markup.parseLength(value);
291 }
292 if ((value = attributes.getProperty(Markup.HTML_ATTR_STYLE)) != null) {
293 style |= Font.getStyleValue(value);
294 }
295 if ((value = attributes.getProperty(ElementTags.STYLE)) != null) {
296 style |= Font.getStyleValue(value);
297 }
298 String r = attributes.getProperty(ElementTags.RED);
299 String g = attributes.getProperty(ElementTags.GREEN);
300 String b = attributes.getProperty(ElementTags.BLUE);
301 if (r != null || g != null || b != null) {
302 int red = 0;
303 int green = 0;
304 int blue = 0;
305 if (r != null) red = Integer.parseInt(r);
306 if (g != null) green = Integer.parseInt(g);
307 if (b != null) blue = Integer.parseInt(b);
308 color = new Color(red, green, blue);
309 }
310 else if ((value = attributes.getProperty(ElementTags.COLOR)) != null) {
311 color = Markup.decodeColor(value);
312 }
313 if (fontname == null) {
314 return getFont(null, encoding, embedded, size, style, color);
315 }
316 return getFont(fontname, encoding, embedded, size, style, color);
317 }
318
319 /**
320 * Constructs a <CODE>Font</CODE>-object.
321 *
322 * @param fontname the name of the font
323 * @param encoding the encoding of the font
324 * @param embedded true if the font is to be embedded in the PDF
325 * @param size the size of this font
326 * @param style the style of this font
327 * @return the Font constructed based on the parameters
328 */
329
330 public Font getFont(String fontname, String encoding, boolean embedded, float size, int style) {
331 return getFont(fontname, encoding, embedded, size, style, null);
332 }
333
334 /**
335 * Constructs a <CODE>Font</CODE>-object.
336 *
337 * @param fontname the name of the font
338 * @param encoding the encoding of the font
339 * @param embedded true if the font is to be embedded in the PDF
340 * @param size the size of this font
341 * @return the Font constructed based on the parameters
342 */
343
344 public Font getFont(String fontname, String encoding, boolean embedded, float size) {
345 return getFont(fontname, encoding, embedded, size, Font.UNDEFINED, null);
346 }
347
348 /**
349 * Constructs a <CODE>Font</CODE>-object.
350 *
351 * @param fontname the name of the font
352 * @param encoding the encoding of the font
353 * @param embedded true if the font is to be embedded in the PDF
354 * @return the Font constructed based on the parameters
355 */
356
357 public Font getFont(String fontname, String encoding, boolean embedded) {
358 return getFont(fontname, encoding, embedded, Font.UNDEFINED, Font.UNDEFINED, null);
359 }
360
361 /**
362 * Constructs a <CODE>Font</CODE>-object.
363 *
364 * @param fontname the name of the font
365 * @param encoding the encoding of the font
366 * @param size the size of this font
367 * @param style the style of this font
368 * @param color the <CODE>Color</CODE> of this font.
369 * @return the Font constructed based on the parameters
370 */
371
372 public Font getFont(String fontname, String encoding, float size, int style, Color color) {
373 return getFont(fontname, encoding, defaultEmbedding, size, style, color);
374 }
375
376 /**
377 * Constructs a <CODE>Font</CODE>-object.
378 *
379 * @param fontname the name of the font
380 * @param encoding the encoding of the font
381 * @param size the size of this font
382 * @param style the style of this font
383 * @return the Font constructed based on the parameters
384 */
385
386 public Font getFont(String fontname, String encoding, float size, int style) {
387 return getFont(fontname, encoding, defaultEmbedding, size, style, null);
388 }
389
390 /**
391 * Constructs a <CODE>Font</CODE>-object.
392 *
393 * @param fontname the name of the font
394 * @param encoding the encoding of the font
395 * @param size the size of this font
396 * @return the Font constructed based on the parameters
397 */
398
399 public Font getFont(String fontname, String encoding, float size) {
400 return getFont(fontname, encoding, defaultEmbedding, size, Font.UNDEFINED, null);
401 }
402
403
404 /**
405 * Constructs a <CODE>Font</CODE>-object.
406 *
407 * @param fontname the name of the font
408 * @param size the size of this font
409 * @param color the <CODE>Color</CODE> of this font.
410 * @return the Font constructed based on the parameters
411 * @since 2.1.0
412 */
413
414 public Font getFont(String fontname, float size, Color color) {
415 return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, color);
416 }
417
418 /**
419 * Constructs a <CODE>Font</CODE>-object.
420 *
421 * @param fontname the name of the font
422 * @param encoding the encoding of the font
423 * @return the Font constructed based on the parameters
424 */
425
426 public Font getFont(String fontname, String encoding) {
427 return getFont(fontname, encoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null);
428 }
429
430 /**
431 * Constructs a <CODE>Font</CODE>-object.
432 *
433 * @param fontname the name of the font
434 * @param size the size of this font
435 * @param style the style of this font
436 * @param color the <CODE>Color</CODE> of this font.
437 * @return the Font constructed based on the parameters
438 */
439
440 public Font getFont(String fontname, float size, int style, Color color) {
441 return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, color);
442 }
443
444 /**
445 * Constructs a <CODE>Font</CODE>-object.
446 *
447 * @param fontname the name of the font
448 * @param size the size of this font
449 * @param style the style of this font
450 * @return the Font constructed based on the parameters
451 */
452
453 public Font getFont(String fontname, float size, int style) {
454 return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, null);
455 }
456
457 /**
458 * Constructs a <CODE>Font</CODE>-object.
459 *
460 * @param fontname the name of the font
461 * @param size the size of this font
462 * @return the Font constructed based on the parameters
463 */
464
465 public Font getFont(String fontname, float size) {
466 return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, null);
467 }
468
469 /**
470 * Constructs a <CODE>Font</CODE>-object.
471 *
472 * @param fontname the name of the font
473 * @return the Font constructed based on the parameters
474 */
475
476 public Font getFont(String fontname) {
477 return getFont(fontname, defaultEncoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null);
478 }
479
480 /**
481 * Register a font by giving explicitly the font family and name.
482 * @param familyName the font family
483 * @param fullName the font name
484 * @param path the font path
485 */
486 public void registerFamily(String familyName, String fullName, String path) {
487 if (path != null)
488 trueTypeFonts.setProperty(fullName, path);
489 ArrayList tmp = (ArrayList) fontFamilies.get(familyName);
490 if (tmp == null) {
491 tmp = new ArrayList();
492 tmp.add(fullName);
493 fontFamilies.put(familyName, tmp);
494 }
495 else {
496 int fullNameLength = fullName.length();
497 boolean inserted = false;
498 for (int j = 0; j < tmp.size(); ++j) {
499 if (((String)tmp.get(j)).length() >= fullNameLength) {
500 tmp.add(j, fullName);
501 inserted = true;
502 break;
503 }
504 }
505 if (!inserted)
506 tmp.add(fullName);
507 }
508 }
509
510 /**
511 * Register a ttf- or a ttc-file.
512 *
513 * @param path the path to a ttf- or ttc-file
514 */
515
516 public void register(String path) {
517 register(path, null);
518 }
519
520 /**
521 * Register a font file and use an alias for the font contained in it.
522 *
523 * @param path the path to a font file
524 * @param alias the alias you want to use for the font
525 */
526
527 public void register(String path, String alias) {
528 try {
529 if (path.toLowerCase().endsWith(".ttf") || path.toLowerCase().endsWith(".otf") || path.toLowerCase().indexOf(".ttc,") > 0) {
530 Object allNames[] = BaseFont.getAllFontNames(path, BaseFont.WINANSI, null);
531 trueTypeFonts.setProperty(((String)allNames[0]).toLowerCase(), path);
532 if (alias != null) {
533 trueTypeFonts.setProperty(alias.toLowerCase(), path);
534 }
535 // register all the font names with all the locales
536 String[][] names = (String[][])allNames[2]; //full name
537 for (int i = 0; i < names.length; i++) {
538 trueTypeFonts.setProperty(names[i][3].toLowerCase(), path);
539 }
540 String fullName = null;
541 String familyName = null;
542 names = (String[][])allNames[1]; //family name
543 for (int k = 0; k < TTFamilyOrder.length; k += 3) {
544 for (int i = 0; i < names.length; i++) {
545 if (TTFamilyOrder[k].equals(names[i][0]) && TTFamilyOrder[k + 1].equals(names[i][1]) && TTFamilyOrder[k + 2].equals(names[i][2])) {
546 familyName = names[i][3].toLowerCase();
547 k = TTFamilyOrder.length;
548 break;
549 }
550 }
551 }
552 if (familyName != null) {
553 String lastName = "";
554 names = (String[][])allNames[2]; //full name
555 for (int i = 0; i < names.length; i++) {
556 for (int k = 0; k < TTFamilyOrder.length; k += 3) {
557 if (TTFamilyOrder[k].equals(names[i][0]) && TTFamilyOrder[k + 1].equals(names[i][1]) && TTFamilyOrder[k + 2].equals(names[i][2])) {
558 fullName = names[i][3];
559 if (fullName.equals(lastName))
560 continue;
561 lastName = fullName;
562 registerFamily(familyName, fullName, null);
563 break;
564 }
565 }
566 }
567 }
568 }
569 else if (path.toLowerCase().endsWith(".ttc")) {
570 if (alias != null)
571 System.err.println("class FontFactory: You can't define an alias for a true type collection.");
572 String[] names = BaseFont.enumerateTTCNames(path);
573 for (int i = 0; i < names.length; i++) {
574 register(path + "," + i);
575 }
576 }
577 else if (path.toLowerCase().endsWith(".afm") || path.toLowerCase().endsWith(".pfm")) {
578 BaseFont bf = BaseFont.createFont(path, BaseFont.CP1252, false);
579 String fullName = bf.getFullFontName()[0][3].toLowerCase();
580 String familyName = bf.getFamilyFontName()[0][3].toLowerCase();
581 String psName = bf.getPostscriptFontName().toLowerCase();
582 registerFamily(familyName, fullName, null);
583 trueTypeFonts.setProperty(psName, path);
584 trueTypeFonts.setProperty(fullName, path);
585 }
586 }
587 catch(DocumentException de) {
588 // this shouldn't happen
589 throw new ExceptionConverter(de);
590 }
591 catch(IOException ioe) {
592 throw new ExceptionConverter(ioe);
593 }
594 }
595
596 /** Register all the fonts in a directory.
597 * @param dir the directory
598 * @return the number of fonts registered
599 */
600 public int registerDirectory(String dir) {
601 return registerDirectory(dir, false);
602 }
603
604 /**
605 * Register all the fonts in a directory and possibly its subdirectories.
606 * @param dir the directory
607 * @param scanSubdirectories recursively scan subdirectories if <code>true</true>
608 * @return the number of fonts registered
609 * @since 2.1.2
610 */
611 public int registerDirectory(String dir, boolean scanSubdirectories) {
612 int count = 0;
613 try {
614 File file = new File(dir);
615 if (!file.exists() || !file.isDirectory())
616 return 0;
617 String files[] = file.list();
618 if (files == null)
619 return 0;
620 for (int k = 0; k < files.length; ++k) {
621 try {
622 file = new File(dir, files[k]);
623 if (file.isDirectory()) {
624 if (scanSubdirectories) {
625 count += registerDirectory(file.getAbsolutePath(), true);
626 }
627 } else {
628 String name = file.getPath();
629 String suffix = name.length() < 4 ? null : name.substring(name.length() - 4).toLowerCase();
630 if (".afm".equals(suffix) || ".pfm".equals(suffix)) {
631 /* Only register Type 1 fonts with matching .pfb files */
632 File pfb = new File(name.substring(0, name.length() - 4) + ".pfb");
633 if (pfb.exists()) {
634 register(name, null);
635 ++count;
636 }
637 } else if (".ttf".equals(suffix) || ".otf".equals(suffix) || ".ttc".equals(suffix)) {
638 register(name, null);
639 ++count;
640 }
641 }
642 }
643 catch (Exception e) {
644 //empty on purpose
645 }
646 }
647 }
648 catch (Exception e) {
649 //empty on purpose
650 }
651 return count;
652 }
653
654 /** Register fonts in some probable directories. It usually works in Windows,
655 * Linux and Solaris.
656 * @return the number of fonts registered
657 */
658 public int registerDirectories() {
659 int count = 0;
660 count += registerDirectory("c:/windows/fonts");
661 count += registerDirectory("c:/winnt/fonts");
662 count += registerDirectory("d:/windows/fonts");
663 count += registerDirectory("d:/winnt/fonts");
664 count += registerDirectory("/usr/share/X11/fonts", true);
665 count += registerDirectory("/usr/X/lib/X11/fonts", true);
666 count += registerDirectory("/usr/openwin/lib/X11/fonts", true);
667 count += registerDirectory("/usr/share/fonts", true);
668 count += registerDirectory("/usr/X11R6/lib/X11/fonts", true);
669 count += registerDirectory("/Library/Fonts");
670 count += registerDirectory("/System/Library/Fonts");
671 return count;
672 }
673
674 /**
675 * Gets a set of registered fontnames.
676 * @return a set of registered fonts
677 */
678
679 public Set getRegisteredFonts() {
680 return Utilities.getKeySet(trueTypeFonts);
681 }
682
683 /**
684 * Gets a set of registered fontnames.
685 * @return a set of registered font families
686 */
687
688 public Set getRegisteredFamilies() {
689 return Utilities.getKeySet(fontFamilies);
690 }
691
692 /**
693 * Checks if a certain font is registered.
694 *
695 * @param fontname the name of the font that has to be checked.
696 * @return true if the font is found
697 */
698 public boolean isRegistered(String fontname) {
699 return trueTypeFonts.containsKey(fontname.toLowerCase());
700 }
701 }
702