如何在 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)
    }
}