国际语言环境指南

第 6 章 复杂文本布局

复杂文本布局 (CTL) 扩展使 Motif 的 API 能支持需要在逻辑文本表示和物理文本表示之间进行复杂转换的书写系统。阿拉伯语、希伯来语和泰语需要上述转换。CTL Motif 提供字符成形(如连写符、变音符号和段排序)功能。还提供静态和动态文本小部件转换支持,以及对动态文本小部件的双向文本和制表功能的支持。由于文本绘制是通过绘制层处理的,因此可以很容易地扩展其他小部件库以支持 CTL。

本章包含以下主题:

CTL 技术概述

要利用新功能,用户必须拥有可移植布局服务 (PLS) 库和适当的语言引擎。CTL 使用 PLS 作为语言引擎界面,并使用语言引擎转换文本,然后才能绘制文本。支持 CTL 的应用程序必须包含附加的资源,请见 CTL 文档中的说明。

特别地,XomCTL 支持基础语言环境相关的 PLS 模块转换提供的下列复杂符成形和重新排列功能:

CTL 体系结构概述

CTL 体系结构的组织如图 6–1 所示。栈顶部的 Dt Apps 使用 Motif CTL 功能来绘制文本。而 Motif 则使用 PLS 与特定语言环境的语言引擎交互,并执行变换以支持位置变化、数字成形等等。

CTL 体系结构使用特定于语言环境的引擎支持新语言。换句话说,无须改变 Motif 或 Dt Apps 即可添加对泰语和越南语的支持。

图 6–1 CTL 体系结构

上文介绍了此图形。

对基于 X 库的应用程序的 CTL 支持

XomCTL(X 库输出模块中的复杂文本布局支持)允许所有的纯粹 X Windows 应用程序(如基于 X 的终端仿真器)具有 CTL 支持。XomCTL 提供了包括 X11 哑字体支持在内的具有所有功能的 Open Source XI18N 实现。

XOC 资源

当前 Solaris 环境中提供下列 XOC 资源:

XNText

使用户能够设置需要在其中执行 CTL 操作的文本缓冲区

XNTextLayoutNumGlyphs

为文本缓冲区中的文本提供字型数目

XNTextLayoutModifier

与 XmNLayoutModifier 或 Motif 相同

XNTextLayoutProperty

与 PLS 特性相同(输入至输出和输出至输入)

XNTextLayoutMapInpToOut

与 PLS 特性相同(输入至输出和输出至输入)

XNTextLayoutMapOutToInp

与 PLS 特性相同(输入至输出和输出至输入)

这些资源的说明可以从 X/Open 或 PLS 可移植布局服务的规范中获得。

支持 CTL 技术的 Motif 更改

下列 Motif 更改支持 CTL 技术。

XmNlayoutDirection

控制对象布局

XmStringDirection

指定系统显示字符串中字符的方向

XmRendition

将新的伪资源添加到 XmRendition

XmTextXmTextField

影响与 XmRendition 关联的文本的布局行为

XmTextFieldGetLayoutModifier

返回绘制布局对象的布局修饰符字符串

XmTextGetLayoutModifier

返回与小部件关联的绘制的当前布局对象设置的值

XmTextFieldSetLayoutModifier

设置与其绘制关联的布局对象的布局修饰符值

XmTextSetLayoutModifier

修改与小部件关联的绘制的布局对象设置

XmStringDirectionCreate

创建复合字符串

XmNlayoutDirection 资源

XmNlayoutDirection 资源控制对象布局。此资源以如下所示的方式同 LayoutObject 的定向值进行交互。

有关 XmNlayoutDirection 的概述,尤其是对 XmStringDirectionXmNlayoutDirection 之间交互的说明,请参见 Motif《程序员指南》(2.1 版 )的 11.3 节。

确定布局方向

如果将 XmNlayoutDirection 指定为 XmDEFAULT_DIRECTION,则小部件的布局方向在创建时从主导伪 XOC 中进行设置。对于动态文本(XmTextXmTextField),则主导伪 XOC 是与用于小部件的 XmRendition 关联的伪 XOC。对于静态文本(XmListXmLabelXmLabelG),则布局方向从指定方向的第一个复合字符串组件中设置。此规范以下列两种方式之一发生:

如果未将 XmNlayoutDirection 指定为 XmDEFAULT_DIRECTION,并且未在布局修饰符字符串中显式指定 XmNlayoutModifier @ls orientation值,则 XmNlayoutDirection 值将传递到 XOC 及其 LayoutObject

