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