Condividi tramite


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 potrebbe trattare come una sezione separata un passaggio in un testo principalmente in inglese che è reso 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 utilizza le informazioni sugli elementi per produrre serie univoche per script e direzione che rientrano completamente in 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. La porzione che supera la riga è divisa 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 scritture come il Thai richiede il supporto del dizionario. Ad esempio, non viene usato alcun carattere separatore tra le parole thai.
  • Arabo, Ebraico, Persiano, Urdu e altri testo bidirezionale lingue 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 regolare di Uniscribe 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 segmenti.

  1. Chiamare ScriptRecordDigitSubstitution solo quando si avvia o si riceve un messaggio di WM_SETTINGCHANGE.

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

  3. (Facoltativo) Se si usa Uniscribe per gestire la sostituzione di testo bidirezionale e/o di cifre, chiamare ScriptApplyDigitSubstitution per preparare le strutture SCRIPT_CONTROL e SCRIPT_STATE come input per ScriptItemize. Se si salta questo passaggio ma è ancora necessaria la sostituzione delle cifre, sostituire con le cifre nazionali quelle per Unicode da U+0030 a U+0039 (cifre europee). Per informazioni sulla sostituzione delle cifre, vedere 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 modellazione 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 nulli 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 caratteri da un tipo di carattere diverso. Sostituire il tipo di carattere con un altro o disabilitare lo shaping impostando il membro eScript della struttura SCRIPT_ANALYSIS passato a ScriptShape su SCRIPT_UNDEFINED. Per altre informazioni, vedere Using Font Fallback.

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

  9. Somma le dimensioni dell'intervallo fino al sovraccarico della riga.

  10. Spezza l'intervallo su un confine 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 utilizza un livello di incorporazione con base da sinistra a destra.

 

  1. Per ogni corsa, 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. Seguire i passaggi seguenti per stabilire l'ordine di visualizzazione corretto per i segmenti nella riga:

    1. Estrarre una matrice di livelli di incorporamento bidirezionali , uno per intervallo. Il livello di incorporamento è determinato da (SCRIPT_ITEM) si. (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 visuale-logica per visualizzare le sequenze 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 nella mappa, chiamare ScriptTextOut per visualizzare l'esecuzione indicata a destra dell'esecuzione visualizzata in precedenza.

    Se si omette il passaggio 2, iniziare dall'estremità sinistra della riga e chiamare ScriptTextOut per visualizzare la prima esecuzione logica e quindi visualizzare ogni esecuzione logica a destra dell'esecuzione successiva.

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

Utilizzo di Uniscribe