Mostrar texto con Uniscribe

Las aplicaciones pueden usar las funciones de las API de Uniscribe para admitir la tipografía y la visualización y la edición de texto internacional. Uniscribe usa el párrafo como unidad para mostrar texto y la funcionalidad Uniscribe debe usarse para todo el párrafo.

Al usar Uniscribe para mostrar texto, una aplicación debe pasar por un proceso de formato ("diseño"), normalmente mediante Uniscribe. La aplicación divide un párrafo de texto en cadenas de caracteres con el mismo estilo, denominado "ejecuciones". El estilo viene determinado por una implementación concreta, pero normalmente incluye los atributos fuente, tamaño y color. Al definir las ejecuciones, la aplicación también puede aplicar otra información, como los datos de idioma y la configuración regional mantenidos para su uso con herramientas léxicas. Por ejemplo, una aplicación podría tratar como una ejecución independiente un pasaje de un texto principalmente en inglés que se representa en francés.

Una vez que haya determinado las ejecuciones de todos los párrafos, la aplicación divide cada párrafo en cadenas que tienen el mismo script y dirección ("elementos"). La aplicación utiliza la información del elemento para generar ejecuciones que son únicas en el script y la dirección y que se encuentran completamente dentro de un solo elemento ("intervalos").

El desglose de un elemento en intervalos es algo arbitrario, aunque un intervalo debe constar de una o varias agrupaciones de caracteres indivisibles definidas por scripts consecutivos, denominadas "clústeres". En el caso de los idiomas europeos, un clúster normalmente corresponde a un único carácter de página de códigos o a un punto de código Unicode y consta de un solo glifo. Sin embargo, en idiomas como el tailandés, un clúster es una agrupación de glifos y corresponde a varios caracteres consecutivos o puntos de código. Por ejemplo, un clúster tailandés podría contener un consonante, una vocal y una marca de tono. Para que no interrumpa los clústeres, la aplicación normalmente debe usar los intervalos más largos que pueda o usar su propia información léxica para interrumpir los intervalos en lugares que no están en medio de un clúster.

Cuando ha identificado los clústeres de cada intervalo, la aplicación debe determinar el tamaño de cada clúster. Usa Uniscribe para sumar los clústeres para determinar el tamaño de cada intervalo. A continuación, la aplicación suma los tamaños de los intervalos hasta que desbordan una línea, es decir, llegan al margen. El intervalo que desborda la línea se divide entre la línea actual y la línea siguiente. Para cada línea, la aplicación crea un mapa desde la posición visual hasta la posición lógica de cada intervalo. A continuación, la aplicación da forma de glifo a los puntos de código de cada intervalo, que posteriormente puede colocar y representar.

Una aplicación realiza un diseño de texto solo una vez. Después, guarda los glifos y las posiciones para fines de visualización o los genera cada vez que muestra el texto, con la velocidad de compensación frente a la memoria. Una aplicación típica implementa el proceso de diseño una vez y, a continuación, genera los glifos y posiciones cada vez que muestra el texto.

Una aplicación que usa scripts complejos tiene los siguientes problemas con un enfoque sencillo de diseño y visualización.

  • El ancho de un carácter de script complejo depende de su contexto. No es posible guardar los anchos en tablas simples.
  • La separación entre palabras en scripts como el tailandés requiere compatibilidad con diccionarios. Por ejemplo, no se usa ningún carácter separador entre palabras tailandesas.
  • Los idiomas árabe, hebreo, persa, urdu y otros idiomas de texto bidireccionales requieren ser reordenados antes de mostrarse.
  • A menudo, se requiere alguna forma de asociación de fuentes para usar fácilmente scripts complejos.

El hecho de que Uniscribe use el párrafo como unidad de visualización ayuda a la aplicación a tratar adecuadamente estos problemas de script complejos.

Nota:

Se debe usar Uniscribe para un párrafo completo, aunque las secciones del párrafo no sean scripts complejos.

 

Como se muestra en la tabla siguiente, la versión 1.6 o posterior de Uniscribe admite varias funciones que aprovechan las etiquetas OpenType. Se pueden sustituir por las funciones Uniscribe normales correspondientes. Por lo general, las aplicaciones deben funcionar completamente con funciones de un conjunto u otro y no deben intentar "mezclar y coincidir" funciones.

Función Uniscribe normal Función OpenType equivalente
ScriptItemize ScriptItemizeOpenType
ScriptShape ScriptShapeOpenType
ScriptPlace ScriptPlaceOpenType

 

Diseño de texto mediante Uniscribe

