Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2001-113
$eventId
ID of event: wwdc2001
$eventContentId
ID of session without event part: 113
$eventShortId
Shortened ID of event: wwdc01
$year
Year of session: 2001
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC01 • Session 113

Text on Mac OS X

Mac OS • 55:55

A major contributor to the overall look and feel of the Aqua interface in Mac OS X is anti-aliased text. For Carbon developers wanting static or editable anti-aliased text, this session includes in-depth discussions of the options available, including Appearance Manager APIs, Unicode toolbox controls, and the Multilingual Text Editor (MLTE).

Speakers: Xavier Legros, John Harvey, Greg Dow, Rick Fabrick

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Hi, Bonjour, je l'essaye. I'd like to welcome you to session 113, Text on Mac OS X. This session will focus on the technologies that will enable a Carbon application to display text correctly on Mac OS X. When I say correctly, I mean two things. First, the text has to be in UniCode, and you need to support multilingual text. Mac OS X is an international OS, and you see it Monday with Avi. We're going to be shipping a new version of Mac OS X with support with Korean, Chinese, and other languages in Europe.

And your application needs to support UniCode. UniCode is like, you know, the standard for encoding text now. The second point, which is very important for our customers, is you need to use Quartz rendering to display the text. Quartz is a powerful 2D rendering engine that gives to Mac OS X its special taste. The nice anti-aliasing on the text, the drop shadows. You need to use Quartz to render your text. You don't want your text to stick like a sore thumb. if you still use the Quick Draw rendering.

Excellent. In this session, we'll discuss as well MLT, which is the Multilingual Text Engine. Last year in this same room, I discussed MLT, the benefits, the features, and how it could be implemented in your application. We got tremendous feedback from MLT, and I'd like to show you a couple of applications that are using MLT and are shipping, actually. Some of them are shipping right now.

I'll start with Acrobat Reader. We're very pleased Acrobat has been using MLT. For instance, here you can see in the Find window. And Acrobat needed to support UniCode. And they had their implementation using TextEdit. And MLT fitted very well in this integration towards Mac OS X. With MLT, they get the Quartz anti-aliasing and the UniCode support they needed in their edit text fields.

Another client of MLT and we're very happy that they're using it is Maya. Maya is a huge application, and when they had to find a way to render their text in Mac OS X, they used MLT. MLT was their choice. Here they get, for instance, in the script editor, they have a full MLT object with the scroll bars. They support UniCode text, and the text is anti-aliased correctly.

Another client, and we're very pleased of that because we think it's very important for the platform, is of course, ResourceSerer. I'm sure all of you know ResourceSerer, and here, ResourceSerer implements MLT as a UTXT editor. A lot of the strings you're going to be passing to Apparence Manager, for instance, have to be Unicode.

Well, now with a new version of ResourceSerer, and thanks to MLT, the Multilingual Text Engine, you're going to be able to have Unicode resources in your application, so you don't have to do a CFString and convert your text from Mac OS X encodings to Unicode, and then pass it to MLT, DrawTheme TextBox, or other APIs. Another great feature that I really like in the new ResourceSerer is actually the Unicode Viewer.

They implemented in Resourcer this window that shows you all the character sets for UniCode, the 65,000 characters. So you could change the font and you'd be able to see all the characters. Here in this case, they use ATSUI, or actually the TXN Draw UniCode TextBox API, which enables them once again to have the UniCode support and the great quartz rendering.

Last, and this is of course just a couple of our customers, the Finder. The Finder uses MLT. The Finder needs to be able to enter Japanese and Roman text in the text files. Well here, in fact, when you edit text in the Finder, in fact, behind is an MLT text object.

Keycaps, you all know Keycaps. Keycaps uses MLT as well and uses the DrawTheme TextBox APIs to display the characters on the keys. Another great application, of course, is WordText, which takes power off MLT and shows advanced typographic features that we support on Mac OS X with AppSuite, Apple-type services for Unicode imaging.

There are way more customers, of course, and if you look at the Carbon Development List, you'll see a lot of questions on MLTE and a lot of developers using it. We're very pleased with what we've been doing and we're very pleased with the feedback that you're giving us so far.

Now, the agenda for today. I'll give you quickly a brief overview about the text architecture, how the solutions we're going to be talking about today are going to be fitting in the Mac OS X overview and the Mac OS X architecture by itself. Then John Harvey, our senior architect on MLT, will be talking about what APIs you're going to be able to use to display static text.

Last year, actually at the same conference, we got a lot of feedback and a lot of people wanted to have a UniCode Text Edit Control. They wanted the toolbox to have an MLT control in the toolbox. What I'm glad to say, with the new version of Mac OS X, the one that has shipped in March, you have actually this control and you can use it. John will be talking about that as well.

