Skip to content

Instantly share code, notes, and snippets.

@jjgod
Created July 31, 2012 21:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jjgod/3220817 to your computer and use it in GitHub Desktop.
Save jjgod/3220817 to your computer and use it in GitHub Desktop.
Lookup AAT features with Core Text
// CTTest.c
#include <ApplicationServices/ApplicationServices.h>
CFDictionaryRef findFeatureByName(CFArrayRef features, const char *name)
{
CFDictionaryRef feature = NULL;
CFStringRef featureName = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
CFIndex i;
for (i = 0; i < CFArrayGetCount(features); i++) {
CFDictionaryRef f = CFArrayGetValueAtIndex(features, i);
CFStringRef typeName = CFDictionaryGetValue(f, kCTFontFeatureTypeNameKey);
if (typeName && !CFStringCompare(featureName, typeName, kCFCompareCaseInsensitive)) {
feature = f;
break;
}
}
CFRelease(featureName);
return feature;
}
SInt32 findSelectorByName(CFDictionaryRef feature, const char *name)
{
SInt32 selector = -1;
CFStringRef selectorName = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
if (selectors) {
CFIndex i;
for (i = 0; i < CFArrayGetCount(selectors); i++) {
CFDictionaryRef s = CFArrayGetValueAtIndex(selectors, i);
CFStringRef sName = CFDictionaryGetValue(s, kCTFontFeatureSelectorNameKey);
if (sName && !CFStringCompare(selectorName, sName, kCFCompareCaseInsensitive)) {
CFNumberRef sIdentifier = CFDictionaryGetValue(s, kCTFontFeatureSelectorIdentifierKey);
if (sIdentifier) {
CFNumberGetValue(sIdentifier, kCFNumberSInt32Type, &selector);
break;
}
}
}
}
CFRelease(selectorName);
return selector;
}
int main(int argc, char *argv[])
{
if (argc < 2)
return -1;
CFStringRef name = CFStringCreateWithCString(NULL, argv[1], kCFStringEncodingUTF8);
CTFontRef font = CTFontCreateWithName(name, 12, 0);
CFRelease(name);
CFArrayRef features = CTFontCopyFeatures(font);
if (features) {
// print out all features if no additional argument is given
if (argc < 3) {
CFIndex i;
for (i = 0; i < CFArrayGetCount(features); i++)
CFShow(CFArrayGetValueAtIndex(features, i));
} else {
CFDictionaryRef feature = findFeatureByName(features, argv[2]);
if (feature) {
if (argc < 4)
CFShow(feature);
else {
SInt32 selector = findSelectorByName(feature, argv[3]);
printf("%s: %d\n", argv[3], selector);
}
}
}
CFRelease(features);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment