Visualizzazione di testo con Uniscribe

Le applicazioni possono usare funzioni API Uniscribe per supportare la tipografia e la visualizzazione e la modifica di testo internazionale. Uniscribe usa il paragrafo come unità per la visualizzazione del testo e la funzionalità Uniscribe deve essere utilizzata per l'intero paragrafo.

Quando si usa Uniscribe per la visualizzazione del testo, un'applicazione deve eseguire un processo di formattazione ("layout"), in genere usando Uniscribe. L'applicazione divide un paragrafo di testo in stringhe di caratteri con lo stesso stile, denominato "runs". Lo stile è determinato dall'implementazione specifica, ma in genere include attributi quali tipo di carattere, dimensioni e colore. Nella definizione delle esecuzioni, l'applicazione può anche applicare altre informazioni, ad esempio i dati relativi alla lingua e alle impostazioni locali mantenuti per l'uso con strumenti lessicali. Ad esempio, un'applicazione può trattare come un'esecuzione separata di un passaggio in un testo principalmente in inglese di cui viene eseguito il rendering in francese.

Dopo aver determinato le esecuzioni per tutti i paragrafi, l'applicazione divide ogni paragrafo in stringhe con lo stesso script e la stessa direzione ("elementi"). L'applicazione applica le informazioni sugli elementi per produrre esecuzioni univoche nello script e nella direzione e rientrano interamente all'interno di un singolo elemento ("intervalli").

La suddivisione di un elemento in intervalli è in qualche modo arbitraria, anche se un intervallo deve essere costituito da uno o più raggruppamenti di caratteri consecutivi definiti dallo script, indivisibili, denominati "cluster". Per le lingue europee, un cluster corrisponde in genere a un singolo carattere tabella codici o punto di codice Unicode ed è costituito da un singolo glifo. Tuttavia, in linguaggi come thai, un cluster è un raggruppamento di glifi e corrisponde a più caratteri o punti di codice consecutivi. Ad esempio, un cluster thai potrebbe contenere una consonante, una vocale e un segno di tono. In modo che non interrompa i cluster, l'applicazione deve in genere usare gli intervalli più lunghi che può o usare le proprie informazioni lessicali per interrompere gli intervalli in posizioni che non si trovano al centro di un cluster.

Dopo aver identificato i cluster in ogni intervallo, l'applicazione deve determinare le dimensioni di ogni cluster. Usa Uniscribe per sommare i cluster per determinare le dimensioni di ogni intervallo. L'applicazione somma quindi le dimensioni degli intervalli fino a quando non superano una linea, ovvero raggiungono il margine. L'intervallo che esegue l'overflow della riga è diviso tra la riga corrente e la riga successiva. Per ogni riga, l'applicazione compila una mappa dalla posizione visiva alla posizione logica per ogni intervallo. L'applicazione modella quindi i punti di codice per ogni intervallo in glifi, che può successivamente posizionare ed eseguire il rendering.

Un'applicazione esegue il layout del testo una sola volta. Successivamente, salva i glifi e le posizioni per scopi di visualizzazione oppure li genera ogni volta che visualizza il testo, con il compromesso tra velocità e memoria. Un'applicazione tipica implementa il processo di layout una sola volta, quindi genera i glifi e le posizioni ogni volta che visualizza il testo.

Un'applicazione che usa script complessi presenta i problemi seguenti con un approccio semplice al layout e alla visualizzazione.

  • La larghezza di un carattere di script complesso dipende dal contesto. Non è possibile salvare le larghezze in tabelle semplici.
  • L'interruzione tra parole in script come thai richiede il supporto del dizionario. Ad esempio, non viene usato alcun carattere separatore tra le parole thai.
  • L'arabo, l'ebraico, il persiano, l'urdu e altre lingue di testo bidirezionale richiedono il riordinamento prima della visualizzazione.
  • Alcune forme di associazione dei tipi di carattere sono spesso necessarie per usare facilmente script complessi.

Il fatto che Uniscribe usi il paragrafo come unità di visualizzazione consente all'applicazione di gestire in modo adeguato questi problemi complessi di script.

Nota

Uniscribe deve essere utilizzato per un intero paragrafo, anche se le sezioni del paragrafo non sono script complessi.

 

Come illustrato nella tabella seguente, Uniscribe versione 1.6 o successiva supporta diverse funzioni che sfruttano i tag OpenType. Possono essere sostituite dalle normali funzioni Uniscribe corrispondenti. In genere le applicazioni devono funzionare interamente con funzioni di un set o l'altro e non devono tentare di "combinare e abbinare" funzioni.

Funzione Uniscribe regolare Funzione OpenType equivalente
ScriptItemize ScriptItemizeOpenType
ScriptShape ScriptShapeOpenType
ScriptPlace ScriptPlaceOpenType

 

Disposizione del testo con Uniscribe