Thank you. We'll talk about that, don't worry. And then of course we still have MLT. If you need more control, if you want support for drag and drop, if you want support for embedded objects, we'll talk a bit about how you can do that once again with a Multilingual Text Engine.

And we have a special guest. We worked very closely with Metro-ERC, and happy to say that actually, Metro-ERC, in the next release, will implement a couple of new classes in Power Plant. So in Power Plant, you'll be able to drag and drop an object and you get all the MLT support you wanted.

Greg Dow, the architect for Power Plant, will be here and come on stage and show you a demo of his implementation. The last point that we talk about is Rick Fabric, one of engineers on the MLT team, will talk about tips and tricks on how to use a multilingual text engine. Sometimes we get some questions, since the architecture is different between quick draw text and MLT, and he'll be answering a couple of most of the questions, most of the common questions, when we can ask them. Pretty interesting. I encourage you to stay.

Quickly, the overview. So we'll be talking today about two different parts. The first thing you have to achieve in your application is display some static text. And if you use a drawstring, it's not going to work. Or draw text is not going to work because it's going to work. But then the text is going to be rendered with Quick Draw.

And you don't want that. You don't want your text to stick out. You want it to use Quartz. And here we talk about solutions to draw static text using our technologies that use Quartz and UniCode. The second part, we'll talk about text editing. And here, once again, you have two different choices.

We'll talk about the single line control, which is the toolbox control I talked about that uses MLT. And in order to display bigger text areas-- and once again, if you want support for embedded objects like sound, picture, or movies, then you'd be able to use MLT. All these technologies use ATSUI. ATSUI is the heart or text rendering on Mac OS X. ATSUI is Apple type services for UniCode imaging. And it's a powerful UniCode layout engine that enables us to enter CGK script-- Chinese, Korean, Japanese-- and give us advantage of Quartz rendering.

MLTE of course uses ATSUI directly and has its own implementation using ATSUI. On top of that, you'll see that in order to display static text and the single line control, the Apparence Manager is the one that will be actually using ATSUI. And below all that, you see that Quartz is the heart of our 2D rendering and gives us a point of flexibility of this new architecture to render text on Mac OS X. Alright, in order to talk about these different solutions to display text on Mac OS X, I have to invite on stage John Harvey. John Harvey has been working on MLT and is the architect for the technology.

Well, it's great to have a chance to come out and talk to people about the things we've been working on for the last year, and I appreciate your coming. There we go. So as Xavier said, I'm going to talk about three different areas: static text drawing, drawing a simple text area via control the way you did it on System 9 with the Edit Text control.

It's exactly the same kind of thing, except you get all the Mac OS X features with this new control: Unicode editing, Quartz rendering, automatic CJK support. And then finally, we'll talk a lot about building your own text area using MLTE. It's not that complicated, but obviously there's more APIs and so on you need to be involved in than if you just use the control.

Okay, so displaying static text. There's basically two approaches you can use on 10. You can use the theme text APIs, which are really pretty nice, because they bring together all the parts you need to deal with to get the right look in your text, you know. The theme text APIs, they know about what is the localization, they know about what the theme appearance should look like, they know about the state of whatever that text is.

And then if you really want a lot of control and like an incredibly feature rich set of APIs, you'd want to use Atsui. Now, in this session, I'm not going to talk any more about Atsui rather than to say that. There wasn't drawing with Atsui session. There'll be feedback for them. But it's just important to know that if you really want to get down and have fine-tuned text, those APIs are going to be there. And those APIs are available. But we'll talk about the theme text APIs for static text.

Okay, so here's the set. It's a pretty small set. Obviously the first thing you want to do is render text. For that, there's Draw Theme Text Box. It's basically the same kind of functionality you got from the TextEdit text box, but you get your quartz rendering, which you can see we're going to emphasize over and over again how important that is to have.

[Transcript missing]

Okay, and finally, I think a nice thing is the truncate theme text. On 9, you used to have to call, I think it's a text utility function to get a truncated string back, and then you'd have to go to Quick Draw to render it. Truncate theme text will do the rendering for you.

And, you know, these replace these old familiar routines, and I think a really nice thing is you don't have to sometimes look in the, in text edit, sometimes look in Quick Draw, sometimes look in text utilities. They're all there in Appearance Manager, specifically Appearance.h is the header where you can find them. Oops.

