Ok, I did some research and now are able to provide some more info on this.
First, about the enhancements to the API:
normalPdfFont
boldPdfFont
italicPdfFont
boldItalicPdfFont
I wonder whether these methods are really necesarry...
I was tracing through the code and noticed this in SimpleFontFace.getInstance:
if (fontName.trim().toUpperCase().endsWith(".TTF"))
{
fontFace = new SimpleFontFace(fontName);
}
else
{
JRFontUtil.checkAwtFont(fontName, JRPropertiesUtil.getInstance( jasperReportsContext ).getBooleanProperty( JRStyledText.PROPERTY_AWT_IGNORE_MISSING_FONT ));
fontFace = new SimpleFontFace( new Font( fontName, Font.PLAIN, JRPropertiesUtil.getInstance( jasperReportsContext ).getIntegerProperty( JRFont.DEFAULT_FONT_SIZE )));
}
There is a hardcoded check on .TTF here that explains why these fonts do work out-of-the-box, without resorting to the special setXxxPdfFont methods. All other font types, including .ttc (TryeType Collection) fonts go into the else branch, where we see that JRFontUtil.checkAwtFont is called. That is the method that throws the JRFontNotFoundException. However, I think the call to this method is programmed in the wrong way.
The checkAwtFont method is expecting a font name, but the SimpleFontFace.getInstance method accepts a font *file* name and it just passes that along directly. Teodor's solution fixes that. You set the font name in the setNormalFont method and set the font *file* name in the setNormalPdfFont... However, why not just fix this check?
Second, about figuring out the path to the individual font faces within the TrueType Collection (.ttc) file:
I was able to make it work by leveraging some existing code in iText (support lib that comes with Jasper). Basically, what we do is call some method on iText to get the names of the font faces that are inside the .ttc file and then loop through them to see which one corresponds to the font that we are trying to find. We then append the index of the face whose name matches to the path to the .ttc.
Font font;
// Assume font is set to the Java Font instance corresponding to the font face we are trying to set (e.g. Arial Bold)
String path;
// Assume path is set to a valid .ttc file containing the faces of the font family (e.g. "arial.ttc")
// Get the names of the individual font face files within the TrueType Collection
String[] names = BaseFont.enumerateTTCNames(path);
// Loop through the names to determine the index of the current font face within the collection.
for (int idx = 0; idx < names.length; idx++) {
// My testing indicates that font.getPSName() corresponds to the names returned by enumerateTTCNames...
if (font.getPSName().equals(names[idx])) {
// Found the current font face at index 'idx' inside the collection, update path to reflect this
path += "," + idx;
break; // done!
}
}
The 'path' variable will end up looking like this:
"arial.ttc,2"
Now I don't think Arial is in a TTC actually, but it's just an example.
When I complete my code, I am planning to post some more details on my blog about this. I will put a link here by then.
-Stijn