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 may have transcription errors.
Bonjour.. 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 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.
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 NT-adiesing 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, it's 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 nt-alias correctly.
Another client-- and we're very pleased of that because we think it's very important for the platform-- is, of course, Resourcerer. I'm sure all of you know Resourcerer. And here, Resourcerer implements MLT as a UTXT editor. A lot of the strings you're going to be passing to the Apparence Manager, for instance, have to be Unicode. Well, now with a new version of Resourcerer, 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 and codings to Unicode and then pass it to MLT, draw theme text box, or other APIs. Another great feature that I really like in the new resourcer is actually the Unicode viewer.
They implemented in Resourcer kind of this window that shows you all the character set 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 Join Unicode Textbox API, which enables them once again to have the Unicode support and the great quarts 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 draw theme text box 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 encode imaging.
now when our customers of course and if you look at the Carbon development list you see a lot of questions on a mighty and a lot of developers using it we're very pleased with what they've been doing and we're very pleased with the feedback that you're giving us so far - Yeah.
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 macros 10 overview and the macros 10 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 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 Marcha, 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 try. 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 Earths. I'm happy to say that actually Metro Earths, 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'll 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 Fabrick, one of the engineers on the MLT team. We'll 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 DrawString, it's not going to work. Or DrawText is not going to work, because it's going to work. But then the text is going to be rendered with QuickDraw. 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 of text rendering on Mac OS X. ATSUI is Apple type services for Unicode imaging, and it's the powerful Unicode layout engine that enables us to enter CGK script, Chinese, Korean, Japanese, and give us advantage of Quartz rendering.
MLT, 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 Appearance 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. All right, 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. Hey, John.
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 Savya 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. The theme text APIs, they know about what is the localization. They know about what the theme appearance should look like. and know about the state of whatever that text is. And then if you really want a lot of control and 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 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 text edit 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.
So, I mean, other than that, you get your justification right, center, left, the standard things. And I'll talk a little bit about the parameters that get passed into this that give you more features, more control over how the text looks, what the font is. If you want to measure that text, which obviously a lot of times you want to do, you want to figure out how big the box is that you're going to draw into, you can call the get theme dimensions. This returns not only the height and width of text, but it will also return a baseline, which typically is a small negative value, one or two, and you add that to the height to figure exactly where to start your drawing. And on 10, since a lot of things are shadowed, you need to find out how much shadow space there's going to be around your text so you don't clip that out or draw over it. and that second API text shadow offset will tell you that. It's a rectangle with offset values as the return.
OK, and finally, I think a nice thing is to 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 these replace these old familiar routines. And I think a really nice thing is you don't have to sometimes look in text edit, sometimes look in Quick Draws, sometimes look in Text Utilities. They're all there in Appearance Manager, specifically Appearance.h. It's the header where you can find them.
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, OK, 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 You don't have to say a font, a style, a size explicitly. It figures that out. 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. 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.
OK, so making sure these perform at their best, there's a few things you can do. These--where appropriate, these APIs take a CG context ref. Now, if you are 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 constantly be calling the measurement routine all the time. There's a lot more that goes on on 10. Probably on 9, it was really easy to just get text width all the time. That was real fast compared to maybe storing it. But it's really important to think about holding on to those values. And then, 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 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 dialog 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, this control is built on top of MLT. That's different from the edit text control, which was built on top of text edit. But it's the same concept, 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 last year we talked about some of these features, but we want to go over them again. People may not have been here. 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. was a big problem in the past with TextEdit for years and years. People said, "Fix that, fix that." Well, we didn't fix it in TextEdit. 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 "built-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.
In 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, and 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-- is 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 again and again, we're going to say this. You get the quartz rendering, which is such a signature part of Mac OS X.
OK, 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 edit, you had to write a fairly large amount of code. And that's just-- there's two functions, txnPageSetup and txnPrint, you can call, and you get the printing.
So just to emphasize this, you can see the difference in lines. There's 269 lines. These samples are taken from the TE sample, which has been shipping with all the development environments that ever went out, Metrowerks, 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 Metrowerks 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. The nice thing is, 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. OK, 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. Here it comes.
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. I can type text here. I can also--here I have in the finder, I've just made a couple of picture clippings. I can take that, drop that in there. Now I have... light bulb in there. Can click back out. Let me drag another one in. Car in there. So it supports automatically graphics and text mixed together. Again, MLTE is giving me the scroll bars automatically. It's giving me the font menu automatically. It builds the font menu for me. I can select-- I'll get another font in there.
more readable, bigger, capital's there, different font. It also automatically supports Unicode. Here I'm going to switch over to a Japanese keyboard here. And if I type some-- there. I automatically get Japanese characters right 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 I'm undoing 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 text box control, or actually not a control, just a pane. One of the problems with this is a normal static text control, people have mentioned 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. You can see if I click off it there, the text automatically 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-- at SUI is handling everything for me. So this 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 ATSUI 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 ATSUI classes.
And best of all, it's 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 maybe 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 here and-- shrink that a bit and go back here to the layout catalog and drag out a new image. MLTE pane here so I can put a new one right next to that one there. If I save this.
I'll go back to my project and run. We'll just bring in the new POB and here I have text over here, text over here. So again, it's very simple to use. You just use it like you do any other power plant pane. And the same thing for the Theme text. Close this window here. Bring up 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.
Save this. And again, go back to my project. And run that again. 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 Power Plant 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 background depending on your needs. So this is all built into Power Plant. 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 Power Plant which if you haven't signed up already you should consider joining the Metrowerks 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 and that way you'll be able to get access to the latest builds of Power Plant and these new text features. Thank you.
hand off the baton. 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 work 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. OK, so now we'll talk a little bit about the newer things. We'll talk about quartz rendering again. And so quartz rendering, 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. And then on system 9, all the input from Unicode keyboards came through Apple events. Currently on 10 now. By default, it 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 atsunicode.h. That's the ATSUI 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 Create CG Context Report. 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, set TXN object control. Once you've done that, you get Quartz rendering. You don't have to do anything else.
OK, the next thing is the Carbon events, text input specifically. It's nice to see everything and then highlight like that. 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'll 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 use Carbon events, 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. 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 want to 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 field.
And you call that same function again. It hooks it up. And MLTE will start 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 setTxInObject control function. Very straightforward. It's sort of like 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, or 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. Thank you.
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 gonna 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 V 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 new object. 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 trying to change the size of the window is TxInGrowWindow. 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, and resize frame, passing in the new 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 and set frame bounds. In this case, you'd 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 Um, 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 wanted it to be.
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. 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 and new object and 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 gonna 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 WordWrap off. So our second option here allows you to do so. What you would do is you would pass in the WordWrap 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 WordRep 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 txn set type attributes. 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. 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 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 second 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-- and 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 MLTE not to install its drag handlers. And then, basically, you just install your drag tracking and drag receive handlers. And I'll describe those two handlers in a second.
Telling ML to E-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 drag procs 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 is sufficient in most cases. So all you would need to do is pass this event on to MLTE by calling tx_drag_tracker.
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, MLT'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 pass no error -- 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 the 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 we have been talking about today use the power of that suey 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 HIToolbox APIs. The Theme Text Box APIs are great. We're still working, of course, on always making them better. They are like a nice migration for you to display 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 Unicode Edit Text control. 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 Unicode Text control.
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 from multilingual text, But you'd 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 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 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 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 the latest things. You'll get 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 the foundation for all our text drawing. once again as just said you need more control on the layout you really need to reach over text yourself and you need that's your writing your own text in china then please check out that's the documentation and here you have it you find it on the represent that but that's common Thank you.
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 Quartz as well. If you need more information about using text, the next TextView classes, for instance in Cocoa, please go to the session 122 on Thursday, which will be actually in this hall. Font management, it's 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 to session 128, Thursday at 2:00 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, and 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 you know 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 you know what we're doing how much like you know 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 tomorrow what we call the international lunch where french food will be served in the cafeteria actually and we We'll try to get some balloons, and we'll have different themes going on. We have a table for if you want to talk about the font management APIs. We 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 have another table, too, on localization. And there is a session that is not there, but we 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.