libui/darwin/opentype.m

114 lines
2.9 KiB
Objective-C

// 11 may 2017
#import "uipriv_darwin.h"
#import "attrstr.h"
struct addCTFeatureEntryParams {
CFMutableArrayRef array;
const void *tagKey;
BOOL tagIsNumber;
CFNumberType tagType;
const void *tagValue;
const void *valueKey;
CFNumberType valueType;
const void *valueValue;
};
static void addCTFeatureEntry(struct addCTFeatureEntryParams *p)
{
CFDictionaryRef featureDict;
CFNumberRef tagNum, valueNum;
const void *keys[2], *values[2];
keys[0] = p->tagKey;
tagNum = NULL;
values[0] = p->tagValue;
if (p->tagIsNumber) {
tagNum = CFNumberCreate(NULL, p->tagType, p->tagValue);
values[0] = tagNum;
}
keys[1] = p->valueKey;
valueNum = CFNumberCreate(NULL, p->valueType, p->valueValue);
values[1] = valueNum;
featureDict = CFDictionaryCreate(NULL,
keys, values, 2,
// TODO are these correct?
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (featureDict == NULL) {
// TODO
}
CFArrayAppendValue(p->array, featureDict);
CFRelease(featureDict);
CFRelease(valueNum);
if (p->tagIsNumber)
CFRelease(tagNum);
}
static uiForEach otfArrayForEachAAT(const uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t value, void *data)
{
__block struct addCTFeatureEntryParams p;
p.array = (CFMutableArrayRef) data;
p.tagIsNumber = YES;
uiprivOpenTypeToAAT(a, b, c, d, value, ^(uint16_t type, uint16_t selector) {
p.tagKey = kCTFontFeatureTypeIdentifierKey;
p.tagType = kCFNumberSInt16Type;
p.tagValue = (const SInt16 *) (&type);
p.valueKey = kCTFontFeatureSelectorIdentifierKey;
p.valueType = kCFNumberSInt16Type;
p.valueValue = (const SInt16 *) (&selector);
addCTFeatureEntry(&p);
});
return uiForEachContinue;
}
// TODO find out which fonts differ in AAT small caps and test them with this
static uiForEach otfArrayForEachOT(const uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t value, void *data)
{
struct addCTFeatureEntryParams p;
char tagcstr[5];
CFStringRef tagstr;
p.array = (CFMutableArrayRef) data;
p.tagKey = *FUTURE_kCTFontOpenTypeFeatureTag;
p.tagIsNumber = NO;
tagcstr[0] = a;
tagcstr[1] = b;
tagcstr[2] = c;
tagcstr[3] = d;
tagcstr[4] = '\0';
tagstr = CFStringCreateWithCString(NULL, tagcstr, kCFStringEncodingUTF8);
if (tagstr == NULL) {
// TODO
}
p.tagValue = tagstr;
p.valueKey = *FUTURE_kCTFontOpenTypeFeatureValue;
p.valueType = kCFNumberSInt32Type;
p.valueValue = (const SInt32 *) (&value);
addCTFeatureEntry(&p);
CFRelease(tagstr);
return uiForEachContinue;
}
CFArrayRef uiprivOpenTypeFeaturesToCTFeatures(const uiOpenTypeFeatures *otf)
{
CFMutableArrayRef array;
uiOpenTypeFeaturesForEachFunc f;
array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
if (array == NULL) {
// TODO
}
f = otfArrayForEachAAT;
if (FUTURE_kCTFontOpenTypeFeatureTag != NULL && FUTURE_kCTFontOpenTypeFeatureValue != NULL)
f = otfArrayForEachOT;
uiOpenTypeFeaturesForEach(otf, f, array);
return array;
}