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: wwdc2002-208
$eventId
ID of event: wwdc2002
$eventContentId
ID of session without event part: 208
$eventShortId
Shortened ID of event: wwdc02
$year
Year of session: 2002
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC02 • Session 208

MLTE: A Unicode Text Engine

Carbon • 54:16

Learn about the Multilingual Text Engine (MLTE), Apple's full-featured API for creating and editing Unicode text documents. MLTE is the modern replacement to TextEdit. This session covers the benefits of MLTE for developers and discusses such new features as URL support and the new scrolling APIs.

Speakers: Rick Fabrick, John Harvey

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, everybody. Welcome to session 208, MLTE, Unicode Text Engine. I know it's a bit early, but I think you'll appreciate the content today. My name is Xavier Legro and I work in Developer Relations. I'm the Mac OS X Evangelist. And I'm going to walk you through the introduction on what the session is going to be today.

We'll have a quick overview on MLTE, the Multilingual Text Engine. We'll walk you through a couple of concepts around MLTE. And these concepts are very important for you to understand if you're new on the platform or you're new to MLTE in the sense that the approach in using MLTE and using TextEdit is very different. And once you understand these concepts, I think you'll get the best of MLTE very quickly.

We'll go through some of the basic tasks: how to set styles, attributes, how to pass change text, set text, create a new object. And of course we'll have another level where we'll go through some more complex tasks. And I think some of you that are probably using MLTE already will be very, very interested in actually the feature set that we'll be adding to the next version of MLTE in Jaguar Mac OS 10.2.

Alright, before we go into the details, let me give you a quick overview on where MLTE stands in the system and on what it relies on in order to do its job. First, you can see on the bottom is that the rendering that MLTE is using is Quartz.

Quartz is our 2D rendering engine, and MLTE takes full use of this 2D rendering engine. The first aspect that you see on the screen is the beautiful anti-aliasing. So remember, if you're using TextEdit, you're going to get the quick joint aliasing. MLTE, by default, will be using actually Quartz, so you get the nice anti-aliasing.

MLTE is based in order to do its UniCode layout on Hatsui, Apple-type services for UniCode imaging. And I'm sure you all went to the Hatsui session on Tuesday. But it's very important to understand that in fact MLTE is a text engine built on top of Hatsui. So for you as a Carbon developer, that's probably the main way to achieve support for all these new languages we introduced with Jaguar. And for you as a Carbon developer, it's the only way to actually have a quick text engine that will have support for UniCode input and layout.

MLTE offers many, many different features and maybe the feature set is too heavy for you and maybe your needs are more limited. And in this case, you will have different solutions. You could use actually the UniCode control, which actually we created in Mac OS X from feedback that developers gave us a couple years ago, actually at WWDC.

So you could actually create a UniCode text engine by using the toolbox. So you know, like the way you do, like create new control and you'll have a few parts of the TextEdit tag. Well, on Mac OS X, remember that you can switch very quickly to have an MLTEdit field by switching the tag to use the CAI thing, CAI UniCode Text Edit Control. I encourage you to look at the Appearance Manager for more information.

Now, as a developer, you probably have two different needs in order to display text on the platform. And here on the top, we try to distinguish that between using static text and using editing text. If you need very basic fields, edit fields, such as, you know, if you want to enter the name of one of your customers, if you want to just have -- enter some data on a single line, you could use directly the Toolbox control. It's very easy. If you're using TextEdit right now, it's going to be an easy switch. It's pretty straightforward. And that gives you all the feature set of MLTE.

Now, if you have needs a little bit more elaborate and you need to have scroll bars, you need to support drag and drop, maybe embedded objects such as pictures, sound, movies, I would encourage you to use MLTE directly. MLTE is a set of APIs that is very, very easy to use and we have a lot of sample code actually to help you migrate from the previous TextEdit implementation to MLTE. There is one thing here that doesn't appear, it's TextEdit. It's very important for you to understand that TextEdit was what we had on Mac OS 9 and moving forward, MLTE is actually a replacement for TextEdit on 10.

Now, as I told you, you probably have two different needs: text editing and static text. For the static text, once again, you have two different choices. The first that comes to mind, of course, is to use the Draw Theme Text Box APIs, which are in the Appearance Manager, and I'm sure you're all now familiar with that.

The second way, if you need to do, for instance, rotation or you need to pass specific style attributes and you want to manage the styles yourself, or you want to do alignment, justification, and flushness, another solution for you is actually to use one of the APIs in the MLTE headers called TXN Draw UniCode Text Box.

