1 17 18 19 20 package org.apache.fop.pdf; 21 22 import org.apache.fop.fonts.CIDFont; 23 24 37 public class PDFToUnicodeCMap extends PDFCMap { 38 39 42 protected CIDFont cidFont; 43 44 52 public PDFToUnicodeCMap(CIDFont cidMetrics, String name, PDFCIDSystemInfo sysInfo) { 53 super(name, sysInfo); 54 cidFont = cidMetrics; 55 } 56 57 58 public void fillInPDF(StringBuffer p) { 59 writeCIDInit(p); 60 writeCIDSystemInfo(p); 61 writeVersionTypeName(p); 62 writeCodeSpaceRange(p); 63 writeBFEntries(p); 64 writeWrapUp(p); 65 add(p.toString()); 66 } 67 68 69 protected void writeCIDSystemInfo(StringBuffer p) { 70 p.append("/CIDSystemInfo\n"); 71 p.append("<< /Registry (Adobe)\n"); 72 p.append("/Ordering (UCS)\n"); 73 p.append("/Supplement 0\n"); 74 p.append(">> def\n"); 75 } 76 77 78 protected void writeVersionTypeName(StringBuffer p) { 79 p.append("/CMapName /Adobe-Identity-UCS def\n"); 80 p.append("/CMapType 2 def\n"); 81 } 82 83 87 protected void writeBFEntries(StringBuffer p) { 88 if (cidFont == null) { 89 return; 90 } 91 92 char[] charArray = cidFont.getCharsUsed(); 93 94 if (charArray != null) { 95 writeBFCharEntries(p, charArray); 96 writeBFRangeEntries(p, charArray); 97 } 98 } 99 100 106 protected void writeBFCharEntries(StringBuffer p, char[] charArray) { 107 int totalEntries = 0; 108 for (int i = 0; i < charArray.length; i++) { 109 if (!partOfRange(charArray, i)) { 110 totalEntries++; 111 } 112 } 113 if (totalEntries < 1) { 114 return; 115 } 116 int remainingEntries = totalEntries; 117 int charIndex = 0; 118 do { 119 120 int entriesThisSection = Math.min(remainingEntries, 100); 121 p.append(entriesThisSection + " beginbfchar\n"); 122 for (int i = 0; i < entriesThisSection; i++) { 123 124 while (partOfRange(charArray, charIndex)) { 125 charIndex++; 126 } 127 p.append("<" + padHexString(Integer.toHexString(charIndex), 4) + "> "); 128 p.append("<" + padHexString(Integer.toHexString(charArray[charIndex]), 4) + ">\n"); 129 charIndex++; 130 } 131 remainingEntries -= entriesThisSection; 132 p.append("endbfchar\n"); 133 } while (remainingEntries > 0); 134 } 135 136 141 protected void writeBFRangeEntries(StringBuffer p, char[] charArray) { 142 int totalEntries = 0; 143 for (int i = 0; i < charArray.length; i++) { 144 if (startOfRange(charArray, i)) { 145 totalEntries++; 146 } 147 } 148 if (totalEntries < 1) { 149 return; 150 } 151 int remainingEntries = totalEntries; 152 int charIndex = 0; 153 do { 154 155 int entriesThisSection = Math.min(remainingEntries, 100); 156 p.append(entriesThisSection + " beginbfrange\n"); 157 for (int i = 0; i < entriesThisSection; i++) { 158 159 while (!startOfRange(charArray, charIndex)) { 160 charIndex++; 161 } 162 p.append("<" + padHexString(Integer.toHexString(charIndex), 4) + "> "); 163 p.append("<" 164 + padHexString(Integer.toHexString(endOfRange(charArray, charIndex)), 4) 165 + "> "); 166 p.append("<" + padHexString(Integer.toHexString(charArray[charIndex]), 4) + ">\n"); 167 charIndex++; 168 } 169 remainingEntries -= entriesThisSection; 170 p.append("endbfrange\n"); 171 } while (remainingEntries > 0); 172 } 173 174 181 private int endOfRange(char[] charArray, int startOfRange) { 182 int i = startOfRange; 183 while (i < charArray.length - 1 && sameRangeEntryAsNext(charArray, i)) { 184 i++; 185 } 186 return i; 187 } 188 189 196 private boolean partOfRange(char[] charArray, int arrayIndex) { 197 if (charArray.length < 2) { 198 return false; 199 } 200 if (arrayIndex == 0) { 201 return sameRangeEntryAsNext(charArray, 0); 202 } 203 if (arrayIndex == charArray.length - 1) { 204 return sameRangeEntryAsNext(charArray, arrayIndex - 1); 205 } 206 if (sameRangeEntryAsNext(charArray, arrayIndex - 1)) { 207 return true; 208 } 209 if (sameRangeEntryAsNext(charArray, arrayIndex)) { 210 return true; 211 } 212 return false; 213 } 214 215 224 private boolean sameRangeEntryAsNext(char[] charArray, int firstItem) { 225 if (charArray[firstItem] + 1 != charArray[firstItem + 1]) { 226 return false; 227 } 228 if (firstItem / 256 != (firstItem + 1) / 256) { 229 return false; 230 } 231 return true; 232 } 233 234 241 private boolean startOfRange(char[] charArray, int arrayIndex) { 242 if (!partOfRange(charArray, arrayIndex)) { 244 return false; 245 } 246 if (arrayIndex == 0) { 248 return true; 249 } 250 if (arrayIndex == charArray.length - 1) { 252 return false; 253 } 254 258 if (sameRangeEntryAsNext(charArray, arrayIndex - 1)) { 259 return false; 260 } 261 return true; 263 } 264 265 272 public static String padHexString(String input, int numChars) { 273 int length = input.length(); 274 if (length >= numChars) { 275 return input; 276 } 277 StringBuffer returnString = new StringBuffer (); 278 for (int i = 1; i <= numChars - length; i++) { 279 returnString.append("0"); 280 } 281 returnString.append(input); 282 return returnString.toString(); 283 } 284 285 } 286 | Popular Tags |