L'applicazione può usare la procedura seguente per disporre un paragrafo di testo con Uniscribe. Questa procedura presuppone che l'applicazione abbia già diviso il paragrafo in esecuzioni.

  1. Chiamare ScriptRecordDigitSubstitution solo all'avvio o alla ricezione di un messaggio WM_edizione Standard TTINGCHANGE.

  2. (Facoltativo) Chiamare ScriptIsComplex per determinare se il paragrafo richiede un'elaborazione complessa.

  3. (Facoltativo) Se si usa Uniscribe per gestire la sostituzione bidirezionale di testo e/o cifra, chiamare ScriptApplyDigitSubstitution per preparare le strutture SCRIPT_CONTROL e SCRIPT_STATE come input per ScriptItemize. Se ignora questo passaggio, ma richiede ancora la sostituzione delle cifre, sostituire le cifre nazionali per Unicode U+0030 fino a U+0039 (cifre europee). Per informazioni sulla sostituzione delle cifre, vedere Digit Shapes.For information about digit substitution, see Digit Shapes.

  4. Chiamare ScriptItemize per dividere il paragrafo in elementi. Se non si usa Uniscribe per la sostituzione delle cifre e l'ordine bidirezionale è noto, ad esempio a causa del layout della tastiera usato per immettere il carattere, chiamare ScriptItemize. Nella chiamata specificare puntatori Null per le strutture SCRIPT_CONTROL e SCRIPT_STATE. Questa tecnica genera elementi usando solo il motore di data shaping e gli elementi possono essere riordinati usando le informazioni del motore.

    Nota

    In genere, le applicazioni che funzionano solo con script da sinistra a destra e senza alcuna sostituzione di cifre devono passare puntatori Null per le strutture SCRIPT_CONTROL e SCRIPT_STATE.

     

  5. Unire le informazioni sull'elemento con le informazioni di esecuzione per produrre intervalli.

  6. Chiamare ScriptShape per identificare i cluster e generare glifi.

  7. Se ScriptShape restituisce il codice USP_E_SCRIPT_NOT_IN_FONT o S_OK con l'output contenente glifi mancanti, selezionare i caratteri da un tipo di carattere diverso. Sostituire un altro tipo di carattere o disabilitare la forma impostando il membro eScript della struttura SCRIPT_ANALYSIS passata a ScriptShape su SCRIPT_UNDEFINED. Per altre informazioni, vedere Uso del fallback dei tipi di carattere.

  8. Chiamare ScriptPlace per generare larghezze avanzate e posizioni x e y per i glifi in ogni intervallo successivo. Questo è il primo passaggio per cui le dimensioni del testo diventano una considerazione.

  9. Sommare le dimensioni dell'intervallo fino all'overflow della riga.

  10. Interrompere l'intervallo su un limite di parola usando i membri fSoftBreak e fWhiteSpace negli attributi logici. Per interrompere l'esecuzione di un singolo cluster di caratteri, usare le informazioni restituite chiamando ScriptBreak.

    Nota

    Decidere se il primo punto di codice di un intervallo deve essere un punto di interruzione di parola perché l'ultimo carattere dell'intervallo precedente lo richiede. Ad esempio, se un intervallo termina in una virgola, considerare il primo carattere dell'intervallo successivo come punto di interruzione di parola.

     

  11. Ripetere i passaggi da 6 a 10 per ogni riga del paragrafo. Tuttavia, se si interrompe l'ultima esecuzione della riga, chiamare ScriptShape per modellare la parte rimanente dell'esecuzione come prima esecuzione nella riga successiva.

Visualizzare testo con Uniscribe

L'applicazione può usare la procedura seguente per visualizzare un paragrafo di testo. Questa procedura presuppone che l'applicazione abbia già disposto il testo e non abbia salvato i glifi e le posizioni dal processo di layout. Se la velocità è un problema, l'applicazione può salvare i glifi e le posizioni dalla procedura di layout e iniziare al passaggio 2 nella procedura di visualizzazione.

Nota

L'applicazione può omettere il passaggio 2 se il testo non contiene caratteri dagli script da destra a sinistra, non contiene caratteri di controllo bidirezionali e usa un livello di incorporamento da sinistra a destra.

 

  1. Per ogni esecuzione, eseguire le operazioni seguenti:

    1. Se lo stile è cambiato dall'ultima esecuzione, aggiornare l'handle al contesto di dispositivo rilasciandolo e recuperandolo nuovamente.
    2. Chiamare ScriptShape per generare glifi per l'esecuzione.
    3. Chiamare ScriptPlace per generare una larghezza avanzata e un offset x,y per ogni glifo.
  2. Eseguire le operazioni seguenti per stabilire l'ordine di visualizzazione corretto per le esecuzioni nella riga:

    1. Estrarre una matrice di livelli di incorporamento bidirezionale, uno per intervallo. Il livello di incorporamento viene assegnato dal si (SCRIPT_ITEM). (SCRIPT_ANALYSIS) a. (SCRIPT_STATE) s.uBidiLevel.
    2. Passare questa matrice a ScriptLayout per generare una mappa delle posizioni visive alle posizioni logiche.
  3. (Facoltativo) Per giustificare il testo, chiamare ScriptJustify o usare conoscenze specializzate del testo.

  4. Usare la mappa da visualizzazione a logica per visualizzare le esecuzioni nell'ordine visivo. A partire dall'estremità sinistra della riga, chiamare ScriptTextOut per visualizzare l'esecuzione specificata dalla prima voce della mappa. Per ogni voce successiva della mappa, chiamare ScriptTextOut per visualizzare l'esecuzione indicata a destra dell'esecuzione visualizzata in precedenza.

    Se omette il passaggio 2, iniziare alla fine sinistra della riga e chiamare ScriptTextOut per visualizzare la prima esecuzione logica e quindi visualizzare ogni esecuzione logica a destra dell'esecuzione precedente.

  5. Ripetere i passaggi precedenti per tutte le righe del paragrafo.

Uso di Uniscribe