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-201
$eventId
ID of event: wwdc2002
$eventContentId
ID of session without event part: 201
$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 201

Font Manager

Carbon • 57:22

The Font Manager for Mac OS X makes it easy to support an extensive range of font technologies and data formats. This session is essential for developers of advanced applications who need to manage fonts and/or directly access font data. Learn about the font formats supported in Mac OS X, how to create and manage a font menu, how to get the font panel into a Carbon application, and much more.

Speakers: Mike Conley, Nathan Taylor

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 the session on the Font Manager in Mac OS X. It has been a great year for us. We've been doing a lot of improvements on the supported fonts, the different types. If you went to, actually yesterday, to the keynote, you heard that now the font panel is available for Carbon applications.

The group that has been working on that is actually the Font Manager group, and we'll have them today, so this should be a pretty interesting session. Quickly, I'll go through the agenda. We'll have a quick overview of what the Font Manager is on Mac OS X and what have been the changes compared with Mac OS 9.

We'll go through what I think is probably the most important for you developers. We'll go through a list of features and enhancements that the team has been working on for Mac OS codename Jaguar. We'll have some demonstration about these new features. And, of course, we'll go into the details of programming APIs on how you're going to be able to access the font panel, for instance, and all these new features and the new font that we're supporting now on Mac OS X. To talk about this overview and build this presentation, I'd like to introduce Mike Conley, who is a senior software engineer in the Type group. And Mike will be actually guiding you through all these features that you're going to be discovering. Thank you.

So I'm going to guide you through the exciting and never-ending fun world of the Font Manager. As Xavier pointed out, I'm going to do a quick overview. I'm going to try to make it as quick and painless as possible. For those of you who have already seen all this material, you can probably just close your eyes and get some rest, and the rest of you can pay attention. We'll wake the other folks up when we're all done with the overview.

This is the diagram that describes the interaction between applications and Mac OS X font services. You'll notice that various applications communicate with the Application Services Framework. The Application Services Framework contains, among other things, the QuickDraw subframework, which exports the APIs for Atsui, and QuickDraw text services, which are used primarily by Carbon applications and .

I just lost my mic. HTML rendering. It also exports the Quartz API. I keep losing my mic. But that's all right. I'll just talk. Quartz API, which is part of Core Graphics, and it's used by Cocoa applications. All these subframeworks communicate with the ATS client framework, which handles all the ATS APIs and SPIs used by the system.

And the ATS client framework talks directly to the ATS server, which is a separate process that's responsible for maintaining the font database for the entire system. And it also handles such things as activating and deactivating your fonts and supplying glyph outline data and table information, name table information, that sort of thing.

Font formats supported in OS X are all the ones you're used to by now: Macintosh TrueType, PostScript, Windows TrueType, OpenType fonts of various types. For Jaguar, and those of you who are sleeping can keep on sleeping because we'll go back over these in more detail later, we plan to add PostScript Multiple Master Support, some enhancements to our TrueType support, and protected CID font support.

I'm sure by now you're all pretty used to the user font locations. These are the various font folders which the system knows about. We refer to these as domains, user local network system, and classic font domains. These are the standard locations where ATS Server will automatically activate and deactivate fonts for you as necessary.

If you want to have fonts installed on your system that only the currently logged in user has access to, you should put them in the User Domain, the User Fonts folder. If you have fonts you want to have all the users on a given system have access to, they should go into the Local Domain, the Local Fonts folder.

The System Fonts folder, the system domain is designed specifically for fonts that are used by the system, and you really shouldn't be putting anything in there. We would really prefer it if you didn't. Classic Font Domain is for cases where you have a large number of users who have access to a common file server and a large number of fonts you want to share with all those users. You can install them on a network server, which comes up on a mount point on everybody's system. They all will have access to the same set of fonts, and it makes administration and control of those files a whole lot simpler.

Of course, then there's the Classic Fonts folder, which is in the currently active system folder for Classic on your system, and it will change depending on which Classic system you decide to select. Note that Classic apps, of course, only have access to those fonts. They don't get access to the other ones.

When you're activating fonts, you can do it programmatically from anywhere in the system. You don't have to depend on the standard font domains. If your application needs to activate a font, you can put the fonts in any folder that you know about. You can put it in your application bundle.

You can stick it in your application resource fork and activate it programmatically from there, if you like. Note that unlike OS 9, of course, application resource fork fonts don't get activated automatically when you open up the file. You have to actually to make a call to do that.

For Jaguar, we plan to add a new feature called Auto Activation, and I'll be talking about that a little bit later. After we've woken everybody up. Installing fonts. Installing fonts, everybody's used to how to do that. You drag and drop them into the standard font directories. On application launch or at user login, ATS Server will automatically scan those directories and activate the fonts or deactivate ones that have been removed. We do resolution of duplicate fonts across domains. If you have two of the same font, we will handle the resolution between those two and select one preferentially over the other.

