SCORING POINTS WITH TRUETYPE

KONSTANTIN OTHMER AND MIKE REED

TrueType, Apple's outline font technology, opens up a world of possibilities for improved
handling of text. For example, with outline fonts, users can resize text as they've always
been able to resize other objects in drawing programs--by grabbing handles and
dragging. This article shows how to program this and other exciting transformations to
text.

The Font Manager in System 7.0 can use TrueType outline fonts, in addition to bitmapped fonts, to
produce text on the screen and on a printer. In outline fonts, the appearance of individual characters
is defined by outlines, not bitmaps. The TrueType font mechanism is also available as an INIT for
System 6.0.7 users.

Your application can take advantage of the special capabilities provided by TrueType fonts to
transform text in decorative and useful ways. These transformations include shrinking or stretching
text to fit a given bounding box and creating patterned, antialiased text. This article provides routines
for accomplishing both of these kinds of transformations. First, though, let's explore in more detail
how TrueType fonts differ from their predecessor, bitmapped fonts.

WHY TRUETYPE IS TRULY WONDERFUL

To understand why TrueType is truly wonderful, you first have to understand the trouble with
bitmapped fonts. With bitmapped fonts, to generate fonts of sizes for which no bitmap exists,
QuickDraw simply picks an available font size according to a gnarly algorithm and stretches or
shrinks the bits. Unfortunately, when a bitmap is resized the resulting image is often far from
pleasing.

This problem is easily understood: imagine you're shrinking a 1-bit image by a factor of two in the
vertical dimension. This means two pixels in the source image combine to form one pixel in the
result. If both source pixels are black or both are white, the solution is easy. The problem comes
when the two source pixels are different. In this case, since most images on the Macintosh appear on
a white background, QuickDraw preserves black. Thus, if either source pixel is black, the result is
black.

QuickDraw uses this same algorithm for larger shrinks. When an image is shrunk vertically by a
factor of eight, if any one of the eight source pixels is black, the resulting pixel is black. Because there
is more information in the source than can be represented in the destination, the resulting image
often looks ragged and is typically too dark.

A similar problem is encountered when enlarging an image. QuickDraw enlarges images by
replicating pixels; thus, the result becomes blocky. There simply is not enough information in the
source image to provide a better scaled-up representation. Figure 1 shows a 72-point B in the
bitmapped Times® font resized by various amounts.

Figure 1 Resizing a Bitmapped Character

This problem with resizing has further implications. Have you ever tried to resize text in the same
way you resize other objects in a drawing program like MacDraw®? If you have, you've discovered
that when you move the handles on the bounding box, the text clipping and formatting change, but
the text isn't resized. This inconsistency between the way text and other objects are handled can be
very confusing to users and may deny them the function they really want: to stretch the text to fill the
box. The reason for this difficulty is--you guessed it! Although resizing an object such as a rectangle
produces excellent results, resizing a bitmapped font results in an image that is, well, ugly.

Enter TrueType. With TrueType fonts, each character is stored as an outline. QuickDraw knows
the shape of the character, much as it knows the shape of a circle. When a character is imaged, its
outline is scaled to the appropriate size and then filled. When a character is scaled, the outline is
scaled rather than the bits. Thus, an excellent representation of the character is possible at all scaling
factors. Figure 2 shows how an outline font looks when compared to a bitmapped font drawn in a
size for which no bitmap exists.

Figure 2 Bitmapped Versus Outline Font

Because characters maintain their integrity at all sizes in TrueType, it's now possible to resize text in
the same way users have always been able to resize other objects in drawing programs. We'll show
you a routine for doing this. It's also possible to superimpose a text mask on any picture you want in
order to create decorative effects. We'll also show you how to do this.

SCALING TEXT TO FIT A GIVEN RECTANGLE

To show how easy it is with TrueType to produce high-quality text scaled to given dimensions,
we've written a routine called BoxText that scales a string of text to fit a given rectangle. It takes a
parameter that indicates how the text should be constrained: vertically, horizontally, both, or neither.
Figure 3 shows examples of text treated in these ways with the BoxText routine.