This API comes actually in two different flavors: one takes a CFString, and the other one takes like a UniCode pointer and a length. And I think we'll talk later, actually, in the presentation about these APIs. But remember, it's really about choices here. And you, as a developer, your goal is to make sure that your application displays UniCode text correctly. And here, we're offering you different solutions.

Important to note too that if these two APIs are not enough, you can of course always go in that three layer and use that three APIs to display your static text. All right, let's go now on the concepts and how you as a developer are going to take advantage of MLTE. And for this, I'd like to invite on stage Rick Fabrick, who is actually a software engineer in the Toolbox group.

Thank you. Thanks, Xavier. And good morning, everybody. So, Multilingual Text Engine. What is MLTE and what can it do for me? What new things do you plan on adding for Jaguar? And what do I have to do to get text from my customers using MLTE? I'm sure that most of you would like at least one of these questions answered, so that's what I'm going to do for you in the beginning of our presentation, the overview. So let's start there.

MLTE, in short, is the carbon-based UniCode text engine for the Mac OS X. It's the multilingual successor to TextEdit, as Xavier mentioned, which was the text engine that Apple has used over the last decade and a half. Now, MLTE has been designed such that most or a lot of the standard user interactions with your text objects are handled automatically by MLTE. What you see here is a list of some of those things. Now, when I say basic, I mean basic to your clients, your customers. Some of these are non-trivial to implement by you.

So we've taken a lot of that burden on for you. And the most important of these is text input. The input of text can be either directly from a keyboard or indirectly through an input method. So if you're using Kotori and you're typing in Japanese, we'll handle that for you automatically, and we'll do so with an inline session within the text field itself.

Now, the associated rendering of that text we will be using Apple's Atsui, a powerful text services layout. And for rendering, we are going to use quartz imaging so that you get the nice quartz anti-aliasing to match the text and the rest of the system. There's a couple of other things we'll handle for you. Scroll bars, drag and drop.

You can have us create our own scroll bars and handle scrolling for you. Most cases, you won't have to deal with scroll bars at all. We'll do it for you. So what I'd like to do now is to go through a really quick demo of exactly what it is you'll need to do to get an application with all of these features. So if I can bring demo two up on the screen to my left.

So, what I want to show you first is, this is a basic application. It's doing nothing more than bringing in a menu bar. It's creating a new window, showing it. and running Application Event Loop. And this will give you a basic menu bar with menus. You can... What did I do here? Oh. Okay. What I forgot to do is change... I forgot to attach the file. Alright. So, you can resize the window, move the window around. Very simple.

So, now you have your application and you have your window. You want to add your text object. There's only three things that you're going to need to do. Let me scroll down a little. You need to initialize Text Engine. You need to create your new object and then focus the object. So now what I have, again I did the same exact thing. I forgot to touch the file.

So now I can start typing. I can switch to Kotori and try to type some Japanese. Hopefully that's not garbage. Resize. Now what I want to demo here is drag and drop. You can drag in a file from an external source. When you resize the window, we'll reflow the text for you automatically.

We'll handle scrolling automatically for you. Let's see. Is there anything else I wanted to show you? Oh, well, drag and drop within the object, obviously. All right. So with these three lines of code, you get all of that built in for you. Okay, so if I could bring the slides up again.

Now, in most cases, this is about 70% of everything that you'll need to do in order to use MLTE. Now, to be more practical, you're going to want to at least get your text from those objects or at least save it to a file. So to support that, we provide you with a simple set of APIs to do things such as opening a document, printing your text. Most of the edit commands we'll handle for you: copy, paste, undo, redo, select all things like that. If you want to supply your customers with a font menu, you can ask us to make one for you. We can even handle that font menu if you like.

We supply a search mechanism so that you can export to your clients a way to search for text in your text fields and some other things as well here. At SUI, which is Apple's type services for UniCode imaging, it offers a very powerful set of advanced topography features. So, for example, let's say you have a text field and you want to display a chemical equation. You may want to need more fine control over exactly where some of the characters go.

Advanced typography features allow you to do that. Another example would be if you're designing a fancy invitation and you want, like on the sides of the text, really nice swatches or you want ligatures. Since MLTE is well integrated with ATSUI, we can provide you a very easy interface to those powerful features. And a little later on in this presentation, we'll show you exactly what you would need to do to take advantage of these.

