org.pz.platypus.plugin.rtf.RtfFont.java Source code

Java tutorial

Introduction

Here is the source code for org.pz.platypus.plugin.rtf.RtfFont.java

Source

/***
 *  Platypus: Page Layout and Typesetting Software (free at platypus.pz.org)
 *
 *  Platypus is (c) Copyright 2006-10 Pacific Data Works LLC. All Rights Reserved.
 *  Licensed under Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html)
 */

package org.pz.platypus.plugin.rtf;

import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.pdf.BaseFont;
import org.pz.platypus.GDD;
import org.pz.platypus.Source;
import org.pz.platypus.TypefaceMap;
import org.pz.platypus.DefaultValues;

/**
 * Handles fonts for the RTF plugin
 *
 * @author alb
 */
public class RtfFont {
    /** the iText font */
    private Font iTfont = null;

    /** the font typeface in the form of a string used by iText */
    private String typeface = null;

    /** font size */
    private float size = 0f;

    /** color of font */
    //    private RgbColor color;

    /** is font bold? */
    private boolean bold;

    /** is fond italic? */
    private boolean italics;

    /** file and line number of last change */
    private Source source;

    private GDD gdd;
    private RtfData rtfData;

    RtfFont(RtfData rtfData) {
        this.rtfData = rtfData;
        gdd = rtfData.getGdd();
        setToDefault();
    }

    /**
     * Constructor for cloning an existing PdfFont, but specifying a different typeface.
     *
     * @param rdd PDF data
     * @param fontName the name of the new font/typeface
     * @param existingFont the font to clone the other attributes from
     */
    public RtfFont(RtfData rdd, String fontName, RtfFont existingFont) {
        gdd = rdd.getGdd();
        rtfData = rdd;
        typeface = fontName;
        size = existingFont.getSize();
        bold = existingFont.getBold();
        italics = existingFont.getItalics();
        source = existingFont.getSource();

        iTfont = createFont(this);
    }

    /**
     * Initializes all PdfFont fields to defaults, and sets line number to 0
     */
    public void setToDefault() {
        typeface = DefaultValues.FONT_TYPEFACE;
        //        color     = new RgbColor();
        size = DefaultValues.FONT_SIZE;
        bold = DefaultValues.FONT_BOLD;
        italics = DefaultValues.FONT_ITALIC;
        source = new Source();

        iTfont = createFont(this);
    }

    /**
     * Creates an iText Font object based on the class fields
     * @param f the PdfFont containing the parameters for the font
     * @return the iText Font object
     */
    Font createFont(final RtfFont f) {
        int style = 0;
        //       Color col  = new Color( color.getR(), color.getG(), color.getB() );
        Font font = null;

        String iTextFontName = createItextFontName(f);
        if (iTextFontName == null) { // if the font is not in the fontlist nor is it a Base14 font
            f.typeface = DefaultValues.FONT_TYPEFACE;
            iTextFontName = BaseFont.TIMES_ROMAN;
        }

        if (!isBase14Font(f.typeface)) {
            style = computeItextStyle();
            font = getIdentityHFont(iTextFontName, size, style);
        }

        if (font == null) {
            font = getCp1252Font(iTextFontName, size, style);
        }

        if (font == null || font.getBaseFont() == null) { //TODO: Make error msg use literals
            gdd.logWarning("iText could not find font for: " + iTextFontName + ". Using Times-Roman");
            font = FontFactory.getFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, BaseFont.EMBEDDED, size, style);
        }

