MACINTOSH C CARBON: A Hobbyist's Guide To Programming the Macintosh in C
Version 1.0
© 2001 K. J. Bricknell
CHAPTER 21
TEXT, TEXTEDIT, DATES, TIMES, AND NUMBERS
Introduction
The subject of text on the Macintosh is quite a complex matter, involving as it does QuickDraw, TextEdit, the Font Manager, the Text Utilities, the Script Manager, the Text Services Manager, Apple Type Services for Unicode Imaging, the Resource Manager, keyboard resources, and international resources. Part of that complexity arises from the fact that the system software supports many different writing systems, including Roman, Chinese, Japanese, Hebrew, and Arabic.
|
Some of the information in this chapter is valid only in the case of the Roman writing system.
|
Text on the Macintosh was touched on briefly at Chapter 12, which included descriptions of QuickDraw functions used for drawing text and for setting the font, style, size, and transfer mode. Chapter 15 contained a brief treatment of considerations applying to the printing of text. Chapter 26 addresses the Multilingual Text Engine (MLTE) introduced with Mac OS 9
This chapter addresses:
- TextEdit, which you can use to provide your application with basic text editing and formatting capabilities.
Note that the emphasis in this chapter is on monostyled TextEdit. With the introduction, with Mac OS 9, of the Multilingual Text Engine (see Chapter 26), it became all but inconceivable that programmers would ever again use multistyled TextEdit to provide their applications with multi-styled text editing capabilities. Accordingly, in the following, multistyled TextEdit is addressed only to the extent necessary to support an understanding of the display of non-editable multi-styled text, as in the Help dialog component of the demonstration program MonoTextEdit associated with this chapter.
- The formatting and display of dates, times, and numbers.
Before addressing those particular subjects, however, a brief overview of various closely related matters is appropriate.
More on Text
Characters, Character Sets and Codes, Glyphs, Typefaces, Styles, Fonts and Font Families
Characters and Character Sets and Codes
A character is a symbol which represents the concept of, for example, a lowercase "b", the number "2" or the arithmetic operator "+". A collection of characters is called a character set. Individual characters within a character set are identified by a character code.
The Apple Standard Roman character set is the fundamental character set for the Macintosh computer. As shown at Fig 1, it uses all character codes from 0x00 to 0xFF. The Standard Roman character set is actually an extended version of the ASCII character set, which uses character codes from 0x00 to 0x7F only, and which is highlighted at Fig 1.
Glyphs
The visual representation of a character on a display device is called a glyph. In other words, a glyph is the shape by which a character is represented. A specific character can be represented by many different shapes (that is, glyphs).
Two types of glyphs are used by the Font Manager: bitmapped glyphs and glyphs from outline fonts. A bitmapped glyph is a bitmap designed at a fixed size for a particular display device. An "outline" is a mathematical description of the glyph in terms of lines and curves, and is used by the Font Manager to create bitmaps at any size for any display device.
Typefaces
If all glyphs for a character set share certain design characteristics, they form a typeface. Typefaces have their own names, such as Arial, Geneva, or Times.
Styles
A specific variation in a glyphs appearance is called a style. On the Macintosh, available styles include plain, bold, italic, underline, outline, shadow, condensed, and extended. QuickDraw can add styles to bitmaps, or fonts can be designed in a specific style, such as, for example, Arial Italic.
Fonts and Font Families
A font is a full set of glyphs in a specific typeface and style. All fonts have a font name, such as Arial or Geneva, which is ordinarily the same name as the typeface from which it was derived. Except for fonts not in the plain style, the font's name includes the style (or styles), for example Palatino Bold Italic.
Fonts on the Macintosh are resources. The resource types are as follows:
- Bitmapped font resources are of type 'FONT' (the original resource type for fonts) and 'NFNT' (bitmapped font). 'FONT' and 'NFNT' resources provide a separate bitmap for each glyph in each style and size.
- Outline font resources are of type 'sfnt'. 'sfnt' resources comprise glyphs in a particular typeface and style.
If multiple fonts of the same typeface are present, the Font Manager groups those fonts into font families of resource type 'FOND'. A font family ID is the resource ID for a font family.
As an aside, most (though not all) fonts assign glyphs to character codes 0x20 to 0x7F which visually define the characters associated with those codes.
|
Fonts such as Zapf Dingbats assign glyphs of pictorial symbols to this range. as well as the low-ASCII range.
|
However, there are differences in the glyphs assigned to the high-ASCII range. Indeed, some fonts do not actually include glyphs for all, or part, of the high-ASCII range.
Font Measurements
Fonts are either monospaced or proportional. All glyphs in a monospaced font are the same width. The glyphs in a proportional font have different widths, "m" being wider than "i", for example.
Base Line, Ascent Line and Descent Line
Most glyphs in a font sit on an imaginary line called the base line. The ascent line approximately corresponds with the tops of the uppercase letters of the font. The descent line usually corresponds to the bottom of descenders (the tails of glyphs like "j"). (See Fig 2.)
Glyph Origin, Left Side Bearing, and Advance Width
The glyph origin is where QuickDraw begins drawing the glyph. The left side bearing is the white space between the glyph origin and the beginning of the glyph. The advance width is the full width of a glyph, measured from its origin to the origin of the next glyph. (See Fig 2.)
Font Size
Font size is the measurement, in points, from the base line of one line of text to the base line of the next line (assuming single-spaced text). A point is equivalent to 1/72 of an inch. The size of a font is often, but not always, the sum of the ascent, descent and leading (pronounced "ledding") values for a font. (The leading is the vertical space between the descent line of one line of single-spaced text and the ascent line of the next line.)
The Font Manager and QuickDraw
The Font Manager keeps track of all fonts available to an application and supports QuickDraw by providing the character bitmaps that QuickDraw needs. If QuickDraw requests a typeface that is not represented in the available fonts, the Font Manager substitutes one that is. Where necessary, QuickDraw scales the font to the requested size and applies the specified style.
Aspects of Text Editing - Caret Position, Text Offsets, Selection Range, Insertion Point, and Highlighting
Caret Position and Text Offset
In the world of text editing, the caret is defined as the blinking vertical bar that indicates the insertion point in text, and a caret position is a location on the screen that corresponds to an insertion point in memory. A caret position is always between glyphs on the screen. The caret is always positioned on the leading edge of the glyph corresponding to the character at the insertion point in memory. When a new character is inserted, the character at the insertion point, and all subsequent characters, are shifted forward one character position in memory.
The relationship between caret position, insertion point and offset is illustrated at Fig 3.
Converting Screen Position to Text Offset
A mouse-down event can occur anywhere in a glyph; however, the caret position derived from that mouse-down must be an infinitely thin line between two glyphs.
As shown at Fig 4, a line of glyphs is divided into mouse-down regions, which, except at the end of the line, extend from the centre of one glyph to the centre of the next glyph. A click anywhere in a particular mouse-down region yields the same caret position.
Selection Range and Insertion Points
The selection range is the sequence of zero or more contiguous characters where the next text editing operation is to occur. If a selection range contains zero characters, it is called an insertion point.
Highlighting
A selection range is typically marked by highlighting, that is, by drawing the glyphs with a coloured background. The limits of highlighting rectangles are measured in terms of caret position. For example, if the characters A, C, and I at Fig 3 were highlighted, the highlighting would extend from the leading edge of A (offset = 1) to the leading edge of N (offset = 4).
Outline Highlighting
Outline highlighting is the "framing" of text in the selection range in an inactive window. If there is no selection range, a grey, unblinking caret is displayed. By default, outline highlighting is disabled.
Keyboards and Text
Each keypress on a particular keyboard generates a value called a raw key code. The keyboard driver which handles the keypress uses the key-map ('KMAP') resource to map the raw key code to a keyboard-independent virtual key code. It then uses the Event Manager and the keyboard layout ('KCHR') resource to convert a virtual keycode into a character code. The character code is passed to your application in the event structure generated by the keypress.
Introduction to TextEdit
TextEdit is a collection of functions and data structures which you can use for the purposes of basic text formatting and editing. It was originally designed to handle edit text items in dialogs, and was subsequently enhanced to provide some of the more complex capabilities required of a basic text editor. That said, it should be understood that TextEdit was never intended to support all of the basic features generally required of a text editor (for example, tabs) and was never intended to manipulate lengthy text documents in excess of 32 KB. Indeed, the limit for documents created by TextEdit is 32,767 characters.
If you do not need to create large files and only need basic formatting capabilities, TextEdit provides a useful alternative to writing your own specialised text processing functions.
Editing Tasks Performed by TextEdit
The fundamental editing tasks which TextEdit can perform for your application are as follows:
- Selection of text by clicking and dragging the mouse.
- Selecting text by clicking and dragging the mouse, selecting words by double-clicking, and extending or shortening selections by Shift-clicking.
- Displaying the caret at the insertion point or highlighting the current text selection, as appropriate.
- Handling line breaking, that is, preventing a word from being split between lines.
- Cutting, copying, and pasting text within your application, and between your application and other applications.
- Managing the use of more than one font, text size, text colour, and text style from character to character.
Thus, if you do not need to manipulate large files and do not need extensive formatting capabilities, TextEdit is a convenient alternative to writing your own specialised text processing functions.
TextEdit Options
You can use TextEdit at different levels of complexity.
Using TextEdit Indirectly
For the simplest level of text handling (that is, in dialogs), you need not even call TextEdit directly but rather use the Dialog Manager. The Dialog Manager, in turn, calls TextEdit to edit and display text.
Displaying Static Text
If you simply want to display one or more lines of static (non-editable) text, you can call TETextBox, which draws your text in the location you specify. TETextBox may be used to display text that you cannot edit. You do not need to create an edit text structure (see below) because TETextBox creates its own edit structure. TETextBox draws the text in a rectangle whose size you specify in the coordinates of the current graphics port. Using the following constants, you can specify how text is aligned in the box:
Constant |
Description |
teFlushDefault |
Default alignment according to primary line direction of the script system. (Left for Roman script system.) |
teCenter |
Centre alignment. |
teFlushRight |
Right alignment. |
teFlushLeft |
Left alignment. |
Text Handling - Monostyled Text
If your application requires very basic text handling in a single typeface, style, and size, you probably only need monostyled TextEdit. You can use monostyled TextEdit with any single available font.
Text Handling - Multistyled Text
If your application requires a somewhat higher level of text handling (allowing the user to change typeface, style, and size within the document, for example), you can use multistyled TextEdit. However, as previously stated, mutistyled TextEdit has now been overshadowed by the introduction of the Multilingual Text Engine.
Caret Position and Movement in TextEdit
TextEdit always positions the caret where the next editing operation will occur. When TextEdit pastes text, it positions the caret after the newly pasted text. Assuming that the caret is not in the first or last line of text,TextEdit moves the caret up or down one line when the user presses the Up Arrow key or the Down Arrow key. (If the caret is on the first line, TextEdit moves the caret to the beginning of text on that line if the user presses the Up Arrow key,. If the caret is on the last line, TextEdit moves the caret to the end of the text on that line if the user presses the Down Arrow key.)
|
TextEdit does not support the use of modifier keys, such as the Shift key, in conjunction with the arrow keys.
|
Automatic Scrolling
One way for the user is to select large blocks of text is to click in the text and, holding the mouse button down, drag the cursor above, below, left of, or right of TextEdit's view rectangle (see below). While the mouse button remains down, and provided that your application has enabled automatic scrolling, TextEdit continually calls its click loop function to automatically scroll the text.
Although TextEdit's default click loop function automatically scrolls the text, it cannot adjust the scroll box/scroller position in an application's scroll bars to follow up the scrolling. The default click loop function can, however, be replaced with an application-defined click loop (callback) function which accommodates scroll bars.
TextEdit's Private, Null, and Style Scraps
Internally, TextEdit uses three scrap areas, namely, the private scrap, the null scrap, and the style scrap. The null scrap and the style scrap apply only to multistyled TextEdit.
The private scrap, which belongs to your application, is used for all cut, copy, and paste activity.
The null scrap is used by TextEdit to store character attribute information associated with a null selection or text that is deleted by backspacing. (A null selection is an insertion point.)
|
The font, style, size, and colour aspects of text are collectively referred to as character attributes.
|
When multistyled text is cut or copied, TextEdit copies character attribute information to the style scrap.
Text Alignment
Text alignment can be left-aligned, right-aligned, centred, or justified. Justified means aligned with both the left and right edges of TextEdit's destination rectangle (see below), and is achieved by spreading or compressing text to fit a given line width.
Primary TextEdit Data Structures
The primary data structures used by TextEdit are the edit text structure and the dispatch structure. Additional data structures are associated with multistyled TextEdit. This section describes the primary data structures only.
The TextEdit Structure
The edit text structure is the principal data structure used by TextEdit. This structure is the same regardless of whether the text is monostyled or multistyled, although some fields are used differently for multistyled edit text structures. The edit text structure is as follows:
struct TERec
{
Rect destRect; // Destination rectangle.
Rect viewRect; // View rectangle.
Rect selRect; // Selection rectangle.
short lineHeight; // Vert spacing of lines. -1 in multistyled.
short fontAscent; // Font ascent. -1 in multistyled TextEdit structure.
Point selPoint; // Point selected with the mouse.
short selStart; // Start of selection range.
short selEnd; // End of selection range.
short active; // Set when structure is activated or deactivated.
WordBreakUPP wordBreak; // Word break function.
TEClickLoopUPP clickLoop; // Click loop function.
long clickTime; // (Used internally.)
short clickLoc; // (Used internally.)
long caretTime; // (Used internally.)
short caretState; // (Used internally.)
short just; // Text alignment.
short teLength; // Length of text.
Handle hText; // Handle to text to be edited.
long hDispatchRec; // Handle to TextEdit dispatch structure.
short clikStuff; // (Used internally)
short crOnly; // If < 0, new line at Return only.
short txFont; // Text font. // If multistyled edit struct (txSize = -1),
StyleField txFace; // Chara style. // these bytes are used as a handle
SInt8 filler; // // to a style structure (TEStyleHandle).
short txMode; // Pen mode.
short txSize; // Font size. -1 in multistyled TextEdit structure.
GrafPtr inPort; // Pointer to grafPort for this TextEdit structure.
HighHookUPP highHook; // Used for text highlighting, caret appearance.
CaretHookUPP caretHook; // Used from assembly language.
short nLines; // Number of lines.
short lineStarts[16001]; // Positions of line starts.
};
typedef struct TERec TERec;
typedef TERec *TEPtr;
typedef TEPtr *TEHandle;
Field Descriptions
destRect |
The destination rectangle (local coordinates), which is the area in which text is drawn (see Fig 5). The top of this rectangle determines the position of the first line of text and the two sides determine the beginning and the end of each line. The bottom of the rectangle varies as text is added or removed as a result of editing operations.
The destination rectangle is central to the matter of scrolling text. When text is scrolled downwards, for example, you can think of the destination rectangle as being moved upwards through the view rectangle. |
viewRect |
The view rectangle (local coordinates), which is the area in which text is actually displayed (see Fig 5).
|
selRect |
The selection rectangle boundaries (local coordinates). |
lineHeight |
In a monostyled TextEdit structure, the vertical spacing of lines of text, that is, the distance from the ascent line of any one line of text to the ascent line of the next line of text.
Multistyled TextEdit Structure. In a multistyled TextEdit structure, this field is set to -1, which indicates that line heights are calculated for each individual line of text. |
fontAscent |
In a monostyled TextEdit structure, the font ascent, that is, the vertical distance above the baseline the pen is positioned to begin drawing the caret or selection highlighting. (In the case of single-spaced text, the font ascent is the height of the text in pixels.)
Multistyled TextEdit Structure. In a multistyled edit text structure, this field is set to -1, which indicates that the font ascent is calculated independently for each line based on the maximum value for any individual character on that line.
|
selPoint |
The point selected with the mouse (local coordinates). |
selStart |
The byte offset of the start of the selection range. TextEdit initialises this field to 0 when you create an TextEdit structure. |
selEnd |
The byte offset of the end of the selection range. TextEdit initialises this field to 0 when you create an TextEdit structure. With both selStart and selEnd initialised to 0, the insertion point is placed at the beginning of the text. |
active |
Set when the TextEdit structure is activated and reset when the TextEdit structure is rendered inactive. |
wordBreak |
Universal procedure pointer to the word selection break function, which determines, firstly, the word that is highlighted when the user double-clicks in the text and, secondly, the position at which text is wrapped at the end of the line. |
clickLoop |
Universal procedure pointer to the click loop function, which is called repeatedly while the mouse button is held down within the text. |
just |
Text alignment (default, left, centre, or right). |
teLength |
The number of bytes in the text. The maximum allowable length is 32,767 bytes. When you create a TextEdit structure, TextEdit initialises this field to 0. |
hText |
A handle to the text. When you create a TextEdit structure, TextEdit initialises this field to point to a zero-length block in the application heap. |
hDispatchRec |
The handle to the TextEdit dispatch structure (see below). For internal use only. |
clikStuff |
TextEdit sets this field according to whether the most recent mouse-down event occurred on a glyph's leading or trailing edge. Used internally by TextEdit to determine a caret position. |
crOnly |
If the value in this field is positive, text wraps at the right edge of the destination rectangle. If the value is negative, text does not wrap. |
txFont |
In a monostyled TextEdit structure, the font of all the text in the TextEdit structure. (If you change the value, you should also change the lineHeight and fontAscent fields as appropriate.)
Multistyled TextEdit Structure. In a multistyled edit text structure, if the txSize field (see below) is set to -1, this field combines with txFace and filler to hold a handle to the associated style structure. |
txFace |
In a monostyled TextEdit structure, the character attributes of all the text in a TextEdit structure. (If you change this value, you should also change the lineHeight and fontAscent fields as appropriate.)
Multistyled TextEdit Structure. In a multistyled TextEdit structure, if the txSize field (see below) is set to -1, this field combines with txFont and filler to hold a handle to the associated style structure. |
txMode |
The pen mode of all the text. |
txSize |
In a monostyled edit text structure, this field is set to the size of the text in points.
Multistyled TextEdit Structure. In a multistyled edit text structure, this field is set to is -1, indicating that the TextEdit structure contains associated character attribute information. The txFont, txFace, and filler fields combine to form a handle to the style structure in which this character attribute information is stored. |
inPort |
A pointer to the graphics port associated with this edit text structure. |
highHook |
A universal procedure pointer to the function that deals with text highlighting. |
caretHook |
A universal procedure pointer to the function that controls the appearance of the caret. |
numLines |
The number of lines of text. |
lineStarts |
A dynamic array which contains the character position of the first character in each line of the text. This array grows and shrinks, containing only as many elements as needed. |
The Dispatch Structure
The hDispatchRec field of the TextEdit structure stores a handle to the dispatch structure. The dispatch structure is an internal data structure whose fields contain the addresses of functions which determine the way TextEdit behaves. You can modify TextEdit's default behaviour by replacing the address of a default function in the dispatch structure with the address of your own customized function.
Monostyled TextEdit
This section describes the use of TextEdit with monostyled text, that is, text with a single typeface, style, and size. Everything in this section also applies to using TextEdit with multistyled text except where otherwise indicated.
Creating, and Disposing of, a Monostyled TextEdit Structure
Creating a Monostyled TextEdit Structure
To use TextEdit functions, you must first create a TextEdit structure using TENew. TENew returns a handle to the newly-created monostyled edit text structure. You typically store the returned handle in a field of a document structure, the handle to which is typically stored in the application window's refCon field.
The required destination and view rectangles are specified in the TENew call. You should inset the destination rectangle at least four pixels from the left and right edges of the graphics port, making an additional allowance for scroll bars as appropriate. This will ensure that the first and last glyphs in each line are fully visible. You typically make the view rectangle equal to the destination rectangle. (If you do not want the text to be visible, specify a view rectangle off the screen.)
When a TextEdit structure is created, TextEdit initialises the TextEdit structure's fields based on values in the current graphics port object and on the type of TextEdit structure you create.
Disposing of a TextEdit Structure
Memory allocated for a TextEdit structure may be released by calling TEDispose.
Setting the Text
A new TextEdit structure does not contain any text until the user either opens an existing document or enters text via the keyboard. The following is concerned with existing documents.
TESetText may be used to specify the text to be edited. Alternatively, you can set the hText field of the TextEdit structure directly.
Calling TESetText
When a user opens a document, your application can load that document's text and then call TESetText. TESetText creates a copy of the text and stores the copy in the existing handle of the TextEdit structure's hText field.
You must pass the length of the text in the call to TESetText. TESetText uses this to reset the teLength field of the TextEdit structure, and to set the selStart and selEnd fields to the last byte offset of the text. TESetText also calculates the line breaks.
TESetText does not cause the text to be displayed immediately. You must call InvalWindowRect to force the text to be displayed at the next update event for the active window.
Changing the hText Field
The alternative of setting the hText field directly, replacing the existing handle with the handle of the new text, saves memory if you have a lot of text. When you use this method, you must also assign the length of the text to the teLength field of the TextEdit structure and call TECalText to recalculate the lineStarts array and numLines values.
Responding to Events
Activate Events
When your application receives an activate event (Classic event model) or kEventWindowActivated or kEventWindowDeactivated event type (Carbon event model, it should call TEActivate or TEDeactivate as appropriate.
A TextEdit structure which has been activated by TEActivate has its selection highlighted or, if there is no selection, has its caret displayed and blinking at the insertion point. A TextEdit structure which has been deactivated by TEDeactivate has its selection range outlined (if outline highlighting is enabled) or, if there is no selection, has a grey, unblinking caret displayed at the insertion point.
|
Outline highlighting may be activated and deactivated using TEFeatureFlag.
|
Note that, when you use TEClick and TESetSelect (see below) to set the selection range or insertion point, the selection range is not highlighted, or the blinking caret is not displayed, until the TextEdit structure is activated. (However, if outline highlighting is enabled , the text of the selection range will be framed or a gray, unblinking caret will be displayed.)
Update Events - Calling TEUpdate
When your application receives an update event (Classic event model) or kEventWindowDrawContent or kEventWindowUpdate event type (Carbon event model), it should call TEUpdate. In addition, you should call TEUpdate after changing any fields of the TextEdit structure, or after any editing or scrolling operation, which alters the onscreen appearance of the text.
Mouse-Down Events - Calling TEClick
On receipt of a mouse-down event that should be handled by TextEdit, your application must pass the event to TEClick. TEClick tells TextEdit that a mouse-down event has occurred. Before calling TEClick, however, your application must:
- Convert the mouse location passed in the event structure from global coordinates to the local coordinates required by TEClick.
- Determine if the Shift key was held down at the time of the event.
TEClick repeatedly calls the click loop function (see below) as long as the mouse button is held down and retains control until the button is released. The behaviour of TEClick depends on whether the Shift key was down at the time of the mouse-down event and on other user actions as follows:
User's Action |
Behaviour of TEClick |
Shift key down. |
Extend the current selection range. |
Shift key not down. |
Remove highlighting from current selection range. Position the insertion point as close as possible to the location of the mouse click. |
Mouse dragged. |
Expand or shorten the selection range a character at a time. Keep control until the user releases the mouse button. |
Double-click. |
Extend the selection to include the entire word where the cursor is positioned. |
Key-Down Events - Accepting Text Input
On receipt of a key-down event that should be handled by TextEdit, your application must call TEKey to accept the keyboard input. TEKey replaces the current selection range with the character passed to it and moves the insertion point just past the inserted character.
Depending on the requirements of your application, you may need to filter out certain character codes (for example, that for a Tab key press) so that they are not passed to TEKey. You should also check that the TextEdit limit of 32,767 bytes will not be exceeded by the insertion of the character before calling TEKey and you should call your scroll bar adjustment function immediately after the insertion.
Caret Blinking
To force the insertion point caret to blink, your application must call TEIdle at an interval equal to the value stored in the low-memory global CaretTime. You can retrieve this value by calling GetCaretTime. In Classic event model applications, you should set the sleep parameter in the WaitNextEvent call to this value and call TEIdle when WaitNextEvent returns 0 with a null event. In Carbon event model applications, you should install a timer set to fire at this interval and call TEIdle when the timer fires.
If there is more than one edit text structure associated with an active window, you must ensure that you pass TEIdle the handle to the currently active edit text structure. You should also check that the handle to be passed to TEIdle does not contain NULL before calling the function.
Cutting, Copying, Pasting, Inserting, and Deleting Text
Cutting, Copying, and Pasting
You can use TextEdit to cut, copy, and paste text within a single edit text structure, between edit text structures, or across applications. The relevant functions, and their effect in the case of a monostyled edit text structure, are as follows:
Function |
Use To |
Comments |
TECut |
Cut text. |
Copies the text to the TextEdit private scrap. |
TECopy |
Copy text. |
Copies the text to the TextEdit private scrap. |
TEPaste |
Paste text. |
Pastes from the TextEdit private scrap to the TextEdit structure. |
TEToScrap |
Copy TextEdit private scrap to the Carbon Scrap Manager's scrap. |
Copying via the Carbon Scrap Manager's scrap is required if text is to be carried across applications. |
TEFromScrap |
Copy the Carbon Scrap Manager's scrap to TextEdit private scrap. |
Copying via the Carbon Scrap Manager's scrap is required if monostyled text is to be carried across applications. |
TEGetScrapLength |
Determine the length of the text to be pasted. |
Returns the size, in bytes, of the text in the private scrap. |
You will need to call your vertical scroll bar adjustment function immediately after cut and paste operations. You will need to call your vertical scroll bar adjustment function immediately after cut and paste operations. In addition, you will need to ensure that a paste will not cause the TextEdit limit of 32,767 bytes to be exceeded.
Inserting and Deleting Text
The following TextEdit functions are used to insert and delete monostyled text:
Function |
Use To |
Comments |
TEInsert |
Insert text into the TextEdit structure immediately before the selection range or insertion point. |
Does not affect the selection range.
Redraws the text if necessary. |
TEDelete |
Remove the selected range of text from the TextEdit structure. |
Does not transfer the text to either TextEdit's private scrap or the Carbon Scrap Manager's scrap.
Useful for implementing a Clear command.
Redraws the remaining text if necessary. |
You will need to call your vertical scroll bar adjustment function immediately after insertions and deletions. In addition, you will need to ensure that an insertion will not cause the TextEdit limit of 32,767 bytes to be exceeded.
Setting the Selection Range or Insertion Point
Using the TESetSelect function, your application can set the selection range or set the location of the insertion point. (For example, your application might use TESetSelect to locate the caret at the start of a data entry field where you want the user to enter a value.) TESetSelect changes the value in the selStart and selEnd fields of the TextEdit structure.
To set a selection range, you pass the byte offsets of the starting and ending characters in the selStart and selEnd parameters. To set the location of the insertion point, you pass the same values in the selStart and selEnd parameters. You can set the selection range (or insertion point) to any character position corresponding to byte offsets 0 to 32767.
To implement a Select All menu command, pass 0 in the selStart parameter and the value in the teLength field of the TextEdit structure in the selEnd parameter.
Enabling, Disabling, and Customising Automatic Scrolling
Enabling and Disabling
You can use the TEAutoView function to enable automatic scrolling (which, by default, is disabled). TEAutoView may also be used to disable automatic scrolling.
Customising
As previously stated, the default click loop (callback) function does not adjust the scroll bars as the text is scrolled, a situation that can be overcome by replacing the default click loop function with an application-defined click loop (callback) function which updates the scroll bars as it scrolls the text.
The clickLoop field of the TextEdit structure contains a universal procedure pointer to a click loop (callback) function, which is called continuously as long as the mouse button is held down. Installing your custom function involves a call to TESetClickLoop to assign the universal procedure pointer to the TextEdit structure's clickLoop field.
Scrolling Text
When a mouse-down event occurs in a scroll bar, your application must determine how far to scroll the text. The basic value for vertical scrolling of monostyled text is typically the value in the lineHeight field of the TextEdit structure, which can be used as the number of pixels to scroll for clicks in the Up and Down scroll arrows. For clicks in the gray areas/track, this value is typically multiplied by the number of text lines in the view rectangle minus 1. Scrolling by dragging the scroll box/scroller involves determining the number of text lines to scroll based on the current position of the top of the destination rectangle and the control value on mouse button release.
You pass the number of pixels to scroll in a call to TEScroll or TEPinScroll. (The difference between these two functions is that the latter stops scrolling when the last line is scrolled into the view rectangle.) The destination rectangle is offset by the amount you scroll.
Forcing the Selection Range Into the View
Your application can call TESelView to force the selection range to be displayed in the view rectangle. When automatic scrolling is enabled, TESelView scrolls the selection range into view, if necessary.
Setting Text Alignment
You can change the alignment of the entire text of a TextEdit structure by calling TESetAlignment (old name TESetJust). The following constants apply:
Constant |
Description |
teFlushDefault |
Default alignment according to primary line direction of the script system. (Left for Roman script system.) |
teCenter |
Centre alignment. |
teFlushRight |
Right alignment. |
teFlushLeft |
Left alignment. |
You should call the Window manager's InvalWindowRect function after you change the alignment so that the text is redrawn in the new alignment.
Saving and Opening TextEdit Documents
The demonstration program at Chapter 18 demonstrates opening and saving monostyled TextEdit documents.
Multistyled TextEdit
With the introduction, with Mac OS 9, of the Multilingual Text Editor (see Chapter 26), it became all but inconceivable that programmers would ever again use multistyled TextEdit to provide their applications with multi-styled text editing capabilities. That said, multistyled TextEdit may still be considered useful where the requirement is simply the display of non-editable multi-styled text, as in the Help dialog component of the demonstration program associated with this chapter.
This section addresses additional factors and considerations applying to multistyled TextEdit, but only to the extent necessary to gain an understanding of those factors involved in the display of non-editable styled text.
Text With Multiple Styles - Style Runs, Text Segments, Font Runs, Character Attributes
Text which uses a variety of fonts, styles, sizes, and colours is referred to as multistyled text.
TextEdit organises multistyled text into style runs, which comprise a sets of contiguous characters which all share the same font, size, style, and colour characteristics. TextEdit tracks style runs in the data structures allocated for a multistyled edit text structure and uses this information to correctly display multistyled text.
The part of a style run that exists on a single line is called a text segment. A larger division than a style run is the font run, which comprises those characters which share the same font. The font, style, size, and colour aspects of text are collectively referred to as character attributes.
Additional TextEdit Data Structures for Multistyled Text
The edit text structure and the dispatch structure are the only data structures associated with monostyled text. However, when you allocate a multistyled edit text structure, a number of additional subsidiary data structures are created to support the text styling capabilities. The first of these additional data structures is the style structure, which stores the character attribute information for the text. (Recall that, when a multistyled edit text structure is created, the bytes at the txFont, txFace, and filler fields of the TextEdit structure contain a handle to the style structure.)
The additional data structures associated with a multistyled edit text structure are shown at Fig 6.
Creating a Multistyled TextEdit Structure
The multistyled edit text structure is created by calling TEStyleNew.
Inserting Text
The following describes TEStyleInsert, which is used to insert multistyled text:
Function |
Use To |
Comments |
TEStyleInsert |
Insert multistyled text into the TextEdit structure immediately before the selection range or insertion point. |
Does not affect the selection range.
Redraws the text if necessary.
Applies the specified character attributes to the text. (You should create your own style scrap structure, specifying the style attributes to be inserted and applied to the text. These attributes are copied directly into the style structure's style table.) |
Formatting and Displaying Dates, Times, and Numbers
Preamble - The Text Utilities and International Resources
The Text Utilities
The Text Utilities are a collection of text-handling functions which you can use to, amongst other things, format numbers, currency, dates, and times.
International Resources
Many Text Utilities functions utilise the international resources, which define how different text elements are represented depending on the script system in use. The international resources relevant to formatting numbers, currency, dates, and times are as follows:
- Numeric Format Resource. The numeric format ('itl0') resource contains short date and time formats, and formats for currency and numbers. It provides separators for decimals, thousands, and lists. It also contains the region code for this particular resource. Three of the several variations in short date and time formats are as follows:
System Software |
Morning |
Afternoon |
Short Date |
United States |
1:02 AM |
1:02 PM |
2/1/90 |
Sweden |
01:02 |
13:02 |
90-01-01 |
Germany |
1:02 Uhr |
13:02 Uhr |
2.1.1990 |
- Long Date Format Resource. The long date format ('itl1') resource specifies the long and abbreviated date formats for a particular region, including the names of days and months and the exact order of presentation of the elements. It also contains a region code for this particular resource. Three of the several variations of the long and abbreviated date formats are as follows:
System Software |
Abbreviated Date |
Long Date |
United States |
Tue, Jan 2, 1990 |
Tuesday, January 2 1990 |
French |
Mar 2 Jan 1990 |
Mardi 2 Janvier 1990 |
Australian |
Tue, 2 Jan 1990 |
Tuesday, 2 January 1990 |
- Tokens Resource. The tokens ('itl4') resource contains, amongst other things, a table for formatting numbers. This table, which is called the number parts table, contains standard representations for the components of numbers and numeric strings. As will be seen, certain Text Utilities number formatting functions use the number parts table to create number strings in localised formats.
Date and Time
The Text Utilities functions which work with dates and times use information in the international resources to create different representations of date and time values. The Operating System provides functions that return the current date and time in numeric format. Text Utilities functions can then be used to convert these values into strings which can, in turn, be presented in the different international formats.
Date and Time Value Representations
The Operating System provides the following differing representations of date and time values:
Representation |
Description |
Standard date-time value. |
A 32-bit integer representing the number of seconds between midnight, 1 January 1904 and the current time. |
Long date-time value. |
A 64-bit signed representation of data type LongDateTime.
Allows for coverage of a longer time span than the standard date-time value, specifically, about 30,000 years. |
|
Date-time structure. |
Data type DateTimeRec. Includes integer fields for year, month, day, hour, minute, second, and day of week. |
Long date-time structure. |
Data type LongDateRec. Similar to the date-time structure, except that it adds several additional fields, including integer values for the era, day of the year, and week of the year. Allows for a longer time span than the date-time structure. |
The date-time (DateTimeRec) and the long date-time (LongDateRec) structures are as follows:
union LongDateRec
{
struct
struct DateTimeRec {
{ short era;
short year; short year;
short month; short month;
short day; short day;
short hour; short hour;
short minute; short minute;
short second; short second;
short dayOfWeek; short dayOfWeek;
}; short dayOfYear;
short weekOfYear;
typedef struct DateTimeRec DateTimeRec; short pm;
short res1;
short res2;
short res3;
} ld;
short list[14];
struct
{
short eraAlt;
DateTimeRec oldDate;
} od;
};
typedef union LongDateRec LongDateRec;
Obtaining Date-Time Values and Structures
The Operating System Utilities provide the following two functions for obtaining date-time values and structures.
Function |
Description |
GetDateTime |
Returns a standard date-time value. |
GetTime |
Returns a date-time structure. |
Converting Between Values and Structures
The Operating System provides the following four functions for converting between the different date and time data types:
Function |
Converts |
To |
DateToSeconds |
Date-time structure. |
Standard date-time value. |
SecondsToDate |
Standard date-time value. |
Date-time structure. |
LongDateToSeconds |
Long date-time structure. |
Long date-time value. |
LongSecondsToDate |
Long date-time value. |
Long date-time structure. |
Converting Date-Time Values Into Strings
The Text Utilities provide the following functions for converting from one of the numeric date-time representations to a formatted string.
Function |
Description |
DateString |
Converts standard date-time value to a date string formatted according to the specified international resource. |
LongDateString |
Converts long date-time value to a date string formatted according to the specified international resource. |
TimeString |
Converts standard date-time value to a time string formatted according to the specified international resource. |
LongTimeString |
Converts long date-time values to a time string formatted according to the specified international resource. |
Output Format - Date. When you use DateString and LongDateString, you can specify, in the longFlag parameter, an output format for the resulting date string. This format can be one of the following three values of the DateForm enumerated data type:
Value |
Date String Produced (Example) |
Formatting Information Obtained From |
shortDate |
1/31/92 |
Numeric format resource ('itl0'). |
abbrevDate |
Fri, Jan 31, 1992 |
Long date format resource ('itl1'). |
longDate |
Friday, January 31, 1992 |
Long date format resource ('itl1'). |
Output Format - Time. When you use TimeString and LongTimeString, you can request an output format for the resulting time string by specifying either true or false in the wantSeconds parameter. true will cause seconds to be included in the string.
DateString, LongDateString, TimeString and LongTimeString use the date and time formatting information in the format resource that you specify in the resource handle (intlHandle) parameter. If you specify NULL for the value of the resource handle parameter, the appropriate format resource for the current script system is used.
Converting Date-Time Strings Into Internal Numeric Representation
The Text Utilities include functions which can parse date and time strings as entered by users and fill in the fields of a structure with the components of the date and time, including the month, day, year, hours, minutes, and seconds, extracted from the string.
Suppose your application needs to, say, convert a date and time string typed in by the user (for example, "March 27, 1992, 08:14 p.m.") into numeric representation. The following Text Utilities functions may be used to convert the string entered by the user into a long date-time structure:
Function |
Description |
StringToDate |
Parses an input string for a date and creates an internal numeric representation of that date. Returns a status value indicating the confidence level for the success of the conversion.
Expects a date specification, in one of the formats defined by the current script system, at the beginning of the string. Recognizes date strings in many formats, for example: "September 1,1987", "1 Sept 87", "1/9/87", and "1 1987 Sept". |
StringToTime |
Parses an input string for a time and creates an internal numeric representation of that time. Returns a status value indicating the confidence level for the success of the conversion.
Expects a time specification, in a format defined by the current script system, at the beginning of the string. |
You usually call StringToDate and StringToTime sequentially to parse the date and time values from an input string and fill in these fields. Note that StringToDate assigns to its lengthUsed parameter the number of bytes that it uses to parse the date. Use this value to compute the starting location of the text that you can pass to StringToTime.
The "confidence level" value returned by both StringToDate and StringToTime is of type StringToDateStatus, a set of bit values which have been OR'd together. The higher the resultant number, the lower the confidence level. Three of the twelve StringToDateStatus values, and their meanings, are as follows:
Value |
Meaning |
fataldateTime |
Fatal error during the parse. |
dateTimeNotFound |
Valid date or time value not be found in string. |
sepNotIntlSep |
Valid date or time value found, but one or more of the separator characters in the string was not an expected separator character for the script system in use. |
Date Cache Structure. Both StringToDate and StringToTime take a date cache structure as one of their parameters. A date cache structure (a data structure of type DateCacheRec) stores date conversion data used by the date and time conversion functions. You must declare a data cache structure in your application and initialise it by calling InitDateCache once, typically in your main program initialisation code.
Numbers
The Text Utilities provide several functions for converting between the internal numeric representation of a number and the output (or input) format of that number. You will need to perform these conversions when the user enters numbers for your application to use or when you present numbers to the user.
Integers
The simplest number conversion tasks involve integer values. The following Text Utilities functions may be used to convert an integer value to a numeric string and vice versa:
Function |
Description |
NumToString |
Converts a long integer value into a string representation. |
StringToNum |
Converts a string representation of a number into a long integer value. |
The range of values accommodated by these functions is -2,147,483,647 to 2,147,483,648. No comma insertion or other formatting is performed.
Number Format Specification Strings
Number format specification strings define the appearance of numeric strings. When you need to accommodate the differences in number output formats for different countries and regions, or when you are working with floating point numbers, you will need to use number format specification strings.
Parts. Each number format specification string contains up to three parts:
- The positive number format.
- The negative number format.
- The zero number format.
Each of these formats is applied to a numeric value of the corresponding type. When the specification string contains only one part, that part is used for all values. When in contains two parts, the first part is used for positive and zero values and the second part is used for negative values.
Elements. A number format specification string can contain the following elements:
- Number parts separators (, and .) for the decimal separator and the thousands separator.
- Literals to be included in the output. (Literals can be strings or brackets, braces and parentheses, and must be enclosed in quotation marks.)
- Digit place holders. (Digit place holders that you want displayed must be indicated by digit symbols. Zero digits (0) add leading zeroes whenever an input digit is not present. Skipping digits (#) only produce output characters when an input digit is present. Padding digits (^) are like zero digits except that a padding character such as a non-breaking space is used instead of leading zeros to pad the output string.)
- Quoting mechanisms for handling literals correctly.
- Symbol and sign characters.
Examples. The following shows several different number format specification strings and the output produced by each:
Number Format Specification String |
Numeric Value |
Output Format |
###,###.##;-###,###.##;0 |
876543.21 |
876,543.21 |
###,###.0##,### |
4321 |
4,321.0 |
###,###.0##,### |
7.563489 |
7.563,489 |
###;(000);^^^ |
-1 |
(001) |
###.### |
5.234999 |
5.235 |
###'CR';###'DB';''zero'' |
1 |
1CR |
###'CR';###'DB';''zero'' |
0 |
'zero' |
##% |
0.1 |
10% |
Integer digits are always filled in from the right and decimal places are always filled in from the left. The following examples, in which a literal is included in the middle of the format strings, demonstrate this behaviour:
Number Format Specification String |
Numeric Value |
Output Format |
###'ab'### |
1 |
1 |
###'ab'### |
123 |
123 |
###'ab'### |
1234 |
1ab1234 |
0.###'ab'### |
0.1 |
0.1 |
0.###'ab'### |
0.123 |
1.123 |
0.###'ab'### |
0.1234 |
0.123ab4 |
Overflow and Rounding. If the input string contains more digits than are specified in the number format specification string, an error (formatOverflow) will be generated. If the input string contains more decimal places than are specified in the number format specification string, the decimal portion is automatically rounded.
Converting Number Format Specification Strings to Internal Numeric Representations. With the required number format specification string defined, you must then convert the string into an internal numeric representation. The internal representation of format strings is stored in a NumFormatString structure. You use the following functions to convert a number format specification string to a NumFormatString structure and vice versa.
Function |
Description |
StringToFormatRec |
Converts a number format specification string into a NumFormatString structure. |
FormatRecToString |
Convert a NumFormatString structure back to a number format specification string. |
Number Parts Table. The internal numeric representation allows you to map the number into different output formats. One of the parameters taken by StringToFormatRec is a number parts table. The number parts table specifies which characters are used for certain purposes, such as separating parts of a number (for example, a thousands separator is a comma in Australia and a decimal point in France), in the format specification string. As previously stated, the number parts table is contained in the 'itl4' resource. A handle to the 'itl4' resource may be obtained by a call to GetIntlResourceTable, specifying iuNumberPartsTable in the tableCode parameter.
|
The FormatRecToString function also contains a number parts table parameter. By using a different table than was used in the call to StringToFormatRec, you can produce a number format specification string that specifies how numbers are formatted for a different region of the world. You use FormatRecToString when you want to display the number format specification string to the user for perusal or modification.
|
Converting Between Floating Point Numbers and Numeric Strings
Armed with a NumFormatString structure, you can convert floating point numbers into numeric strings and numeric strings into floating point numbers using the following functions:
Function |
Description |
StringToExtended |
Using a NumFormatString structure and a number parts table, converts a numeric string to an 80-bit floating point value. |
ExtendedToString |
Using a NumFormatString structure and a number parts table, converts an 80-bit floating point number to a numeric string. |
PowerPC Considerations. The PowerPC-based Macintosh follows the IEEE 754 standard for floating point arithmetic. In this standard, float is 32 bits and double is 64 bits. (Apple has added the 128 bit long double type.) However, the PowerPC floating point unit does not support Motorola's 80/96-bit extended type, and neither do the PowerPC numerics. To accommodate this, you can use Apple-supplied conversion utilities to move to and from extended. For example, the functions x80tod and dtox80 (see the header file fp.h) can be used to directly transform 680x0 80-bit extended data types to double and back.
StringToFormatRec, FormatRecToString, StringToExtended, and ExtendedToString return a result of type FormatStatus, which is an integer value. The low byte is of type FormatResultType. Typical examples of the returned format status are as follows:
Value |
Meaning |
fFormatOK |
The format of the input value is appropriate and the conversion was successful. |
fBestGuess |
The format of the input value is questionable. The result of the conversion may or may not be correct. |
fBadPartsTable |
The parts table is not valid. |
Main TextEdit Constants, Data Types and Functions
Constants
Alignment
teFlushDefault = 0
teCenter = 1
teFlushRight = -1
teFlushLeft = -2
Feature or Bit Definitions for TEFeatureFlag feature Parameter
teFAutoScroll = 0
teFTextBuffering = 1
teFOutlineHilite = 2
teFInlineInput = 3
teFUseWhiteBackground = 4
teFUseInlineInput = 5
teFInlineInputAutoScroll = 6
Data Types
typedef char Chars[32001];
typedef char *CharsPtr;
typedef CharsPtr *CharsHandle;
TextEdit Structure
struct TERec
{
Rect destRect; // Destination rectangle.
Rect viewRect; // View rectangle.
Rect selRect; // Selection rectangle.
short lineHeight; // Vert spacing of lines. -1 in multistyled.
short fontAscent; // Font ascent. -1 in multistyled TextEdit structure.
Point selPoint; // Point selected with the mouse.
short selStart; // Start of selection range.
short selEnd; // End of selection range.
short active; // Set when structure is activated or deactivated.
WordBreakUPP wordBreak; // Word break function.
TEClickLoopUPP clickLoop; // Click loop function.
long clickTime; // (Used internally.)
short clickLoc; // (Used internally.)
long caretTime; // (Used internally.)
short caretState; // (Used internally.)
short just; // Text alignment.
short teLength; // Length of text.
Handle hText; // Handle to text to be edited.
long hDispatchRec; // Handle to TextEdit dispatch structure.
short clikStuff; // (Used internally)
short crOnly; // If < 0, new line at Return only.
short txFont; // Text font. // If multistyled edit struct (txSize = -1),
StyleField txFace; // Chara style. // these bytes are used as a handle
SInt8 filler; // // to a style structure (TEStyleHandle).
short txMode; // Pen mode.
short txSize; // Font size. -1 in multistyled TextEdit structure.
GrafPtr inPort; // Pointer to grafPort for this TextEdit structure.
HighHookUPP highHook; // Used for text highlighting, caret appearance.
CaretHookUPP caretHook; // Used from assembly language.
short nLines; // Number of lines.
short lineStarts[16001]; // Positions of line starts.
};
typedef struct TERec TERec;
typedef TERec *TEPtr;
typedef TEPtr *TEHandle;
Style Structure
struct TEStyleRec
{
short nRuns; // Number of style runs.
short nStyles; // Size of style table.
STHandle styleTab; // Handle to style table.
LHHandle lhTab; // Handle to line-height table.
long teRefCon; // Reserved for application use.
NullStHandle nullStyle; // Handle to style set at null selection.
StyleRun runs[8001]; // ARRAY [0..8000] OF StyleRun.
};
typedef struct TEStyleRec TEStyleRec;
typedef TEStyleRec *TEStylePtr;
typedef TEStylePtr *TEStyleHandle;
Text Style Structure
struct TextStyle
{
short tsFont; // Font (family) number.
StyleField tsFace; // Character Style.
short tsSize; // Size in point.
RGBColor tsColor; // Absolute (RGB) color.
};
typedef struct TextStyle TextStyle;
typedef TextStyle *TextStylePtr;
typedef TextStylePtr *TextStyleHandle;
Functions
Initialising TextEdit, Creating a TextEdit Structure, Disposing of a TextEdit Structure
void TEInit(void);
TEHandle TENew(const Rect *destRect,const Rect *viewRect);
TEHandle TEStyleNew(const Rect *destRect,const Rect *viewRect);
void TEDispose(TEHandle hTE);
Activating and Deactivating a TextEdit Structure
void TEActivate(TEHandle hTE);
void TEDeactivate(TEHandle hTE);
Setting and Getting a TextEdit Structure's Text
void TEKey(short key,TEHandle hTE);
void TESetText(const void *text,long length,TEHandle hTE);
CharsHandle TEGetText(TEHandle hTE);
Setting the Caret and Selection Range
void TEIdle(TEHandle hTE);
void TEClick(Point pt,Boolean fExtend,TEHandle h);
void TESetSelect(long selStart,long selEnd,TEHandle hTE);
Displaying and Scrolling Text
void TESetAlignment(short just,TEHandle hTE);
void TEUpdate(const Rect *rUpdate,TEHandle hTE);
void TETextBox(const void *text,long length,const Rect *box,short just);
void TECalText(TEHandle hTE);
long TEGetHeight(long endLine,long startLine,TEHandle hTE);
void TEScroll(short dh,short dv,TEHandle hTE);
void TEPinScroll(short dh,short dv,TEHandle hTE);
void TEAutoView(Boolean fAuto,TEHandle hTE);
void TESelView(TEHandle hTE);
Modifying the Text of a TextEdit Structure
void TEDelete(TEHandle hTE);
void TEInsert(const void *text,long length,TEHandle hTE);
void TEStyleInsert(const void *text,long length,StScrpHandle hST,TEHandle hTE);
void TECut(TEHandle hTE);
void TECopy(TEHandle hTE);
void TEPaste(TEHandle hTE);
OSErr TEFromScrap(void);
OSErr TEToScrap(void);
Managing the TextEdit Private Scrap
#define TEScrapHandle(); (* (Handle*) 0xAB4);
#define TEGetScrapLength(); ((long) * (unsigned short *) 0x0AB0);
void TESetScrapLength(long length);
Checking, Setting, and Replacing Styles
void TESetStyle(short mode,const TextStyle *newStyle,Boolean redraw,
TEHandle hTE);
void TEReplaceStyle(short mode,const TextStyle *oldStyle,
const TextStyle *newStyle,Boolean fRedraw,TEHandle hTE);
Boolean TEContinuousStyle(short *mode,TextStyle *aStyle,TEHandle hTE);
void TEStyleInsert(const void *text,long length,StScrpHandle hST,TEHandle hTE);
TEStyleHandle TEGetStyleHandle(TEHandle hTE);
StScrpHandle TEGetStyleScrapHandle(TEHandle hTE);
void TEUseStyleScrap(long rangeStart,long rangeEnd,StScrpHandle newStyles,
Boolean fRredraw,TEHandle hTE);
long TENumStyles(long rangeStart,long rangeEnd,TEHandle hTE);
Using Byte Offsets and Corresponding Points
short TEGetOffset(Point pt,TEHandle hTE);
Point TEGetPoint(short offset,TEHandle hTE);
Customising TextEdit
void TESetClickLoop(TEClickLoopUPP clikProc,TEHandle hTE);;
void TESetWordBreak(WordBreakUPP wBrkProc,TEHandle hTE);;
void TECustomHook(TEIntHook which, UniversalProcPtr *addr,TEHandle hTE);
Additional TextEdit Features
short TEFeatureFlag(short feature,short action,TEHandle hTE);
Main Constants, Data Types and Functions Relating to Dates, Times and Numbers
Constants
StringToDate and StringToTime Status Values
fatalDateTime = 0x8000 Mask to a fatal error.
longDateFound = 1 Mask to long date found.
leftOverChars = 2 Mask to warn of left over characters.
sepNotIntlSep = 4 Mask to warn of non-standard separators.
fieldOrderNotIntl = 8 Mask to warn of non-standard field order.
extraneousStrings = 16 Mask to warn of unparsable strings in text.
tooManySeps = 32 Mask to warn of too many separators.
sepNotConsistent = 64 Mask to warn of inconsistent separators.
tokenErr = 0x8100 Mask for 'tokenizer err encountered'.
cantReadUtilities = 0x8200
dateTimeNotFound = 0x8400
dateTimeInvalid = 0x8800
FormatResultType Values for Numeric Conversion Functions
fFormatOK = 0
fBestGuess = 1
fOutOfSynch = 2
fSpuriousChars = 3
fMissingDelimiter = 4
fExtraDecimal = 5
fMissingLiteral = 6
fExtraExp = 7
fFormatOverflow = 8
fFormStrIsNAN = 9
fBadPartsTable = 10
fExtraPercent = 11
fExtraSeparator = 12
fEmptyFormatString = 13
Data Types
typedef short StringToDateStatus;
typedef SInt8 DateForm;
typedef short FormatStatus;
typedef Sint8 FormatResultType;
Data Cache Structure
struct DateCacheRecord
{
short hidden[256]; // Only for temporary use.
};
typedef struct DateCacheRecord DateCacheRecord;
typedef DateCacheRecord *DateCachePtr;
Number Format Specification Structure
struct NumFormatString
{
UInt8 fLength;
UInt8 fVersion;
char data[254]; // Private data.
};
typedef struct NumFormatString NumFormatString;
typedef NumFormatString NumFormatStringRec;
Functions
Getting Date-Time Values and Structures
void GetDateTime(unsigned long *secs);
void GetTime(DateTimeRec *d);
Converting Between Date-Time values and Structures
void DateToSeconds(const DateTimeRec *d,unsigned long *secs);
void SecondsToDate(unsigned long secs,DateTimeRec *d);
void LongDateToSeconds(const LongDateRec *lDate,LongDateTime *lSecs);
void LongSecondsToDate(LongDateTime *lSecs,LongDateRec *lDate);
Converting Date-Time Strings Into Internal Numeric Representation
OSErr InitDateCache(DateCachePtr theCache);
StringToDateStatus StringToDate(Ptr textPtr,long textLen,DateCachePtr theCache,
long *lengthUsed,LongDateRec *dateTime);
StringToDateStatus StringToTime(Ptr textPtr,long textLen,DateCachePtr theCache,
long *lengthUsed,LongDateRec *dateTime);
Converting Long Date and Time Values Into Strings
void DateString(long dateTime,DateForm longFlag,Str255 result);
void TimeString(long dateTime,Boolean wantSeconds,Str255 result);
void LongDateString(LongDateTime *dateTime,DateForm longFlag,
Str255 result,Handle intlHandle);
void LongTimeString(LongDateTime *dateTime,Boolean wantSeconds,
Str255 result,Handle intlHandle);
Converting Between Integers and Strings
void StringToNum(ConstStr255Param theString,long *theNum);
void NumToString(long theNum,Str255 theString);
Using Number Format Specification Strings For International Number Formatting
FormatStatus StringToFormatRec(ConstStr255Param inString,
const NumberParts *partsTable,NumFormatString *outString)
FormatStatus FormatRecToString(const NumFormatString *myCanonical,
const NumberParts *partsTable,Str255 outString,TripleInt positions)
Converting Between Strings and Floating Point Numbers
FormatStatus ExtendedToString(const extended80 x,
const NumFormatString *myCanonical,const NumberParts *partsTable,
Str255 outString);
FormatStatus StringToExtended(ConstStr255Param source,
const NumFormatString *myCanonical,const NumberParts *partsTable,
extended80 *x);
Moving To and From Extended
void x80told(const extended80 *x80,long double *x);
void ldtox80(const long double *x,extended80 *x80);
double x80tod(const extended80 *x80);
void dtox80(const double *x, extended80 *x80);
|