1 51 package org.apache.fop.fonts.type1; 52 53 import java.io.IOException ; 54 import java.io.InputStream ; 55 import java.io.DataInputStream ; 56 import java.io.BufferedInputStream ; 57 58 import org.apache.fop.tools.IOUtil; 60 61 66 public class PFBParser { 67 68 private static final byte[] CURRENTFILE_EEXEC; 69 private static final byte[] CLEARTOMARK; 70 71 static { 72 try { 73 CURRENTFILE_EEXEC = "currentfile eexec".getBytes("US-ASCII"); 74 CLEARTOMARK = "cleartomark".getBytes("US-ASCII"); 75 } catch (java.io.UnsupportedEncodingException e) { 76 throw new RuntimeException ("Incompatible VM. It doesn't support the US-ASCII encoding"); 77 } 78 } 79 80 81 87 public PFBData parsePFB(java.net.URL url) throws IOException { 88 InputStream in = url.openStream(); 89 try { 90 return parsePFB(in); 91 } finally { 92 in.close(); 93 } 94 } 95 96 97 103 public PFBData parsePFB(java.io.File pfbFile) throws IOException { 104 InputStream in = new java.io.FileInputStream (pfbFile); 105 try { 106 return parsePFB(in); 107 } finally { 108 in.close(); 109 } 110 } 111 112 113 119 public PFBData parsePFB(InputStream in) throws IOException { 120 PFBData pfb = new PFBData(); 121 BufferedInputStream bin = new BufferedInputStream (in); 122 DataInputStream din = new DataInputStream (bin); 123 din.mark(32); 124 int firstByte = din.readUnsignedByte(); 125 din.reset(); 126 if (firstByte == 128) { 127 pfb.setPFBFormat(PFBData.PFB_PC); 128 parsePCFormat(pfb, din); 129 } else { 130 pfb.setPFBFormat(PFBData.PFB_RAW); 131 parseRAWFormat(pfb, bin); 132 } 133 return pfb; 134 } 135 136 137 private static int swapInteger(final int value) { 138 return (((value >> 0) & 0xff) << 24) 139 + (((value >> 8) & 0xff) << 16) 140 + (((value >> 16) & 0xff) << 8) 141 + (((value >> 24) & 0xff) << 0); 142 } 143 144 145 private void parsePCFormat(PFBData pfb, DataInputStream din) throws IOException { 146 int segmentHead; 147 int segmentType; 148 int bytesRead; 149 150 segmentHead = din.readUnsignedByte(); 152 if (segmentHead != 128) { 153 throw new IOException ("Invalid file format. Expected ASCII 80hex"); 154 } 155 segmentType = din.readUnsignedByte(); int len1 = swapInteger(din.readInt()); 157 byte[] headerSegment = new byte[len1]; 158 din.readFully(headerSegment); 159 pfb.setHeaderSegment(headerSegment); 160 161 segmentHead = din.readUnsignedByte(); 163 if (segmentHead != 128) { 164 throw new IOException ("Invalid file format. Expected ASCII 80hex"); 165 } 166 segmentType = din.readUnsignedByte(); 167 int len2 = swapInteger(din.readInt()); 168 byte[] encryptedSegment = new byte[len2]; 169 din.readFully(encryptedSegment); 170 pfb.setEncryptedSegment(encryptedSegment); 171 172 segmentHead = din.readUnsignedByte(); 174 if (segmentHead != 128) { 175 throw new IOException ("Invalid file format. Expected ASCII 80hex"); 176 } 177 segmentType = din.readUnsignedByte(); 178 int len3 = swapInteger(din.readInt()); 179 byte[] trailerSegment = new byte[len3]; 180 din.readFully(trailerSegment); 181 pfb.setTrailerSegment(trailerSegment); 182 183 segmentHead = din.readUnsignedByte(); 185 if (segmentHead != 128) { 186 throw new IOException ("Invalid file format. Expected ASCII 80hex"); 187 } 188 segmentType = din.readUnsignedByte(); 189 if (segmentType != 3) { 190 throw new IOException ("Expected segment type 3, but found: " + segmentType); 191 } 192 } 193 194 195 private static final boolean byteCmp(byte[] src, int srcOffset, byte[] cmp) { 196 for (int i = 0; i < cmp.length; i++) { 197 if (src[srcOffset + i] != cmp[i]) { 199 return false; 200 } 201 } 202 return true; 203 } 204 205 private void calcLengths(PFBData pfb, byte[] originalData) { 206 209 int len1 = 30; 213 214 while (!byteCmp(originalData, len1 - CURRENTFILE_EEXEC.length, CURRENTFILE_EEXEC)) { 216 len1++; 217 } 218 219 len1++; 221 222 int len3 = 0; 224 len3 -= CLEARTOMARK.length; 225 while (!byteCmp(originalData, originalData.length + len3, CLEARTOMARK)) { 226 len3--; 227 } 229 len3 = -len3; 230 len3++; 231 int numZeroes = 0; 233 byte[] ws1 = new byte[]{0x0D}; byte[] ws2 = new byte[]{0x0A}; byte[] ws3 = new byte[]{0x30}; while ((originalData[originalData.length - len3] == ws1[0] 237 || originalData[originalData.length - len3] == ws2[0] 238 || originalData[originalData.length - len3] == ws3[0]) 239 && numZeroes < 512) { 240 len3++; 241 if (originalData[originalData.length - len3] == ws3[0]) { 242 numZeroes++; 243 } 244 } 245 247 byte[] buffer = new byte[len1]; 249 System.arraycopy(originalData, 0, buffer, 0, len1); 250 pfb.setHeaderSegment(buffer); 251 252 int len2 = originalData.length - len3 - len1; 253 buffer = new byte[len2]; 254 System.arraycopy(originalData, len1, buffer, 0, len2); 255 pfb.setEncryptedSegment(buffer); 256 257 buffer = new byte[len3]; 258 System.arraycopy(originalData, len1 + len2, buffer, 0, len3); 259 pfb.setTrailerSegment(buffer); 260 } 261 262 private void parseRAWFormat(PFBData pfb, BufferedInputStream bin) 263 throws IOException { 264 calcLengths(pfb, IOUtil.toByteArray(bin, 32768)); 265 } 266 267 } | Popular Tags |