如果同时显式指定了 XmNlayoutDirectionXmNlayoutModifier@ls orientation 值,则行为将混合在一起。XmNlayoutDirection 控制小部件对象布局,而 XmNlayoutModifier @ls orientation 值控制布局变换。

请参见《CAE 规范:可移植布局服务:依赖于上下文的定向文本》(开放组:1997 年 2 月;ISBN 1-85912-142-X;文档号码 C616),了解对于处理依赖于上下文的双向文本转换的可移植功能的描述,这些功能是对现有 POSIX 语言环境模型的逻辑扩展。该文档适用于希望为复杂文本语言提供支持的系统和应用程序程序员。

XmStringDirection 资源

XmStringDirection 是用于指定系统显示字符串中字符方向的数据类型。

XmNlayoutDirection 资源为任何没有指定字符串方向的组件的复合字符串 (XmString) 设置缺省绘制方向。因此,要设置布局方向,需要为 XmNlayoutDirection 资源设置适当的值。不需要创建具有特定方向组件的复合字符串。当应用程序绘制 XmString 时,此应用程序应检查所创建的字符串是否具有显式方向 (XmStringDirection)。如果没有方向组件,应用程序应检查当前小部件的 XmNlayoutDirection 资源的值并使用此值作为 XmString 的缺省绘制方向。

XmRendition 资源

CTL 将下表中列出的新的伪资源添加到 XmRendition 中。表之后是对伪资源的描述。

表 6–1 XmRendition 中的新资源

名称 

类/类型 

存取 

缺省值 

XmNfontType

XmCFontType/XmFontType

CSG 

XmAS_IS

XmNlayoutAttrObject

XmClayoutAttrObject/String

CG 

NULL

XmNlayoutModifier

XmClayoutModifier/String

CSG 

NULL

XmNfontType

指定“绘制”字体对象的类型。对于 CTL,此资源的值必须是 XmFONT_IS_XOC 值。如果此值不匹配,则忽略 XmNlayoutAttrObjectXmNlayoutModifier 资源。

如果此资源的值为 XmFont_IS_XOC 且未指定 XmNfont 资源,则 XmNfontName 资源的值在创建时在 XmNlayoutAttrObject 资源指定的语言环境或当前语言环境中转换为 XOC 对象。此外,XmNlayoutModifier 资源的值被传递给与此 XOC 关联的任何布局对象。

XmNlayoutAttrObject

指定布局 AttrObject 参数。此资源用于创建与此 XOC(它与此 XmRendition 关联)关联的布局对象。有关此字符串的语法和语义,请参考布局服务 m_create_layout() 规范。有关“布局修饰符定向”输出值和 XmNlayoutDirection 小部件资源间交互作用的说明,请参见 XmNfontType 的描述。

XmNlayoutModifier

指定要传递给与此 XmRendition 的 XOC 一起使用的布局对象的布局值。有关该字符串的语法和语义,请参见《CAE 规范》。

使用 XmRendition{Retrieve,Update} 设置此资源会导致字符串传递给与此绘制的关联 XOC 关联的布局对象。该机制使您能动态配置布局服务。如果 OrientationContextTypeOfTextTextShapingShapeCharset 发生更改,则可能导致不可预测的行为。

附加布局行为

XmNlayoutModifier 影响与 XmRendition 关联的文本的布局行为。例如,如果数字的缺省布局处理是 NUMERALS_NOMINAL,则可以通过将 XmNlayoutModifier 设置为 @ls numerals=nominal:national@ls numerals=:national 而更改为 NUMERALS_NATIONAL

布局值可分为下列几个组:

XmTextXmTextField 资源

Xm CTL 扩展了 XmTextXmTextField,方法是模仿 Motif 2.0 CSText 小部件,添加一组以可视方式运行的相似的移动和删除操作。标准 Motif 2.1 TextTextField 不区分逻辑和物理顺序:下一个向前意为“向右”,而上一个向后意为“向左”。然而,CSText 进行了适当的区分并定义了一组具有严格物理名称的新操作(例如,left-character ()delete-right-word() 等等)。这些操作例程均被定义为对小部件的 XmNlayoutDirection 敏感,并可调用适当的 next-previous- 操作。