Font ID conflicts will be handled by synthesizing font IDs, which is why, as we'll mention later on, it's a bad idea to use font IDs to track fonts in your documents because they're not unique across boots. For Jaguar, we plan to add a couple of new features: handling nested font subdirectories, and font notification API, which will be discussed in more detail in a minute.

Most of you are familiar with the API for the standard Carbon font menu. It gives you an easy and uniform way of putting up a font menu for all your Carbon applications. For Jaguar, we plan to add an API to support the font panel that you've seen in Cocoa apps, which will allow you to have a uniform font selection across both Carbon and Cocoa applications, and we'll talk about that in a bit.

Okay, time to wake up. So, all you guys were sleeping. These are the new features that we're planning on adding for Jaguar, and we'll go through them one by one and discuss them in a little more detail. So the overview wasn't too bad, was it? Nice and painless.

Postscript Multiple Master Fonts. We plan to support Postscript Type 1 Multiple Master Fonts. They will show up as typefaces, separate typefaces of a given type family in applications, in font menus and in the font panel. You'll be able to select the instances, the intrinsic instances as a typeface or a style. If you have a document that has a Multiple Master Font in it or uses one that is not, even if it is not an intrinsic instance of that Multiple Master Font, it will be rendered correctly.

We've heard from our users that some of them miss some of the features that they used to get with their Quick Draw based apps from ATM, such as the metrics and kerning from the font. They would like to have those on 10, and they're going to get them under Jaguar. We'll be synthesizing data for the font, kerning and metrics information, identical to what used to be available in ATM.

You will have to make virtually no change to your code in order to get this. The only change is the API to actually load the font data, which is very minor, and we'll be talking about that when we talk about the APIs. Now you won't have to worry or wish that you had ATM on 10 because you won't need it. It will all be there for you.

Copy-protected CID fonts are extremely important to our Asian business and design markets, and we are going to be supporting them in JAGUAR, or we plan to. If you happen to have a copy-protected CID font installed in your classic fonts folder, we will activate it, and we will respect all the copy protection requirements. The protocols that are intrinsic to that font, things like resolution restriction, selective PDF embedding, selective outline extraction, all that sort of thing, will all work. We've tested these fairly extensively with our Japanese desktop publishing applications, and they work great. You'll have that, with any luck.

uh... nested font subdirectories so no longer do you have to tear apart your carefully constructed font folder hierarchies in order to install a font on OS X you'll be able to simply drag the folder to a standard font folder and ATS Server will scan it automatically as part of the standard process you can now drop the entire Adobe FontFolio CD into a font folder and it will be activated automatically for you.

Font Notification We plan to be able to give clients the ability to register for notification when we activate and deactivate fonts. This will allow you to update your HI as necessary. You'll be able to do things like update your font menu, update the font panel, which of course you'll be supporting, and any other things you need to do as part of your user interface. You will require a CF RunLoop-based application, but of course since Carbon and Cocoa apps are by default CF RunLoop-based, you don't have this problem unless you're writing a tool or some kind of other application that doesn't have a UI, like a server of some sort.

Normally applications would receive these notifications when they're in the foreground. If you suspend the app into the background, the notification will be delivered once the app comes into the foreground. If you've got a tool or a server that doesn't have a GUI associated with it, you can ask to get the notification immediately so you won't have to wait, obviously.

Clients will be able to register for auto-activation notification. For instance, if you've got a document and it's got a font in it that's not installed on the system, ATS will, if clients have registered for auto-activation, start scanning its list of registered clients and ask them to activate the font.

So if you have a third-party font management software, you now have a hook that will tell you when it's time to go and activate a particular font. You won't have to activate them ahead of time. You can do it on request from ATS. The registered client will then go ahead and activate the font, pass the data back to ATS, and ATS then supplies it to the client as requested.

The client is none the wiser and thinks it all came from the system just normally. So that's... Font Panel for Carbon. As you heard from Xavier and from other people during the conference, we will be supporting the Font Panel for Carbon. We will have an API that will allow Carbon applications to access the Font Panel, to be able to send font selection information to the Font Panel, and receive font selection information from the Font Panel.

The font data reception is Carbon event-based, but even if you have a Wait Next Event app, which of course none of you do because you've all adopted the Carbon event model, but if you did, you would be able to do this because Wait Next Event, of course, handles Carbon events just fine. You just have to write a little Carbon event handler, and it's really not too difficult.

So this diagram here is a schematic of the interaction between the various components that I've talked about with the ATS software. Finder will notify ATS Server when changes are made to the standard font domains, and ATS Server can then tell registered clients that fonts have been activated or deactivated.

Likewise, clients can register for auto-activation as part of the auto-activation queue, and when fonts are requested that can't be supplied by the standard installed fonts, ATS will query registered third-party font manager clients and obtain font activation from them. The font panel is implemented actually as part of the common panels framework, so you would link against that, but it will communicate with ATS in order to obtain font information, and it will pass font selection information by Carbon event back to the client applications.

While we were at it, we took some steps to improve stability of the system as a whole. One of the major problems that we run into occasionally is that while interpreting data from font files that may have gotten corrupted, you may walk off into the weeds and generate address exceptions. We've improved the exception handling for this on ATS Server and in the scalers so that we're able to catch these exceptions more reliably. We also have a facility internally to disable suspect font files if we think they might be corrupt.

We can notify the user when that's happened so he can then remove them if he wants to. We've also made the API thread safe. We've added some better error checking throughout the system. Even of course, though there weren't many bugs there to start with, we have gone and fixed bugs. All this has led to improved stability of the system.

Also, we've enhanced performance. We've improved font streaming for such activities as PDF embedding, downloading fonts to printers. Log in and log out has been sped up by caching more information to disk. It still takes a while to activate those 10,000 fonts that you just installed, but after the first time, it's a lot faster. TrueType Font Scaler has been sped up.

We do a little more caching throughout the system so that we return data to you faster. We also allocate memory more efficiently, so we're not constantly deallocating and allocating memory all the time. All of this makes ATS faster, which makes for the faster applications. That, of course, makes for happier users, and that is a good thing.

What I'd like to do now is introduce our demonstration. We're going to demo some of the features that I just talked about, notably the font panel, the notification API, and the auto-activation system. To do those demos for you will be Nathan Taylor, one of our software engineers. Thanks.

Thank you for the introduction, Mike. I'm going to be showing you a demo of some of our planned features for Jaguar. I've implemented these into some of the apps you may recognize, actually one in particular. So let me switch over and show you what we've got. First off, I wanted to show you the Nested Font.

[Transcript missing]

I'm going to bring up TextEdit with a document that uses these fonts. As you can see, we now have the fonts that were in that folder activated, and they are present in the font panel so you can use them.

As you can see, I have a Cocoa application here, TextEdit. It comes with a font panel by default. We'd like you to add font panels to your Carbon applications, and it's a feature we have planned for Jaguar. So let me bring up a version of Simple Text with a font panel and give you something to Okay, so I've reduced, as you can see, the menu bar of simple text is greatly reduced. There is only now a font menu, no style, and no size menus. If I bring down the font panel, everything that you expect to be there is here.

I can change a selection of text, and To a particular font, face, and size, and everything is supported. Contrast this with an older version of simple text. Where we have a long font menu, slightly difficult to navigate, especially with multiple master fonts involved and multiple UIs, the UI is now more consistent with the font panel between Cocoa applications and Carbon applications.

What happens now if I remove those fonts I just put in there and want to view that document again? I think you're all familiar with this. Your users may have complained about it. I If we try to open a document without the fonts present, it's going to take a little while as it looks for the fonts, ask the ATS server where they are, and you get nothing. I mean, everything here is rendered in Helvetica. Things don't look as they should. It's pretty ugly. With the new auto-activation feature, and let me actually set something up for another bit of this demo.

A simple font server. This font server knows about a folder of fonts, the ones I want. If I start it up, it's going to scan the directory, make a little database. Now I can bring up simple text or text edit and try to open that document again. You see the red text scrolling. The font server processes the requests and we get the fonts we expect to see. Everything's there. But look what simple text did in the background.

I've set the simple text up to receive notifications. It got a notification for each activation. As I have it set up, unfortunately there's a few of them, the font menu was updated on receipt of the notification. Now Adobe Garamond Pro is available and I can select it and change text.

What's also nice is doing this, the document refreshed, and where I have family, style, and size, those also got refreshed and pulled up the fonts that they needed. That concludes the brief demo of planned Jaguar features. We hope you'd like to implement the Font Panel in your Carbon applications, and we hope some of the font utilities out there will take advantage of the auto-activation feature we have planned.

I get the distinct pleasure of talking to you about the programming interface. I'll be talking to you for about the next 40 minutes about the programming interface, and I've got to warn you, there is going to be some code, so bear with me, pay attention, take notes, it'll help you down the road.

The first couple things I'm going to talk about are the API sets. There are two basic API sets on Mac OS X, and I will go over those with a little bit of detail. Next, common programming tasks that we've received questions about and that you need to do to make your apps work with fonts better. Finally, performance issues and ways to get around them and diagnose them.

Let's see if I have the API sets. The first API set you may have been familiar with when migrating from Mac OS 9 to Mac OS X is the Font Manager API. This is available on Mac OS 9. It's also in CarbonLib, and it's available on Mac OS X. This includes all the APIs that are prefixed with the FM insignia, I guess. An example is this FM Create Font Family Iterator.

For Mac OS X only, we have the ATS set of APIs. Again, these are all prefixed with ATS, an example of which is ATS Font Iterator Create. If you are writing an application that is designed for Mac OS X and you want some new functionality, you may want to consider looking at the ATS APIs.

When working with fonts and font families, there are several types of references you're going to need to work with. Font references include the ATS Font Ref, FM Font, and ATSU Font ID. Family references include the ATS Font Family Ref and FM Font Family, which you are probably familiar with if you use Quick Draw.

One thing to keep in note is that these references cannot be different. An exception to this is that the FM font and ATSU font ID are essentially the same thing. It's important, because they are different, that you use provided conversion APIs to convert from an FM font to an ATS font ref if you'd like to use it within an ATS API.

Here's a list of some of the more common programming tasks, and some of which we have received the most questions about. The first two most common tasks that you will need to perform, especially if you want to activate a font for your UI, is activation and enumeration. You'll need to enumerate the fonts to build font lists, font menus of your own, or just to get an idea of the fonts that are on the system. When saving a document that your user has created, you need to worry about storing font references and doing it in a persistent way.

Next, when migrating from Quick Draw to the new APIs or from Mac OS 9 to Mac OS X, conversion and compatibility functions are important to consider. Finally, we have a list of some of the new features we have planned for Jaguar. This includes notification, and I'll go into detail on how to implement notification in your application. We have the font panel and font menu. The menu is not entirely new, but we'd like to reinforce on how to use it. And we have auto activation, which font utilities can use to provide fonts on queries if they are not available in the current database.

The first task I'd like to cover is activation. If your application needs a special font for its UI, you're going to want to activate that font. Or if you have a font utility, you're going to need to activate fonts that the user requests. To activate fonts, there are three basic APIs: ATS Font Activate from File Specification, ATS Font Activate from Memory and FM Activate Fonts The File Specification API and FM API both take a file spec to activate a font and are our preferred APIs for you to use when you need to do this. The ATS Font Activate from Memory API is provided as a mechanism to activate raw TrueType data. We don't recommend that you use this unless you absolutely need to.

The ATS Font Activate from File Specification API handles a lot of the stuff in the background and will activate the complete set of fonts that we support and is easier to use in that way. Finally, when you're done with a font and you don't need it anymore, you want to deactivate the fonts. I'm not going to go into too much detail here because it's really quite simple.

Here's a close-up of the activation API if you haven't taken a look at the header documentation Some of the key areas of interest in this API are the context parameter and the option parameter. When using the context parameter, you have two options you can use, or actually three.

There is local, global, and unspecified. Unspecified is actually equivalent to local. This defines the accessibility of the fonts that you are activating and restricts the access to these fonts to a specific set of applications. Globally activated fonts will be available to all applications and local to your own client.

The Options field is necessary to support Resource Fork or Data Fork. You can specify that in this field. This is important if you want to activate a font that you may have stored in the Resource Fork of your application via the old method. Specify the file spec to your application, Resource Fork, that will do it for you.

One of the quick ways, now that we have the The first step in hierarchical folder activation is you can activate a font or all the fonts stored in your application bundle by just specifying the main bundle as the file spec using the options field to specify the process subdirectories and if you want them local, use a local context.

That will activate all the fonts inside of your bundle. Here's a quick example of how to use these APIs. Here I'm activating a font in a local context with default options. This is what I would need to do if I just want this font for use within my application. When I'm done with it, I deactivate it.

When you want to build a font list, you need to get an idea of all the fonts on the system. To do this, you want to enumerate them. We have several APIs to enumerate the different types of font structures. We have font family iterators, font iterators, and family instance iterators.

An example of a font family is Helvetica by itself. This is the group of faces that comprise Helvetica. To iterate through these fonts, you can use either the family iterators, the ATS or FM family iterators. If you would like to iterate through the fonts, such as Helvetica Bold or Helvetica Oblique, you can use the font iterators provided in both ATS and Font Manager.

Finally, for those of you that are familiar with walking the font association table in the font resource, we have an FM Create Font Family Instance Iterator. This instance iterator allows you to walk through the specific instances that you would normally find in the font association table, such as Helvetica, Bold, 12Point. All you need to do in this case is use the API and you don't actually need to get the font.

Okay, did I go too far? Alright, sorry about that. This is a close up of font enumeration. We have the Font Iterator Creator for ATS, and the key parameters that I'd like to point out to you here are the context, the filter, and the options. Similar to activation, the context is used to specify the accessibility of the fonts you want to look at.

It's different in the sense that you are using it in conjunction with an option bit to restrict or unrestrict the accessibility that you want. The option bits have a synergy with the context, and you can restrict or unrestrict it. As you briefly saw as I flew by, there is a chart that I will show you next that outlines how these work together.

First, I'd like to just mention the filter here. It's an important aspect. You can create a custom filter, and if you need to pass in information, you can pass it in through the RefCon. The filter is designed to allow you to filter out or reduce the fonts that you get returned from your iteration to within a set of parameters that you define.

Here is the chart outlining the interactions between contexts and scopes. We've received a few questions about how these work. We've implemented some changes with 10.1 that made it make more sense and allow you to access things more consistently. Let me walk you through this. If you want to use a local context and a restricted scope in your iteration, this will get you all the fonts that are activated locally to your application and none others. If you specify a global context and a restricted scope, this will get you all the fonts that were activated globally in the system, including fonts in the font directories, but not fonts that were activated locally by your application or any others.

Similarly, using an unrestricted scope with a local context gets you the default sets of fonts. These are the fonts that we want your application to see. It's the global activations as well as your own local fonts. You can also get to this by using default parameters as opposed to specifying local or unrestricted.

This is the equivalent. Finally, there is the Global Context. This is of interest to developers of font utilities that want to know all the fonts that are in the system and be able to go through them and discern which they are. Specifying Global Context and Unrestricted Scope gets you this.

Here's a quick example of enumeration. I actually skipped to this a little too quickly before, but as you see, it's pretty easy to set up an iterator. Here I'm creating one with a local context and an unrestricted scope. I'm going to pass this iterator that I get back into ATS Font Iterator next and continue iterating until I get a status code back. Here's where things get a little interesting. The status code tells you something about your iteration. Let me show you those.

First status code, and the one you want to see most often, is that the iteration has completed. When you get this code, it means everything went through successfully, you're done, you don't need to worry about anything, go home and have a nice day. If you get the Iteration Scope Modified error or status code, it's there to tell you that something has changed. Someone behind your back went in and activated a font, deactivated a font to cause a database change. This iterator is there to tell you that your iteration was not complete. You should reset the iterator using the Reset API and try again.

Well, here's something interesting. This is one of those features we have planned for Jaguar, notification support. In order to provide notification support to you, you first need to create a callback. This callback is meant to handle the notification and do something when you get it. The most common thing is to update your UI, such as updating the font menu. To subscribe to notifications, you need to call the API and register the callback.

When something happens to the database, a font has been activated or dropped into one of the font folders, your application, if it's in the foreground, will receive a notification. There is also an API of interest here to installer developers. Installers often had a problem of installing fonts into a font folder manually or programmatically, and other applications not seeing these fonts.

Well now, installers can notify ATS Server that they've done this. And ATS Server can then rescan the directories and then provide notifications to all the clients that are available. Lastly, if you're tired of receiving notifications, your app is finished, or you just don't want to get them anymore, unsubscribe and your application will stop getting notifications.

Here's a brief example of a simple notification callback. Notice that the callback has two parameters, an info ref and a refcon. The InfoRef currently is unused but is available for future expansion. We intend to be able to provide notifications down the road for other tasks happening behind your back besides just activation. But what we currently have planned for Jaguar is notifications for activation. Here's an example of what to do. I'm updating my standard font menu so that when the next time the user looks at the fonts he has available, he'll get what he needs.

The ATS Font Notification API is, well, the subscribe API I have here is what you will use to register your callback. You pass in your callback. Here I'm using default options. I don't need to pass any information through, and I'm going to get a notification ref back. This option flag that I have here could be substituted by an immediate notification option flag that Mike described earlier, whereby a faceless font server can receive notifications immediately, instead of having to wait until their application is brought into the foreground, which might not ever happen. Finally, when you're done, unsubscribing is a piece of cake. They pass in the notification ref you got back, and you'll no longer be told when things happen.

One of the complex problems that developers need to solve is how do I store fonts in my document so that when a user opens the document, they get the correct font displayed and everything looks appropriate. We have a few recommendations for you and a few things we recommend that you not do. First, the good stuff.

We recommend storing the font family name and style bits. This is much like what Apple Works currently does, and it's been working for them, and it's something we've recommended that you do in the past. AppKit applications store the PostScript name. This is also another fairly unique way to determine fonts, and it's another method that we would recommend. You also have options of using a full name, or a full name in combination with a manufacturer name, or some other combination of names available within the font.

You might need to develop your own heuristics because all fonts don't have the same data, and not all data is as reliable as the next. A couple of bad things to do that Mike hit on earlier. Don't store IDs. It's simple. They are not guaranteed across reboots. We do font family synthesis behind the scene so that a font family ID may not be consistent once another font has been activated or the system has been restarted. The same holds for font IDs.

When bringing your application up to Mac OS X for Mac OS 9, you're going to need to worry about conversion. For Quick Draw developers, you're used to working with font families and style bits and whatnot. Well, with some of the APIs that you will want to use on Mac OS X, you'll need to get a font from this. We have a couple APIs to do that.

You can get a font from a font family instance with the FM_Git_Font_Family instance from font, actually the other one, and given its family and the style, you'll get a font back. To go the other way, from a font to a family instance, you can use the API I just mentioned earlier, and it will give you the family and the style from the font.

One thing to keep in note here is that this conversion is not necessarily one-to-one. A font may represent a different style within different families. For example, a Helvetica Bold/Oblique font could be the oblique style in a Helvetica Bold family, as well as the Bold/Oblique style within the Helvetica family. This is often the case with family synthesis for OTF fonts.

Another major task to worry about is compatibility. How do I take the things I've been working with with Quickdraw, with Mac OS 9, with CarbonLib, and bring them over so that they work seamlessly with Mac OS X? For example, I'm used to getting the font resource and pulling out of the font resource kerning information. Well, as Mike mentioned, we now synthesize font resources for OpenType fonts.

This is the API, or two APIs, HTS Font, Git Font Family Resource, and FM Git Font Family Resource. These APIs will provide to you the font resource, if available, or synthesized, which you can then use with your normal methods that you have before from Quickdraw to apply kerning to pairs or to get the metrics.

Another API if you need to know about font files to worry about are the ATS FontKit file specification and FM Git container from Font Family Instance. If you are used to actually delving into the font data yourself and there's information in there that we don't provide an accessor to, you're going to want to use these APIs to get the font file spec and look at the font yourself.

One thing to keep in note that the different APIs have slightly different behavior. ATS font get file specification will provide you the file spec to the file containing the outline data. What that means in the case of PostScript fonts with auxiliary LWFN files is that you will get the file spec for the LWFN file, not the file spec for the suitcase containing the bitmaps.

FM container from Font Family Instance, on the other hand, is designed to return you the container that holds the font resource. Now, if a font doesn't have a native font resource, you will get back an error. But the goal of this is to provide you access to the font with the font resource.

Finally, the last two APIs are of interest to those of you coming up from Quick Draw into some of the new API sets on Mac OS X, such as Atsui or Cocoa, etc. If you have been storing in your documents and you want to provide backwards compatibility, for example, to old documents that have Quick Draw names or font family names in them and use the ATS API set, we have a mechanism to get the Quick Draw name for storage and also to find a font family from the Quick Draw name.

This is the big feature that we have planned for Jaguar and the one that we're most excited about. We would really like you to implement the font panel inside of your Carbon applications. As I showed you in the demo, it can simplify your menu bar, it can simplify your user interface, and it provides a consistent user interface for font selection between Cocoa frameworks and Carbon frameworks.

There are several things you need to worry about doing when you want to implement the font panel. The first one is to toggle the font panel state to show it when the user wants it and hide it when they're done with it. You may also have a need to query the font panel state, but this API is not used quite as often as showing it or updating the display, which is the next, probably most important thing you need to worry about to provide a consistent UI.

When a user changes their selection in their document or moves the cursor around into a different style run, you want to update the display of the font panel and let it know which styles to provide. There's an API to do that. I will go into that in a little bit of detail. The other important thing about this particular API is that it tells the font panel which window target to send the Carbon events for the selection to.

So that leads me into the next topic, is how do you get the selection? Well, we've defined a Carbon event suite that you can implement a handler for that will tell you when a font has been selected from the font panel, and you can pull out the information from it. Let me just quickly show you, in the worst case, the most work you would have to do to implement the font panel.

To implement the planned font panel with the WaitNext event application, you would need to build a Carbon event handler. To handle the command classes for the application and then be able to handle the command parameter to show and hide the font panel. When you get this, you call the API FP, show hide font panel. There is no parameter list. It's really simple. Just call it and you'll get the font panel.

When the font panel and the user have made a selection, your application and your window will receive a Carbon event. This event will be of type of class font, and there are two types you may get. One, that the font panel has closed, or more importantly, that you've gotten an event for a font selection. Once you get this font selection, then you're going to need to want to pull out of the event some parameters. If you have an ATSUI-based application, you'll be interested in pulling out the ATSU font ID and ATSU font size.