The BoxText routine is fairly simple. It first checks to see if any constraints are turned on. The
constraints are defined as follows:

Normally, BoxText works just like DrawString. If you pass constraints, the text is stretched to fit the
bounding rectangle's width, or height, or both. This is done through a call to StdText. The
stretching factors are computed from the text's original bounds and the bounds passed to BoxText.

GetTextRect calls GetTextBounds. GetTextBounds takes a string and scaling factors and returns the
bounding rectangle; note that it calls GetFontInfo to determine the height and StringWidth to
determine the width. GetFontInfo is used instead of OutlineMetrics since the measurements for the
entire font (not just individual characters) are used to calculate the rectangle for the text.
Furthermore, GetFontInfo is faster than OutlineMetrics.

The bounds are then scaled by the given scaling factors. The ascent is scaled by the vertical
stretching factor to correctly place the text's baseline. Without this adjustment, the top of the text
would not align with the top of the constraining rectangle. Finally, the rectangle is offset to the
current pen location.

When the text is constrained to fit in the rectangle both horizontally and vertically, the numerator
for vertical scaling is set to the height of the rectangle and the denominator is set to the height of the
text. For horizontal scaling, the numerator is set to the rectangle width and the denominator is set to
the string width. Traditionally, these scaling factors have been stored in point records, and in our
routine the code uses SetPt to set the values. Then MoveTo is called to position the pen at the
location where the text is to be drawn. Finally, the scaled text is drawn using StdText and the text
size is restored.

Note the technique used to call StdText: First the code checks to see whether there are custom
bottlenecks in the current port (as there are when printing). If so (the grafProcs field is nonzero), the
StdText bottleneck routine, rather than the trap, is called. This is necessary to allow BoxText to
print. (Calling the StdText bottleneck is accomplished via the macro, given for both MPW and
THINK C, before the BoxText routine.)

RESIZING TEXT INTERACTIVELY

In most drawing programs, you change the size of an object by clicking and dragging with the mouse.
This type of interactive resizing is calledrubberbanding since the borders of the object stretch and
shrink like a rubber band. Using the previously described BoxText routine, it's easy to achieve this
result for text.

The following routine, SlowRubberBandText, performs the operation. As you can probably guess
from the routine name, the performance is not optimal. We'll return to this issue later with the
FastRubberBandText routine.

The first thing SlowRubberBandText does is to set the pen mode and text mode to Xor. Xor mode is
used so that drawing and erasing can be accomplished without buffering the screen contents and thus
without using much memory. The drawback is that the text flickers when it's being resized. A
commercial application would check to see if enough memory is available to buffer the screen
contents, and if so would provide flicker-free resizing.

Next we have a do-while loop that tracks the mouse as long as the button is held down. On each
iteration through the loop, a rectangle is constructed from the anchor point and the current mouse
position. This rectangle is drawn and then BoxText is called to draw the text scaled to the rectangle.

The do-while loop waits for the mouse to move or for the button to be let up. If either of these
conditions occurs, the text is erased (by being drawn again in the same place). If the button is let up
(the terminating condition on the do-while loop), the routine exits, returning the bounding rectangle.
Otherwise, the text is drawn scaled, using the new mouse position.

While this routine is a simple illustration of the use of BoxText, it's excruciatingly slow. The reason
is that QuickDraw must rerender the outline every time the scaling changes. The
FastRubberBandText routine images the text into a 1-bit off-screen GWorld, and then uses CopyBits
to stretch the resulting bitmap to fit the specified rectangle. This is similar to the method
QuickDraw uses to scale bitmapped fonts, described previously, and is much faster than the slow
case.

