问题
I have a CTFont that contains a font style, and sumbolic traits.
I want to create a new font with a new style that inherits the symbolic traits of the first font. How can I achieve this?
CTFontRef newFontWithoutTraits = CTFontCreateWithName((CFString)newFontName, CTFontGetSize(font), NULL);
CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits(newFontWithoutTraits, CTFontGetSize(font), NULL, 0, CTFontGetSymbolicTraits(font));
the new font is null here
I don't know what should I pass to the 4th
parameter in CTFontCreateCopyWithSymbolicTraits
.
回答1:
I do this line of code to generate a bold font from non-bold font:
CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits(currentFont, 0.0, NULL, (wantBold?kCTFontBoldTrait:0), kCTFontBoldTrait);
currentFont
is theCTFontRef
I want to add symbolic traits towantBold
is a boolean to tell if I want to add or remove the bold trait to the fontkCTFontBoldTrait
is the symbolic trait I want to modify on the font.
The 4th parameter is the value you want to apply. The 5th is the mask to select the symbolic trait.
You may thing of it as bitmask to apply to the symbolic trait, where the 4th parameter of CTFontCreateCopyWithSymbolicTraits
is the value and the 5th parameter is the mask:
- If you want to set the symtrait and add it to the font, iOS will probably apply sthg like
newTrait = oldTrait | (value&mask)
, setting the bit corresponding tomask
to the value ofvalue
. If you want to unset the symtrait and remove it from the font, you use the value of 0 as the 4th parameter and iOS will probably apply sthg like
newTrait = oldTrait & ~mask
to unset the bit.But if you need to, you can also set and unset multiple bits (thus multiple symbolic traits) at once, using the right
value
that have 1 on bits to set and 0 on bits to unset (or to ignore), and and using the rightmask
that have 1 on bits that needs to be modified and 0 on bits that don't need to be changed.
[EDIT2]
I finally managed to find the solution for your specific case: you need to get the symtraits mask of your font
as you already do… and bitwise-or it with the symtraits of your newFontWithoutTraits
font.
This is because newFontWithoutTraits
actually do have default symtraits (contrary to what I thought, it has a non-zero CTFontSymbolicTraits
value) as the symtraits value also contains info for the font class and such things (so even a non-bold, non-italic font can have a non-zero symtraits value, log the hex value of the symtraits of your font to understand better).
So this is the code you need:
CTFontRef font = CTFontCreateWithName((CFStringRef)@"Courier Bold", 12, NULL);
CGFloat fontSize = CTFontGetSize(font);
CTFontSymbolicTraits fontTraits = CTFontGetSymbolicTraits(font);
CTFontRef newFontWithoutTraits = CTFontCreateWithName((CFStringRef)@"Arial", fontSize, NULL);
fontTraits |= CTFontGetSymbolicTraits(newFontWithoutTraits);
CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits(newFontWithoutTraits, fontSize, NULL, fontTraits, fontTraits);
// Check the results (yes, this NSLog create leaks as I don't release the CFStrings, but this is just for debugging)
NSLog(@"font:%@, newFontWithoutTraits:%@, newFont:%@", CTFontCopyFullName(font), CTFontCopyFullName(newFontWithoutTraits), CTFontCopyFullName(newFont));
// Clear memory (CoreFoundation "Create Rule", objects needs to be CFRelease'd)
CFRelease(newFont);
CFRelease(newFontWithoutTraits);
CFRelease(font);
来源:https://stackoverflow.com/questions/7492237/objective-c-ctfont-change-font-style