ADC Home > Reference Library > Technical Notes > Legacy Documents > Text & Fonts >

Legacy Documentclose button

Important: This document is part of the Legacy section of the ADC Reference Library. This information should not be used for new development.

Current information on this Reference Library topic can be found here:

Script Manager Q&As

CONTENTS

This Technical Note contains a collection of archived Q&As relating to a specific topic--questions sent the Developer Support Center (DSC) along with answers from the DSC engineers. Current Q&As can be found on the Macintosh Technical Q&As web site.

[Oct 01 1990]






String2Date and Date2Secs conversion surprises

Date Written: 8/19/91

Last reviewed: 6/14/93

String2Date and Date2Secs treat all dates with the year 04 to 10 as 2004 to 2010 instead of 1904 to 1910.

___

This is correct; the Script Manager treats two-digit years less than or equal to 10 as 20xx dates if the current year is between 1990 and 1999, inclusive. Basically, it just assumes that you're talking about 1-20 years in the future, rather than 80-100 years in the past. The same is true of two-digit 9x dates, when the current year is less than or equal to xx10. Thus, in 2003, the date returned when 3/7/94 is converted will be 1994, not 2094. This is all documented in "Worldwide Development: Guide to System Software".

Back to top

Using FormatXToStr and FormatStrToX with Pascal switches

Date Written: 12/10/90

Last reviewed: 6/14/93

Why do the FormatXToStr and FormatStrToX Script Manager routines stop working when I use the Pascal -MC68881 switch?

___

Regular SANE extended numbers are 10 bytes long while MC68881 extended numbers are 12 bytes long, and the extra two bytes are right in the middle of every 68881 extended number. Appendix G "The SANE Library" in the Macintosh Programmer's Workshop (MPW) Object Pascal version 3.1 manual goes into detail about this. The FormatX2Str and FormatStr2X parse the extended number you pass them directly, and they can only parse 10-byte extended numbers. Fortunately, you can still use the -mc68881 option with these routines as long as you convert any extended numbers to 80-bit extended numbers before passing them to FormatX2Str and FormatStr2X. The SANE.p unit has routines to do this called X96toX80 and X80toX96 (incorrectly documented as X96to80 and X80to96 in the MPW Object Pascal manual). Because the extended80 and extended96 types aren't equivalent to the extended type as far as Object Pascal is concerned, you have to redeclare FormatX2Str and FormatStr2X to take these types. You can do this as follows:

FUNCTION FormatX2Str80 (x:             extended80;
                        myCanonical:   NumFormatString;
                        partsTable:    NumberParts;
                        VAR outString:  Str255):  FormatStatus;
    INLINE $2F3C,$8210,$FFE8,$A8B5;

FUNCTION FormatStr2X80 (source:      Str255;
                        myCanonical:  NumFormatString;
                        partsTable:  NumberParts;
                        VAR x:       extended80):  FormatStatus;
    INLINE $2F3C,$8210,$FFE6,$A8B5;

Call these routines instead of the originals. To call FormatX2Str80, all you have to do is this:

VAR
   x:             extended80; {96-bit extended number}
   myCanonical:   NumFormatString;
   partsTable:    NumberParts;
   outString:     Str255

result := FormatX2Str80 (X96toX80 (x), myCanonical, partsTable, outString);

Calling FormatStr2X80 is just slightly more complicated because the extended number is passed by reference:

VAR
   x:           extended;   {96-bit extended number}
   x80:         extended80; {80-bit extended number}
   source:      Str255;
   myCanonical:  NumFormatString;
   partsTable:  NumberParts;

x80 := X96toX80 (x);
result := FormatStr2X80 (theString, realCanon, PartsTable, x80);
x := X80toX96 (x80);

You should find that these calls now work properly with the -mc68881 option set. This of course means that you'll need two versions of the source code; one with the calls to convert between 96-bit and 80-bit extended numbers for use with the -mc68881 option and another one which just uses plain old 80-bit extended numbers for use when the -mc68881 option is turned off.

Back to top

FormatX2Str strings

Date Written: 10/9/91

Last reviewed: 6/14/93

Using the Script Manager to convert numbers to strings and vice versa, in any language, what's the best way to create the string to pass to FormatX2Str? Will strings using the characters: "#" or "0" or "." or "," work no matter what script is currently running, and if not, what can I do?

___

The number format string and canonical number format string mechanisms that you use with FormatX2Str and its kin is a strange design, for exactly the reason that you asked about. The number format string (the one with the characters such as "#" and "0") does not necessarily work right regardless of the current script. In fact, it doesn't even necessarily work right between localized versions within one script system. The canonical number format string does work between localized systems and between script systems. The strange thing is there's an easy way to store number format strings (usually in a 'STR ' resource), but no obvious way to store canonical number format strings. Here's what you can do when converting between numbers and strings:

When you convert a number format string to a canonical number format string with Str2Format on a U.S. system, it converts it from something like "###.###" to a canonical number format string that looks something like, "three digits, a decimal point, and three digits." On a German system, that same number format string would be converted to "three digits, a thousands separator, and three digits."

