All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.pdfview.font.PDFFont Maven / Gradle / Ivy

/*
 * $Id: PDFFont.java,v 1.6 2009/03/15 20:47:38 tomoke Exp $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package com.sun.pdfview.font;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.sun.pdfview.PDFObject;
import com.sun.pdfview.PDFParseException;

/**
 * a Font definition for PDF files
 * @author Mike Wessler
 */
public abstract class PDFFont {

    /** the font SubType of this font */
    private String subtype;
    /** the postscript name of this font */
    private String baseFont;
    /** the font encoding (maps character ids to glyphs) */
    private PDFFontEncoding encoding;
    /** the font descriptor */
    private PDFFontDescriptor descriptor;
    /** the CMap that maps this font to unicode values */
    private PDFCMap unicodeMap;
    /** a cache of glyphs indexed by character */
    private Map charCache;

    /**
     * get the PDFFont corresponding to the font described in a PDFObject.
     * The object is actually a dictionary containing the following keys:
* Type = "Font"
* Subtype = (Type1 | TrueType | Type3 | Type0 | MMType1 | CIDFontType0 | * CIDFontType2)
* FirstChar = #
* LastChar = #
* Widths = array of #
* Encoding = (some name representing a dictionary in the resources | an * inline dictionary) *

* For Type1 and TrueType fonts, the dictionary also contains:
* BaseFont = (some name, or XXXXXX+Name as a subset of font Name) *

* For Type3 font, the dictionary contains:
* FontBBox = (rectangle)
* FontMatrix = (array, typically [0.001, 0, 0, 0.001, 0, 0])
* CharProcs = (dictionary) * Resources = (dictionary) */ public synchronized static PDFFont getFont(PDFObject obj, HashMap resources) throws IOException { // the obj is actually a dictionary containing: // Type (=Font) // Subtype (Type1, TrueType, Type3, Type0, MMType1, CIDFontType0,2) // FirstChar (int) // LastChar (int) // Widths (array) // Encoding (name or dict) : assumes StandardEncoding // and........ // Type1 and TrueType fonts: // BaseFont (name) // may be XXXXXX+Fontname as a subset. // FontDescriptor (dict) // Type3 fonts: // FontBBox (rectangle) // FontMatrix (array) // e.g. [0.001 0 0 0.001 0 0] // CharProcs (dict) // Resources (dict) // // Font descriptor (Type1 and TrueType fonts): // FontName (name) // Flags (1=monospace, 2=serif, 4=script, 7=italic, 19=bold) // FontBBox (rectangle) // ItalicAngle (float) // Ascent (float) // Descent (float) // CapHeight (float) // StemV (float) // FontFile (stream for Type1 fonts) // FontFile2 (stream for TrueType fonts) // FontFile3 (stream for CFF/Type1C fonts) // // Font data can be Type1, TrueType(native), or Type1C PDFFont font = (PDFFont) obj.getCache(); if (font != null) { return font; } String baseFont = null; PDFFontEncoding encoding = null; PDFFontDescriptor descriptor = null; String subType = obj.getDictRef("Subtype").getStringValue(); if (subType == null) { subType = obj.getDictRef("S").getStringValue(); } PDFObject baseFontObj = obj.getDictRef("BaseFont"); PDFObject encodingObj = obj.getDictRef("Encoding"); PDFObject descObj = obj.getDictRef("FontDescriptor"); if (baseFontObj != null) { baseFont = baseFontObj.getStringValue(); } else { baseFontObj = obj.getDictRef("Name"); if (baseFontObj != null) { baseFont = baseFontObj.getStringValue(); } } if (encodingObj != null) { encoding = new PDFFontEncoding(subType, encodingObj); } if (descObj != null) { descriptor = new PDFFontDescriptor(descObj); } else { descriptor = new PDFFontDescriptor(baseFont); } if (subType.equals("Type0")) { font = new Type0Font(baseFont, obj, descriptor); } else if (subType.equals("Type1")) { // load a type1 font if (descriptor == null) { // it's one of the built-in fonts font = new BuiltinFont(baseFont, obj); } else if (descriptor.getFontFile() != null) { // it's a Type1 font, included. font = new Type1Font(baseFont, obj, descriptor); } else if (descriptor.getFontFile3() != null) { // it's a CFF (Type1C) font font = new Type1CFont(baseFont, obj, descriptor); } else { // no font info. Fake it based on the FontDescriptor // System.out.println("Fakeout native font"); font = new BuiltinFont(baseFont, obj, descriptor); } } else if (subType.equals("TrueType")) { if (descriptor.getFontFile2() != null) { // load a TrueType font font = new TTFFont(baseFont, obj, descriptor); } else { // fake it with a built-in font font = new BuiltinFont(baseFont, obj, descriptor); } } else if (subType.equals("Type3")) { // load a type 3 font font = new Type3Font(baseFont, obj, resources, descriptor); } else if (subType.equals("CIDFontType2")) { font = new CIDFontType2(baseFont, obj, descriptor); } else if (subType.equals("CIDFontType0")) { font = new CIDFontType2(baseFont, obj, descriptor); // font = new CIDFontType0(baseFont, obj, descriptor); // throw new IOException ("CIDFontType0 is unimplemented. " + obj); } else { throw new PDFParseException("Don't know how to handle a '" + subType + "' font"); } font.setSubtype(subType); font.setEncoding(encoding); obj.setCache(font); return font; } /** * Get the subtype of this font. * @return the subtype, one of: Type0, Type1, TrueType or Type3 */ public String getSubtype() { return subtype; } /** * Set the font subtype */ public void setSubtype(String subtype) { this.subtype = subtype; } /** * Get the postscript name of this font * @return the postscript name of this font */ public String getBaseFont() { return baseFont; } /** * Set the postscript name of this font * @param baseFont the postscript name of the font */ public void setBaseFont(String baseFont) { this.baseFont = baseFont; } /** * Get the encoding for this font * @return the encoding which maps from this font to actual characters */ public PDFFontEncoding getEncoding() { return encoding; } /** * Set the encoding for this font */ public void setEncoding(PDFFontEncoding encoding) { this.encoding = encoding; } /** * Get the descriptor for this font * @return the font descriptor */ public PDFFontDescriptor getDescriptor() { return descriptor; } /** * Set the descriptor font descriptor */ public void setDescriptor(PDFFontDescriptor descriptor) { this.descriptor = descriptor; } /** * Get the CMap which maps the characters in this font to unicode names */ public PDFCMap getUnicodeMap() { return unicodeMap; } /** * Set the CMap which maps the characters in this font to unicode names */ public void setUnicodeMap(PDFCMap unicodeMap) { this.unicodeMap = unicodeMap; } /** * Get the glyphs associated with a given String in this font * * @param text the text to translate into glyphs */ public List getGlyphs(String text) { List outList = null; // if we have an encoding, use it to get the commands if (encoding != null) { outList = encoding.getGlyphs(this, text); } else { // use the default mapping char[] arry = text.toCharArray(); outList = new ArrayList(arry.length); for (int i = 0; i < arry.length; i++) { // only look at 2 bytes when there is no encoding char src = (char) (arry[i] & 0xff); outList.add(getCachedGlyph(src, null)); } } return outList; } /** * Get a glyph for a given character code. The glyph is returned * from the cache if available, or added to the cache if not * * @param src the character code of this glyph * @param name the name of the glyph, or null if the name is unknown * @return a glyph for this character */ public PDFGlyph getCachedGlyph(char src, String name) { if (charCache == null) { charCache = new HashMap(); } // try the cache PDFGlyph glyph = (PDFGlyph) charCache.get(new Character(src)); // if it's not there, add it to the cache if (glyph == null) { glyph = getGlyph(src, name); charCache.put(new Character(src), glyph); } return glyph; } /** * Create a PDFFont given the base font name and the font descriptor * @param baseFont the postscript name of this font * @param descriptor the descriptor for the font */ protected PDFFont(String baseFont, PDFFontDescriptor descriptor) { setBaseFont(baseFont); setDescriptor(descriptor); } /** * Get the glyph for a given character code and name * * The preferred method of getting the glyph should be by name. If the * name is null or not valid, then the character code should be used. * If the both the code and the name are invalid, the undefined glyph * should be returned. * * Note this method must *always* return a glyph. * * @param src the character code of this glyph * @param name the name of this glyph or null if unknown * @return a glyph for this character */ protected abstract PDFGlyph getGlyph(char src, String name); /** * Turn this font into a pretty String */ @Override public String toString() { return getBaseFont(); } /** * Compare two fonts base on the baseFont */ @Override public boolean equals(Object o) { if (!(o instanceof PDFFont)) { return false; } return ((PDFFont) o).getBaseFont().equals(getBaseFont()); } /** * Hash a font based on its base font */ @Override public int hashCode() { return getBaseFont().hashCode(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy