• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSString to *NSGlyph conversion...
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSString to *NSGlyph conversion...


  • Subject: Re: NSString to *NSGlyph conversion...
  • From: Douglas Davidson <email@hidden>
  • Date: Mon, 8 Oct 2001 10:08:52 -0700

On Monday, October 8, 2001, at 05:20 AM, Simon Stapleton wrote:

I need to lay some text out along an arbitrary path. This could be a
curve. Now, I can work out how to lay out a glyph, and all that good
stuff, but I can't for the life of me work out how to go from an
NSString to an array of NSGlyphs.

This is one of the jobs of NSLayoutManager--you can expect to become quite familiar with this handy class if you do sophisticated work with the Cocoa text system, since the layout manager is the central controlling object for text display.

Before you start working with it, you should read the overview documentation (http://developer.apple.com/techpubs/macosx/Cocoa/ProgrammingTopics/TextOverview.
pdf) which describes how the various classes are related to each other and discusses some common configurations. Most of this is oriented toward configurations containing an NSTextView, which is not what you will be doing, but it will tell you what does what.

Next, you should look at the CircleView example included with 10.1, since this is very close to what you want to do. You could probably just cut and paste a lot of that code, but you will probably want to get a deeper understanding of what it is doing.

Here is a brief summary. The three objects you minimally need to do this sort of work with text without displaying it in an NSTextView (e.g. for displaying it in some other kind of view, or just for measuring it) are an NSTextStorage (the model object, to hold the text), an NSLayoutManager (the controller), and an NSTextContainer (an auxiliary object that describes the geometric region in which the text is to be laid out).

The NSTextStorage, a subclass of NSAttributedString, holds the contents of the text as an attributed string--that is, a string with additional attributes for such things as fonts, colors, etc. The NSLayoutManager takes this text and derives from it all of the additional information needed to display the text, on a lazy as-needed basis. There are two distinct steps to this: glyph generation and layout.

The way this works is that you ask the layout manager questions about the text (e.g., what is the glyph range corresponding to a given character range?) and the layout manager answers them, doing whatever work is required to do so. If answering the question requires glyph generation, then the layout manager will generate glyphs as needed to answer it. If answering the question requires layout, then the layout manager will perform layout (using an auxiliary class, NSTypesetter to do so) as needed to answer it. The NSLayoutManager header file describes in detail exactly which questions will cause glyph generation or layout.

Note that glyph generation and layout are both complex and time-consuming tasks, so the layout manager caches the results of both processes, and in addition manages fine-grained invalidation of these caches. If the text storage changes, then the relevant glyph and layout information will automatically be invalidated. If you wish, you can also manually invalidate either glyph or layout information.

The CircleView example uses NSLayoutManager for both glyph generation and layout. It creates a layout manager, associates it to a text storage for the text, and adds a simple rectangular NSTextContainer in which the text is to be laid out. When it needs to display the text, it goes on to ask a question that causes NSLayoutManager to make sure that glyph generation and layout is up to date for the entire text. (This does only as much work as necessary. The first time it is called, the work will be done; thereafter, unless the text changes, this will be very cheap.)

Then the example code takes the layout thus created, in a simple rectangular text container, and transforms it glyph by glyph so that the text lies along a circle. The spacing of the glyphs along a line in the original layout is turned into angular spacing along the circle. Vertical spacing of the glyphs (e.g. if the original text included hard line breaks) becomes radial spacing. For each glyph an appropriately rotated and translated coordinate system is set up, and the layout manager is used to draw the glyph (this could also be done through CG directly, but that would be considerably more inconvenient and probably not much faster).

The performance ends up being fairly reasonable--try pressing the button to turn on animation, and click and drag in the view to drag the circle around while it rotates, and see how it performs for you. Click on the border of the color well, and you will get a color panel; you can click and drag the mouse around in the color wheel, and the color will change on the fly.

Douglas Davidson


References: 
 >NSString to *NSGlyph conversion... (From: Simon Stapleton <email@hidden>)

  • Prev by Date: Re: global default for NSLayoutManager selection threshold?
  • Next by Date: Re: How to modify dialup number, login and password
  • Previous by thread: Re: NSString to *NSGlyph conversion...
  • Next by thread: Re: cocoa-dev digest, Vol 1 #687 - 10 msgs
  • Index(es):
    • Date
    • Thread