And finally, if you have a couple of text fields in your window, this may not be an issue for you. But in a lot of cases, you may want to dump a lot of information in your text fields. Maybe you're trying to view a binary file or providing, you want to see, let's see, a script, a huge script or something like that.

Well, MLTE has no set limit to the amount of data you can put in its objects. So basically you're limited by the amount of memory you have in your computer. So there is no 32K text limit in MLTE. Yay. That's not news, but it's still good. Okay, so new features in Jaguar.

Last year's WWDC and over the past year, you've given us a lot of feedback on some of the features you'd like us to add to have MLTE more helpful to your particular applications. So what I'm going to do is a brief overview, a brief listing of what we plan on adding for Jaguar. And let me preface this by saying that later on in this presentation, we'll go into more detail on each of these things. So the first of these is automatic URL detection.

So if you have a text field and there happens to be somewhere in the text a URL, right now, what your customers, if they wanted to see that for, let's say, it's a website, they'd have to select the entire address, copy it, go to their web browser, wait, click on the URL text field, paste, hit return.

Wouldn't it be nice if all they had to do is command click somewhere in that URL and have the web browser automatically come up and go to that website? Well, we do plan on adding that for you in Jaguar. Now, in addition to that, we also will allow you to tag particular ranges of text with your own URL. You'd give us the range of text, the start and the end offset, and the URL, and we'll basically do the same thing. thing when they click on that.

The second thing is monostyle text. So let's say you have a text field, and you've designed it perfectly, you've chosen the right font, the right font size to make it look exactly the way you want it to look, and then now your customer comes along and the first thing they do is they paste from an external source. Well, MLTE supports multi-styles, so of course for whatever reason, their text is 72 point and it's purple and some

[Transcript missing]

Scrolling support.

So as I said before, MLTE can have its own scroll bars, and in most cases that's just fine for you. But there are some cases where you may want to have your own controls. They don't even have to be scroll bars. So we're going to supply away some hooks that allow you to control the scrolling and vice versa. When the client scrolls in the text field, we'll tell you and you can update your controls.

Okay, so let's go back to your text field. If you set some default text, maybe you want to set some default text in your text field. Well, of course, the first thing that happens is your client's going to do a Command-Z. I don't know why they would do that, but they will do that. And all your text goes away. And it's a little disconcerting because your customer isn't the one who put the text there. So we're going to allow you to clear the undo stack, and anything that happened up to that point can't be undone.

Oh yes, and we will be adding support for the mouse scroll wheel. Now as I said before, we'll go into more detail on each of these new features and show you exactly what you would need to do to take advantage of them. So what I'd like to do now is go to the next slide, please.

Go over some basic concepts in MLTE. Now I know that a lot of you in the audience are familiar with MLTE already and are probably well familiar with most of these concepts. But there are some who are new to MLTE and knowing these concepts will give you a better understanding of exactly what you'll need to do to interact with your text fields. So the first thing is that the TxInObject is an opaque data structure.

You won't be able to go inside and inspect it or change the information in it directly. But that's alright. We'll supply you a set of APIs that allow you to do anything that you want to do. And of course we've done this so that we can add those new features that you request without breaking your existing applications.

Alright, so there are two basic types of MLTE objects. There's a full window object and this, your text field will take up the entire window. And then there's also a pane object spelled P-A-N-E and it will only take up a portion of your window. And you specify which ones of these will be created when you create your text field.

Now there are two types of settings you can make on your objects. There's object controls, and these change the behavior of the entire object. And there are also type attributes, style attributes, and they'll change the appearance of particular ranges within your text field. And I'll go into a little more detail on this in just a second. As well as, Carmen events.

So, you may have learned yesterday how powerful Carbon events can be, and what we'll do is we'll install several of them, the Carbon event handlers, so that we can handle some of those basic operations that I mentioned before, like text editing and scrolling. We'll handle that automatically for you, and I will list a couple of those, well, which ones we install automatically for you. I'd like to start though with some examples of object controls. First of all, the API you want to use is TXinSetTXinObjectControls. Now this API was designed so that you can pass in multiple controls at the same time, so you're passing in an array of them.

The first example that I want to show you is you'll notice in the first paragraph two missing glyph symbols. "We've got two rectangles, and what that means is that the font chosen to display those glyphs, those characters, well, they can't. They don't have those particular glyphs. So if you turn font substitution on with a single tag here, What Atsui will do is when it detects that a missing glyph symbol will appear, instead of using the particular font, it will go and search your entire system for a font that can display it, and will use it instead. Now this is really great if you allow your customers to open documents and you have no idea what content is in the file. You don't have to worry about it. We'll have Atsui do all the work for you.