What you can do to get around this is to save the canonical number format string in a resource instead of the number format string. The canonical string stores things in a language- and script-independent way. Create this resource by writing a trivial utility program that takes a number format string and calls Str2Format to convert it into a canonical number format string, and then copy this into a handle and save it as a resource of a custom type, like 'NUMF'. In your real program, load the 'NUMF' resource, lock it, and then pass the dereferenced handle to FormatX2Str and FormatStr2X.

You can see this done in the ProcDoggie Process Manager sample from the 7.0 Golden Master CD. Take a look at the SetUpProcessInfoItems procedure in UProcessGuts.inc1.p file. You'll see that the 'NUMF' resource is loaded, locked, and then passed to FormatX2Str. The result is displayed in the Process Information window.

If your program is localized by nonprogrammers, then you might want to provide the utility that converts a number format string to a canonical number format string resource just in case they have to change the entire format of the string. Then they can install the new 'NUMF' (or whatever you choose) resource as part of the localization process.

Back to top

Code for truncating a multi-byte character string

Date Written: 1/24/92

Last reviewed: 6/14/93

I create a Macintosh file name from another file name. Since I am adding information to the name, I must make sure that it is within the 31 chars maximum allowed by the operating system. What I need is the equivalent of the TruncText command, except instead of dealing with pixel width, I want the width to be number of characters (31). I can trunc myself, but I'd rather do a proper smTruncMiddle and have it nicely internationalized.

___

If you're going to be adding a set number of bytes to the end of a existing string and you don't want the localized ellipsis (from the 'itl4' resource) between the truncated string and your bytes, then you can use this routine:

PROCEDURE TruncPString (VAR theString: Str255; maxLength: Integer);
{ This procedure truncates a Pascal string to be of length maxLength or }
{ shorter. It uses the Script Manager charByte function to make sure }
{ the string is not broken in the middle of a multi-byte character. }
  VAR
    charType: Integer;
  BEGIN
    IF Length(theString) > maxLength THEN
      BEGIN
        charType := CharByte(@theString[1], maxLength);
        WHILE ((charType < 0) OR (charType > 1)) AND (maxLength <> 0) DO
          BEGIN
            maxLength := maxLength - 1;
            charType := CharByte(@theString[1], maxLength);
          END;
        theString[0] := chr(maxLength);
      END;
  END;
  

If you want the localized ellipsis (from the 'itl4' resource) between the truncated string and your bytes, or you want the localized ellipsis in the middle of the combined strings truncated to a specific length, then you can use this routine:

FUNCTION TruncPString (maxLength: Integer; VAR theString: Str255;
truncWhere: TruncCode): Integer;
{ This function truncates a Pascal String to be of length maxLength or }
{ shorter. It uses the Script Manager TruncString function which adds }
{ the correct tokenEllipsis to the middle or end of the string. See }
{ Inside Macintosh Volume VI, pages 14-59 and14-60 for more info. }
  VAR
    found: Boolean;
    first, midPoint, last: Integer;
    tempString: Str255;
    whatHappened: Integer;
  BEGIN
    found := FALSE;
    first := 0;
    last := TextWidth(@theString[1], 0, Length(theString));
    IF Length(theString) > maxLength THEN
      BEGIN
        WHILE (first <= last) AND NOT found DO
          BEGIN
            tempString := theString; { tempString gets destroyed every }
                                     { time through }
            midPoint := (first + last) DIV 2;
            whatHappened := TruncString(midPoint, tempString, truncWhere);
            IF whatHappened < smNotTruncated THEN
              BEGIN { ERROR, bail out now }
                TruncPString := whatHappened; { return error }
                Exit(TruncPString);
              END
            ELSE IF Length(tempString) = maxLength THEN
              found := TRUE
            ELSE IF Length(tempString) > maxLength THEN
              last := midPoint - 1
            ELSE
              first := midPoint + 1;
          END;
        theString := tempString;
        TruncPString := whatHappened; { will always be smTruncated }
                                      { in this case }
      END
    ELSE
      TruncPString := smNotTruncated; { the string wasn't too long }
  END;

Back to top

Character type and subtype values within the Kanji system

Date Written: 11/17/89

Last reviewed: 12/17/90

What are the values of character type and subtype with the Macintosh Kanji system?

___

For Roman, these are the values of character type:

    Punctuation         0
    ASCII               1
    European            7
    

For KanjiTalk, the values are the same as Roman, with the addition of:

    Katakana            2
    Hiragana            3
    Kanji               4
    Greek               5
    Russian (Cyrillic)  6

In Roman, the subtype field is interpreted as:

    Normal punctuation  0
    Numeric             1
    Symbols             2
    Blanks              3

The KanjiTalk subtype values are the same as Roman except if the character type is Kanji, in which case the subtype field takes these values:

    JIS Level 1         0
    JIS Level 2         1
    JIS User Character  2
    

Finally, for KanjiTalk, the character direction field is replaced by the In-ROM field. It is 1 if the character is in the ROM card and 0 otherwise.

Back to top

Downloadables

Acrobat gif

Acrobat version of this Note (36K)

Download


Back to top


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.