Okay, so talk a minute about the parameters that you pass into this. They have the concept of metafon IDs. These have been around for a while in the Appearance Manager, but they give you some really nice control, or makes it easy for you to tell what you want the text to look like without having to do all the work you had to do online where you'd have to go look in the Script Manager data structures and things like that to find what the right text is. You use these APIs, you say, "Okay, I want the views font, the push button font," something like that. The Appearance Manager does all the work, what's the localization, what's the right shadowing, that kind of thing.

At the same time, if you do want to use a font of the port, there's a metafont that says, "Use the information in the port." And by using these metafonts, you don't have to say a font, a style. And by using these metafonts, you don't have to say a font, a style.

And again, if you wanted to use the information in the graph port, you use the metafont which says, "Use port information." Like I said, these will take care of appropriate shadowing effects, you know, if something's active, inactive, that kind of thing, on the desktop, drawn in white, you know, the dot kind of text, that thing, those things.

And these are Unicode-savvy. One way that they are Unicode-savvy is when you pass text into these APIs, you use a CFStringRef. That's really the way to package Unicode text on Mac OS X. And the toolbox deals completely in those. And it's an opaque structure. You're probably familiar with it. And it will efficiently store Unicode text in there. You just pass it into these functions or other window titling menu functions, and it will draw the text in there.

Okay, so making sure these perform at their best, there's a few things you can do. Where appropriate, these APIs take a CG context ref. Um, now, if you were allowed to pass null in, if you do, the function will create a CG context ref and then dispose it.

Obviously, that takes time-- some time, not a huge amount of time. But if you're calling the function over and over again, it's creating, throwing away, creating, throwing away. It's time wasted. So you can create your own, keep it around, and just use that to pass in. Like anything you code, you know, be careful how often you measure text. Catch the values you get from measuring the text, and so on. Don't, like, constantly be calling, um, the measurement routine all the time.

Um, there's a lot more that goes on on 10. You know, probably on 9, it was real easy to just, uh, get, you know, text width all the time. That was real fast compared to maybe storing it. But it's really--it's important to think about holding on to those values. And of course, in the engineering group, performance is our utmost concern, and so we're working on speeding things up internally.

Okay, so next area I'll talk a bit about the edit text control, which, you know, for your basic editing needs, passwords, so on, is there. It's real easy to use. Oops, keep pointing up at that. OK, so again, you use this, you get quartz rendering for free. You don't need to worry about creating the CG context. In this case, the control does that for you.

The one thing that's nice is you use the same control, and you'll get built-in support for CJK input, but really there's a lot now on Mac OS X that has input methods. I mean there's UniCode input methods, hex input methods, things like that. You just use this control, it's all built-in. It's different from 9.

On 9 you had to use, be sure and use a different proc ID if you wanted to care about that. And probably diddle around a little bit with TSMTE and modified dialogue structures and things like that. But this is, you don't need to think about it, it's just there.

Which of course is really important on an international system. Again, you know, this control is built on top of MLTE. That's different from the Edit Text Control, which was built on top of TextEdit. But it's the same concept, you know, the basic text engine and then the control on top of that.

If you want to create this control, well all the controls on 10 now have a create function, which is a bit more straightforward to use. They're only on 10. So the old ways of course still work, new control, get new control. And in that case you have the new proc ID, which is K control edit UniCode text proc.

Okay, so with that, we'll move on to the building your own text area using MLTE directly. So, you know, last year we talked about some of these features, but we want to go over them again. People may not have been here. People not, you know, a lot of new developers coming over to Mac, I think, because of System 10.

Again, this is, on Carbon, this is the only way you can edit UniCode text. This is what you use, MLTE. There's no more 32K limit. That's been said a lot of times. It was a big problem in the past with text edit. For years and years, people said, "Fix that, fix that." Well, we didn't fix it in text edit. We made a new engine.

And again, you get your built-in support for CJK. You don't have to worry about it. And it's really not right, as I said, to just say, "Build in support for CJK." It's built-in support for input methods. And there can be an input method for any language now, any section of the UniCode character set.

On the old days, you had to allocate and hook your scroll bars up with text edit and handle the scrolling there. You don't have to do that. That's built in. Really, everything is handled, drag and drop, any sort of click handling that you had to deal with a lot of code in the past. Well, not a lot, but a significant amount. It's just handled with one function, the TXN click function.

We support embedded objects, pictures, sound, movies. There's a single tab per document. And we have a multiple undo/redo stack and also a way to find out what the undo/redo action is so you can then not only just say undo/redo, but undo typing, undo cuts, and that kind of thing. And, you know, again and again we're going to say this, you get the quartz rendering, which is such a signature part of Mac OS X.