If you're still working with a Quickdraw-based application, or you just want to get the font family, you can pull out the FM font family, font style, and size. Finally, because the font panel provides support for coloring fonts, there is a parameter to pull out the color information, which you can then apply to your text if you desire.

So first off, here's an example, when I receive a Carbon event, of how I would pull out the font family. You can see it's really quite simple. I determine the event kind, I then get the parameter out of the event once I determine that it's actually a selection. I ask for the font family, I get it back, and then the last thing I need to do is apply it to the user selection.

Say a user is mousing around through the document, selecting different style runs. You want the font panel to represent the current selected style run. To do this, you need to tell it that it has changed, and then the font panel will automatically update its UI. So the first thing to do is to build, in this case, I'm using a QuickDraw info structure that includes the instance, the font family and style, as well as the size, and then I send that to the font panel with the window target reference. As I mentioned a couple slides ago, this window target reference is important.

This tells the font panel which window that it should send its next selection event to. If you pass null through here, your selection events are going to go into the great beyond, into the void, and you'll never get them. If you don't pass the correct window target here, then you're going to get some interesting behavior as other windows that the user didn't mean to update get updated.

The old way of handling font selection in Carbon applications was the font menu. This is pretty convenient. It's a simple list of fonts. It works fairly well, but with the number of fonts we support in Mac OS X, it can get extremely long and extremely cumbersome. But if you continue and you want to use it, we have some APIs that we recommend that you Create the menu, update the menu, and determine a selection. It's important to keep in mind that although we are recommending that you use the font panel that we planned for Jaguar, you may still find a good use for this font menu.

The first thing you need to do in making the font menu is create the standard font menu for the appropriate menu handle. Here I'm giving you an example of how to create the hierarchical menu. This will provide a menu containing families and hierarchical menus of the various instances available for them.

When my app receives a notification event, or a notification when my callback is hit, I want to update the font menu. ATS is telling me that something has changed in the database, and I want the user to know this. If you're not subscribing for notifications, we also recommend that you call update standard font menu either when your application is brought to the foreground or when the user clicks on the font menu. But here I'm showing you how to update the standard font menu for a hierarchical menu. And then to get the selection, when the user has selected a font, you can pull out the family and the style information with Get Font Family from Menu Selection.

Here's the big feature that we have received a lot of requests for from utility developers that we plan to get into Jaguar, which I noticed during the demo, got a few oohs and aahs as the red text scrolled by and the document appeared with the fonts that it needed. Auto activation. There's a hook in ATS to support auto activation that you will receive queries to your server and utility when a client application requests a font that does not exist in the the database.

The type of message ID you will get is the KATS Query Activate Font Message. This is The message I did to let you know that somebody wants a font and they want you to activate them. To register for queries, you'll want to register a callback with ATS Create font query and run loop source.

And then the source you get back from this should be applied to the CF run loop. Again, all Carbon applications with a UI have a CF run loop, so there's nothing extra you really need to do. But if you were doing a faceless server, like the one I had, you need to make sure that your application does have a CF run loop.

Here's an outline of the communications that occur when a font query request comes through. The application here has requested a font by its postscript name, family name, any sort of name that we can allow a font query on. The query goes through to the ATS client library, which knows about the port that the font utility has subscribed.

This port was sent to the ATS server, which passed it on to the clients as they were launched. So the communication in this case goes directly from the client to the font utility to query for a font. The font utility then does its work, parses its database, translates the query into a file specification, and uses the ATS client to activate the font, which triggers a message to the ATS server and tells it to activate the font, which then goes out to all clients on the system. And, as I showed you in the demo, this will also trigger notifications.

Creating a callback for auto activation support is a little bit more difficult than a callback for notification because there's more work that you need to do inside of it, but it's not that hard. The callback takes in a message ID, the data reference, and a RefCon. The message ID that you care about at this point in time would be the KATS Font Request Query Message ID, at which point when you receive it, you take the data that is received, you parse the data, which I will show you an example of later, and then you translate that into the font file that you need to open.

So registering the callback is as simple as calling one API with it. As I mentioned, it's the ATS Create Font Query and Run Loop Source API. You pass in your callback. The first two parameters there are to indicate a--one of them is there to indicate a precedence for your callback query. Zero is default, but you can put your query handler at a higher precedence order so that it will get handled first.

Now we can see precedence wars occurring, and hopefully they won't, but we recommend that for the most part you use zero as it will work fine. Finally, once you get the source back from registering your callback, you need to add this source to your current run loop through CFRunLoop Add Source.

When your callback is called to handle the query, first thing you're going to do is you're going to get back a CFDictionary. That's the data. Then you can query the dictionary to verify that it contains a key, and you'll want to walk through all the keys that you care about.