Now the second example is justification. I'm sure you're all aware what justification is, but we supply tags that allow you to change the justification for the entire document. So you have left, right, center justification, and full justification. Alright, so the final example here that I want to show you is Word Wrap.

By default, MLTE has Word Wrap turned on, so in regular document, in your text fields, we'll wrap the text for you. But if you're supplying a programming interface or something like that, you may not want that, so you can turn that off. So with single tags, you can get a lot of behavior. You can look in our header file to find some of the other controls.

So style attributes is the next thing. Some examples of these would be the font, the color, the size, the point size, things like that. The API you would use for this would be TXInsetTypeAttributes. Unlike the previous one, you pass in an array of these. Now, another thing that I want you to understand is that alongside of the data that we maintain, we also maintain an array of style runs.

What you see here is a sentence, all the text has one style, so we have one style run in our array. And it's associated with all the text. So if the client comes along, if your customer changes the style of some of the text, we will now have two style runs.

And the first here in this example will be associated with the first half of the sentence and the plain style basically gets shrunk down. And so on, they change the color, make some bold. So basically, all of the text in a particular style run has the same style.

And all the text in your document is associated with some style run. Now this is helpful if you supply a UI to your customers that allows them to change the style. We supply some APIs that allow you to count the number of styles within a particular run and get the style information from each of those so that you can maintain your UI, whether it be a menu or a floating palette, something like that. So that it will always be maintained and accurate up to date to the current selection.

All righty. So, finally here, Carbon Events. As I said before, we'll handle the text input for you automatically. We do so by installing Text Input Event Handlers. This way, you don't have to call TXN key down anymore. Same for mouse clicks. You don't have to call TXN click. And for the full window objects, we'll install window event handlers so that you don't have to worry about activating, deactivating, redrawing, things like that, resizing. We'll handle that for you automatically.

Okay, so the final thing I want to go over is the basic tasks of what you're going to want to do with your text objects. Working with TXN objects is what I'm going to start with. I'm going to have a slight detour and describe a couple of the things about our UniCode control because we do, as Xavier mentioned, wrap most of our features, MLTE features, into a really convenient control. And as Xavier already pointed out, we do offer a couple of static text APIs. And I'll describe when it is you use those as opposed to another one that's supplied in the OS.

Okay, so the first thing that you're going to want to do is to create your object. We've already seen this in the demo. It's Tx a new object, and you can see how powerful this API is just by the number of parameters you have. I'm not going to go through all the parameters, but I'm going to go through the first three for you. The first one is an FSSpec. When you're creating your object, you know that you have a file that you want to load in all the text. You can give us the FSSpec to that existing document, and it will load in the data for you automatically.

The second parameter is the window that you want your object to be displayed in. And the third one is the bounds for the object. So this is where you specify whether you want a full window object or you just want a pane object. If you pass a null, we'll assume you want the full window to be used. If you pass in a rectangle, then that's the bounds and local coordinates to the window that we'll use.

You may want to supply some default data to the object. Do you use TX and set data to do that? We also offer TX and get data encoded and that's how you get the data once the users put it in there. We've seen this next one, TX and set TX and object controls.

This is where you set the object-wide behavior settings, such as justification, font substitution. We've seen this one as well, TX and set type attributes. This is where you set the color and you pass in the particular range that you want the new attributes to be associated with to be applied to.

Saving an object is as simple as TX and save. And printing, we have TX and page setup and TX and print. Now you can see how convenient, how straightforward it is to use most of MLTE. If you want to save, you call TX and save. If you want to print, you call TX and print. It's really that simple.

All right, so the detour here. As we mentioned before, the UniCode control does inherit most of MLTE's features. And it's really convenient to switch. If you're already using the edit text control, you just change the creation, the creator API that you call. It's create, edit UniCode text control.

Now because it does conform to the control manager, you can get an event target ref for that. So if you have multiple text fields in an object, I'd recommend that you use this if you aren't already. If you want to override some of the default behaviors, installing your own Carbon events, it's much easier to install them on the individual controls as opposed to installing them all on the same window.

