tags:

views:

392

answers:

2

I'm trying to draw in the currently selected system font using the ATSU api in a Carbon app. And the fonts are coming out bolder than all the other native apps. Here is a screenshot example of what I'm talking about:

The top line is XCode, and the middle is my app using a non-bold font and the bottom is my app using a bold font. I used the same text to make it easy to see the difference in weight between them. The code I'm using to create the styles I draw with is:

if (Face() AND !(e = ATSUCreateStyle(&d->hFont)))
{
    // Lookup ID
    ATSUFontID atsuFont = 0;
    e = ATSUFindFontFromName(Face(),
                            strlen(Face()),
                            kFontFamilyName,
                            (FontPlatformCode)kFontNoPlatform,
                            (FontScriptCode)kFontNoScript,
                            (FontLanguageCode)kFontNoLanguage,
                            &atsuFont);
    if (!e)
    {
        Fixed Size;
        Size = PointSize() << 16;
        Boolean IsBold = Bold();
        Boolean IsItalic = Italic();
        Boolean IsUnder = Underline();

        // Set style attr
        ATSUAttributeTag Tags[]         = {kATSUFontTag,     kATSUSizeTag, kATSUQDItalicTag, kATSUQDUnderlineTag, kATSUQDBoldfaceTag};
        ATSUAttributeValuePtr Values[]  = {&atsuFont,        &Size,        &IsItalic,        &IsUnder,            &IsBold};
        ByteCount Lengths[]             = {sizeof(atsuFont), sizeof(Size), sizeof(IsItalic), sizeof(IsUnder),     sizeof(IsBold)};
        if (!(e = ATSUSetAttributes(d->hFont,
                                    CountOf(Tags),
                                    Tags,
                                    Lengths,
                                    Values)))
        {
            GDisplayString ds(this, "A");
            d->Height = ds.Y();
            return true;
        }
    }
}

Where "Face()" returns a C string containing the font name, "PointSize()" returns an integer containing the point size I want etc etc. I'm retreiving this values with this code:

Str255 Name;
SInt16 Size;
Style St;
OSStatus e = GetThemeFont(  kThemeSmallSystemFont,
                            smSystemScript,
                            Name,
                            &Size,
                            &St);
if (e) printf("%s:%i - GetThemeFont failed with %i\n", __FILE__, __LINE__, e);
else
{
    Info.Face(p2c(Name));
    Info.PointSize(Size);
    Status = true;
}

And it returns valid looking face/pointsize info, and in fact the font looks correct apart from it looking bolder than other apps. It might not look like a big difference but when your entire app is full of text it gets to be obvious. And my flagship product is an email client... hence lots of text.

The drawing code that creates the layouts and eventually calls ATSUDrawText is quite long, and I'm not sure it's causing the issue.. I think it's more style related... but if need by I'll post a link to that source later.

Can anyone help getting my fonts looking less bold?

A: 

Actually, that is the bold font you're seeing in the upper line in your app. Here's photographic evidence, with Lucida Grande Bold 11 in TextEdit on the right. The lower line in your app is that with faux bold added.

And you know Carbon is deprecated, right?

Peter Hosey
But I'm passing in false as the value for the kATSUQDBoldfaceTag tag.Carbon deprecated? Well thats fine... but I don't have the time to rewrite my apps right now.
fret
+1  A: 

I've converted the cocoa ATSU example code to carbon and ran that alongside my own code. It looked correct so I refined that code and worked out what I was doing differently. Turns out that it's that initial stage of turning a font face name into an ATSUFontID. Obviously I'm using ATSUFindFontFromName which appears to be totally reasonable, however it looks different to the rest of the operating system. The correct drop in replacement code is:

CFStringRef fontName = CFStringCreateWithBytes( kCFAllocatorDefault,
                                                (UInt8*)Face(),
                                                strlen(Face()),
                                                kCFStringEncodingUTF8,
                                                false);
ATSFontRef atsFont = ATSFontFindFromName(fontName, kATSOptionFlagsDefault);
CFRelease(fontName);
ATSUFontID font = FMGetFontFromATSFontRef(atsFont);

So now my apps are looking great :)

fret