In this case, I'm looking for a Quick Draw Family Name key. Then get the value for the appropriate key. And then, as I said before, translate that into a file specification and activate it. One thing to keep in mind, when implementing query handling and auto-activation, it's important that you need to activate in the global context, because if you activate it default or locally, the app that needed it isn't going to see it.

The last thing that I really wanted to talk about was some of the performance issues that you may encounter when bringing your applications to Mac OS X or writing new ones. And here are some solutions we have to help you solve these. One is the User Notification API. This prevents you from having to query the generation seed of the database regularly to pick up generation changes and update your user interface. Now granted, the generation seed and acquiring that is not expensive, but it saves you from having to pull, which is a good thing.

Use the performance tools available on Mac OS X, such as Top, to gauge server messaging. The APIs you use could send a message to the ATS server. There is a cost associated with sending these messages. And you want to watch for ATS server activity, especially very heavy activity when your application might be unresponsive, and evaluate your usage of the APIs. We do our best to provide caching, but sometimes... APIs are used how we don't expect them to and can cause undue messaging and performance degradation.

Another way to avoid performance problems is to avoid using the primitives while iterating through all the fonts. This is such as getting the font tables for any specific table, like the name table, to handle it yourself and walk through it and determine the names of the font. Use an API like ATS font get postscript name instead of the primitive if all you really want is the postscript name. This avoids bringing and mapping all the font files in and thrashing our caches.

That leads me into the last topic. Try to use the high-level APIs whenever possible. We've analyzed their usage, we provide caching, and they are optimized for optimal usage. And if you find a problem with it, please notify us or Developer Relations and we will address them as necessary.

So, in summary, I'd like to reiterate some of the topics I talked about. I showed you how using context and scopes, you can use the iteration APIs to iterate only the fonts that you really care about. This is important. You don't have to -- you can reduce the fonts you get back, improve your application's response, and restrict your search very easily.

Next, we can't stress hard enough how much we would like you to implement the font panel in your Carbon application once it's available. This, as I've mentioned a couple times before, will provide a consistent UI between the two stacks, between AppKit and Carbon. It'll make the feature parity seem like it's present. We all know that Carbon does a lot for us and we can do everything that Cocoa does with Carbon. But now we've got the font panel and we can be very sure of that.

Continue developing to the programming interface of the Font Manager, especially if you are concerned with compatibility between CarbonLib on Mac OS 9 and Mac OS X. But if you are looking to take the jump and make Mac OS X-only applications, make sure to review the ATS framework, as here is where this is our future direction. This is what we would like you to be using down the road, and a lot of our work will be focused on improving this API set for you. I'd like to call Xavier up to cover the roadmap and... Thanks, Nathan. Thank you.

This afternoon, we'll have actually drawing text with AdSui, which is like the higher-- the low-level interface is the way to put it to draw Unicode text on Mac OS X for Carbon applications. On Thursday, I invite you to go and see the MLT, which is the Multilingual Text Engine session, where we'll be discussing actually some great features that the team has been adding for Jaguar. I think you'll be pretty happy with what we've been doing.

Should you have any feedback, we have a feedback forum, which unfortunately is not there, and I think it's tomorrow afternoon. I encourage you to look at your agenda. And this afternoon-- this-- tonight, actually at 7:30, we'll have what we call the Birds of Feather for International Technologies, and we'll have as well there engineers from the Font Manager team, from the AdSui team, from MLT.

If you have any questions on techniques or maybe some blocking bugs, we could probably look at it and, you know, kind of talk between engineers. A great session for those of you that want to go international that are wondering about the markets that Apple is trying to address with Mac OS X is session 010, going international with Mac OS X, which is going to be on Friday at 10:30 in room A2.

Documentation. We'll have Benny on stage, actually, which is our tech representative. He can talk about that. And we'll have a new font manager reference, which explains the font manager reference, what's the ATS framework, and all these APIs we have been discussing today. You have the URL here at the bottom of the screen for information.

More documentation on technologies we discuss in this session, Techno 2024, which is the Mac OS X font manager reference, which is kind of a QA about what are D fonts, a lot of things about what's new actually on Mac OS X and the font manager, which answers a lot of the questions we've been getting on the development list.

And as well, you could check the Apple Type Services technical documentation if you need to find more about what we've been talking today. You have here the URL. The easiest thing for this kind of documentation is definitely to go on the TechPubs website where you have a list of all the documentation available.

Should you have any questions and contacts next week or in two months or next year, you can always send me an email at [email protected] and we'll make sure we get whatever feature that you would like or enhancement request, get the priority bump and make sure that we address your concerns. I'd like to mention as well at the bottom of the screen, you have a Uberall URL, I suppose, where you'll have all the URLs we've been discussing today and this morning in the previous session.