共用方式為


使用 Uniscribe 顯示文字

您的應用程式可以使用 Uniscribe API 函式來支援印刷樣式和國際文字的顯示和編輯。 Uniscribe 會使用段落做為文字顯示的單位,而且必須針對整個段落使用 Uniscribe 功能。

使用 Uniscribe 來顯示文字時,應用程式必須經歷格式設定 (「layout」) 程式,通常是使用 Uniscribe。 應用程式會將文欄位落分割成具有相同樣式的字元字串,稱為「執行」。 樣式是由特定實作所決定,但通常包含字型、大小和色彩等屬性。 在定義執行時,應用程式也可以套用其他資訊,例如維護的語言和地區設定資料,以搭配語彙工具使用。 例如,應用程式可能會將它視為主要英文文字中以法文轉譯的個別段落。

一旦判斷所有段落的執行,應用程式會將每個段落分割成具有相同腳本和方向的字串(「items」)。 應用程式會套用專案資訊來產生在腳本和方向上唯一的執行,而且完全落在單一專案(「ranges」 中)。

將專案分解為範圍有點任意,不過範圍應該包含一或多個連續的腳本定義、不可見的字元群組,稱為「叢集」。針對歐洲語言,叢集通常對應至單一字碼頁字元或 Unicode 字碼點,並包含單 一圖像 。 不過,在泰文等語言中,叢集是字元群組,並對應至多個連續字元或字碼點。 例如,泰文叢集可能包含同音、母音和音調標記。 因此,它不會中斷叢集,應用程式通常應該使用它可以使用最長的範圍,或使用它自己的語彙資訊,在不在叢集中間的位置之間中斷範圍。

當它識別出每個範圍的叢集時,應用程式必須判斷每個叢集的大小。 它會使用 Uniscribe 來加總叢集,以判斷每個範圍的大小。 然後,應用程式會加總範圍的大小,直到它們溢位一行,也就是到達邊界為止。 溢位行的範圍會分割在目前行和下一行之間。 針對每一行,應用程式會建置從視覺位置到每個範圍的邏輯位置的對應。 然後,應用程式會將每個範圍的字碼點塑造成圖像,以便後續放置和轉譯。

應用程式只會執行文字配置一次。 之後,它會儲存圖像和位置以供顯示用途,或每次顯示文字時產生圖像和位置,取捨速度與記憶體。 一般應用程式會實作配置程式一次,然後在每次顯示文字時產生圖像和位置。

使用 複雜字集 的應用程式在配置和顯示方式簡單時發生下列問題。

  • 複雜字集字元的寬度取決於其內容。 無法將寬度儲存在簡單資料表中。
  • 在泰文等腳本中斷字需要字典支援。 例如,泰文單字之間不會使用分隔符號。
  • 阿拉伯文、希伯來文、波斯文、烏爾都文和其他 雙向文字 語言需要重新排列,才能顯示。
  • 通常需要某種形式的字型關聯,才能輕鬆地使用複雜的腳本。

Uniscribe 使用段落做為顯示單位的事實,可協助應用程式適當地處理這些複雜的腳本問題。

注意

即使段落的區段不是複雜的腳本,Uniscribe 也必須用於整個段落。

 

如下表所示,Uniscribe 1.6 版或更新版本支援數個利用 OpenType 標籤的函式。 這些函式可以替代對應的一般 Uniscribe 函式。 一般而言,您的應用程式應該與一組或另一組的函式完全搭配運作,而且不應該嘗試「混合和比對」函式。

一般 Uniscribe 函式 對等的 OpenType 函式
ScriptItemize ScriptItemizeOpenType
ScriptShape ScriptShapeOpenType
ScriptPlace ScriptPlaceOpenType

 

使用 Uniscribe 配置文字