Xm CTL 扩展比 CSText 扩展稍微复杂一些。Xm CTL 扩展对小部件的全局定向不敏感,但是对伪 XOC 所确定的光标周围物理字符的特定方向性(包括中性稳定性)敏感。

新资源名称使您能控制选择策略,提供绘制标签及控制对齐方式。

新 Xm CTL 操作集合大致是 {Move,Delete,Kill} 乘以 {Left,Right} 乘以 {Character,Word} 的向量积。下表中列出操作集。

表 6–2 Xm CTL 中的新资源

姓名 

类/类型 

存取 

缺省值 

XmNrenditionTag

XmCRenditionTag/XmRString

CSG 

XmFONTLIST_DEFAULT_TAG

XmNalignment

XmCAlignment/XmRAlignment

CSG 

XmALIGNMENT_BEGINNING

XmNeditPolicy

XmCEditPolicy/XmREditPolicy

CSG 

XmEDIT_LOGICAL

XmNrenditionTag

指定位于 XmNrenderTable 资源(用于小部件)中的 XmRendition 的绘制标签。

XmNalignment

指定此小部件中使用的文本对齐方式。仅支持 XmALIGNMENT_ENDXmALIGNMENT_CENTER

XmNeditPolicy

指定此小部件使用的编辑策略(XmEDIT_LOGICALXmEDIT_VISUAL)。如果指定 XmEDIT_VISUAL ,则选择、光标移动和删除将以可视形式进行。设置该资源还可将标准键盘移动和删除事件的转换更改为新的“可视”操作列表或现有的逻辑操作。

字符定向操作例程

forward-cell()backward-cell() 操作在指定的方向中查询字符的定向。如方向是从左向右,则这些操作调用相应的 next-/forward-previous-/backward- 变式。

字符定向附加行为

这些操作通过使用布局服务变换 OutToInpProperty 缓冲区(对于嵌套级)来确定字符的方向。因而,小部件的行为取决于语言环境的特定变换。如果 OutToInp(尤其是 Property 缓冲区)中的信息不正确,则小部件可能会产生意外行为。此外,由于语言环境特定的模块处于该规范的范围之外,相同文本、应用程序、资源值和 LayoutObject 配置的双向编辑行为可能因平台的不同而不同。

可视模式操作导致显示基于单元的行为。逻辑模式操作导致基于字符的逻辑行为。例如,delete-right-character() 操作删除与显示单元相对应的输入缓冲区字符。即一个 LayoutObject 变换“特性”字节“新单元指示器”为 1 的输入缓冲区字符,以及“新单元指示器”为 0 的所有后继字符。

有关 Property 缓冲区的更多信息,请参见《CAE 规范》中的 m_transform_layout()

同样,对于 backward-character(),插入点在输入缓冲区中向后移动一个字符,光标被在与关联的输出缓冲区字符相对应的可视位置重新绘制。因而,要进行若干次击键以在复合显示单元中移动。当插入点在“新单元指示器”为 0 的输入缓冲区字符(即音调符号或连字片段)中移动时,光标并不实际更改显示位置。

此行为意味着删除操作或者从逻辑/输入缓冲区端执行,或者从物理/输出端的显示单元级执行。没有严格的、物理的逐字符删除模式,因为在输入和输出缓冲区之间不存在一对一的对应关系。例如,给定的物理字符只能代表逻辑字符片断。

XmText 操作例程

下表描述 XmText 操作例程。

left-character(extend)

如果 XmNeditPolicyXmEDIT_LOGICAL 且被不带参数调用,则插入光标在逻辑上向后移动一个字符。如果插入光标位于行首,则它将移动到上一行(如果存在)的最后一个逻辑字符。否则,插入光标位置不变。

如果 XmNeditPolicyXmEDIT_VISUAL,则光标移动到光标位置的左侧。如果插入光标位于行首,则它将移动到上一行(如果存在)的结尾字符。

如果使用 extend 参数调用 left-character(),则插入光标将像没有参数时一样移动,并扩展当前所选内容。

left-character() 操作使用原因值 XmCR_MOVING_INSERT_CURSOR 生成对 XmNmotionVerifyCallback 过程的调用。如果使用 extend 参数进行调用,则此操作可以生成对 XmNgainPrimaryCallback 过程的调用。有关更多信息,请参见《Motif 程序员参考》中的回调说明。

right-character(extend)

