TweetFollow Us on Twitter

MACINTOSH C CARBON
MACINTOSH C CARBON: A Hobbyist's Guide To Programming the Macintosh in C
Version 1.0
© 2001 K. J. Bricknell
Go to Contents Go to Program Listing

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);

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

The Legend of Heroes: Trails of Cold Ste...
I adore game series that have connecting lore and stories, which of course means the Legend of Heroes is very dear to me, Trails lore has been building for two decades. Excitedly, the next stage is upon us as Userjoy has announced the upcoming... | Read more »
Go from lowly lizard to wicked Wyvern in...
Do you like questing, and do you like dragons? If not then boy is this not the announcement for you, as Loongcheer Game has unveiled Quest Dragon: Idle Mobile Game. Yes, it is amazing Square Enix hasn’t sued them for copyright infringement, but... | Read more »
Aether Gazer unveils Chapter 16 of its m...
After a bit of maintenance, Aether Gazer has released Chapter 16 of its main storyline, titled Night Parade of the Beasts. This big update brings a new character, a special outfit, some special limited-time events, and, of course, an engaging... | Read more »
Challenge those pesky wyverns to a dance...
After recently having you do battle against your foes by wildly flailing Hello Kitty and friends at them, GungHo Online has whipped out another surprising collaboration for Puzzle & Dragons. It is now time to beat your opponents by cha-cha... | Read more »
Pack a magnifying glass and practice you...
Somehow it has already been a year since Torchlight: Infinite launched, and XD Games is celebrating by blending in what sounds like a truly fantastic new update. Fans of Cthulhu rejoice, as Whispering Mist brings some horror elements, and tests... | Read more »
Summon your guild and prepare for war in...
Netmarble is making some pretty big moves with their latest update for Seven Knights Idle Adventure, with a bunch of interesting additions. Two new heroes enter the battle, there are events and bosses abound, and perhaps most interesting, a huge... | Read more »
Make the passage of time your plaything...
While some of us are still waiting for a chance to get our hands on Ash Prime - yes, don’t remind me I could currently buy him this month I’m barely hanging on - Digital Extremes has announced its next anticipated Prime Form for Warframe. Starting... | Read more »
If you can find it and fit through the d...
The holy trinity of amazing company names have come together, to release their equally amazing and adorable mobile game, Hamster Inn. Published by HyperBeard Games, and co-developed by Mum Not Proud and Little Sasquatch Studios, it's time to... | Read more »
Amikin Survival opens for pre-orders on...
Join me on the wonderful trip down the inspiration rabbit hole; much as Palworld seemingly “borrowed” many aspects from the hit Pokemon franchise, it is time for the heavily armed animal survival to also spawn some illegitimate children as Helio... | Read more »
PUBG Mobile teams up with global phenome...
Since launching in 2019, SpyxFamily has exploded to damn near catastrophic popularity, so it was only a matter of time before a mobile game snapped up a collaboration. Enter PUBG Mobile. Until May 12th, players will be able to collect a host of... | Read more »

Price Scanner via MacPrices.net

Apple is offering significant discounts on 16...
Apple has a full line of 16″ M3 Pro and M3 Max MacBook Pros available, Certified Refurbished, starting at $2119 and ranging up to $600 off MSRP. Each model features a new outer case, shipping is free... Read more
Apple HomePods on sale for $30-$50 off MSRP t...
Best Buy is offering a $30-$50 discount on Apple HomePods this weekend on their online store. The HomePod mini is on sale for $69.99, $30 off MSRP, while Best Buy has the full-size HomePod on sale... Read more
Limited-time sale: 13-inch M3 MacBook Airs fo...
Amazon has the base 13″ M3 MacBook Air (8GB/256GB) in stock and on sale for a limited time for $989 shipped. That’s $110 off MSRP, and it’s the lowest price we’ve seen so far for an M3-powered... Read more
13-inch M2 MacBook Airs in stock today at App...
Apple has 13″ M2 MacBook Airs available for only $849 today in their Certified Refurbished store. These are the cheapest M2-powered MacBooks for sale at Apple. Apple’s one-year warranty is included,... Read more
New today at Apple: Series 9 Watches availabl...
Apple is now offering Certified Refurbished Apple Watch Series 9 models on their online store for up to $80 off MSRP, starting at $339. Each Watch includes Apple’s standard one-year warranty, a new... Read more
The latest Apple iPhone deals from wireless c...
We’ve updated our iPhone Price Tracker with the latest carrier deals on Apple’s iPhone 15 family of smartphones as well as previous models including the iPhone 14, 13, 12, 11, and SE. Use our price... Read more
Boost Mobile will sell you an iPhone 11 for $...
Boost Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering an iPhone 11 for $149.99 when purchased with their $40 Unlimited service plan (12GB of premium data). No trade-in is required... Read more
Free iPhone 15 plus Unlimited service for $60...
Boost Infinite, part of MVNO Boost Mobile using AT&T and T-Mobile’s networks, is offering a free 128GB iPhone 15 for $60 per month including their Unlimited service plan (30GB of premium data).... Read more
$300 off any new iPhone with service at Red P...
Red Pocket Mobile has new Apple iPhones on sale for $300 off MSRP when you switch and open up a new line of service. Red Pocket Mobile is a nationwide MVNO using all the major wireless carrier... Read more
Clearance 13-inch M1 MacBook Airs available a...
Apple has clearance 13″ M1 MacBook Airs, Certified Refurbished, available for $759 for 8-Core CPU/7-Core GPU/256GB models and $929 for 8-Core CPU/8-Core GPU/512GB models. Apple’s one-year warranty is... Read more

Jobs Board

DMR Technician - *Apple* /iOS Systems - Haml...
…relevant point-of-need technology self-help aids are available as appropriate. ** Apple Systems Administration** **:** Develops solutions for supporting, deploying, Read more
Operating Room Assistant - *Apple* Hill Sur...
Operating Room Assistant - Apple Hill Surgical Center - Day Location: WellSpan Health, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Read more
Solutions Engineer - *Apple* - SHI (United...
**Job Summary** An Apple Solution Engineer's primary role is tosupport SHI customers in their efforts to select, deploy, and manage Apple operating systems and Read more
DMR Technician - *Apple* /iOS Systems - Haml...
…relevant point-of-need technology self-help aids are available as appropriate. ** Apple Systems Administration** **:** Develops solutions for supporting, deploying, Read more
Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.