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:
- NetWork Sobre el hilo principal Excepción
- ¿Cómo puedo depurar el consumo de memoria RAM de mi aplicación Android en tiempo de ejecución?
- ¿Cómo obtener velocidad de enlace mediante programación?
- Android: Añadir botón a YouTubePlayerView
- Kotlin-android: enlace de datos de referencia no resuelto
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
.
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.
- Java Android - Redmi 3 (MIUI) - No se pueden cambiar los iconos de notificación?
- Android ListView personalizado no puede hacer clic en los elementos
- Mantener el receptor de difusión funcionando después de cerrar la aplicación
- Pasar un ArrayList de cualquier tipo a un método
- Cómo detener ProGuard de eliminar la interfaz Serializable de una clase
- No se puede resolver el método checkSelfPermission
- Android - Mantener usuario conectado
- Ajustar EditText a una sola línea hace que pierda su foco después de presionar enter
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:
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.
- Cómo crear varias aplicaciones desde una sola aplicación de Android con diferentes contenidos
- RecyclerView: devolución de llamada cuando la vista ya no es visible