如果 XmNeditPolicyXmEDIT_LOGICAL 且不被带参数调用,则它将插入光标逻辑地向前移动一个字符。如果插入光标位于行的逻辑结尾处,则此操作将插入光标移动到下一行(如果存在)的逻辑开始处。

如果 XmNeditPolicyXmEDIT_VISUAL,则光标移动到该光标位置的右侧。如果插入光标位于行尾,则它将插入光标移动到下一行(如果存在)的开始处。

如果使用 extend 参数进行调用,则 XmNeditPolicy 将像不带参数调用一样移动插入光标,并扩展当前所选内容。

right-character() 操作使用原因值 XmCR_MOVING_INSERT_CURSOR 生成对 XmNmotionVerifyCallback 过程的调用。如果使用 extend 参数进行调用,则此操作可以生成对 XmNgainPrimaryCallback 过程的调用。有关更多信息,请参见《Motif 程序员参考》中的回调说明。

right-word(extend)

如果 XmNeditPolicyXmEDIT_LOGICAL 且被不带任何参数调用,则插入光标移动到逻辑后继字(如果存在)的逻辑开始处。否则,此光标移动到当前字的逻辑结尾处。如果插入光标位于行的逻辑结尾处或此行的最后一个逻辑字,则光标移动到下一行(如果存在)的第一个逻辑字;否则,光标移动到当前字的逻辑结尾处。

如果 XmNeditPolicyXmEDIT_VISUAL 且被不带参数调用,则插入光标移动到行尾右侧或后面的第一个空格字符后的第一个非空格字符处。

如果使用 extend 参数进行调用,则就像不带参数调用一样移动插入光标,并扩展当前所选内容。

left-word() 操作使用原因值 XmCR_MOVING_INSERT_CURSOR 生成对 XmNmotionVerifyCallback 过程的调用。如果使用 extend 参数调用,则此操作可以生成对 XmNgainPrimaryCallback 过程的调用。有关更多信息,请参见《 Motif 程序员参考》中的回调说明。

delete-left-character()

如果 XmNeditPolicyXmEDIT_LOGICAL,则它等效于 delete-previous-char()。如果 XmNeditPolicyXmEDIT_VISUAL,则在正常模式下,如果有一个非空选择,则它将删除此选择。否则,此操作删除插入光标左侧的字符。在添加模式下,如果有一个非空选择,光标未离开所选内容,并且 XmNpendingDelete 设置为真,则此操作删除此选择。否则,此操作删除插入光标左侧的字符,这可能会影响选择。

delete-left-character() 操作使用原因值 XmCR_MODIFYING_TEXT_VALUE 生成对 XmNmodifyVerifyCallback 过程的调用,并且使用原因值 XmCR_VALUE_CHANGED 生成对 XmNvalueChangedCallback 过程的调用。

delete-right-character()

如果 XmNeditPolicyXmEDIT_VISUAL,则它等效于 delete-next-character()。如果 XmNeditPolicyXmEDIT_VISUAL,则在正常模式下,如果有一个非空选择,则它删除此选择。否则,它删除插入光标右侧的字符。在添加模式中,如果有一个非空选择,并且光标未离开所选内容,则将 XmNpendingDelete 设置为真,并删除此选择;否则,删除插入光标右侧的字符。此操可能会对选择造成影响。

delete-right-character() 操作使用原因值 XmCR_MODIFYING_TEXT_VALUE 生成对 XmNmodifyVerify-Callback 过程的调用,并且使用原因值 XmCR_VALUE_CHANGED 生成对 XmNvalue-ChangedCallback 过程的调用。

实现了一些基于单元的例程以支持字符组合、连字和音调符号。换句话说,两个或多个字符可以被占用一个表示单元的单个字形表示。

XmText 单元操作例程如下表所示。

backward-cell(extend)

将插入光标向后移动一个单元。如果 XmNeditPolicyXmEDIT_LOGICAL,则插入光标移动到逻辑上位于当前单元之前的那个单元(如果存在)的开始处。否则,光标移动到当前单元的开始处。

如果 XmNeditPolicyXmEDIT_VISUAL,则光标移动到光标左侧单元(如果存在)的开始处。prev-cell() 操作使用原因值 XmCR_MOVING_INSERT_CURSOR 生成对 XmNmotionVerifyCallback 过程的调用。如果使用 extend 参数进行调用,则此操作可以生成对 XmNgainPrimaryCallback 过程的调用。有关更多信息,请参阅《Motif 程序员参考》中的回调说明。

