And finished the font attribute rewrite on OS X. Now to test.
This commit is contained in:
parent
91bfceaf71
commit
06becce34c
|
@ -1,6 +1,8 @@
|
||||||
// 14 february 2017
|
// 14 february 2017
|
||||||
#import "uipriv_darwin.h"
|
#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)
|
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)
|
// TODO are values other than 1 accepted for true by OpenType itself? (same for the rest of the file)
|
||||||
|
|
|
@ -146,6 +146,7 @@ struct foreachParams {
|
||||||
|
|
||||||
@end
|
@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)
|
static void ensureFontInRange(struct foreachParams *p, size_t start, size_t end)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -207,30 +208,6 @@ static CGColorRef mkcolor(uiAttributeSpec *spec)
|
||||||
return color;
|
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)
|
static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data)
|
||||||
{
|
{
|
||||||
struct foreachParams *p = (struct foreachParams *) data;
|
struct foreachParams *p = (struct foreachParams *) data;
|
||||||
|
@ -341,22 +318,67 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
return 0;
|
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)
|
static void applyAndFreeFontAttributes(struct foreachParams *p)
|
||||||
{
|
{
|
||||||
[p->converted enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, NSValue *val, BOOL *stop) {
|
CFIndex i;
|
||||||
struct fontParams *fp;
|
combinedFontAttr *cfa, *cfab;
|
||||||
CTFontRef font;
|
CTFontRef defaultFont;
|
||||||
CFRange range;
|
CTFontRef font;
|
||||||
|
CFRange range;
|
||||||
|
|
||||||
fp = (struct fontParams *) [val pointerValue];
|
// first get the default font as a CTFontRef
|
||||||
font = fontdescToCTFont(fp);
|
cfa = [[combinedFontAttr alloc] initWithDefaultFont:p->defaultFont];
|
||||||
range.location = [key integerValue];
|
defaultFont = [cfa toCTFont];
|
||||||
// TODO this is wrong for surrogate pairs
|
[cfa release];
|
||||||
range.length = 1;
|
|
||||||
|
// 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);
|
CFAttributedStringSetAttribute(p->mas, range, kCTFontAttributeName, font);
|
||||||
CFRelease(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[] = {
|
static const CTTextAlignment ctaligns[] = {
|
||||||
|
@ -424,12 +446,12 @@ CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray
|
||||||
|
|
||||||
CFAttributedStringBeginEditing(mas);
|
CFAttributedStringBeginEditing(mas);
|
||||||
fep.mas = mas;
|
fep.mas = mas;
|
||||||
fep.converted = [NSMutableDictionary new];
|
fep.combinedFontAttrs = [NSMutableDictionary new];
|
||||||
fep.defaultFont = p->DefaultFont;
|
fep.defaultFont = p->DefaultFont;
|
||||||
fep.backgroundBlocks = [NSMutableArray new];
|
fep.backgroundBlocks = [NSMutableArray new];
|
||||||
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
||||||
applyAndFreeFontAttributes(&fep);
|
applyAndFreeFontAttributes(&fep);
|
||||||
[fep.converted release];
|
[fep.combinedFontAttrs release];
|
||||||
CFAttributedStringEndEditing(mas);
|
CFAttributedStringEndEditing(mas);
|
||||||
|
|
||||||
*backgroundBlocks = fep.backgroundBlocks;
|
*backgroundBlocks = fep.backgroundBlocks;
|
||||||
|
|
Loading…
Reference in New Issue