ADC Home > Reference Library > Technical Q&As > Carbon > Text & Fonts >

Improving ATSUI Text Drawing Performance

Q: Is there any way I can improve text drawing performance when using the ATSUI APIs?

A: Yes, there is. By preallocating the ATSUStyle records used by your application and reusing them whenever your application draws some text using ATSUI, your text drawing performance should improve. The routine shown in Listing 1 illustrates how your application can pre-allocate an ATSUStyle record based on an Appearance theme font id.

    /* MakeThemeATSUIStyle creates a simple ATSUI style record
    that based on the current theme font ID that can be used in
    calls to the ATSUI text drawing routines. */
OSStatus MakeThemeATSUIStyle(ThemeFontID themeFontID,
        ATSUStyle *theStyle) {
    OSStatus err;
    ATSUStyle localStyle;
    ATSUFontID atsuFont;
    Fixed atsuSize;
    short atsuOrientation, fontFamily, fontSize;
    Str255 fontName;
    Style fontStyle;
    Boolean trueVar = true, falseVar = false;

        /* Three parrallel arrays for setting up attributes. */
    ATSUAttributeTag theTags[] = {
            kATSUFontTag, kATSUSizeTag, kATSUVerticalCharacterTag,
            kATSUQDBoldfaceTag, kATSUQDItalicTag, kATSUQDUnderlineTag,
            kATSUQDCondensedTag, kATSUQDExtendedTag
    ByteCount theSizes[] = {
            sizeof(ATSUFontID), sizeof(Fixed), sizeof(UInt16),
            sizeof(Boolean), sizeof(Boolean), sizeof(Boolean),
            sizeof(Boolean), sizeof(Boolean)
    ATSUAttributeValuePtr theValues[] = {
            NULL, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL

        /* set up locals */
    localStyle = NULL;
    atsuFont = 0;
    atsuSize = 0x00080000;
    atsuOrientation = kATSUStronglyHorizontal;
    /* or atsuOrientation = kATSUStronglyVertical */

        /* calculate the theme font parameters */
    err = GetThemeFont( themeFontID, smSystemScript,
            fontName,  &fontSize, &fontStyle);
    if (err != noErr) goto bail;
    atsuSize = FixRatio(fontSize, 1);

        /* set the values array to point to our locals */
    theValues[0] = &atsuFont;
    theValues[1] = &atsuSize;
    theValues[2] = &atsuOrientation;
    theValues[3] = ((fontStyle & bold) != 0 ? &trueV : &falseV);
    theValues[4] = ((fontStyle & italic) != 0 ? &trueV : &falseV);
    theValues[5] = ((fontStyle & underline) != 0 ? &trueV : &falseV);
    theValues[6] = ((fontStyle & condense) != 0 ? &trueV : &falseV);
    theValues[7] = ((fontStyle & extend) != 0 ? &trueV : &falseV);

        /* calculate the font ID */
    GetFNum( fontName, &fontFamily);
    err = ATSUFONDtoFontID( fontFamily, fontStyle, &atsuFont);
    if (err != noErr) goto bail;

        /* find the font ID */
    err = ATSUFindFontFromName((Ptr)fontName+1, (long)fontName[0],
        kFontFullName, kFontMacintoshPlatform,
        kFontRomanScript, kFontNoLanguage, &atsuFont);
    if (err != noErr) goto bail;

        /* create a style */
    err = ATSUCreateStyle(&localStyle);
    if (err != noErr) goto bail;

        /* set the style attributes */
    err = ATSUSetAttributes( localStyle,
        theTags, theSizes, theValues );
    if (err != noErr) goto bail;

        /* store the new style for the caller */
    *theStyle = localStyle;
    return noErr;
    if (localStyle != NULL) ATSUDisposeStyle(localStyle);
    return err;

Listing 1. Allocating an ATSUStyle based on an Appearance theme font ID.

Once your application has allocated an ATSUStyle record, it can be used again and again whenever your application needs to draw some text using ATSUI. The routine shown in Listing 2 illustrates how one would go about using the style record in a routine that draws some Unicode text.

    /* RenderUnicodeString renders a CFString at (h, v) in the
    current grafport using ATSUI using the style specified in
    the atsui style record. */
OSStatus RenderUnicodeString(ConstUniCharArrayPtr iText,
        UniCharCount iTextLength, ATSUStyle theStyle,
        short h, short v)  {
    ATSUTextLayout theLayout = NULL;
    OSStatus err;

        /* set up our locals, verify parameters... */
    if (iText == NULL || theStyle == NULL) return paramErr;
    theLayout = NULL;
    if (iTextLength == 0) return noErr;

        /* create the ATSUI layout */
    err = ATSUCreateTextLayoutWithTextPtr( iText, 0,
        iTextLength, iTextLength, 1,
        (unsigned long *) &iTextLength, &theStyle,
    if (err != noErr) goto bail;

        /* draw the text */
    err = ATSUDrawText(theLayout, 0, iTextLength,
            FixRatio(h, 1), FixRatio(v, 1));
    if (err != noErr) goto bail;

        /* done */
    return noErr;

    if (theLayout != NULL) ATSUDisposeTextLayout(theLayout);
    return err;

Listing 2. A routine that draws some text using a pre-allocated ATSUStyle record.



Source files illustrating techniques described herein.


[Apr 17 2001]

Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.