KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > fonts > FontReader


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: FontReader.java 463180 2006-10-12 10:08:01Z bdelacretaz $ */
19
20 package org.apache.fop.fonts;
21
22 //Java
23
import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.io.IOException JavaDoc;
26
27 import javax.xml.parsers.SAXParserFactory JavaDoc;
28
29 //SAX
30
import org.xml.sax.XMLReader JavaDoc;
31 import org.xml.sax.SAXException JavaDoc;
32 import org.xml.sax.Locator JavaDoc;
33 import org.xml.sax.Attributes JavaDoc;
34 import org.xml.sax.helpers.DefaultHandler JavaDoc;
35
36 //FOP
37
import org.apache.fop.apps.FOPException;
38 import org.apache.fop.fonts.apps.TTFReader;
39 import org.xml.sax.InputSource JavaDoc;
40
41 /**
42  * Class for reading a metric.xml file and creating a font object.
43  * Typical usage:
44  * <pre>
45  * FontReader reader = new FontReader(<path til metrics.xml>);
46  * reader.setFontEmbedPath(<path to a .ttf or .pfb file or null to diable embedding>);
47  * reader.useKerning(true);
48  * Font f = reader.getFont();
49  * </pre>
50  */

51 public class FontReader extends DefaultHandler JavaDoc {
52
53     private Locator JavaDoc locator = null;
54     private boolean isCID = false;
55     private CustomFont returnFont = null;
56     private MultiByteFont multiFont = null;
57     private SingleByteFont singleFont = null;
58     private StringBuffer JavaDoc text = new StringBuffer JavaDoc();
59
60     private List JavaDoc cidWidths = null;
61     private int cidWidthIndex = 0;
62
63     private Map JavaDoc currentKerning = null;
64
65     private List JavaDoc bfranges = null;
66
67     private void createFont(InputSource JavaDoc source) throws FOPException {
68         XMLReader JavaDoc parser = null;
69
70         try {
71             final SAXParserFactory JavaDoc factory = javax.xml.parsers.SAXParserFactory.newInstance();
72             factory.setNamespaceAware(true);
73             parser = factory.newSAXParser().getXMLReader();
74         } catch (Exception JavaDoc e) {
75             throw new FOPException(e);
76         }
77         if (parser == null) {
78             throw new FOPException("Unable to create SAX parser");
79         }
80
81         try {
82             parser.setFeature("http://xml.org/sax/features/namespace-prefixes",
83                               false);
84         } catch (SAXException JavaDoc e) {
85             throw new FOPException("You need a SAX parser which supports SAX version 2",
86                                    e);
87         }
88
89         parser.setContentHandler(this);
90
91         try {
92             parser.parse(source);
93         } catch (SAXException JavaDoc e) {
94             throw new FOPException(e);
95         } catch (IOException JavaDoc e) {
96             throw new FOPException(e);
97         }
98
99     }
100
101     /**
102      * Sets the path to embed a font. A null value disables font embedding.
103      * @param path URI for the embeddable file
104      */

105     public void setFontEmbedPath(String JavaDoc path) {
106         returnFont.setEmbedFileName(path);
107     }
108
109     /**
110      * Enable/disable use of kerning for the font
111      * @param enabled true to enable kerning, false to disable
112      */

113     public void setKerningEnabled(boolean enabled) {
114         returnFont.setKerningEnabled(enabled);
115     }
116
117     /**
118      * Sets the font resolver. Needed for URI resolution.
119      * @param resolver the font resolver
120      */

121     public void setResolver(FontResolver resolver) {
122         returnFont.setResolver(resolver);
123     }
124
125
126     /**
127      * Get the generated font object
128      * @return the font
129      */

130     public Typeface getFont() {
131         return returnFont;
132     }
133
134     /**
135      * Construct a FontReader object from a path to a metric.xml file
136      * and read metric data
137      * @param source Source of the font metric file
138      * @throws FOPException if loading the font fails
139      */

140     public FontReader(InputSource JavaDoc source) throws FOPException {
141         createFont(source);
142     }
143
144     /**
145      * @see org.xml.sax.ContentHandler#startDocument()
146      */

147     public void startDocument() {
148     }
149
150     /**
151      * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator)
152      */

153     public void setDocumentLocator(Locator JavaDoc locator) {
154         this.locator = locator;
155     }
156
157     /**
158      * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
159      */

160     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName,
161                              Attributes JavaDoc attributes) throws SAXException JavaDoc {
162         if (localName.equals("font-metrics")) {
163             if ("TYPE0".equals(attributes.getValue("type"))) {
164                 multiFont = new MultiByteFont();
165                 returnFont = multiFont;
166                 isCID = true;
167                 TTFReader.checkMetricsVersion(attributes);
168             } else if ("TRUETYPE".equals(attributes.getValue("type"))) {
169                 singleFont = new SingleByteFont();
170                 singleFont.setFontType(FontType.TRUETYPE);
171                 returnFont = singleFont;
172                 isCID = false;
173                 TTFReader.checkMetricsVersion(attributes);
174             } else {
175                 singleFont = new SingleByteFont();
176                 singleFont.setFontType(FontType.TYPE1);
177                 returnFont = singleFont;
178                 isCID = false;
179             }
180         } else if ("embed".equals(localName)) {
181             returnFont.setEmbedFileName(attributes.getValue("file"));
182             returnFont.setEmbedResourceName(attributes.getValue("class"));
183         } else if ("cid-widths".equals(localName)) {
184             cidWidthIndex = getInt(attributes.getValue("start-index"));
185             cidWidths = new java.util.ArrayList JavaDoc();
186         } else if ("kerning".equals(localName)) {
187             currentKerning = new java.util.HashMap JavaDoc();
188             returnFont.putKerningEntry(new Integer JavaDoc(attributes.getValue("kpx1")),
189                                         currentKerning);
190         } else if ("bfranges".equals(localName)) {
191             bfranges = new java.util.ArrayList JavaDoc();
192         } else if ("bf".equals(localName)) {
193             BFEntry entry = new BFEntry(getInt(attributes.getValue("us")),
194                                         getInt(attributes.getValue("ue")),
195                                         getInt(attributes.getValue("gi")));
196             bfranges.add(entry);
197         } else if ("wx".equals(localName)) {
198             cidWidths.add(new Integer JavaDoc(attributes.getValue("w")));
199         } else if ("widths".equals(localName)) {
200             //singleFont.width = new int[256];
201
} else if ("char".equals(localName)) {
202             try {
203                 singleFont.setWidth(Integer.parseInt(attributes.getValue("idx")),
204                         Integer.parseInt(attributes.getValue("wdt")));
205             } catch (NumberFormatException JavaDoc ne) {
206                 throw new SAXException JavaDoc("Malformed width in metric file: "
207                                    + ne.getMessage(), ne);
208             }
209         } else if ("pair".equals(localName)) {
210             currentKerning.put(new Integer JavaDoc(attributes.getValue("kpx2")),
211                                new Integer JavaDoc(attributes.getValue("kern")));
212         }
213     }
214
215     private int getInt(String JavaDoc str) throws SAXException JavaDoc {
216         int ret = 0;
217         try {
218             ret = Integer.parseInt(str);
219         } catch (Exception JavaDoc e) {
220             throw new SAXException JavaDoc("Error while parsing integer value: " + str, e);
221         }
222         return ret;
223     }
224
225     /**
226      * @see org.xml.sax.ContentHandler#endElement(String, String, String)
227      */

