And finished the font attribute rewrite on OS X. Now to test.

This commit is contained in:
Pietro Gagliardi 2017-05-30 14:38:25 -04:00
parent 91bfceaf71
commit 06becce34c
2 changed files with 61 additions and 37 deletions

View File

@ -1,6 +1,8 @@
// 14 february 2017
#import "uipriv_darwin.h"
// TODO explain the purpose of this file
static void boolspec(uint32_t value, uint16_t type, uint16_t ifTrue, uint16_t ifFalse, aatBlock f)
{
// TODO are values other than 1 accepted for true by OpenType itself? (same for the rest of the file)

View File

@ -146,6 +146,7 @@ struct foreachParams {
@end
// TODO merge this with adjustFontInRange() (and TODO figure out why they were separate in the first place; probably Windows?)
static void ensureFontInRange(struct foreachParams *p, size_t start, size_t end)
{
size_t i;
@ -207,30 +208,6 @@ static CGColorRef mkcolor(uiAttributeSpec *spec)
return color;
}
struct aatParam {
struct foreachParams *p;
size_t start;
size_t end;
};
static void doAAT(uint16_t type, uint16_t selector, void *data)
{
#if 0 /* TODO */
struct aatParam *p = (struct aatParam *) data;
ensureFontInRange(p->p, p->start, p->end);
adjustFontInRange(p->p, p->start, p->end, ^(struct fontParams *fp) {
fp->featureTypes[fp->nFeatures] = type;
fp->featureSelectors[fp->nFeatures] = selector;
fp->nFeatures++;
if (fp->nFeatures == maxFeatures) {
// TODO
// TODO move this check to the top like in the drawtext example? and all the other instances of this?
}
});
#endif
}
static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data)
{
struct foreachParams *p = (struct foreachParams *) data;
@ -341,22 +318,67 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
return 0;
}
static BOOL cfaIsEqual(combinedFontAttr *a, combinedFontAttr *b)
{
if (a == nil && b == nil)
return YES;
if (a == nil || b == nil)
return NO;
return [a same:b];
}
static void applyAndFreeFontAttributes(struct foreachParams *p)
{
[p->converted enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, NSValue *val, BOOL *stop) {
struct fontParams *fp;
CTFontRef font;
CFRange range;
CFIndex i;
combinedFontAttr *cfa, *cfab;
CTFontRef defaultFont;
CTFontRef font;
CFRange range;
fp = (struct fontParams *) [val pointerValue];
font = fontdescToCTFont(fp);
range.location = [key integerValue];
// TODO this is wrong for surrogate pairs
range.length = 1;
// first get the default font as a CTFontRef
cfa = [[combinedFontAttr alloc] initWithDefaultFont:p->defaultFont];
defaultFont = [cfa toCTFont];
[cfa release];
// now go through, fililng in the font attribute for successive ranges of identical combinedFontAttrs
// we are best off treating series of identical fonts as single ranges ourselves for parity across platforms, even if OS X does something similar itself
// this also avoids breaking apart surrogate pairs (though IIRC OS X doing the something similar itself might make this a non-issue here)
cfa = nil;
n = CFAttributedStringGetLength(p->mas);
range.location = 0;
for (i = 0; i < n; i++) {
NSNumber *nn;
nn = [NSNumber numberWithInteger:i];
cfab = (combinedFontAttr *) [p->combinedFontAttrs objectForKey:nn];
if (cfaIsEqual(cfa, cfab))
continue;
// the font has changed; write out the old one
range.length = i - range.location;
if (cfa == nil) {
font = defaultFont;
CFRetain(font);
} else
font = [cfa toCTFont];
CFAttributedStringSetAttribute(p->mas, range, kCTFontAttributeName, font);
CFRelease(font);
uiFree(fp);
}];
// and start this run
cfa = cfab;
range.location = i;
}
// and finally, write out the last range
range.length = i - range.location;
if (cfa == nil) {
font = defaultFont;
CFRetain(font);
} else
font = [cfa toCTFont];
CFAttributedStringSetAttribute(p->mas, range, kCTFontAttributeName, font);
CFRelease(font);
CFRelease(defaultFont);
}
static const CTTextAlignment ctaligns[] = {
@ -424,12 +446,12 @@ CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray
CFAttributedStringBeginEditing(mas);
fep.mas = mas;
fep.converted = [NSMutableDictionary new];
fep.combinedFontAttrs = [NSMutableDictionary new];
fep.defaultFont = p->DefaultFont;
fep.backgroundBlocks = [NSMutableArray new];
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
applyAndFreeFontAttributes(&fep);
[fep.converted release];
[fep.combinedFontAttrs release];
CFAttributedStringEndEditing(mas);
*backgroundBlocks = fep.backgroundBlocks;