        return (font);
    }

    /**
     * Opens a font using the IDENTITY-H encoding.
     *
     * @param fontName  the name assigned to the font in the font list
     * @param size the size in points
     * @param style bold, italic, etc.
     * @return the Font if opened; null if the file could not be opened or an error occurred.
     */
    Font getIdentityHFont(final String fontName, float size, int style) {
        // for the time being, if the font is an .otf font, don't open it with IDENTITY-H. Symbola is an
        // exception that seems to work.
        // need to explore the problem further in iText. It's recorded as PLATYPUS-32 in JIRA at Codehaus.
        // returning null forces the calling routine to open the font with CP1252 encoding, which is
        // fine for .otf fonts
        if (isFileOtf(fontName) && (!fontName.toLowerCase().equals("symbola"))) {
            return (null);
        }

        Font font;
        try {
            font = FontFactory.getFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, size, style);
        } catch (Exception ex) {
            font = null;
        }

        return (font);
    }

    /**
     * Looks up a font in the fontlist and determines whether it uses the .otf font format.
     * @param fontName name of font to verify
     * @return true if it's an .otf font, otherwise false.
     */
    private boolean isFileOtf(String fontName) {
        String[] fontFilenames = lookupFontFilenames(fontName);
        if (fontFilenames.length > 0) {
            if (fontFilenames[0].endsWith(".otf")) {
                return (true);
            }
        }
        return (false);
    }

    /**
     * Gets the font with CP1252 (aka WINANSI) encoding
     * @param fontName name of font to get
     * @param size  size in points
     * @param style bold, italic, etc.
     * @return the font, or null if an error occurred.
     */
    Font getCp1252Font(final String fontName, float size, int style) {
        Font font;
        try {

            font = FontFactory.getFont(fontName, BaseFont.CP1252, BaseFont.EMBEDDED, size, style);
        } catch (Exception ex) {
            font = null;
        }

        return (font);
    }

    /**
     * Determines whehter the current font is one of the Base14 Acrobat fonts, built into
     * every PDF reader. These fonts require special hanldling, and so this routine helps
     * identify them, based on their font face name.
     *
     * @param fontName name of the font face
     * @return true if it's a base14 font name, false otherwise.
     */
    boolean isBase14Font(final String fontName) {
        if (fontName.equals("COURIER") || fontName.equals("DINGBATS") || fontName.equals("HELVETICA")
                || fontName.equals("SYMBOL") || fontName.equals("TIMES_ROMAN")) {
            return (true);
        }

        return (false);
    }

    /**
     * Get the name by which iText refers to this font. This routine is mostly occupied
     * with the special handling of the base14 fonts.
     *
     * For all other fonts, this method makes sure the font is registered with iText and
     * returns its name as registered by iText (which is the family name for the font).
     *
     * @param f PdfFont whose iText name we're getting
     * @return a string containing the iText usable name for this font.
     */
    String createItextFontName(final RtfFont f) {
        String iTextFontName;
        String typefaceName = f.typeface;

        // handle the different versions of base14 fonts
        if (typefaceName.equals("COURIER")) {
            if (f.bold) {
                if (f.italics)
                    iTextFontName = BaseFont.COURIER_BOLDOBLIQUE;
                else
                    iTextFontName = BaseFont.COURIER_BOLD;
            } else if (f.italics)
                iTextFontName = BaseFont.COURIER_OBLIQUE;
            else
                iTextFontName = BaseFont.COURIER;
        } else if (typefaceName.equals("HELVETICA")) {
            if (f.bold) {
                if (f.italics)
                    iTextFontName = BaseFont.HELVETICA_BOLDOBLIQUE;
                else
                    iTextFontName = BaseFont.HELVETICA_BOLD;
            } else if (f.italics)
                iTextFontName = BaseFont.HELVETICA_OBLIQUE;
            else
                iTextFontName = BaseFont.HELVETICA;
        } else if (typefaceName.equals("TIMES_ROMAN")) {
            if (f.bold) {
                if (f.italics)
                    iTextFontName = BaseFont.TIMES_BOLDITALIC;
                else
                    iTextFontName = BaseFont.TIMES_BOLD;
            } else if (f.italics)
                iTextFontName = BaseFont.TIMES_ITALIC;
            else
                iTextFontName = BaseFont.TIMES_ROMAN;
        } else if (typefaceName.equals("SYMBOL")) {
            iTextFontName = BaseFont.SYMBOL;
        } else if (typefaceName.equals("DINGBATS")) {
            iTextFontName = BaseFont.ZAPFDINGBATS;
        } else
        // It's not a base14 font. So make sure we've loaded the font files for Platypus
        // then look up this font among them. If it's still not there, then return
        // a TIMES_ROMAN and note the error.
        {
            if (!FontFactory.isRegistered(typefaceName)) {
                if (!findAndRegisterFont(typefaceName)) {
                    return (null);
                }
            }

            if (FontFactory.isRegistered(typefaceName)) {
                iTextFontName = typefaceName;
            } else {
                // in theory, cannot get here.
                gdd.logWarning(gdd.getLit("COULD_NOT_FIND") + " " + typefaceName + " "
                        + gdd.getLit("IN_FONT_REGISTER") + ". " + gdd.getLit("USING_TIMES_ROMAN") + ".");
                iTextFontName = null;
            }
        }
        return (iTextFontName);
    }

    /**
     * Get the filenames from the typefaceMap and register them in iText's FontFactory.
     *
     * @param typefaceName name of the typeface
     * @return true if the font is now registered, false if an error occurred. (Font was not in fontlist.)
     */
    boolean findAndRegisterFont(String typefaceName) {
        String[] fontFiles = lookupFontFilenames(typefaceName);
        if (fontFiles.length == 0) {
            gdd.logWarning(gdd.getLit("COULD_NOT_FIND") + " " + typefaceName + " " + gdd.getLit("IN_FONT_LIST")
                    + ". " + gdd.getLit("USING_TIMES_ROMAN") + ".");
            return (false);
        } else {
            for (String fontFile : fontFiles) {
                FontFactory.register(fontFile, typefaceName);
            }
            gdd.log("Registered fonts for " + typefaceName + " in iText");
            return (true);
        }
    }

    /**
     * Get the names of the actual font files that are the implementation of this typeface
     * @param typefaceName the typefaces
     * @return an array of strings containing the file names.
     */
    String[] lookupFontFilenames(String typefaceName) {
        assert rtfData != null;
        assert typefaceName != null;

        TypefaceMap typefaceMap = rtfData.getTypefaceMap();
        if (typefaceMap == null) {
            rtfData.loadTypefaceMap();
        }

        return (typefaceMap.getFamilyFilenames(typefaceName));
    }

    /**
     * iText font style captures bold, italic, strikethru, underline. Since we handle
     * strikethrough and underline ourselves, we use it to communicate italic and bold
     * only. This computation done here.
     *
     * @return the iText Style
     */
    int computeItextStyle() {
        int style = 0;

        if (italics && bold) {
            style |= Font.BOLDITALIC;
        } else if (italics) {
            style |= Font.ITALIC;
        } else if (bold) {
            style |= Font.BOLD;
        }

        return (style);
    }

    //=== getters and setters ===//

    public boolean getBold() {
        return (bold);
    }

    public boolean getItalics() {
        return (italics);
    }

    /**
     * Get the iText font
     *
     * @return  the iText font
     */
    public Font getItextFont() {
        return (iTfont);
    }

    public String getFace() {
        return (typeface);
    }

    public float getSize() {
        return (size);
    }

    public Source getSource() {
        return (source);
    }

    /**
     * set bold on/off and re-create the iText font to record the change.
     *
     * @param onOff the new value for the italics setting
     * @param newSource the file and line # of the token that changed italics
     */
    public void setBold(final boolean onOff, final Source newSource) {
        if (bold != onOff) {
            bold = onOff;
            source = newSource;
            iTfont = createFont(this);
        }
    }

    /**
     * set italics on/off and re-create the iText font to record the change.
     *
     * @param onOff the new value for the italics setting
     * @param newSource the file and line # of the token that changed italics
     */
    public void setItalics(final boolean onOff, final Source newSource) {
        if (italics != onOff) {
            italics = onOff;
            source = newSource;
            iTfont = createFont(this);
        }
    }

    public void setSize(final float newSize, final Source newSource) {
        if (size != newSize) {
            size = newSize;
            source = newSource;
            iTfont = createFont(this);
        }
    }

    public void setFace(final String newFace, final Source newSource) {
        if (!typeface.equals(newFace)) {
            typeface = newFace;
            source = newSource;
            iTfont = createFont(this);
        }
    }
}