Как получить мой пользовательский шрифт в Apache FOP в Kotlin?

#kotlin #fonts #apache-fop

#котлин #шрифты #apache-fop

Вопрос:

я создаю PDF-файл с помощью Apache FOP.

я хочу загрузить свой пользовательский шрифт «Interstate» в kotlin, чтобы я мог рассчитать ширину текста, используя метрики шрифта.

Однако, похоже, я не могу получить свой пользовательский шрифт.

Я пытался использовать 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()
}
 

Ответ №1:

я нашел свою ошибку. похоже, что 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)
    }
}