1 /* 2 * $Id$ 3 * 4 * Copyright 2000-2006 by Paulo Soares. 5 * 6 * The contents of this file are subject to the Mozilla Public License Version 1.1 7 * (the "License"); you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at http://www.mozilla.org/MPL/ 9 * 10 * Software distributed under the License is distributed on an "AS IS" basis, 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 * for the specific language governing rights and limitations under the License. 13 * 14 * The Original Code is 'iText, a free JAVA-PDF library'. 15 * 16 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by 17 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. 18 * All Rights Reserved. 19 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer 20 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. 21 * 22 * Contributor(s): all the names of the contributors are added in the source code 23 * where applicable. 24 * 25 * Alternatively, the contents of this file may be used under the terms of the 26 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the 27 * provisions of LGPL are applicable instead of those above. If you wish to 28 * allow use of your version of this file only under the terms of the LGPL 29 * License and not to allow others to use your version of this file under 30 * the MPL, indicate your decision by deleting the provisions above and 31 * replace them with the notice and other provisions required by the LGPL. 32 * If you do not delete the provisions above, a recipient may use your version 33 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. 34 * 35 * This library is free software; you can redistribute it and/or modify it 36 * under the terms of the MPL as stated above or under the terms of the GNU 37 * Library General Public License as published by the Free Software Foundation; 38 * either version 2 of the License, or any later version. 39 * 40 * This library is distributed in the hope that it will be useful, but WITHOUT 41 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 42 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more 43 * details. 44 * 45 * If you didn't download this code from the following link, you should check if 46 * you aren't using an obsolete version: 47 * http://www.lowagie.com/iText/ 48 */ 49 50 package com.lowagie.text.pdf; 51 import java.io.IOException; 52 import java.io.InputStream; 53 import java.util.ArrayList; 54 import java.util.HashMap; 55 import java.util.Iterator; 56 import java.util.StringTokenizer; 57 import com.lowagie.text.error_messages.MessageLocalization; 58 59 import com.lowagie.text.DocumentException; 60 61 /** 62 * Base class for the several font types supported 63 * 64 * @author Paulo Soares (psoares@consiste.pt) 65 */ 66 67 public abstract class BaseFont { 68 69 /** This is a possible value of a base 14 type 1 font */ 70 public static final String COURIER = "Courier"; 71 72 /** This is a possible value of a base 14 type 1 font */ 73 public static final String COURIER_BOLD = "Courier-Bold"; 74 75 /** This is a possible value of a base 14 type 1 font */ 76 public static final String COURIER_OBLIQUE = "Courier-Oblique"; 77 78 /** This is a possible value of a base 14 type 1 font */ 79 public static final String COURIER_BOLDOBLIQUE = "Courier-BoldOblique"; 80 81 /** This is a possible value of a base 14 type 1 font */ 82 public static final String HELVETICA = "Helvetica"; 83 84 /** This is a possible value of a base 14 type 1 font */ 85 public static final String HELVETICA_BOLD = "Helvetica-Bold"; 86 87 /** This is a possible value of a base 14 type 1 font */ 88 public static final String HELVETICA_OBLIQUE = "Helvetica-Oblique"; 89 90 /** This is a possible value of a base 14 type 1 font */ 91 public static final String HELVETICA_BOLDOBLIQUE = "Helvetica-BoldOblique"; 92 93 /** This is a possible value of a base 14 type 1 font */ 94 public static final String SYMBOL = "Symbol"; 95 96 /** This is a possible value of a base 14 type 1 font */ 97 public static final String TIMES_ROMAN = "Times-Roman"; 98 99 /** This is a possible value of a base 14 type 1 font */ 100 public static final String TIMES_BOLD = "Times-Bold"; 101 102 /** This is a possible value of a base 14 type 1 font */ 103 public static final String TIMES_ITALIC = "Times-Italic"; 104 105 /** This is a possible value of a base 14 type 1 font */ 106 public static final String TIMES_BOLDITALIC = "Times-BoldItalic"; 107 108 /** This is a possible value of a base 14 type 1 font */ 109 public static final String ZAPFDINGBATS = "ZapfDingbats"; 110 111 /** The maximum height above the baseline reached by glyphs in this 112 * font, excluding the height of glyphs for accented characters. 113 */ 114 public static final int ASCENT = 1; 115 /** The y coordinate of the top of flat capital letters, measured from 116 * the baseline. 117 */ 118 public static final int CAPHEIGHT = 2; 119 /** The maximum depth below the baseline reached by glyphs in this 120 * font. The value is a negative number. 121 */ 122 public static final int DESCENT = 3; 123 /** The angle, expressed in degrees counterclockwise from the vertical, 124 * of the dominant vertical strokes of the font. The value is 125 * negative for fonts that slope to the right, as almost all italic fonts do. 126 */ 127 public static final int ITALICANGLE = 4; 128 /** The lower left x glyph coordinate. 129 */ 130 public static final int BBOXLLX = 5; 131 /** The lower left y glyph coordinate. 132 */ 133 public static final int BBOXLLY = 6; 134 /** The upper right x glyph coordinate. 135 */ 136 public static final int BBOXURX = 7; 137 /** The upper right y glyph coordinate. 138 */ 139 public static final int BBOXURY = 8; 140 141 /** java.awt.Font property */ 142 public static final int AWT_ASCENT = 9; 143 /** java.awt.Font property */ 144 public static final int AWT_DESCENT = 10; 145 /** java.awt.Font property */ 146 public static final int AWT_LEADING = 11; 147 /** java.awt.Font property */ 148 public static final int AWT_MAXADVANCE = 12; 149 /** 150 * The underline position. Usually a negative value. 151 */ 152 public static final int UNDERLINE_POSITION = 13; 153 /** 154 * The underline thickness. 155 */ 156 public static final int UNDERLINE_THICKNESS = 14; 157 /** 158 * The strikethrough position. 159 */ 160 public static final int STRIKETHROUGH_POSITION = 15; 161 /** 162 * The strikethrough thickness. 163 */ 164 public static final int STRIKETHROUGH_THICKNESS = 16; 165 /** 166 * The recommended vertical size for subscripts for this font. 167 */ 168 public static final int SUBSCRIPT_SIZE = 17; 169 /** 170 * The recommended vertical offset from the baseline for subscripts for this font. Usually a negative value. 171 */ 172 public static final int SUBSCRIPT_OFFSET = 18; 173 /** 174 * The recommended vertical size for superscripts for this font. 175 */ 176 public static final int SUPERSCRIPT_SIZE = 19; 177 /** 178 * The recommended vertical offset from the baseline for superscripts for this font. 179 */ 180 public static final int SUPERSCRIPT_OFFSET = 20; 181 /** The font is Type 1. 182 */ 183 public static final int FONT_TYPE_T1 = 0; 184 /** The font is True Type with a standard encoding. 185 */ 186 public static final int FONT_TYPE_TT = 1; 187 /** The font is CJK. 188 */ 189 public static final int FONT_TYPE_CJK = 2; 190 /** The font is True Type with a Unicode encoding. 191 */ 192 public static final int FONT_TYPE_TTUNI = 3; 193 /** A font already inside the document. 194 */ 195 public static final int FONT_TYPE_DOCUMENT = 4; 196 /** A Type3 font. 197 */ 198 public static final int FONT_TYPE_T3 = 5; 199 /** The Unicode encoding with horizontal writing. 200 */ 201 public static final String IDENTITY_H = "Identity-H"; 202 /** The Unicode encoding with vertical writing. 203 */ 204 public static final String IDENTITY_V = "Identity-V"; 205 206 /** A possible encoding. */ 207 public static final String CP1250 = "Cp1250"; 208 209 /** A possible encoding. */ 210 public static final String CP1252 = "Cp1252"; 211 212 /** A possible encoding. */ 213 public static final String CP1257 = "Cp1257"; 214 215 /** A possible encoding. */ 216 public static final String WINANSI = "Cp1252"; 217 218 /** A possible encoding. */ 219 public static final String MACROMAN = "MacRoman"; 220 221 public static final int[] CHAR_RANGE_LATIN = {0, 0x17f, 0x2000, 0x206f, 0x20a0, 0x20cf, 0xfb00, 0xfb06}; 222 public static final int[] CHAR_RANGE_ARABIC = {0, 0x7f, 0x0600, 0x067f, 0x20a0, 0x20cf, 0xfb50, 0xfbff, 0xfe70, 0xfeff}; 223 public static final int[] CHAR_RANGE_HEBREW = {0, 0x7f, 0x0590, 0x05ff, 0x20a0, 0x20cf, 0xfb1d, 0xfb4f}; 224 public static final int[] CHAR_RANGE_CYRILLIC = {0, 0x7f, 0x0400, 0x052f, 0x2000, 0x206f, 0x20a0, 0x20cf}; 225 226 /** if the font has to be embedded */ 227 public static final boolean EMBEDDED = true; 228 229 /** if the font doesn't have to be embedded */ 230 public static final boolean NOT_EMBEDDED = false; 231 /** if the font has to be cached */ 232 public static final boolean CACHED = true; 233 /** if the font doesn't have to be cached */ 234 public static final boolean NOT_CACHED = false; 235 236 /** The path to the font resources. */ 237 public static final String RESOURCE_PATH = "com/lowagie/text/pdf/fonts/"; 238 /** The fake CID code that represents a newline. */ 239 public static final char CID_NEWLINE = '\u7fff'; 240 241 protected ArrayList subsetRanges; 242 /** The font type. 243 */ 244 int fontType; 245 /** a not defined character in a custom PDF encoding */ 246 public static final String notdef = ".notdef"; 247 248 /** table of characters widths for this encoding */ 249 protected int widths[] = new int[256]; 250 251 /** encoding names */ 252 protected String differences[] = new String[256]; 253 /** same as differences but with the unicode codes */ 254 protected char unicodeDifferences[] = new char[256]; 255 256 protected int charBBoxes[][] = new int[256][]; 257 /** encoding used with this font */ 258 protected String encoding; 259 260 /** true if the font is to be embedded in the PDF */ 261 protected boolean embedded; 262 263 /** 264 * The compression level for the font stream. 265 * @since 2.1.3 266 */ 267 protected int compressionLevel = PdfStream.DEFAULT_COMPRESSION; 268 269 /** 270 * true if the font must use its built in encoding. In that case the 271 * <CODE>encoding</CODE> is only used to map a char to the position inside 272 * the font, not to the expected char name. 273 */ 274 protected boolean fontSpecific = true; 275 276 /** cache for the fonts already used. */ 277 protected static HashMap fontCache = new HashMap(); 278 279 /** list of the 14 built in fonts. */ 280 protected static final HashMap BuiltinFonts14 = new HashMap(); 281 282 /** Forces the output of the width array. Only matters for the 14 283 * built-in fonts. 284 */ 285 protected boolean forceWidthsOutput = false; 286 287 /** Converts <CODE>char</CODE> directly to <CODE>byte</CODE> 288 * by casting. 289 */ 290 protected boolean directTextToByte = false; 291 292 /** Indicates if all the glyphs and widths for that particular 293 * encoding should be included in the document. 294 */ 295 protected boolean subset = true; 296 297 protected boolean fastWinansi = false; 298 299 /** 300 * Custom encodings use this map to key the Unicode character 301 * to the single byte code. 302 */ 303 protected IntHashtable specialMap; 304 305 static { BuiltinFonts14.put(COURIER, PdfName.COURIER)306 BuiltinFonts14.put(COURIER, PdfName.COURIER); BuiltinFonts14.put(COURIER_BOLD, PdfName.COURIER_BOLD)307 BuiltinFonts14.put(COURIER_BOLD, PdfName.COURIER_BOLD); BuiltinFonts14.put(COURIER_BOLDOBLIQUE, PdfName.COURIER_BOLDOBLIQUE)308 BuiltinFonts14.put(COURIER_BOLDOBLIQUE, PdfName.COURIER_BOLDOBLIQUE); BuiltinFonts14.put(COURIER_OBLIQUE, PdfName.COURIER_OBLIQUE)309 BuiltinFonts14.put(COURIER_OBLIQUE, PdfName.COURIER_OBLIQUE); BuiltinFonts14.put(HELVETICA, PdfName.HELVETICA)310 BuiltinFonts14.put(HELVETICA, PdfName.HELVETICA); BuiltinFonts14.put(HELVETICA_BOLD, PdfName.HELVETICA_BOLD)311 BuiltinFonts14.put(HELVETICA_BOLD, PdfName.HELVETICA_BOLD); BuiltinFonts14.put(HELVETICA_BOLDOBLIQUE, PdfName.HELVETICA_BOLDOBLIQUE)312 BuiltinFonts14.put(HELVETICA_BOLDOBLIQUE, PdfName.HELVETICA_BOLDOBLIQUE); BuiltinFonts14.put(HELVETICA_OBLIQUE, PdfName.HELVETICA_OBLIQUE)313 BuiltinFonts14.put(HELVETICA_OBLIQUE, PdfName.HELVETICA_OBLIQUE); BuiltinFonts14.put(SYMBOL, PdfName.SYMBOL)314 BuiltinFonts14.put(SYMBOL, PdfName.SYMBOL); BuiltinFonts14.put(TIMES_ROMAN, PdfName.TIMES_ROMAN)315 BuiltinFonts14.put(TIMES_ROMAN, PdfName.TIMES_ROMAN); BuiltinFonts14.put(TIMES_BOLD, PdfName.TIMES_BOLD)316 BuiltinFonts14.put(TIMES_BOLD, PdfName.TIMES_BOLD); BuiltinFonts14.put(TIMES_BOLDITALIC, PdfName.TIMES_BOLDITALIC)317 BuiltinFonts14.put(TIMES_BOLDITALIC, PdfName.TIMES_BOLDITALIC); BuiltinFonts14.put(TIMES_ITALIC, PdfName.TIMES_ITALIC)318 BuiltinFonts14.put(TIMES_ITALIC, PdfName.TIMES_ITALIC); BuiltinFonts14.put(ZAPFDINGBATS, PdfName.ZAPFDINGBATS)319 BuiltinFonts14.put(ZAPFDINGBATS, PdfName.ZAPFDINGBATS); 320 } 321 322 /** Generates the PDF stream with the Type1 and Truetype fonts returning 323 * a PdfStream. 324 */ 325 static class StreamFont extends PdfStream { 326 327 /** Generates the PDF stream with the Type1 and Truetype fonts returning 328 * a PdfStream. 329 * @param contents the content of the stream 330 * @param lengths an array of int that describes the several lengths of each part of the font 331 * @param compressionLevel the compression level of the Stream 332 * @throws DocumentException error in the stream compression 333 * @since 2.1.3 (replaces the constructor without param compressionLevel) 334 */ StreamFont(byte contents[], int lengths[], int compressionLevel)335 public StreamFont(byte contents[], int lengths[], int compressionLevel) throws DocumentException { 336 try { 337 bytes = contents; 338 put(PdfName.LENGTH, new PdfNumber(bytes.length)); 339 for (int k = 0; k < lengths.length; ++k) { 340 put(new PdfName("Length" + (k + 1)), new PdfNumber(lengths[k])); 341 } 342 flateCompress(compressionLevel); 343 } 344 catch (Exception e) { 345 throw new DocumentException(e); 346 } 347 } 348 349 /** 350 * Generates the PDF stream for a font. 351 * @param contents the content of a stream 352 * @param subType the subtype of the font. 353 * @param compressionLevel the compression level of the Stream 354 * @throws DocumentException error in the stream compression 355 * @since 2.1.3 (replaces the constructor without param compressionLevel) 356 */ StreamFont(byte contents[], String subType, int compressionLevel)357 public StreamFont(byte contents[], String subType, int compressionLevel) throws DocumentException { 358 try { 359 bytes = contents; 360 put(PdfName.LENGTH, new PdfNumber(bytes.length)); 361 if (subType != null) 362 put(PdfName.SUBTYPE, new PdfName(subType)); 363 flateCompress(compressionLevel); 364 } 365 catch (Exception e) { 366 throw new DocumentException(e); 367 } 368 } 369 } 370 371 /** 372 *Creates new BaseFont 373 */ BaseFont()374 protected BaseFont() { 375 } 376 377 /** 378 * Creates a new font. This will always be the default Helvetica font (not embedded). 379 * This method is introduced because Helvetica is used in many examples. 380 * @return a BaseFont object (Helvetica, Winansi, not embedded) 381 * @throws IOException This shouldn't occur ever 382 * @throws DocumentException This shouldn't occur ever 383 * @since 2.1.1 384 */ createFont()385 public static BaseFont createFont() throws DocumentException, IOException { 386 return createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED); 387 } 388 389 /** 390 * Creates a new font. This font can be one of the 14 built in types, 391 * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the 392 * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier 393 * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An 394 * example would be "STSong-Light,Bold". Note that this modifiers do not work if 395 * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". 396 * This would get the second font (indexes start at 0), in this case "MS PGothic". 397 * <P> 398 * The fonts are cached and if they already exist they are extracted from the cache, 399 * not parsed again. 400 * <P> 401 * Besides the common encodings described by name, custom encodings 402 * can also be made. These encodings will only work for the single byte fonts 403 * Type1 and TrueType. The encoding string starts with a '#' 404 * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list 405 * of hex values representing the Unicode codes that compose that encoding.<br> 406 * The "simple" encoding is recommended for TrueType fonts 407 * as the "full" encoding risks not matching the character with the right glyph 408 * if not done with care.<br> 409 * The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be 410 * described by non standard names like the Tex math fonts. Each group of three elements 411 * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character 412 * used to access the glyph. The space must be assigned to character position 32 otherwise 413 * text justification will not work. 414 * <P> 415 * Example for a "simple" encoding that includes the Unicode 416 * character space, A, B and ecyrillic: 417 * <PRE> 418 * "# simple 32 0020 0041 0042 0454" 419 * </PRE> 420 * <P> 421 * Example for a "full" encoding for a Type1 Tex font: 422 * <PRE> 423 * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020" 424 * </PRE> 425 * <P> 426 * This method calls:<br> 427 * <PRE> 428 * createFont(name, encoding, embedded, true, null, null); 429 * </PRE> 430 * @param name the name of the font or its location on file 431 * @param encoding the encoding to be applied to this font 432 * @param embedded true if the font is to be embedded in the PDF 433 * @return returns a new font. This font may come from the cache 434 * @throws DocumentException the font is invalid 435 * @throws IOException the font file could not be read 436 */ createFont(String name, String encoding, boolean embedded)437 public static BaseFont createFont(String name, String encoding, boolean embedded) throws DocumentException, IOException { 438 return createFont(name, encoding, embedded, true, null, null, false); 439 } 440 441 /** 442 * Creates a new font. This font can be one of the 14 built in types, 443 * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the 444 * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier 445 * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An 446 * example would be "STSong-Light,Bold". Note that this modifiers do not work if 447 * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". 448 * This would get the second font (indexes start at 0), in this case "MS PGothic". 449 * <P> 450 * The fonts are cached and if they already exist they are extracted from the cache, 451 * not parsed again. 452 * <P> 453 * Besides the common encodings described by name, custom encodings 454 * can also be made. These encodings will only work for the single byte fonts 455 * Type1 and TrueType. The encoding string starts with a '#' 456 * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list 457 * of hex values representing the Unicode codes that compose that encoding.<br> 458 * The "simple" encoding is recommended for TrueType fonts 459 * as the "full" encoding risks not matching the character with the right glyph 460 * if not done with care.<br> 461 * The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be 462 * described by non standard names like the Tex math fonts. Each group of three elements 463 * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character 464 * used to access the glyph. The space must be assigned to character position 32 otherwise 465 * text justification will not work. 466 * <P> 467 * Example for a "simple" encoding that includes the Unicode 468 * character space, A, B and ecyrillic: 469 * <PRE> 470 * "# simple 32 0020 0041 0042 0454" 471 * </PRE> 472 * <P> 473 * Example for a "full" encoding for a Type1 Tex font: 474 * <PRE> 475 * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020" 476 * </PRE> 477 * <P> 478 * This method calls:<br> 479 * <PRE> 480 * createFont(name, encoding, embedded, true, null, null); 481 * </PRE> 482 * @param name the name of the font or its location on file 483 * @param encoding the encoding to be applied to this font 484 * @param embedded true if the font is to be embedded in the PDF 485 * @param forceRead in some cases (TrueTypeFont, Type1Font), the full font file will be read and kept in memory if forceRead is true 486 * @return returns a new font. This font may come from the cache 487 * @throws DocumentException the font is invalid 488 * @throws IOException the font file could not be read 489 * @since 2.1.5 490 */ createFont(String name, String encoding, boolean embedded, boolean forceRead)491 public static BaseFont createFont(String name, String encoding, boolean embedded, boolean forceRead) throws DocumentException, IOException { 492 return createFont(name, encoding, embedded, true, null, null, forceRead); 493 } 494 495 /** Creates a new font. This font can be one of the 14 built in types, 496 * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the 497 * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier 498 * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An 499 * example would be "STSong-Light,Bold". Note that this modifiers do not work if 500 * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". 501 * This would get the second font (indexes start at 0), in this case "MS PGothic". 502 * <P> 503 * The fonts may or may not be cached depending on the flag <CODE>cached</CODE>. 504 * If the <CODE>byte</CODE> arrays are present the font will be 505 * read from them instead of the name. A name is still required to identify 506 * the font type. 507 * <P> 508 * Besides the common encodings described by name, custom encodings 509 * can also be made. These encodings will only work for the single byte fonts 510 * Type1 and TrueType. The encoding string starts with a '#' 511 * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list 512 * of hex values representing the Unicode codes that compose that encoding.<br> 513 * The "simple" encoding is recommended for TrueType fonts 514 * as the "full" encoding risks not matching the character with the right glyph 515 * if not done with care.<br> 516 * The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be 517 * described by non standard names like the Tex math fonts. Each group of three elements 518 * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character 519 * used to access the glyph. The space must be assigned to character position 32 otherwise 520 * text justification will not work. 521 * <P> 522 * Example for a "simple" encoding that includes the Unicode 523 * character space, A, B and ecyrillic: 524 * <PRE> 525 * "# simple 32 0020 0041 0042 0454" 526 * </PRE> 527 * <P> 528 * Example for a "full" encoding for a Type1 Tex font: 529 * <PRE> 530 * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020" 531 * </PRE> 532 * @param name the name of the font or its location on file 533 * @param encoding the encoding to be applied to this font 534 * @param embedded true if the font is to be embedded in the PDF 535 * @param cached true if the font comes from the cache or is added to 536 * the cache if new, false if the font is always created new 537 * @param ttfAfm the true type font or the afm in a byte array 538 * @param pfb the pfb in a byte array 539 * @return returns a new font. This font may come from the cache but only if cached 540 * is true, otherwise it will always be created new 541 * @throws DocumentException the font is invalid 542 * @throws IOException the font file could not be read 543 * @since iText 0.80 544 */ createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[])545 public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[]) throws DocumentException, IOException { 546 return createFont(name, encoding, embedded, cached, ttfAfm, pfb, false); 547 } 548 549 /** Creates a new font. This font can be one of the 14 built in types, 550 * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the 551 * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier 552 * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An 553 * example would be "STSong-Light,Bold". Note that this modifiers do not work if 554 * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". 555 * This would get the second font (indexes start at 0), in this case "MS PGothic". 556 * <P> 557 * The fonts may or may not be cached depending on the flag <CODE>cached</CODE>. 558 * If the <CODE>byte</CODE> arrays are present the font will be 559 * read from them instead of the name. A name is still required to identify 560 * the font type. 561 * <P> 562 * Besides the common encodings described by name, custom encodings 563 * can also be made. These encodings will only work for the single byte fonts 564 * Type1 and TrueType. The encoding string starts with a '#' 565 * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list 566 * of hex values representing the Unicode codes that compose that encoding.<br> 567 * The "simple" encoding is recommended for TrueType fonts 568 * as the "full" encoding risks not matching the character with the right glyph 569 * if not done with care.<br> 570 * The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be 571 * described by non standard names like the Tex math fonts. Each group of three elements 572 * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character 573 * used to access the glyph. The space must be assigned to character position 32 otherwise 574 * text justification will not work. 575 * <P> 576 * Example for a "simple" encoding that includes the Unicode 577 * character space, A, B and ecyrillic: 578 * <PRE> 579 * "# simple 32 0020 0041 0042 0454" 580 * </PRE> 581 * <P> 582 * Example for a "full" encoding for a Type1 Tex font: 583 * <PRE> 584 * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020" 585 * </PRE> 586 * @param name the name of the font or its location on file 587 * @param encoding the encoding to be applied to this font 588 * @param embedded true if the font is to be embedded in the PDF 589 * @param cached true if the font comes from the cache or is added to 590 * the cache if new, false if the font is always created new 591 * @param ttfAfm the true type font or the afm in a byte array 592 * @param pfb the pfb in a byte array 593 * @param noThrow if true will not throw an exception if the font is not recognized and will return null, if false will throw 594 * an exception if the font is not recognized. Note that even if true an exception may be thrown in some circumstances. 595 * This parameter is useful for FontFactory that may have to check many invalid font names before finding the right one 596 * @return returns a new font. This font may come from the cache but only if cached 597 * is true, otherwise it will always be created new 598 * @throws DocumentException the font is invalid 599 * @throws IOException the font file could not be read 600 * @since 2.0.3 601 */ createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[], boolean noThrow)602 public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[], boolean noThrow) throws DocumentException, IOException { 603 return createFont(name, encoding, embedded, cached, ttfAfm, pfb, false, false); 604 } 605 606 /** Creates a new font. This font can be one of the 14 built in types, 607 * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the 608 * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier 609 * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An 610 * example would be "STSong-Light,Bold". Note that this modifiers do not work if 611 * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". 612 * This would get the second font (indexes start at 0), in this case "MS PGothic". 613 * <P> 614 * The fonts may or may not be cached depending on the flag <CODE>cached</CODE>. 615 * If the <CODE>byte</CODE> arrays are present the font will be 616 * read from them instead of the name. A name is still required to identify 617 * the font type. 618 * <P> 619 * Besides the common encodings described by name, custom encodings 620 * can also be made. These encodings will only work for the single byte fonts 621 * Type1 and TrueType. The encoding string starts with a '#' 622 * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list 623 * of hex values representing the Unicode codes that compose that encoding.<br> 624 * The "simple" encoding is recommended for TrueType fonts 625 * as the "full" encoding risks not matching the character with the right glyph 626 * if not done with care.<br> 627 * The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be 628 * described by non standard names like the Tex math fonts. Each group of three elements 629 * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character 630 * used to access the glyph. The space must be assigned to character position 32 otherwise 631 * text justification will not work. 632 * <P> 633 * Example for a "simple" encoding that includes the Unicode 634 * character space, A, B and ecyrillic: 635 * <PRE> 636 * "# simple 32 0020 0041 0042 0454" 637 * </PRE> 638 * <P> 639 * Example for a "full" encoding for a Type1 Tex font: 640 * <PRE> 641 * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020" 642 * </PRE> 643 * @param name the name of the font or its location on file 644 * @param encoding the encoding to be applied to this font 645 * @param embedded true if the font is to be embedded in the PDF 646 * @param cached true if the font comes from the cache or is added to 647 * the cache if new, false if the font is always created new 648 * @param ttfAfm the true type font or the afm in a byte array 649 * @param pfb the pfb in a byte array 650 * @param noThrow if true will not throw an exception if the font is not recognized and will return null, if false will throw 651 * an exception if the font is not recognized. Note that even if true an exception may be thrown in some circumstances. 652 * This parameter is useful for FontFactory that may have to check many invalid font names before finding the right one 653 * @param forceRead in some cases (TrueTypeFont, Type1Font), the full font file will be read and kept in memory if forceRead is true 654 * @return returns a new font. This font may come from the cache but only if cached 655 * is true, otherwise it will always be created new 656 * @throws DocumentException the font is invalid 657 * @throws IOException the font file could not be read 658 * @since 2.1.5 659 */ createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[], boolean noThrow, boolean forceRead)660 public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[], boolean noThrow, boolean forceRead) throws DocumentException, IOException { 661 String nameBase = getBaseName(name); 662 encoding = normalizeEncoding(encoding); 663 boolean isBuiltinFonts14 = BuiltinFonts14.containsKey(name); 664 boolean isCJKFont = isBuiltinFonts14 ? false : CJKFont.isCJKFont(nameBase, encoding); 665 if (isBuiltinFonts14 || isCJKFont) 666 embedded = false; 667 else if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V)) 668 embedded = true; 669 BaseFont fontFound = null; 670 BaseFont fontBuilt = null; 671 String key = name + "\n" + encoding + "\n" + embedded; 672 if (cached) { 673 synchronized (fontCache) { 674 fontFound = (BaseFont)fontCache.get(key); 675 } 676 if (fontFound != null) 677 return fontFound; 678 } 679 if (isBuiltinFonts14 || name.toLowerCase().endsWith(".afm") || name.toLowerCase().endsWith(".pfm")) { 680 fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb, forceRead); 681 fontBuilt.fastWinansi = encoding.equals(CP1252); 682 } 683 else if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) { 684 if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V)) 685 fontBuilt = new TrueTypeFontUnicode(name, encoding, embedded, ttfAfm, forceRead); 686 else { 687 fontBuilt = new TrueTypeFont(name, encoding, embedded, ttfAfm, false, forceRead); 688 fontBuilt.fastWinansi = encoding.equals(CP1252); 689 } 690 } 691 else if (isCJKFont) 692 fontBuilt = new CJKFont(name, encoding, embedded); 693 else if (noThrow) 694 return null; 695 else 696 throw new DocumentException(MessageLocalization.getComposedMessage("font.1.with.2.is.not.recognized", name, encoding)); 697 if (cached) { 698 synchronized (fontCache) { 699 fontFound = (BaseFont)fontCache.get(key); 700 if (fontFound != null) 701 return fontFound; 702 fontCache.put(key, fontBuilt); 703 } 704 } 705 return fontBuilt; 706 } 707 708 /** 709 * Creates a font based on an existing document font. The created font font may not 710 * behave as expected, depending on the encoding or subset. 711 * @param fontRef the reference to the document font 712 * @return the font 713 */ createFont(PRIndirectReference fontRef)714 public static BaseFont createFont(PRIndirectReference fontRef) { 715 return new DocumentFont(fontRef); 716 } 717 718 /** 719 * Gets the name without the modifiers Bold, Italic or BoldItalic. 720 * @param name the full name of the font 721 * @return the name without the modifiers Bold, Italic or BoldItalic 722 */ getBaseName(String name)723 protected static String getBaseName(String name) { 724 if (name.endsWith(",Bold")) 725 return name.substring(0, name.length() - 5); 726 else if (name.endsWith(",Italic")) 727 return name.substring(0, name.length() - 7); 728 else if (name.endsWith(",BoldItalic")) 729 return name.substring(0, name.length() - 11); 730 else 731 return name; 732 } 733 734 /** 735 * Normalize the encoding names. "winansi" is changed to "Cp1252" and 736 * "macroman" is changed to "MacRoman". 737 * @param enc the encoding to be normalized 738 * @return the normalized encoding 739 */ normalizeEncoding(String enc)740 protected static String normalizeEncoding(String enc) { 741 if (enc.equals("winansi") || enc.equals("")) 742 return CP1252; 743 else if (enc.equals("macroman")) 744 return MACROMAN; 745 else 746 return enc; 747 } 748 749 /** 750 * Creates the <CODE>widths</CODE> and the <CODE>differences</CODE> arrays 751 */ createEncoding()752 protected void createEncoding() { 753 if (encoding.startsWith("#")) { 754 specialMap = new IntHashtable(); 755 StringTokenizer tok = new StringTokenizer(encoding.substring(1), " ,\t\n\r\f"); 756 if (tok.nextToken().equals("full")) { 757 while (tok.hasMoreTokens()) { 758 String order = tok.nextToken(); 759 String name = tok.nextToken(); 760 char uni = (char)Integer.parseInt(tok.nextToken(), 16); 761 int orderK; 762 if (order.startsWith("'")) 763 orderK = order.charAt(1); 764 else 765 orderK = Integer.parseInt(order); 766 orderK %= 256; 767 specialMap.put(uni, orderK); 768 differences[orderK] = name; 769 unicodeDifferences[orderK] = uni; 770 widths[orderK] = getRawWidth(uni, name); 771 charBBoxes[orderK] = getRawCharBBox(uni, name); 772 } 773 } 774 else { 775 int k = 0; 776 if (tok.hasMoreTokens()) 777 k = Integer.parseInt(tok.nextToken()); 778 while (tok.hasMoreTokens() && k < 256) { 779 String hex = tok.nextToken(); 780 int uni = Integer.parseInt(hex, 16) % 0x10000; 781 String name = GlyphList.unicodeToName(uni); 782 if (name != null) { 783 specialMap.put(uni, k); 784 differences[k] = name; 785 unicodeDifferences[k] = (char)uni; 786 widths[k] = getRawWidth(uni, name); 787 charBBoxes[k] = getRawCharBBox(uni, name); 788 ++k; 789 } 790 } 791 } 792 for (int k = 0; k < 256; ++k) { 793 if (differences[k] == null) { 794 differences[k] = notdef; 795 } 796 } 797 } 798 else if (fontSpecific) { 799 for (int k = 0; k < 256; ++k) { 800 widths[k] = getRawWidth(k, null); 801 charBBoxes[k] = getRawCharBBox(k, null); 802 } 803 } 804 else { 805 String s; 806 String name; 807 char c; 808 byte b[] = new byte[1]; 809 for (int k = 0; k < 256; ++k) { 810 b[0] = (byte)k; 811 s = PdfEncodings.convertToString(b, encoding); 812 if (s.length() > 0) { 813 c = s.charAt(0); 814 } 815 else { 816 c = '?'; 817 } 818 name = GlyphList.unicodeToName(c); 819 if (name == null) 820 name = notdef; 821 differences[k] = name; 822 unicodeDifferences[k] = c; 823 widths[k] = getRawWidth(c, name); 824 charBBoxes[k] = getRawCharBBox(c, name); 825 } 826 } 827 } 828 829 /** 830 * Gets the width from the font according to the Unicode char <CODE>c</CODE> 831 * or the <CODE>name</CODE>. If the <CODE>name</CODE> is null it's a symbolic font. 832 * @param c the unicode char 833 * @param name the glyph name 834 * @return the width of the char 835 */ getRawWidth(int c, String name)836 abstract int getRawWidth(int c, String name); 837 838 /** 839 * Gets the kerning between two Unicode chars. 840 * @param char1 the first char 841 * @param char2 the second char 842 * @return the kerning to be applied in normalized 1000 units 843 */ getKerning(int char1, int char2)844 public abstract int getKerning(int char1, int char2); 845 846 /** 847 * Sets the kerning between two Unicode chars. 848 * @param char1 the first char 849 * @param char2 the second char 850 * @param kern the kerning to apply in normalized 1000 units 851 * @return <code>true</code> if the kerning was applied, <code>false</code> otherwise 852 */ setKerning(int char1, int char2, int kern)853 public abstract boolean setKerning(int char1, int char2, int kern); 854 855 /** 856 * Gets the width of a <CODE>char</CODE> in normalized 1000 units. 857 * @param char1 the unicode <CODE>char</CODE> to get the width of 858 * @return the width in normalized 1000 units 859 */ getWidth(int char1)860 public int getWidth(int char1) { 861 if (fastWinansi) { 862 if (char1 < 128 || (char1 >= 160 && char1 <= 255)) 863 return widths[char1]; 864 else 865 return widths[PdfEncodings.winansi.get(char1)]; 866 } 867 else { 868 int total = 0; 869 byte mbytes[] = convertToBytes((char)char1); 870 for (int k = 0; k < mbytes.length; ++k) 871 total += widths[0xff & mbytes[k]]; 872 return total; 873 } 874 } 875 876 /** 877 * Gets the width of a <CODE>String</CODE> in normalized 1000 units. 878 * @param text the <CODE>String</CODE> to get the width of 879 * @return the width in normalized 1000 units 880 */ getWidth(String text)881 public int getWidth(String text) { 882 int total = 0; 883 if (fastWinansi) { 884 int len = text.length(); 885 for (int k = 0; k < len; ++k) { 886 char char1 = text.charAt(k); 887 if (char1 < 128 || (char1 >= 160 && char1 <= 255)) 888 total += widths[char1]; 889 else 890 total += widths[PdfEncodings.winansi.get(char1)]; 891 } 892 return total; 893 } 894 else { 895 byte mbytes[] = convertToBytes(text); 896 for (int k = 0; k < mbytes.length; ++k) 897 total += widths[0xff & mbytes[k]]; 898 } 899 return total; 900 } 901 902 /** 903 * Gets the descent of a <CODE>String</CODE> in normalized 1000 units. The descent will always be 904 * less than or equal to zero even if all the characters have an higher descent. 905 * @param text the <CODE>String</CODE> to get the descent of 906 * @return the descent in normalized 1000 units 907 */ getDescent(String text)908 public int getDescent(String text) { 909 int min = 0; 910 char chars[] = text.toCharArray(); 911 for (int k = 0; k < chars.length; ++k) { 912 int bbox[] = getCharBBox(chars[k]); 913 if (bbox != null && bbox[1] < min) 914 min = bbox[1]; 915 } 916 return min; 917 } 918 919 /** 920 * Gets the ascent of a <CODE>String</CODE> in normalized 1000 units. The ascent will always be 921 * greater than or equal to zero even if all the characters have a lower ascent. 922 * @param text the <CODE>String</CODE> to get the ascent of 923 * @return the ascent in normalized 1000 units 924 */ getAscent(String text)925 public int getAscent(String text) { 926 int max = 0; 927 char chars[] = text.toCharArray(); 928 for (int k = 0; k < chars.length; ++k) { 929 int bbox[] = getCharBBox(chars[k]); 930 if (bbox != null && bbox[3] > max) 931 max = bbox[3]; 932 } 933 return max; 934 } 935 936 /** 937 * Gets the descent of a <CODE>String</CODE> in points. The descent will always be 938 * less than or equal to zero even if all the characters have an higher descent. 939 * @param text the <CODE>String</CODE> to get the descent of 940 * @param fontSize the size of the font 941 * @return the descent in points 942 */ getDescentPoint(String text, float fontSize)943 public float getDescentPoint(String text, float fontSize) 944 { 945 return getDescent(text) * 0.001f * fontSize; 946 } 947 948 /** 949 * Gets the ascent of a <CODE>String</CODE> in points. The ascent will always be 950 * greater than or equal to zero even if all the characters have a lower ascent. 951 * @param text the <CODE>String</CODE> to get the ascent of 952 * @param fontSize the size of the font 953 * @return the ascent in points 954 */ getAscentPoint(String text, float fontSize)955 public float getAscentPoint(String text, float fontSize) 956 { 957 return getAscent(text) * 0.001f * fontSize; 958 } 959 // ia> 960 961 /** 962 * Gets the width of a <CODE>String</CODE> in points taking kerning 963 * into account. 964 * @param text the <CODE>String</CODE> to get the width of 965 * @param fontSize the font size 966 * @return the width in points 967 */ getWidthPointKerned(String text, float fontSize)968 public float getWidthPointKerned(String text, float fontSize) { 969 float size = getWidth(text) * 0.001f * fontSize; 970 if (!hasKernPairs()) 971 return size; 972 int len = text.length() - 1; 973 int kern = 0; 974 char c[] = text.toCharArray(); 975 for (int k = 0; k < len; ++k) { 976 kern += getKerning(c[k], c[k + 1]); 977 } 978 return size + kern * 0.001f * fontSize; 979 } 980 981 /** 982 * Gets the width of a <CODE>String</CODE> in points. 983 * @param text the <CODE>String</CODE> to get the width of 984 * @param fontSize the font size 985 * @return the width in points 986 */ getWidthPoint(String text, float fontSize)987 public float getWidthPoint(String text, float fontSize) { 988 return getWidth(text) * 0.001f * fontSize; 989 } 990 991 /** 992 * Gets the width of a <CODE>char</CODE> in points. 993 * @param char1 the <CODE>char</CODE> to get the width of 994 * @param fontSize the font size 995 * @return the width in points 996 */ getWidthPoint(int char1, float fontSize)997 public float getWidthPoint(int char1, float fontSize) { 998 return getWidth(char1) * 0.001f * fontSize; 999 } 1000 1001 /** 1002 * Converts a <CODE>String</CODE> to a </CODE>byte</CODE> array according 1003 * to the font's encoding. 1004 * @param text the <CODE>String</CODE> to be converted 1005 * @return an array of <CODE>byte</CODE> representing the conversion according to the font's encoding 1006 */ convertToBytes(String text)1007 byte[] convertToBytes(String text) { 1008 if (directTextToByte) 1009 return PdfEncodings.convertToBytes(text, null); 1010 if (specialMap != null) { 1011 byte[] b = new byte[text.length()]; 1012 int ptr = 0; 1013 int length = text.length(); 1014 for (int k = 0; k < length; ++k) { 1015 char c = text.charAt(k); 1016 if (specialMap.containsKey(c)) 1017 b[ptr++] = (byte)specialMap.get(c); 1018 } 1019 if (ptr < length) { 1020 byte[] b2 = new byte[ptr]; 1021 System.arraycopy(b, 0, b2, 0, ptr); 1022 return b2; 1023 } 1024 else 1025 return b; 1026 } 1027 return PdfEncodings.convertToBytes(text, encoding); 1028 } 1029 1030 /** 1031 * Converts a <CODE>char</CODE> to a </CODE>byte</CODE> array according 1032 * to the font's encoding. 1033 * @param char1 the <CODE>char</CODE> to be converted 1034 * @return an array of <CODE>byte</CODE> representing the conversion according to the font's encoding 1035 */ convertToBytes(int char1)1036 byte[] convertToBytes(int char1) { 1037 if (directTextToByte) 1038 return PdfEncodings.convertToBytes((char)char1, null); 1039 if (specialMap != null) { 1040 if (specialMap.containsKey(char1)) 1041 return new byte[]{(byte)specialMap.get(char1)}; 1042 else 1043 return new byte[0]; 1044 } 1045 return PdfEncodings.convertToBytes((char)char1, encoding); 1046 } 1047 1048 /** Outputs to the writer the font dictionaries and streams. 1049 * @param writer the writer for this document 1050 * @param ref the font indirect reference 1051 * @param params several parameters that depend on the font type 1052 * @throws IOException on error 1053 * @throws DocumentException error in generating the object 1054 */ writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[])1055 abstract void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException; 1056 1057 /** 1058 * Returns a PdfStream object with the full font program (if possible). 1059 * This method will return null for some types of fonts (CJKFont, Type3Font) 1060 * or if there is no font program available (standard Type 1 fonts). 1061 * @return a PdfStream with the font program 1062 * @since 2.1.3 1063 */ getFullFontStream()1064 abstract PdfStream getFullFontStream() throws IOException, DocumentException; 1065 1066 /** Gets the encoding used to convert <CODE>String</CODE> into <CODE>byte[]</CODE>. 1067 * @return the encoding name 1068 */ getEncoding()1069 public String getEncoding() { 1070 return encoding; 1071 } 1072 1073 /** Gets the font parameter identified by <CODE>key</CODE>. Valid values 1074 * for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>AWT_ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>, 1075 * <CODE>DESCENT</CODE>, <CODE>AWT_DESCENT</CODE>, 1076 * <CODE>ITALICANGLE</CODE>, <CODE>BBOXLLX</CODE>, <CODE>BBOXLLY</CODE>, <CODE>BBOXURX</CODE> 1077 * and <CODE>BBOXURY</CODE>. 1078 * @param key the parameter to be extracted 1079 * @param fontSize the font size in points 1080 * @return the parameter in points 1081 */ getFontDescriptor(int key, float fontSize)1082 public abstract float getFontDescriptor(int key, float fontSize); 1083 1084 /** Gets the font type. The font types can be: FONT_TYPE_T1, 1085 * FONT_TYPE_TT, FONT_TYPE_CJK and FONT_TYPE_TTUNI. 1086 * @return the font type 1087 */ getFontType()1088 public int getFontType() { 1089 return fontType; 1090 } 1091 1092 /** Gets the embedded flag. 1093 * @return <CODE>true</CODE> if the font is embedded. 1094 */ isEmbedded()1095 public boolean isEmbedded() { 1096 return embedded; 1097 } 1098 1099 /** Gets the symbolic flag of the font. 1100 * @return <CODE>true</CODE> if the font is symbolic 1101 */ isFontSpecific()1102 public boolean isFontSpecific() { 1103 return fontSpecific; 1104 } 1105 1106 /** Creates a unique subset prefix to be added to the font name when the font is embedded and subset. 1107 * @return the subset prefix 1108 */ createSubsetPrefix()1109 public static String createSubsetPrefix() { 1110 String s = ""; 1111 for (int k = 0; k < 6; ++k) 1112 s += (char)(Math.random() * 26 + 'A'); 1113 return s + "+"; 1114 } 1115 1116 /** Gets the Unicode character corresponding to the byte output to the pdf stream. 1117 * @param index the byte index 1118 * @return the Unicode character 1119 */ getUnicodeDifferences(int index)1120 char getUnicodeDifferences(int index) { 1121 return unicodeDifferences[index]; 1122 } 1123 1124 /** Gets the postscript font name. 1125 * @return the postscript font name 1126 */ getPostscriptFontName()1127 public abstract String getPostscriptFontName(); 1128 1129 /** 1130 * Sets the font name that will appear in the pdf font dictionary. 1131 * Use with care as it can easily make a font unreadable if not embedded. 1132 * @param name the new font name 1133 */ setPostscriptFontName(String name)1134 public abstract void setPostscriptFontName(String name); 1135 1136 /** Gets the full name of the font. If it is a True Type font 1137 * each array element will have {Platform ID, Platform Encoding ID, 1138 * Language ID, font name}. The interpretation of this values can be 1139 * found in the Open Type specification, chapter 2, in the 'name' table.<br> 1140 * For the other fonts the array has a single element with {"", "", "", 1141 * font name}. 1142 * @return the full name of the font 1143 */ getFullFontName()1144 public abstract String[][] getFullFontName(); 1145 1146 /** Gets all the entries of the names-table. If it is a True Type font 1147 * each array element will have {Name ID, Platform ID, Platform Encoding ID, 1148 * Language ID, font name}. The interpretation of this values can be 1149 * found in the Open Type specification, chapter 2, in the 'name' table.<br> 1150 * For the other fonts the array has a single element with {"4", "", "", "", 1151 * font name}. 1152 * @return the full name of the font 1153 * @since 2.0.8 1154 */ getAllNameEntries()1155 public abstract String[][] getAllNameEntries(); 1156 1157 /** Gets the full name of the font. If it is a True Type font 1158 * each array element will have {Platform ID, Platform Encoding ID, 1159 * Language ID, font name}. The interpretation of this values can be 1160 * found in the Open Type specification, chapter 2, in the 'name' table.<br> 1161 * For the other fonts the array has a single element with {"", "", "", 1162 * font name}. 1163 * @param name the name of the font 1164 * @param encoding the encoding of the font 1165 * @param ttfAfm the true type font or the afm in a byte array 1166 * @throws DocumentException on error 1167 * @throws IOException on error 1168 * @return the full name of the font 1169 */ getFullFontName(String name, String encoding, byte ttfAfm[])1170 public static String[][] getFullFontName(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { 1171 String nameBase = getBaseName(name); 1172 BaseFont fontBuilt = null; 1173 if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) 1174 fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true, false); 1175 else 1176 fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); 1177 return fontBuilt.getFullFontName(); 1178 } 1179 1180 /** Gets all the names from the font. Only the required tables are read. 1181 * @param name the name of the font 1182 * @param encoding the encoding of the font 1183 * @param ttfAfm the true type font or the afm in a byte array 1184 * @throws DocumentException on error 1185 * @throws IOException on error 1186 * @return an array of Object[] built with {getPostscriptFontName(), getFamilyFontName(), getFullFontName()} 1187 */ getAllFontNames(String name, String encoding, byte ttfAfm[])1188 public static Object[] getAllFontNames(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { 1189 String nameBase = getBaseName(name); 1190 BaseFont fontBuilt = null; 1191 if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) 1192 fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true, false); 1193 else 1194 fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); 1195 return new Object[]{fontBuilt.getPostscriptFontName(), fontBuilt.getFamilyFontName(), fontBuilt.getFullFontName()}; 1196 } 1197 1198 /** Gets all the entries of the namestable from the font. Only the required tables are read. 1199 * @param name the name of the font 1200 * @param encoding the encoding of the font 1201 * @param ttfAfm the true type font or the afm in a byte array 1202 * @throws DocumentException on error 1203 * @throws IOException on error 1204 * @return an array of Object[] built with {getPostscriptFontName(), getFamilyFontName(), getFullFontName()} 1205 * @since 2.0.8 1206 */ getAllNameEntries(String name, String encoding, byte ttfAfm[])1207 public static String[][] getAllNameEntries(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { 1208 String nameBase = getBaseName(name); 1209 BaseFont fontBuilt = null; 1210 if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) 1211 fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true, false); 1212 else 1213 fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); 1214 return fontBuilt.getAllNameEntries(); 1215 } 1216 1217 /** Gets the family name of the font. If it is a True Type font 1218 * each array element will have {Platform ID, Platform Encoding ID, 1219 * Language ID, font name}. The interpretation of this values can be 1220 * found in the Open Type specification, chapter 2, in the 'name' table.<br> 1221 * For the other fonts the array has a single element with {"", "", "", 1222 * font name}. 1223 * @return the family name of the font 1224 */ getFamilyFontName()1225 public abstract String[][] getFamilyFontName(); 1226 1227 /** Gets the code pages supported by the font. This has only meaning 1228 * with True Type fonts. 1229 * @return the code pages supported by the font 1230 */ getCodePagesSupported()1231 public String[] getCodePagesSupported() { 1232 return new String[0]; 1233 } 1234 1235 /** Enumerates the postscript font names present inside a 1236 * True Type Collection. 1237 * @param ttcFile the file name of the font 1238 * @throws DocumentException on error 1239 * @throws IOException on error 1240 * @return the postscript font names 1241 */ enumerateTTCNames(String ttcFile)1242 public static String[] enumerateTTCNames(String ttcFile) throws DocumentException, IOException { 1243 return new EnumerateTTC(ttcFile).getNames(); 1244 } 1245 1246 /** Enumerates the postscript font names present inside a 1247 * True Type Collection. 1248 * @param ttcArray the font as a <CODE>byte</CODE> array 1249 * @throws DocumentException on error 1250 * @throws IOException on error 1251 * @return the postscript font names 1252 */ enumerateTTCNames(byte ttcArray[])1253 public static String[] enumerateTTCNames(byte ttcArray[]) throws DocumentException, IOException { 1254 return new EnumerateTTC(ttcArray).getNames(); 1255 } 1256 1257 /** Gets the font width array. 1258 * @return the font width array 1259 */ getWidths()1260 public int[] getWidths() { 1261 return widths; 1262 } 1263 1264 /** Gets the array with the names of the characters. 1265 * @return the array with the names of the characters 1266 */ getDifferences()1267 public String[] getDifferences() { 1268 return differences; 1269 } 1270 1271 /** Gets the array with the unicode characters. 1272 * @return the array with the unicode characters 1273 */ getUnicodeDifferences()1274 public char[] getUnicodeDifferences() { 1275 return unicodeDifferences; 1276 } 1277 1278 /** Gets the state of the property. 1279 * @return value of property forceWidthsOutput 1280 */ isForceWidthsOutput()1281 public boolean isForceWidthsOutput() { 1282 return forceWidthsOutput; 1283 } 1284 1285 /** Set to <CODE>true</CODE> to force the generation of the 1286 * widths array. 1287 * @param forceWidthsOutput <CODE>true</CODE> to force the generation of the 1288 * widths array 1289 */ setForceWidthsOutput(boolean forceWidthsOutput)1290 public void setForceWidthsOutput(boolean forceWidthsOutput) { 1291 this.forceWidthsOutput = forceWidthsOutput; 1292 } 1293 1294 /** Gets the direct conversion of <CODE>char</CODE> to <CODE>byte</CODE>. 1295 * @return value of property directTextToByte. 1296 * @see #setDirectTextToByte(boolean directTextToByte) 1297 */ isDirectTextToByte()1298 public boolean isDirectTextToByte() { 1299 return directTextToByte; 1300 } 1301 1302 /** Sets the conversion of <CODE>char</CODE> directly to <CODE>byte</CODE> 1303 * by casting. This is a low level feature to put the bytes directly in 1304 * the content stream without passing through String.getBytes(). 1305 * @param directTextToByte New value of property directTextToByte. 1306 */ setDirectTextToByte(boolean directTextToByte)1307 public void setDirectTextToByte(boolean directTextToByte) { 1308 this.directTextToByte = directTextToByte; 1309 } 1310 1311 /** Indicates if all the glyphs and widths for that particular 1312 * encoding should be included in the document. 1313 * @return <CODE>false</CODE> to include all the glyphs and widths. 1314 */ isSubset()1315 public boolean isSubset() { 1316 return subset; 1317 } 1318 1319 /** Indicates if all the glyphs and widths for that particular 1320 * encoding should be included in the document. When set to <CODE>true</CODE> 1321 * only the glyphs used will be included in the font. When set to <CODE>false</CODE> 1322 * and {@link #addSubsetRange(int[])} was not called the full font will be included 1323 * otherwise just the characters ranges will be included. 1324 * @param subset new value of property subset 1325 */ setSubset(boolean subset)1326 public void setSubset(boolean subset) { 1327 this.subset = subset; 1328 } 1329 1330 /** Gets the font resources. 1331 * @param key the full name of the resource 1332 * @return the <CODE>InputStream</CODE> to get the resource or 1333 * <CODE>null</CODE> if not found 1334 */ getResourceStream(String key)1335 public static InputStream getResourceStream(String key) { 1336 return getResourceStream(key, null); 1337 } 1338 1339 /** Gets the font resources. 1340 * @param key the full name of the resource 1341 * @param loader the ClassLoader to load the resource or null to try the ones available 1342 * @return the <CODE>InputStream</CODE> to get the resource or 1343 * <CODE>null</CODE> if not found 1344 */ getResourceStream(String key, ClassLoader loader)1345 public static InputStream getResourceStream(String key, ClassLoader loader) { 1346 if (key.startsWith("/")) 1347 key = key.substring(1); 1348 InputStream is = null; 1349 if (loader != null) { 1350 is = loader.getResourceAsStream(key); 1351 if (is != null) 1352 return is; 1353 } 1354 // Try to use Context Class Loader to load the properties file. 1355 try { 1356 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); 1357 if (contextClassLoader != null) { 1358 is = contextClassLoader.getResourceAsStream(key); 1359 } 1360 } catch (Throwable e) {} 1361 1362 if (is == null) { 1363 is = BaseFont.class.getResourceAsStream("/" + key); 1364 } 1365 if (is == null) { 1366 is = ClassLoader.getSystemResourceAsStream(key); 1367 } 1368 return is; 1369 } 1370 1371 /** Gets the Unicode equivalent to a CID. 1372 * The (inexistent) CID <FF00> is translated as '\n'. 1373 * It has only meaning with CJK fonts with Identity encoding. 1374 * @param c the CID code 1375 * @return the Unicode equivalent 1376 */ getUnicodeEquivalent(int c)1377 public int getUnicodeEquivalent(int c) { 1378 return c; 1379 } 1380 1381 /** Gets the CID code given an Unicode. 1382 * It has only meaning with CJK fonts. 1383 * @param c the Unicode 1384 * @return the CID equivalent 1385 */ getCidCode(int c)1386 public int getCidCode(int c) { 1387 return c; 1388 } 1389 1390 /** Checks if the font has any kerning pairs. 1391 * @return <CODE>true</CODE> if the font has any kerning pairs 1392 */ hasKernPairs()1393 public abstract boolean hasKernPairs(); 1394 1395 /** 1396 * Checks if a character exists in this font. 1397 * @param c the character to check 1398 * @return <CODE>true</CODE> if the character has a glyph, 1399 * <CODE>false</CODE> otherwise 1400 */ charExists(int c)1401 public boolean charExists(int c) { 1402 byte b[] = convertToBytes(c); 1403 return b.length > 0; 1404 } 1405 1406 /** 1407 * Sets the character advance. 1408 * @param c the character 1409 * @param advance the character advance normalized to 1000 units 1410 * @return <CODE>true</CODE> if the advance was set, 1411 * <CODE>false</CODE> otherwise 1412 */ setCharAdvance(int c, int advance)1413 public boolean setCharAdvance(int c, int advance) { 1414 byte b[] = convertToBytes(c); 1415 if (b.length == 0) 1416 return false; 1417 widths[0xff & b[0]] = advance; 1418 return true; 1419 } 1420 addFont(PRIndirectReference fontRef, IntHashtable hits, ArrayList fonts)1421 private static void addFont(PRIndirectReference fontRef, IntHashtable hits, ArrayList fonts) { 1422 PdfObject obj = PdfReader.getPdfObject(fontRef); 1423 if (obj == null || !obj.isDictionary()) 1424 return; 1425 PdfDictionary font = (PdfDictionary)obj; 1426 PdfName subtype = font.getAsName(PdfName.SUBTYPE); 1427 if (!PdfName.TYPE1.equals(subtype) && !PdfName.TRUETYPE.equals(subtype)) 1428 return; 1429 PdfName name = font.getAsName(PdfName.BASEFONT); 1430 fonts.add(new Object[]{PdfName.decodeName(name.toString()), fontRef}); 1431 hits.put(fontRef.getNumber(), 1); 1432 } 1433 recourseFonts(PdfDictionary page, IntHashtable hits, ArrayList fonts, int level)1434 private static void recourseFonts(PdfDictionary page, IntHashtable hits, ArrayList fonts, int level) { 1435 ++level; 1436 if (level > 50) // in case we have an endless loop 1437 return; 1438 PdfDictionary resources = page.getAsDict(PdfName.RESOURCES); 1439 if (resources == null) 1440 return; 1441 PdfDictionary font = resources.getAsDict(PdfName.FONT); 1442 if (font != null) { 1443 for (Iterator it = font.getKeys().iterator(); it.hasNext();) { 1444 PdfObject ft = font.get((PdfName)it.next()); 1445 if (ft == null || !ft.isIndirect()) 1446 continue; 1447 int hit = ((PRIndirectReference)ft).getNumber(); 1448 if (hits.containsKey(hit)) 1449 continue; 1450 addFont((PRIndirectReference)ft, hits, fonts); 1451 } 1452 } 1453 PdfDictionary xobj = resources.getAsDict(PdfName.XOBJECT); 1454 if (xobj != null) { 1455 for (Iterator it = xobj.getKeys().iterator(); it.hasNext();) { 1456 recourseFonts(xobj.getAsDict((PdfName)it.next()), hits, fonts, level); 1457 } 1458 } 1459 } 1460 1461 /** 1462 * Gets a list of all document fonts. Each element of the <CODE>ArrayList</CODE> 1463 * contains a <CODE>Object[]{String,PRIndirectReference}</CODE> with the font name 1464 * and the indirect reference to it. 1465 * @param reader the document where the fonts are to be listed from 1466 * @return the list of fonts and references 1467 */ getDocumentFonts(PdfReader reader)1468 public static ArrayList getDocumentFonts(PdfReader reader) { 1469 IntHashtable hits = new IntHashtable(); 1470 ArrayList fonts = new ArrayList(); 1471 int npages = reader.getNumberOfPages(); 1472 for (int k = 1; k <= npages; ++k) 1473 recourseFonts(reader.getPageN(k), hits, fonts, 1); 1474 return fonts; 1475 } 1476 1477 /** 1478 * Gets a list of the document fonts in a particular page. Each element of the <CODE>ArrayList</CODE> 1479 * contains a <CODE>Object[]{String,PRIndirectReference}</CODE> with the font name 1480 * and the indirect reference to it. 1481 * @param reader the document where the fonts are to be listed from 1482 * @param page the page to list the fonts from 1483 * @return the list of fonts and references 1484 */ getDocumentFonts(PdfReader reader, int page)1485 public static ArrayList getDocumentFonts(PdfReader reader, int page) { 1486 IntHashtable hits = new IntHashtable(); 1487 ArrayList fonts = new ArrayList(); 1488 recourseFonts(reader.getPageN(page), hits, fonts, 1); 1489 return fonts; 1490 } 1491 1492 /** 1493 * Gets the smallest box enclosing the character contours. It will return 1494 * <CODE>null</CODE> if the font has not the information or the character has no 1495 * contours, as in the case of the space, for example. Characters with no contours may 1496 * also return [0,0,0,0]. 1497 * @param c the character to get the contour bounding box from 1498 * @return an array of four floats with the bounding box in the format [llx,lly,urx,ury] or 1499 * <code>null</code> 1500 */ getCharBBox(int c)1501 public int[] getCharBBox(int c) { 1502 byte b[] = convertToBytes(c); 1503 if (b.length == 0) 1504 return null; 1505 else 1506 return charBBoxes[b[0] & 0xff]; 1507 } 1508 getRawCharBBox(int c, String name)1509 protected abstract int[] getRawCharBBox(int c, String name); 1510 1511 /** 1512 * iText expects Arabic Diactrics (tashkeel) to have zero advance but some fonts, 1513 * most notably those that come with Windows, like times.ttf, have non-zero 1514 * advance for those characters. This method makes those character to have zero 1515 * width advance and work correctly in the iText Arabic shaping and reordering 1516 * context. 1517 */ correctArabicAdvance()1518 public void correctArabicAdvance() { 1519 for (char c = '\u064b'; c <= '\u0658'; ++c) 1520 setCharAdvance(c, 0); 1521 setCharAdvance('\u0670', 0); 1522 for (char c = '\u06d6'; c <= '\u06dc'; ++c) 1523 setCharAdvance(c, 0); 1524 for (char c = '\u06df'; c <= '\u06e4'; ++c) 1525 setCharAdvance(c, 0); 1526 for (char c = '\u06e7'; c <= '\u06e8'; ++c) 1527 setCharAdvance(c, 0); 1528 for (char c = '\u06ea'; c <= '\u06ed'; ++c) 1529 setCharAdvance(c, 0); 1530 } 1531 1532 /** 1533 * Adds a character range when subsetting. The range is an <CODE>int</CODE> array 1534 * where the first element is the start range inclusive and the second element is the 1535 * end range inclusive. Several ranges are allowed in the same array. 1536 * @param range the character range 1537 */ addSubsetRange(int[] range)1538 public void addSubsetRange(int[] range) { 1539 if (subsetRanges == null) 1540 subsetRanges = new ArrayList(); 1541 subsetRanges.add(range); 1542 } 1543 1544 /** 1545 * Returns the compression level used for the font streams. 1546 * @return the compression level (0 = best speed, 9 = best compression, -1 is default) 1547 * @since 2.1.3 1548 */ getCompressionLevel()1549 public int getCompressionLevel() { 1550 return compressionLevel; 1551 } 1552 1553 /** 1554 * Sets the compression level to be used for the font streams. 1555 * @param compressionLevel a value between 0 (best speed) and 9 (best compression) 1556 * @since 2.1.3 1557 */ setCompressionLevel(int compressionLevel)1558 public void setCompressionLevel(int compressionLevel) { 1559 if (compressionLevel < PdfStream.NO_COMPRESSION || compressionLevel > PdfStream.BEST_COMPRESSION) 1560 this.compressionLevel = PdfStream.DEFAULT_COMPRESSION; 1561 else 1562 this.compressionLevel = compressionLevel; 1563 } 1564 } 1565