Question

Unfortunately, Lucida Grande does not have an italic variant and I need one.

My options here seem limited and I am hoping someone has a better one for me.

First, I tried, applying a NSAffineTransform by doing the following:

NSFont *theFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];

const CGFloat kRotationForItalicText = -15.0;

NSAffineTransform *italicTransform = [NSAffineTransform transform];

[italicTransform scaleBy:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];
[italicTransform rotateByDegrees:kRotationForItalicText];

theFont = [NSFont fontWithDescriptor:[theFont fontDescriptor] textTransform:italicTransform];

but, this does not produce text that is particularly readable.

My next option is to switch to a different font:

theFont = [NSFont userFontOfSize:[NSFont labelFontSize]];
theFont = [sharedFontManager convertFont:theFont toHaveTrait:NSItalicFontMask];

and while the text here is readable when italicized, I would rather be using the same font since it is obviously different.

I could, of course, use userFontOfSize font for both my italic and non-italic text, but I am currently limited to using the systemFontOfSize font.

Do I have any other (good) options?

Thank you.

Was it helpful?

Solution

This answer will be similar to my initial one, but updated for what, after more testing, works.

So, first, my method of creating the italic font was deeply flawed. Instead of simply applying a rotation to the text, I needed to apply a skew transform. I ended up finding a good skew transform to apply at WebKit's Font code. It contained the skew transform:

CGAffineTransformMake(1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, 0, 0)

It does look good.

Simply using a different font is not the correct answer. While the Lucida Sans font is virtually identical to Lucida Grande (which is returned by systemFontOfSize) and has a real italic variant, the italic variant will not draw Japanese Characters in italic.

So, what appears to be the only answer is to obtain the systemFontOfSize, check to see if it has an italic variant, and, if not, add a skew transform.

Here is my final solution:

NSFont              *theFont            = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];
NSFontManager       *sharedFontManager  = [NSFontManager sharedFontManager];

if ( wantItalic ) 
{
    theFont = [sharedFontManager convertFont:theFont toHaveTrait:NSItalicFontMask];

    NSFontTraitMask fontTraits = [sharedFontManager traitsOfFont:theFont];

    if ( !( (fontTraits & NSItalicFontMask) == NSItalicFontMask ) ) 
    {
        const CGFloat kRotationForItalicText = -14.0;

        NSAffineTransform *fontTransform = [NSAffineTransform transform];           

        [fontTransform scaleBy:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];

        NSAffineTransformStruct italicTransformData;

        italicTransformData.m11 = 1;
        italicTransformData.m12 = 0;
        italicTransformData.m21 = -tanf( kRotationForItalicText * acosf(0) / 90 );
        italicTransformData.m22 = 1;
        italicTransformData.tX  = 0;
        italicTransformData.tY  = 0;

        NSAffineTransform   *italicTransform = [NSAffineTransform transform];

        [italicTransform setTransformStruct:italicTransformData];

        [fontTransform appendTransform:italicTransform];

        theFont = [NSFont fontWithDescriptor:[theFont fontDescriptor] textTransform:fontTransform];
    }
}

OTHER TIPS

So, first, my method of creating the italic font was deeply flawed. Instead of simply applying a rotation to the text, I needed to apply a skew transform. I ended up finding a good skew transform to apply at WebKit's Font code. It contained the skew transform:

CGAffineTransformMake(1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, 0, 0)

It does look good. The cocoa code to set this up is:

const CGFloat kRotationForItalicText = -14.0;

NSAffineTransform *fontTransform = [NSAffineTransform transform];           

[fontTransform scaleBy:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];

NSAffineTransformStruct italicTransformData;

italicTransformData.m11 = 1;
italicTransformData.m12 = 0;
italicTransformData.m21 = -tanf( kRotationForItalicText * acosf(0) / 90 );
italicTransformData.m22 = 1;
italicTransformData.tX  = 0;
italicTransformData.tY  = 0;

NSAffineTransform   *italicTransform = [NSAffineTransform transform];

[italicTransform setTransformStruct:italicTransformData];

However, I was told by another person that the "Lucida Sans" font is virtually identical to Lucida Grande and does have a real italic variant.

So, basically, I am using a different font, but one that should meet with full approval. However, if for some reason the Lucida Sans font cannot be found, I will default back to systemFontOfSize and apply the above transform to it if necessary.

You rock! I made one mod -16.0 instead of -14.0 rotation... so user can find italicized values more easily in a giant spreadsheet. My problem was that using a non-LucidaGrande font causes all kinds of vertical alignment issues throughout my UI.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top