Udostępnij za pośrednictwem


Wyświetlanie tekstu za pomocą Uniscribe

Aplikacje mogą używać funkcji interfejsu API Uniscribe do obsługi typografii i wyświetlania i edytowania tekstu międzynarodowego. Uniscribe używa akapitu jako jednostki do wyświetlania tekstu, a funkcja Uniscribe musi być używana dla całego akapitu.

W przypadku używania funkcji Uniscribe do wyświetlania tekstu aplikacja musi przechodzić przez proces formatowania ("układ"), zazwyczaj przy użyciu funkcji Uniscribe. Aplikacja dzieli akapit tekstowy na ciągi znaków o tym samym stylu, nazywane "sekwencjami". Styl jest określany przez określoną implementację, ale zazwyczaj zawiera takie atrybuty jak czcionka, rozmiar i kolor. Podczas definiowania przebiegów aplikacja może również stosować inne informacje, takie jak język i dane regionalne przechowywane do użycia z narzędziami leksykalnymi. Na przykład aplikacja może traktować jako osobny fragment w tekście, który jest głównie po angielsku, a został przetłumaczony na francuski.

Po określeniu przebiegów dla wszystkich akapitów aplikacja dzieli każdy akapit na ciągi, które mają ten sam skrypt i kierunek ("elementy"). Aplikacja stosuje informacje o elemencie do generowania sekwencji, które są unikatowe pod względem skryptu i kierunku, i które mieszczą się całkowicie w jednym elemencie ("zakresy").

Podział elementu na zakresy jest nieco arbitralny, chociaż zakres powinien składać się z co najmniej jednego lub więcej kolejnych grup znaków zdefiniowanych przez skrypt, nazywanych "klastrami". W przypadku języków europejskich klaster zazwyczaj odpowiada pojedynczemu znakowi strony kodowej lub punktowi kodowemu Unicode i składa się z jednego glyph. Jednak w językach takich jak tajski, zgrupowanie jest grupowaniem glifów i odpowiada wielu kolejnym znakom lub punktom kodowym. Na przykład klaster tajski może zawierać spółgłoski, samogłoski i znak tonu. Aby nie przerywać klastrów, aplikacja zazwyczaj powinna używać najdłuższych zakresów, które może lub użyć własnych informacji leksykalnych, aby przerwać między zakresami w miejscach, które nie znajdują się w środku klastra.

Po zidentyfikowaniu klastrów w każdym zakresie aplikacja musi określić rozmiar każdego klastra. Używa metody Uniscribe do sumowania klastrów w celu określenia rozmiaru każdego zakresu. Następnie aplikacja sumuje rozmiary zakresów, aż przepełnią linię, czyli do osiągnięcia marginesu. Zakres, który przepełnia linię, jest podzielony między bieżącą linią a następnym wierszem. Dla każdego wiersza aplikacja tworzy mapę z pozycji wizualnej do pozycji logicznej dla każdego zakresu. Następnie aplikacja kształtuje punkty kodu dla każdego zakresu na glify, które można następnie umieścić i renderować.

Aplikacja wykonuje układ tekstu tylko raz. Następnie zapisuje glify i pozycje do celów wyświetlania lub generuje je za każdym razem, gdy wyświetla tekst, co wiąże się z kompromisem między szybkością a pamięcią. Typowa aplikacja implementuje procedurę układu raz, a następnie za każdym razem, gdy wyświetla tekst, generuje glify i ustala pozycje.

Aplikacja wykorzystująca złożone skrypty napotyka następujące problemy przy prostym podejściu do układu i wyświetlania.

  • Szerokość złożonego znaku skryptu zależy od jego kontekstu. Nie można zapisać szerokości w prostych tabelach.
  • Łamanie wyrazów w skryptach, takich jak tajski, wymaga wsparcia słownikowego. Na przykład żaden znak separatora nie jest używany między wyrazami tajskimi.
  • Arabski, perski, hebrajski, urdu i inne dwukierunkowe języki wymagają zmiany kolejności przed wyświetleniem.
  • Niektóre formy skojarzenia czcionek są często wymagane do łatwego korzystania ze złożonych skryptów.