Now for Jaguar, we do plan on adding single line control tag. So all you have to do is tell us that you only want one line, and from that point on, no matter what the client does, there will only be one line in your control. And we'll go into a little more of that A little later on in the presentation. Exactly how you go about doing that. Alright, so some examples of where in our system we use the MLTE. Whether it's an MLTE object or a control. The Finder uses it in numerous places.

You'll probably notice it mostly when you're changing file names. So that's an MLTE object. The new search field in the toolbar, that's an MLTE object. The finder has a new find window that doesn't use Sherlock. Well, actually, Sherlock uses MLTE, too. So all the text fields in the Find window are MLTE objects. And you notice that we have some multilingual text going on there. Another example is keycaps. Keycaps is an MLTE object.

and I think actually they use some of our static text APIs for the keys. Nav Services. So when you're saving a file or opening a file up if you're typing in the path name, those are MLTE objects throughout the system. And finally, another example would be iTunes. iTunes uses it for their search field as well. They use it for when you're changing the, what is it, song names.

And the Get Info window that you can bring up, those are all MLTE objects. So as I said before, if you're already using the Edit Text Control, it's really simple to switch to these. That's what most of these clients did. The benefit is that you get multi-lingual support automatically and the nice quartz anti-aliasing to match the rest of the system.

Now for static text, HIToolbox does supply an API, DrawThemeTextBox. And in most cases, this is exactly what you want to use. It's theme-savvy, and that's what most of the system uses to draw its static text, and then use some things like that. There are some cases that Xavier mentioned that you may want more control. You want to pass in your own CG context or you want rotated text.

I recommend that you use one of our two APIs. One takes the UniCode, one takes the CFString. And if that isn't flexible enough for you, I'd recommend going directly to Etsui because they can draw text any way you can imagine, especially if you have your own CG context.

All right, so an example of that would be here. I don't know how pretty it is, but, yeah, that looks good. What you see here is we've passed in our own CG context, so the rotation here you can do by passing in parameters to the API directly, the static text API directly, but in this case we're using a CG context and applying matrices to them.

So each one of these is a separate call to one of our APIs, and you see some nice ligatures over there on the left. No, a swash, I guess. All right, so that's some basic tasks that you may want to do on your objects. What I'd like to do now is invite our senior engineer for MLTE up to the stage to go over some more advanced tasks that you may want to do on your objects. Thank you very much. Thank you.

This is Ford. Thanks, Rick. Hi, everybody. Okay, so we'll look at a few advanced tasks. They're called advanced, but they're really pretty easy to do. We're going to look at how you filter text input, a thing that a lot of people want to do and have asked questions about.

We're going to talk about letting MLTE handle your edit menu for you, so all you have to do is supply the edit menu and we'll update it and handle user selections. Passing your own CG context to MLTE, the reason you might want to do that is so you can manipulate the context and then when the text is drawn, that manipulation, whatever you did, will be We'll look at how you would set some of the advanced typographic features that we've seen and will see.

Okay, so filtering text input thanks to Carbon Events is really a simple, straightforward thing to do. You just write a Carbon Event handler for text input. You then install it on your window or your control. And then you sit there and you watch for the text you want to block or change or whatever your filter's doing.

There's one thing, of course, you have to remember is you install it after you install or create the MLTE object. If that makes sense. If you do it before, well then the MLTE Carbon Event handlers are going to be in front of yours and it won't get to your filter. And if you want MLTE to handle it, you just return the EventNotHandledAir. This is really standard Carbon Event stuff that's been covered in other sessions, but it's a nice example of the flexibility that Carbon Events provide.

So here's a Carbon event handler, easy to write. You've got your handler ref and your event, your user data. So in this simple thing here we call a filter. If the filter says it did something, we return no error, which means it won't go down to MLTE. And otherwise we return not handled error and MLTE will take care of things after that.

And here's where that filter's being installed. You can see that we're sitting on text input Unicodes for key events. That's the event you would get for input methods straight from a key--I mean, text input straight from the keyboard that hasn't gone through an input Okay, so you have an edit menu in your application. You like when an MLTE object is active for that MLTE object to handle the edit menu and update it.

Again, that's easy to do. And you'll see that you actually are going to be using the set objects control API that Rick talked about because we're going to be setting a global setting. And the one thing you do when you create your edit menu, you need to make sure it has command IDs. It happens automatically if you use a nib file and you need an XMNU resource if you use a resource file. But that's easy enough to do.

[Transcript missing]