La aplicación puede diseñar un párrafo de texto con Uniscribe siguiendo estos pasos. En este procedimiento se supone que la aplicación ya ha dividido el párrafo en ejecuciones.

  1. Llame a ScriptRecordDigitSubstitution solo al iniciar o al recibir un mensaje de WM_SETTINGCHANGE.

  2. (Opcional) Llame a ScriptIsComplex para determinar si el párrafo requiere un procesamiento complejo.

  3. (Opcional) Si usa Uniscribe para controlar el texto bidireccional o la sustitución de dígitos, llame a ScriptApplyDigitSubstitution para preparar las estructuras de SCRIPT_CONTROL y SCRIPT_STATE como entradas para ScriptItemize. Si omite este paso, pero aún requiere la sustitución de dígitos, sustituya los dígitos nacionales de Unicode U+0030 por U+0039 (dígitos europeos). Para obtener información sobre la sustitución de dígitos, vea Formas de dígitos.

  4. Llame a ScriptItemize para dividir el párrafo en elementos. Si no usa Uniscribe para la sustitución de dígitos y conoce el orden bidireccional, por ejemplo, debido al diseño de teclado usado para escribir el carácter, llame a ScriptItemize. En la llamada, proporcione punteros nulos para las estructuras SCRIPT_CONTROL y SCRIPT_STATE. Esta técnica genera elementos solo mediante el uso del motor de forma y los elementos se pueden reordenar mediante la información del motor.

    Nota:

    Normalmente, las aplicaciones que solo funcionan con scripts de izquierda a derecha y sin sustitución de dígitos deben transmitir punteros nulos para las estructuras de SCRIPT_CONTROL y SCRIPT_STATE.

     

  5. Combine la información del elemento con la información de ejecución para generar intervalos.

  6. Llame a ScriptShape para identificar clústeres y generar glifos.

  7. Si ScriptShape devuelve el código USP_E_SCRIPT_NOT_IN_FONT o S_OK con la salida que contiene los glifos que faltan, seleccione caracteres de otra fuente. Sustituya otra fuente o deshabilite la forma estableciendo el miembro eScript de la estructura de SCRIPT_ANALYSIS pasada a ScriptShape en SCRIPT_UNDEFINED. Para obtener más información, consulte Uso de reserva de fuentes.

  8. Llame a ScriptPlace para generar anchos avanzados y posiciones x e y para los glifos en cada intervalo sucesivo. Este es el primer paso para el que el tamaño del texto se considere.

  9. Sume los tamaños del intervalo hasta que se desborda la línea.

  10. Interrumpa el intervalo en un límite de palabras mediante los miembros fSoftBreak y fWhiteSpace en los atributos lógicos. Para interrumpir un clúster de caracteres único fuera de la ejecución, use la información devuelta mediante una llamada a ScriptBreak.

    Nota:

    Decida si el primer punto de código de un intervalo debe ser un punto de interrupción de palabras porque el último carácter del intervalo anterior lo requiere. Por ejemplo, si un intervalo termina en una coma, considere el primer carácter del siguiente intervalo para ser un punto de interrupción de palabras.

     

  11. Repita los pasos del 6 al 10 para cada línea del párrafo. Sin embargo, si se rompe la última ejecución en la línea, llame a ScriptShape para volver a dar forma a la parte restante de la ejecución como la primera ejecución en la línea siguiente.

Mostrar texto mediante Uniscribe

La aplicación puede usar los pasos siguientes para mostrar un párrafo de texto. En este procedimiento se supone que la aplicación ya ha diseñado el texto y no ha guardado los glifos y las posiciones del proceso de diseño. Si la velocidad es un problema, la aplicación puede guardar los glifos y las posiciones del procedimiento de diseño e empezar en el paso 2 del procedimiento de visualización.

Nota:

La aplicación puede omitir el paso 2 si el texto no contiene caracteres de scripts de derecha a izquierda, no contiene caracteres de control bidireccionales y usa un nivel de inserción base de izquierda a derecha.

 

  1. Para cada ejecución, haga lo siguiente:

    1. Si el estilo ha cambiado desde la última ejecución, actualice el identificador al contexto del dispositivo liberando y obteniéndolo de nuevo.
    2. Llame a ScriptShape para generar glifos para la ejecución.
    3. Llame a ScriptPlace para generar un ancho avanzado y un desplazamiento x,y para cada glifo.
  2. Haga lo siguiente para establecer el orden visual correcto para las ejecuciones en la línea:

    1. Extraiga una matriz de niveles de inserción bidireccional, uno por intervalo. El nivel de inserción lo da (SCRIPT_ITEM) si.(SCRIPT_ANALYSIS) a. (SCRIPT_STATE) s.uBidiLevel.
    2. Pase esta matriz a ScriptLayout para generar un mapa de posiciones visuales a posiciones lógicas.
  3. (Opcional) Para justificar el texto, llame a ScriptJustify o use conocimientos especializados del texto.

  4. Use el mapa visual a lógico para mostrar las ejecuciones en orden visual. A partir del extremo izquierdo de la línea, llame a ScriptTextOut para mostrar la ejecución dada por la primera entrada del mapa. Para cada entrada posterior en el mapa, llame a ScriptTextOut para mostrar la ejecución indicada a la derecha de la ejecución mostrada anteriormente.

    Si se omite el paso 2, comience en el extremo izquierdo de la línea y llame a ScriptTextOut para mostrar la primera ejecución lógica y, a continuación, para mostrar cada ejecución lógica a la derecha de la ejecución anterior.

  5. Repita los pasos anteriores para todas las líneas del párrafo.

Uso de Uniscribe