View Javadoc

1   /*
2    * Copyright 2007 - 2007 JEuclid, http://jeuclid.sf.net
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id: DefaultFontFactory.java 600 2008-01-22 15:12:48Z maxberger $ */
18  
19  package net.sourceforge.jeuclid.font;
20  
21  import java.awt.Font;
22  import java.awt.FontFormatException;
23  import java.awt.GraphicsEnvironment;
24  import java.io.File;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.util.Collection;
28  import java.util.HashMap;
29  import java.util.List;
30  import java.util.Map;
31  
32  /**
33   * Concrete FontFactory implementation that does simple caching of Fonts
34   * loaded via {@link Font#createFont(int, File)} APIs.
35   * 
36   * @author Ernest Mishkin
37   * @version $Revision: 600 $
38   */
39  public class DefaultFontFactory extends FontFactory {
40  
41      private final Map<String, Font> fontCache;
42  
43      private static final String AWT_SANSSERIF = "sansserif";
44  
45      DefaultFontFactory() {
46          this.fontCache = new HashMap<String, Font>();
47          this.autoloadFontsFromAWT();
48      }
49  
50      private void autoloadFontsFromAWT() {
51          final String[] fam = GraphicsEnvironment
52                  .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
53          for (final String element : fam) {
54              final Font f = new Font(element, 0, 12);
55              this.cacheFont(f);
56          }
57      }
58  
59      /**
60       * Create a font object with specified properties. Font name may refer to
61       * either 'built-in' or loaded externally and 'cached' font.
62       * 
63       * @param name
64       *            font name or font family name
65       * @param style
66       *            font style
67       * @param size
68       *            font size
69       * @return Font instance
70       * @see java.awt.Font#Font(String, int, int)
71       */
72      @Override
73      public Font getFont(final String name, final int style, final int size) {
74          Font font = this.fontCache.get(name);
75          if (font == null) {
76              font = new Font(name, style, size);
77          } else {
78              font = font.deriveFont(style, size);
79          }
80          return font;
81      }
82  
83      /** {@inheritDoc} */
84      @Override
85      public Font getFont(final List<String> preferredFonts,
86              final int codepoint, final int style, final int size) {
87          Font font = this.searchFontList(preferredFonts, codepoint, style,
88                  size);
89          if (font == null) {
90              font = this.searchFontList(this.fontCache.keySet(), codepoint,
91                      style, size);
92          }
93          if (font == null) {
94              font = this
95                      .getFont(DefaultFontFactory.AWT_SANSSERIF, style, size);
96          }
97          return font;
98      }
99  
100     private Font searchFontList(final Collection<String> fontList,
101             final int codepoint, final int style, final int size) {
102         for (final String fontName : fontList) {
103             final Font font = this.getFont(fontName, style, size);
104             final String desiredFont = fontName.trim();
105             if ((font.getFamily().equalsIgnoreCase(desiredFont))
106                     || (font.getFontName().equalsIgnoreCase(desiredFont))) {
107                 if (font.canDisplay(codepoint)) {
108                     return font;
109                 }
110             }
111         }
112         return null;
113     }
114 
115     /**
116      * Load an external font from a file and 'register' (aka 'cache') it for
117      * future use.
118      * 
119      * @param format
120      *            font format (TTF or TYPE_1 currently supported by the
121      *            platform)
122      * @param fontFile
123      *            file which contains the font
124      * @return The newly created Font instance
125      * @throws FontFormatException
126      *             if font contained in the file doesn't match the specified
127      *             format
128      * @throws IOException
129      *             in case of problem while reading the file
130      * @see java.awt.Font#createFont(int, File)
131      */
132     @Override
133     public Font registerFont(final int format, final File fontFile)
134             throws IOException, FontFormatException {
135 
136         return this.cacheFont(Font.createFont(format, fontFile));
137     }
138 
139     /**
140      * Load an external font from a stream and 'register' (aka 'cache') it for
141      * future use.
142      * 
143      * @param format
144      *            font format (TTF or TYPE_1 currently supported by the
145      *            platform)
146      * @param fontStream
147      *            file which contains the font
148      * @return The newly created Font instance
149      * @throws FontFormatException
150      *             if font contained in the stream doesn't match the specified
151      *             format
152      * @throws IOException
153      *             in case of problem while reading the stream
154      * @see java.awt.Font#createFont(int, InputStream)
155      */
156     @Override
157     public Font registerFont(final int format, final InputStream fontStream)
158             throws IOException, FontFormatException {
159 
160         return this.cacheFont(Font.createFont(format, fontStream));
161     }
162 
163     /**
164      * Actually stores a font in the cache. Uses font name and font family as
165      * keys.
166      * 
167      * @param font
168      *            Font instance to cache
169      * @return the font instance that was cached
170      */
171     protected Font cacheFont(final Font font) {
172         this.fontCache.put(font.getFontName(), font);
173         final String family = font.getFamily();
174         // This is a safeguard. On Linux for DejaVu Sans Oblique we get:
175         // Name: DejaVu Sans Oblique
176         // Family: DejaVu Sans
177         // For DejaVu Sans we get:
178         // Name: DejaVu Sans
179         // Family: DejaVu Sans
180         // And of course we don't want the oblique font to override the
181         // regular font...
182         if (!this.fontCache.containsKey(family)) {
183             this.fontCache.put(font.getFamily(), font);
184         }
185         return font;
186     }
187 
188 }