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 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.

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.

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:

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.

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 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.

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.

Software Updates via MacUpdate

Bookends 12.5.8 - Reference management a...

Bookends is a full-featured bibliography/reference and information-management system for students and professionals.
Access the power of Bookends directly from Mellel, Nisus Writer Pro, or MS Word (... Read more

Chromium 44.0.2403.125 - Fast and stable...

Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web.
Version 44.0.2403.125:
This release contains a number... Read more

iMazing 1.2.2 - Complete iOS device mana...

iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can:
Copy music to and from... Read more

Audio Hijack 3.2.0 - Record and enhance...

Audio Hijack (was Audio Hijack Pro) drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio... Read more

FontExplorer X Pro 5.0.1 - Font manageme...

FontExplorer X Pro is optimized for professional use; it's the solution that gives you the power you need to manage all your fonts.
Now you can more easily manage, activate and organize your... Read more

Calcbot 1.0.2 - Intelligent calculator a...

Calcbot is an intelligent calculator and unit converter for the rest of us. Featuring an easy-to-read history tape, expression view, intuitive conversion, and much more!
Features
History Tape -... Read more

MTR 5.0.0.1 - The Mac's oldest and...

MTR (was MacTheRipper)--the Mac's oldest and smartest DVD-backup app--is now updated to version 5.001
MTR -- the complete toolbox, not a one-trick, point-and-click extractor. MTR is intended for... Read more

LibreOffice 4.4.5.2 - Free, open-source...

LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more

Adobe Lightroom 6.1.1 - Import, develop,...

Adobe Lightroom is available as part of Adobe Creative Cloud for as little as $9.99/month bundled with Photoshop CC as part of the photography package. Lightroom 6 is also available for purchase as a... Read more

File Juicer 4.41 - Extract images, video...

File Juicer is a drag-and-drop can opener and data archaeologist. Its specialty is to find and extract images, video, audio, or text from files which are hard to open in other ways.
It finds and... Read more

Bandai Namco has released Pac-Man Championship Edition DX on iOS and Android, which features the classic arcade gameplay that we've all grown to love.
Pac-Man Championship Edition DX can be enjoyed in much shorter bursts than the arcade versions... | Read more »

Angel Stone is Fincon's follow up to the massively successful Hello Hero and is out now on iOS and Android.
You play as a member of The Resistance, a group of mighty human warriors who have risen up in defiance of the Demon horde threatening to... | Read more »

The not exactly rumors were true and the birds are back. Angry Birds 2 has come to the App Store and the world will... well I suppose it'll still be the same, but now we have more bird-flinging options!
[Read more]
| Read more »

You Could Design Your Own Card for Chain...

If you've ever wanted to create your own item, weapon, trap, or even monster for Chainsaw Warrior: Lords of the Night, this is your chance. Auroch Digital is currently holding a contest so that fans can fight to the death (not really) to see which... | Read more »

Bitcoin Billionaire is Going Back in Tim...

If you thought you managed to buy everything there is to buy in Bitcoin Billionaire and make all the money, well you though wrong. Those of you who made it far enough might remember investing in time travel - and it looks like that investment is... | Read more »

Domino Drop (Games)

Domino Drop 1.0
Device: iOS Universal
Category: Games
Price: $1.99, Version: 1.0 (iTunes)
Description:
Domino Drop is a delightful new puzzle game with dominos and gravity!Learn how to play it in a minute, master it day by day.Your... | Read more »

Best Buy has iPad Air 2s on sale for up to $100 off MSRP on their online store for a limited time. Choose free shipping or free local store pickup (if available). Sale prices available for online... Read more

B&H Photo has the 13â€³ 1.6GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY tax only. Their price is $100 off MSRP, and itâ€™s the lowest price available for this model.... Read more

Worldwide Tablet Market Decline Continues, Ap...

The worldwide tablet market declined -7.0% year-over-year in the second quarter of 2015 (2Q15) with shipments totaling 44.7 million units according to preliminary data from the International Data... Read more

The Apple Store has Apple Certified Refurbished iPad Air 2s available for up to $140 off the price of new models. Appleâ€™s one-year warranty is included with each model, and shipping is free:
- 128GB... Read more

Updated Apple iPad Price Trackers

Weâ€™ve updated ourÂ iPad Air Price Tracker and ourÂ iPad mini Price Tracker with the latest information on prices and availability from Apple and other resellers.
Read more

Apple refurbished 2014 13-inch 128GB MacBook...

The Apple Store has Apple Certified Refurbished 2014 13â€³ MacBook Airs available starting at $759. An Apple one-year warranty is included with each MacBook, and shipping is free:
- 13â€³ 1.4GHz/128GB... Read more

Appleâ€™s Education discount saves up to $300 o...

Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more

MacTech is a registered trademark of Xplain Corporation. Xplain, "The journal of Apple technology", Apple Expo, Explain It, MacDev, MacDev-1, THINK Reference, NetProfessional, Apple Expo, MacTech Central, MacTech Domains, MacNews, MacForge, and the MacTutorMan are trademarks or service marks of Xplain Corporation. Sprocket is a registered trademark of eSprocket Corporation. Other trademarks and copyrights appearing in this printing or software remain the property of their respective holders. Not responsible for typographical errors.

All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.