The code first allocates a sufficiently large bitmap so that the text looks good even at large sizes. If
the allocation fails in both temporary memory and the application heap, the code tries smaller
rectangles in both heaps. If this also fails, it calls the SlowRubberBandText routine. If the needed
memory is available, GWorld gyrations are performed to image the text into the off-screen pixMap.
Then a do-while loop similar to the one in the SlowRubberBandText routine is executed, but rather
than calling BoxText, it calls CopyBits. The exit conditions are similar to SlowRubberBandText,
with the addition that the GWorld is disposed of.

The FastRubberBandText routine calls ConstrainRect, which mirrors the scaling performed by
BoxText. The routine scales the source rectangle to fit inside the destination rectangle with regard to
constraints.

CREATING PATTERNED, ANTIALIASED TEXT

Generation of high-quality scaled text is only one of the fun tricks of the new outline fonts in System
7.0. You can also create patterned, antialiased text with just a few lines of code. (Antialiased text is
text whose edges have been smoothed by the addition of gray, creating a softer effect; see Figure 4,
and see the antialiased version in color on the inside front cover of this issue.) The possibilities this
opens up for writing a "Hello, World" program are staggering, as illustrated in Figure 5.

Figure 4 Regular Versus Antialiased Text

Figure 5 How "Hello, World" Looks in 1991

To achieve this result you use the CopyDeepMask call (available only in System 7.0). Your
application generates a source pixMap with the pattern or picture you want to use; the
CreateTextMask routine creates a GWorld containing the text mask; and
finally, you call CopyDeepMask to image the source through the mask onto the destination. Figure 6
illustrates this.

GENERATING THE MASK
The CreateTextMask routine works as follows: First, we attempt to allocate a GWorld that would
allow text to be rendered at four times its final size. (If there's not enough memory in the application
heap or temporary memory to allocate a GWorld this big, GWorlds of three times and then two
times the final size are created. If all of these attempts fail, nil is returned.) Next the 1-bit GWorld is
cleared to white and the text is imaged into it scaled by a factor of four (or whatever multiple the 1-
bit GWorld turned out to be) in each direction. Then CopyBits with mode ditherCopy is used to
shrink the large 1-bit GWorld to a 4-bit gray-scale GWorld; this is illustrated in Figure 7.

Because the mask will consist only of grays, the 4-bit GWorld is given a gray-scale CLUT. We are
now finished with the 1-bit GWorld and dispose of it. The 4-bit gray-scale image we just created is
returned by CreateTextMask. Notice that this routine may return a GWorld allocated in temporary
memory, so you must dispose of the GWorld before calling WaitNextEvent.

SAYING "HELLO, WORLD"
Now we're ready to say "Hello, World" in patterned, antialiased text as shown in Figure 4. The
following routine combines the BoxText, FastRubberBandText, and CreateTextMask routines to
produce its results. In this example, the source pixMap contains a picture that's read in from a
resource file. This pixMap could, of course, contain anything, and that image would peek through
the text mask. The interesting thing to notice is that if you scale the source picture to the size of the
text, the image behind each letter will stay the same regardless of the scaling factor.

SUMMARY AND PARTING THOUGHTS

TrueType fonts provide high-quality characters at all sizes and scaling factors. This is possible
because TrueType fonts are stored as outlines rather than bitmaps, and scaling an outline produces
much better results than scaling a bitmap. The BoxText routine described in this article uses the
StdText call to stretch text to fit within a specified box. A logical extension of this could solve a
problem that has plagued humankind (or at least high school students): how to expand six and a half
pages of text to produce a report that's exactly ten pages long, as required by law or a high school
teacher.

Usually tactics such as adjusting the margins, line spacing, and font size can get you close. But this
trial-and-error process could easily be replaced with a procedure written by some enterprising and
humanitarian programmer:

FitTextToPages(char *text, long numPages);

Rather than simply adjusting the margins and line spacing, this routine could uniformly stretch a
block of text to fill the desired number of pages.