Okay, so a quick comparison. I talked about how in TextEdit you had to do work to scroll and print and things like that. So on TextEdit, you had to write code, create the scroll bars, hook the rectangles up, deal with offsetting the rack. There certainly was a TE click function, but if you were scrolling, there was more that you had to do than just call TE click. All that scrolling is handled with the TXN click. There's one thing you know, it's the multilingual text engine, but for historical reasons, the APIs begin with the signature TXN.

So it's building support for clicks. That includes drag and drop and all the highlighting. And the other big thing is if you wanted to print text at it, you had to write a fairly large amount of code. And that's just, there's two functions, TXN page setup and TXN print you can call and you get the printing.

So just to emphasize this, you can see the difference in lines. These 269 lines, these samples are taken from the TE sample, which has been shipping with all the development environments that ever went out, MetroWorks, MPW. There's 269 lines to do these things, compared to two if you do it in MLTE.

And on the web, there's a project, a MetroWorks project, which has the old TE sample and then a new MLTE sample built in the same project. And you can compare the files, you can see it's the same basic functionality. And it's just a lot of code dropped out of the MLTE version.

And the nice thing is, you know, I mean, you need this functionality, but you'd really probably rather not worry about it, because you're trying to give something else to your users, your clients. So you don't have to anymore. Okay, now something I'm really looking forward to because I haven't seen it yet. We're going to see the demo from Greg Dow, and I think this is going to be really great.

I'm going to quickly just run through a couple of slides here. I think John already mentioned everything that MLTE and ATSUI and themed text drawing can do. And what I've done is created some Power Plant classes that wrap all this functionality up into simple, neat packages that you can use directly in Power Plant.

So I have a class now for MLTE. It replaces the existing text edit classes. There's also a class that calls LThemeTextBox to give you just a simple static text caption that you can use instead of all the other Power Plant caption or static text controls. Let me just move quickly to the demo here. This machine's seven.

I have a project here that I've built with these new classes. I'm just going to run it quickly. First thing that comes up is we have an MLTE pane.

[Transcript missing]

It's giving me the font menu automatically. It builds the font menu for me. I can select.

More readable, bigger. Capital's there, different font. It also automatically supports

[Transcript missing]

There, I automatically get Japanese characters mixed in with the same English characters, pictures, everything is all wrapped together neatly for me by MLTE. Undo, redo, here I can undo what I did there, undo a little more, keep going on the undo here.

and others. "I'm doing the picture drop and then I can go back, redo everything. And all this is handled automatically by MLTE. What I did is I took the existing Power Plant L-Edit text classes, pretty much stripped out all the code in each of the functions and replaced it with one or two lines of text of calls to MLTE. So in terms of your code that uses Power Plant, it'll be almost exactly the same.

The same API, you'll be just calling into a different object, but your calls will all be the same and it'll just work much better and faster." show quickly here's a demonstration of the theme box theme text box control or actually not to control just the pain one of the problems with this is a normal static text control people have mentions that it automatically erases so here you can see that there's the gray striped background behind the text when I have it over a picture if you don't want that to happen you can use the new theme text box class which will just draw the text directly without any erasing and see if I click off it there the text automatically dims there comes back and that's all taken care of automatically and this is all properly anti-aliased here over the picture Finally, I just want to show quickly here at SUI, although John didn't mention a lot of the details of what you can do with it, here is a sample here of the animation I'm doing myself just quickly inside a loop. What I'm doing is I'm changing the degree of rotation by five degrees each time and then just redrawing.

And here I'm drawing over a background picture and all that SUI is handling everything for me. So there's very flexible text. You can set the rotation, you can set the size, the style, and all sorts of other features. And all that is wrapped together in two power plant classes, one for handling the text layout itself and the other for handling the ADSUI style. And you can take those classes and use them in a custom pane to draw captions, like if you're doing a graph or something like that, we need vertical text on an axis. All this is accessible here from just a couple calls to ADSUI classes.

and best of all, this is also integrated now into Constructor. quickly here. Here's the MLTE pane that I had up there. I can just double click here. All the options for MLTE are accessible to you here from the properties. I can change the file type that's associated with the MLTE, the encoding. Here's some options.

You probably can't read all the options here, but I can turn off whether it has scroll bars, whether the carrot blinks in the background or not. Let me shrink this one up here. Take this Let's shrink that a bit and go back here to the layout catalog and drag out a new... MLTE pane here, so I can put a new one right next to that one there. And if I save this.

I'll go back to my project and run. We'll just bring in the new...

[Transcript missing]

Theme text. I'm going to close this window here. Bring up the, uh, the and the Theme text window. For the theme text box, again, I have a couple new options. It supports the theme font ID, so here I've chosen to use the current port font. I can switch over to use the system font. You won't see it updated in Constructor since Constructor hasn't been rebuilt yet with the new classes. And maybe I'll turn off--I don't want it to dim when inactive.