forward-cell(extend)

将插入光标移动到下一个逻辑单元(如果存在)的开始处。否则,此操作将光标移动到此单元的结尾处。如果 XmNeditPolicyXmEDIT_LOGICAL,则光标向前移动一个单元。

如果 XmNeditPolicyXmEDIT_VISUAL,则光标移动到此光标位置右侧单元的开始处(如果此单元存在);否则,光标移动到当前单元的结尾处。forward-cell() 操作使用原因值 XmCR_MOVING_INSERT_CURSOR 生成对 XmNmotionVerifyCallback 过程的调用。如果使用 extend 参数进行调用,则此操作可以生成对 XmNgainPrimaryCallback 过程的调用。有关更多信息,请参阅《Motif 程序员参考》中的回调说明。

XmTextFieldGetLayoutModifier 资源

XmTextFieldGetLayoutModifier() 返回布局修饰符字符串,它反映了与其绘制关联的布局对象的状态。

XmTextFieldGetLayoutModifier() 的语法是:

#include <Xm/TextF.h>字符串 XmTextFieldGetLayoutModifier(小部件 小部件)

XmTextFieldGetLayoutModifier() 存取与小部件关联的绘制的当前布局对象设置的值。当使用公用函数更改布局对象修饰符的值时,XmTextFieldGetLayoutModifier 函数返回布局对象的完整状态,而不仅仅返回更改后的值。

XmTextFieldGetLayoutModifier() 以字符串值的形式返回布局对象修饰符值。

XmTextGetLayoutModifier 资源

XmTextGetLayoutModifier() 返回布局修饰符字符串, 它反映了与其绘制关联的布局对象的状态。

XmTextGetLayoutModifier() 的语法是:

#include <Xm/Text.h>String XmTextGetLayoutModifier(小部件 小部件)

XmTextGetLayoutModifier 存取与小部件关联的绘制的当前布局对象设置的值。当使用公用函数更改布局对象修饰符值时, XmTextGetLayoutModifier 函数返回布局对象的完整状态,而不仅仅返回更改后的值。

XmTextGetLayoutModifier 以字符串值的形式返回布局对象修饰符值。

XmTextFieldSetLayoutModifier 资源

XmTextFieldSetLayoutModifier() 设置布局修饰符值,这会更改与其绘制关联的布局对象的行为。

XmTextFieldSetLayoutModifier() 的语法是:

#include <Xm/TextF.h> \
void XmTextFieldSetLayoutModifier(小部件 \
小部件字符串 layout_modifier)

XmTextFieldSetLayoutModifier 修改与小部件关联的绘制的布局对象设置。当布局对象修饰符值使用此公共函数设置时,只有输入参数中指定的属性被更改;其余属性保持不变。

XmTextSetLayoutModifier 资源

XmTextSetLayoutModifier() 设置布局修饰符值,这会更改与其绘制关联的布局对象的行为。

XmTextSetLayoutModifier() 的语法是:

#include <Xm/Text.h>void XmTextSetLayoutModifier(小部件 小部件,字符串 layout_modifier)

XmTextSetLayoutModifier 修改与小部件关联的绘制的布局对象设置。布局对象修饰符值使用此公共函数设置时,只有输入参数中指定的属性被更改; 其余属性保持不变。

XmStringDirectionCreate 资源

XmStringDirectionCreate 用于创建复合字符串。

XmTextSetLayoutModifier() 的语法是:

#include <Xm/Xm.h>XmString XmStringDirectionCreate(方向)XmStringDirection 方向

XmStringDirectionCreate 创建一个具有单个组件(一个具有给定值的方向)的复合字符串。另一方面,XmNlayoutDirection 资源为任何不具有指定其方向的组件的复合字符串 (XmString) 设置缺省绘制方向。因此,要设置布局方向,需要为 XmNlayoutDirection 资源设置适当值。您不需要创建具有特定方向组件的复合字符串。

当应用程序绘制 XmString 时,此应用程序应检查所创建的字符串是否具有显式方向 (XmStringDirection)。如果没有向应用程序提供方向组件,则此应用程序应检查当前小部件的 XmNlayoutDirection 资源的值并将此值作为 XmString 的缺省绘制方向。

UIL 参数

下表显示了 UIL 参数名称和类型。

表 6–3 UIL
 UIL 参数名称 参数类型

XmNlayoutAttrObject

String 