So far, you've seen the two APIs that Rick talked about. We actually haven't seen the setTXN attributes yet. We will, but you've been able to take advantage, do some advanced things just by using that one function to set the global attributes. Okay, so custom drag behavior. Why would you want to do this in the first place? One obvious reason is to filter things. Maybe you only want numbers or something going into your field.

Another reason is we had to set up this way for the case where there's multiple MLTE objects in one window because you need to help MLTE by telling us that even though this drag is in the same window where it originated, it actually started in a different MLTE object. And why is that? Because each MLTE object is individual and doesn't have any knowledge of other MLTE objects that might be in the window. So you have to help us out there. And you'll see how you do that.

Okay, so how do you do this? You first of all tell us not to install custom drag handlers, which is just a matter of setting a parameter of an option bit when you create the object. Then you write drag and receive handlers, and then you install those handlers on the window.

So, tell us not to install is real easy. There's the option bit. Do not install drag prox mask and then create the object. Couldn't be very much simpler than that. You write your drag tracking handler. This is the standard. The drag manager thing you've probably done before. One thing to know that if you're overriding the drag and receive and you really only want to do the work in the receive handler, which would be what you'd do if you were filtering, you still need this function here because when you tell us not to install drag procs, we don't install any.

It's not a question of one or the other. So if you didn't really want to do any work here, it would just be a matter of calling that function you see there TXN_DRAG_TRACKER, which will let MLTE take over the drag and do the dragging. And that last parameter there, the boolean after the drag ref parameter, that's where you say whether the drag started in the window but actually began with a different object. True would be the case if you were trying to communicate that. In this case, we're just saying false.

And then in your receive handler, this example here is where we're filtering for numbers here. So you can see there's a little function called to see if the data is a number. If it is, we call TXN Drag Receiver to let the drag go through to let MLTE receive that text. If we want to stop the drag, we return no error and don't let it go through. Very simple to do. And then you just install it using standard drag manager calls you always used. Install jacking and install receive handler.

Okay, so advanced typography. You saw that you used TXN set type attributes to set this, the standard, bold, the font style, set size, all the text attributes that you're used to from QuickDraw that you commonly think of. Now, Atsui provides a whole host of different ones, more advanced ones, particularly in font features, which is something that's specific to each font. I mean, certain fonts have a huge host of features and variations, you know, ligatures and cross-stream shifting and swash variants and all that kind of stuff.

So you may want to offer that to your user. And we do let you pay for that. And you can tell us to take advantage of that if it's there. And you set it just like you would, and you do this work, you tell us to do that the same way you tell us to change run to bold, say.

So here's an example of two. The top one is a chemical equation looking line that was done with the stream shifting tags for that font. And then the bottom one is we've turned on some swash variants so you can see the R coming under. And that might be a double L ligature. I'm not sure from the font. And that was, so that's done like this.

So when you're doing this, you're going to need to talk to Atsui a little bit. You're going to need to ask us, or you're going to need to get the Atsui font ID, find out what the font is. You can ask us for that with a get type attributes call.

Once you get that information, you're going to ask Atsui, "Alright, what are the variations or what are the features that this font has?" If it has a feature or variation, you can grab the one you want to set. You tell us how many you're setting. In this case, just one. And the feature type and the feature selector.

So in that last example, you might have said with stream shifting and you want it on. And then in the attributes array, you give us a tag telling us what kind of data. It's the Atsui font features attribute. You tell us the size, which is the size of the structure up above, and then a pointer to that. And so once you've set that up, you can see, what you're doing here is just mostly setting things up. Then you call the TXN set type attributes. Again, exactly the same way if you wanted to tell us to make text bold.

So conceptually it's really easy to do. Okay, so we'll take a look now at some of the new things we did for Jaguar. One thing that we don't have a demo on but actually has been our main focus is we've been working on performance because we really sort of fell short in 10.0. We can improve more but we've made a lot of advances thanks mostly to Rick because he's really been tuning how we use Atsui and file opening, font changes. It's gotten a lot faster. So that's good news.

So Rick went over these. We'll go over them here. One thing he didn't touch on, we're going to make it possible so you can take any object, any run of data in a text area, and then attach a URL to it. This is separate from command-clicking on an actual URL. This is, say, take a word and then supply a different URL.

When you click on that, we're going to launch the helper for whatever the URL is. The other thing about that is we're going to -- if you use mail, you know that URL that hasn't been clicked on is, by standards, blue text that's underlined. That'll be the style attribute of a URL. This is the style attribute of a URL.