[Transcript missing]

through, bring up the theme text, and now you can see the theme text box is again drawn in the system font, again using the theme font ID so you don't have to worry when you're internationalizing your code, whether it's Japanese, Korean, English, or whatever, you'll get the proper system font without worrying about having to set up in PowerPlant now where you have to make a text trace resource where you put the name of the font in there.

Here you can choose the theme font ID. Again, if I click here you can see there the text doesn't dim, I've turned that off, so you have the option of having the text dim or not in the background depending on your needs. So this is all built into PowerPlant.

Unfortunately, it's not in the version you have on your CD now. That version froze about a month ago and I didn't have time to update it, but it'll be in the next seed version of PowerPlant, which if you haven't signed up already, you should consider joining the MetroWorks Beta program and you can come by the booth and ask about this or check on the website and it'll give you directions for sending an email in to join up on the Beta program. Subtitles by the Amara.org community program. Subtitles by the Amara.org community Thank you. Thank you. Well, that's really great. I mean, it's so rewarding to work on something, and you wonder how much people use it while you're working on it.

And then to see that demo is fantastic for me. And really thanks to Greg for doing that. I can't wait to start using it myself. Make my life a lot easier. Okay, so now we'll talk a little bit about the newer things. We'll talk about Quartz rendering again. And so Quartz rendering, you know, over and over again, this is what you can get.

You get your anti-aliasing, it's a really significant part of the look of Mac OS X. Also in MLTE, we have the beginning of support for Carbon Events. We're going to extend this as we go along. Right now, we support text input Carbon Events, and I'll talk about some of what this gives you. On System 9, all the input from UniCode keyboards came through Apple Events.

Currently on 10 now, it by default comes through Apple Events, but you can tell us to use Carbon Events, or you can put your own text input handler on top of us and do filtering, which I'll talk about. And the other thing we've done is, where appropriate, we haven't changed our APIs, but underneath, under the hood, we've adopted the newer Mac OS X architecture. The specific cases are printing and the Scrap Manager. So we use the promises, things like that, if you're familiar with the new Mac OS X Scrap Manager.

Okay, so quartz rendering. Let's look at how you do this. You get your system, get that right system look when you do it, and it's really pretty simple to do. You create a CG context, and then you hook the CG context up with your MLTE object. That's all you need to do. I can show you the code right here.

So, there's a few data structures. You have your TXN, the prefaced data structures, the control tag and the control data. The tag you set with a constant. It's actually defined in at atsunicode.h. That's the atzui header. The other ones are in mactexteditor.h. That's where MLTE constants and functions are defined.

And then you create your CG context with the createCGContext for port. That's an API in Quick Draw. Once that's done and it's done successfully, you plug that into the control data, the value field, and then you just simply call this TXN setTXNObjectControl. Once you've done that, you get Quartz rendering. You don't have to do anything else.

Okay, the next thing is the Carbon events, text input specifically. It's nice to see everything and then highlight like that. Okay, so we support all the text input events. So that includes the text input event when it's coming directly from a keyboard, and then the text input events that come from an input method, which include all the ones which tell me which the input method might ask where the text is, or might ask for the text, and that kind of thing. The nice thing about text input events, which For you, which was very, very hard to do if close to impossible when we used Apple Events, is you can pre- and post-process text input.

and the other thing to know is that if you tell MLTE to use text input events, that's going to be the optimal path. Because right now on 10, if we are still using Apple events, what happens is the text services manager has to take the text input event off the event queue, pull the data out, allocate an Apple event, fill that in, and then pass that to us.

I mean it's not something that's so time consuming that you really notice it in your typing, but if you tell MLTE to use a text input event handler, that doesn't happen. The data structure can just move around the S's without any massaging on the part of the text services manager.

Okay, so how to do this? You see this is, the code is actually very, very similar to what we saw for the CG context draft. You've got those same TXN control data structures. This time we use a constant useCarbonEvents, which is in the Mac Text Editor header. And we have an array of keys, an array of values, which we'll use to build a CFDictionary. We use CFDictionary so we can include more and more Carbon events as appropriate. So the expandability is right there and ready for you, or us, ready for everyone.

Okay, then there's a data structure, the TXN Carbon event info. A few fields you set up there. You say, "I'm using Carbon events." Obviously you can turn them off if you want by setting that to false. In this case, there's a flag that says, "I want you to turn off the Apple event handlers." This is usually what you do. But the thing is that when you throw this object away, if you have other TXN objects, or there might be other TXN objects around in your application, you want to be sure and tell it to turn the Apple event handlers back on.

