001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.gvt.font;
020:
021: import java.awt.GraphicsEnvironment;
022: import java.util.Collection;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.Map;
026: import java.util.StringTokenizer;
027: import java.util.List;
028: import java.util.ArrayList;
029:
030: /**
031: * The is a utility class that is used for resolving UnresolvedFontFamilies.
032: *
033: * @author <a href="mailto:bella.robinson@cmis.csiro.au">Bella Robinson</a>
034: * @version $Id: FontFamilyResolver.java 479559 2006-11-27 09:46:16Z dvholten $
035: */
036: public class FontFamilyResolver {
037:
038: /**
039: * The default font. This will be used when no font families can
040: * be resolved for a particular text chunck/run.
041: */
042: public static final AWTFontFamily defaultFont = new AWTFontFamily(
043: "SansSerif");
044:
045: /**
046: * List of all available fonts on the current system, plus a few common
047: * alternatives.
048: */
049: protected static final Map fonts = new HashMap();
050:
051: protected static final List awtFontFamilies = new ArrayList();
052: protected static final List awtFonts = new ArrayList();
053:
054: /**
055: * This sets up the list of available fonts.
056: */
057: static {
058: fonts.put("sans-serif", "SansSerif");
059: fonts.put("serif", "Serif");
060: fonts.put("times", "Serif");
061: fonts.put("times new roman", "Serif");
062: fonts.put("cursive", "Dialog");
063: fonts.put("fantasy", "Symbol");
064: fonts.put("monospace", "Monospaced");
065: fonts.put("monospaced", "Monospaced");
066: fonts.put("courier", "Monospaced");
067:
068: //
069: // Load all fonts. Work around
070: //
071:
072: GraphicsEnvironment env;
073: env = GraphicsEnvironment.getLocalGraphicsEnvironment();
074: String[] fontNames = env.getAvailableFontFamilyNames();
075:
076: int nFonts = fontNames != null ? fontNames.length : 0;
077: for (int i = 0; i < nFonts; i++) {
078: fonts.put(fontNames[i].toLowerCase(), fontNames[i]);
079:
080: // also add the font name with the spaces removed
081: StringTokenizer st = new StringTokenizer(fontNames[i]);
082: String fontNameWithoutSpaces = "";
083: while (st.hasMoreTokens()) {
084: fontNameWithoutSpaces += st.nextToken();
085: }
086: fonts
087: .put(fontNameWithoutSpaces.toLowerCase(),
088: fontNames[i]);
089:
090: // also add the font name with spaces replaced by dashes
091: String fontNameWithDashes = fontNames[i].replace(' ', '-');
092: if (!fontNameWithDashes.equals(fontNames[i])) {
093: fonts.put(fontNameWithDashes.toLowerCase(),
094: fontNames[i]);
095: }
096: }
097:
098: // first add the default font
099: awtFontFamilies.add(defaultFont);
100: awtFonts
101: .add(new AWTGVTFont(defaultFont.getFamilyName(), 0, 12));
102:
103: Collection fontValues = fonts.values();
104: Iterator iter = fontValues.iterator();
105: while (iter.hasNext()) {
106: String fontFamily = (String) iter.next();
107: AWTFontFamily awtFontFamily = new AWTFontFamily(fontFamily);
108: awtFontFamilies.add(awtFontFamily);
109: AWTGVTFont font = new AWTGVTFont(fontFamily, 0, 12);
110: awtFonts.add(font);
111: }
112:
113: }
114:
115: /**
116: * This keeps track of all the resolved font families. This is to hopefully
117: * reduce the number of font family objects used.
118: */
119: protected static final Map resolvedFontFamilies = new HashMap();
120:
121: /**
122: * Looks up a font family name and returns the platform name
123: * for the font.
124: *
125: * @param familyName The Font Family name to resolve
126: *
127: * @return The platform name for the font or null if it can't be found.
128: */
129: public static String lookup(String familyName) {
130: return (String) fonts.get(familyName.toLowerCase());
131: }
132:
133: /**
134: * Resolves a font family name into a GVTFontFamily. If the font
135: * family cannot be resolved then null will be returned.
136: *
137: * @param familyName The Font Family name to resolve
138: *
139: * @return A resolved GVTFontFamily or null if the font family could not
140: * be resolved.
141: */
142: public static GVTFontFamily resolve(String familyName) {
143:
144: familyName = familyName.toLowerCase();
145:
146: // first see if this font family has already been resolved
147: GVTFontFamily resolvedFF = (GVTFontFamily) resolvedFontFamilies
148: .get(familyName);
149:
150: if (resolvedFF == null) { // hasn't been resolved yet
151: // try to find a matching family name in the list of
152: // available fonts
153: String awtFamilyName = (String) fonts.get(familyName);
154: if (awtFamilyName != null) {
155: resolvedFF = new AWTFontFamily(awtFamilyName);
156: }
157:
158: resolvedFontFamilies.put(familyName, resolvedFF);
159: }
160:
161: // if (resolvedFF != null) {
162: // System.out.println("resolved " + fontFamily.getFamilyName() +
163: // " to " + resolvedFF.getFamilyName());
164: // } else {
165: // System.out.println("could not resolve " +
166: // fontFamily.getFamilyName());
167: // }
168: return resolvedFF;
169: }
170:
171: /**
172: * Resolves an UnresolvedFontFamily into a GVTFontFamily. If the font
173: * family cannot be resolved then null will be returned.
174: *
175: * @param fontFamily The UnresolvedFontFamily to resolve
176: *
177: * @return A resolved GVTFontFamily or null if the font family could not
178: * be resolved.
179: */
180: public static GVTFontFamily resolve(UnresolvedFontFamily fontFamily) {
181:
182: return resolve(fontFamily.getFamilyName());
183: }
184:
185: public static GVTFontFamily getFamilyThatCanDisplay(char c) {
186: for (int i = 0; i < awtFontFamilies.size(); i++) {
187: AWTFontFamily fontFamily = (AWTFontFamily) awtFontFamilies
188: .get(i);
189: AWTGVTFont font = (AWTGVTFont) awtFonts.get(i);
190: if (font.canDisplay(c)
191: && fontFamily.getFamilyName().indexOf("Song") == -1) {
192: // the awt font for "MS Song" doesn't display chinese glyphs correctly
193: return fontFamily;
194: }
195: }
196:
197: return null;
198: }
199:
200: }
|