001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Ilya S. Okomin
019: * @version $Revision$
020: */package org.apache.harmony.awt.gl.font;
021:
022: import java.awt.Font;
023: import java.awt.peer.FontPeer;
024: import java.io.File;
025: import java.io.IOException;
026: import java.util.Properties;
027: import java.util.Vector;
028:
029: import org.apache.harmony.awt.gl.font.FontManager;
030: import org.apache.harmony.awt.gl.font.FontProperty;
031: import org.apache.harmony.awt.internal.nls.Messages;
032:
033: public class LinuxFontManager extends FontManager {
034:
035: // set of all available faces supported by a system
036: String faces[];
037:
038: // weight names according to xlfd structure
039: public static final String[] LINUX_WEIGHT_NAMES = {
040: "black", "bold", "demibold", "medium", "light" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
041: };
042:
043: // slant names according to xlfd structure
044: public static final String[] LINUX_SLANT_NAMES = { "i", "o", "r" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
045: };
046:
047: /** Singleton LinuxFontManager instance */
048: public static final LinuxFontManager inst = new LinuxFontManager();
049:
050: private LinuxFontManager() {
051: super ();
052: faces = LinuxNativeFont.getFaces();
053: initFontProperties();
054: }
055:
056: public void initLCIDTable() {
057: LinuxNativeFont.initLCIDsTable(this .tableLCID);
058: }
059:
060: /**
061: * Returns temporary File object to store data from InputStream.
062: * This File object saved to `~/.fonts/' folder that is included in the
063: * list of folders searched for font files, and this is where user-specific
064: * font files should be installed.
065: */
066: public File getTempFontFile() throws IOException {
067: File fontFile = File.createTempFile("jFont", ".ttf"); //$NON-NLS-1$ //$NON-NLS-2$
068: fontFile.deleteOnExit();
069:
070: return fontFile;
071: }
072:
073: /**
074: * Initializes fProperties array field for the current system configuration font
075: * property file.
076: *
077: * RuntimeException is thrown if font property contains incorrect format of
078: * xlfd string.
079: *
080: * @return true is success, false if font property doesn't exist or doesn't
081: * contain roperties.
082: */
083: public boolean initFontProperties() {
084: File fpFile = getFontPropertyFile();
085: if (fpFile == null) {
086: return false;
087: }
088:
089: Properties props = getProperties(fpFile);
090: if (props == null) {
091: return false;
092: }
093:
094: for (int i = 0; i < LOGICAL_FONT_NAMES.length; i++) {
095: String lName = LOGICAL_FONT_NAMES[i];
096: for (int j = 0; j < STYLE_NAMES.length; j++) {
097: String styleName = STYLE_NAMES[j];
098: Vector propsVector = new Vector();
099:
100: // Number of entries for a logical font
101: int numComp = 0;
102: // Is more entries for this style and logical font name left
103: boolean moreEntries = true;
104: String value = null;
105:
106: while (moreEntries) {
107: // Component Font Mappings property name
108: String property = FONT_MAPPING_KEYS[0]
109: .replaceAll("LogicalFontName", lName).replaceAll("StyleName", styleName).replaceAll("ComponentIndex", String.valueOf(numComp)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
110: value = props.getProperty(property);
111:
112: // If the StyleName is omitted, it's assumed to be plain
113: if ((j == 0) && (value == null)) {
114: property = FONT_MAPPING_KEYS[1]
115: .replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp)); //$NON-NLS-1$ //$NON-NLS-2$
116: value = props.getProperty(property);
117: }
118:
119: if (value != null) {
120: String[] fields = parseXLFD(value);
121:
122: if (fields == null) {
123: // awt.08=xfld parse string error: {0}
124: throw new RuntimeException(Messages
125: .getString("awt.08", value)); //$NON-NLS-1$
126: }
127:
128: String fontName = fields[1];
129: String weight = fields[2];
130: String italic = fields[3];
131:
132: int style = getBoldStyle(weight)
133: | getItalicStyle(italic);
134: // Component Font Character Encodings property value
135: String encoding = props
136: .getProperty(FONT_CHARACTER_ENCODING
137: .replaceAll(
138: "LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp))); //$NON-NLS-1$ //$NON-NLS-2$
139:
140: // Exclusion Ranges property value
141: String exclString = props
142: .getProperty(EXCLUSION_RANGES
143: .replaceAll(
144: "LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp))); //$NON-NLS-1$ //$NON-NLS-2$
145: int[] exclRange = parseIntervals(exclString);
146:
147: FontProperty fp = new LinuxFontProperty(lName,
148: styleName, null, fontName, value,
149: style, exclRange, encoding);
150:
151: propsVector.add(fp);
152: numComp++;
153: } else {
154: moreEntries = false;
155: }
156: }
157: fProperties.put(
158: LOGICAL_FONT_NAMES[i] + "." + j, propsVector); //$NON-NLS-1$
159: }
160: }
161:
162: return true;
163:
164: }
165:
166: /**
167: * Returns style according to the xlfd weight string.
168: * If weight string is incorrect returned value is Font.PLAIN
169: *
170: * @param str weight name String
171: */
172: private int getBoldStyle(String str) {
173: for (int i = 0; i < LINUX_WEIGHT_NAMES.length; i++) {
174: if (str.equalsIgnoreCase(LINUX_WEIGHT_NAMES[i])) {
175: return (i < 3) ? Font.BOLD : Font.PLAIN;
176: }
177: }
178: return Font.PLAIN;
179: }
180:
181: /**
182: * Returns style according to the xlfd slant string.
183: * If slant string is incorrect returned value is Font.PLAIN
184: *
185: * @param str slant name String
186: */
187: private int getItalicStyle(String str) {
188: for (int i = 0; i < LINUX_SLANT_NAMES.length; i++) {
189: if (str.equalsIgnoreCase(LINUX_SLANT_NAMES[i])) {
190: return (i < 2) ? Font.ITALIC : Font.PLAIN;
191: }
192: }
193: return Font.PLAIN;
194: }
195:
196: /**
197: * Parse xlfd string and returns array of Strings with separate xlfd
198: * elements.<p>
199: *
200: * xlfd format:
201: * -Foundry-Family-Weight-Slant-Width-Style-PixelSize-PointSize-ResX-ResY-Spacing-AvgWidth-Registry-Encoding
202: * @param xlfd String parameter in xlfd format
203: */
204: public static String[] parseXLFD(String xlfd) {
205: int fieldsCount = 14;
206: String fieldsDelim = "-"; //$NON-NLS-1$
207: String[] res = new String[fieldsCount];
208: if (!xlfd.startsWith(fieldsDelim)) {
209: return null;
210: }
211:
212: xlfd = xlfd.substring(1);
213: int i = 0;
214: int pos;
215: for (i = 0; i < fieldsCount - 1; i++) {
216: pos = xlfd.indexOf(fieldsDelim);
217: if (pos != -1) {
218: res[i] = xlfd.substring(0, pos);
219: xlfd = xlfd.substring(pos + 1);
220: } else {
221: return null;
222: }
223: }
224: pos = xlfd.indexOf(fieldsDelim);
225:
226: // check if no fields left
227: if (pos != -1) {
228: return null;
229: }
230: res[fieldsCount - 1] = xlfd;
231:
232: return res;
233: }
234:
235: public int getFaceIndex(String faceName) {
236: for (int i = 0; i < faces.length; i++) {
237: if (faces[i].equals(faceName)) {
238: return i;
239: }
240: }
241: return -1;
242: }
243:
244: public String[] getAllFamilies() {
245: if (allFamilies == null) {
246: allFamilies = LinuxNativeFont.getFamilies();
247: }
248: return allFamilies;
249: }
250:
251: public Font[] getAllFonts() {
252: Font[] fonts = new Font[faces.length];
253: for (int i = 0; i < fonts.length; i++) {
254: fonts[i] = new Font(faces[i], Font.PLAIN, 1);
255: }
256: return fonts;
257: }
258:
259: public FontPeer createPhysicalFontPeer(String name, int style,
260: int size) {
261: LinuxFont peer;
262: int familyIndex = getFamilyIndex(name);
263: if (familyIndex != -1) {
264: // !! we use family names from the list with cached families because
265: // they are differ from the family names in xlfd structure, in xlfd
266: // family names mostly in lower case.
267: peer = new LinuxFont(getFamily(familyIndex), style, size);
268: peer.setFamily(getFamily(familyIndex));
269: return peer;
270: }
271: int faceIndex = getFaceIndex(name);
272: if (faceIndex != -1) {
273: style |= LinuxNativeFont.getFontStyle(faceIndex);
274: name = LinuxNativeFont.getFamilyFromFaceIndex(faceIndex);
275:
276: peer = new LinuxFont(name, style, size);
277: return peer;
278: }
279:
280: return null;
281: }
282:
283: public FontPeer createDefaultFont(int style, int size) {
284: return new LinuxFont(DEFAULT_NAME, style, size);
285: }
286:
287: }
|