1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /* $Id: PDFFont.java 1610947 2014-07-16 09:10:53Z ssteiner $ */
19 
20 package org.apache.fop.pdf;
21 
22 import java.io.IOException;
23 import java.io.OutputStream;
24 
25 import org.apache.fop.fonts.FontType;
26 
27 /**
28  * Class representing a /Font object.
29  * <p>
30  * A more complete object expressing the base font name and encoding of a
31  * font along with an internal name for the font used within
32  * streams of content.
33  * <p>
34  * Fonts are specified on page 198 and onwards of the PDF 1.3 spec.
35  */
36 public class PDFFont extends PDFDictionary {
37 
38     /** Internal F-number for each font (it is not written to the font dict) */
39     private String fontname;
40 
41     /**
42      * create the /Font object
43      *
44      * @param fontname the internal name for the font
45      * @param subtype the font's subtype
46      * @param basefont the base font name
47      * @param encoding the character encoding schema used by the font
48      */
PDFFont(String fontname, FontType subtype, String basefont, Object encoding)49     public PDFFont(String fontname, FontType subtype,
50                    String basefont,
51                    Object encoding) {
52 
53         /* generic creation of PDF object */
54         super();
55 
56         this.fontname = fontname;
57         put("Type", new PDFName("Font"));
58         put("Subtype", getPDFNameForFontType(subtype));
59         //put("Name", new PDFName(fontname));
60         put("BaseFont", new PDFName(basefont));
61         if (encoding instanceof PDFEncoding) {
62             setEncoding((PDFEncoding)encoding);
63         } else if (encoding instanceof String) {
64             setEncoding((String)encoding);
65         }
66     }
67 
68     /**
69      * Sets the Encoding value of the font.
70      * @param encoding the encoding
71      */
setEncoding(String encoding)72     public void setEncoding(String encoding) {
73         if (encoding != null && !PDFEncoding.hasStandardEncoding(encoding)) {
74             put("Encoding", new PDFName(encoding));
75         }
76     }
77 
78     /**
79      * Sets the Encoding value of the font.
80      * @param encoding the encoding
81      */
setEncoding(PDFEncoding encoding)82     public void setEncoding(PDFEncoding encoding) {
83         if (encoding != null) {
84             put("Encoding", encoding);
85         }
86     }
87 
88     /**
89      * Sets a ToUnicode CMap.
90      * @param cmap the ToUnicode character map
91      */
setToUnicode(PDFCMap cmap)92     public void setToUnicode(PDFCMap cmap) {
93         put("ToUnicode", cmap);
94     }
95 
96     /**
97      * factory method with the basic parameters
98      *
99      * @param fontname the internal name for the font
100      * @param subtype the font's subtype
101      * @param basefont the base font name
102      * @param encoding the character encoding schema used by the font
103      * @return the generated PDFFont object
104      */
createFont(String fontname, FontType subtype, String basefont, Object encoding)105     public static PDFFont createFont(String fontname,
106                                      FontType subtype, String basefont,
107                                      Object encoding) {
108         if (subtype == FontType.TYPE0 || subtype == FontType.CIDTYPE0) {
109             return new PDFFontType0(fontname, basefont,
110                                     encoding);
111         } else if ((subtype == FontType.TYPE1)
112                 || (subtype == FontType.TYPE1C)
113                 || (subtype == FontType.MMTYPE1)) {
114             return new PDFFontType1(fontname, basefont,
115                                     encoding);
116         } else if (subtype == FontType.TYPE3) {
117             //return new PDFFontType3(number, fontname, basefont, encoding);
118             return null; //NYI
119         } else if (subtype == FontType.TRUETYPE) {
120             return new PDFFontTrueType(fontname, basefont,
121                                        encoding);
122         } else {
123             return null;    // should not happen
124         }
125     }
126 
127     /**
128      * Get the internal name used for this font.
129      * @return the internal name
130      */
getName()131     public String getName() {
132         return this.fontname;
133     }
134 
135     /**
136      * Returns the name of the BaseFont.
137      * @return the BaseFont
138      */
getBaseFont()139     public PDFName getBaseFont() {
140         return (PDFName)get("BaseFont");
141     }
142 
143     /**
144      * Returns the PDF name for a certain font type.
145      * @param fontType font type
146      * @return String corresponding PDF name
147      */
getPDFNameForFontType(FontType fontType)148     protected PDFName getPDFNameForFontType(FontType fontType) {
149         if (fontType == FontType.TYPE0) {
150             return new PDFName(fontType.getName());
151         } else if (fontType == FontType.TYPE1) {
152             return new PDFName(fontType.getName());
153         } else if (fontType == FontType.MMTYPE1) {
154             return new PDFName(fontType.getName());
155         } else if (fontType == FontType.TYPE3) {
156             return new PDFName(fontType.getName());
157         } else if (fontType == FontType.TRUETYPE) {
158             return new PDFName(fontType.getName());
159         } else {
160             throw new IllegalArgumentException("Unsupported font type: " + fontType.getName());
161         }
162     }
163 
164     /**
165      * Validates the PDF object prior to serialization.
166      */
validate()167     protected void validate() {
168         if (getDocumentSafely().getProfile().isFontEmbeddingRequired()) {
169             if (this.getClass() == PDFFont.class) {
170                 throw new PDFConformanceException("For " + getDocumentSafely().getProfile()
171                     + ", all fonts, even the base 14"
172                     + " fonts, have to be embedded! Offending font: " + getBaseFont());
173             }
174         }
175     }
176 
177     /** {@inheritDoc} */
output(OutputStream stream)178     public int output(OutputStream stream) throws IOException {
179         validate();
180         return super.output(stream);
181     }
182 
183 }
184