如何在 Kotlin 的 Apache FOP 中获取我的自定义字体?
How to get my custom font in Apache FOP in Kotlin?
我正在使用 Apache FOP 生成 PDF。
我想在 kotlin 中加载我的自定义字体“Interstate”,这样我就可以使用字体规格来计算文本的宽度。
但是我似乎无法获得我的自定义字体。
我尝试使用 FontListGenerator,但它只列出了默认字体,如“Helvetica”,即使 FopFactory 得到了包含自定义字体的配置。
这是我获取字体的 kotlin 函数:
private fun getFopFont(configFile: String, fontFamily: String, triplet: FontTriplet, fontSize: Int): Font? {
// create empty FontEventListener just to satisfy FontListGenerator
val listener: FontEventListener = object : FontEventListener {
override fun fontLoadingErrorAtAutoDetection(source: Any, fontURL: String, e: Exception) {}
override fun fontSubstituted(source: Any, requested: FontTriplet, effective: FontTriplet) {}
override fun glyphNotAvailable(source: Any, ch: Char, fontName: String) {}
override fun fontDirectoryNotFound(source: Any, msg: String) {}
override fun svgTextStrokedAsShapes(source: Any, fontFamily: String) {}
}
val listGenerator = FontListGenerator()
val fopFactory = FopFactory.newInstance(File(configFile).toURI())
@Suppress("UNCHECKED_CAST")
val fontFamilies = listGenerator.listFonts(fopFactory, MimeConstants.MIME_PDF, listener) as SortedMap<String, List<FontSpec>>
val fontSpec = fontFamilies[fontFamily] as ArrayList<FontSpec>? ?: return null
return fontSpec.filter {spec -> spec.triplets.contains(triplet)}
.map {Font(fontFamily, triplet, it.fontMetrics, fontSize)}
.firstOrNull()
}
我发现了我的错误。
我在代码中使用的 fopFactory 似乎没有正确加载我的字体。
为了修复我使用 FopConfParser 解析我的配置文件并使用解析器的 fopFactoryBuilder 来获取 fopFactory 的问题。
fop 工厂创建:
private fun createFopFactory(fopConfiguration: URL): FopFactory {
try {
fopConfiguration.openStream().use {fopConfigurationStream ->
// FontResourceResolver is my custom resource resolver to load font resources
val parser = FopConfParser(fopConfigurationStream, fopConfiguration.toURI(), FontResourceResolver())
val builder = parser.fopFactoryBuilder
return builder.build()
}
} catch (e: Exception) {
throw PDFServiceException("Could not initialize FOP factory", e)
}
}
我正在使用 Apache FOP 生成 PDF。
我想在 kotlin 中加载我的自定义字体“Interstate”,这样我就可以使用字体规格来计算文本的宽度。
但是我似乎无法获得我的自定义字体。
我尝试使用 FontListGenerator,但它只列出了默认字体,如“Helvetica”,即使 FopFactory 得到了包含自定义字体的配置。
这是我获取字体的 kotlin 函数:
private fun getFopFont(configFile: String, fontFamily: String, triplet: FontTriplet, fontSize: Int): Font? {
// create empty FontEventListener just to satisfy FontListGenerator
val listener: FontEventListener = object : FontEventListener {
override fun fontLoadingErrorAtAutoDetection(source: Any, fontURL: String, e: Exception) {}
override fun fontSubstituted(source: Any, requested: FontTriplet, effective: FontTriplet) {}
override fun glyphNotAvailable(source: Any, ch: Char, fontName: String) {}
override fun fontDirectoryNotFound(source: Any, msg: String) {}
override fun svgTextStrokedAsShapes(source: Any, fontFamily: String) {}
}
val listGenerator = FontListGenerator()
val fopFactory = FopFactory.newInstance(File(configFile).toURI())
@Suppress("UNCHECKED_CAST")
val fontFamilies = listGenerator.listFonts(fopFactory, MimeConstants.MIME_PDF, listener) as SortedMap<String, List<FontSpec>>
val fontSpec = fontFamilies[fontFamily] as ArrayList<FontSpec>? ?: return null
return fontSpec.filter {spec -> spec.triplets.contains(triplet)}
.map {Font(fontFamily, triplet, it.fontMetrics, fontSize)}
.firstOrNull()
}
我发现了我的错误。 我在代码中使用的 fopFactory 似乎没有正确加载我的字体。 为了修复我使用 FopConfParser 解析我的配置文件并使用解析器的 fopFactoryBuilder 来获取 fopFactory 的问题。
fop 工厂创建:
private fun createFopFactory(fopConfiguration: URL): FopFactory {
try {
fopConfiguration.openStream().use {fopConfigurationStream ->
// FontResourceResolver is my custom resource resolver to load font resources
val parser = FopConfParser(fopConfigurationStream, fopConfiguration.toURI(), FontResourceResolver())
val builder = parser.fopFactoryBuilder
return builder.build()
}
} catch (e: Exception) {
throw PDFServiceException("Could not initialize FOP factory", e)
}
}