Then you create your dictionary with CFDictionary create, one of the core foundation functions. And at that point, you put a pointer to the Carbon event info in the value. And you call that same function again. It hooks it up and MLTE will start using text, handling text input with the Carbon event handler rather than Apple events.

And in this case, you need to be sure and release the CFDictionary because all the information MLTE needs is copied when you call the set TXN object control function. Very straightforward. It's sort of like boilerplate. Okay. So, I'm going to use the boilerplate now for telling MLTE what to do on 10.

Okay, so there's the three topics again. And what, I mean, I'm not going to say anything else. There's no slides talking about the printing or the scrap managers. Just as I said before, we have the exact same functions that we had before, you know, TXN paste, copy cut, TXN print, TXN page setup. But underneath, they use the new architectures.

Okay, so at this point, I've been working a lot with Rick Fabrick. He's done most of the work, or all the work, not all the work, but most of the work on CarbonLib. And he's had the most interaction with you, the developers. And he'll talk about some problems people have had and issues that they weren't sure about that he's been able to help them with, and basically his experience working with developers. Thanks a lot.

Thanks, John. In working with developers who are integrating MLTE into their applications, we get many questions, as John has said, similar to what's the best way to program for this particular task. So what we're going to do now is go over some of the tasks that we have received the most questions on.

What you see here is a list of the tasks that we'll be discussing today. And we'll see this list several more times as we go through each of the tasks individually. We're going to be starting with, what is the best way for you to change the size of your text objects? And there are some key concepts to understand in order to get the best interaction between the user and your text object, as well as the printout that you're looking for when you print the object out. Now the first thing to understand is what the difference is between the view rectangle and the destination rectangle, and how MLTE defines them.

So the destination rectangle defines where the text will wrap in your text objects. It's the full page of text for your object and is what would be printed out when you print the object out. The view rectangle shows the currently visible portion of the destination rectangle and is what the user sees at any one time.

Now in MLTE, the view rectangle includes the area taken up by the scroll bar. So if you're familiar with the Mac OS's original text engine, the view rectangle in text-edited objects doesn't include the area of the scroll bars, and that's because text-edited objects don't have scroll bars. If scroll bars were necessary, then the developer would have to create and manage them separately from the text object. But since MLTE handles the creation and the event handling automatically for you, we do include the areas from the scroll bars.

So the initial value of these rectangles are set when you create the object with Tx and newObject. This API has a parameter that accepts either null or a pointer to a rectangle. If you passed in null to this API, what you would get back is an object that takes up the entire window. Basically the view rectangle would be the bounds of the window. And the destination rectangle would be set to the standard US letter page size.

If on the other hand you passed in a pointer to a rectangle, the object that you got back would only take up a portion of the window, and that portion would be equal to the rectangle that you passed in. Now in this case, the destination rectangle would be that rectangle, but we don't include the scroll bars in this case because you want the text to wrap at the scroll bar and not go underneath.

So let's say you need to change the size of your object. If you had passed a null and your object takes up the entire window, then what you should be calling when the user is trying to change the size of the window is Tx and growWindow. And what this will do, this API changes both the size of the window and the view rectangle for your object.

But if you had passed in the pointer to a rectangle, you would want to call one of these APIs. So let's say you have an object that you allow the user to change the size of, and when the size of the object changes, you want the text to always wrap at the scroll bar. In this case you would call the first API here Tx and resizeFrame, passing in the new window. So you can see that the text is always going to be at the width and height of your object.

What this API does is it keeps the destination rectangle and the view rectangle in sync so that the text will always wrap at the scroll bar. Now, let's say you have another object that when the user changes its size, you don't want to change the size of the text, the destination rectangle in your object, just the view into it. In this case, you would call the second API here, TX_IN_SET_FRAME_BOUNDS. In this case, you would be passing in all four boundaries of the new view rectangle.

Now, this API is very handy if your object takes up the entire window, because what it does is... Well, actually, I'm not there yet. So what this API will do is it's also helpful when you want to move the object around in your window, because you are passing in all four boundaries.

So we don't offer an API that allows you to change just the destination rectangle. But if you find it necessary to change the dimensions of the destination rectangle, what you can do is call TXN resize frame, passing in the new width and height of the destination rectangle. And what this will do is the side effect will be that the view rectangle will also change, so then you could call after that TXN set frame bounds so that you can reset the view rectangle back to what you want it to be. Thank you.

So we do offer a couple of options that allow you to change the behavior of these API, and they deal with how the text will wrap in your objects. and the first option here, Always Wrap at View Edge. If you go back to the example of your object where you always want the text to wrap the edge, what you could do is pass in this mask to Tx a new object when you create the object.

