La fuente personalizada da un glifo incorrecto para ciertas combinaciones de letras en Android

Estoy usando una fuente personalizada en mi proyecto de Android. Por alguna razón, cuando el texto incluye las letras IJ juntas, me da el siguiente glifo:

Introduzca aquí la descripción de la imagen

Este parece ser el glifo localizado en \uE2C5 de la región PUA de la fuente.

Los glifos individuales I y J existen en la fuente y puedo hacer que aparezcan si establezco el texto en IJ .

Introduzca aquí la descripción de la imagen

No es una fuente OpenType (no creo que Android ni siquiera apoya la representación de OpenType en fuentes personalizadas), así que no debería haber nada como esto sucediendo. ¿Que esta pasando aqui?

El problema es reproducible con el siguiente proyecto simple:

 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = (TextView) findViewById(R.id.textview); Typeface tf = Typeface.createFromAsset(this.getAssets(), "MenksoftHawang.ttf"); textView.setTypeface(tf); textView.setText("IJ"); } } 

La fuente se puede descargar desde aquí . Póngalo en la carpeta de activos del proyecto.

Realmente no puedo hablar de la razón por la que estás viendo lo que estás viendo, pero la combinación de letras de "IJ" parece tener un historial de tratamiento especial. De la página de Wikipédia sobre Ligadura tipográfica .

El holandés ij, sin embargo, es algo más ambiguo. Dependiendo de la norma utilizada, puede considerarse un digrafo, una ligadura o una letra en sí mismo, y sus formas en mayúsculas y minúsculas están a menudo disponibles como un glifo único con una ligadura distintiva en varias fuentes profesionales (por ejemplo, Zapfino). Los glifos en letra mayúscula IJ sin serifa, muy populares en los Países Bajos, usan típicamente una ligadura que se asemeja a una U con un golpe roto a la izquierda.

También de Wikipedia :

Sustitución y composición de glifos

Algunos caracteres de compatibilidad son completamente dispensables para procesamiento de texto y software de visualización que se ajusta al estándar Unicode. Éstas incluyen:

Ligaduras Ligaduras como 'ffi' en la escritura latina a menudo se codifican como un carácter separado en conjuntos de caracteres heredados. El acercamiento de Unicode a las ligaduras es tratarlas como un texto rico y, si está activado, manejado a través de la sustitución del glifo.

Teniendo en cuenta esto, mi conjetura es que la fuente que está utilizando ha aprovechado este tipo de uso para hacer su propia cosa.

Actualización El uso de setFontFeatureSettings() funciona para desactivar la visualización del glifo como se muestra en el código siguiente. Lamentablemente, esto solo está disponible en API 21+. Hay una advertencia de que puede haber otros efectos secundarios que usted puede ser consciente de.

Para APIs por debajo de 21, puede utilizar un programa de edición de fuentes como FontForge y eliminar el glifo en U + E2C5. He hecho esto y elimina el glifo. Esta puede ser la mejor manera de ir, siempre y cuando usted piensa que puede identificar todas las combinaciones de letras que pueden dar lugar a un glifo.

 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String features = "\"liga\"=0"; TextView textView = (TextView) findViewById(R.id.textview); Typeface tf = Typeface.createFromAsset(this.getAssets(), "MenksoftHawang" + ".ttf"); textView.setTypeface(tf); textView.setFontFeatureSettings(features); textView.setText("IJ ij"); } } 

No estoy seguro de la causa exacta del problema, supongo que podría ser también un problema de fuente.

Pero como solución, puede aplicar un espaciado de letras minúsculas, que mostrará las letras como se esperaba.

 textView1.setText("IJ"); textView2.setLetterSpacing(0.04f); textView2.setText("IJ"); 

Resultado:

Introduzca aquí la descripción de la imagen

Parece haber tres soluciones a este problema:

1. Deshabilitar mediante programación las ligaduras

Puede desactivar las ligaduras mediante programación con setFontFeatureSettings (como se sugiere aquí ) o setLetterSpacing (como se sugiere aquí ). Una desventaja de ambos métodos es que sólo están disponibles en la API 21.

2. Editar las ligaduras de la fuente

Puede utilizar el software de edición de fuentes para corregir o eliminar los errores de ligadura en la fuente. Consulte esta Q & A para saber cómo hacerlo en FontForge. Un problema potencial aquí es que los propietarios de copyright de fuentes no pueden permitir que terceros editen sus fuentes.

3. Utilizar una fuente diferente

Diferentes fuentes a menudo están disponibles y eso es cierto en este caso. La misma compañía que tenía la fuente TrueType problemática en la pregunta también tiene una versión OpenType de esa fuente. La versión OpenType no parece tener los errores de ligadura. Una desventaja, sin embargo, es que es significativamente más grande en tamaño, lo que hará que el tamaño de descarga de la aplicación más grande.

Notas

  • Anteriormente había pensado que no había renderizado de ligadura antes de Android 6.0. Sin embargo, las fuentes TrueType al parecer admiten algunas ligaduras básicas y las que se representan en las versiones de Android anteriores a 6.0.
  • La siguiente imagen de FontForge muestra todas las ligaduras definidas en la fuente problemática referida en la pregunta. Introduzca aquí la descripción de la imagen
  • Subclase de JavaScript en Parse.com
  • Adjuntar TextView a RecyclerView
  • Ocultar cadenas en código ofuscado
  • Obtenga el tamaño de RAM total que utiliza Aplicación en Android
  • Google TV - está diseñando para la eficiencia tan importante como lo es con los teléfonos / tabletas?
  • Android: obtenga el resultado del cuadro de diálogo predeterminado de cambios de la aplicación de SMS
  • ¿Qué es más fácil de codificar: aplicación de Android vs iOS aplicación?
  • Prueba de una clase Fragment en aislamiento usando Mockito
  • Hacer una matriz para un efecto smuge / wobble (ver imágenes) en Android
  • MissingResourceException: No se puede encontrar el paquete para el nombre base sun.util.logging.resources.logging, locale en_US
  • Pruebas de la unidad Android con Dagger 2
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.