System 7.0 also allows applications to pass a deep mask to CopyMask or CopyDeepMask. By imaging
text into a large bitmap and then scaling it down with ditherCopy, it's possible to generate a soft-
edged mask for producing antialiased text. Furthermore, text drawn using CopyDeepMask can have
any image as the source pixMap, making it easy to produce patterned or picture text.

In the process of producing all of these great effects with text, we used GWorlds extensively. From
the code samples it should be clear that GWorlds are extremely simple to create and manipulate.
Judicious use of temporary memory for holding GWorlds allows our sample "Hello, World"
program to run in a 100K heap and still produce very large (bigger than 1200 x 500 pixels) scaled text
(provided there's enough temporary memory available, of course).

Enjoy!

KONSTANTIN OTHMER AND MIKE REED Have you seen these two guys? Konstantin and Mike, better known as Jake and Elwood, were last seen driving an old
Black & White to the Palace Hotel Ballroom where they performed such hits as "Everybody Needs Some PixMaps to
CopyBits" and "Gimme Some TrueType." Frequented hangouts: kitchen after lunch meetings, football field, poker tables,slopes at Tahoe, beach, Fitness Center, center stage. Known contacts: Bruce "Second Hand" Leak, Dave "Know" Good.
Distinguishing marks: gym bag, running shoes, soft-edged clip art, smooth text forms. Latest fortune cookie: Ask and you
shall receive; this includes trouble. Any information as to the whereabouts of these rascals should be sent to their
managers, who are probably looking for them. *

Note that the fonts shown in the illustrations are drawn at screen resolution, so they don't look as good as they would if
drawn on a higher-resolution device such as a printer. *

The example code shown here was written in THINK C. The Developer Essentials disc contains both THINK C and MPW ®versions. *

The antialiasing technique used in this article requires a multiple-bits-per-pixel destination device. Since most printers are 1
bit per pixel, these antialiasing techniques are useful primarily for the screen. A second problem with printing antialiased
text using these techniques is that QuickDraw does not pass the CopyDeepMask call to printer drivers. For multiple-bits-per-
pixel printers, you could image the antialiased text into a GWorld and then use CopyBits to draw the image on a
printer. *

For details on using CopyBits with ditherCopy, see "QuickDraw's CopyBits Procedure" in develop, Issue 6. *

Software Updates via MacUpdate

EtreCheck 3.1.5 - For troubleshooting yo...

EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more

WALTR 2 2.0.8 - $39.95

WALTR 2 helps you wirelessly drag-and-drop any music, ringtones, videos, PDF, and ePub files onto your iPhone, iPad, or iPod without iTunes. It is the second major version of Softorino's critically-... Read more

Carbon Copy Cloner 4.1.12 - Easy-to-use...

Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more

Dropbox 16.3.27 - Cloud backup and synch...

Dropbox is an application that creates a special Finder folder that automatically syncs online and between your computers. It allows you to both backup files and keep them up-to-date between systems... Read more

Microsoft OneNote 15.29 - Free digital n...

OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that's too important to forget. Whether you're at... Read more

Spotify 1.0.44.100. - Stream music, crea...

Spotify is a streaming music service that gives you on-demand access to millions of songs. Whether you like driving rock, silky R&B, or grandiose classical music, Spotify's massive catalogue puts... Read more

SpamSieve 2.9.27 - Robust spam filter fo...

SpamSieve is a robust spam filter for major email clients that uses powerful Bayesian spam filtering.
SpamSieve understands what your spam looks like in order to block it all, but also learns what... Read more

VueScan 9.5.62 - Scanner software with a...

VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more

Fantastical 2.3.2 - Create calendar even...

Fantastical 2 is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun:
Open Fantastical with a single click or keystroke
Type in your event... Read more

PCalc 4.4.4 - Full-featured scientific c...

PCalc is a full-featured, scriptable scientific calculator with support for hexadecimal, octal, and binary calculations, as well as an RPN mode, programmable functions, and an extensive set of unit... Read more

Latest Forum Discussions

Christmas is fast approaching and that means it's time to prepare for Santa's yearly pilgrimage around the globe. Christmas Eve is an exciting time as parents help their kids get ready to welcome Santa. You've got the cookies and milk all planned... | Read more »

Galaxy on Fire 3 and four other fantasti...

Galaxy on Fire 3 - Manticore brings the series back for another round of daring space battles. It's familiar territory for folks who are familiar with the franchise. If you've beaten the game and are looking to broaden your horizons, might we... | Read more »

The best apps for your holiday gift exch...

What's that, you say? You still haven't started your holiday shopping? Don't beat yourself up over it -- a lot of people have been putting it off, too. It's become easier and easier to procrastinate gift shopping thanks to a number of apps that... | Read more »

MyTona, based in the chilly Siberian city of Yakutsk, has brought a little festive fun to its hidden object game Seekers Notes: Hidden Mystery. The Christmas update introduces some new inhabitants to players, and with them a chance to win plenty of... | Read more »

PINE GROVE 1.0
Device: iOS Universal
Category: Games
Price: $1.99, Version: 1.0 (iTunes)
Description:
A pine grove where there are no footsteps of people due to continuous missing cases. The case is still unsolved and nothing has... | Read more »

Niantic teases new Pokémon announcement...

After rumors started swirling yesterday, it turns out there is an official Pokémon GO update on its way. We’ll find out what’s in store for us and our growing Pokémon collections tomorrow during the Starbucks event, but Niantic will be revealing... | Read more »

3 reasons why Nicki Minaj: The Empire is...

Nicki Minaj is as business-savvy as she is musically talented and she’s proved that by launching her own game. Designed by Glu, purveyors of other fine celebrity games like cult favorite Kim Kardashian: Hollywood, Nicki Minaj: The Empire launched... | Read more »

Clash of Clans is getting its own animat...

Riding on its unending wave of fame and success, Clash of Clans is getting an animated web series based on its Clash-A-Rama animated shorts.As opposed to the current shorts' 60 second run time, the new and improved Clash-A-Rama will be comprised of... | Read more »

Price Scanner via MacPrices.net

Never Settle for Low Performing Wifi With iOS...

AppYogi Software has announced the release of WiFi Signal Strength Status App 1.0, the company’s new utility developed exclusively for macOS. WiFi Signal Strength Status App features a unique, single... Read more

DietSensor, Inc., a developer of smart food and nutrition applications designed to fight diabetes and obesity and help improve overall fitness, has announced the launch of its DietSensor app for... Read more

Best Buy has dropped their price on the 64GB Apple TV to $159.99 including free shipping. That’s $40 off MSRP.
32GB Apple TVs are on sale right now for $98 on Sams Club’s online store. That’s $51 off... Read more

12-inch Retina MacBooks, Apple refurbished, n...

Apple has restocked a full line of Certified Refurbished 2016 12″ Retina MacBooks, now available for $200-$260 off MSRP. Refurbished 2015 models are available starting at $929. Apple will include a... Read more

Apple has Certified Refurbished 13″ MacBook Airs available starting at $849. An Apple one-year warranty is included with each MacBook, and shipping is free:
- 13″ 1.6GHz/8GB/128GB MacBook Air: $849 $... Read more

Apple refurbished iMacs available for up to $...

Apple has Certified Refurbished 2015 21″ & 27″ iMacs available for up to $350 off MSRP. Apple’s one-year warranty is standard, and shipping is free. The following models are available:
- 21″ 3.... Read more

MacTech is a registered trademark of Xplain Corporation. Xplain, "The journal of Apple technology", Apple Expo, Explain It, MacDev, MacDev-1, THINK Reference, NetProfessional, Apple Expo, MacTech Central, MacTech Domains, MacNews, MacForge, and the MacTutorMan are trademarks or service marks of Xplain Corporation. Sprocket is a registered trademark of eSprocket Corporation. Other trademarks and copyrights appearing in this printing or software remain the property of their respective holders. Not responsible for typographical errors.

All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.