Fakt, że Uniscribe używa akapitu jako jednostki wyświetlania, pomaga aplikacji odpowiednio rozwiązać te złożone problemy ze skryptami.

Notatka

Uniscribe musi być używany dla całego akapitu, nawet jeśli sekcje akapitu nie są złożonymi skryptami.

 

Jak pokazano w poniższej tabeli, uniscribe w wersji 1.6 lub nowszej obsługuje kilka funkcji korzystających z tagów OpenType. Można je zastąpić odpowiednimi regularnymi funkcjami Uniscribe. Ogólnie rzecz biorąc, aplikacje powinny działać całkowicie z funkcjami z jednego zestawu lub drugiego i nie powinny próbować "mieszać i dopasowywać" funkcji.

Regularna funkcja Uniscribe Równoważna funkcja OpenType
ScriptItemize ScriptItemizeOpenType
ScriptShape ScriptShapeOpenType
ScriptPlace ScriptPlaceOpenType

 

Układaj tekst przy użyciu Uniscribe

Twoja aplikacja może użyć poniższych kroków, aby sformatować akapit tekstowy za pomocą Uniscribe. W tej procedurze przyjęto założenie, że aplikacja podzieliła już akapit na ciągi.

  1. Wywołaj ScriptRecordDigitSubstitution tylko podczas uruchamiania lub odbierania komunikatu WM_SETTINGCHANGE.

  2. (Opcjonalnie) Wywołaj ScriptIsComplex, aby ustalić, czy akapit wymaga złożonego przetwarzania.

  3. (Opcjonalnie) Jeśli używasz funkcji Uniscribe do obsługi tekstu dwukierunkowego i/lub podstawiania cyfr, wywołaj metodę ScriptApplyDigitSubstitution, aby przygotować struktury SCRIPT_CONTROL oraz SCRIPT_STATE jako dane wejściowe dla ScriptItemize. Jeśli pominiesz ten krok, ale nadal wymagasz zastąpienia cyfr, zastąp cyfry krajowe na miejsca znaków Unicode od U+0030 do U+0039 (cyfry europejskie). Aby uzyskać informacje na temat zastępowania cyfr, zobacz Digit Shapes.

  4. Wywołaj ScriptItemize, aby podzielić akapit na elementy. Jeśli nie używasz Uniscribe do podstawienia cyfr i kolejność dwukierunkowa jest znana, na przykład z powodu układu klawiatury używanego do wprowadzania znaku, wywołaj ScriptItemize. W wywołaniu podaj wskaźniki o wartości null dla struktur SCRIPT_CONTROL i SCRIPT_STATE. Ta technika generuje elementy tylko przy użyciu silnika kształtującego, a elementy można przestawić przy użyciu informacji z silnika.

    Notatka

    Zazwyczaj aplikacje, które działają tylko z skryptami od lewej do prawej i bez podstawień cyfr, powinny przekazywać wskaźniki null dla struktur SCRIPT_CONTROL i SCRIPT_STATE.

     

  5. Połącz informacje o elemencie z informacjami o przebiegu, aby utworzyć zakresy.

  6. Wywołaj ScriptShape, aby zidentyfikować klastry i wygenerować glify.

  7. Jeśli ScriptShape zwraca kod USP_E_SCRIPT_NOT_IN_FONT lub S_OK z danymi wyjściowymi zawierającymi brakujące glify, wybierz znaki z innej czcionki. Zastąp inną czcionkę lub wyłącz kształtowanie, ustawiając element eScript struktury SCRIPT_ANALYSIS przekazany do ScriptShape na SCRIPT_UNDEFINED. Aby uzyskać więcej informacji, zobacz Using Font Fallback.

  8. Wywołaj ScriptPlace, aby wygenerować współczynniki szerokości i pozycje x oraz y dla glifów w każdym kolejnym zakresie. Jest to pierwszy krok, dla którego rozmiar tekstu staje się kwestią.

  9. Sumuj rozmiary zakresów do momentu przepełnienia linii.

  10. Przerwij zakres na granicy wyrazów przy użyciu członków fSoftBreak i fWhiteSpace w atrybutach logicznych. Aby przerwać uruchamianie klastra pojedynczego znaku, użyj informacji zwróconych przez wywołanie ScriptBreak.

    Notatka

    Zdecyduj, czy pierwszy punkt kodowy zakresu powinien być punktem łamania wyrazów, ponieważ wymaga tego ostatni znak poprzedniego zakresu. Jeśli na przykład jeden zakres kończy się przecinkiem, rozważ pierwszy znak następnego zakresu jako punkt przerwania wyrazu.

     

  11. Powtórz kroki od 6 do 10 dla każdego wiersza w akapicie. Jednak w przypadku przerwania ostatniego ciągu w wierszu wywołaj ScriptShape, aby przekształcić pozostałą część ciągu jako pierwszy ciąg w następnym wierszu.