XmNlayoutModifier

String 

XmNrenditionTag

String 

XmNalignment

Integer 

XmNeditPolicy

Integer 

开发 CTL 应用程序

下列几节说明了如何开发 CTL 应用程序。

控制布局方向

复合字符串的方向被存储起来,以便使数据结构对于描述从左到右的语言(如英语、西班牙语、法语和德语)的文本或者从右到左的语言(如希伯来语和阿拉伯语)的文本同样有用。在 Motif 应用程序中,可以使用 VendorShell 或 MenuShell 中的 XmNlayoutDirection 资源来设置布局方向。管理器和原始小部件(以及小配件)也具有 XmNlayoutDirection 资源。缺省值从具有相同资源的最近的祖先继承。

如果是 XmText 小部件,则必须指定垂直方向及水平方向。将 layoutDirection 设置为 XmRIGHT_TO_LEFT 将会使字符串方向成为从右到左,而光标则垂直向下移动。如果垂直方向重要且要求从顶到底对齐,确保指定 XmRIGHT_TO_LEFT_TOP_TO_BOTTOM。本设置将组件布局首先指定为从右到左,然后从上到下,从而产生所需的行为。

XmTextTextField 小部件的行为也受 XmNalignmentXmNlayoutModifier XmRendition 资源的影响。这些资源与 XmNlayoutDirection 共同控制文本小部件的布局行为。图 6–2 中阐释了此行为。

该图中使用的输入字符串是:

下图阐释了同一行中英文字符和阿拉伯字符的双向文本布局。

下图中 XmNlayoutModifier 字符串 @ls orientation=设置值如左列中所示。

图 6–2 布局方向

此图说明从左到右文本和从右到左文本的开头与结尾对齐方式。

如插图所示,XmNalignment 规定文本是否与布局方向一起右对齐或左对齐。XmNlayoutModifier 将文本分成多段,并根据定向值将它们从左到右或从右到左排列。换句话说,如果 XmNlayoutDirectionXmRIGHT_TO_LEFT,并且 XmNAlignment 值是 XmALIGNMENT_BEGINNING,则此字符串右对齐。


实例 6–1 创建绘制

下列代码使用标记为“ArabicShaped”的“绘制”创建 XmNlabelStringXmCHARSET_TEXT 类型的 XmLabel。使用“ar”(对应于阿拉伯语言环境的语言环境名称)的 XmNlayoutAttrObject 以及布局修饰符字符串来创建“绘制”。该布局修饰符字符串为输出缓冲指定了 NUMERALS_CONTEXTUALNumerals 值和 “iso8859-6”的 ShapeCharset值。

特定于语言环境的布局模块将其输入文本转换到使用 16 位 Unicode 代码集编码的物理字符的输出缓冲区。由于已经指定了显式布局语言环境,因此此文本能够独立于运行时语言环境设置正确绘制。在此实例中,用 ISO 8859-6 对输入进行编码。

int n;
Arg args[10];
Widget w;
XmString labelString;
XmRendition rendition;
XmStringTag renditionTag;
XmRenderTable renderTable;
      /* alef lam baa noon taa - iso8859-6 */
labelString = XmStringGenerate("\307\344\310\346\312\", NULL
			                          XmCHARSET_TEXT, "ArabicShaped");
w = XtVaCreateManagedWidget("a label", xmLabelWidgetClass, parent,
                             XmNlabelString, labelString,
		                          XmNlabelType, XmSTRING,
                             NULL);
n = 0;
XtSetArg(args[n], XmNfontName, "-*-*-medium-r-normal-*-24-*-*-*-*-*-*");
      n++;
XtSetArg(args[n], XmNfontType, XmFONT_IS_XOC); n++;
XtSetArg(args[n], XmNlayoutAttrObject, "ar"); n++;
XtSetArg(args[n], XmNlayoutModifier, 
          "@ls numerals=:contextual, shapecharset=iso8859-6"); n++;
renditionTag = (XmStringTag) "ArabicShaped";
rendition = XmRenditionCreate(w, renditionTag, argcs
s, n);
renderTable = 
    XmRenderTableAddRenditions(NULL, &rendition, 1, XmREPLACE_MERGE);
XtVaSetValues(w, XmNrenderTable, renderTable, NULL);


实例 6–2 编辑绘制

