Text Architecture
Text Architecture
2007-10-02
Apple Inc.
1997, 2007 Apple Inc.
All rights reserved.
No part of this publication may be
reproduced, stored in a retrieval system, or
transmitted, in any form or by any means,
mechanical, electronic, photocopying,
recording, or otherwise, without prior
written permission of Apple Inc., with the
following exceptions: Any person is hereby
authorized to store documentation on a
single computer for personal use only and
to print copies of documentation for
personal use provided that the
documentation contains Apples copyright
notice.
The Apple logo is a trademark of Apple Inc.
Use of the keyboard Apple logo
(Option-Shift-K) for commercial purposes
without the prior written consent of Apple
may constitute trademark infringement and
unfair competition in violation of federal
and state laws.
No licenses, express or implied, are granted
with respect to any of the technology
described in this document. Apple retains
all intellectual property rights associated
with the technology described in this
document. This document is intended to
assist application developers to develop
applications only for Apple-labeled or
Apple-licensed computers.
Every effort has been made to ensure that
the information in this document is
accurate. Apple is not responsible for
typographical errors.
Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
408-996-1010
Apple, the Apple logo, Carbon, Cocoa, Mac,
Mac OS, Objective-C, Quartz, Tiger, and
Xcode are trademarks of Apple Inc.,
registered in the United States and other
countries.
Smalltalk-80 is a trademark of ParcPlace
Systems.
Times is a registered trademark of
Heidelberger Druckmaschinen AG,
available from Linotype Library GmbH.
Contents
Introduction to Text System Overview 7
Who Should Read This Document 7
Organization of This Document 7
See Also 8
3
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
4
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Figures
Text System Architecture 9
Figure 1
A text field 19
A text view 20
The field editor 21
Common Configurations 25
Figure 1
Figure 2
Figure 3
Figure 4
Figure 5
5
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Figure 5
6
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
37
Text System Overview provides a survey of the Cocoa text system. The articles introduce important
features and describe aspects of the text system as a whole.
Text System Architecture (page 9) presents a high-level discussion of the design goals and
capabilities of the text system, and it explains the roles of some important text classes.
The Cocoa Text System, MLTE, and ATSUI (page 11) briefly explains the position of the Cocoa
text system relative to other Mac OS X text-handling technologies.
Typographical Features of the Cocoa Text System (page 13) explains the concepts of
typographysuch as glyphs, fonts, typefaces, and layoutthat correlate with features of the text
system.
Text Fields, Text Views, and the Field Editor (page 19) introduces the main user interface objects
of the text system.
The Text System and MVC (page 23) explains how objects of the text system relate to the
model-view-controller paradigm of object-oriented programming.
Common Configurations (page 25) describes various ways in which you can configure text
system objects to accomplish different text-handling goals.
Class Hierarchy of the Cocoa Text System (page 29) presents an inheritance diagram of the
text system classes.
Building a Text Editor in 15 Minutes (page 31) is a tutorial showing how you can quickly and
easily create a very capable text editing program using Cocoa.
Simple Text Tasks (page 39) presents programming techniques to accomplish several text-related
goals using the text system.
Assembling the Text System by Hand (page 41) shows how to instantiate and explicitly hook
together objects of the text system programmatically.
See Also
The following documents discuss specific aspects of the text system architecture in greater detail:
Text System User Interface Layer Programming Guide for Cocoa describes the high-level interface to
the Cocoa text system.
Text System Storage Layer Overview discusses the lower-level facilities that the Cocoa text system
uses to store text.
For further reading, see other documents in the Cocoa Text and Fonts Documentation. In addition,
please refer to the Cocoa text-related code samples on the Apple Developer Connection website and
the Application Kit examples installed with the Xcode Tools.
See Also
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
The text-handling component of any application presents one of the greatest challenges to software
designers. Even the most basic text-handling system must be relatively sophisticated, allowing for
text input, layout, display, editing, copying and pasting, and many other features. But these days
developers and users commonly expect even more than these basic features, requiring even simple
editors to support multiple fonts, various paragraph styles, embedded images, spell checking, and
other features.
The Cocoa text system provides all these basic and advanced text-handling features, and it also satisfies
additional requirements that are emerging from our ever more interconnected computing world:
support for the character sets of the worlds living languages, powerful layout capabilities to handle
various text directionality and nonrectangular text containers, and sophisticated typesetting capabilities
including control of kerning and ligatures. Cocoas text system is designed to provide all these
capabilities without requiring you to learn about or interact with more of the system than is necessary
to meet the needs of your application.
For most developers, the general-purpose programmatic interface of the NSTextView class is all you
need to learn. NSTextView provides the user interface to the text system. If you need more flexible,
programmatic access to the text, youll need to learn about the storage layer and the NSTextStorage
class. And, of course, to access all the available features, you can learn about and interact with any
of the classes that support the text-handling system.
Figure 1 shows the major functional areas of the text system with the user interface layer on top, the
storage layer on the bottom, and, in the middle region, the components that interpret keyboard input
and arrange the text for display.
Figure 1
Font & color
panels
Glyph
generator
Text views
Ruler views
Layout
manager
Text input
management
Typesetter
Text containers
Text storage
9
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
The text classes exceed most other classes in the Application Kit in the richness and complexity of
their interface. One of their design goals is to provide a comprehensive set of text-handling features
so that youll rarely need to create a subclass. Among other things, a text object such as NSTextView
can:
Control the font and layout characteristics of its text by working with the Font menu and Font
panel (also called the Fonts window).
Write text to or read text from files in the form of RTFDRich Text Format files that contain TIFF
or EPS images, or attached files.
Let the user copy and paste text within and between applications.
Let the user copy and paste font and format information between NSText objects.
Graphical user-interface building tools (such as Interface Builder) may give you access to text objects
in several different configurations, such as those found in the NSTextField, NSForm, and NSScrollView
objects. These classes configure a text object for their own specific purposes. Additionally, all
NSTextFields, NSForms, NSButtons within the same windowin short, all objects that access a text
object through associated cellsshare the same text object, called the field editor, reducing the memory
demands of an application. Thus, its generally best to use one of these classes whenever it meets
your needs, rather than create text objects yourself. But if one of these classes doesnt provide enough
flexibility for your purposes, you can create text objects programmatically.
Text objects typically work closely with various other objects. Some of thesesuch as the delegate
or an embedded graphic objectrequire some programming on your part. Otherssuch as the Font
panel, spell checker, or rulertake no effort other than deciding whether the service should be enabled
or disabled.
To control layout of text on the screen or printed page, you work with the objects that link the
NSTextStorage repository to the NSTextView that displays its contents. These objects are of the
NSLayoutManager and NSTextContainer classes.
An NSTextContainer object defines a region where text can be laid out. Typically, a text container
defines a rectangular area, but by creating a subclass of NSTextContainer you can create other shapes:
circles, pentagons, or irregular shapes, for example. NSTextContainer isnt a user-interface object, so
it cant display anything or receive events from the keyboard or mouse. It simply describes an area
that can be filled with text. Nor does an NSTextContainer object store textthats the job of an
NSTextStorage object.
A layout manager object, of the NSLayoutManager class, orchestrates the operation of the other text
handling objects. It intercedes in operations that convert the data in an NSTextStorage object to
rendered text in an NSTextView objects display. It also oversees the layout of text within the areas
defined by NSTextContainer objects.
10
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
The Cocoa text system is an object-oriented framework designed to provide all the text services needed
by Cocoa applications. Carbon applications, on the other hand, use the APIs of other text-oriented
components such as the Multilingual Text Engine (MLTE), which provides editing features, and Apple
Type Services for Unicode Imaging (ATSUI), which provides typography and layout services.
From the developers perspective, the Cocoa text system and ATSUI are two parallel APIs that both
handle line layout and character-to-glyph transformations, calling into the Quartz Core Graphics
library for text rendering. A developer using the Cocoa text system for a given project is not likely to
use ATSUI and vice versa.
The relationships among the Cocoa text system, MLTE, ATSUI, and other text-related components
of the Mac OS X development environment are shown in Figure 1.
Figure 1
Carbon applications
Cocoa applications
Cocoa
text system
ATSUI
QuickDraw
Text rendering
Quartz
Text rendering
For more information about the Core Graphics rendering engine, see the Quartz 2D documentation.
11
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
12
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
The Cocoa text system is responsible for the processing and display of all visible text in Cocoa. It
provides a complete set of high-quality typographical services through the Application Kit classes.
This article defines typographical concepts relevant to the text system.
Characters and glyphs do not have a one-to-one correspondence. In some cases a character may be
represented by multiple glyphs, such as an which may be an e glyph combined with an acute
accent glyph . In other cases, a single glyph may represent multiple characters, as in the case of a
ligature, or joined letter. Figure 2 shows individual characters and the single-glyph ligature often
used when they are adjacent. A ligature is an example of a contextual form in which the glyph used
to represent a character changes depending on the characters next to it. Other contextual forms include
alternate glyphs for characters beginning or ending a word.
13
Figure 2
Ligatures
Computers store characters as numbers mapped by encoding tables to their corresponding characters.
The encoding scheme native to Mac OS X is called Unicode. The Unicode standard provides a unique
number for every character in every modern written language in the world, independent of the
platform, program, and programming language being used. This universal standard solves a
longstanding problem of different computer systems using hundreds of conflicting encoding schemes.
Unicode provides the encoding used to store characters in Cocoa. It also has features that simplify
handling bidirectional text and contextual forms.
Glyphs are also represented by numeric codes called glyph codes. The glyphs used to depict characters
are selected by the Cocoa layout manager (NSLayoutManager) during composition and layout
processing. The layout manager determines which glyphs to use and where to place them in the
display, or view. The layout manager caches the glyph codes in use and provides methods to convert
between characters and glyphs and between characters and view coordinates. (See Text Layout (page
15) for more information about the layout process.)
14
Figure 3
In some cases a particular style of a typeface is a separate font, but in other cases where such a font
is not available, the system can produce the typestyle programmatically by varying certain
characteristics of another font in family. For example, an algorithm can create a bold typestyle by
increasing the line weight of the regular font of the same family. The Cocoa text system can substitute
these variations as necessary. Styles, also called traits, that are available in Cocoa include variations
such as bold, italic, condensed, expanded, narrow, small caps, poster fonts, and fixed pitch.
Text Layout
Text layout is the process of arranging glyphs on a display device, in an area called a text view, which
represents an area similar to a page in traditional typesetting. The way in which glyphs are laid out
relative to each other is called text direction. In English and other languages derived from Latin,
glyphs are placed side by side to form words that are separated by spaces. Words are laid out in lines
beginning at the top left of the text view proceeding from left to right until the text reaches the right
side of the view. Text then begins a new line at the left side of the view under the beginning of the
previous line, and layout proceeds in the same manner to the bottom of the text view.
In other languages, glyph layout can be quite different. For example, some languages lay out glyphs
from right to left or vertically instead of horizontally. It is common, especially in technical writing,
to mix languages with differing text direction, such as English and Hebrew, in the same line. Some
writing systems even alternate layout direction in every other line (an arrangement called
boustrophedonic writing). Some languages do not group glyphs into words separated by spaces.
Moreover, some applications call for arbitrary arrangements of glyphs; a graphic layout may require
glyphs to be arranged on a nonlinear path.
The Cocoa layout manager (an instance of the NSLayoutManager class) lays out glyphs along an
invisible line called the baseline. In Roman text, the baseline is horizontal, and the bottom edge of
most of the glyphs rest on it. Some glyphs extend below the baseline, including those for characters
like g that have descenders, or tails, and large rounded characters like O that must extend
slightly below the baseline to compensate for optical effects. Other writing systems place glyphs
below or centered on the baseline. Every glyph includes an origin point that the layout manager uses
to align it properly with the baseline.
Glyph designers provide a set of measurements with a font, called metrics, which describe the spacing
around each glyph in the font. The layout manager uses these metrics to determining glyph placement.
In horizontal text, the glyph has a metric called the advance width, which measures the distance
along the baseline to the origin point of the next glyph. Typically there is some space between the
origin point and the left side of the glyph, which is called the left-side bearing. There may also be
space between the right side of the glyph and the point described by the advance width, which is
Text Layout
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
15
called the right-side bearing. The vertical dimension of the glyph is provided by two metrics called
the ascent and the descent. The ascent is the distance from the origin (on the baseline) to the top of
the tallest glyphs in the font. The descent, which is the distance below the baseline to the bottom of
the fonts deepest descenders. The rectangle enclosing the visible parts of the glyph is called the
bounding rectangle or bounding box. Figure 4 illustrates these metrics and similar ones used for
vertical glyph placement.
Figure 4
Glyph metrics
Bounding
box
Ascent
Left-side
bearing
Right-side bearing
Baseline
Descent
Advance width
= Origin
By default, typesetters place glyphs side-by-side using the advance width, resulting in a standard
interglyph space. However, in some combinations text is made more readable by kerning, which is
shrinking or stretching the space between two glyphs. A very common example of kerning occurs
between an uppercase W and uppercase A, as shown in Figure 5. Type designers include kerning
information in the metrics for a font. The Cocoa text system provides methods to turn kerning off,
use the default settings provided with the font, or tighten or loosen the kerning throughout a selection
of text.
Figure 5
Kerning
With kerning
Without kerning
Type systems usually measure font metrics in units called points, which in Mac OS X measure exactly
72 per inch. Adding the distance of the ascent and the descent of a font provides the fonts point size.
Space added during typesetting between lines of type is called leading, after the slugs of lead used
for that purpose in traditional metal-type page layout. (Leading is sometimes also called linegap.)
The total amount of ascent plus descent plus leading provides a fonts line height.
16
Text Layout
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Although the typographic concepts of type design are somewhat esoteric, most people who have
created documents on a computer or typewriter are familiar with the elements of text layout on a
page. For example, the margins are the areas of white space between the edges of the page and the
text area where the layout engine places glyphs. Alignment describes the way text lines are placed
relative to the margins. For example, horizontal text can be aligned right, left, or centered, as shown
in Figure 6.
Figure 6
Centered
Right aligned
Lines of text can also be justified; for horizontal text the lines are aligned on both right and left
margins, as shown in Figure 7.
Figure 7
Justified text
Justified
Text Layout
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
17
To create lines from a string of glyphs, the layout engine must perform line breaking by finding a
point at which to end one line and begin the next. In the Cocoa text system, you can specify line
breaking at either word or glyph boundaries. In Roman text, a word broken between glyphs requires
insertion of a hyphen glyph at the breakpoint. Once the text stream has been broken into lines, the
system performs alignment and justification, if requested.
18
Text Layout
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Text fields, text views, and the field editor are important objects in the Cocoa text system because
they are central to the users interaction with the system. They provide text entry, manipulation, and
display. If your application deals in any way with user-entered text, you should understand these
objects.
Text Fields
A text field is a user interface control object instantiated from the NSTextField class. Figure 1 shows
a text field. Text fields display small amounts of text, typically (although not necessarily) a single line.
Text fields also provide places for users to enter text responses, such as search parameters. Like all
controls, a text field has a target and an action. By default, text fields send their action message when
editing endsthat is, when the user presses Return or moves focus to another control. You can also
control a text fields shape and layout, the font and color of its text, background color, whether the
text is editable or read-only, whether it is selectable or not (if read-only), and whether the text scrolls
or wraps when the text exceeds the text fields visible area.
Figure 1
A text field
To create a secure text field for password entry, you use NSSecureTextField, a subclass of NSTextField.
Secure text fields display bullets in place of characters entered by the user, and they do not allow
cutting or copying of their contents. You can get the text fields value using the stringValue method,
but users have no access to the value.
The usual way to instantiate a text field is to drag an NSTextField object from the the Cocoa-Views
palette in Interface Builder and place it in a window of your applications user interface. Then, if you
then want to convert the text field to a secure text field, you select it, open the Info window
(Command-Shift-I), choose the Custom Class pane (Command-5), and select NSSecureTextField.
Text Fields
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
19
Text Views
Text views are user interface objects instantiated from the NSTextView class. Figure 2 shows a text
view. Text views typically display multiple lines of text laid out in paragraphs with all the
characteristics of sophisticated typesetting. A text view is the main user interface to the Cocoa
text-editing system. It handles user events to provide text entry and modification, and to display any
font, including those of non-English languages, with arbitrary colors, styles, and other attributes.
Figure 2
A text view
The Cocoa text system supports text views with many other underlying objects providing text storage,
layout, font and attribute manipulation, spell checking, undo and redo, copy and paste, drag and
drop, saving of text to files, and other features. NSTextView is a subclass of NSText, which is a separate
class for historical reasons. You dont instantiate NSText, although it declares many of the methods
you use with NSTextView. When you put an NSTextView object in an NSWindow object, you have
a full-featured text editor whose capabilities are provided for free by the Cocoa text system. (See
Building a Text Editor in 15 Minutes (page 31) for more information.)
20
Text Views
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Figure 3
Field editor
delegate
anNSTextField
Because only one of the text fields in a window can be active at a time, the system needs only one
NSTextView instance per window to be the field editor. Among its other duties, the field editor
maintains the selection. Therefore, a text field that's not being edited typically does not have a selection
at all. (However, developers can substitute custom field editors, in which case there could be more
than one field editor.)
For more information about the field editor, see Working With the Field Editor.
21
22
The Cocoa text systems architecture is both modular and layered to enhance its ease of use and
flexibility. Its modular design reflects the model-view-controller paradigm (originating with
Smalltalk-80) where the data, its visual representation, and the logic that links the two are represented
by separate objects. In the case of the text system, NSTextStorage holds the models text data,
NSTextContainer models the geometry of the layout area, NSTextView presents the view, and
NSLayoutManager intercedes as the controller to make sure that the data and its representation
onscreen stay in agreement.
This factoring of responsibilities makes each component less dependent on the implementation of
the others and makes it easier to replace individual components with improved versions without
having to redesign the entire system. To illustrate the independence of the text-handling components,
consider some of the operations that are possible using different subsets of the text system:
Using only an NSTextStorage object, you can search text for specific characters, strings, paragraph
styles, and so on.
Using only an NSTextStorage object you can programmatically operate on the text without
incurring the overhead of laying it out for display.
Using all the components of the text system except for an NSTextView object, you can calculate
layout information, determining where line breaks occur, the total number of pages, and so forth.
The layering of the text system reduces the amount you have to learn to accomplish common
text-handling tasks. In fact, many applications interact with this system solely through the API of the
NSTextView class.
23
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
24
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Common Configurations
The following diagrams give you an idea of how you can configure objects of the four primary text
system classesNSTextStorage, NSLayoutManager, NSTextContainer, and NSTextViewto
accomplish different text-handling goals.
To display a single flow of text, arrange the objects as shown in Figure 1.
Figure 1
NSTextStorage
NSLayoutManager
NSTextContainer
NSTextView
With one
NSTextView,
all of the text
flows within a
single, typically
rectangular,
area.
The NSTextView provides the view that displays the glyphs, and the NSTextContainer object defines
an area within that view where the glyphs are laid out. Typically in this configuration, the
NSTextContainers vertical dimension is declared to be some extremely large value so that the container
can accommodate any amount of text, while the NSTextView is set to size itself around the text using
the setVerticallyResizable: method defined by NSText, and given a maximum height equal to
the NSTextContainers height. Then, with the NSTextView embedded in an NSScrollView, the user
can scroll to see any portion of this text.
If the NSTextContainers area is inset from the NSTextViews bounds, a margin appears around the
text. The NSLayoutManager object, and other objects not pictured here, work together to generate
glyphs from the NSTextStorages data and lay them out within the area defined by the
NSTextContainer.
This configuration is limited by having only one NSTextContainer-NSTextView pair. In such an
arrangement, the text flows uninterrupted within the area defined by the NSTextContainer. Page
breaks, multicolumn layout, and more complex layouts cant be accommodated by this arrangement.
By using multiple NSTextContainer-NSTextView pairs, more complex layout arrangements are
possible. For example, to support page breaks, an application can configure the text objects as shown
in Figure 2.
25
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Common Configurations
Figure 2
NSTextContainer
NSTextStorage
NSTextView
NSLayoutManager
NSTextContainer
NSTextView
As text is added, it
fills the region
defined by the first
NSTextContainer.
The text is displayed
in the NSTextView
that is paired with
the NSTextContainer.
When there's no
more room, another
NSTextContainer
(and associated
NSTextView) is
added, and the text
flows onto the
second page.
Each NSTextContainer-NSTextView pair corresponds to a page of the document. The gray rectangle
in the diagram above represents a custom view object that your application provides as a background
for the NSTextViews. This custom view can be embedded in an NSScrollView to allow the user to
scroll through the documents pages.
A multicolumn document uses a similar configuration, as shown in Figure 3.
Figure 3
NSTextStorage
NSTextContainer
NSTextView
NSTextContainer
NSTextView
With
multiple
text views
and
containers,
text can
flow in
more
complex
layouts,
such as in
paginated
documents
having
multiple
columns.
As a
column
fills with
NSLayoutManager
NSTextContainer
NSTextView
NSTextContainer
NSTextView
26
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
text, a new
NSTextContainer
column is
(and associated
added.
NSTextView) is
When the
added, and the text
second
flows onto the
column on
second page.
the page is
filled, a
new page
is added.
Common Configurations
Instead of having one NSTextView-NSTextContainer pair correspond to a single page, there are now
two pairsone for each column on the page. Each NSTextContainer-NSTextView controls a portion
of the document. As the text is displayed, glyphs are first laid out in the top-left view. When there is
no more room in that view, the NSLayoutManager informs its delegate that it has finished filling the
container. The delegate can check whether theres more text that needs to be laid out and add another
NSTextContainer and NSTextView. The NSLayoutManager proceeds to lay out text in the next
container, notifies the delegate when finished, and so on. Again, a custom view (depicted as a gray
rectangle) provides a canvas for these text columns.
Not only can you have multiple NSTextContainer-NSTextView pairs, you can also have multiple
NSLayoutManagers accessing the same NSTextStorage. Figure 4 illustrates the simplest arrangement
with multiple layout managers.
Figure 4
NSLayoutManager
NSTextContainer
NSTextView
NSTextStorage
NSLayoutManager
NSTextContainer
NSTextView
Multiple NSLayoutManagers
allow you to have multiple
presentations of the same
text. The text within each
view can have separate
layout and selections.
Multiple
NSLayoutManagers
allow you to have
multiple presentations
of the same text.
The text within each
view can have
separate layout
and selections.
The effect of this arrangement is to give multiple views on the same text. If the user alters the text in
the top view, the change is immediately reflected in the bottom view (assuming the location of the
change is within the bottom views bounds).
Finally, complex page layout requirements, such as permitting text to wrap around embedded graphics,
can be achieved by a configuration that uses a custom subclass of NSTextContainer. This subclass
defines a region that adapts its shape to accommodate the graphic image and uses the object
configuration shown in Figure 5.
27
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Common Configurations
Figure 5
MyTextContainer
NSTextStorage
NSTextView
NSLayoutManager
MyTextContainer
28
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
NSTextView
The text
container
defines a
region that wraps
around the embedded
graphic. A custom
view is the super
view for each of the
NSTextViews. It both
arranges the
NSTextViews as
pages and detects
when the
graphic has
moved. When
a graphic is
moved or added, the
text container must
adapt its shape to
accommodate the
new placement.
NSTextStorage
NSLayoutManager
NSTypesetter
NSATSTypesetter
NSTextContainer
NSResponder
NSView
NSParagraphStyle
NSText
<NSChangeSpelling,
NSIgnoreMisspelledWords>
NSTextView
<NSTextInput>
NSMutableParagraphStyle
NSTextTab
<NSCopying>
NSTextAttachmentCell
NSCell
<NSCopying,NSMutableCopying>
NSTextAttachment
NSFileWrapper
NSInputManager
NSInputServer
NSFont
NSFontPanel
NSFontManager
29
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
NSFontDescriptor
NSGlyphGenerator
NSGlyphInfo
NSGlyphStorage protocol
NSRulerView
NSRulerMarker
NSTextField
NSSecureTextField
NSSpellChecker
NSTextBlock
NSTextTable
NSTextTableBlock
NSTextList
30
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
This article shows how you can use Cocoa to create a simple but highly capable text editor in less
than 15 minutes using Xcode and Interface Builder. The Cocoa document architecture provides many
of the features required for this type of application automatically, requiring you to write a minimal
amount of code.
Here is a simplified summary of the steps needed to complete this task:
You can build and test the application at several stages of completion. The following steps expand
and explain this procedure. The steps assume that you have a basic acquaintance with Xcode and
Interface Builder.
2.
Open the MyDocument.nib file, which is in the Resources folder. Double-click the MyDocument.nib
icon, which launches Interface Builder.
31
3.
Delete the label reading Your document contents here from the Window object. Drag an
NSTextView object from the Cocoa-Text palette, which is shown in Figure 1 (page 32). Resize
the text view to almost fill the window, leaving margins as indicated by Interface Builders guide
lines.
Figure 1
4.
32
Click once inside the text view and choose Show Inspector from the Tools menu to open the
Inspector window. Choose Size from the pop-up menu, and set the view to resize with the window,
by clicking on the inner set of crossed lines, which changes their appearance to springs, as shown
in Figure 2 (page 33).
Note: Clicking once inside the text view area selects the scroll view containing the text view, as
indicated by the title of the Inspector window. Clicking twice inside the text view selects the text
view itself. Be sure to set the resize characteristics of the scroll view.
Figure 2
5.
Choose Attributes from the pop-up menu of the Inspector window, and ensure that the following
options are selected: Editable, Multiple fonts allowed, Undo allowed, Continuous Spell Checking,
Uses Find Panel, and Show Scroller.
6.
Choose Test Interface from Interface Builder's File menu, and resize the window to ensure that
the text view resizes properly along with the window. Note that you can already edit text in the
text view. When you drag the NSTextView object from the Cocoa Text Controls palette, Interface
Builder automatically instantiates all the Cocoa text objects required for a complete editing and
layout implementation. Choose Quit Interface Builder to leave interface test mode (Interface
Builder should continue running).
33
7.
Add a Format menu to the application. In Xcode, double-click the MainMenu.nib icon to open
the MainMenu window, which represents the new applications menu bar. From the Cocoa-Menus
palette, drag a Format menu to the menu bar. Typically, a Format menu goes to the right of the
Edit menu, as shown in Figure 3 (page 34).
Figure 3
8.
Save both nib files and return to Xcode. Build and test the new application.
At this stage of your editors development, it has many sophisticated features. You should be able to
enter, edit, cut, copy, and paste text. You can find and replace text using the Find window. You can
undo and redo editing actions. You can also format text, setting its font, size, style, and color attributes.
You can control text alignment, justification, baseline position, kerning, and ligatures. You can display
a ruler that provides a graphical interface to manipulate many text and layout attributes, as well as
setting tab stops. You can even use the spelling checker.
In addition to its many editing features, your editor can open multiple documents, each with its own
text view and contents. What it lacks most prominently are the abilities to open files and save text in
files (that is, archiving and unarchiving documents). It also lacks such features as displaying its name
in its menu bar, having its own icon, and having useful information in its About window.
Quit your new application before proceeding to the next section.
Add an instance variable for the text view, so you can connect the text view with the code in your
NSDocument subclass that handles archiving and unarchiving of documents in files. You also
need to add an instance variable to hold the text string being edited (the documents data model).
Put the variable declarations in MyDocument.h as follows:
#import <Cocoa/Cocoa.h>
@interface MyDocument: NSDocument
{
34
2.
Initialize the string instance variable. Put the following lines in the init method (which has a
stub implementation) in MyDocument.m:
if (mString == nil) {
mString = [[NSAttributedString alloc] initWithString:@""];
}
3.
Write getter and setter methods for the string instance variable. Put them in MyDocument.m as
follows:
- (NSAttributedString *) string { return [[mString retain] autorelease]; }
- (void) setString: (NSAttributedString *) newValue {
if (mString != newValue) {
if (mString) [mString release];
mString = [newValue copy];
}
}
4.
Add method declarations for the getter and setter methods to the header file. MyDocument.h
should now appear as follows:
#import <Cocoa/Cocoa.h>
@interface MyDocument: NSDocument
{
IBOutlet NSTextView *textView;
NSAttributedString *mString;
}
- (NSAttributedString *) string;
- (void) setString: (NSAttributedString *) value;
@end
5.
From Xcode, drag the MyDocument.h file icon onto the Instances pane of MyDocument.nib, which
is in Interface Builder. This step informs the MyDocument.nib file that the MyDocument interface
now has an outlet variable named textView .
6.
In Interface Builder, click twice inside the text view to select the NSTextView object. Be sure you
connect to the NSTextView and not its containing NSScrollView.
35
7.
Connect the textView outlet of the File's Owner by Control-dragging from the File's Owner icon
in the Instances pane of MyDocument.nib to the text view in the window, as shown in Figure
4 (page 36). Use the File's Owner Inspector to make the connection by double-clicking the textView
outlet or by selecting the textView outlet and clicking the Connect button.
Figure 4
36
8.
In Interface Builder, make the Files Owner (that is, the MyDocument object) the delegate of the
text view. Double-click to select the text view in the window and Control-drag from the text view
to the Files Owner icon, as shown in Figure 5 (page 37). Use the Connections pane of the
NSTextView Inspector window to make the connection by double-clicking the delegate outlet
or by selecting the delegate outlet and clicking the Connect button.
Figure 5
9.
10. Implement the archiving and unarchiving methods. When you initially created the project, Xcode
placed stubs for these methods in MyDocument.m. Fill in the method bodies as follows:
- (NSData *)dataRepresentationOfType:(NSString *)aType
{
NSData *data;
[self setString:[textView textStorage]];
data = [NSArchiver archivedDataWithRootObject:[self string]];
37
return data;
}
- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
NSAttributedString *tempString = [NSUnarchiver unarchiveObjectWithData: data];
[self setString:tempString];
return YES;
}
Applications targeted for Mac OS X v10.4 or later systems should override dataOfType:error:
and readFromData:ofType:error: instead of the methods shown in this step.
11. Add one line of code to the windowControllerDidLoadNib method to place the contents of the
windows data model into the text view when the windows nib file is initially loaded. Leave the
call to the superclass windowControllerDidLoadNib method and add the following line after it:
if ([self string] != nil) {
[[textView textStorage] setAttributedString: [self string]];
}
38
This article explains some programmatic techniques using the Cocoa text system to accomplish simple
tasks which may not be obvious until you see how theyre done.
39
If your mutable attributed string is actually an NSTextStorage object, place this code between
beginEditing and endEditing calls.
Then add the origin of that rectangle to the location of the glyph returned by
locationForGlyphAtIndex:
40
The vast majority of applications interact with the text system at a high level through one class:
NSTextView. It is also possible to build the network of objects that make up the text system from the
bottom up, starting with the NSTextStorage object. Understanding how this is done helps illuminate
the design of the text-handling system.
In creating the text-handling network by hand, you create four objects but then release three as they
are added to the network. You are left with a reference only to the NSTextStorage object. The
NSTextView is retained, however, by both its NSTextContainer and its superview; to fully destroy
this group of text objects you must send removeFromSuperview to the NSTextView object and then
release the NSTextStorage object.
An NSTextStorage object is conceptually the owner of any network of text objects, no matter how
complex. When you release the NSTextStorage object, it releases its NSLayoutManagers, which release
their NSTextContainers, which in turn release their NSTextViews.
Figure 1
MyTextContainer
NSTextView
NSLayoutManager
Release
Release
Release
MyTextContainer
Release
NSTextView
NSTextStorage
Release
Release
MyTextContainer
Release
NSTextView
NSLayoutManager
Release
MyTextContainer
Release
NSTextView
However, recall that the text system implements a simplified ownership policy for those whose only
interaction with the system is through the NSTextView class. See Creating an NSTextView
Programmatically for more information.
41
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
If, on the other hand, you want to initialize an NSTextStorage object with rich text data from a file,
the initialization looks like this (assume filename is defined):
textStorage = [[NSTextStorage alloc]
initWithRTF:[NSData dataWithContentsOfFile:filename]
documentAttributes:NULL];
Weve assumed that textStorage is an instance variable of the object that contains this method.
When you create the text-handling system by hand, you need to keep a reference only to the
NSTextStorage object as youve done here. The other objects of the system are owned either directly
or indirectly by this NSTextStorage object, as youll see in the next steps.
Note that layoutManager is released after being added to textStorage. This is because the
NSTextStorage object retains each NSLayoutManager thats added to itthat is, the NSTextStorage
object owns its NSLayoutManagers.
The NSLayoutManager needs a number of supporting objectssuch as those that help it generate
glyphs or position text within a text containerfor its operation. It automatically creates these objects
(or connects to existing ones) upon initialization. You only need to connect the NSLayoutManager to
the NSTextStorage object and to the NSTextContainer object, as seen in the next step.
42
[container release];
Once youve created the NSTextContainer, you add it to the list of containers that the
NSLayoutManager owns, and then you release it. The NSLayoutManager now owns the
NSTextContainer and is responsible for releasing it when its no longer needed. If your application
has multiple NSTextContainers, you can create them and add them at this time.
43
44
Notes
2007-10-02
Made minor change to code snippet in "Simple Text Tasks" to set font trait.
2007-03-06
2006-08-07
2005-08-11
Updated the tutorial for Mac OS X v10.4 and made minor revisions
throughout. Changed title from Text System Architecture.
2004-05-27
2004-02-10
2003-04-30
2002-11-12
45
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
46
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
Index
document archiving 34
A
advance width of glyphs 15
alignment of text 17
alloc method 42
Apple Type Services for Unicode Imaging (ATSUI)
11
ascent of glyphs 16
ATSUI. See Apple Type Services for Unicode Imaging
B
baseline of text 15
bearing of glyphs 15
beginEditing method 40
bounding rectangle of glyphs 16
E
endEditing method 40
F
field editors 10, 20
font attributes, setting 39
font families 14
font styles, setting 39
fonts
defined 14
G
C
Carbon applications
relation to Cocoa text system 11
characters 13
class hierarchy of Cocoa text system 29
Cocoa Text Controls palette
as source of text views 32
configuration of text system objects 2527
glyphs
codes 14
defined 13
display 25
locations 40
metrics of 15
I
init... methods 42
D
data model 23, 34
delegate methods 37
delegates 37
descenders of glyphs 15
descent of glyphs 16
direction of text 15
document architecture 31
initialization
of NSLayoutManager 42
of NSTextContainer 42
of NSTextStorage 42
of NSTextView 43
initWithFrame: method 43
initWithFrame:textContainer: method 43
Interface Builder
to create a text editor 31
47
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
kerning 16
origin of glyphs 15
removeFromSuperview method 41
J
justified text 17
P
point size of fonts 16
points 16
S
string variables
getter methods for 35
setter methods for 35
stringValue method 19
N
NSFileWrapper class 29
NSForm class 10
NSInputManager class 29
NSInputServer class 29
NSLayoutManager class
glyphs and 14
memory management and 41
MVC and 23
relation to other text objects 10, 25
NSScrollView class 10, 25
NSSecureTextField class 19
NSText class 20
NSTextContainer class
memory management and 41
MVC and 23
T
text editors
creating 3138
features of 34
text fields 19
text layout
complex 25
defined 15
text system objects
assembling by hand 4143
configuration of 2527
features of 10
text views
48
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.
appending text 39
defined 20
textDidChange method 37
typefaces 14
typestyles 14
U
Unicode
as Mac OS X native encoding 14
V
view coordinates of glyphs 40
W
windowControllerDidLoadNib method 38
X
Xcode
to create a text editor 31
49
2007-10-02 | 1997, 2007 Apple Inc. All Rights Reserved.