Wyświetlanie tekstu przy użyciu Uniscribe

Aplikacja może wykonać następujące kroki, aby wyświetlić akapit tekstowy. W tej procedurze przyjęto założenie, że aplikacja określiła już tekst i nie zapisała glifów i pozycji z procesu układu. Jeśli szybkość jest problemem, aplikacja może zapisać glify i pozycje z procedury układu i rozpocząć od kroku 2 w procedurze wyświetlania.

Notatka

Aplikacja może pominąć krok 2, jeśli tekst nie zawiera żadnych znaków pochodzących ze skryptów od prawej do lewej, nie zawiera dwukierunkowych znaków sterujących i używa podstawowego poziomu osadzania od lewej do prawej.

 

  1. Dla każdego przebiegu wykonaj następujące czynności:

    1. Jeśli styl zmienił się od ostatniego uruchomienia, zaktualizuj uchwyt do kontekstu urządzenia, zwalniając go i pobierając ponownie.
    2. Wywołaj ScriptShape, aby wygenerować glyphs dla przebiegu.
    3. Wywołaj ScriptPlace aby wygenerować początkową szerokość i przesunięcie x,y dla każdego glifu.
  2. Wykonaj następujące czynności, aby ustalić poprawną kolejność wizualizacji dla przebiegów w wierszu:

    1. Wyodrębnij tablicę dwukierunkowych poziomów osadzenia , jeden na każdy zakres. Poziom osadzania jest określany przez (SCRIPT_ITEM) si. (SCRIPT_ANALYSIS) a. (SCRIPT_STATE) s.uBidiLevel.
    2. Przekaż tę tablicę do ScriptLayout, aby wygenerować mapę pozycji wizualnych do pozycji logicznych.
  3. (Opcjonalnie) Aby uzasadnić tekst, wywołaj metodę ScriptJustify lub użyj specjalistycznej wiedzy na temat tekstu.

  4. Użyj mapy wizualnej do logicznej, aby wyświetlić przebiegi w kolejności wizualnej. Począwszy od lewego końca wiersza, wywołaj metodę ScriptTextOut, aby wyświetlić przebieg podany przez pierwszy wpis na mapie. Dla każdego kolejnego wpisu na mapie wywołaj ScriptTextOut, aby wyświetlić wskazany przebieg po prawej stronie wcześniej wyświetlonego przebiegu.

    Jeśli pominięto krok 2, zacznij od lewego końca wiersza i wywołaj ScriptTextOut, aby wyświetlić pierwszy ciąg logiczny, a następnie każdy ciąg logiczny na prawo od poprzedniego.

  5. Powtórz powyższe kroki dla wszystkich wierszy w akapicie.

Używanie Uniscribe