Application • 51:00
This session outlines the font technologies in Mac OS X and provides programming techniques that you can use to improve the way your application works with fonts. We discuss techniques for supporting font collections and the related font management advances in Carbon, Cocoa, and Font Book, as well as extensions to the printing architecture that provide additional flexibility in handling PDF and PostScript font data.
Speakers: Robin Mikawa, 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.
Please welcome from Apple Computer, Robin Mikawa. All right, so let's get started. My name is Robin Mikawa. I'm the manager of the type engineering team at Apple Computer, and I'm going to be here talking to you today about the font APIs on Mac OS X. So before I get started, let me give you some background and an explanation why are we all here today.
Why are fonts so important? First and foremost, the thing to remember about fonts is that they're inextricably tied together with text. So if you're working with text, you are working with fonts. That's really the thing to remember. Even if you're developing, let's say, a simple application terminal emulator that only uses one font at a time, even nowadays, we provide the option for users to set your preferences. So in that case, you'll have to deal with fonts and being able to list it and allow your users to set your preferences. users to select the fonts.
Now, second, fonts have a long history. They've evolved over time. You've got all these different formats available, and users can and have found them frustrating or difficult to use. They're tricky. Some have multiple files that you have to carry across. Others, well, they're all different formats. They're all different styles.
So what we've done on the system is made it a lot easier for both the users and you as developers to take advantage of all these technologies. And have consistent, reliable results, make it really simple to work with fonts. And so what you're going to get out of today's session is how to hook into the operating system and really make your applications shine, take up to the front of the pack, you know, become leaders in the world of fonts.
So just to give you a short overview of what the presentation is, I'm going to be talking about just how to get started. We're going to go right into the meat of the matter. We're going to show you programming techniques, tips and tricks, hints, stuff that you shouldn't do. And along the way, you're going to get some glimpses into the future, what we're working on for Tiger, as well as the roadmap for longer term beyond Tiger. So let's get started.
All right, as developers, and I know exactly how you feel, one of the first questions, maybe not the first one, but at least maybe the second or third one, is what APIs are available and how should I use them? What I've shown you here is not only the layering, but also what each component or API set is really tailored for. So to get started... Up at the upper left, we've got Cocoa. That is the application framework for Mac OS X. So if you're starting from scratch or you have the option to switch over to the Cocoa framework, great. You're going to get a lot of this support for free.
Now, if you want to do user interface text, you've got HIToolbox. That is the engine for drawing user interface text as well as measuring it and then handling all the font support underneath it, such as substituting the appropriate fonts for different languages. Now, underlying that is the multilingual text engine.
What that does is it handles the text editing and static text behavior in HIToolbox itself. There's also support for handling a document-based model, as well as doing a font user interface. And so all of that allows you to build essentially a very basic text editing application just by using MLTE.
Now, underlying all of this is Atsui. You've got Apple Type Services for Unicode imaging. People have asked me that before. That's the official name. What it is is the text layout engine for Mac OS X. It provides support for positioning text in the right places, handling the fonts, the graphics.
All of that stuff is abstracted out from underneath you. It also handles things like justification, font features, a lot of details that you don't need to worry about. But that you can hook in at that layer if you just want to take advantage of some parts of the system services.
[Transcript missing]
And then underlying all of that is ATS itself. That's Apple Type Services. And that's the core font system on Mac OS X. And so what that gives you is a way to hook into the way fonts are tracked, detailed information about the fonts, such as the metrics, and it's really what serves all the font information up to the other parts of the system.
Now you'll notice there's one component I've mentioned in the past that isn't up here, and that's Quick Draw. Quick Draw as a tiger has been deprecated. Now don't panic. It's not going away. It's just we've marked it in the interfaces and allowed you to or let you know that we're recommending that you move on to other technologies such as Quartz. We've made sure there's additional support in there to at least match or parallel the functionality that you become used to. There's going to be a discussion about it later in the week at the graphics session, and you can listen in on those at that point in time.
All right. So next up, as opposed to you as developers, where do your users get started? Where are they going to see the user interface? How do they get at the fonts that they want? Where are the commands? How do they process the fonts? And so one of the things we noticed at Apple was that there really hasn't been any guidelines for providing a consistent user interface for fonts.
Think of it this way. You've got the file menu. Most of you know it's like, okay, we've got a couple commands in there that should be in there. Edit menus. In a similar way, we're recommending that you move to this model for your font menu. Now, the key thing to remember here is that first command up there, show fonts.
That's really where we're going to focus all of our new features, our development, our ease of use on the font panel. That command shows and hides the font panel. Now, we've made it really easy by building in the support in Interface Builder. You can just drag in the font menu.
The other items, the other commands in there, if you don't want to support them, you can simply gray them out in the menu. But you probably already have commands like this spread out somewhere in your menu structure. The idea is so that users know exactly where to go for at least their really basic commands for dealing with fonts.
Now, going along with Quickdraw being deprecated, we're highly recommending that you move away from the old font and style menus that you used to see in Quickdraw applications. One of the key things is that users have found it confusing. Sometimes they wouldn't even use the style menu because they couldn't get at exactly the fonts that they wanted.
And so we've been working on ways to make sure that that's much more easy to do with the font panel. All right, so that's the basics. I just covered how to get started, and let's just dive into the rest of the presentation. And I'll give you another engineer on my team, Nathan Taylor, to talk about them.
Thank you, Robin. Hi, I'm Nathan Taylor. I'm a software engineer with the Type Engineering team, and my responsibilities include many of the APIs that we're going to show you today. So, what I'm here to talk about are some of the basic programming techniques that you can implement in your applications to bring it to the head of the pack, as Robin said.
There are three basic items we want you to take from this. One, and foremost, adopt the font panel in your application. The font panel is the common interface that we have provided for accessing fonts. It solves a lot of the previous problems with font menus and adds new functionality for the users.
It's also important to consider this in providing a consistent user interface for accessing fonts throughout the system via your application. The second item is to handle font notifications in your application. These notifications are provided to you so that you can respond to changes to the font registry that a user may enact.
And the third item up here, store font references. How should you store font references in your document-- in the user documents now and going forward with the system? And I'll cover that a bit later. Before I show you how to do this, let me give you a brief demo of what these things will provide for your application.
What I'm going to do is fire up a simple app here. This is your basic Hello World application written with the Carbon frameworks. And what I have here is a basic window with some pretty plain text. So now I'm going to bring up the font panel. And as you can see, we have the font panel implemented through a pretty standard fonts menu according to the HI guidelines.
Now, one of the first things your application is going to need to do when a user changes a font is respond to that and actually change the font in the document. So let me pick another font here, Heffler Text 96 point, and you can see that I've implemented basic font changing within this application.
So besides just the basic support for the font panel, which you can see right here, there's also additional functionality that the font panel provides and you can choose to implement. This is some nice features such as font effects. You can see I just implemented this panel bar right here. These effects provide things like shadow, Colors, Underline, and Strike Through, things that go above and beyond what the font itself actually provides. This information is provided to your application through the same mechanism that a lot of the font panel information is.
In addition to the font effects, there are also typographic features that the user can access through the typography panel. As you can see, Heffler Text has a bunch of features here, and these include things like ligature control. This allows the user to have extra control over the fonts that support these features, so they can turn off or turn on some of the special ligatures that a font might have. For example, our Zappfino font has this cool ligature that when you type Zappfino, it makes one single glyph for the whole name of the font.
Now, the other thing to worry about when implementing support for the font panel is handling user focus. The most common user focus change that you need to be worried about and that you won't probably forget is tracking the user's position through a body of text and through different style runs. But one that is often forgotten is tracking the change between windows. So I just brought up a second window here with another greeting. And let me set the font on that real quick.
Now, you see I have Cochin selected here. If I change windows, I've implemented here tracking of the user focus between windows. When I switch to the other window, Heffler text is selected. Let me do that again so you can see. Now it's back to Cochin. Finally, I mentioned font notifications.
And so let me turn on notifications to my application. I'm going to subscribe to them. Now the demo app is listening for these. And I'm going to be a user, and I'm going to disable a font using Font Book. Let me go right after Cochran there and turn it off.
At Hide Font Book, you'll see that the demo application has received a notification. This is gratuitous. You don't need to do this in your application, but the alert is here to illustrate the point. And as you can see, this text has now changed. It is now using a substitute font, and I handled that substitution in my notification callback so that the text didn't disappear in my simple text engine here. And that about covers it for the basic demo. So let's go back to the slides and dive right into how you can implement this in your application. So first, let's look at how to adopt the Font Panel.
The first thing you need to do is how do you get this font panel in your application. As Robin mentioned, use Interface Builder for Carbon or Cocoa and drag the font menu into your menu bar. In Cocoa, once you've done that, it's pretty much free for all the basic view classes.
In Carbon, there's a little bit more work. And so let me go into that. There are three basic steps once you've put the font panel in your application. So you need to show and hide the font panel on demand. You need to handle user selection events. And you need to handle user focus.
So showing and hiding the font panel is pretty straightforward. It's supported through the standard event handler. And if you create a show fonts menu item and give it that SHFP tag I have here, the standard command identifier for the show/hide font panel, you will get much of the support to hide and show the font panel with the selection through the standard event handler. You can also handle that event yourself if you choose to.
Again, font selection events are important because that's where the user interacts with your application through the font panel. They'll select a font, a size, and you should be able to handle it and show it in the current selection that they have. And finally, as I showed, user-focused tracking between windows is important.
There's also another stage of user-focused tracking that's important. When the user has closed all windows or just interim between switching windows, you want to be able to clear the state of the font panel. And so I'll go into, when I show you the code, the simple steps to do that.
So handling font selection is pretty straightforward. The first thing you're going to do is you're going to receive font selection events from the font panel. These events contain information about the user's selection. The first thing you're probably going to want to pull out of here is the typeface.
That can be provided by family, by typeface directly, and it will probably also include size information. As I mentioned in the demo, additional information such as typographic features, text effects, and even variation instance information could be provided through the event mechanism. We've had many requests for support for variation instances, and it's now available through the typographic features panel.
So let's take a look at how to implement font selection in your application. This is a really simple event handler here. And what I've got is I look for the basic class of the event. Then I check to make sure to see if it's a font selection event, at which point I select and extract the parameters from the event that I need.
In this case, I'm pulling out the ATSU font ID and the ATSU font size. I'll then pass those on to my text engine, apply them to the user's current selection, and then move on. Here's the point where you'd also want to pull out the extra parameters, such as the type effects, typographic features, and anything else you might want from this event. Now, handling user focus is another simple thing to do, and let's take a look at it.
All right. So this first block of code shows how to handle user focus when a window focus acquired event comes through. The same code would be used when you're switching between users' selections. The basic flow here is you extract your target. This is where you want your events to be sent. Then you extract the current text style from that target. Finally, calling set font info for selection, you pass in the style and the target, and that causes the font panel to select the current style within the window.
When the focus from the window is relinquished by the event window focus relinquished, You could call set font info for selection. Here, it's important to note, you just pass in null for the target and the style, and that clears the state of the font panel. Additionally, that instructs the font panel to discontinue sending notifications to the previous target.
All right, the next item we have to cover is handling font notifications. Font notifications are pretty simple to do, but they provide a lot of functionality for you. And let's look at what you can get and what you can do with them. The first thing to do with notifications is you need to subscribe. And you do this by creating a callback and using the appropriate API. Subscribe that callback to notifications.
In your callback, it's important that you do the work that you need to do. This could involve updating documents, like I did in the demo, with custom font substitution. Or if you have a standard font menu or font list, updating that. It's really important to track the notifications so that a user doesn't have to quit and relaunch your application to see changes they made to the font system.
Other things you can do with font notifications are you can notify the system of changes you've made to the font directories or the registry. There's a simple API to notify the system of changes, and you'll want to do this if you're installing fonts from an installer application or some installer block in your code that drops fonts in the standard directory.
And finally, the little bit more interesting option you can do, and it interacts with some of the other font management APIs that we have available, is to batch your processing events. Things like ATS Font Activate and Deactivate are lengthy operations, and they trigger automatic notifications to anybody who has subscribed.
If you're doing a lot of these in sequence, you'll generate a lot of events sent to anybody who's subscribing to notifications, which could be a performance issue. What you can do is batch your operation by passing the Do Not Notify flag to those APIs, and at the end of your batch operation, call the same ATS Font Notify API to tell everybody that you're done and that something has changed. So let's see how to do a basic subscription to font notifications. What I've done here is I have a very simple callback. Within the braces, you would put the code that you want to run. And for brevity, I kind of left mine out.
Then, register it with the system. You can register your notification with the system using the API ATS Font Notification Subscribe, and you pass in your callback, and you get back a notification reference. It's possible to register multiple notifications, and you would want to hang on to the references, especially if you want to unsubscribe them like I do at the bottom.
When unsubscribing, you pass in the notification reference, and then you no longer will receive notifications for the callback that's attached to that reference. You can do this in the case where you've got multiple functionality, but only some of it needs to be maintained through a certain time period. So you set up a bunch of callbacks and turn one off when you no longer need it. Anything else you have when your application terminates will automatically be unsubscribed.
All right, the last item I have to cover is how to store font references in your document. Font references are important because a user wants to open their documents that they previously saved and see it coming back just as they saved it with the correct fonts and the correct style information.
So what are the best ways for you to store font references? I've got three here, and one of them is new for Tiger. So let's start with that one. Use the NS Font Descriptor class available from Cocoa if you can. This provides extended functionality for specifying fonts. It allows you to specify fonts more precisely if you desire, and also allows us to be more flexible with providing fonts for your request.
There are three simple steps to using these. First, you would create a font descriptor with some font attributes. It could be as simple as a font name. Then to save it, you'll extract the attributes from the font descriptor, which returns a dictionary, which you can flatten and save into your document using the standard methods. Finally, upon opening the document, you'll create the NS font from this font descriptor and display it, and your user will be happy.
The other methods that you've seen before, if you've been at any of these previous sessions, are use the PostScript name. If you can't adopt font descriptors, the PostScript name is the next best thing. It's the standard reference mechanism in Cocoa and Quartz up to this point for referencing fonts. And if you happen to have a QuickDraw-based application, you may still need to store the family name and style information. All right, so let's take a look at some quick code snippets for handling font descriptors.
All right. I've got three blocks here. The first block, I create a font descriptor by a create with name. This name is simply the PostScript name. Then, in the second block, I extract the font attributes. This returns, as you can see, an NSDictionary. I then can save that to my file and then bring it back and create a font after unarchiving the dictionary, creating a descriptor from that dictionary, and then creating an NS font with font with descriptor and size. At this point, the document is ready to display and the user is happy. All right, that about wraps it up for me, so I'll have Robin come back on stage to give you some more advanced programming techniques to customize your applications. Thank you.
So I'm back. Essentially, you can see what I'm going to talk about for the rest of the session, which is even more programming techniques. So hang in there. I'm going to try and make this as fun as possible. Now, one of the key things I thought about when I was looking over this session was, what are the sorts of things I want to hear about if I were just a generic developer who did something with fonts? And here's something that's really important for you is, in addition to the basic stuff we've just described up above, what you can get out of the system is hooking into it at the right level and customizing the way font handling works in your application.
So, again, we're giving you recommendations and guidelines, but if you want to do your own custom support or if you want to make something slightly different that makes things even better for your users, you can do it. And so that includes things like the user interface, looking at fonts in detail so you can implement, let's say, your own custom text engine, handling font management in your own way, or implementing a font utility, just like Font Book.
You can also hook into the graphics system or the way fonts are processed, either for printing or for rendering on screen. And then finally, there's a new feature that I'll go into later that I'm pretty excited about, you'll probably notice it later, is scripting for font management. And that lets your users customize the way fonts work for them on the operating system. So before I do that, let me go in and give you a quick demo that shows you how you might want to customize some of these features.
All right, so I'll bring up Font Book here. And I've implemented a really simple, basic application that shows you how you can customize the user interface. So like we've said, we recommend using the Font Panel. But if you want to do something different, let's say a font menu that does pretty much exactly the same thing as the Font Panel, Then I've done it here. If you look at this, you can see that it's got all the standard collections in there.
Within them, they've got all the contents that you would get in a Carbon or Cocoa application that's adopted the font panel. These are all the standard collections. In fact, I've shown it on the side with Font Book, so you can see that they're actually exactly the same. Now another thing that we've done on Tiger that's new that takes advantage of the font system and extracts information out of it and puts it up on screen in a slightly different way is Apple System Profiler.
Let me blow this up a little bit so you can see it. And what we've done is we've added a fonts plugin for System Profiler that essentially lists all the fonts available on your system, extracts different bits of information about the font, and then splashes it up on screen or in the System Profiler app so you can actually see and get a lot of interesting information that's in the fonts themselves. So you can see this is Zapfino. I've got where it's located, whether or not it's enabled, and then all kinds of information about the font itself that's actually available to you as developers.
That's my demo, real quick and short. And moving back to the presentation, What I'm going to go over next is all of these items. I'll go through them real quick. If you can tell, I can speak pretty quickly. I'll try and make sure I don't run everything together and blah, blah, blah, blah, blah, so you can understand me. But essentially, customizing the user interface. First off, I'm going to talk about Cocoa, and then I'm going to talk about another component, MLTE.
So with Cocoa, what we've got here is it parallels the implementation or the additional work you might need to do that Nathan described for Carbon. And this is important if you're writing a custom view. All of the standard text views, the text fields, they handle the font panel automatically. But let's say you're writing a subclass of table view or the outline view, which don't inherently support the font panel. This is how you go about doing it.
And it's just two slides worth of steps. It's really easy. So first of all, in Cocoa, just the general thing, if you're dealing with fonts, most likely you're going to have to get an instance of the shared font manager. This is the hub of getting all your font services.
Now once you've got your hands on that, you can send a notification whenever your current selection in your text object, your view, changes, or when you become first responder. Those are the two places where you'd actually want to do it. And so you simply send this command and indicate the font and whether or not it's a multiple selection. That's one part of the communication.
The second half is just about as simple. So what happens here is that, like I said, standard text views automatically do this for you. But if you want, you can respond to changes in the font panel or the font user interface in the font menu. The font manager will send a notification up the responder chain.
All you have to do is listen to the default message. In this case, I've implemented a basic delegate method. Change font is the message or the action message that you need to respond to. Within that function, all you need to do is pull out your current selection. I've got a really simple example here.
It's only one font for the object, but you can do something more complex, as you can imagine. I pull that out. It's my old font. I send it back to the font manager to modify it and make that match exactly what the user has selected, whatever actions the user has done in the font panel or the font menu.
It sends me back a new instance of an NSFont object. which then I can apply to my text view. That's it. So you notice it's actually in parallel with what Nathan described. You listen in to the messages and you send notifications out to communicate the information to the font panel.
Now, in MLTE, In the past, you've had to do what Nathan described as with any Carbon application. But new for Tiger, we've made it even simpler. All you have to do now is one line of code, or in my case, four lines of code. Essentially, there's a new API available to enable support in a text extension, which is the old name for MLT, text object.
And so, in essence, I've created a text object. It could be either a document or a text field. indicate that you want it to listen and support the standard font commands. That's it. You're done. All of that communication back and forth, updating the text object itself, all of that's handled automatically for you on Tiger. So that was a pretty boring slide, but it's really simple.
indicate that you want it to listen and support the standard font commands. That's it. You're done. All of that communication back and forth, updating the text object itself, all of that's handled automatically for you on Tiger. So that was a pretty boring slide, but it's really simple. Now I've got some sample code here, but let me give you just a real quick hint. When you're dealing with fonts and you want to get information, there's APIs available at pretty much all the layers that I described earlier. Cocoa, Atsui, ATS.
In all of those, the recommendation is whichever one you've chosen to work at primarily, let's say you're a Cocoa application, a lot of the APIs there support the same level of support for accessing font information. Try and use it at that level. If you need to, you can dip down lower into the deeper layers as you need to. So at the very bottom, of course, you've got ATS. And in this case, what I've done is I want to get access to every single font on the system in the registry.
Actually, let me strike that. Every single font my app can see. In fact, I'll talk about this next. There's some options you can set to define the context and the scope of an enumeration or a listing. So in this case, I create an iterator object. I pass that iterator object to a function, ATS font iterator next, that basically steps through every single font on the system that matches my criteria, returns a standard font ref that I can then use later to access information.
And I'll go into that in a little bit more detail later. Once I'm done with the iteration or the enumeration, I'll release the iterator object and I can move on. In fact, that's exactly what I'll do next. Thank you. All right, so I mentioned context and scope. A lot of people tend to ask this question, what the heck is that? There's two options, I gotta mess with it.
The simplest way to look at it is in this diagram, you'll see the local unrestricted combination of options really matches what I just described. It's really all the fonts that your app should be able to use and see. Now, within that set, you've got more restricted sets. One is the local restricted, local context, which is really your local application, restricted to just those fonts that your application owns and manages and has entered into the system. So they're like application-specific fonts. Global restricted is the global space. It's all the shared fonts, and those fonts managed by the system itself. Put those together, and you get all the fonts that you can see and use within your app.
There's one more combination, the fourth one, which is global unrestricted, which we don't recommend you use, mainly because if you take this image, duplicate it essentially with all the processes or all the applications in the system, It'll give you all those fonts, every single font. And so the key thing here to remember is you might get your hands on some fonts that you don't have, you know, you can't use. Basically, they're owned by somebody else.
All right, so once you get your hands on a font ref, what can you do with it? Here's one example. There's support at various layers. NSFont has the support. ATS also has the support. You can access metrics information about the fonts. And also, in some cases, information about individual glyphs within the fonts. And so you've got the advance, you've got line information, bounding recs, and additional information, including like the italic angle. So again, the recommendation is use those APIs at the same level as the other APIs you're using in your application.
Now another thing. Okay, so customizing font management is the next section. What's that mean? Well, let me give you a little background. Font management, when I talk about it, we're talking about... Component-wise, it's the shared font registry on the system. It's the support available from Mac OS X that goes out and finds all the fonts. It tracks information such as what users can see the fonts, what processes can use and see the fonts, and access privileges, as well as where the fonts are located.
This font database or font registry handles the standard file system domain ordering. This is all the different locations. So just to go through it real quickly, first off, the system will look in the user domain or your home directory's font library. Next up, the local domain, which is the library fonts that's shared across the particular computer between different users as well as different applications. You've got the network fonts and then the system critical fonts that you're not supposed to touch. And then finally, it's not a standard file system domain, but we support it.
The classic environment, which doesn't need to be running, by the way. All you have to do is register it with system preferences. We'll look inside its system folder and give you back all those fonts also. So the way you can take advantage of this is you can add fonts or remove fonts in that registry. You can modify the contents.
The way you would do it is using this function. ATS Font Activate from File Specification is one example. It uses a standard file spec. This is obviously an older API. Point it at your font or your directory of fonts. Indicate. Now, this is why we had different context and scope options. We reused that one so you can register the fonts locally within your application.
I've also specified that I don't know what the format is, so please figure it out for me. And that's a really good example where the system, you can leverage it and still provide custom support because it handles all of the details of the different formats and activates them accordingly. You get a container object back. Whenever you want to, you can remove those fonts from the system using that container. That's it.
All right, now this is something really cool. It's new. In the past, we've told you if you have an application-specific font, you need to do that stuff in the previous slide. Well, now on Tiger, all you have to do is stuff your font somewhere in your application bundle, put a pointer to it in the Info.plist file, and then you're done.
Everything else is taken care of for you. So the system will automatically register those fonts with itself when your application is launched, and then remove those fonts when your application shuts down. And again, the key that you'll want to use is right up there, ATS Application Fonts Path.
Now another thing is in the demo I showed you, I accessed the system support for collections. And the way this works, just a quick review, is it lets users filter down the font list to something more manageable. And so when you do that, we actually-- The way you can support it is hooking into Cocoa.
We also have C callable equivalents for getting at this support. What we have here right now is the first block of code is just getting a list of all the collections available. It's essentially an array of NSStrings. From that, you can actually modify or add additional collections. You can add and remove them. I don't show it here, but I do show how you can modify the contents one or create a new one on your own.
There's a font geek in my group. I won't mention their name, but I happen to install my fonts and group them according to different styles and categories historically. Venetian, Gurali are two different subclasses of, or subgroups of the serif old style category. So what I want to do here in this example is essentially take all the descriptors, Side note, every collection consists of font descriptors, as Nathan mentioned earlier. These are essentially a way to describe or criteria that describe one or more fonts together.
So again, my collection, I extract all the descriptors out of it, stick it in an array. Then I stuff in some more. I pull them out of the Guraldi collection, stuff them into that array, and then I add all of those font descriptors to my new collection that I referenced by the name Serif Old Style. Simple as that. And again, there's C callable equivalents that you can use in the Carbon framework.
All right. So we've got font processing. What does that mean for you? I think I mentioned it earlier. They're essentially a way for you to hook into the graphics system or the printing system. What the rasterizers do, they're actually modular components on the system. They take the raw font data, they run through it, and they spit out graphics or print-related data.
That includes the bitmaps, the outlines. It also converts the font data from what you see on disk to something that can be embedded within a PostScript document or PDF files. In fact, that's exactly what the printing system on Mac OS X uses. It uses this level of support. So if you want to hook into it, you can take advantage of that now.
The rasterizers also hide all of the details of the different formats for you. So we've got TrueType in all its variants. OpenType is actually a new format package that is supported by Microsoft and Adobe and Mac OS X. We also handle PostScript, both the Type 1 and the OpenType flavors. So all of that detail is hidden away from you so you don't have to worry about it, but still take advantage of the general features.
Now, here's one example of doing that. I'm going to give you two. I'll touch on printing next. But in this case, I'm using the text layout system itself. I'm using its character-to-glyph conversion support in the initial block. Essentially, I'm using this API. Okay, I'll let you read it out loud. By the way, I've done worse in my history. Essentially, it takes a text layout object that stores the text stream, the text information. It takes those character codes, converts them over to a list of glyph records. I've got a glyph data array and account.
One thing to note is that character codes don't necessarily map to glyph IDs, which are actually the representation of the actual shapes within a font. So a good example of this is a ligature. If you have F, let's say F and L in your character stream, when you apply it to a font or apply a font to it, it might get merged into one ligature, one glyph.
That's the FL ligature itself. And so you can take advantage of the text system to do that conversion for you in a standard way. Now, the second block of code shows you how you can actually get that graphics data I mentioned. One of the things you can use it for is, let's say you've got some text, you want to turn it into graphics data that you want to send straight to the printer, you want to modify it, you want to morph it into a different graphic shape, put polka dots on it for all I know.
So in order to do this, you go through those glyph records one by one, grab the relevant information, in this case, the style object and the glyph ID. And what's really interesting here is that, by the way, I'm converting this to cubic data, cubic paths. You can also convert it to another form, quadratic curves. But in this case, I've got four standard operations that define the shape of the glyph.
And so one would be moving to a particular point. Another one would be drawing a straight line. Another one might be drawing a curve. And the last one is drawing or indicating the end of the path. And so all of these functions you can define, pass it into the Atsugecubic glyph pass function. It will basically record or play back those glyphs, allow you to record that information in a buffer and process it however you want. You can send it straight down to a disk, whatever you choose to.
All right. So I mentioned printing support. Essentially this is a new feature in Tiger. Now we still highly recommend you let the printing system do as much of the work as possible. But if you were using instead of, let's say, the PDF rendering path, which is recommended, if you're using the old LaserWriter 8 compatibility print support to do post script rendering or post script downloads. This lets you take advantage of newer support to actually just get that font data to do it to manipulate in your own way.
And so we allow you to generate font subsets from a standard Quartz font reference using the function, well, CG font create PostScript subset. You can indicate what the output format should be and then an array of glyphs, CG glyph IDs. These are just the same as those glyph IDs I mentioned earlier in the Atsui example.
If you pass in null for the array, it'll just give you every single glyph in the font, or you can indicate specific glyphs as you choose. Once you've done that, it will return all that data back in a CF package, a core foundation data package, which then you can use the standard functions in core foundation to parse and process however you want, including sending it to a disk or downloading it straight to a printer.
Okay, so at this layer, when you're working on it, you have to be more aware of performance. And so here's some tips and hints. When you're working in Atsui, try and reuse objects as much as possible. Specifically for fonts, pre-allocate and reuse the Atsu style objects. This allows you to use the caching system available in Atsui, and it basically minimizes the amount of memory allocations and reuse of system resources.
Also, use the Quartz graphics context as much as possible when you're working directly with Atsui. This is because Atsui has been optimized for Quartz. If you're using an older, let's say, Quick Draw graphics port, there's some conversion that's needed that slows things down potentially. Now, when you're working in Quartz, the same principles tend to apply. Try and reuse the CG font refs as much as possible, the Quartz font references.
The reason for this is even though you might have the same font reference pointing at the same font, let's say, Times, Now, when you're working in Quartz, the same principles tend to apply. Try and reuse the CG font refs as much as possible, the Quartz font references. The reason for this is even though you might have the same font reference pointing at the same font, let's say Times, Now, when you're working in Quartz, the same principles tend to apply. Try and reuse the CG font refs as much as possible, the Quartz font references.
The reason for this is even though you might have the same font reference pointing at the same font, let's say Times, with an example of what we've done on Mac OS X for Tiger. So right now, I've got Font Book showing. If you didn't notice earlier, take a look here. I've got a standard AppleScript menu now available. I'll just open up the script folder. And I've got two scripts there available. In fact, let me just pull up one using Script Editor to show you that it is actually AppleScript.
All right. So one of the key things to remember here, you can manipulate any object that Font Book itself can see and handle. So in this particular case, I'm just showing you the code so you get a sense of, yeah, this is real code. But just a quick summary of it is, it's creating a new collection named Bold, and then it's asking all the typefaces in Font Book for every entry in there that might match the name Bold. Pulls those out and stuffs them into the new collection I just created called Bold.
Now, instead of running it from within Script Editor, let me run it straight from Font Book. Now, the thing to remember is watch the Collections pane on the left-hand side. You're going to see a new collection show up there pretty much instantaneously called Bold. It contains
[Transcript missing]
I've implemented another Apple script. It's really cool. I actually hugged the engineer when he showed me this, mainly because... I'll let it run.
I used to have to do this by hand. Okay? So I'd go in and I'd have to test it. I'd have to create the sample. Ugh, I hated it. Well, it's done. Well, yes, it's done now. So essentially, I created a document with 87 different families, 183 typefaces, all using AppleScript. And the key thing to remember here is that not only is Font Book itself AppleScripted, but you can interact or your users can interact with other applications that support AppleScript just as easily. Okay, so that's the demo. Real quick.
And getting back to the presentation, here's just the final summary of what the scripting support that's new for Tiger consists of. It's a standard Apple script dictionary in Font Book. It has a number of classes and elements that you can take advantage of, including the domains I described earlier, collections themselves, as well as containers. And you can also manipulate or look at the font families and typefaces.
Within those, each of them has a bunch of different properties that you can check out, but the name is definitely one of them, whether or not that font or collection is enabled. And then you can manipulate them using the standard AppleScript commands, like add and remove, to remove items from a container object, let's say fonts from a collection. You can also delete objects wholesale. So that's new for Tiger. It's really exciting. I know some of you have asked us in the past for it. We got it done.
All right, so that wraps up the presentation. Let me just give you an overall summary. Essentially, adopt the font panel. If anything, please try to do that. Let the system do the work for you. That's really the key message here. That's where we're going to put a lot of support in. You can take advantage of it by just doing that. Now, if you want to customize support, you can do it.
Like I described, there's a bunch of different things you can do with the operating system, a bunch of different APIs available. You can customize the way fonts work within your application to match your users' needs. Now, if you have any questions, you can contact our evangelist, Xavier Legro. And you can also refer to the documentation on the Apple Developer Connection website. And this just touches on a couple of the items I've discussed today. I kind of went everywhere.