1 29 30 package com.caucho.quercus.lib.pdf; 31 32 import com.caucho.util.L10N; 33 import com.caucho.vfs.MergePath; 34 import com.caucho.vfs.Path; 35 import com.caucho.vfs.ReadStream; 36 37 import java.io.FileNotFoundException ; 38 import java.io.IOException ; 39 40 43 public class AfmParser { 44 private static final L10N L = new L10N(AfmParser.class); 45 46 private static final String END_OF_FILE = "end of file"; 47 48 private ReadStream _is; 49 50 53 public Font parse(String name) 54 throws IOException 55 { 56 MergePath mergePath = new MergePath(); 57 mergePath.addClassPath(); 58 59 Path path = mergePath.lookup("com/caucho/quercus/lib/pdf/font/" + name + ".afm"); 60 61 if (! path.canRead()) 62 throw new FileNotFoundException (L.l("Can't find font {0}", name)); 63 64 _is = path.openRead(); 65 66 try { 67 return parseTop(); 68 } finally { 69 _is.close(); 70 } 71 } 72 73 private Font parseTop() 74 throws IOException 75 { 76 Font font = new Font(); 77 78 while (skipWhitespace()) { 79 String id = parseIdentifier(); 80 81 if ("FontName".equals(id)) { 82 font.setFontName(parseString()); 83 } 84 else if ("Weight".equals(id)) { 85 font.setWeight(parseString()); 86 } 87 else if ("FontBBox".equals(id)) { 88 font.setBBox(parseNumber(), parseNumber(), 89 parseNumber(), parseNumber()); 90 } 91 else if ("CapHeight".equals(id)) { 92 font.setCapHeight(parseNumber()); 93 } 94 else if ("XHeight".equals(id)) { 95 font.setXHeight(parseNumber()); 96 } 97 else if ("Ascender".equals(id)) { 98 font.setAscender(parseNumber()); 99 } 100 else if ("Descender".equals(id)) { 101 font.setDescender(parseNumber()); 102 } 103 else if ("UnderlinePosition".equals(id)) { 104 font.setUnderlinePosition(parseNumber()); 105 } 106 else if ("UnderlineThickness".equals(id)) { 107 font.setUnderlineThickness(parseNumber()); 108 } 109 else if ("C".equals(id)) { 110 font.addChar(parseCharacter()); 111 } 112 113 skipToEndOfLine(); 114 } 115 116 return font; 117 } 118 119 private FontChar parseCharacter() 120 throws IOException 121 { 122 int code = parseInteger(); 123 124 skipWhitespace(); 125 126 int ch; 127 128 if ((ch = _is.read()) != ';') 129 throw new IOException ("Expected ';'"); 130 131 String wx = parseString(); 132 133 if (! "WX".equals(wx)) 134 throw new IOException ("Expected 'WX'"); 135 136 double width = parseNumber(); 137 138 return new FontChar(code, width); 139 } 140 141 private String parseString() 142 throws IOException 143 { 144 skipWhitespace(); 145 146 StringBuilder sb = new StringBuilder (); 147 int ch; 148 149 while ((ch = _is.read()) >= 0 && ! Character.isWhitespace(ch)) { 150 sb.append((char) ch); 151 } 152 153 if (ch >= 0) 154 _is.unread(); 155 156 return sb.toString(); 157 } 158 159 private int parseInteger() 160 throws IOException 161 { 162 skipWhitespace(); 163 164 int value = 0; 165 int sign = 1; 166 167 int ch = _is.read(); 168 169 if (ch == '-') { 170 sign = -1; 171 ch = _is.read(); 172 } 173 174 for (; '0' <= ch && ch <= '9'; ch = _is.read()) { 175 value = 10 * value + ch - '0'; 176 } 177 178 if (ch >= 0) 179 _is.unread(); 180 181 return sign * value; 182 } 183 184 private double parseNumber() 185 throws IOException 186 { 187 skipWhitespace(); 188 189 StringBuilder sb = new StringBuilder (); 190 int ch; 191 192 while ('0' <= (ch = _is.read()) && ch <= '9' || 193 ch == '.' || ch == '-' || ch == '+') { 194 sb.append((char) ch); 195 } 196 197 if (ch >= 0) 198 _is.unread(); 199 200 if (sb.length() == 0) 201 return 0; 202 203 return Double.parseDouble(sb.toString()); 204 } 205 206 private String parseIdentifier() 207 throws IOException 208 { 209 StringBuilder sb = new StringBuilder (); 210 211 int ch; 212 213 while (Character.isLetterOrDigit((ch = _is.read()))) { 214 sb.append((char) ch); 215 } 216 217 _is.unread(); 218 219 return sb.toString(); 220 } 221 222 private void skipToEndOfLine() 223 throws IOException 224 { 225 int ch; 226 227 while ((ch = _is.read()) >= 0 && ch != '\n') { 228 } 229 } 230 231 private boolean skipWhitespace() 232 throws IOException 233 { 234 int ch; 235 236 while ((ch = _is.read()) == ' ' || ch == '\t') { 237 } 238 239 if (ch >= 0) 240 _is.unread(); 241 242 return ch >= 0; 243 } 244 } 245 | Popular Tags |