in fop-core/src/main/java/org/apache/fop/pdf/PDFFactory.java [937:1153]
public PDFFont makeFont(String fontname, String basefont,
String encoding, FontMetrics metrics,
FontDescriptor descriptor) {
PDFFont preRegisteredfont = getDocument().findFont(fontname);
if (preRegisteredfont != null) {
return preRegisteredfont;
}
boolean forceToUnicode = true;
if (descriptor == null) {
//Usually Base 14 fonts
PDFFont font = new PDFFont(fontname, FontType.TYPE1, basefont, encoding);
getDocument().registerObject(font);
if (forceToUnicode && !PDFEncoding.isPredefinedEncoding(encoding)) {
SingleByteEncoding mapping;
if (encoding != null) {
mapping = CodePointMapping.getMapping(encoding);
} else {
//for Symbol and ZapfDingbats where encoding must be null in PDF
Typeface tf = (Typeface)metrics;
mapping = CodePointMapping.getMapping(tf.getEncodingName());
}
generateToUnicodeCmap(font, mapping);
}
return font;
} else {
FontType fonttype = metrics.getFontType();
String fontPrefix = descriptor.isSubsetEmbedded() ? createSubsetFontPrefix() : "";
String subsetFontName = fontPrefix + basefont;
PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor, fontPrefix);
PDFFont font = null;
font = PDFFont.createFont(fontname, fonttype, subsetFontName, null);
if (descriptor instanceof RefPDFFont) {
font.setObjectNumber(((RefPDFFont)descriptor).getRef().getObjectNumber());
font.setDocument(getDocument());
getDocument().addObject(font);
} else {
getDocument().registerObject(font);
}
if ((fonttype == FontType.TYPE0 || fonttype == FontType.CIDTYPE0)) {
font.setEncoding(encoding);
CIDFont cidMetrics;
if (metrics instanceof LazyFont) {
cidMetrics = (CIDFont)((LazyFont) metrics).getRealFont();
} else {
cidMetrics = (CIDFont)metrics;
}
PDFCIDSystemInfo sysInfo = new PDFCIDSystemInfo(cidMetrics.getRegistry(),
cidMetrics.getOrdering(), cidMetrics.getSupplement());
sysInfo.setDocument(document);
assert pdfdesc instanceof PDFCIDFontDescriptor;
PDFCIDFont cidFont = new PDFCIDFont(subsetFontName, cidMetrics.getCIDType(),
cidMetrics.getDefaultWidth(), getFontWidths(cidMetrics), sysInfo,
(PDFCIDFontDescriptor) pdfdesc);
getDocument().registerObject(cidFont);
PDFCMap cmap;
if (cidMetrics instanceof MultiByteFont && ((MultiByteFont) cidMetrics).getCmapStream() != null) {
cmap = new PDFCMap("fop-ucs-H", null);
try {
cmap.setData(IOUtils.toByteArray(((MultiByteFont) cidMetrics).getCmapStream()));
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
cmap = new PDFToUnicodeCMap(cidMetrics.getCIDSet().getChars(), "fop-ucs-H",
new PDFCIDSystemInfo("Adobe", "Identity", 0), false, eventBroadcaster);
}
getDocument().registerObject(cmap);
assert font instanceof PDFFontType0;
((PDFFontType0)font).setCMAP(cmap);
((PDFFontType0)font).setDescendantFonts(cidFont);
} else if (fonttype == FontType.TYPE1C
&& (metrics instanceof LazyFont || metrics instanceof MultiByteFont)) {
handleType1CFont(pdfdesc, font, metrics, fontname, basefont, descriptor);
} else {
assert font instanceof PDFFontNonBase14;
PDFFontNonBase14 nonBase14 = (PDFFontNonBase14)font;
nonBase14.setDescriptor(pdfdesc);
SingleByteFont singleByteFont;
if (metrics instanceof LazyFont) {
singleByteFont = (SingleByteFont)((LazyFont)metrics).getRealFont();
} else {
singleByteFont = (SingleByteFont)metrics;
}
int firstChar = 0;
int lastChar = 0;
boolean defaultChars = false;
if (singleByteFont.getEmbeddingMode() == EmbeddingMode.SUBSET) {
Map<Integer, Integer> usedGlyphs = singleByteFont.getUsedGlyphs();
if (fonttype == FontType.TYPE1 && usedGlyphs.size() > 0) {
SortedSet<Integer> keys = new TreeSet<Integer>(usedGlyphs.keySet());
keys.remove(0);
if (keys.size() > 0) {
firstChar = keys.first();
lastChar = keys.last();
int[] newWidths = new int[(lastChar - firstChar) + 1];
for (int i = firstChar; i < lastChar + 1; i++) {
if (usedGlyphs.get(i) != null) {
if (i - singleByteFont.getFirstChar() < metrics.getWidths().length) {
newWidths[i - firstChar] = metrics.getWidths()[i
- singleByteFont.getFirstChar()];
} else {
defaultChars = true;
break;
}
} else {
newWidths[i - firstChar] = 0;
}
}
nonBase14.setWidthMetrics(firstChar,
lastChar,
new PDFArray(null, newWidths));
}
} else {
defaultChars = true;
}
} else {
defaultChars = true;
}
if (defaultChars) {
firstChar = singleByteFont.getFirstChar();
lastChar = singleByteFont.getLastChar();
nonBase14.setWidthMetrics(firstChar,
lastChar,
new PDFArray(null, metrics.getWidths()));
}
//Handle encoding
SingleByteEncoding mapping = singleByteFont.getEncoding();
if (singleByteFont.isSymbolicFont()) {
//no encoding, use the font's encoding
if (forceToUnicode) {
generateToUnicodeCmap(nonBase14, mapping);
}
} else if (PDFEncoding.isPredefinedEncoding(mapping.getName())) {
font.setEncoding(mapping.getName());
//No ToUnicode CMap necessary if PDF 1.4, chapter 5.9 (page 368) is to be
//believed.
} else if (mapping.getName().equals("FOPPDFEncoding")) {
if (fonttype == FontType.TRUETYPE) {
font.setEncoding(encoding);
} else {
String[] charNameMap = mapping.getCharNameMap();
char[] intmap = mapping.getUnicodeCharMap();
PDFArray differences = new PDFArray();
int len = intmap.length;
if (charNameMap.length < len) {
len = charNameMap.length;
}
int last = Integer.MIN_VALUE;
for (int i = 0; i < len; i++) {
if (intmap[i] - 1 != last) {
differences.add(intmap[i]);
}
last = intmap[i];
differences.add(new PDFName(charNameMap[i]));
}
PDFEncoding pdfEncoding = new PDFEncoding(singleByteFont.getEncodingName());
getDocument().registerObject(pdfEncoding);
pdfEncoding.setDifferences(differences);
font.setEncoding(pdfEncoding);
if (mapping.getUnicodeCharMap() != null) {
generateToUnicodeCmap(nonBase14, mapping);
}
}
} else {
Object pdfEncoding = createPDFEncoding(mapping,
singleByteFont.getFontName());
if (pdfEncoding instanceof PDFEncoding) {
font.setEncoding((PDFEncoding)pdfEncoding);
} else {
font.setEncoding((String)pdfEncoding);
}
if (forceToUnicode) {
generateToUnicodeCmap(nonBase14, mapping);
}
}
//Handle additional encodings (characters outside the primary encoding)
if (singleByteFont.hasAdditionalEncodings()) {
for (int i = 0, c = singleByteFont.getAdditionalEncodingCount(); i < c; i++) {
SimpleSingleByteEncoding addEncoding
= singleByteFont.getAdditionalEncoding(i);
String name = fontname + "_" + (i + 1);
Object pdfenc = createPDFEncoding(addEncoding,
singleByteFont.getFontName());
PDFFontNonBase14 addFont = (PDFFontNonBase14)PDFFont.createFont(
name, fonttype,
basefont, pdfenc);
addFont.setDescriptor(pdfdesc);
addFont.setWidthMetrics(
addEncoding.getFirstChar(),
addEncoding.getLastChar(),
new PDFArray(null, singleByteFont.getAdditionalWidths(i)));
getDocument().registerObject(addFont);
getDocument().getResources().addFont(addFont);
if (forceToUnicode) {
generateToUnicodeCmap(addFont, addEncoding);
}
}
}
}
return font;
}
}