001: /**
002: * AfmCompiler.java
003: *
004: Copyright (c) 2007, Innovatics Inc.
005:
006: All rights reserved.
007:
008: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
009:
010: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
011: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
012:
013: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
014: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
015: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
016: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
017: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
018: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
019: PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
020: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
021: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
022: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
023: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
024: */package util;
025:
026: import java.lang.*;
027: import java.io.*;
028: import java.util.*;
029:
030: /**
031: * AfmCompiler.java
032: * Extracts information from .afm file and creates
033: * .java and .cs files containing the font metrics.
034: */
035: public class AfmCompiler {
036:
037: public AfmCompiler(String path, String fontName, String lang) {
038:
039: boolean generateJava = false;
040: if (lang.equals("Java")) {
041: generateJava = true;
042: }
043:
044: StringBuffer[] data = new StringBuffer[256];
045: for (int i = 32; i < 256; i++) {
046: data[i] = new StringBuffer();
047: }
048:
049: Map<String, String> map = new HashMap<String, String>();
050: try {
051: BufferedReader in = new BufferedReader(new FileReader(path
052: + fontName));
053: String className = fontName.substring(0, fontName
054: .lastIndexOf('.'));
055: className = className.replace('-', '_');
056: BufferedWriter out = null;
057: if (generateJava) {
058: out = new BufferedWriter(new FileWriter("com/pdfjet/"
059: + className + ".java"));
060: out.write("package com.pdfjet;\n\n");
061: out.write("public class " + className
062: + " extends CoreFont {\n");
063: } else {
064: out = new BufferedWriter(new FileWriter("net/pdfjet/"
065: + className + ".cs"));
066: out.write("namespace PDFjet.NET {\n");
067: out.write("public class " + className
068: + " : CoreFont {\n");
069: }
070:
071: List<String> list = new ArrayList<String>();
072: String line = null;
073: while ((line = in.readLine()) != null) {
074: list.clear();
075: StringTokenizer st = new StringTokenizer(line, " ;");
076: while (st.hasMoreTokens())
077: list.add(st.nextToken());
078:
079: int index = 0;
080: if (list.get(0).equals("FontBBox")) {
081: // FontBBox -166 -225 1000 931
082: out.write(" int bBoxLLx = " + list.get(1)
083: + ";\n");
084: out.write(" int bBoxLLy = " + list.get(2)
085: + ";\n");
086: out.write(" int bBoxURx = " + list.get(3)
087: + ";\n");
088: out.write(" int bBoxURy = " + list.get(4)
089: + ";\n");
090: if (generateJava) {
091: out.write(" protected int getBBoxLLx() {\n");
092: out.write(" return bBoxLLx;\n");
093: out.write(" }\n");
094: out.write(" protected int getBBoxLLy() {\n");
095: out.write(" return bBoxLLy;\n");
096: out.write(" }\n");
097: out.write(" protected int getBBoxURx() {\n");
098: out.write(" return bBoxURx;\n");
099: out.write(" }\n");
100: out.write(" protected int getBBoxURy() {\n");
101: out.write(" return bBoxURy;\n");
102: out.write(" }\n");
103: } else {
104: out
105: .write(" internal override int getBBoxLLx() {\n");
106: out.write(" return bBoxLLx;\n");
107: out.write(" }\n");
108: out
109: .write(" internal override int getBBoxLLy() {\n");
110: out.write(" return bBoxLLy;\n");
111: out.write(" }\n");
112: out
113: .write(" internal override int getBBoxURx() {\n");
114: out.write(" return bBoxURx;\n");
115: out.write(" }\n");
116: out
117: .write(" internal override int getBBoxURy() {\n");
118: out.write(" return bBoxURy;\n");
119: out.write(" }\n");
120: }
121: } else if (list.get(0).equals("Notice")) {
122: if (generateJava) {
123: out
124: .write(" protected static final String notice = \"");
125: } else {
126: out
127: .write(" protected const string notice = \"");
128: }
129: out.write(line.substring(7));
130: out.write("\";\n");
131: } else if (list.get(0).equals("StartCharMetrics")) {
132: out.write(" int[][] data = {\n");
133: } else if (list.get(0).equals("C")) {
134: // C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
135: String name = list.get(5);
136:
137: boolean found = false;
138: for (int i = 32; i < 256; i++) {
139: if (name.equals(com.pdfjet.Glyph.names[i - 32])) {
140: index = i;
141: found = true;
142: break;
143: }
144: }
145: if (!found)
146: continue;
147:
148: map.put(name, String.valueOf(index));
149: if (generateJava) {
150: data[index].append(" {");
151: } else {
152: data[index].append(" new int[] {");
153: }
154: data[index].append(String.valueOf(index));
155: data[index].append(',');
156: data[index].append(list.get(3));
157: data[index].append(',');
158: } else if (list.get(0).equals("KPX")) {
159: // KPX o v -15
160: if (!map.containsKey(list.get(1))
161: || !map.containsKey(list.get(2))) {
162: continue;
163: }
164: index = Integer.parseInt(map.get(list.get(1)));
165: data[index].append(map.get(list.get(2)));
166: data[index].append(',');
167: data[index].append(list.get(3));
168: data[index].append(',');
169: }
170: }
171:
172: for (int i = 32; i < data.length; i++) {
173: if (data[i].length() == 0) {
174: if (generateJava) {
175: out.write(" {");
176: } else {
177: out.write(" new int[] {");
178: }
179: out.write(String.valueOf(i));
180: String bullet = data[183].toString();
181: out.write(bullet
182: .substring(bullet.indexOf("183") + 3));
183: } else {
184: out.write(data[i].toString());
185: }
186: out.write("},\n");
187: }
188: out.write(" };\n\n");
189:
190: if (generateJava) {
191: out.write(" protected int[][] getMetrics() {\n");
192: } else {
193: out
194: .write(" internal override int[][] getMetrics() {\n");
195: }
196: out.write(" return data;\n");
197: out.write(" }\n");
198: out.write("}\n");
199:
200: if (lang.equals("C#")) {
201: out.write("} // End of namespace PDFjet.NET\n");
202: }
203:
204: in.close();
205: out.close();
206: } catch (Exception e) {
207: System.err.println(e);
208: }
209: }
210:
211: // Special compiler for the Symbol.afm and ZapfDingbats.afm
212: public AfmCompiler(String path, String fontName, String lang,
213: String symbol) {
214:
215: boolean generateJava = false;
216: if (lang.equals("Java")) {
217: generateJava = true;
218: }
219:
220: StringBuffer[] data = new StringBuffer[256];
221: for (int i = 32; i < 256; i++) {
222: data[i] = new StringBuffer();
223: }
224:
225: try {
226: BufferedReader in = new BufferedReader(new FileReader(path
227: + fontName));
228: String className = fontName.substring(0, fontName
229: .lastIndexOf('.'));
230:
231: BufferedWriter out = null;
232: if (generateJava) {
233: out = new BufferedWriter(new FileWriter("com/pdfjet/"
234: + className + ".java"));
235: out.write("package com.pdfjet;\n\n");
236: out.write("public class " + className
237: + " extends CoreFont {\n");
238: } else {
239: out = new BufferedWriter(new FileWriter("net/pdfjet/"
240: + className + ".cs"));
241: out.write("namespace PDFjet.NET {\n");
242: out.write("public class " + className
243: + " : CoreFont {\n");
244: }
245:
246: List<String> list = new ArrayList<String>();
247: String line = null;
248: while ((line = in.readLine()) != null) {
249: list.clear();
250: StringTokenizer st = new StringTokenizer(line, " ;");
251: while (st.hasMoreTokens())
252: list.add(st.nextToken());
253:
254: if (list.get(0).equals("FontBBox")) {
255: // FontBBox -166 -225 1000 931
256: out.write(" int bBoxLLx = " + list.get(1)
257: + ";\n");
258: out.write(" int bBoxLLy = " + list.get(2)
259: + ";\n");
260: out.write(" int bBoxURx = " + list.get(3)
261: + ";\n");
262: out.write(" int bBoxURy = " + list.get(4)
263: + ";\n");
264: if (generateJava) {
265: out.write(" protected int getBBoxLLx() {\n");
266: out.write(" return bBoxLLx;\n");
267: out.write(" }\n");
268: out.write(" protected int getBBoxLLy() {\n");
269: out.write(" return bBoxLLy;\n");
270: out.write(" }\n");
271: out.write(" protected int getBBoxURx() {\n");
272: out.write(" return bBoxURx;\n");
273: out.write(" }\n");
274: out.write(" protected int getBBoxURy() {\n");
275: out.write(" return bBoxURy;\n");
276: out.write(" }\n");
277: } else {
278: out
279: .write(" internal override int getBBoxLLx() {\n");
280: out.write(" return bBoxLLx;\n");
281: out.write(" }\n");
282: out
283: .write(" internal override int getBBoxLLy() {\n");
284: out.write(" return bBoxLLy;\n");
285: out.write(" }\n");
286: out
287: .write(" internal override int getBBoxURx() {\n");
288: out.write(" return bBoxURx;\n");
289: out.write(" }\n");
290: out
291: .write(" internal override int getBBoxURy() {\n");
292: out.write(" return bBoxURy;\n");
293: out.write(" }\n");
294: }
295: } else if (list.get(0).equals("Notice")) {
296: if (generateJava) {
297: out
298: .write(" protected static final String notice = \"");
299: } else {
300: out
301: .write(" protected const string notice = \"");
302: }
303: out.write(line.substring(7));
304: out.write("\";\n");
305: } else if (list.get(0).equals("StartCharMetrics")) {
306: out.write(" int[][] data = {\n");
307: } else if (list.get(0).equals("C")) {
308: // C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
309: String ch = list.get(1);
310: String wx = list.get(3);
311:
312: if (ch.equals("32")) {
313: for (int i = 32; i < 256; i++) {
314: if (generateJava) {
315: data[i].append(" {");
316: } else {
317: data[i].append(" new int[] {");
318: }
319: data[i].append(i);
320: data[i].append(',');
321: data[i].append(wx);
322: data[i].append("},\n");
323: }
324: } else {
325: int i = Integer.parseInt(ch);
326: if (i > 0) {
327: data[i] = new StringBuffer();
328: if (generateJava) {
329: data[i].append(" {");
330: } else {
331: data[i].append(" new int[] {");
332: }
333: data[i].append(ch);
334: data[i].append(',');
335: data[i].append(wx);
336: data[i].append("},\n");
337: }
338: }
339: }
340: }
341:
342: for (int i = 32; i < 256; i++) {
343: out.write(data[i].toString());
344: }
345:
346: out.write(" };\n\n");
347:
348: if (generateJava) {
349: out.write(" protected int[][] getMetrics() {\n");
350: } else {
351: out
352: .write(" internal override int[][] getMetrics() {\n");
353: }
354: out.write(" return data;\n");
355: out.write(" }\n");
356: out.write("}\n");
357:
358: if (lang.equals("C#")) {
359: out.write("}\n");
360: }
361:
362: in.close();
363: out.close();
364: } catch (Exception e) {
365: System.err.println(e);
366: }
367: }
368:
369: public static void main(String[] args) {
370: File file = new File("./afm/");
371: String[] fileNames = file.list(new util.AfmFilenameFilter());
372: for (int i = 0; i < fileNames.length; i++) {
373: if (fileNames[i].equals("Symbol.afm")
374: || fileNames[i].equals("ZapfDingbats.afm")) {
375: new AfmCompiler("./afm/", fileNames[i], "Java",
376: "Symbol");
377: new AfmCompiler("./afm/", fileNames[i], "C#", "Symbol");
378: } else {
379: new AfmCompiler("./afm/", fileNames[i], "Java");
380: new AfmCompiler("./afm/", fileNames[i], "C#");
381: }
382: }
383: }
384:
385: } // End of AfmCompiler.java
386:
387: class AfmFilenameFilter implements FilenameFilter {
388:
389: public boolean accept(File dir, String name) {
390: if (name.endsWith(".afm")) {
391: return true;
392: }
393: return false;
394: }
395:
396: } // End of AfmFilenameFilter.java
|