您的應用程式可以使用下列步驟來配置文欄位落與 Uniscribe。 此程式假設應用程式已將段落分割成執行。

  1. 只有在啟動或收到 WM_SETTINGCHANGE 訊息時,才呼叫 ScriptRecordDigitSubstitution。

  2. (選擇性)呼叫 ScriptIsComplex 以判斷段落是否需要複雜的處理。

  3. (選擇性)如果使用 Uniscribe 來處理雙向文字和/或數位替代,請呼叫 ScriptApplyDigitSubstitution 來準備 SCRIPT_CONTROL ,並將 SCRIPT_STATE 結構作為 ScriptItemize 輸入。 如果略過此步驟,但仍需要數位替代,請以 Unicode U+0030 到 U+0039(歐洲數位)取代國家/地區數位。 如需數位替代的相關資訊,請參閱 數位圖形

  4. 呼叫 ScriptItemize ,將段落分割成專案。 例如,如果沒有使用 Uniscribe 進行數位替代,而且雙向順序已知,因為用來輸入字元的鍵盤配置,請呼叫 ScriptItemize 。 在 呼叫中,為SCRIPT_CONTROL SCRIPT_STATE 結構提供 null 指標。 這項技術只會使用成形引擎來產生專案,而且專案可以使用引擎資訊重新排序。

    注意

    一般而言,只使用由左至右腳本且沒有任何數位替代的應用程式,應該傳遞SCRIPT_CONTROL SCRIPT_STATE 結構的 Null 指標。

     

  5. 將專案資訊與執行資訊合併以產生範圍。

  6. 呼叫 ScriptShape 以識別叢集並產生圖像。

  7. 如果 ScriptShape 傳回程序代碼USP_E_SCRIPT_NOT_IN_FONT或S_OK包含遺漏字元的輸出,請從不同的字型中選取字元。 藉由將傳遞至 ScriptShape SCRIPT_ANALYSIS 結構的 eScript 成員設定 SCRIPT_UNDEFINED,以替代另一個字型或停用成形。 如需詳細資訊,請參閱 使用字型後援

  8. 呼叫 ScriptPlace 以針對每個連續範圍中的字元產生 進階寬度 和 x 和 y 位置。 這是文字大小成為考慮的第一個步驟。

  9. 將範圍大小加總,直到行溢位為止。

  10. 使用邏輯屬性中的 fSoftBreak fWhiteSpace 成員, 中斷字邊界上的範圍。 若要中斷執行中的單一字元叢集,請使用呼叫 ScriptBreak 傳回的資訊。

    注意

    決定範圍的第一個字碼點是否應該是斷詞點,因為前一個範圍的最後一個字元需要它。 例如,如果某個範圍以逗號結尾,請將下一個範圍的第一個字元視為中斷點。

     

  11. 針對段落中的每個行重複步驟 6 到 10。 不過,如果中斷該行的最後一次執行,請呼叫 ScriptShape ,以重新調整執行剩餘部分,做為下一行的第一個執行。

使用 Uniscribe 顯示文字

您的應用程式可以使用下列步驟來顯示文欄位落。 此程式假設應用程式已配置文字,且未從版面配置程式儲存字元和位置。 如果速度是個問題,應用程式可以從版面配置程式儲存圖像和位置,並從顯示程式中的步驟 2 開始。

注意

如果文字不含從右至左腳本的字元、不包含雙向控制字元,並使用由左至右的基底內嵌層級,則應用程式可以省略步驟 2。

 

  1. 針對每個回合,執行下列動作:

    1. 如果樣式自上次執行後已變更,請釋放並再次取得它,以更新裝置內容的控制碼。
    2. 呼叫 ScriptShape 以產生執行圖像。
    3. 呼叫 ScriptPlace 來產生每個圖像的進階寬度和 x,y 位移。
  2. 執行下列動作,以建立行中執行的正確視覺順序:

    1. 擷取雙向 內嵌層級 的陣列,每個範圍各一個。 內嵌層級是由 (SCRIPT_ITEM) si 提供。(SCRIPT_ANALYSIS) a. (SCRIPT_STATE) uBidiLevel.
    2. 將此陣列傳遞至 ScriptLayout ,以產生視覺位置到邏輯位置的對應。
  3. (選擇性)若要證明文字的合理性,請呼叫 ScriptJustify 或使用文字的特製化知識。

  4. 使用視覺化對邏輯對應,以視覺化順序顯示執行。 從行左端開始,呼叫 ScriptTextOut 以顯示地圖中第一個專案所指定的回合。 針對對應中的每個後續專案,呼叫 ScriptTextOut 以顯示先前顯示之執行右邊的指示執行。

    如果省略步驟 2,請從行左端開始,並呼叫 ScriptTextOut 以顯示第一個邏輯執行,然後在上一次執行右邊顯示每個邏輯執行。

  5. 針對段落中的所有行重複上述步驟。

使用 Uniscribe