001: /**
002: * Copyright (c) 2004-2005, www.pdfbox.org
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * 1. Redistributions of source code must retain the above copyright notice,
009: * this list of conditions and the following disclaimer.
010: * 2. Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: * 3. Neither the name of pdfbox; nor the names of its
014: * contributors may be used to endorse or promote products derived from this
015: * software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
021: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: *
028: * http://www.pdfbox.org
029: *
030: */package org.pdfbox.pdmodel.font;
031:
032: import java.io.BufferedInputStream;
033: import java.io.FileInputStream;
034: import java.io.IOException;
035: import java.io.InputStream;
036: import java.util.ArrayList;
037: import java.util.Iterator;
038: import java.util.List;
039:
040: import org.fontbox.afm.AFMParser;
041: import org.fontbox.afm.CharMetric;
042: import org.fontbox.afm.FontMetric;
043:
044: import org.fontbox.pfb.PfbParser;
045:
046: import org.pdfbox.encoding.AFMEncoding;
047: import org.pdfbox.pdmodel.PDDocument;
048: import org.pdfbox.pdmodel.common.PDRectangle;
049: import org.pdfbox.pdmodel.common.PDStream;
050:
051: /**
052: * This is implementation of the Type1 Font
053: * with a afm and a pfb file.
054: *
055: * @author <a href="mailto:m.g.n@gmx.de">Michael Niedermair</a>
056: * @version $Revision: 1.5 $
057: */
058: public class PDType1AfmPfbFont extends PDType1Font {
059: /**
060: * the buffersize.
061: */
062: private static final int BUFFERSIZE = 0xffff;
063:
064: /**
065: * The font descriptor.
066: */
067: private PDFontDescriptorDictionary fd;
068:
069: /**
070: * The font metric.
071: */
072: private FontMetric metric;
073:
074: /**
075: * Create a new object.
076: * @param doc The PDF document that will hold the embedded font.
077: * @param afmname The font filename.
078: * @throws IOException If there is an error loading the data.
079: */
080: public PDType1AfmPfbFont(final PDDocument doc, final String afmname)
081: throws IOException {
082:
083: super ();
084:
085: InputStream afmin = new BufferedInputStream(
086: new FileInputStream(afmname), BUFFERSIZE);
087: String pfbname = afmname.replaceAll(".AFM", "").replaceAll(
088: ".afm", "")
089: + ".pfb";
090: InputStream pfbin = new BufferedInputStream(
091: new FileInputStream(pfbname), BUFFERSIZE);
092:
093: load(doc, afmin, pfbin);
094: }
095:
096: /**
097: * Create a new object.
098: * @param doc The PDF document that will hold the embedded font.
099: * @param afm The afm input.
100: * @param pfb The pfb input.
101: * @throws IOException If there is an error loading the data.
102: */
103: public PDType1AfmPfbFont(final PDDocument doc,
104: final InputStream afm, final InputStream pfb)
105: throws IOException {
106: super ();
107:
108: load(doc, afm, pfb);
109: }
110:
111: /**
112: * This will load a afm and pfb to be embedding into a document.
113: *
114: * @param doc The PDF document that will hold the embedded font.
115: * @param afm The afm input.
116: * @param pfb The pfb input.
117: * @throws IOException If there is an error loading the data.
118: */
119: private void load(final PDDocument doc, final InputStream afm,
120: final InputStream pfb) throws IOException {
121:
122: fd = new PDFontDescriptorDictionary();
123: setFontDescriptor(fd);
124:
125: // read the pfb
126: PfbParser pfbparser = new PfbParser(pfb);
127: pfb.close();
128:
129: PDStream fontStream = new PDStream(doc, pfbparser
130: .getInputStream(), false);
131: fontStream.getStream().setInt("Length", pfbparser.size());
132: for (int i = 0; i < pfbparser.getLengths().length; i++) {
133: fontStream.getStream().setInt("Length" + (i + 1),
134: pfbparser.getLengths()[i]);
135: }
136: fontStream.addCompression();
137: fd.setFontFile(fontStream);
138:
139: // read the afm
140: AFMParser parser = new AFMParser(afm);
141: parser.parse();
142: metric = parser.getResult();
143: setEncoding(new AFMEncoding(metric));
144:
145: // set the values
146: setBaseFont(metric.getFontName());
147: fd.setFontName(metric.getFontName());
148: fd.setFontFamily(metric.getFamilyName());
149: fd.setNonSymbolic(true);
150: fd.setFontBoundingBox(new PDRectangle(metric.getFontBBox()));
151: fd.setItalicAngle(metric.getItalicAngle());
152: fd.setAscent(metric.getAscender());
153: fd.setDescent(metric.getDescender());
154: fd.setCapHeight(metric.getCapHeight());
155: fd.setXHeight(metric.getXHeight());
156: fd.setAverageWidth(metric.getAverageCharacterWidth());
157: fd.setCharacterSet(metric.getCharacterSet());
158:
159: // get firstchar, lastchar
160: int firstchar = 255;
161: int lastchar = 0;
162:
163: // widths
164: List listmetric = metric.getCharMetrics();
165:
166: int maxWidths = 256;
167: List widths = new ArrayList(maxWidths);
168: Integer zero = new Integer(0);
169: Iterator iter = listmetric.iterator();
170: while (iter.hasNext()) {
171: CharMetric m = (CharMetric) iter.next();
172: int n = m.getCharacterCode();
173: if (n > 0) {
174: firstchar = Math.min(firstchar, n);
175: lastchar = Math.max(lastchar, n);
176: if (m.getWx() > 0) {
177: float width = m.getWx();
178: widths.add(new Float(width));
179: } else {
180: widths.add(zero);
181: }
182: }
183: }
184: setFirstChar(firstchar);
185: setLastChar(lastchar);
186: setWidths(widths);
187:
188: }
189:
190: /**
191: * {@inheritDoc}
192: */
193: public PDFontDescriptor getFontDescriptor() throws IOException {
194: return fd;
195: }
196:
197: }
|