228     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
229         String JavaDoc content = text.toString().trim();
230         if ("font-name".equals(localName)) {
231             returnFont.setFontName(content);
232         } else if ("ttc-name".equals(localName) && isCID) {
233             multiFont.setTTCName(content);
234         } else if ("encoding".equals(localName)) {
235             if (singleFont != null && singleFont.getFontType() == FontType.TYPE1) {
236                 singleFont.setEncoding(content);
237             }
238         } else if ("cap-height".equals(localName)) {
239             returnFont.setCapHeight(getInt(content));
240         } else if ("x-height".equals(localName)) {
241             returnFont.setXHeight(getInt(content));
242         } else if ("ascender".equals(localName)) {
243             returnFont.setAscender(getInt(content));
244         } else if ("descender".equals(localName)) {
245             returnFont.setDescender(getInt(content));
246         } else if ("left".equals(localName)) {
247             int[] bbox = returnFont.getFontBBox();
248             bbox[0] = getInt(content);
249             returnFont.setFontBBox(bbox);
250         } else if ("bottom".equals(localName)) {
251             int[] bbox = returnFont.getFontBBox();
252             bbox[1] = getInt(content);
253             returnFont.setFontBBox(bbox);
254         } else if ("right".equals(localName)) {
255             int[] bbox = returnFont.getFontBBox();
256             bbox[2] = getInt(content);
257             returnFont.setFontBBox(bbox);
258         } else if ("top".equals(localName)) {
259             int[] bbox = returnFont.getFontBBox();
260             bbox[3] = getInt(content);
261             returnFont.setFontBBox(bbox);
262         } else if ("first-char".equals(localName)) {
263             returnFont.setFirstChar(getInt(content));
264         } else if ("last-char".equals(localName)) {
265             returnFont.setLastChar(getInt(content));
266         } else if ("flags".equals(localName)) {
267             returnFont.setFlags(getInt(content));
268         } else if ("stemv".equals(localName)) {
269             returnFont.setStemV(getInt(content));
270         } else if ("italic-angle".equals(localName)) {
271             returnFont.setItalicAngle(getInt(content));
272         } else if ("missing-width".equals(localName)) {
273             returnFont.setMissingWidth(getInt(content));
274         } else if ("cid-type".equals(localName)) {
275             multiFont.setCIDType(CIDFontType.byName(content));
276         } else if ("default-width".equals(localName)) {
277             multiFont.setDefaultWidth(getInt(content));
278         } else if ("cid-widths".equals(localName)) {
279             int[] wds = new int[cidWidths.size()];
280             int j = 0;
281             for (int count = 0; count < cidWidths.size(); count++) {
282                 Integer JavaDoc i = (Integer JavaDoc)cidWidths.get(count);
283                 wds[j++] = i.intValue();
284             }
285
286             //multiFont.addCIDWidthEntry(cidWidthIndex, wds);
287
multiFont.setWidthArray(wds);
288
289         } else if ("bfranges".equals(localName)) {
290             multiFont.setBFEntries((BFEntry[])bfranges.toArray(new BFEntry[0]));
291         }
292         text.setLength(0); //Reset text buffer (see characters())
293
}
294
295     /**
296      * @see org.xml.sax.ContentHandler#characters(char[], int, int)
297      */

298     public void characters(char[] ch, int start, int length) {
299         text.append(ch, start, length);
300     }
301 }
302
303
304
Popular Tags