And what this option will do is it will keep the destination rectangle always in sync with the view rectangle, regardless of which of the API you call. So what I was going to say before is if you have a window that the object takes up the entire window, You're going to have to call Tx in Grow window. And normally this API only changes the size of the view rectangle. But if this option is set, then the destination rectangle will be kept in sync with the view rectangle and text will always wrap in your window.

So if you have an object that you allow the user to edit source code, you're going to want to turn Word Wrap off. So our second option here allows you to do so. What you would do is you would pass in the Word Wrap state tag to the API TXN set TXN object controls. And what that does is basically sets the width of the destination rectangle to be infinite. So text will not wrap unless the user explicitly enters a character that ends a line. And one example would be character term.

So along with the tag, what you'd want to pass in is a constant that is defined in MacTextEditor.h telling the object whether it should be turning WordRef on or off. So we offer several API that lets you change the size of your objects, and that gives you the flexibility of getting the exact behavior that you want, and you can have different types of objects.

So another task that we've gotten lots of questions on is how to set the style of a certain range of text in your object. And in order to do that, what you would need to call is txnSetTypeAttributes. What you would do is you would fill in an array of TX and type attributes with all of the attributes that you want to change, and then pass that array into the API along with a count of the number of attributes you're changing.

What I want you to note here is that you can change as many of the attributes as you want with a single call to the API, just simply by filling in as many of the elements of the array that you need. Now along with the array and the count, you would also be passing in the start and end offsets for the text you want updated. So in this case, when this text gets executed, the current selection will become red. It will have a font size of 36, and it will become bold.

Pretty straightforward. Filtering text. That's another important thing that we get questions on. And so For instance, you may have an MLTE field that you only want numbers to be entered into, or you want to filter out characters like the carriage return or tab character. What you would need to do is install some filters, and in this case, for key events entered from the keyboard, these filters take the form of Carbon event handlers. Here's an example of one of them.

Normally what you would do is you would install this handler to the particular class, the event class of text input and the event kind of UniCode for key event. So you wouldn't be doing the test for those values here in your filter, but I put them here so you can see what their values are. This example here basically just makes sure that all the key downs in your object are numbers. If they're not numbers, then they're filtered out.

So you do your test. If you want the text to be entered into your object, then what you would do is you would return event not handled error, telling the Carbon event manager that you haven't handled the event, so pass it on to some other handler that may. And in this case, that would be MLTE. If you do want to filter the text out, then you would return no error, telling the Carbon event manager that you've handled the event with no error and nothing else needs to happen.

So this event handler for UniCode for a key event will get called for every key event that's entered into the keyboard if there isn't an input method handling the text. If you do have an active inline area, however, a seconds handler will be called, and this is the update active input area.

What you would do here is basically the same thing, but you would need to wait until the active input area has been confirmed. And there's a piece of information in the event that you can examine to tell when this happens. When this does happen, then all you need to do is do your test on all of the text that was just entered. And part of the data for the event is the range offset, so you know exactly what text to filter. And you return the same values depending on whether you want to filter that data in, filter that data out or let it pass in.

Normally you wouldn't have two separate filters, you'd have a single one and you could install it directly to the two event kinds, Update Active Input Area and Unicode for Key Event. have two filters here so that I can fit them on a slide--on two slides. Okay, so entering data in from the keyboard is one way to get text into your object but you can also have drag events happening.

So to be able to filter that data, you would need to install your own drag handlers. And it's pretty easy to do. The first thing you need to do is tell MLT not to install its drag handlers, and then basically you just install your drag and drag receive handlers. And I'll describe those two handlers in a second.

Telling MLTE not to install its drag handlers is really easy. All you do is when you're creating your object, you pass in "Do not install dragprox mask" to Tx a new object. Now, this mask doesn't disable drag and drop. Dragging from your object is still enabled at this point. All it does is it temporarily disables drags to your object until you've installed your own drag handlers.

So the first drag handler you need to install is the drag tracking procedure. And this handler gets called continuously as the user is dragging the data over your object. And MLTE's default behavior isn't sufficient in most cases. So all you would need to do is pass this event on to MLTE by calling txndragtracker.

In my example here, I'm doing some eye candy just to show you that if you need to do something, you can. But as I said, MLTE's default behavior is, in most cases, sufficient. Now the filtering of the data is done here in your drag-receive procedure. And this gets called once when the user lets go of the mouse button and has dropped the data into your object.

This example here also filters out anything that isn't a number, so the first thing you need to do is test the data to see if it's all digits, all numbers. If so, then you want to pass the event on to MLTE by calling TXN_DRAG_RECEIVER. If you do want to filter the text out, however, you return no error, telling the drag manager that you've handled the event with no error and nothing else needs to happen.

