// Copyright 2001-2006, FreeHEP. package org.freehep.postscript; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.freehep.util.io.EEXECDecryption; public class PSCharStringDecoder { protected int currentX, currentY; private InputStream decryption; private List charProc; protected int sbX, sbY, widthX, widthY; private PSPackedArray array; private PSDictionary dict; public PSCharStringDecoder(PSDictionary dict) { this.dict = dict; } public PSGlyph decode(PSString charString) throws IOException { decryption = new EEXECDecryption(charString.getInputStream(), EEXECDecryption.CHARSTRING_R, EEXECDecryption.N); currentX = currentY = 0; charProc = new LinkedList(); boolean end = false; do { int byte1 = decryption.read(); if (byte1 < 0) { end = true; } else if (byte1 >= 0 && byte1 <= 31) { // command if (byte1 != 12) { switch (byte1) { case 14: addCommand("eofill"); break; case 13: hsbw(); break; case 9: addCommand("closepath"); break; case 6: addCommand("hlineto"); break; case 22: addCommand("hmoveto"); break; case 31: addCommand("hcurveto"); break; case 5: addCommand("rlineto"); break; case 21: addCommand("rmoveto"); break; case 8: addCommand("rrcurveto"); break; case 30: addCommand("vhcurveto"); break; case 7: addCommand("vlineto"); break; case 4: addCommand("vmoveto"); break; case 1: ignore(2); break; // hstem case 3: ignore(2); break; // vstem default: System.err.println("Command " + byte1 + " not implemented"); break; } } else { int byte2 = decryption.read(); switch (byte2) { case 7: sbw(); break; case 0: ignore(2); break; // dotsection case 2: ignore(6); break; // hstem3 case 1: ignore(6); break; // vstem3 case 33: addCommand("setcurrentpoint"); break; // vstem3 default: System.err.println("Command 12 " + byte2 + " not implemented"); break; } } } else { int value = readNumber(byte1); addNumber(value); } } while (!end); PSObject[] obj = new PSObject[charProc.size()]; Iterator i = charProc.iterator(); int j = 0; while (i.hasNext()) { obj[j++] = (PSObject) i.next(); } array = new PSPackedArray(obj); array.setExecutable(); return new PSType1Glyph(array, widthX, sbX); } private int readNumber(int v) throws IOException { int value = 0; if (v >= 32 && v <= 246) { value = v - 139; } else if (v >= 247 && v <= 250) { int w = decryption.read(); value = ((v - 247) * 256) + w + 108; } else if (v >= 251 && v <= 254) { int w = decryption.read(); value = -((v - 251) * 256) - w - 108; } else { // v == 255 value = decryption.read() << 3 * 8 + decryption.read() << 2 * 8 + decryption .read() << 1 * 8 + decryption.read() << 0 * 8; } return value; } private void addCommand(String name) { charProc.add(dict.get(name)); } private void addNumber(int i) { charProc.add(new PSInteger(i)); } private void ignore(int n) { for (int i = 0; i < n; i++) { charProc.remove(charProc.size() - 1); } } private int pop() { return ((PSInteger) charProc.remove(charProc.size() - 1)).getValue(); } private void hsbw() { widthY = 0; widthX = pop(); sbY = 0; sbX = pop(); addInitialPoint(); } private void sbw() { widthY = pop(); widthX = pop(); sbY = pop(); sbX = pop(); addInitialPoint(); } private void addInitialPoint() { if (sbX == 0) return; charProc.add(0, dict.get("moveto")); charProc.add(0, new PSInteger(0)); charProc.add(0, new PSInteger(sbX)); } // public int getSBX() { return sbX; } // public int getSBY() { return sbY; } // public int getWidthX() { return widthX; } // public int getWidthY() { return widthY; } // public PSPackedArray getPackedArray() { return array; } // public PSGlyph getGlyph() { // return new PSGlyph(array, widthX, sbX); // return null; // } }