1 17 18 19 20 package org.apache.fop.fonts; 21 22 import java.util.List ; 24 import java.util.Map ; 25 import java.io.IOException ; 26 27 import javax.xml.parsers.SAXParserFactory ; 28 29 import org.xml.sax.XMLReader ; 31 import org.xml.sax.SAXException ; 32 import org.xml.sax.Locator ; 33 import org.xml.sax.Attributes ; 34 import org.xml.sax.helpers.DefaultHandler ; 35 36 import org.apache.fop.apps.FOPException; 38 import org.apache.fop.fonts.apps.TTFReader; 39 import org.xml.sax.InputSource ; 40 41 51 public class FontReader extends DefaultHandler { 52 53 private Locator 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 text = new StringBuffer (); 59 60 private List cidWidths = null; 61 private int cidWidthIndex = 0; 62 63 private Map currentKerning = null; 64 65 private List bfranges = null; 66 67 private void createFont(InputSource source) throws FOPException { 68 XMLReader parser = null; 69 70 try { 71 final SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance(); 72 factory.setNamespaceAware(true); 73 parser = factory.newSAXParser().getXMLReader(); 74 } catch (Exception 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 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 e) { 94 throw new FOPException(e); 95 } catch (IOException e) { 96 throw new FOPException(e); 97 } 98 99 } 100 101 105 public void setFontEmbedPath(String path) { 106 returnFont.setEmbedFileName(path); 107 } 108 109 113 public void setKerningEnabled(boolean enabled) { 114 returnFont.setKerningEnabled(enabled); 115 } 116 117 121 public void setResolver(FontResolver resolver) { 122 returnFont.setResolver(resolver); 123 } 124 125 126 130 public Typeface getFont() { 131 return returnFont; 132 } 133 134 140 public FontReader(InputSource source) throws FOPException { 141 createFont(source); 142 } 143 144 147 public void startDocument() { 148 } 149 150 153 public void setDocumentLocator(Locator locator) { 154 this.locator = locator; 155 } 156 157 160 public void startElement(String uri, String localName, String qName, 161 Attributes attributes) throws SAXException { 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 (); 186 } else if ("kerning".equals(localName)) { 187 currentKerning = new java.util.HashMap (); 188 returnFont.putKerningEntry(new Integer (attributes.getValue("kpx1")), 189 currentKerning); 190 } else if ("bfranges".equals(localName)) { 191 bfranges = new java.util.ArrayList (); 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 (attributes.getValue("w"))); 199 } else if ("widths".equals(localName)) { 200 } else if ("char".equals(localName)) { 202 try { 203 singleFont.setWidth(Integer.parseInt(attributes.getValue("idx")), 204 Integer.parseInt(attributes.getValue("wdt"))); 205 } catch (NumberFormatException ne) { 206 throw new SAXException ("Malformed width in metric file: " 207 + ne.getMessage(), ne); 208 } 209 } else if ("pair".equals(localName)) { 210 currentKerning.put(new Integer (attributes.getValue("kpx2")), 211 new Integer (attributes.getValue("kern"))); 212 } 213 } 214 215 private int getInt(String str) throws SAXException { 216 int ret = 0; 217 try { 218 ret = Integer.parseInt(str); 219 } catch (Exception e) { 220 throw new SAXException ("Error while parsing integer value: " + str, e); 221 } 222 return ret; 223 } 224 225 228 public void endElement(String uri, String localName, String qName) throws SAXException { 229 String 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 i = (Integer )cidWidths.get(count); 283 wds[j++] = i.intValue(); 284 } 285 286 multiFont.setWidthArray(wds); 288 289 } else if ("bfranges".equals(localName)) { 290 multiFont.setBFEntries((BFEntry[])bfranges.toArray(new BFEntry[0])); 291 } 292 text.setLength(0); } 294 295 298 public void characters(char[] ch, int start, int length) { 299 text.append(ch, start, length); 300 } 301 } 302 303 304 | Popular Tags |