Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Text /
Chapter 6 - Script Manager / Using the Script Manager


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

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 variable SysDirection. The value of SysDirection 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 call GetSysDirection to save the original value. Then call SetSysDirection again at the appropriate time--such as when your application becomes inactive--to restore SysDirection to its original value.

Checking and Setting Script Manager Variables

The GetScriptManagerVariable and SetScriptManagerVariable 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 or SetScriptManagerVariable. (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.
Script Manager variables accessed through GetScriptManagerVariable/SetScriptManagerVariable (Continued)
Selector constantExplanation
smVersionScript Manager version number
smMungedModification count
smEnabledScript count (0 if Script Manager not enabled)
smBidirectBidirectional script present flag
smFontForceFont force flag
smIntlForceInternational resources selection flag
smForcedScript-forced result flag
smDefaultScript-defaulted result flag
smPrintPrint action vector
smSysScriptSystem script code
smLastScriptPrevious keyboard script
smKeyScriptCurrent keyboard script
smSysRefSystem Folder volume reference number
smKeyCache(obsolete, not used)
smKeySwapHandle to keyboard-swap ('KSWP') resource
smGenFlagsScript Manager general flags
 
smOverrideScript override flags (reserved)
smCharPortionIntercharacter/interword spacing proportion
smDoubleByte2-byte script present flag
smKCHRCachePointer to current keyboard-layout ('KCHR') data
smRegionCodeRegion code for system script
smKeyDisableStateCurrent disable state for keyboards

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 the Gestalt function using the gestaltScriptMgrVersion selector.

VAR
   selectorValue: LongInt;
BEGIN
   selectorValue := GetScriptManagerVariable(smVersion);
END;
The SetScriptManagerVariable function allows you to change many text-related settings, including

Listing 6-1 shows how to use the 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 the GetScriptManagerVariable 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 use SetScriptManagerVariable 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 call GetScriptManagerVariable to retrieve the variable's original value, and save that value. Then call SetScriptManagerVariable and perform your task. Finally, restore the original value of the Script Manager variable with another call to SetScriptManagerVariable 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

The GetScriptVariable and SetScriptVariable 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 or SetScriptVariable. 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.
Script variables accessed through
GetScriptVariable/SetScriptVariable (Continued)
Selector constantExplanation
smScriptVersionScript-system version number
smScriptMungedModification count
smScriptEnabledScript-enabled flag
smScriptRightRight-to-left line direction flag
smScriptJustDefault alignment (left or right)
smScriptRedrawAmount of line to redraw when changing a character
smScriptSysFondPreferred system font
smScriptAppFondPreferred application font
smScriptNumberNumeric-format ('itl0') resource ID
smScriptDateLong-date-format ('itl1') resource ID
smScriptSortString-manipulation ('itl2') resource ID
smScriptFlagsScript flags
smScriptTokenTokens ('itl4') resource ID
smScriptEncodingEncoding/rendering ('itl5') resource ID
smScriptLangLanguage code for script
smScriptNumDateCurrent numeral code and calendar code
smScriptKeysKeyboard-layout ('KCHR') resource ID
smScriptIconKeyboard icon family ID
smScriptPrintPrint action routine for script
smScriptTrapPointer to script record dispatch routine entry point (for internal use)
smScriptCreatorCreator name for script file
smScriptFileFilename for script file
smScriptNameName of script system
smScriptMonoFondSizePreferred font and size for fixed-width font
smScriptPrefFondSize(unused)
smScriptSmallFondSizePreferred font family and size for small text
smScriptSysFondSizePreferred system font family and size
smScriptAppFondSizePreferred application font family and size
smScriptHelpFondSizePreferred Balloon Help font family and size
smScriptValidStylesValid text styles for script
smScriptAliasStyleText styles to use for aliases

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 constant smSystemScript 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 Manager GetFNum procedure to get the font family ID using the font name. You call the FontToScript function using that font family ID to get the value of the associated script code. You then call GetScriptVariable with the smScriptSysFond selector to determine the font family ID for the preferred system font for the specified script. Finally, you call the QuickDraw TextFont 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.

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.
Listing 6-2 Representing font names correctly in the script for that font

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;
The SetScriptVariable 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 call SetScriptVariable with the appropriate script constant and selector to indicate the setting you want changed. Listing 6-3 shows how to use the SetScriptVariable function to set the size of the Balloon Help font to the size passed in the parameter theSize:

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 using SetScriptVariable to change the value of a variable for a specific task, first call GetScriptVariable to retrieve the variable's original value, and save it. Then call SetScriptVariable and perform your task. Finally, restore the original value of the script variable with another call to SetScriptVariable 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 Manager KeyScript 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, use KeyScript 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 the FontToScript function to find the script for the font, then use KeyScript 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 the GetScriptVariable 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 a code 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 for code 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 the code parameter.
Constants for the code parameter in the KeyScript procedure (Continued)
ConstantValueExpanation
(any script code)0...64Switch to specified script
smKeyNextScript -1Switch to next script in Keyboard menu
smKeySysScript -2Switch to the system script
smKeySwapScript -3Switch to previously used script
smKeyNextKybd -4Switch to next keyboard layout or input method in Keyboard menu (within current script)
smKeySwapKybd -5(not implemented)
smKeyDisableKybds -6Disable keyboard layouts not in system script or Roman script
smKeyEnableKybds -7Enable keyboard layouts for all
enabled scripts
smKeyToggleInline -8Toggle inline input for current script (available if 2-byte script present)
smKeyToggleDirection -9Toggle default line direction (available if bidirectional script present)
smKeyNextInputMethod -10(not implemented)
smKeySwapInputMethod -11(not implemented)
smKeyDisableKybdSwitch-12Disable switching out of current
keyboard layout
smKeySetDirLeftRight-15Set primary line direction to left-to-right (available if bidirectional script present)
smKeySetDirRightLeft-16Set primary line direction to right-to-left (available if bidirectional script present)
smKeyRoman-17Set keyboard script to Roman (available only if multiple scripts present)

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 calls KeyScript with the smKeyDisableKybds 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 calls KeyScript again with a selector of smKeyEnableKybds 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 calls KeyScript with the selector smKeyDisableKybdSwitch. When the move has been completed, the Finder again calls KeyScript with a selector of smKeyEnableKybds to reenable keyboard switching.

If you call KeyScript with code = smKeyRoman on a system in which only the Roman script system is enabled, nothing happens. However, if you call KeyScript with code = 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 the smKeyScript 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 FontToScript function (see "Determining Script Codes From Font Information" beginning on page 6-21), you call the GetScriptManagerVariable function with the smKeyScript selector to determine the keyboard script. If the font script and the keyboard script are not the same, call the KeyScript 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 GetScriptManagerVariable with the smKeyScript selector to determine the current keyboard script. It then calls FontToScript to determine whether the keyboard script differs from the font script. If it does, the routine calls GetScriptVariable with the smScriptAppFond 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.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
6 JUL 1996