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

Save This Page
Home » iText-src-2.1.3 » com.lowagie » text » pdf » [javadoc | source]