1
47
48 package com.lowagie.text.pdf;
49 import java.io.BufferedReader;
50 import java.io.IOException;
51 import java.io.InputStream;
52 import java.io.InputStreamReader;
53 import java.io.UnsupportedEncodingException;
54 import java.util.ArrayList;
55 import java.util.HashMap;
56 import java.util.StringTokenizer;
57
58 import com.lowagie.text.ExceptionConverter;
59
64 public class PdfEncodings {
65 protected static final int CIDNONE = 0;
66 protected static final int CIDRANGE = 1;
67 protected static final int CIDCHAR = 2;
68
69 static final char winansiByteToChar[] = {
70 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
71 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
72 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
73 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
74 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
75 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
76 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
77 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
78 8364, 65533, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 65533, 381, 65533,
79 65533, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 65533, 382, 376,
80 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
81 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
82 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
83 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
84 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
85 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};
86
87 static final char pdfEncodingByteToChar[] = {
88 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
89 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
90 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
91 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
92 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
93 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
94 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
95 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
96 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018,
97 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 65533,
98 0x20ac, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
99 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
100 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
101 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
102 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
103 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};
104
105 static final IntHashtable winansi = new IntHashtable();
106
107 static final IntHashtable pdfEncoding = new IntHashtable();
108
109 static HashMap extraEncodings = new HashMap();
110
111 static {
112 for (int k = 128; k < 161; ++k) {
113 char c = winansiByteToChar[k];
114 if (c != 65533)
115 winansi.put(c, k);
116 }
117
118 for (int k = 128; k < 161; ++k) {
119 char c = pdfEncodingByteToChar[k];
120 if (c != 65533)
121 pdfEncoding.put(c, k);
122 }
123
124 addExtraEncoding("Wingdings", new WingdingsConversion());
125 addExtraEncoding("Symbol", new SymbolConversion(true));
126 addExtraEncoding("ZapfDingbats", new SymbolConversion(false));
127 addExtraEncoding("SymbolTT", new SymbolTTConversion());
128 addExtraEncoding("Cp437", new Cp437Conversion());
129 }
130
131
137 public static final byte[] convertToBytes(String text, String encoding) {
138 if (text == null)
139 return new byte[0];
140 if (encoding == null || encoding.length() == 0) {
141 int len = text.length();
142 byte b[] = new byte[len];
143 for (int k = 0; k < len; ++k)
144 b[k] = (byte)text.charAt(k);
145 return b;
146 }
147 ExtraEncoding extra = (ExtraEncoding)extraEncodings.get(encoding.toLowerCase());
148 if (extra != null) {
149 byte b[] = extra.charToByte(text, encoding);
150 if (b != null)
151 return b;
152 }
153 IntHashtable hash = null;
154 if (encoding.equals(BaseFont.WINANSI))
155 hash = winansi;
156 else if (encoding.equals(PdfObject.TEXT_PDFDOCENCODING))
157 hash = pdfEncoding;
158 if (hash != null) {
159 char cc[] = text.toCharArray();
160 int len = cc.length;
161 int ptr = 0;
162 byte b[] = new byte[len];
163 int c = 0;
164 for (int k = 0; k < len; ++k) {
165 char char1 = cc[k];
166 if (char1 < 128 || (char1 > 160 && char1 <= 255))
167 c = char1;
168 else
169 c = hash.get(char1);
170 if (c != 0)
171 b[ptr++] = (byte)c;
172 }
173 if (ptr == len)
174 return b;
175 byte b2[] = new byte[ptr];
176 System.arraycopy(b, 0, b2, 0, ptr);
177 return b2;
178 }
179 if (encoding.equals(PdfObject.TEXT_UNICODE)) {
180
181 char cc[] = text.toCharArray();
182 int len = cc.length;
183 byte b[] = new byte[cc.length * 2 + 2];
184 b[0] = -2;
185 b[1] = -1;
186 int bptr = 2;
187 for (int k = 0; k < len; ++k) {
188 char c = cc[k];
189 b[bptr++] = (byte)(c >> 8);
190 b[bptr++] = (byte)(c & 0xff);
191 }
192 return b;
193 }
194 try {
195 return text.getBytes(encoding);
196 }
197 catch (UnsupportedEncodingException e) {
198 throw new ExceptionConverter(e);
199 }
200 }
201
202
208 public static final byte[] convertToBytes(char char1, String encoding) {
209 if (encoding == null || encoding.length() == 0)
210 return new byte[]{(byte)char1};
211 ExtraEncoding extra = (ExtraEncoding)extraEncodings.get(encoding.toLowerCase());
212 if (extra != null) {
213 byte b[] = extra.charToByte(char1, encoding);
214 if (b != null)
215 return b;
216 }
217 IntHashtable hash = null;
218 if (encoding.equals(BaseFont.WINANSI))
219 hash = winansi;
220 else if (encoding.equals(PdfObject.TEXT_PDFDOCENCODING))
221 hash = pdfEncoding;
222 if (hash != null) {
223 int c = 0;
224 if (char1 < 128 || (char1 > 160 && char1 <= 255))
225 c = char1;
226 else
227 c = hash.get(char1);
228 if (c != 0)
229 return new byte[]{(byte)c};
230 else
231 return new byte[0];
232 }
233 if (encoding.equals(PdfObject.TEXT_UNICODE)) {
234
235 byte b[] = new byte[4];
236 b[0] = -2;
237 b[1] = -1;
238 b[2] = (byte)(char1 >> 8);
239 b[3] = (byte)(char1 & 0xff);
240 return b;
241 }
242 try {
243 return String.valueOf(char1).getBytes(encoding);
244 }
245 catch (UnsupportedEncodingException e) {
246 throw new ExceptionConverter(e);
247 }
248 }
249
250
256 public static final String convertToString(byte bytes[], String encoding) {
257 if (bytes == null)
258 return PdfObject.NOTHING;
259 if (encoding == null || encoding.length() == 0) {
260 char c[] = new char[bytes.length];
261 for (int k = 0; k < bytes.length; ++k)
262 c[k] = (char)(bytes[k] & 0xff);
263 return new String(c);
264 }
265 ExtraEncoding extra = (ExtraEncoding)extraEncodings.get(encoding.toLowerCase());
266 if (extra != null) {
267 String text = extra.byteToChar(bytes, encoding);
268 if (text != null)
269 return text;
270 }
271 char ch[] = null;
272 if (encoding.equals(BaseFont.WINANSI))
273 ch = winansiByteToChar;
274 else if (encoding.equals(PdfObject.TEXT_PDFDOCENCODING))
275 ch = pdfEncodingByteToChar;
276 if (ch != null) {
277 int len = bytes.length;
278 char c[] = new char[len];
279 for (int k = 0; k < len; ++k) {
280 c[k] = ch[bytes[k] & 0xff];
281 }
282 return new String(c);
283 }
284 try {
285 return new String(bytes, encoding);
286 }
287 catch (UnsupportedEncodingException e) {
288 throw new ExceptionConverter(e);
289 }
290 }
291
292
296 public static boolean isPdfDocEncoding(String text) {
297 if (text == null)
298 return true;
299 int len = text.length();
300 for (int k = 0; k < len; ++k) {
301 char char1 = text.charAt(k);
302 if (char1 < 128 || (char1 > 160 && char1 <= 255))
303 continue;
304 if (!pdfEncoding.containsKey(char1))
305 return false;
306 }
307 return true;
308 }
309
310 static final HashMap cmaps = new HashMap();
311
314 public static final byte CRLF_CID_NEWLINE[][] = new byte[][]{{(byte)'\n'}, {(byte)'\r', (byte)'\n'}};
315
316
322 public static void clearCmap(String name) {
323 synchronized (cmaps) {
324 if (name.length() == 0)
325 cmaps.clear();
326 else
327 cmaps.remove(name);
328 }
329 }
330
331
336 public static void loadCmap(String name, byte newline[][]) {
337 try {
338 char planes[][] = null;
339 synchronized (cmaps) {
340 planes = (char[][])cmaps.get(name);
341 }
342 if (planes == null) {
343 planes = readCmap(name, newline);
344 synchronized (cmaps) {
345 cmaps.put(name, planes);
346 }
347 }
348 }
349 catch (IOException e) {
350 throw new ExceptionConverter(e);
351 }
352 }
353
354
364 public static String convertCmap(String name, byte seq[]) {
365 return convertCmap(name, seq, 0, seq.length);
366 }
367
368
380 public static String convertCmap(String name, byte seq[], int start, int length) {
381 try {
382 char planes[][] = null;
383 synchronized (cmaps) {
384 planes = (char[][])cmaps.get(name);
385 }
386 if (planes == null) {
387 planes = readCmap(name, (byte[][])null);
388 synchronized (cmaps) {
389 cmaps.put(name, planes);
390 }
391 }
392 return decodeSequence(seq, start, length, planes);
393 }
394 catch (IOException e) {
395 throw new ExceptionConverter(e);
396 }
397 }
398
399 static String decodeSequence(byte seq[], int start, int length, char planes[][]) {
400 StringBuffer buf = new StringBuffer();
401 int end = start + length;
402 int currentPlane = 0;
403 for (int k = start; k < end; ++k) {
404 int one = seq[k] & 0xff;
405 char plane[] = planes[currentPlane];
406 int cid = plane[one];
407 if ((cid & 0x8000) == 0) {
408 buf.append((char)cid);
409 currentPlane = 0;
410 }
411 else
412 currentPlane = cid & 0x7fff;
413 }
414 return buf.toString();
415 }
416
417 static char[][] readCmap(String name, byte newline[][]) throws IOException {
418 ArrayList planes = new ArrayList();
419 planes.add(new char[256]);
420 readCmap(name, planes);
421 if (newline != null) {
422 for (int k = 0; k < newline.length; ++k)
423 encodeSequence(newline[k].length, newline[k], BaseFont.CID_NEWLINE, planes);
424 }
425 char ret[][] = new char[planes.size()][];
426 return (char[][])planes.toArray(ret);
427 }
428
429 static void readCmap(String name, ArrayList planes) throws IOException {
430 String fullName = BaseFont.RESOURCE_PATH + "cmaps/" + name;
431 InputStream in = BaseFont.getResourceStream(fullName);
432 if (in == null)
433 throw new IOException("The Cmap " + name + " was not found.");
434 encodeStream(in, planes);
435 in.close();
436 }
437
438 static void encodeStream(InputStream in, ArrayList planes) throws IOException {
439 BufferedReader rd = new BufferedReader(new InputStreamReader(in, "iso-8859-1"));
440 String line = null;
441 int state = CIDNONE;
442 byte seqs[] = new byte[7];
443 while ((line = rd.readLine()) != null) {
444 if (line.length() < 6)
445 continue;
446 switch (state) {
447 case CIDNONE: {
448 if (line.indexOf("begincidrange") >= 0)
449 state = CIDRANGE;
450 else if (line.indexOf("begincidchar") >= 0)
451 state = CIDCHAR;
452 else if (line.indexOf("usecmap") >= 0) {
453 StringTokenizer tk = new StringTokenizer(line);
454 String t = tk.nextToken();
455 readCmap(t.substring(1), planes);
456 }
457 break;
458 }
459 case CIDRANGE: {
460 if (line.indexOf("endcidrange") >= 0) {
461 state = CIDNONE;
462 break;
463 }
464 StringTokenizer tk = new StringTokenizer(line);
465 String t = tk.nextToken();
466 int size = t.length() / 2 - 1;
467 long start = Long.parseLong(t.substring(1, t.length() - 1), 16);
468 t = tk.nextToken();
469 long end = Long.parseLong(t.substring(1, t.length() - 1), 16);
470 t = tk.nextToken();
471 int cid = Integer.parseInt(t);
472 for (long k = start; k <= end; ++k) {
473 breakLong(k, size, seqs);
474 encodeSequence(size, seqs, (char)cid, planes);
475 ++cid;
476 }
477 break;
478 }
479 case CIDCHAR: {
480 if (line.indexOf("endcidchar") >= 0) {
481 state = CIDNONE;
482 break;
483 }
484 StringTokenizer tk = new StringTokenizer(line);
485 String t = tk.nextToken();
486 int size = t.length() / 2 - 1;
487 long start = Long.parseLong(t.substring(1, t.length() - 1), 16);
488 t = tk.nextToken();
489 int cid = Integer.parseInt(t);
490 breakLong(start, size, seqs);
491 encodeSequence(size, seqs, (char)cid, planes);
492 break;
493 }
494 }
495 }
496 }
497
498 static void breakLong(long n, int size, byte seqs[]) {
499 for (int k = 0; k < size; ++k) {
500 seqs[k] = (byte)(n >> ((size - 1 - k) * 8));
501 }
502 }
503
504 static void encodeSequence(int size, byte seqs[], char cid, ArrayList planes) {
505 --size;
506 int nextPlane = 0;
507 for (int idx = 0; idx < size; ++idx) {
508 char plane[] = (char[])planes.get(nextPlane);
509 int one = seqs[idx] & 0xff;
510 char c = plane[one];
511 if (c != 0 && (c & 0x8000) == 0)
512 throw new RuntimeException("Inconsistent mapping.");
513 if (c == 0) {
514 planes.add(new char[256]);
515 c = (char)((planes.size() - 1) | 0x8000);
516 plane[one] = c;
517 }
518 nextPlane = c & 0x7fff;
519 }
520 char plane[] = (char[])planes.get(nextPlane);
521 int one = seqs[size] & 0xff;
522 char c = plane[one];
523 if ((c & 0x8000) != 0)
524 throw new RuntimeException("Inconsistent mapping.");
525 plane[one] = cid;
526 }
527
528
532 public static void addExtraEncoding(String name, ExtraEncoding enc) {
533 synchronized (extraEncodings) {
534 HashMap newEncodings = (HashMap)extraEncodings.clone();
535 newEncodings.put(name.toLowerCase(), enc);
536 extraEncodings = newEncodings;
537 }
538 }
539
540 private static class WingdingsConversion implements ExtraEncoding {
541
542 public byte[] charToByte(char char1, String encoding) {
543 if (char1 == ' ')
544 return new byte[]{(byte)char1};
545 else if (char1 >= '\u2701' && char1 <= '\u27BE') {
546 byte v = table[char1 - 0x2700];
547 if (v != 0)
548 return new byte[]{v};
549 }
550 return new byte[0];
551 }
552
553 public byte[] charToByte(String text, String encoding) {
554 char cc[] = text.toCharArray();
555 byte b[] = new byte[cc.length];
556 int ptr = 0;
557 int len = cc.length;
558 for (int k = 0; k < len; ++k) {
559 char c = cc[k];
560 if (c == ' ')
561 b[ptr++] = (byte)c;
562 else if (c >= '\u2701' && c <= '\u27BE') {
563 byte v = table[c - 0x2700];
564 if (v != 0)
565 b[ptr++] = v;
566 }
567 }
568 if (ptr == len)
569 return b;
570 byte b2[] = new byte[ptr];
571 System.arraycopy(b, 0, b2, 0, ptr);
572 return b2;
573 }
574
575 public String byteToChar(byte[] b, String encoding) {
576 return null;
577 }
578
579 private final static byte table[] = {
580 0, 35, 34, 0, 0, 0, 41, 62, 81, 42,
581 0, 0, 65, 63, 0, 0, 0, 0, 0, -4,
582 0, 0, 0, -5, 0, 0, 0, 0, 0, 0,
583 86, 0, 88, 89, 0, 0, 0, 0, 0, 0,
584 0, 0, -75, 0, 0, 0, 0, 0, -74, 0,
585 0, 0, -83, -81, -84, 0, 0, 0, 0, 0,
586 0, 0, 0, 124, 123, 0, 0, 0, 84, 0,
587 0, 0, 0, 0, 0, 0, 0, -90, 0, 0,
588 0, 113, 114, 0, 0, 0, 117, 0, 0, 0,
589 0, 0, 0, 125, 126, 0, 0, 0, 0, 0,
590 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
591 0, 0, 0, 0, 0, 0, 0, 0, -116, -115,
592 -114, -113, -112, -111, -110, -109, -108, -107, -127, -126,
593 -125, -124, -123, -122, -121, -120, -119, -118, -116, -115,
594 -114, -113, -112, -111, -110, -109, -108, -107, -24, 0,
595 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
596 0, -24, -40, 0, 0, -60, -58, 0, 0, -16,
597 0, 0, 0, 0, 0, 0, 0, 0, 0, -36,
598 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
599 0
600 };
601 }
602
603 private static class Cp437Conversion implements ExtraEncoding {
604 private static IntHashtable c2b = new IntHashtable();
605
606 public byte[] charToByte(String text, String encoding) {
607 char cc[] = text.toCharArray();
608 byte b[] = new byte[cc.length];
609 int ptr = 0;
610 int len = cc.length;
611 for (int k = 0; k < len; ++k) {
612 char c = cc[k];
613 if (c < 128)
614 b[ptr++] = (byte)c;
615 else {
616 byte v = (byte)c2b.get(c);
617 if (v != 0)
618 b[ptr++] = v;
619 }
620 }
621 if (ptr == len)
622 return b;
623 byte b2[] = new byte[ptr];
624 System.arraycopy(b, 0, b2, 0, ptr);
625 return b2;
626 }
627
628 public byte[] charToByte(char char1, String encoding) {
629 if (char1 < 128)
630 return new byte[]{(byte)char1};
631 else {
632 byte v = (byte)c2b.get(char1);
633 if (v != 0)
634 return new byte[]{v};
635 else
636 return new byte[0];
637 }
638 }
639
640 public String byteToChar(byte[] b, String encoding) {
641 int len = b.length;
642 char cc[] = new char[len];
643 int ptr = 0;
644 for (int k = 0; k < len; ++k) {
645 int c = b[k] & 0xff;
646 if (c < ' ')
647 continue;
648 if (c < 128)
649 cc[ptr++] = (char)c;
650 else {
651 char v = table[c - 128];
652 cc[ptr++] = v;
653 }
654 }
655 return new String(cc, 0, ptr);
656 }
657
658 private final static char table[] = {
659 '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5',
660 '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', '\u00FF', '\u00D6', '\u00DC', '\u00A2', '\u00A3', '\u00A5', '\u20A7', '\u0192',
661 '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', '\u00AA', '\u00BA', '\u00BF', '\u2310', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB',
662 '\u2591', '\u2592', '\u2593', '\u2502', '\u2524', '\u2561', '\u2562', '\u2556', '\u2555', '\u2563', '\u2551', '\u2557', '\u255D', '\u255C', '\u255B', '\u2510',
663 '\u2514', '\u2534', '\u252C', '\u251C', '\u2500', '\u253C', '\u255E', '\u255F', '\u255A', '\u2554', '\u2569', '\u2566', '\u2560', '\u2550', '\u256C', '\u2567',
664 '\u2568', '\u2564', '\u2565', '\u2559', '\u2558', '\u2552', '\u2553', '\u256B', '\u256A', '\u2518', '\u250C', '\u2588', '\u2584', '\u258C', '\u2590', '\u2580',
665 '\u03B1', '\u00DF', '\u0393', '\u03C0', '\u03A3', '\u03C3', '\u00B5', '\u03C4', '\u03A6', '\u0398', '\u03A9', '\u03B4', '\u221E', '\u03C6', '\u03B5', '\u2229',
666 '\u2261', '\u00B1', '\u2265', '\u2264', '\u2320', '\u2321', '\u00F7', '\u2248', '\u00B0', '\u2219', '\u00B7', '\u221A', '\u207F', '\u00B2', '\u25A0', '\u00A0'
667 };
668
669 static {
670 for (int k = 0; k < table.length; ++k)
671 c2b.put(table[k], k + 128);
672 }
673 }
674
675 private static class SymbolConversion implements ExtraEncoding {
676
677 private static final IntHashtable t1 = new IntHashtable();
678 private static final IntHashtable t2 = new IntHashtable();
679 private IntHashtable translation;
680
681 SymbolConversion(boolean symbol) {
682 if (symbol)
683 translation = t1;
684 else
685 translation = t2;
686 }
687
688 public byte[] charToByte(String text, String encoding) {
689 char cc[] = text.toCharArray();
690 byte b[] = new byte[cc.length];
691 int ptr = 0;
692 int len = cc.length;
693 for (int k = 0; k < len; ++k) {
694 char c = cc[k];
695 byte v = (byte)translation.get(c);
696 if (v != 0)
697 b[ptr++] = v;
698 }
699 if (ptr == len)
700 return b;
701 byte b2[] = new byte[ptr];
702 System.arraycopy(b, 0, b2, 0, ptr);
703 return b2;
704 }
705
706 public byte[] charToByte(char char1, String encoding) {
707 byte v = (byte)translation.get(char1);
708 if (v != 0)
709 return new byte[]{v};
710 else
711 return new byte[0];
712 }
713
714 public String byteToChar(byte[] b, String encoding) {
715 return null;
716 }
717
718 private final static char table1[] = {
719 ' ','!','\u2200','#','\u2203','%','&','\u220b','(',')','*','+',',','-','.','/',
720 '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?',
721 '\u2245','\u0391','\u0392','\u03a7','\u0394','\u0395','\u03a6','\u0393','\u0397','\u0399','\u03d1','\u039a','\u039b','\u039c','\u039d','\u039f',
722 '\u03a0','\u0398','\u03a1','\u03a3','\u03a4','\u03a5','\u03c2','\u03a9','\u039e','\u03a8','\u0396','[','\u2234',']','\u22a5','_',
723 '\u0305','\u03b1','\u03b2','\u03c7','\u03b4','\u03b5','\u03d5','\u03b3','\u03b7','\u03b9','\u03c6','\u03ba','\u03bb','\u03bc','\u03bd','\u03bf',
724 '\u03c0','\u03b8','\u03c1','\u03c3','\u03c4','\u03c5','\u03d6','\u03c9','\u03be','\u03c8','\u03b6','{','|','}','~','\0',
725 '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
726 '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
727 '\u20ac','\u03d2','\u2032','\u2264','\u2044','\u221e','\u0192','\u2663','\u2666','\u2665','\u2660','\u2194','\u2190','\u2191','\u2192','\u2193',
728 '\u00b0','\u00b1','\u2033','\u2265','\u00d7','\u221d','\u2202','\u2022','\u00f7','\u2260','\u2261','\u2248','\u2026','\u2502','\u2500','\u21b5',
729 '\u2135','\u2111','\u211c','\u2118','\u2297','\u2295','\u2205','\u2229','\u222a','\u2283','\u2287','\u2284','\u2282','\u2286','\u2208','\u2209',
730 '\u2220','\u2207','\u00ae','\u00a9','\u2122','\u220f','\u221a','\u2022','\u00ac','\u2227','\u2228','\u21d4','\u21d0','\u21d1','\u21d2','\u21d3',
731 '\u25ca','\u2329','\0','\0','\0','\u2211','\u239b','\u239c','\u239d','\u23a1','\u23a2','\u23a3','\u23a7','\u23a8','\u23a9','\u23aa',
732 '\0','\u232a','\u222b','\u2320','\u23ae','\u2321','\u239e','\u239f','\u23a0','\u23a4','\u23a5','\u23a6','\u23ab','\u23ac','\u23ad','\0'
733 };
734
735 private final static char table2[] = {
736 '\u0020','\u2701','\u2702','\u2703','\u2704','\u260e','\u2706','\u2707','\u2708','\u2709','\u261b','\u261e','\u270C','\u270D','\u270E','\u270F',
737 '\u2710','\u2711','\u2712','\u2713','\u2714','\u2715','\u2716','\u2717','\u2718','\u2719','\u271A','\u271B','\u271C','\u271D','\u271E','\u271F',
738 '\u2720','\u2721','\u2722','\u2723','\u2724','\u2725','\u2726','\u2727','\u2605','\u2729','\u272A','\u272B','\u272C','\u272D','\u272E','\u272F',
739 '\u2730','\u2731','\u2732','\u2733','\u2734','\u2735','\u2736','\u2737','\u2738','\u2739','\u273A','\u273B','\u273C','\u273D','\u273E','\u273F',
740 '\u2740','\u2741','\u2742','\u2743','\u2744','\u2745','\u2746','\u2747','\u2748','\u2749','\u274A','\u274B','\u25cf','\u274D','\u25a0','\u274F',
741 '\u2750','\u2751','\u2752','\u25b2','\u25bc','\u25c6','\u2756','\u25d7','\u2758','\u2759','\u275A','\u275B','\u275C','\u275D','\u275E','\u0000',
742 '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
743 '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
744 '\u0000','\u2761','\u2762','\u2763','\u2764','\u2765','\u2766','\u2767','\u2663','\u2666','\u2665','\u2660','\u2460','\u2461','\u2462','\u2463',
745 '\u2464','\u2465','\u2466','\u2467','\u2468','\u2469','\u2776','\u2777','\u2778','\u2779','\u277A','\u277B','\u277C','\u277D','\u277E','\u277F',
746 '\u2780','\u2781','\u2782','\u2783','\u2784','\u2785','\u2786','\u2787','\u2788','\u2789','\u278A','\u278B','\u278C','\u278D','\u278E','\u278F',
747 '\u2790','\u2791','\u2792','\u2793','\u2794','\u2192','\u2194','\u2195','\u2798','\u2799','\u279A','\u279B','\u279C','\u279D','\u279E','\u279F',
748 '\u27A0','\u27A1','\u27A2','\u27A3','\u27A4','\u27A5','\u27A6','\u27A7','\u27A8','\u27A9','\u27AA','\u27AB','\u27AC','\u27AD','\u27AE','\u27AF',
749 '\u0000','\u27B1','\u27B2','\u27B3','\u27B4','\u27B5','\u27B6','\u27B7','\u27B8','\u27B9','\u27BA','\u27BB','\u27BC','\u27BD','\u27BE','\u0000'
750 };
751
752 static {
753 for (int k = 0; k < table1.length; ++k) {
754 int v = table1[k];
755 if (v != 0)
756 t1.put(v, k + 32);
757 }
758 for (int k = 0; k < table2.length; ++k) {
759 int v = table2[k];
760 if (v != 0)
761 t2.put(v, k + 32);
762 }
763 }
764 }
765
766 private static class SymbolTTConversion implements ExtraEncoding {
767
768 public byte[] charToByte(char char1, String encoding) {
769 if ((char1 & 0xff00) == 0 || (char1 & 0xff00) == 0xf000)
770 return new byte[]{(byte)char1};
771 else
772 return new byte[0];
773 }
774
775 public byte[] charToByte(String text, String encoding) {
776 char ch[] = text.toCharArray();
777 byte b[] = new byte[ch.length];
778 int ptr = 0;
779 int len = ch.length;
780 for (int k = 0; k < len; ++k) {
781 char c = ch[k];
782 if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000)
783 b[ptr++] = (byte)c;
784 }
785 if (ptr == len)
786 return b;
787 byte b2[] = new byte[ptr];
788 System.arraycopy(b, 0, b2, 0, ptr);
789 return b2;
790 }
791
792 public String byteToChar(byte[] b, String encoding) {
793 return null;
794 }
795
796 }
797 }
798