java apache-fop chinese-locale

java - Apache FOP Mostrando### con SimSun



apache-fop chinese-locale (1)

Se deben seguir tres pasos para que los caracteres chinos se muestren correctamente en un archivo PDF creado con FOP (esto también es cierto para todos los caracteres que no están disponibles en la fuente predeterminada y, en general, para usar una fuente no predeterminada) .

Usemos este sencillo ejemplo para mostrar las advertencias producidas por FOP cuando algo está mal:

<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="one"> <fo:region-body /> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="one"> <fo:flow flow-name="xsl-region-body"> <!-- a block of chinese text --> <fo:block>博洛尼亚大学中国学生的毕业论文</fo:block> </fo:flow> </fo:page-sequence> </fo:root>

Al procesar esta entrada, FOP ofrece varias advertencias similares a esta:

org.apache.fop.events.LoggingEventListener processEvent WARNING: Glyph "?" (0x535a) not available in font "Helvetica". ...

Sin ninguna indicación explícita de la familia de fuentes en el archivo FO, FOP usa de forma predeterminada Helvetica, que es una de las fuentes Base-14 (fuentes que están disponibles en todas partes, por lo que no es necesario incrustarlas).

Cada fuente admite un conjunto de caracteres, asignándoles glifos visibles; cuando una fuente no admite un carácter, se genera la advertencia anterior y el PDF muestra "#" en lugar del glifo faltante .

Paso 1: establezca font-family en el archivo FO

Si la fuente predeterminada no admite los caracteres de nuestro texto (o simplemente queremos usar una fuente diferente) , debemos usar la propiedad de font-family para indicar la deseada.

El valor de font-family se hereda, por lo que si queremos usar la misma fuente para todo el documento, podemos establecer la propiedad en fo:page-sequence ; si necesitamos una fuente especial solo para algunos párrafos o palabras, podemos establecer font-family en el fo:block o fo:inline relevante.

Entonces, nuestra entrada se convierte (usando una fuente que tengo como ejemplo):

<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="one"> <fo:region-body /> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="one"> <fo:flow flow-name="xsl-region-body"> <!-- a block of chinese text --> <fo:block font-family="SimSun">博洛尼亚大学中国学生的毕业论文</fo:block> </fo:flow> </fo:page-sequence> </fo:root>

¡Pero ahora recibimos una nueva advertencia, además de las antiguas!

org.apache.fop.events.LoggingEventListener processEvent WARNING: Font "SimSun,normal,400" not found. Substituting with "any,normal,400". org.apache.fop.events.LoggingEventListener processEvent WARNING: Glyph "?" (0x535a) not available in font "Times-Roman". ...

FOP no sabe cómo asignar "SimSun" a un archivo de fuente , por lo que su valor predeterminado es una fuente genérica Base-14 (Times-Roman) que no admite nuestros caracteres chinos, y el PDF aún muestra "#" .

Paso 2: configure la asignación de fuentes en el archivo de configuración de FOP

Dentro de la carpeta de FOP, el archivo conf/fop.xconf es una configuración de ejemplo; podemos editarlo directamente o hacer una copia para comenzar.

El archivo de configuración es un archivo XML, y tenemos que agregar las asignaciones de fuentes dentro de /fop/renderers/renderer[@mime = ''application/pdf'']/fonts/ (hay una sección de renderer para cada posible tipo de mime de salida, por lo que compruebe que está insertando su mapeo en el correcto):

<?xml version="1.0"?> <fop version="1.0"> ... <renderers> <renderer mime="application/pdf"> ... <fonts> <!-- specific font mapping --> <font kerning="yes" embed-url="/Users/furini/Library/Fonts/SimSun.ttf" embedding-mode="subset"> <font-triplet name="SimSun" style="normal" weight="normal"/> </font> <!-- "bulk" font mapping --> <directory>/Users/furini/Library/Fonts</directory> </fonts> ... </renderer> ... </renderers> </fop>

  • cada elemento de font apunta a un archivo de fuente
  • cada entrada de font-triplet identifica una combinación de font-family font-style + font-style (normal, cursiva, ...) + font-weight (normal, negrita, ...) asignada al archivo de fuente en el elemento font primario
  • usando elementos de folder también es posible configurar automáticamente todos los archivos de fuentes dentro de las carpetas indicadas (pero esto lleva algún tiempo si las carpetas contienen muchas fuentes)

Si tenemos un conjunto de archivos completo con versiones específicas de la fuente deseada (normal, cursiva, negrita, clara, negrita cursiva, ...) podemos asignar cada archivo al triplete de fuente preciso, produciendo así un PDF muy sofisticado.

En el extremo opuesto del espectro podemos asignar todo el triplete al mismo archivo de fuente, si es todo lo que tenemos disponible: en la salida, todo el texto aparecerá igual, incluso si en el archivo FO partes del mismo se marcaron en cursiva o negrita.

Tenga en cuenta que no necesitamos registrar todos los tripletes de fuentes posibles; si falta uno, FOP usará la fuente registrada para una "similar" (por ejemplo, si no asignamos el triplete "SimSun, cursiva, 400" FOP usará la fuente asignada a "SimSun, normal, 400" , advirtiéndonos sobre la sustitución de fuentes).

Todavía no hemos terminado, ya que sin el siguiente y último paso nada cambia cuando procesamos nuestro archivo de entrada.

Paso 3: dile a FOP que use el archivo de configuración

Si llamamos a FOP desde la línea de comandos, usamos la opción -c para apuntar a nuestro archivo de configuración, por ejemplo:

$ fop -c /path/to/our/fop.xconf input.fo input.pdf

Desde el código java podemos usar (ver también el sitio de FOP ):

fopFactory.setUserConfig(new File("/path/to/our/fop.xconf"));

Ahora, por fin, el PDF debería usar correctamente las fuentes deseadas y aparecer como se esperaba.

Si en cambio, FOP termina abruptamente con un error como este:

org.apache.fop.cli.Main startFOP SEVERE: Exception org.apache.fop.apps.FOPException: Failed to resolve font with embed-url ''/Users/furini/Library/Fonts/doesNotExist.ttf''

significa que FOP no pudo encontrar el archivo de fuente, y la configuración de la fuente debe verificarse nuevamente; causas típicas son

  • un error tipográfico en la fuente url
  • privilegios insuficientes para acceder al archivo de fuente

Mantengo un programa que utiliza Apache FOP para imprimir documentos PDF. Ha habido un par de quejas sobre los caracteres chinos que aparecen como "####". Encontré un hilo existente sobre este problema y realicé algunas investigaciones de mi parte.

http://apache-fop.1065347.n5.nabble.com/Chinese-Fonts-td10789.html

Tengo los archivos de idioma uming.tff instalados en mi sistema. A diferencia de la persona en este hilo, todavía obtengo el "####".

A partir de este momento, ¿alguien ha visto una solución que le permita imprimir caracteres complejos en un documento PDF con Apache FOP?

Ryan