1 47 48 package com.lowagie.text.pdf; 49 50 import java.util.HashMap ; 51 52 import com.lowagie.text.DocumentException; 53 54 57 public class Type3Font extends BaseFont { 58 59 private boolean[] usedSlot; 60 private IntHashtable widths3 = new IntHashtable(); 61 private HashMap char2glyph = new HashMap (); 62 private PdfWriter writer; 63 private float llx = Float.NaN, lly, urx, ury; 64 private PageResources pageResources = new PageResources(); 65 private boolean colorized; 66 67 74 public Type3Font(PdfWriter writer, char[] chars, boolean colorized) { 75 this(writer, colorized); 76 } 77 78 105 public Type3Font(PdfWriter writer, boolean colorized) { 106 this.writer = writer; 107 this.colorized = colorized; 108 fontType = FONT_TYPE_T3; 109 usedSlot = new boolean[256]; 110 } 111 112 126 public PdfContentByte defineGlyph(char c, float wx, float llx, float lly, float urx, float ury) { 127 if (c == 0 || c > 255) 128 throw new IllegalArgumentException ("The char " + (int)c + " doesn't belong in this Type3 font"); 129 usedSlot[c] = true; 130 Integer ck = new Integer ((int)c); 131 Type3Glyph glyph = (Type3Glyph)char2glyph.get(ck); 132 if (glyph != null) 133 return glyph; 134 widths3.put(c, (int)wx); 135 if (!colorized) { 136 if (Float.isNaN(this.llx)) { 137 this.llx = llx; 138 this.lly = lly; 139 this.urx = urx; 140 this.ury = ury; 141 } 142 else { 143 this.llx = Math.min(this.llx, llx); 144 this.lly = Math.min(this.lly, lly); 145 this.urx = Math.max(this.urx, urx); 146 this.ury = Math.max(this.ury, ury); 147 } 148 } 149 glyph = new Type3Glyph(writer, pageResources, wx, llx, lly, urx, ury, colorized); 150 char2glyph.put(ck, glyph); 151 return glyph; 152 } 153 154 public String [][] getFamilyFontName() { 155 return new String [0][]; 156 } 157 158 public float getFontDescriptor(int key, float fontSize) { 159 return 0; 160 } 161 162 public String [][] getFullFontName() { 163 return new String [0][]; 164 } 165 166 public int getKerning(char char1, char char2) { 167 return 0; 168 } 169 170 public String getPostscriptFontName() { 171 return ""; 172 } 173 174 protected int[] getRawCharBBox(int c, String name) { 175 return null; 176 } 177 178 int getRawWidth(int c, String name) { 179 return 0; 180 } 181 182 public boolean hasKernPairs() { 183 return false; 184 } 185 186 public boolean setKerning(char char1, char char2, int kern) { 187 return false; 188 } 189 190 public void setPostscriptFontName(String name) { 191 } 192 193 void writeFont(PdfWriter writer, PdfIndirectReference ref, Object [] params) throws com.lowagie.text.DocumentException, java.io.IOException { 194 if (this.writer != writer) 195 throw new IllegalArgumentException ("Type3 font used with the wrong PdfWriter"); 196 197 int firstChar = 0; 199 while( firstChar < usedSlot.length && !usedSlot[firstChar] ) firstChar++; 200 201 if ( firstChar == usedSlot.length ) { 202 throw new DocumentException( "No glyphs defined for Type3 font" ); 203 } 204 int lastChar = usedSlot.length - 1; 205 while( lastChar >= firstChar && !usedSlot[lastChar] ) lastChar--; 206 207 int[] widths = new int[lastChar - firstChar + 1]; 208 int[] invOrd = new int[lastChar - firstChar + 1]; 209 210 int invOrdIndx = 0, w = 0; 211 for( int u = firstChar; u<=lastChar; u++, w++ ) { 212 if ( usedSlot[u] ) { 213 invOrd[invOrdIndx++] = u; 214 widths[w] = widths3.get(u); 215 } 216 } 217 PdfArray diffs = new PdfArray(); 218 PdfDictionary charprocs = new PdfDictionary(); 219 int last = -1; 220 for (int k = 0; k < invOrdIndx; ++k) { 221 int c = invOrd[k]; 222 if (c > last) { 223 last = c; 224 diffs.add(new PdfNumber(last)); 225 } 226 ++last; 227 int c2 = invOrd[k]; 228 String s = GlyphList.unicodeToName(c2); 229 if (s == null) 230 s = "a" + c2; 231 PdfName n = new PdfName(s); 232 diffs.add(n); 233 Type3Glyph glyph = (Type3Glyph)char2glyph.get(new Integer (c2)); 234 PdfStream stream = new PdfStream(glyph.toPdf(null)); 235 stream.flateCompress(); 236 PdfIndirectReference refp = writer.addToBody(stream).getIndirectReference(); 237 charprocs.put(n, refp); 238 } 239 PdfDictionary font = new PdfDictionary(PdfName.FONT); 240 font.put(PdfName.SUBTYPE, PdfName.TYPE3); 241 if (colorized) 242 font.put(PdfName.FONTBBOX, new PdfRectangle(0, 0, 0, 0)); 243 else 244 font.put(PdfName.FONTBBOX, new PdfRectangle(llx, lly, urx, ury)); 245 font.put(PdfName.FONTMATRIX, new PdfArray(new float[]{0.001f, 0, 0, 0.001f, 0, 0})); 246 font.put(PdfName.CHARPROCS, writer.addToBody(charprocs).getIndirectReference()); 247 PdfDictionary encoding = new PdfDictionary(); 248 encoding.put(PdfName.DIFFERENCES, diffs); 249 font.put(PdfName.ENCODING, writer.addToBody(encoding).getIndirectReference()); 250 font.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar)); 251 font.put(PdfName.LASTCHAR, new PdfNumber(lastChar)); 252 font.put(PdfName.WIDTHS, writer.addToBody(new PdfArray(widths)).getIndirectReference()); 253 if (pageResources.hasResources()) 254 font.put(PdfName.RESOURCES, writer.addToBody(pageResources.getResources()).getIndirectReference()); 255 writer.addToBody(font, ref); 256 } 257 258 259 byte[] convertToBytes(String text) { 260 char[] cc = text.toCharArray(); 261 byte[] b = new byte[cc.length]; 262 int p = 0; 263 for (int k = 0; k < cc.length; ++k) { 264 char c = cc[k]; 265 if (charExists(c)) 266 b[p++] = (byte)c; 267 } 268 if (b.length == p) 269 return b; 270 byte[] b2 = new byte[p]; 271 System.arraycopy(b, 0, b2, 0, p); 272 return b2; 273 } 274 275 public int getWidth(char char1) { 276 if (!widths3.containsKey(char1)) 277 throw new IllegalArgumentException ("The char " + (int)char1 + " is not defined in a Type3 font"); 278 return widths3.get(char1); 279 } 280 281 public int getWidth(String text) { 282 char[] c = text.toCharArray(); 283 int total = 0; 284 for (int k = 0; k < c.length; ++k) 285 total += getWidth(c[k]); 286 return total; 287 } 288 289 public int[] getCharBBox(char c) { 290 return null; 291 } 292 293 public boolean charExists(char c) { 294 if (c > 0 && c < 256) { 295 return usedSlot[c]; 296 } else { 297 return false; 298 } 299 } 300 301 public boolean setCharAdvance(char c, int advance) { 302 return false; 303 } 304 305 } 306 | Popular Tags |