2011-05-17 8 views
6

Esta es una "meta-pregunta" que encontré al tratar de encontrar una especificación mejor para otra de mis preguntas (Rendering Devanagari ligatures (Unicode) in Java Swing JComponent on Mac OS X).¿Qué componente del sistema es responsable de vincular ligaduras Unicode en una aplicación Java?

Lo que aún no entiendo es qué "componente" (a falta de una palabra mejor) de un sistema dado es responsable de mostrar texto Unicode en Java, y más específicamente ligatures.

Por lo que yo entiendo, los siguientes componentes tienen una influencia en el proceso:

  1. La codificación de caracteres del sistema (que, por ejemplo, es UTF-8 en Mac OS X 10.6, UTF-16 en Windows 7 (de acuerdo con el comentario de Akira en este superuser.com post)).
  2. Java Charset (que de forma predeterminada es MacRoman en Mac OS X 10.6, cp1252 en Windows 7).
  3. La fuente que se utiliza para representar el texto, y la información de codificación de ese tipo de letra (como se sugiere por Donal Fellows en my other question:

    "fuentes incluyen información sobre qué codificación que están usando"

  4. .
  5. Obviamente si los caracteres que hacen que están presentes en los respectivos puntos de código Unicode.

lo tanto, si una cadena de caracteres Unicode no muestra correctamente (como se ve en mi otra pregunta, s.a.), ¿dónde estaría el problema probablemente? Es decir, ¿qué "componente" (¿qué sería una palabra mejor?) Es responsable de "enlazar" la ligadura, su composición?

Muchas gracias de antemano y háganos saber si necesita más información.

+0

Me atrevería a adivinar la máquina virtual, pero no tengo evidencia o experiencia en este asunto. – Mr47

+0

@ Mr47: Bien, gracias, ese sería el número (2) entonces. Que es donde podría ser útil, supongo. Lo tendré en cuenta. He modificado un poco la publicación para especificar el "punto de entrada" de mi problema para los demás. –

Respuesta

3

Ese componente del sistema se llama un visualizador de fuentes o de trama fuente. Es responsable de convertir una secuencia de códigos de caracteres en píxeles en función de los glifos definidos en una fuente. Como han indicado otras respuestas, los diversos valores de codificación de caracteres que puede obtener y establecer desde Java son irrelevantes. Cuando la JVM da al procesador de fuentes una secuencia de códigos de caracteres, le dice qué codificación aplica (probablemente UTF16, pero esto es transparente para el programador Java). El renderizador de fuentes usa la codificación de fuentes especificada en el archivo de fuentes para hacer coincidir el correspondiente glifos.

Las versiones actuales de Windows y Mac OS X vienen con excelentes procesadores de fuentes.

El primer punto de confusión es que el JRE viene con su propio procesador de fuentes, como parte de la plataforma Java2D, y esto es lo que usa Swing. Debería haber una opción para controlar si Java usa su propio procesador o el del sistema.

EDIT:McDowell Como se señala en un comentario, en OS X se puede activar el procesador de sistema estableciendo la propiedad de Java apple.awt.graphics.UseQuartz = true.

El segundo punto de confusión es que las ligaduras son opcionales en inglés. Una aplicación de autoedición sustituirá a una ligadura "ffl" (un solo glifo en la fuente) cuando vea una palabra como "shuffle", pero la mayoría de las otras aplicaciones no molestan.En base a lo que has dicho sobre Devanagari (y lo que acabo de leer en Wikipedia), entiendo que las ligaduras no son opcionales en ese idioma.

De forma predeterminada, el renderizador de fuentes Java2D no hace ligaduras. Sin embargo, JavaDoc para java.awt.font.TextAttribute.LIGATURES dice que las ligaduras siempre están habilitadas para escribir sistemas que las requieren. Si esa no es su experiencia, es posible que haya encontrado un error en el renderizador de fuentes Java2D. Mientras tanto, intente utilizar el constructor de fuentes que toma un mapa de atributos de fuente, incluido TextAttribute.LIGATURES.

+0

Muchas gracias por esta interesante idea. Tienes razón en que las ligaduras no son opcionales en Devanagari. Sin embargo, he probado el 'LIGATURES_ON'' TextAttribute' (como lo sugiere [Oracle] (http://download.oracle.com/javase/tutorial/2d/text/textattributes.html), ver más abajo) y no lo hice No cambias nada, desafortunadamente. Lo que deja el archivo fontconfig como el origen más agradable del problema. 'Map m = new Hashtable (); m.put (TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON); font = font.deriveFont (mapa); g2.setFont (font); ' –

+1

@ baphomet13 - parece que puede usar una [propiedad del sistema Java] (http://developer.apple.com/library/mac/#documentation/Java/Reference/Java_PropertiesRef/Articles/JavaSystemProperties. html # // apple_ref/doc/uid/TP40008047) en OS X para alternar entre Java2D y la representación de Quartz: 'apple.awt.graphics.UseQuartz' – McDowell

+0

@McDowell: Su último comentario fue acertado y resolvió mi problema. ¿Puedo sugerirle que lo edite en su respuesta, para que pueda aceptarlo como la mejor respuesta? Además, he puesto una recompensa en mi pregunta relacionada [http://stackoverflow.com/questions/5994815/rendering-devanagari-ligatures-unicode-in-java-swing-jcomponent-on-mac-os-x], ¡y sugiero que agregues tu respuesta allí también para que pueda recompensarte con la recompensa! Muchas gracias de nuevo, ¡me ayudaste mucho allí! –

2

Si refiere estrictamente a la representación visual, entonces la "codificación" y los temas relacionados ya no son relevantes: la representación va de String a la visualización. El String tiene una codificación definida (e inmutable), que es UTF-16. Así que todas las preguntas como "¿He leído esta secuencia binaria con la codificación correcta" tienen que resolverse primero.

La representación real del texto debe ser realizada por el subsistema de gráficos. Eso sería AWT/Swing para Java o SWT "normal" o cualquier otro sistema alternativo.

El primer paso (que no es estrictamente parte de "representación") es convertir algunos datos binarios a un . Este puede involucrar codificación predeterminada de plataforma iff el código no especifica alguna codificación explícitamente. Este es el paso donde las codificaciones en general entran en juego. Después de eso, estamos en happy-happy-pure-Unicode-land.

+0

Muchas gracias por la especificación de los términos. Me temo que mi explicación no fue muy específica. ¿Estoy en lo cierto, sin embargo, en la suposición de que la * exhibición * correcta de ligaduras (por ejemplo, लक्ष्मी, que se construye utilizando siete puntos de código Unicode, o ff alemán) tiene que ver con la * codificación de caracteres * (el 'Sistema' Propiedad '' "file-encoding" ')? –

+0

Además, he cambiado el título y el texto para reflejar sus correcciones. –

+0

@baphomet: no, la ** pantalla ** correcta no. La pregunta es: ¿sus datos Unicode contienen U + FB00 LITERATURA PEQUEÑA LATINA FF o contiene 2 U + 0066 LETRA PEQUEÑA LATINA F? –

1

Similar a lo que dijo Joachim, ¿cuál es la fuente de los datos? Si está leyendo desde un archivo o secuencia, definitivamente no confíe en la codificación predeterminada del sistema. Debe establecer explícitamente la codificación al leer los datos, p.

BufferedReader br = new BufferedReader(new InputStreamReader(file, "UTF-8")); 

O lo que sea que codifica el torrente está en

Ver:.

http://download.oracle.com/javase/1.4.2/docs/api/java/io/InputStreamReader.html#InputStreamReader(java.io.InputStream,%20java.lang.String)

+0

Bien, ahora sé por qué he activado la respuesta de Joachim. De hecho, no * leo * desde un archivo, pero he definido una variable 'String' con caracteres Unicode (por ejemplo,' String str = "\ u0932 \ u0915 \ u094D \ u0937 \ u094D u092E \ u0940" '). Estos * no * se muestran correctamente en un sistema Mac, pero * se * muestran correctamente en un sistema Windows que provocó mi pregunta. Eliminaré el número (3) para que no active más respuestas sobre la lectura de las transmisiones. Lo siento, pensé que lo pondría para completitud. –

3

No soy un experto, pero espero que estos consejos te orientará en la dirección correcta. ..

La codificación de los datos fuente tiene poca relación con la forma en que se procesan las fuentes. Todos los datos de caracteres en Java son UTF-16, por lo que siempre que transcodifique información de origen a caracteres/cadenas, se debe preservar la integridad de los datos.

Sin embargo, nota:

  • El sistema AWT puede utilizar el sistema de codificación por defecto para hacer la asignación de fuentes
  • Esto es poco probable que solicitar devanagari (no soy consciente de una codificación legado que lo soporta)

AWT maps fonts es a través del fontconfig file. En mi sistema Windows, esto se asigna a la fuente Mangal:

allfonts.devanagari=Mangal 

Sin duda, se está utilizando una fuente diferente en Mac OS.

La traducción de texto nativo se introdujo en algún momento durante la vida útil de Java 6 - No sé si eso tiene alguna relación con el soporte de fuentes o solo afecta la velocidad de renderizado/antialiasing/etc.

+0

¡Gracias por tus consejos! Esto suena como si fuera lo que estaba buscando, aunque mis problemas para describir el problema. Necesitaré un poco de tiempo para probarlo, pero me aseguraré de seguirlo aquí. –

+0

Acabo de consultar a algunos usuarios de Mac y todos ellos tienen la asignación de fontconfig.properties a Mangal para 'allfonts.devanagari'. Para ser sincero, ahora estoy totalmente enterado de cómo entender por qué debería haber una diferencia entre la Mac y la pantalla de Windows, por lo que agradecería cualquier sugerencia. –

+0

@ baphomet13 - asumiendo que la fuente 'Mangal' es idéntica en ambas plataformas (y no en diferentes implementaciones bajo el mismo nombre) entonces sospecho que [gatkin] (http://stackoverflow.com/questions/6032401/which-system-component- is-responsible-for-binding-unicode-ligatures-in-a-java-app/6033769 # 6033769) está más cerca de la marca, el problema puede estar en _how_ la fuente se está procesando. – McDowell

Cuestiones relacionadas