Important: The information in this document is obsolete and should not be used for new development.
Controlling Settings
The first principal use for the Script Manager is in controlling the settings that determine the current characteristics of the text-handling environment. The Script Manager gives you access to many variables, fields, flags, and files that affect how script systems function and how text is manipulated and displayed. The routines described in this section are of general interest and are used by most text applications. You can use these Script Manager routines to
- set the system direction
- access Script Manager variables
- access script variables
- determine the keyboard script, keyboard layout, and input method
Checking and Setting the System Direction
The system direction is a global setting that is commonly used to define the primary line direction for text display. The system direction is specified by the value of the global variableSysDirection
. The value ofSysDirection
is 0 for a left-to-right primary line direction and -1 for a right-to-left primary line direction.System direction always controls the alignment (right or left) of interface elements such as menu items and dialog box items that are drawn by the system. It can also affect caret placement and the order in which blocks of text are drawn or highlighted in bidirectional script runs and in multiscript lines.
QuickDraw, TextEdit, and other parts of system software that use TextEdit set the system direction before drawing text. Although applications can format and draw text independently of the current value of system direction, applications that follow suggested procedures for text layout typically set the system direction before laying out and drawing any text. See, for example, the description of the
GetFormatOrder
function in the chapter "QuickDraw Text" in this book.The default value for
SysDirection
usually corresponds to the primary line direction of the system script; it is initialized from the system's international configuration ('itlc'
) resource at startup. The user can change the system direction from the Text control panel if a bidirectional script system is present.If your application uses
SetSysDirection
to change the system direction in order to correctly order script runs in a line of text while drawing, be sure to first callGetSysDirection
to save the original value. Then callSetSysDirection
again at the appropriate time--such as when your application becomes inactive--to restoreSysDirection
to its original value.Checking and Setting Script Manager Variables
TheGetScriptManagerVariable
andSetScriptManagerVariable
functions let you check and set the values of the Script Manager variables, general environmental settings that the Script Manager maintains for all script systems.These functions give you access to a large variety of general script-related information, including whether one or more bidirectional script systems is present, whether one or more 2-byte script systems is present, and what the states of the font force and international resources selection flags are.
You specify the variable you want to access with a selector, an integer constant that controls the function of a multipurpose routine. You pass a selector as a parameter to
GetScriptManagerVariable
orSetScriptManagerVariable
. (The variables themselves are private and you cannot access them directly.) Table 6-3 lists the selector constants and the Script Manager variables they affect. See "Selectors for Script Manager Variables" beginning on page 6-61 for complete explanations of the selectors and variables.The following code fragment shows how to use the
GetScriptManagerVariable
function to get the Script Manager version number. This is the same value as that returned by theGestalt
function using thegestaltScriptMgrVersion
selector.
VAR selectorValue: LongInt; BEGIN selectorValue := GetScriptManagerVariable(smVersion); END;TheSetScriptManagerVariable
function allows you to change many text-related settings, including
Listing 6-1 shows how to use the
- the font force flag
- the international resources selection flag
- the current keyboard script
- the Script Manager general flags, which include control of the display of the keyboard icon and the dual caret in TextEdit
- the proportion of intercharacter versus interword spacing, when laying out lines of justified text (in non-Roman script systems)
SetScriptManagerVariable
function to specify the display of a dual caret in mixed-directional text. You do this by setting the appropriate bit of the Script Manager general flags field after retrieving it with theGetScriptManagerVariable
function.Listing 6-1 Specifying a dual caret with
SetScriptManagerVariable
FUNCTION MySetDualCaret: OSErr; VAR myErr: OSErr; selectorValue: LongInt; flagValue: LongInt; BEGIN flagValue := BitShift($0001,smfDualCaret); selectorValue := GetScriptManagerVariable(smGenFlags); selectorValue := BitOr(selectorValue, flagValue); myErr := SetScriptManagerVariable(smGenFlags, selectorValue); MySetDualCaret := myErr; END;You can also useSetScriptManagerVariable
to change the settings of the font force flag and the international resources selection flag, two flags that affect which script systems are used for text display and date/time/number formatting, respectively. See "Determining Script Codes From Font Information" beginning on page 6-21.If you are using
SetScriptManagerVariable
to change the value of a variable for a specific task, first callGetScriptManagerVariable
to retrieve the variable's original value, and save that value. Then callSetScriptManagerVariable
and perform your task. Finally, restore the original value of the Script Manager variable with another call toSetScriptManagerVariable
as soon as possible, so that other applications or software components that use the Script Manager will find the values they expect.Checking and Setting Script Variables
TheGetScriptVariable
andSetScriptVariable
functions let you retrieve and set script variables, local variables maintained for each script system by the Script Manager.These functions give you access to a large variety of script-specific information, including the primary line direction for the script system, the default alignment for text in the script system, the script system's preferred system font and size, and its preferred application font and size.
You specify the script system whose variables you want to access with an explicit script code, or with an implicit script code specifying the system script or the font script. You specify the variable you want to access with a selector constant passed as a parameter to
GetScriptVariable
orSetScriptVariable
. Table 6-3 lists the selector constants and the script variables they affect. See "Selectors for Script Variables" beginning on page 6-65 for complete explanations of the selectors and variables.You can use the
GetScriptVariable
function to get, for example, the default application font family ('FOND'
) ID and size. In the following code fragment, the application uses the constantsmSystemScript
to specify that it is the system script whose font ID is needed. The ID is returned in the high-order word and the size is returned in the low-order word. The application then sets the appropriate graphics port fields to those values.
VAR myAppFont: LongInt; BEGIN myAppFont := GetScriptVariable(smSystemScript, smScriptAppFondSize); TextFont(HiWord(myAppFont)); TextSize(LoWord(myAppFont)); END;Listing 6-2 shows how to represent font names correctly using the proper script for that font. First you call the Font ManagerGetFNum
procedure to get the font family ID using the font name. You call theFontToScript
function using that font family ID to get the value of the associated script code. You then callGetScriptVariable
with thesmScriptSysFond
selector to determine the font family ID for the preferred system font for the specified script. Finally, you call the QuickDrawTextFont
procedure with that font family ID to set the font ID of the current graphics port to the preferred system font of the specified script.
Listing 6-2 Representing font names correctly in the script for that font
- Note
- The Menu Manager
AddResMenu
procedure automatically represents font names in their associated script for'FOND'
resources. If you need to display font names elsewhere than in the Font menu (for instance, using the List Manager), be sure to use a technique such as that shown in Listing 6-2.
PROCEDURE MySetTextFont(fontName: Str255); VAR scriptFont: LongInt; scriptNum: Integer; theNum: Integer; BEGIN {from font name, get font ID} GetFNum(fontName, theNum); {use font ID to get script code, } { then get preferred system font ID} scriptNum := FontToScript(theNum); scriptFont := GetScriptVariable(scriptNum, smScriptSysFond); {now set the current grafPort's } TextFont(scriptFont); { font ID to that font} END;TheSetScriptVariable
function allows you to change many script-specific settings, including the default configuration settings for the script system, which are initialized from a script system's international bundle ('itlb'
) resource. You callSetScriptVariable
with the appropriate script constant and selector to indicate the setting you want changed. Listing 6-3 shows how to use theSetScriptVariable
function to set the size of the Balloon Help font to the size passed in the parametertheSize
:Listing 6-3 Setting the size of the Balloon Help font
PROCEDURE MySetHelpFontSize(theSize: LongInt); VAR myErr: OSErr; myHelpFont: LongInt; BEGIN theSize := BitAnd(theSize, $0000FFFF); {keep low word only} myHelpFont := GetScriptVariable(smSystemScript, smScriptHelpFondSize); myHelpFont := BitAnd(myHelpFont, $FFFF0000); {keep high word only} myErr := SetScriptVariable(smSystemScript, smScriptHelpFondSize, BitOr(myHelpFont,theSize)); IF myErr <> noErr THEN DoError(myErr); END;If you are usingSetScriptVariable
to change the value of a variable for a specific task, first callGetScriptVariable
to retrieve the variable's original value, and save it. Then callSetScriptVariable
and perform your task. Finally, restore the original value of the script variable with another call toSetScriptVariable
as soon as possible, so that other applications or software components using that script system will find the values they expect.Making Keyboard Settings
The Script ManagerKeyScript
procedure lets you control the script system, keyboard layout, and input method used for text input. It also lets you make other settings related to text input.You use the
KeyScript
procedure to change the keyboard script, the script system that controls text input. You also use it to switch among different keyboard layouts, resources that define the character sets and key positions for text input in a script system. You can also use it to switch among input methods, software facilities that allow text input in 2-byte script systems. If your application supports multiple languages, useKeyScript
to change the keyboard script when the user changes the current font. For example, if the user selects Geezah as the current font or clicks the cursor within a run of text that uses the Geezah font, your application needs to set the keyboard script to Arabic. To do this, use theFontToScript
function to find the script for the font, then useKeyScript
to set the keyboard.In addition, your application can check the keyboard script (using the
GetScriptManagerVariable
function) in its main event loop; if the keyboard script has changed, you can set the current font to the last-used font, application font, or system font of the new keyboard script (determined by a call to theGetScriptVariable
function). This action saves the user from having to set the font manually after changing the keyboard script.The system software performs the equivalent of calling
KeyScript
in response to the user selecting a keyboard layout or input method from the Keyboard menu. It also does the same when the user types Command-Option-Space bar (to select the next keyboard layout or input method within the same script system), or Command-Space bar (to select the next script system in the Keyboard menu).When you call
KeyScript
, you pass it acode
parameter that can explicitly specify a keyboard script by script code, or can implicitly specify a keyboard script, keyboard layout, input method, or other setting. Values forcode
equal to or greater than zero are interpreted as normal script codes. Several negative codes specify switching among keyboard scripts, keyboard layout, or input methods. Others toggle line direction or input method and are available only with certain script systems. Still others disable or enable keyboard layouts or keyboard scripts. Table 6-5 lists the valid constants for thecode
parameter.The
smKeyDisableKybds
selector is available for your use, although it is primarily used by the Finder or other parts of the system under special circumstances. For example, when the user enters the name of a file in a Standard-File dialog box, text input must be restricted to scripts that display correctly in the Finder and in dialog boxes, menus, and alert boxes. In that situation the system software callsKeyScript
with thesmKeyDisableKybds
selector to disable keyboard input temporarily in any script system except Roman or the system script. Keyboards in other script systems then appear disabled in the Keyboard menu. When the user completes the filename entry, the system callsKeyScript
again with a selector ofsmKeyEnableKybds
to reenable keyboard input in all enabled script systems.The
smKeyDisableKybdSwitch
selector is also available for your use, although it is primarily used by the Finder. When keyboard layouts and script systems are being moved into or out of the System file by the user, changing the current keyboard or keyboard script may corrupt files or cause other unpredictable results. To prevent all keyboard switching and to disable all the Keyboard menu items, the Finder callsKeyScript
with the selectorsmKeyDisableKybdSwitch
. When the move has been completed, the Finder again callsKeyScript
with a selector ofsmKeyEnableKybds
to reenable keyboard switching.If you call
KeyScript
withcode
= smKeyRoman on a system in which only the Roman script system is enabled, nothing happens. However, if you callKeyScript
withcode
= 0 (to select the Roman script system), it forces an update that selects the current default Roman keyboard layout.
- IMPORTANT
- Although it is possible to change the keyboard script without changing the keyboard layout--by calling the
SetScriptManagerVariable
function with thesmKeyScript
selector--it violates the user interface paradigm and creates problems for other script management routines.Synchronizing the Font Script and Keyboard Script
To keep the user from accidentally entering meaningless characters, you must always keep the keyboard script synchronized with the font script, so that the glyphs displayed on the screen match the characters entered at the keyboard. You can synchronize the scripts in two ways: by setting the keyboard script when the font script changes, and by setting the font script when the keyboard script changes.Setting the Keyboard Script From the Font Script
Set the keyboard script from the font script when the user selects a new font or when the user clicks in or selects text.
Listing 6-4 is an example of code to use for setting the keyboard script from the font script. Once you have obtained the script code value from the font family ID using the
- If the user selects a new font from the Font menu, call
TextFont
to set the current font to that font. Then set the keyboard script to the script system of that font.- If the user clicks in or selects a text area, set the current font to be the font, size, and style of the text where the click occurred. Then set the keyboard script to the script system of that font.
FontToScript
function (see "Determining Script Codes From Font Information" beginning on page 6-21), you call theGetScriptManagerVariable
function with thesmKeyScript
selector to determine the keyboard script. If the font script and the keyboard script are not the same, call theKeyScript
procedure to change the keyboard script.Listing 6-4 Setting the keyboard script from the font script
PROCEDURE MySetKeyboardFromFont(myFont: Integer); VAR theFontScript: Integer; BEGIN {get script code from font ID.} theFontScript := FontToScript(myFont); {compare with keyboard script, } { change if necessary} IF (GetScriptManagerVariable(smKeyScript) <> theFontScript) THEN KeyScript(theFontScript); END;Setting the Font Script From the Keyboard Script
Each time the user types a character other than a control character, your application should check that the font script is still the same as the keyboard script. The user may have, for example, switched keyboard scripts since entering the last character. If the font script does not match the keyboard script, change the current font to correspond to the new keyboard script before displaying the character. Follow these guidelines:
Listing 6-5 is an example of setting the font (and therefore the font script) from the keyboard script. It calls
- If possible, set the current font to the previous font that was used for that script (that is, the last font for that script preceding the current point in the document or text buffer).
- Otherwise, set the font to one of the preferred fonts for that script system. The preferred fonts are the preferred application font, the preferred system font, the preferred monospaced font, and the preferred small font. (The ID numbers of these fonts can be obtained through the
GetScriptVariable
function.)
GetScriptManagerVariable
with thesmKeyScript
selector to determine the current keyboard script. It then callsFontToScript
to determine whether the keyboard script differs from the font script. If it does, the routine callsGetScriptVariable
with thesmScriptAppFond
selector to determine the application font for the script. Then it sets the current font based on that result.Listing 6-5 Setting the font (script) from the keyboard script
PROCEDURE MySetFontFromKeyboard(VAR myFont: Integer); VAR scriptNum: LongInt; BEGIN scriptNum := GetScriptManagerVariable(smKeyScript); IF (FontToScript(myFont) <> scriptNum) THEN myFont := GetScriptVariable(scriptNum, smScriptAppFond); TextFont(myFont) END;You can also use this code if your application does not have an interface that lets users change fonts but still needs to provide for different script systems.