1 50 51 package com.lowagie.text.pdf; 52 import java.io.IOException ; 53 import java.io.InputStream ; 54 import java.util.ArrayList ; 55 import java.util.HashMap ; 56 import java.util.Iterator ; 57 import java.util.StringTokenizer ; 58 59 import com.lowagie.text.DocumentException; 60 61 66 67 public abstract class BaseFont { 68 69 70 public static final String COURIER = "Courier"; 71 72 73 public static final String COURIER_BOLD = "Courier-Bold"; 74 75 76 public static final String COURIER_OBLIQUE = "Courier-Oblique"; 77 78 79 public static final String COURIER_BOLDOBLIQUE = "Courier-BoldOblique"; 80 81 82 public static final String HELVETICA = "Helvetica"; 83 84 85 public static final String HELVETICA_BOLD = "Helvetica-Bold"; 86 87 88 public static final String HELVETICA_OBLIQUE = "Helvetica-Oblique"; 89 90 91 public static final String HELVETICA_BOLDOBLIQUE = "Helvetica-BoldOblique"; 92 93 94 public static final String SYMBOL = "Symbol"; 95 96 97 public static final String TIMES_ROMAN = "Times-Roman"; 98 99 100 public static final String TIMES_BOLD = "Times-Bold"; 101 102 103 public static final String TIMES_ITALIC = "Times-Italic"; 104 105 106 public static final String TIMES_BOLDITALIC = "Times-BoldItalic"; 107 108 109 public static final String ZAPFDINGBATS = "ZapfDingbats"; 110 111 114 public static final int ASCENT = 1; 115 118 public static final int CAPHEIGHT = 2; 119 122 public static final int DESCENT = 3; 123 127 public static final int ITALICANGLE = 4; 128 130 public static final int BBOXLLX = 5; 131 133 public static final int BBOXLLY = 6; 134 136 public static final int BBOXURX = 7; 137 139 public static final int BBOXURY = 8; 140 141 142 public static final int AWT_ASCENT = 9; 143 144 public static final int AWT_DESCENT = 10; 145 146 public static final int AWT_LEADING = 11; 147 148 public static final int AWT_MAXADVANCE = 12; 149 150 152 public static final int FONT_TYPE_T1 = 0; 153 155 public static final int FONT_TYPE_TT = 1; 156 158 public static final int FONT_TYPE_CJK = 2; 159 161 public static final int FONT_TYPE_TTUNI = 3; 162 164 public static final int FONT_TYPE_DOCUMENT = 4; 165 167 public static final int FONT_TYPE_T3 = 5; 168 170 public static final String IDENTITY_H = "Identity-H"; 171 173 public static final String IDENTITY_V = "Identity-V"; 174 175 176 public static final String CP1250 = "Cp1250"; 177 178 179 public static final String CP1252 = "Cp1252"; 180 181 182 public static final String CP1257 = "Cp1257"; 183 184 185 public static final String WINANSI = "Cp1252"; 186 187 188 public static final String MACROMAN = "MacRoman"; 189 190 public static final int[] CHAR_RANGE_LATIN = {0, 0x17f, 0x2000, 0x206f, 0x20a0, 0x20cf, 0xfb00, 0xfb06}; 191 public static final int[] CHAR_RANGE_ARABIC = {0, 0x7f, 0x0600, 0x067f, 0x20a0, 0x20cf, 0xfb50, 0xfbff, 0xfe70, 0xfeff}; 192 public static final int[] CHAR_RANGE_HEBREW = {0, 0x7f, 0x0590, 0x05ff, 0x20a0, 0x20cf, 0xfb1d, 0xfb4f}; 193 public static final int[] CHAR_RANGE_CYRILLIC = {0, 0x7f, 0x0400, 0x052f, 0x2000, 0x206f, 0x20a0, 0x20cf}; 194 195 196 public static final boolean EMBEDDED = true; 197 198 199 public static final boolean NOT_EMBEDDED = false; 200 201 public static final boolean CACHED = true; 202 203 public static final boolean NOT_CACHED = false; 204 205 206 public static final String RESOURCE_PATH = "com/lowagie/text/pdf/fonts/"; 207 208 public static final char CID_NEWLINE = '\u7fff'; 209 210 protected ArrayList subsetRanges; 211 213 int fontType; 214 215 public static final String notdef = ".notdef"; 216 217 218 protected int widths[] = new int[256]; 219 220 221 protected String differences[] = new String [256]; 222 223 protected char unicodeDifferences[] = new char[256]; 224 225 protected int charBBoxes[][] = new int[256][]; 226 227 protected String encoding; 228 229 230 protected boolean embedded; 231 232 237 protected boolean fontSpecific = true; 238 239 240 protected static HashMap fontCache = new HashMap (); 241 242 243 protected static final HashMap BuiltinFonts14 = new HashMap (); 244 245 248 protected boolean forceWidthsOutput = false; 249 250 253 protected boolean directTextToByte = false; 254 255 258 protected boolean subset = true; 259 260 protected boolean fastWinansi = false; 261 262 266 protected IntHashtable specialMap; 267 268 static { 269 BuiltinFonts14.put(COURIER, PdfName.COURIER); 270 BuiltinFonts14.put(COURIER_BOLD, PdfName.COURIER_BOLD); 271 BuiltinFonts14.put(COURIER_BOLDOBLIQUE, PdfName.COURIER_BOLDOBLIQUE); 272 BuiltinFonts14.put(COURIER_OBLIQUE, PdfName.COURIER_OBLIQUE); 273 BuiltinFonts14.put(HELVETICA, PdfName.HELVETICA); 274 BuiltinFonts14.put(HELVETICA_BOLD, PdfName.HELVETICA_BOLD); 275 BuiltinFonts14.put(HELVETICA_BOLDOBLIQUE, PdfName.HELVETICA_BOLDOBLIQUE); 276 BuiltinFonts14.put(HELVETICA_OBLIQUE, PdfName.HELVETICA_OBLIQUE); 277 BuiltinFonts14.put(SYMBOL, PdfName.SYMBOL); 278 BuiltinFonts14.put(TIMES_ROMAN, PdfName.TIMES_ROMAN); 279 BuiltinFonts14.put(TIMES_BOLD, PdfName.TIMES_BOLD); 280 BuiltinFonts14.put(TIMES_BOLDITALIC, PdfName.TIMES_BOLDITALIC); 281 BuiltinFonts14.put(TIMES_ITALIC, PdfName.TIMES_ITALIC); 282 BuiltinFonts14.put(ZAPFDINGBATS, PdfName.ZAPFDINGBATS); 283 } 284 285 288 static class StreamFont extends PdfStream { 289 290 296 public StreamFont(byte contents[], int lengths[]) throws DocumentException { 297 try { 298 bytes = contents; 299 put(PdfName.LENGTH, new PdfNumber(bytes.length)); 300 for (int k = 0; k < lengths.length; ++k) { 301 put(new PdfName("Length" + (k + 1)), new PdfNumber(lengths[k])); 302 } 303 flateCompress(); 304 } 305 catch (Exception e) { 306 throw new DocumentException(e); 307 } 308 } 309 310 316 public StreamFont(byte contents[], String subType) throws DocumentException { 317 try { 318 bytes = contents; 319 put(PdfName.LENGTH, new PdfNumber(bytes.length)); 320 if (subType != null) 321 put(PdfName.SUBTYPE, new PdfName(subType)); 322 flateCompress(); 323 } 324 catch (Exception e) { 325 throw new DocumentException(e); 326 } 327 } 328 } 329 330 333 protected BaseFont() { 334 } 335 336 384 public static BaseFont createFont(String name, String encoding, boolean embedded) throws DocumentException, IOException { 385 return createFont(name, encoding, embedded, true, null, null); 386 } 387 388 437 public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[]) throws DocumentException, IOException { 438 return createFont(name, encoding, embedded, cached, ttfAfm, pfb, false); 439 } 440 441 493 public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[], boolean noThrow) throws DocumentException, IOException { 494 String nameBase = getBaseName(name); 495 encoding = normalizeEncoding(encoding); 496 boolean isBuiltinFonts14 = BuiltinFonts14.containsKey(name); 497 boolean isCJKFont = isBuiltinFonts14 ? false : CJKFont.isCJKFont(nameBase, encoding); 498 if (isBuiltinFonts14 || isCJKFont) 499 embedded = false; 500 else if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V)) 501 embedded = true; 502 BaseFont fontFound = null; 503 BaseFont fontBuilt = null; 504 String key = name + "\n" + encoding + "\n" + embedded; 505 if (cached) { 506 synchronized (fontCache) { 507 fontFound = (BaseFont)fontCache.get(key); 508 } 509 if (fontFound != null) 510 return fontFound; 511 } 512 if (isBuiltinFonts14 || name.toLowerCase().endsWith(".afm") || name.toLowerCase().endsWith(".pfm")) { 513 fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb); 514 fontBuilt.fastWinansi = encoding.equals(CP1252); 515 } 516 else if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) { 517 if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V)) 518 fontBuilt = new TrueTypeFontUnicode(name, encoding, embedded, ttfAfm); 519 else { 520 fontBuilt = new TrueTypeFont(name, encoding, embedded, ttfAfm); 521 fontBuilt.fastWinansi = encoding.equals(CP1252); 522 } 523 } 524 else if (isCJKFont) 525 fontBuilt = new CJKFont(name, encoding, embedded); 526 else if (noThrow) 527 return null; 528 else 529 throw new DocumentException("Font '" + name + "' with '" + encoding + "' is not recognized."); 530 if (cached) { 531 synchronized (fontCache) { 532 fontFound = (BaseFont)fontCache.get(key); 533 if (fontFound != null) 534 return fontFound; 535 fontCache.put(key, fontBuilt); 536 } 537 } 538 return fontBuilt; 539 } 540 541 547 public static BaseFont createFont(PRIndirectReference fontRef) { 548 return new DocumentFont(fontRef); 549 } 550 551 556 protected static String getBaseName(String name) { 557 if (name.endsWith(",Bold")) 558 return name.substring(0, name.length() - 5); 559 else if (name.endsWith(",Italic")) 560 return name.substring(0, name.length() - 7); 561 else if (name.endsWith(",BoldItalic")) 562 return name.substring(0, name.length() - 11); 563 else 564 return name; 565 } 566 567 573 protected static String normalizeEncoding(String enc) { 574 if (enc.equals("winansi") || enc.equals("")) 575 return CP1252; 576 else if (enc.equals("macroman")) 577 return MACROMAN; 578 else 579 return enc; 580 } 581 582 585 protected void createEncoding() { 586 if (encoding.startsWith("#")) { 587 specialMap = new IntHashtable(); 588 StringTokenizer tok = new StringTokenizer (encoding.substring(1), " ,\t\n\r\f"); 589 if (tok.nextToken().equals("full")) { 590 while (tok.hasMoreTokens()) { 591 String order = tok.nextToken(); 592 String name = tok.nextToken(); 593 char uni = (char)Integer.parseInt(tok.nextToken(), 16); 594 int orderK; 595 if (order.startsWith("'")) 596 orderK = (int)order.charAt(1); 597 else 598 orderK = Integer.parseInt(order); 599 orderK %= 256; 600 specialMap.put((int)uni, orderK); 601 differences[orderK] = name; 602 unicodeDifferences[orderK] = uni; 603 widths[orderK] = getRawWidth((int)uni, name); 604 charBBoxes[orderK] = getRawCharBBox((int)uni, name); 605 } 606 } 607 else { 608 int k = 0; 609 if (tok.hasMoreTokens()) 610 k = Integer.parseInt(tok.nextToken()); 611 while (tok.hasMoreTokens() && k < 256) { 612 String hex = tok.nextToken(); 613 int uni = Integer.parseInt(hex, 16) % 0x10000; 614 String name = GlyphList.unicodeToName(uni); 615 if (name != null) { 616 specialMap.put(uni, k); 617 differences[k] = name; 618 unicodeDifferences[k] = (char)uni; 619 widths[k] = getRawWidth(uni, name); 620 charBBoxes[k] = getRawCharBBox(uni, name); 621 ++k; 622 } 623 } 624 } 625 for (int k = 0; k < 256; ++k) { 626 if (differences[k] == null) { 627 differences[k] = notdef; 628 } 629 } 630 } 631 else if (fontSpecific) { 632 for (int k = 0; k < 256; ++k) { 633 widths[k] = getRawWidth(k, null); 634 charBBoxes[k] = getRawCharBBox(k, null); 635 } 636 } 637 else { 638 String s; 639 String name; 640 char c; 641 byte b[] = new byte[1]; 642 for (int k = 0; k < 256; ++k) { 643 b[0] = (byte)k; 644 s = PdfEncodings.convertToString(b, encoding); 645 if (s.length() > 0) { 646 c = s.charAt(0); 647 } 648 else { 649 c = '?'; 650 } 651 name = GlyphList.unicodeToName((int)c); 652 if (name == null) 653 name = notdef; 654 differences[k] = name; 655 unicodeDifferences[k] = c; 656 widths[k] = getRawWidth((int)c, name); 657 charBBoxes[k] = getRawCharBBox((int)c, name); 658 } 659 } 660 } 661 662 669 abstract int getRawWidth(int c, String name); 670 671 677 public abstract int getKerning(char char1, char char2); 678 679 686 public abstract boolean setKerning(char char1, char char2, int kern); 687 688 693 public int getWidth(char char1) { 694 if (fastWinansi) { 695 if (char1 < 128 || (char1 >= 160 && char1 <= 255)) 696 return widths[char1]; 697 return widths[PdfEncodings.winansi.get(char1)]; 698 } 699 return getWidth(new String (new char[]{char1})); 700 } 701 702 707 public int getWidth(String text) { 708 int total = 0; 709 if (fastWinansi) { 710 int len = text.length(); 711 for (int k = 0; k < len; ++k) { 712 char char1 = text.charAt(k); 713 if (char1 < 128 || (char1 >= 160 && char1 <= 255)) 714 total += widths[char1]; 715 else 716 total += widths[PdfEncodings.winansi.get(char1)]; 717 } 718 return total; 719 } 720 else { 721 byte mbytes[] = convertToBytes(text); 722 for (int k = 0; k < mbytes.length; ++k) 723 total += widths[0xff & mbytes[k]]; 724 } 725 return total; 726 } 727 728 734 public int getDescent(String text) { 735 int min = 0; 736 char chars[] = text.toCharArray(); 737 for (int k = 0; k < chars.length; ++k) { 738 int bbox[] = getCharBBox(chars[k]); 739 if (bbox != null && bbox[1] < min) 740 min = bbox[1]; 741 } 742 return min; 743 } 744 745 751 public int getAscent(String text) { 752 int max = 0; 753 char chars[] = text.toCharArray(); 754 for (int k = 0; k < chars.length; ++k) { 755 int bbox[] = getCharBBox(chars[k]); 756 if (bbox != null && bbox[3] > max) 757 max = bbox[3]; 758 } 759 return max; 760 } 761 762 769 public float getDescentPoint(String text, float fontSize) 770 { 771 return (float)getDescent(text) * 0.001f * fontSize; 772 } 773 774 781 public float getAscentPoint(String text, float fontSize) 782 { 783 return (float)getAscent(text) * 0.001f * fontSize; 784 } 785 787 794 public float getWidthPointKerned(String text, float fontSize) { 795 float size = (float)getWidth(text) * 0.001f * fontSize; 796 if (!hasKernPairs()) 797 return size; 798 int len = text.length() - 1; 799 int kern = 0; 800 char c[] = text.toCharArray(); 801 for (int k = 0; k < len; ++k) { 802 kern += getKerning(c[k], c[k + 1]); 803 } 804 return size + kern * 0.001f * fontSize; 805 } 806 807 813 public float getWidthPoint(String text, float fontSize) { 814 return (float)getWidth(text) * 0.001f * fontSize; 815 } 816 817 823 public float getWidthPoint(char char1, float fontSize) { 824 return getWidth(char1) * 0.001f * fontSize; 825 } 826 827 833 byte[] convertToBytes(String text) { 834 if (directTextToByte) 835 return PdfEncodings.convertToBytes(text, null); 836 if (specialMap != null) { 837 byte[] b = new byte[text.length()]; 838 int ptr = 0; 839 int length = text.length(); 840 for (int k = 0; k < length; ++k) { 841 char c = text.charAt(k); 842 if (specialMap.containsKey((int)c)) 843 b[ptr++] = (byte)specialMap.get((int)c); 844 } 845 if (ptr < length) { 846 byte[] b2 = new byte[ptr]; 847 System.arraycopy(b, 0, b2, 0, ptr); 848 return b2; 849 } 850 else 851 return b; 852 } 853 return PdfEncodings.convertToBytes(text, encoding); 854 } 855 856 863 abstract void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException ; 864 865 868 public String getEncoding() { 869 return encoding; 870 } 871 872 881 public abstract float getFontDescriptor(int key, float fontSize); 882 883 887 public int getFontType() { 888 return fontType; 889 } 890 891 894 public boolean isEmbedded() { 895 return embedded; 896 } 897 898 901 public boolean isFontSpecific() { 902 return fontSpecific; 903 } 904 905 908 public static String createSubsetPrefix() { 909 String s = ""; 910 for (int k = 0; k < 6; ++k) 911 s += (char)(Math.random() * 26 + 'A'); 912 return s + "+"; 913 } 914 915 919 char getUnicodeDifferences(int index) { 920 return unicodeDifferences[index]; 921 } 922 923 926 public abstract String getPostscriptFontName(); 927 928 933 public abstract void setPostscriptFontName(String name); 934 935 943 public abstract String [][] getFullFontName(); 944 945 958 public static String [][] getFullFontName(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { 959 String nameBase = getBaseName(name); 960 BaseFont fontBuilt = null; 961 if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) 962 fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true); 963 else 964 fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); 965 return fontBuilt.getFullFontName(); 966 } 967 968 976 public static Object [] getAllFontNames(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { 977 String nameBase = getBaseName(name); 978 BaseFont fontBuilt = null; 979 if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) 980 fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true); 981 else 982 fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); 983 return new Object []{fontBuilt.getPostscriptFontName(), fontBuilt.getFamilyFontName(), fontBuilt.getFullFontName()}; 984 } 985 986 994 public abstract String [][] getFamilyFontName(); 995 996 1000 public String [] getCodePagesSupported() { 1001 return new String [0]; 1002 } 1003 1004 1011 public static String [] enumerateTTCNames(String ttcFile) throws DocumentException, IOException { 1012 return new EnumerateTTC(ttcFile).getNames(); 1013 } 1014 1015 1022 public static String [] enumerateTTCNames(byte ttcArray[]) throws DocumentException, IOException { 1023 return new EnumerateTTC(ttcArray).getNames(); 1024 } 1025 1026 1029 public int[] getWidths() { 1030 return widths; 1031 } 1032 1033 1036 public String [] getDifferences() { 1037 return differences; 1038 } 1039 1040 1043 public char[] getUnicodeDifferences() { 1044 return unicodeDifferences; 1045 } 1046 1047 1050 public boolean isForceWidthsOutput() { 1051 return forceWidthsOutput; 1052 } 1053 1054 1059 public void setForceWidthsOutput(boolean forceWidthsOutput) { 1060 this.forceWidthsOutput = forceWidthsOutput; 1061 } 1062 1063 1067 public boolean isDirectTextToByte() { 1068 return directTextToByte; 1069 } 1070 1071 1076 public void setDirectTextToByte(boolean directTextToByte) { 1077 this.directTextToByte = directTextToByte; 1078 } 1079 1080 1084 public boolean isSubset() { 1085 return subset; 1086 } 1087 1088 1095 public void setSubset(boolean subset) { 1096 this.subset = subset; 1097 } 1098 1099 1104 public static InputStream getResourceStream(String key) { 1105 return getResourceStream(key, null); 1106 } 1107 1108 1114 public static InputStream getResourceStream(String key, ClassLoader loader) { 1115 if (key.startsWith("/")) 1116 key = key.substring(1); 1117 InputStream is = null; 1118 if (loader != null) { 1119 is = loader.getResourceAsStream(key); 1120 if (is != null) 1121 return is; 1122 } 1123 try { 1125 java.lang.reflect.Method getCCL = 1126 Thread .class.getMethod("getContextClassLoader", new Class [0]); 1127 if (getCCL != null) { 1128 ClassLoader contextClassLoader = 1129 (ClassLoader )getCCL.invoke(Thread.currentThread(), 1130 new Object [0]); 1131 if (contextClassLoader != null) 1132 is = contextClassLoader.getResourceAsStream(key); 1133 } 1134 } catch (Throwable e) {} 1135 1136 if (is == null) { 1137 is = BaseFont.class.getResourceAsStream("/" + key); 1138 } 1139 if (is == null) { 1140 is = ClassLoader.getSystemResourceAsStream(key); 1141 } 1142 return is; 1143 } 1144 1145 1151 public char getUnicodeEquivalent(char c) { 1152 return c; 1153 } 1154 1155 1160 public char getCidCode(char c) { 1161 return c; 1162 } 1163 1164 1167 public abstract boolean hasKernPairs(); 1168 1169 1175 public boolean charExists(char c) { 1176 byte b[] = convertToBytes(new String (new char[]{c})); 1177 return b.length > 0; 1178 } 1179 1180 1187 public boolean setCharAdvance(char c, int advance) { 1188 byte b[] = convertToBytes(new String (new char[]{c})); 1189 if (b.length == 0) 1190 return false; 1191 widths[0xff & b[0]] = advance; 1192 return true; 1193 } 1194 1195 private static void addFont(PRIndirectReference fontRef, IntHashtable hits, ArrayList fonts) { 1196 PdfObject obj = PdfReader.getPdfObject(fontRef); 1197 if (obj == null || !obj.isDictionary()) 1198 return; 1199 PdfDictionary font = (PdfDictionary)obj; 1200 PdfName subtype = (PdfName)PdfReader.getPdfObject(font.get(PdfName.SUBTYPE)); 1201 if (!PdfName.TYPE1.equals(subtype) && !PdfName.TRUETYPE.equals(subtype)) 1202 return; 1203 PdfName name = (PdfName)PdfReader.getPdfObject(font.get(PdfName.BASEFONT)); 1204 fonts.add(new Object []{PdfName.decodeName(name.toString()), fontRef}); 1205 hits.put(fontRef.getNumber(), 1); 1206 } 1207 1208 private static void recourseFonts(PdfDictionary page, IntHashtable hits, ArrayList fonts, int level) { 1209 ++level; 1210 if (level > 50) return; 1212 PdfDictionary resources = (PdfDictionary)PdfReader.getPdfObject(page.get(PdfName.RESOURCES)); 1213 if (resources == null) 1214 return; 1215 PdfDictionary font = (PdfDictionary)PdfReader.getPdfObject(resources.get(PdfName.FONT)); 1216 if (font != null) { 1217 for (Iterator it = font.getKeys().iterator(); it.hasNext();) { 1218 PdfObject ft = font.get((PdfName)it.next()); 1219 if (ft == null || !ft.isIndirect()) 1220 continue; 1221 int hit = ((PRIndirectReference)ft).getNumber(); 1222 if (hits.containsKey(hit)) 1223 continue; 1224 addFont((PRIndirectReference)ft, hits, fonts); 1225 } 1226 } 1227 PdfDictionary xobj = (PdfDictionary)PdfReader.getPdfObject(resources.get(PdfName.XOBJECT)); 1228 if (xobj != null) { 1229 for (Iterator it = xobj.getKeys().iterator(); it.hasNext();) { 1230 recourseFonts((PdfDictionary)PdfReader.getPdfObject(xobj.get((PdfName)it.next())), hits, fonts, level); 1231 } 1232 } 1233 } 1234 1235 1242 public static ArrayList getDocumentFonts(PdfReader reader) { 1243 IntHashtable hits = new IntHashtable(); 1244 ArrayList fonts = new ArrayList (); 1245 int npages = reader.getNumberOfPages(); 1246 for (int k = 1; k <= npages; ++k) 1247 recourseFonts(reader.getPageN(k), hits, fonts, 1); 1248 return fonts; 1249 } 1250 1251 1259 public static ArrayList getDocumentFonts(PdfReader reader, int page) { 1260 IntHashtable hits = new IntHashtable(); 1261 ArrayList fonts = new ArrayList (); 1262 recourseFonts(reader.getPageN(page), hits, fonts, 1); 1263 return fonts; 1264 } 1265 1266 1275 public int[] getCharBBox(char c) { 1276 byte b[] = convertToBytes(new String (new char[]{c})); 1277 if (b.length == 0) 1278 return null; 1279 else 1280 return charBBoxes[b[0] & 0xff]; 1281 } 1282 1283 protected abstract int[] getRawCharBBox(int c, String name); 1284 1285 1292 public void correctArabicAdvance() { 1293 for (char c = '\u064b'; c <= '\u0658'; ++c) 1294 setCharAdvance(c, 0); 1295 setCharAdvance('\u0670', 0); 1296 for (char c = '\u06d6'; c <= '\u06dc'; ++c) 1297 setCharAdvance(c, 0); 1298 for (char c = '\u06df'; c <= '\u06e4'; ++c) 1299 setCharAdvance(c, 0); 1300 for (char c = '\u06e7'; c <= '\u06e8'; ++c) 1301 setCharAdvance(c, 0); 1302 for (char c = '\u06ea'; c <= '\u06ed'; ++c) 1303 setCharAdvance(c, 0); 1304 } 1305 1306 1312 public void addSubsetRange(int[] range) { 1313 if (subsetRanges == null) 1314 subsetRanges = new ArrayList (); 1315 subsetRanges.add(range); 1316 } 1317} 1318 | Popular Tags |