And implemented fontvariation.m.
This commit is contained in:
parent
72d31285c1
commit
8333063cc0
|
@ -1,5 +1,6 @@
|
||||||
// 3 january 2017
|
// 3 january 2017
|
||||||
#import "uipriv_darwin.h"
|
#import "uipriv_darwin.h"
|
||||||
|
#import "fontstyle.h"
|
||||||
|
|
||||||
// Core Text exposes font style info in two forms:
|
// Core Text exposes font style info in two forms:
|
||||||
// - Fonts with a QuickDraw GX font variation (fvar) table, a feature
|
// - Fonts with a QuickDraw GX font variation (fvar) table, a feature
|
||||||
|
|
|
@ -52,3 +52,10 @@
|
||||||
- (CFStringRef)familyName;
|
- (CFStringRef)familyName;
|
||||||
- (CFArrayRef)variationAxes;
|
- (CFArrayRef)variationAxes;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
// fonttraits.m
|
||||||
|
extern void processFontTraits(fontStyleData *d, uiDrawFontDescriptor *out);
|
||||||
|
|
||||||
|
// fontvariation.m
|
||||||
|
extern NSDictionary *mkVariationAxisDict(CFArrayRef axes, CFDataRef avarTable);
|
||||||
|
extern void processFontVariation(fontStyleData *d, NSDictionary *axisDict, uiDrawFontDescriptor *out);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// 2 november 2017
|
// 2 november 2017
|
||||||
#import "uipriv_darwin.h"
|
#import "uipriv_darwin.h"
|
||||||
|
#import "fontstyle.h"
|
||||||
|
|
||||||
// This is the part of the font style matching and normalization code
|
// This is the part of the font style matching and normalization code
|
||||||
// that handles fonts that use the fvar table.
|
// that handles fonts that use the fvar table.
|
||||||
|
@ -155,7 +156,7 @@ static fixed214 normalizedTo214(fixed1616 val, const fixed1616 *avarMappings, si
|
||||||
return fixed1616ToFixed214(val);
|
return fixed1616ToFixed214(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed1616 *avarExtract(CFDataRef table, size_t index, size_t *n)
|
static fixed1616 *avarExtract(CFDataRef table, CFIndex index, size_t *n)
|
||||||
{
|
{
|
||||||
const UInt8 *b;
|
const UInt8 *b;
|
||||||
size_t off;
|
size_t off;
|
||||||
|
@ -180,3 +181,140 @@ fixed1616 *avarExtract(CFDataRef table, size_t index, size_t *n)
|
||||||
}
|
}
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
staatic BOOL extractAxisDictValue(CFDictionaryRef dict, CFStringRef key, fixed1616 *out)
|
||||||
|
{
|
||||||
|
CFNumberRef num;
|
||||||
|
double v;
|
||||||
|
|
||||||
|
num = (CFNumberRef) CFDictionaryGetValue(dict, key);
|
||||||
|
if (CFNumberGetValue(num, kCFNumberTypeDouble, &v) == false)
|
||||||
|
return NO;
|
||||||
|
*out = doubleToFixed1616(v);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface fvarAxis : NSObject {
|
||||||
|
fixed1616 min;
|
||||||
|
fixed1616 max;
|
||||||
|
fixed1616 def;
|
||||||
|
fixed1616 *avarMappings;
|
||||||
|
size_t avarCount;
|
||||||
|
}
|
||||||
|
- (id)initWithIndex:(CFIndex)i dict:(CFDictionaryRef)dict avarTable:(CFDataRef)table;
|
||||||
|
- (double)normalize:(double)v;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation fvarAxis
|
||||||
|
|
||||||
|
- (id)initWithIndex:(CFIndex)i dict:(CFDictionaryRef)dict avarTable:(CFDataRef)table
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
self->avarMappings = NULL;
|
||||||
|
self->avarCount = 0;
|
||||||
|
if (!extractAxisDictValue(dict, kCTFontVariationAxisMinimumValueKey, &(self->min)))
|
||||||
|
goto fail;
|
||||||
|
if (!extractAxisDictValue(dict, kCTFontVariationAxisMaximumValueKey, &(self->max)))
|
||||||
|
goto fail;
|
||||||
|
if (!extractAxisDictValue(dict, kCTFontVariationAxisDefaultValueKey, &(self->def)))
|
||||||
|
goto fail;
|
||||||
|
if (table != NULL)
|
||||||
|
self->avarMappings = avarExtract(table, i, &(self->avarCount));
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
[self release];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
if (self->avarMappings != NULL) {
|
||||||
|
uiFree(self->avarMappings);
|
||||||
|
self->avarMappings = NULL;
|
||||||
|
}
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (double)normalize:(double)d
|
||||||
|
{
|
||||||
|
fixed1616 n;
|
||||||
|
fixed214 n2;
|
||||||
|
|
||||||
|
n = doubleToFixed1616(d);
|
||||||
|
n = fixed16161Normalize(n, self->min, self->max, self->def);
|
||||||
|
n2 = normalizedTo214(n, self->avarMappings, self->avarCount);
|
||||||
|
return fixed214ToDouble(n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NSDictionary *mkVariationAxisDict(CFArrayRef axes, CFDataRef avarTable)
|
||||||
|
{
|
||||||
|
CFDictionaryRef axis;
|
||||||
|
CFIndex i, n;
|
||||||
|
NSMutableDictionary *out;
|
||||||
|
|
||||||
|
n = CFArrayGetLength(axes);
|
||||||
|
out = [NSMutableDictionary new];
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
CFNumberRef key;
|
||||||
|
|
||||||
|
axis = (CFDictionaryRef) CFArrayGetValueAtIndex(axes, i);
|
||||||
|
key = (CFNumberRef) CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey);
|
||||||
|
[out setObject:[[fvarAxis alloc] initWithIndex:i dict:axis avarTable:table]
|
||||||
|
forKey:((NSNumber *) key)];
|
||||||
|
}
|
||||||
|
if (table != NULL)
|
||||||
|
CFRelease(table);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define fvarAxisKey(n) [NSNumber numberWithUnsignedInteger:k]
|
||||||
|
|
||||||
|
static BOOL tryAxis(NSDictionary *axisDict, CFDictionaryRef var, NSNumber *key, double *out)
|
||||||
|
{
|
||||||
|
fvarAxis *axis;
|
||||||
|
CFNumberRef num;
|
||||||
|
|
||||||
|
axis = (fvarAxis *) [axisDict objectForKey:key];
|
||||||
|
if (axis == nil)
|
||||||
|
return NO;
|
||||||
|
num = (CFNumberRef) CFDictionaryGetValue(var, (CFNumberRef) key);
|
||||||
|
if (num == nil)
|
||||||
|
return NO;
|
||||||
|
if (CFNumberGetValue(num, kCFNumberTypeDouble, out) == false) {
|
||||||
|
// TODO
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
*out = [axis normalize:*out];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
void processFontVariation(fontStyleData *d, NSDictionary *axisDict, uiDrawFontDescriptor *out)
|
||||||
|
{
|
||||||
|
double v;
|
||||||
|
|
||||||
|
out->Weight = uiDrawTextWeightNormal;
|
||||||
|
out->Stretch = uiDrawTextStretchNormal;
|
||||||
|
|
||||||
|
var = [d variation];
|
||||||
|
|
||||||
|
if (tryAxis(axisDict, var, fvarAxisKey(fvarWeight), &v)) {
|
||||||
|
// v is now a value between -1 and 1 scaled linearly between discrete points
|
||||||
|
// we want a linear value between 0 and 1000 with 400 being normal
|
||||||
|
if (v < 0) {
|
||||||
|
v += 1;
|
||||||
|
out->Weight = (uiDrawTextWeight) (v * 400);
|
||||||
|
} else if (v > 0)
|
||||||
|
out->Weight += (uiDrawTextWeight) (v * 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tryAxis(axisDict, var, fvarAxisKey(fvarWidth), &v)) {
|
||||||
|
// likewise, but with stretches, we go from 0 to 8 with 4 being directly between the two, so this is sufficient
|
||||||
|
v += 1;
|
||||||
|
out->Stretch = (uiDrawTextStretch) (v * 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue