001/* 002 * $Id: DefaultFontMapper.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; 045 046import java.awt.Font; 047import java.io.File; 048import java.util.HashMap; 049 050import com.itextpdf.text.ExceptionConverter; 051/** Default class to map awt fonts to BaseFont. 052 * @author Paulo Soares 053 */ 054 055public class DefaultFontMapper implements FontMapper { 056 057 /** A representation of BaseFont parameters. 058 */ 059 public static class BaseFontParameters { 060 /** The font name. 061 */ 062 public String fontName; 063 /** The encoding for that font. 064 */ 065 public String encoding; 066 /** The embedding for that font. 067 */ 068 public boolean embedded; 069 /** Whether the font is cached of not. 070 */ 071 public boolean cached; 072 /** The font bytes for ttf and afm. 073 */ 074 public byte ttfAfm[]; 075 /** The font bytes for pfb. 076 */ 077 public byte pfb[]; 078 079 /** Constructs default BaseFont parameters. 080 * @param fontName the font name or location 081 */ 082 public BaseFontParameters(String fontName) { 083 this.fontName = fontName; 084 encoding = BaseFont.CP1252; 085 embedded = BaseFont.EMBEDDED; 086 cached = BaseFont.CACHED; 087 } 088 } 089 090 /** Maps aliases to names. 091 */ 092 private HashMap<String, String> aliases = new HashMap<String, String>(); 093 /** Maps names to BaseFont parameters. 094 */ 095 private HashMap<String, BaseFontParameters> mapper = new HashMap<String, BaseFontParameters>(); 096 /** 097 * Returns a BaseFont which can be used to represent the given AWT Font 098 * 099 * @param font the font to be converted 100 * @return a BaseFont which has similar properties to the provided Font 101 */ 102 103 public BaseFont awtToPdf(Font font) { 104 try { 105 BaseFontParameters p = getBaseFontParameters(font.getFontName()); 106 if (p != null) 107 return BaseFont.createFont(p.fontName, p.encoding, p.embedded, p.cached, p.ttfAfm, p.pfb); 108 String fontKey = null; 109 String logicalName = font.getName(); 110 111 if (logicalName.equalsIgnoreCase("DialogInput") || logicalName.equalsIgnoreCase("Monospaced") || logicalName.equalsIgnoreCase("Courier")) { 112 113 if (font.isItalic()) { 114 if (font.isBold()) { 115 fontKey = BaseFont.COURIER_BOLDOBLIQUE; 116 117 } else { 118 fontKey = BaseFont.COURIER_OBLIQUE; 119 } 120 121 } else { 122 if (font.isBold()) { 123 fontKey = BaseFont.COURIER_BOLD; 124 125 } else { 126 fontKey = BaseFont.COURIER; 127 } 128 } 129 130 } else if (logicalName.equalsIgnoreCase("Serif") || logicalName.equalsIgnoreCase("TimesRoman")) { 131 132 if (font.isItalic()) { 133 if (font.isBold()) { 134 fontKey = BaseFont.TIMES_BOLDITALIC; 135 136 } else { 137 fontKey = BaseFont.TIMES_ITALIC; 138 } 139 140 } else { 141 if (font.isBold()) { 142 fontKey = BaseFont.TIMES_BOLD; 143 144 } else { 145 fontKey = BaseFont.TIMES_ROMAN; 146 } 147 } 148 149 } else { // default, this catches Dialog and SansSerif 150 151 if (font.isItalic()) { 152 if (font.isBold()) { 153 fontKey = BaseFont.HELVETICA_BOLDOBLIQUE; 154 155 } else { 156 fontKey = BaseFont.HELVETICA_OBLIQUE; 157 } 158 159 } else { 160 if (font.isBold()) { 161 fontKey = BaseFont.HELVETICA_BOLD; 162 } else { 163 fontKey = BaseFont.HELVETICA; 164 } 165 } 166 } 167 return BaseFont.createFont(fontKey, BaseFont.CP1252, false); 168 } 169 catch (Exception e) { 170 throw new ExceptionConverter(e); 171 } 172 } 173 174 /** 175 * Returns an AWT Font which can be used to represent the given BaseFont 176 * 177 * @param font the font to be converted 178 * @param size the desired point size of the resulting font 179 * @return a Font which has similar properties to the provided BaseFont 180 */ 181 182 public Font pdfToAwt(BaseFont font, int size) { 183 String names[][] = font.getFullFontName(); 184 if (names.length == 1) 185 return new Font(names[0][3], 0, size); 186 String name10 = null; 187 String name3x = null; 188 for (int k = 0; k < names.length; ++k) { 189 String name[] = names[k]; 190 if (name[0].equals("1") && name[1].equals("0")) 191 name10 = name[3]; 192 else if (name[2].equals("1033")) { 193 name3x = name[3]; 194 break; 195 } 196 } 197 String finalName = name3x; 198 if (finalName == null) 199 finalName = name10; 200 if (finalName == null) 201 finalName = names[0][3]; 202 return new Font(finalName, 0, size); 203 } 204 205 /** Maps a name to a BaseFont parameter. 206 * @param awtName the name 207 * @param parameters the BaseFont parameter 208 */ 209 public void putName(String awtName, BaseFontParameters parameters) { 210 mapper.put(awtName, parameters); 211 } 212 213 /** Maps an alias to a name. 214 * @param alias the alias 215 * @param awtName the name 216 */ 217 public void putAlias(String alias, String awtName) { 218 aliases.put(alias, awtName); 219 } 220 221 /** Looks for a BaseFont parameter associated with a name. 222 * @param name the name 223 * @return the BaseFont parameter or <CODE>null</CODE> if not found. 224 */ 225 public BaseFontParameters getBaseFontParameters(String name) { 226 String alias = aliases.get(name); 227 if (alias == null) 228 return mapper.get(name); 229 BaseFontParameters p = mapper.get(alias); 230 if (p == null) 231 return mapper.get(name); 232 else 233 return p; 234 } 235 236 /** 237 * Inserts the names in this map. 238 * @param allNames the returned value of calling {@link BaseFont#getAllFontNames(String, String, byte[])} 239 * @param path the full path to the font 240 */ 241 public void insertNames(Object allNames[], String path) { 242 String names[][] = (String[][])allNames[2]; 243 String main = null; 244 for (int k = 0; k < names.length; ++k) { 245 String name[] = names[k]; 246 if (name[2].equals("1033")) { 247 main = name[3]; 248 break; 249 } 250 } 251 if (main == null) 252 main = names[0][3]; 253 BaseFontParameters p = new BaseFontParameters(path); 254 mapper.put(main, p); 255 for (int k = 0; k < names.length; ++k) { 256 aliases.put(names[k][3], main); 257 } 258 aliases.put((String)allNames[0], main); 259 } 260 261 /** Inserts one font file into the map. The encoding 262 * will be <CODE>BaseFont.CP1252</CODE> but can be 263 * changed later. 264 * @param file the file to insert 265 * @return the number of files inserted 266 * @since 5.0.5 267 */ 268 public int insertFile(File file) { 269 String name = file.getPath().toLowerCase(); 270 try { 271 if (name.endsWith(".ttf") || name.endsWith(".otf") || name.endsWith(".afm")) { 272 Object allNames[] = BaseFont.getAllFontNames(file.getPath(), BaseFont.CP1252, null); 273 insertNames(allNames, file.getPath()); 274 return 1; 275 } else if (name.endsWith(".ttc")) { 276 String ttcs[] = BaseFont.enumerateTTCNames(file.getPath()); 277 for (int j = 0; j < ttcs.length; ++j) { 278 String nt = file.getPath() + "," + j; 279 Object allNames[] = BaseFont.getAllFontNames(nt, BaseFont.CP1252, null); 280 insertNames(allNames, nt); 281 } 282 return 1; 283 } 284 } catch (Exception e) { 285 } 286 return 0; 287 } 288 289 /** Inserts all the fonts recognized by iText in the 290 * <CODE>directory</CODE> into the map. The encoding 291 * will be <CODE>BaseFont.CP1252</CODE> but can be 292 * changed later. 293 * @param dir the directory to scan 294 * @return the number of files processed 295 */ 296 public int insertDirectory(String dir) { 297 File file = new File(dir); 298 if (!file.exists() || !file.isDirectory()) 299 return 0; 300 File files[] = file.listFiles(); 301 if (files == null) 302 return 0; 303 int count = 0; 304 for (int k = 0; k < files.length; ++k) { 305 count += insertFile(files[k]); 306 } 307 return count; 308 } 309 310 public HashMap<String, BaseFontParameters> getMapper() { 311 return mapper; 312 } 313 314 public HashMap<String, String> getAliases() { 315 return aliases; 316 } 317}