Okay. Okay. Okay. So we've got a set of, of a range that's been set to be a URL. While we're tracking a mouse that's on the URL, it'll be red with an underline. And a URL that has been pressed previously will be green text with an underline. But you'll be able to override those by using the set objects control function that we've seen a whole lot of times today.

We made it possible to -- for you to control scrolling, for you to handle whatever the control is, it lets the user scroll. Okay. And, and there's a -- and we make sure that that control reflects the position of the text when the user's typing or deleting text. We'll look at that.

You can create an object which is mono-styled. And in fact, all the UniCode, by default, the UniCode text controls are mono-styled. Clear the Undo and Redo StackRack. That was a good example that Rich mentioned that you have text you always want to show up. You don't want it to be undoable. And then we support the scroll wheel now.

So again, so here we are. We're looking at a lot of the same routines. If you want to set a URL, you use the text set, the set type attributes again. The URL, the actual data type is a CFURLRef. And you just set up the type attributes. You tell us, give us a tag identifying the kind of data. Give us the size and then give us the URL. And we'll attach it there.

Okay, using your own scroll bars, it's a little bit more to do, but really not that much. Just like always when you're scrolling, you need to write your action procs, and you need to create your controls, obviously. And then the new things for our support is you need to write what we call a scroll callback and you need to register that callback. So a scroll callback is there so, I mean, you have a control that you're managing. The MLTE object doesn't know anything about it. But the user's typing, the user's cutting text, pasting new text in.

And you obviously want to update that control to reflect the change in how much text is there. So when that's happening, we call your callback and pass you a value and an appropriate maximum. So let's look at some of this. So here's your track action proc. It's, you know, standard control manager thing.

Now the scroll routines here, so what you want to do is you look at the part code, you figure out how much you're going to scroll. The scroll routines let you scroll by units. The units can be pixels, lines, or the size of the view rack, which is basically similar to a scroll by page.

So in this case, in this example, the user mouse down on the button, on the down button, we say, so we want to scroll by lines and we want to scroll by one line. And we set all that up and then we call txn_scroll, pass it the object, the vertical units, the horizontal units, and then the delta, how much to scroll.

And then the scroll back callback here, like I said, you get a value, you get a max value, you figure out which control it is, and then you just update your control to reflect these new values. And then you register that, and there's a new routine to do that: TXN register scroll info proc. So the two new routines are TXN scroll and register scroll info proc. Okay, so you want to set a single style. It's extremely easy. You create your object and you just pass in an option when you create it and the option is mono-styled text.

[Transcript missing]

Okay, so here we have this window here. We have up here, this is a UniCode control. By You can hit return and it returns accepted in. But if you don't want that, You can just turn on the option with Set TXN Objects Control. It's a global option. You can set it just as single line support. And in that case, when you hit return, it substitutes a dash in.

The other thing you want to see is that, like I said, by default the controls are all mono-style now. Some exotic looking text here and we copy that and go to paste it up here. You see that it's in the style that we saw when I was typing so the zap or font style isn't honored here on that paste.

Okay, down here, this is a text area. It's not a control. It's created basically the way you saw Rick created in that demo by creating a new object. We specified a frame rack. And one thing to note about this is that these scroll bars are being managed by the application. MLTE doesn't know anything about it, about them. When I scroll here, we call the MLTE scrolling, calling the scroll call back to tell the application. And you can see the scroll bars being updated correctly there.

If I go over here, the application is calling TXN scroll to scroll the text. So scrolling is being handled by the application, but it looks just exactly like you'd expect. The other feature, real quick, just to show, we've got some URLs down here. And just to show that they work in any MLTE object.

I'll paste it up here in the control. If we command click on it, it brings us over here. Launches Internet Explorer and So that would be, you know, if you have MLTE in anywhere now, you can, the user can put in a URL and get to it. It's a feature that was in Waste, which we now offer. Okay, thanks a lot. And with that, I'm going to turn it back to Xavier to wrap it up. Thank you.

Excellent. All right. The important point here today is that actually, not only we have been doing a lot of progress from a performance point of view for each cases where people will be using MLT with, like, large text files, or some people have been reporting some primes on development list on the way they were using MLT and the performance they were getting. We've been doing a lot of progress on that side, and believe me, that took, you know, a lot of work and some kind of, you know, re-architecturing behind the back. So that's great, because I think you're gonna be very pleased with the version of MLT in Jaguar.