下列代码使用一个 Rendition创建 TextField 小部件和 RenderTable。XmNlayoutAttrObjectXmNlayoutModifier 伪资源均未指定,因此缺省为 NULL。此值意味着与“Rendition”关联的布局对象属于缺省语言环境(如果存在)。

要使此实例正常工作,该语言环境必须设置为代码集是 ISO 8859-6,并且特定于该语言环境的布局模块可支持 IMPLICIT_BASIC 算法。Rendition 的 LayoutObjectImplicitAlg 值通过 Rendition 的 XmNlayoutModifier 伪资源进行修改。

int n;
Arg args[10];
Widget w;
	XmRendition rendition;
XmStringTag renditionTag;
XmRenderTable renderTable;
w = XmCreateTextField(parent, "text field", args, 0);
n = 0;
	XtSetArg(args[n], XmNfontName, "-*-*-medium-r-normal-*-24-*-*-*-*-*-*-*");
     n++;
	XtSetArg(args[n], XmNfontType, XmFONT_IS_XOC); n++;
renditionTag = (XmStringTag) "ArabicShaped";
rendition = XmRenditionCreate(w, renditionTag, args, n);
renderTable = 
    XmRenderTableAddRenditions(NULL, &rendition, 1, XmREPLACE_MERGE);
XtVaSetValues(w, XmNrenderTable, renderTable, NULL);
	....
n = 0;
XtSetArg(args[n], XmNlayoutModifier, "@ls implicitalg=basic");
     n++;
XmRenditionUpdate(rendition, args, n);

在资源文件中创建绘制表

对于正确国际化的应用程序,应在其资源文件中指定 Rendition 和绘制表。在文件中指定了绘制表后,程序二进制代码就与给定语言环境的特定需要无关,从而能够轻松地进行定制以满足本地需要。

绘制表是用以下语法在资源文件中指定的:resource_spec:[tag[,tag]*]

其中 tag 是适用于某个绘制的 XmNtag 资源的某个字符串。

该行将按指定要求创建包含一个或多个绘制的初始绘制表。这些绘制被附加到指定的标记上:

resource_spec[*|.] rendition[*|.]resource_name:value

下例阐释了与 XmRendition 相关的 CTL 资源,这些资源可用资源文件来设置。fontType 必须设置为 FONT_IS_XOC 才能使布局对象生效。使用 @ls 指定的 layoutModifier 通过绘制对象传递给布局对象。

有关在布局对象中可以使用 layoutModifier 设置的资源的完整列表,请参见《CAE 规范:可移植布局服务:依赖于上下文的定向文本》。开放组:1997 年 2 月;ISBN 1-85912-142-X;文档号码 C616。


实例 6–3 在应用程序中创建绘制表

在创建绘制表之前,应用程序必须至少先创建一个属于该表的绘制。顾名思义, XmRenderTableAddRenditions() 函数还用于用新的绘制来增大绘制表。要创建新的绘制表,请使用 NULL 参数调用 XmRenderTableAddRenditions() 函数来替换现有的绘制表。

下列代码使用在将 XmNfontType 设置为 XmFONT_IS_XOC 时创建的绘制来创建一个绘制表。

int n;
Arg args[10];
Widget w;
XmString labelString;
XmRendition rendition;
XmStringTag renditionTag;
XmRenderTable renderTable;
      /* alef lam baa noon taa - iso8859-6 */
labelString = XmStringGenerate("\307\344\310\346\312\", NULL
			                           XmCHARSET_TEXT, "ArabicShaped");
w = XtVaCreateManagedWidget("a label", xmLabelWidgetClass, parent,
                            XmNlabelString, labelString,
		                         XmNlabelType, XmSTRING,
                            NULL);
n = 0;
XtSetArg(args[n], XmNfontName, "-*-*-medium-r-normal-*-24-*-*-*-*-*-*-*");
     n++;
XtSetArg(args[n], XmNfontType, XmFONT_IS_XOC); n++;
XtSetArg(args[n], XmNlayoutAttrObject, "ar"); n++;
XtSetArg(args[n], XmNlayoutModifier, 
          "@ls numerals=nominal:contextual, shapecharset=iso8859-6"); n++;
renditionTag = (XmStringTag) "ArabicShaped";
rendition = XmRenditionCreate(w, renditionTag, args, n);
renderTable = 
    XmRenderTableAddRenditions(NULL, &rendition, 1, XmREPLACE);
XtVaSetValues(w, XmNrenderTable, renderTable, NULL);

