org.apache.pdfbox.pdmodel.font.PDTrueTypeFontEmbedder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pdfbox Show documentation
Show all versions of pdfbox Show documentation
The Apache PDFBox library is an open source Java tool for working with PDF documents.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pdfbox.pdmodel.font;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.fontbox.ttf.HorizontalMetricsTable;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.COSArrayList;
import org.apache.pdfbox.pdmodel.font.encoding.Encoding;
import org.apache.pdfbox.pdmodel.font.encoding.GlyphList;
/**
* Embedded PDTrueTypeFont builder. Helper class to populate a PDTrueTypeFont from a TTF.
*
* @author John Hewson
* @author Ben Litchfield
*/
final class PDTrueTypeFontEmbedder extends TrueTypeEmbedder
{
private final Encoding fontEncoding;
/**
* Creates a new TrueType font embedder for the given TTF as a PDTrueTypeFont.
*
* @param document The parent document
* @param dict Font dictionary
* @param ttfStream TTF stream
* @param encoding The PostScript encoding vector to be used for embedding.
* @throws IOException if the TTF could not be read
*/
PDTrueTypeFontEmbedder(PDDocument document, COSDictionary dict, InputStream ttfStream,
Encoding encoding) throws IOException
{
super(document, dict, ttfStream, false);
dict.setItem(COSName.SUBTYPE, COSName.TRUE_TYPE);
GlyphList glyphList = GlyphList.getAdobeGlyphList();
this.fontEncoding = encoding;
dict.setItem(COSName.ENCODING, encoding.getCOSObject());
fontDescriptor.setSymbolic(false);
fontDescriptor.setNonSymbolic(true);
// add the font descriptor
dict.setItem(COSName.FONT_DESC, fontDescriptor);
// set the glyph widths
setWidths(dict, glyphList);
}
/**
* Sets the glyph widths in the font dictionary.
*/
private void setWidths(COSDictionary font, GlyphList glyphList) throws IOException
{
float scaling = 1000f / ttf.getHeader().getUnitsPerEm();
HorizontalMetricsTable hmtx = ttf.getHorizontalMetrics();
Map codeToName = getFontEncoding().getCodeToNameMap();
int firstChar = Collections.min(codeToName.keySet());
int lastChar = Collections.max(codeToName.keySet());
List widths = new ArrayList(lastChar - firstChar + 1);
for (int i = 0; i < lastChar - firstChar + 1; i++)
{
widths.add(0);
}
// a character code is mapped to a glyph name via the provided font encoding
// afterwards, the glyph name is translated to a glyph ID.
for (Map.Entry entry : codeToName.entrySet())
{
int code = entry.getKey();
String name = entry.getValue();
if (code >= firstChar && code <= lastChar)
{
String uni = glyphList.toUnicode(name);
int charCode = uni.codePointAt(0);
int gid = cmap.getGlyphId(charCode);
widths.set(entry.getKey() - firstChar,
Math.round(hmtx.getAdvanceWidth(gid) * scaling));
}
}
font.setInt(COSName.FIRST_CHAR, firstChar);
font.setInt(COSName.LAST_CHAR, lastChar);
font.setItem(COSName.WIDTHS, COSArrayList.converterToCOSArray(widths));
}
/**
* Returns the font's encoding.
*/
public Encoding getFontEncoding()
{
return fontEncoding;
}
@Override
protected void buildSubset(InputStream ttfSubset, String tag,
Map gidToCid) throws IOException
{
// use PDType0Font instead
throw new UnsupportedOperationException();
}
}