But then we made all these improvements and all these new features that you guys have been asking, and here you have the list. And for that, I mean, I'd like to really thank the MLT team who has been doing an awesome job this year on, like, you know, putting really the resources behind MLT and pushing it forward. The URL support is something that a lot of developers have been asking, and I think you're gonna be very pleased with the flexibility of implementation of this feature. And John gave, like, a great example on how you could be using it in your application.

The monostyle text, it's something that, once again, you guys have been asking for. Well, now you're gonna have it, and I think you do good use about it. We have clients that have been asking-- they wanted to manage their own scrolling for different purposes, because the way they do their scrolling and things like that. And now we have, I think, like, you know, a great set of APIs to help you achieve this.

Clearing their undo and redo stack, now you're gonna be able to manage that yourself in cases where, you know, you have certain type of text that you want to maintain in your text object. So you're gonna have full control, actually, on this. That's great. And once again, you know, things such as the mouse scroll wheel is something you're gonna get for free in the next version of MLT without you having to change anything.

The important point here as well is if you have feedback, don't hesitate. That's how we're going to make the technology better and that's how both you developers and your application and our technology is going to get better. We get a lot of feedback from the finder and of course the system and they are using MLTE very heavily. But developers in most cases have different needs so you need to let us know and believe me, you can see here that with the work we've been doing this year, we'll implement as many features as we can for you guys.

A couple of documentation you may be interested in. Handling Unicode text with MLTE and I think all this documentation are available right now on the website and you have the URL right there at the bottom. I think we'll have a new reference for the Multilingual Text Engine soon and Bernie, our tech pub's representative, can talk a little bit about that during the Q&A.

And we have some documentation as well as setting up MLTE to use Carbon events. I think you looked at the example and it was pretty straightforward. I'm not sure we have sample code but the documentation is pretty clear if you need to do your own management for it.

Documentation is great, but I think the best for developers is sample code. We have the Techno 2026, which actually explains how to set up the Multilingual Text Engine and most of the things you may want to do with MLTE. Something that is not written here but very important to understand is that on the Carbon Lib SDK there is a lot of documentation and a lot of sample code for MLTE. We have sample code to help you migrate from a TextEdit implementation to MLTE, for instance. We have an application that implements custom controls using MLTE, which is very powerful.

We have something that is a replacement for Simple Text, I think. The name of the application is called Simpler Text. Don't ask me. And waiting for the new features to be documented or new sample code to be posted on the website, I encourage you actually to check the header file. And once again, the header file for MLTE, the Multilingual Text Engine, is called MacText. And you find it in the HIToolbox framework.

A couple of sessions that have been going on this week, and you may want to check your DVDs, actually, for this. Session 201 of the Font Manager, where actually we talked about the new Font Panel. The cool thing with the Font Panel for you as a developer is that you're going to be able to integrate it pretty easily with MLTE in the way that the Font Panel is going to send you back notification with an @Suite Font ID. And what you'll be able to do is just take this Font ID and pass it actually to MLTE using the txtnset type attributes that we've been talking about. So it's pretty straightforward.

If MLTE is not enough for you and you need to refine control or you're writing the next text engine for your company or for such great application, I'd encourage you to check the session 202, where actually we talked about @Suite and how you can use it. @Suite, which is Apple-type services for UniCode Imaging, as I talked about, it's the UniCode technology, the UniCode layout engine that MLTE uses internally.

Session 206 was yesterday, was about the new control and services. You saw here we talked a little bit about the UniCode control that you can have in the toolbox. I think you'd be pleased if you want, if you have very basic needs. It's a nice way to actually have an MLTE object without having to worry about how to pass text and things like that. So if you like application is architecture around controls, that would be probably a good way to achieve this.

And please remember that should you have any feedback on these sessions and any other international technologies we've been talking this week, please come to the International Technology Feedback Forum, which actually is this afternoon at 5:00 in room J1, which is completely on the other side. We'll be more than happy to talk to you about anything you want to talk about.

Should you have any questions, announcement requests, bug reports? Two ways. The first thing that is very important for you guys to understand, if you have a prime, a bug, something that is stopping you from shipping your application, you need to file a bug in bugreporter.apple.com. You're all ADC members.

If the bug is not in our database, it's very difficult for us to track down. So remember, step one, file a bug. And then, of course, you can always send me an email at [email protected], and I'd be more than happy to help you with any suggestions and announcement requests or primes you may have with our technologies.