水平制表符

复合字符串可以包含控制文本位置的制表符字符。要在显示时解释这些字符,小部件实际上为复合字符串引用该绘制的制表停止位置列表。但是,动态小部件 TextFieldXmText 并不使用此绘制的制表符资源。它使用 8*(width of character 0) 公式来计算制表符的宽度。

制表符度量值是与复合字符串显示的左边界的距离。如果布局方向是从右向左的,则该距离从右边界开始度量。无论文本方向如何(阿拉伯文从右向左或英文从左向右),制表符都按布局方向(XmNlayoutDirection)的规定,向右或向左插入空格。

制表符后面的文本总是在制表停止位置处对齐。制表停止位置从小部件的起始处算起,而小部件的起始处又受到 XmNlayoutDirection 的影响。下图阐释了制表符的行为及其与文本的方向性和小部件的 XmNlayoutDirection 的交互作用。

此说明的输入是 abc\tdef\tgh

图 6–3 制表符行为

此图阐释了采用从左到右文本和从右到左文本的制表符的外观。

鼠标选定

用户主要用鼠标按钮 1 进行选择。按此按钮会取消对任何当前选择的选定,并将插入光标和锚点移到在文本中按下按钮的位置。按住鼠标按钮 1 并拖动它,可以选择锚点和指针位置之间的所有文本,并取消选定此范围外的任何文本。

选定的文本受资源 XmNeditPolicy 影响,而后者可以设置为 XmEDIT_LOGICALXmEDIT_VISUAL。如果 XmNeditPolicy 设置为 XmEDIT_LOGICAL,并且选定的文本是双向的,则选定的文本从视觉上将是不连续的,而是多个文本段的集合。逻辑缓冲区中的文本与显示内容之间没有一对一的对应关系。

因此,双向文本的逻辑字符的连续缓冲区不采用连续的字符流绘制。与此相反,如果 XmNeditPolicy 设置为 XmEDIT_VISUAL,则选定文本在视觉上可能是连续的,而在逻辑缓冲区中却是分段的。因此,在同一个光标点处按选定、删除和插入双向文本的顺序操作不会产生同一个字符串。

键盘选定

用鼠标进行的选定操作也可以使用键盘来完成。使用 Shift 和箭头键的组合选定文本。

选定的文本受资源 XmNeditPolicy 影响,而后者可设置为 XmEDIT_LOGICALXmEDIT_VISUAL。如果 XmNeditPolicy 设置为 XmEDIT_LOGICAL,并且选定的文本是双向的,则选定的文本在视觉上是不连续的。由于逻辑缓冲区中的文本与显示内容之间没有一对一的对应关系,因此双向文本中的逻辑字符的连续缓冲区不采用连续的字符流绘制。

与此相反,如果 XmNeditPolicy 设置为 XmEDIT_VISUAL,则选定的文本在视觉上可能是连续的,而在逻辑缓冲区中却是分段的。因此,在同一个光标点处按选定、删除和插入双向文本的顺序操作不会产生同一个字符串。

文本资源和几何图形

下列文本资源与几何学有关:

移植说明

为复杂文本布局 (CTL) 启用的新 Motif 库位于 /usr/dt/lib/libXm.so.4 中。如果您的应用程序链接到 libXm.so.3,则此应用程序不支持 CTL。ldd app_name 显示应用程序链接到的库。要移植现有的应用程序以启用 CTL,需要执行以下步骤:

  1. -DSUN_CTL 添加到 Makefile中。

    该标志很重要,它包括支持 CTL 所需的数据结构。此值应在编译期间进行设置。

  2. 重新编译现有的应用程序。

    此重新编译自动与启用 CTL 的 Motif 库 libXm.so.4 进行链接。

  3. XmText.translations 资源添加到应用程序资源文件中。如果没有这些资源,语言环境的布局引擎将不能启动。

  4. 请参考附加在您的文档中的应用程序样例。


注意 –

fontName 资源中使用您的语言环境中提供的并适用于您的语言环境的字体名称。


例如,如果您希望在 XmTextField XmText 小部件中进行基于单元的字符移动(泰语),请按以下方式设置相应小部件的转换:

XmText.translations: #override \n\

<Key>osfRight:forward-cell() \n\

<Key>osfLeft:backward-cell() \n\

<Key>osfDelete:delete-next-cell() \n\

<Key>osfBackSpace:delete-previous-cell() \n\