001/*
002 * $Id: MetaFont.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.codec.wmf;
045import com.itextpdf.text.Document;
046import java.io.IOException;
047import java.io.UnsupportedEncodingException;
048
049import com.itextpdf.text.ExceptionConverter;
050import com.itextpdf.text.Font;
051import com.itextpdf.text.FontFactory;
052import com.itextpdf.text.pdf.BaseFont;
053
054public class MetaFont extends MetaObject {
055    static final String fontNames[] = {
056        "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique",
057        "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique",
058        "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
059        "Symbol", "ZapfDingbats"};
060
061    static final int MARKER_BOLD = 1;
062    static final int MARKER_ITALIC = 2;
063    static final int MARKER_COURIER = 0;
064    static final int MARKER_HELVETICA = 4;
065    static final int MARKER_TIMES = 8;
066    static final int MARKER_SYMBOL = 12;
067
068    static final int DEFAULT_PITCH = 0;
069    static final int FIXED_PITCH = 1;
070    static final int VARIABLE_PITCH = 2;
071    static final int FF_DONTCARE = 0;
072    static final int FF_ROMAN = 1;
073    static final int FF_SWISS = 2;
074    static final int FF_MODERN = 3;
075    static final int FF_SCRIPT = 4;
076    static final int FF_DECORATIVE = 5;
077    static final int BOLDTHRESHOLD = 600;    
078    static final int nameSize = 32;
079    static final int ETO_OPAQUE = 2;
080    static final int ETO_CLIPPED = 4;
081
082    int height;
083    float angle;
084    int bold;
085    int italic;
086    boolean underline;
087    boolean strikeout;
088    int charset;
089    int pitchAndFamily;
090    String faceName = "arial";
091    BaseFont font = null;
092
093    public MetaFont() {
094        type = META_FONT;
095    }
096
097    public void init(InputMeta in) throws IOException {
098        height = Math.abs(in.readShort());
099        in.skip(2);
100        angle = (float)(in.readShort() / 1800.0 * Math.PI);
101        in.skip(2);
102        bold = (in.readShort() >= BOLDTHRESHOLD ? MARKER_BOLD : 0);
103        italic = (in.readByte() != 0 ? MARKER_ITALIC : 0);
104        underline = (in.readByte() != 0);
105        strikeout = (in.readByte() != 0);
106        charset = in.readByte();
107        in.skip(3);
108        pitchAndFamily = in.readByte();
109        byte name[] = new byte[nameSize];
110        int k;
111        for (k = 0; k < nameSize; ++k) {
112            int c = in.readByte();
113            if (c == 0) {
114                break;
115            }
116            name[k] = (byte)c;
117        }
118        try {
119            faceName = new String(name, 0, k, "Cp1252");
120        }
121        catch (UnsupportedEncodingException e) {
122            faceName = new String(name, 0, k);
123        }
124        faceName = faceName.toLowerCase();
125    }
126    
127    public BaseFont getFont() {
128        if (font != null)
129            return font;
130        Font ff2 = FontFactory.getFont(faceName, BaseFont.CP1252, true, 10, ((italic != 0) ? Font.ITALIC : 0) | ((bold != 0) ? Font.BOLD : 0));
131        font = ff2.getBaseFont();
132        if (font != null)
133            return font;
134        String fontName;
135        if (faceName.indexOf("courier") != -1 || faceName.indexOf("terminal") != -1
136            || faceName.indexOf("fixedsys") != -1) {
137            fontName = fontNames[MARKER_COURIER + italic + bold];
138        }
139        else if (faceName.indexOf("ms sans serif") != -1 || faceName.indexOf("arial") != -1
140            || faceName.indexOf("system") != -1) {
141            fontName = fontNames[MARKER_HELVETICA + italic + bold];
142        }
143        else if (faceName.indexOf("arial black") != -1) {
144            fontName = fontNames[MARKER_HELVETICA + italic + MARKER_BOLD];
145        }
146        else if (faceName.indexOf("times") != -1 || faceName.indexOf("ms serif") != -1
147            || faceName.indexOf("roman") != -1) {
148            fontName = fontNames[MARKER_TIMES + italic + bold];
149        }
150        else if (faceName.indexOf("symbol") != -1) {
151            fontName = fontNames[MARKER_SYMBOL];
152        }
153        else {
154            int pitch = pitchAndFamily & 3;
155            int family = (pitchAndFamily >> 4) & 7;
156            switch (family) {
157                case FF_MODERN:
158                    fontName = fontNames[MARKER_COURIER + italic + bold];
159                    break;
160                case FF_ROMAN:
161                    fontName = fontNames[MARKER_TIMES + italic + bold];
162                    break;
163                case FF_SWISS:
164                case FF_SCRIPT:
165                case FF_DECORATIVE:
166                    fontName = fontNames[MARKER_HELVETICA + italic + bold];
167                    break;
168                default:
169                {
170                    switch (pitch) {
171                        case FIXED_PITCH:
172                            fontName = fontNames[MARKER_COURIER + italic + bold];
173                            break;
174                        default:
175                            fontName = fontNames[MARKER_HELVETICA + italic + bold];
176                            break;
177                    }
178                }
179            }
180        }
181        try {
182            font = BaseFont.createFont(fontName, "Cp1252", false);
183        }
184        catch (Exception e) {
185            throw new ExceptionConverter(e);
186        }
187        
188        return font;
189    }
190    
191    public float getAngle() {
192        return angle;
193    }
194    
195    public boolean isUnderline() {
196        return underline;
197    }
198    
199    public boolean isStrikeout() {
200        return strikeout;
201    }
202    
203    public float getFontSize(MetaState state) {
204        return Math.abs(state.transformY(height) - state.transformY(0)) * Document.wmfFontCorrection;
205    }
206}