Partial FontInfo Cache for ignoreCase=false. #142
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The motivation for this pull request comes from the very long durations needed for exporting Excel files from the JasperViewer, when JasperFonts are installed and when the JVM's Locale was changed from its startup value.
Looking at the JasperReports source code, there are several places with comments suggesting that performance is not optimal regarding font handling. For example, in net.sf.jasperreports.engine.fonts.FontUtil.getFontInfo(String name, boolean ignoreCase, Locale locale) line 190 there is the comment:
//FIXMEFONT do some cache
Looking further for the place that causes the delay, java.awt.Font.getFamily() can be identified, which in turn calls sun.font.TrueTypeFont.getFonName(Locale locale). Here, when the given locale (corresponds to Locale.getDefault() in this case) is different from sun.awt.SunToolkit.getStartupLocale(), a rather expensive operation starts to determine the font name. Therefore, avoiding the call to java.awt.Font.getFamily() is desirable.
This pull request includes a simpe cache, which utilizes a map to remember resolved net.sf.jasperreports.engine.fonts.FontInfo objects. The key to the map is defined in the new class FontInfoKey and has currently only two properties, name and local. It only caters for the case when the getFontInfo()'s ignoreCase is false. This flag is false when the method is called from the two-params method getFontInfo(String name, Locale locale), such as when exporting Excel from JasperViewer via JRXlsExporter. For the case when ignoreCase is true, a separate map could be implemented, so that the two cases do not interfere with each other.
The impact of this little cache is rather enormous. In a specific Excel export case, duration without cache was about 1000 seconds, and with cache about 1 second.