So I've given you some help on some of the tasks that we've been getting questions from you guys. If you have any more questions, and I'm sure you do, please stay for the Q&A session at the end of this session and let us have it. At this time, I'd like to bring Xavier back up to go over a quick summary of what we've been talking about today.

Xavier? Okay. Thank you. quick wrap-up for this session so once again you don't want your application to stick out like a sore thumb by displaying text with quick draw text and you want your customers to be able to enter unique code text and use all the power of that suey and the quartz rendering once again all these technologies have been talking about today use the power of at sweet for doing the unique code rendering and use the power of quartz to actually bleed the text correctly with the right anti-aliasing so in order to display text on the Mac OS X please use the H I toolbox API's the theme text box API's are great we're still working of course and always making them better they are like a nice migration for you to display text static text correctly If you want to have editable text areas, you have two solutions. If you want a quick turnaround, and let's say you're using already the old TextEdit control, please use the new UniCodeEditTextControl. John talked about how you can use that. It's very straightforward. It could be just a matter of using the new proc ID for the UniCodeTextControl.

If you need more control, and as we said, if you need embedded objects, if you need support for sound, movies, and pictures in the object, if you want to control yourself, the score bars, if you want vertical, horizontal, if you want drag and drop, please use the MLT APIs directly. I think we showed you that the set of APIs that we're giving you is very powerful. In just a couple of calls, you'll be able to achieve a lot.

You get not only the support for multi-lingual text, but you'll get as well all these features that have been missing in TextEdit. As you're seeing too, with Power Plant, if you're using Power Plant, you get all these features very quickly integrated in your application, which is going to make your life way, way easier.

I'd like to give you some information on where you can get actual information on our documentation. We just released the MLT documentation which has been updated. TechPubs has been doing like a fabulous job with our technologies in the last year, releasing more and more information. And I'm glad to say that actually you'll be able to get the PDF on the web, or you can actually get the bone documentation from FatBrain. You have here like, you know, the two places on the web where you can get them. We have a lot of sample code that uses the Multilingual Text Engine. And you'll be able actually to find the latest sample code on the CarbonLib SDK.

We have as well an MLT SDK, but the CarbonLib SDK is great because we're updated every time we do a new release for CarbonLib. So you'll get there like, you know, the latest things. You'll get like actually the application that was written just to show the migration between text to MLT. It's kind of nice.

AtSuite is the center of text rendering, and that's like, you know, the foundation for all of text drawing. Once again, as John said, you need more control on the layout. You really need to measure the text yourself, and you need, let's say you're writing your own text engine, then please check out Let's Read documentation. And here you have it. You'll find it on developers.apple.com.

So where to go from here? We didn't talk about Cocoa Text, but for a very good reason, which is Cocoa Text is already ready for UniCode and supports Quads as well. If you need more information about using text for your next TextView classes, for instance in Cocoa, please go to the session 122 on Thursday, which will be actually in this hall. Font management is a big, big, big new thing here on Mac OS X with all these new fonts that we support now. I encourage you, if you need to have more information on that, to go to session 128, Thursday at 2 in Room C.

I'll be there. We talked about the Quartz support. And if you need more information about how do I get my CG context on my graph port, how can I manipulate, do rotations, skewing, rotation, all these new things that are supported by the Quartz rendering engine, please go to session 132, Graphics and Imaging Tips and Tricks, in room A2 on Friday at 9:00 AM.

If you have feedback, and I'm sure you have, and you want to let us know that we're on the right track, you love what we're doing, or even if you have questions and you want to tell us, hey, I need this API, please come to the International Feedback Forum. It's a great way for us to measure what we're doing, how much of these answers you need, and it's a great way as well to talk to developers.

Another great way to talk to our engineers is to come to more of what we call the International Lunch, where French food will be served, in the cafeteria, actually. We'll try to get some balloons, and we'll have different themes going on. We'll have a table for if you want to talk about the font management APIs.

We'll have a table about text, and we'll get Cocoa engineers as well there. So if you have Cocoa and Carbon questions on the same table, you'll be able to get your answers. We'll have another table, too, on localization. There is a session that is not there, but we'll have a session on localization and how you can localize your application for Mac OS X tomorrow, Thursday, in Room C at 3:30.

Should you have any questions, you can always contact me at xavier.apple.com. I work in worldwide developer relations and that's my job to answer your needs and to make sure that the APIs that you want and the bugs you want to be fixed are fixed. So you can always contact me. It's great. I have a lot of developers already contacting me and have been working very closely with probably some of you here. Don't hesitate to send an email.