#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)
}
}