Migrated the font matchng stuff on OS X.

This commit is contained in:
Pietro Gagliardi 2018-03-04 18:01:08 -05:00
parent d8ad3300c9
commit 0b3176cead
6 changed files with 91 additions and 93 deletions

View File

@ -1,10 +1,5 @@
// 4 march 2018
// fontmatch.m
extern CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd);
extern CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uiOpenTypeFeatures *otf);
extern void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc);
// attrstr.m
extern void initUnderlineColors(void);
extern void uninitUnderlineColors(void);

View File

@ -1,61 +0,0 @@
// 3 november 2017
// fontmatch.m
@interface fontStyleData : NSObject {
CTFontRef font;
CTFontDescriptorRef desc;
CFDictionaryRef traits;
CTFontSymbolicTraits symbolic;
double weight;
double width;
BOOL didStyleName;
CFStringRef styleName;
BOOL didVariation;
CFDictionaryRef variation;
BOOL hasRegistrationScope;
CTFontManagerScope registrationScope;
BOOL didPostScriptName;
CFStringRef postScriptName;
CTFontFormat fontFormat;
BOOL didPreferredSubFamilyName;
CFStringRef preferredSubFamilyName;
BOOL didSubFamilyName;
CFStringRef subFamilyName;
BOOL didFullName;
CFStringRef fullName;
BOOL didPreferredFamilyName;
CFStringRef preferredFamilyName;
BOOL didFamilyName;
CFStringRef familyName;
BOOL didVariationAxes;
CFArrayRef variationAxes;
}
- (id)initWithFont:(CTFontRef)f;
- (id)initWithDescriptor:(CTFontDescriptorRef)d;
- (BOOL)prepare;
- (void)ensureFont;
- (CTFontSymbolicTraits)symbolicTraits;
- (double)weight;
- (double)width;
- (CFStringRef)styleName;
- (CFDictionaryRef)variation;
- (BOOL)hasRegistrationScope;
- (CTFontManagerScope)registrationScope;
- (CFStringRef)postScriptName;
- (CFDataRef)table:(CTFontTableTag)tag;
- (CTFontFormat)fontFormat;
- (CFStringRef)fontName:(CFStringRef)key;
- (CFStringRef)preferredSubFamilyName;
- (CFStringRef)subFamilyName;
- (CFStringRef)fullName;
- (CFStringRef)preferredFamilyName;
- (CFStringRef)familyName;
- (CFArrayRef)variationAxes;
@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);

View File

@ -7,3 +7,66 @@ extern CFArrayRef uiprivOpenTypeFeaturesToCTFeatures(const uiOpenTypeFeatures *o
// aat.m
typedef void (^uiprivAATBlock)(uint16_t type, uint16_t selector);
extern void uiprivOpenTypeToAAT(char a, char b, char c, char d, uint32_t value, uiprivAATBlock f);
// fontmatch.m
@interface uiprivFontStyleData : NSObject {
CTFontRef font;
CTFontDescriptorRef desc;
CFDictionaryRef traits;
CTFontSymbolicTraits symbolic;
double weight;
double width;
BOOL didStyleName;
CFStringRef styleName;
BOOL didVariation;
CFDictionaryRef variation;
BOOL hasRegistrationScope;
CTFontManagerScope registrationScope;
BOOL didPostScriptName;
CFStringRef postScriptName;
CTFontFormat fontFormat;
BOOL didPreferredSubFamilyName;
CFStringRef preferredSubFamilyName;
BOOL didSubFamilyName;
CFStringRef subFamilyName;
BOOL didFullName;
CFStringRef fullName;
BOOL didPreferredFamilyName;
CFStringRef preferredFamilyName;
BOOL didFamilyName;
CFStringRef familyName;
BOOL didVariationAxes;
CFArrayRef variationAxes;
}
- (id)initWithFont:(CTFontRef)f;
- (id)initWithDescriptor:(CTFontDescriptorRef)d;
- (BOOL)prepare;
- (void)ensureFont;
- (CTFontSymbolicTraits)symbolicTraits;
- (double)weight;
- (double)width;
- (CFStringRef)styleName;
- (CFDictionaryRef)variation;
- (BOOL)hasRegistrationScope;
- (CTFontManagerScope)registrationScope;
- (CFStringRef)postScriptName;
- (CFDataRef)table:(CTFontTableTag)tag;
- (CTFontFormat)fontFormat;
- (CFStringRef)fontName:(CFStringRef)key;
- (CFStringRef)preferredSubFamilyName;
- (CFStringRef)subFamilyName;
- (CFStringRef)fullName;
- (CFStringRef)preferredFamilyName;
- (CFStringRef)familyName;
- (CFArrayRef)variationAxes;
@end
extern CTFontDescriptorRef uiprivDrawFontDescriptorToCTFontDescriptor(uiDrawFontDescriptor *fd);
extern CTFontDescriptorRef uiprivCTFontDescriptorAppendFeatures(CTFontDescriptorRef desc, const uiOpenTypeFeatures *otf);
extern void uiprivDrawFontDescriptorFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc);
// fonttraits.m
extern void uiprivProcessFontTraits(uiprivFontStyleData *d, uiDrawFontDescriptor *out);
// fontvariation.m
extern NSDictionary *uiprivMakeVariationAxisDict(CFArrayRef axes, CFDataRef avarTable);
extern void uiprivProcessFontVariation(uiprivFontStyleData *d, NSDictionary *axisDict, uiDrawFontDescriptor *out);

View File

@ -1,6 +1,6 @@
// 3 january 2017
#import "uipriv_darwin.h"
#import "fontstyle.h"
#import "attrstr.h"
// Core Text exposes font style info in two forms:
// - Fonts with a QuickDraw GX font variation (fvar) table, a feature
@ -26,7 +26,7 @@
// because the descriptors returned by Core Text's own font
// matching won't have any.
@implementation fontStyleData
@implementation uiprivFontStyleData
- (id)initWithFont:(CTFontRef)f
{
@ -294,7 +294,7 @@ static const double *italicClosenesses[] = {
// Core Text doesn't seem to differentiate between Italic and Oblique.
// Pango's Core Text code just does a g_strrstr() (backwards case-sensitive search) for "Oblique" in the font's style name (see https://git.gnome.org/browse/pango/tree/pango/pangocoretext-fontmap.c); let's do that too I guess
static uiDrawTextItalic guessItalicOblique(fontStyleData *d)
static uiDrawTextItalic guessItalicOblique(uiprivFontStyleData *d)
{
CFStringRef styleName;
BOOL isOblique;
@ -318,20 +318,20 @@ static uiDrawTextItalic guessItalicOblique(fontStyleData *d)
// However, Core Text does seem to guarantee (from experimentation; see below) that the slant will be nonzero if and only if the italic bit is set, so we don't need to use the slant value.
// Core Text also seems to guarantee that if a font lists itself as Italic or Oblique by name (font subfamily name, font style name, whatever), it will also have that bit set, so testing this bit does cover all fonts that name themselves as Italic and Oblique. (Again, this is from the below experimentation.)
// TODO there is still one catch that might matter from a user's POV: the reverse is not true the italic bit can be set even if the style of the font face/subfamily/style isn't named as Italic (for example, script typefaces like Adobe's Palace Script MT Std); I don't know what to do about this... I know how to start: find a script font that has an italic form (Adobe's Palace Script MT Std does not; only Regular and Semibold)
static void setItalic(fontStyleData *d, uiDrawFontDescriptor *out)
static void setItalic(uiprivFontStyleData *d, uiDrawFontDescriptor *out)
{
out->Italic = uiDrawTextItalicNormal;
if (([d symbolicTraits] & kCTFontItalicTrait) != 0)
out->Italic = guessItalicOblique(d);
}
static void fillDescStyleFields(fontStyleData *d, NSDictionary *axisDict, uiDrawFontDescriptor *out)
static void fillDescStyleFields(uiprivFontStyleData *d, NSDictionary *axisDict, uiDrawFontDescriptor *out)
{
setItalic(d, out);
if (axisDict != nil)
processFontVariation(d, axisDict, out);
uiprivProcessFontVariation(d, axisDict, out);
else
processFontTraits(d, out);
uiprivProcessFontTraits(d, out);
}
static CTFontDescriptorRef matchStyle(CTFontDescriptorRef against, uiDrawFontDescriptor *styles)
@ -341,7 +341,7 @@ static CTFontDescriptorRef matchStyle(CTFontDescriptorRef against, uiDrawFontDes
struct closeness *closeness;
CTFontDescriptorRef current;
CTFontDescriptorRef out;
fontStyleData *d;
uiprivFontStyleData *d;
NSDictionary *axisDict;
matching = CTFontDescriptorCreateMatchingFontDescriptors(against, NULL);
@ -356,10 +356,10 @@ static CTFontDescriptorRef matchStyle(CTFontDescriptorRef against, uiDrawFontDes
}
current = (CTFontDescriptorRef) CFArrayGetValueAtIndex(matching, 0);
d = [[fontStyleData alloc] initWithDescriptor:current];
d = [[uiprivFontStyleData alloc] initWithDescriptor:current];
axisDict = nil;
if ([d variation] != NULL)
axisDict = mkVariationAxisDict([d variationAxes], [d table:kCTFontTableAvar]);
axisDict = uiprivMakeVariationAxisDict([d variationAxes], [d table:kCTFontTableAvar]);
closeness = (struct closeness *) uiAlloc(n * sizeof (struct closeness), "struct closeness[]");
for (i = 0; i < n; i++) {
@ -368,7 +368,7 @@ static CTFontDescriptorRef matchStyle(CTFontDescriptorRef against, uiDrawFontDes
closeness[i].index = i;
if (i != 0) {
current = (CTFontDescriptorRef) CFArrayGetValueAtIndex(matching, i);
d = [[fontStyleData alloc] initWithDescriptor:current];
d = [[uiprivFontStyleData alloc] initWithDescriptor:current];
}
fillDescStyleFields(d, axisDict, &fields);
closeness[i].weight = fields.Weight - styles->Weight;
@ -413,7 +413,7 @@ static CTFontDescriptorRef matchStyle(CTFontDescriptorRef against, uiDrawFontDes
return out;
}
CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd)
CTFontDescriptorRef uiprivDrawFontDescriptorToCTFontDescriptor(uiDrawFontDescriptor *fd)
{
CFMutableDictionaryRef attrs;
CFStringRef cffamily;
@ -443,7 +443,7 @@ CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd)
}
// fortunately features that aren't supported are simply ignored, so we can copy them all in
CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uiOpenTypeFeatures *otf)
CTFontDescriptorRef uiprivCTFontDescriptorAppendFeatures(CTFontDescriptorRef desc, const uiOpenTypeFeatures *otf)
{
CTFontDescriptorRef new;
CFArrayRef featuresArray;
@ -465,10 +465,10 @@ CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uiOpe
return new;
}
void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc)
void uiprivDrawFontDescriptorFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc)
{
CFStringRef cffamily;
fontStyleData *d;
uiprivFontStyleData *d;
NSDictionary *axisDict;
cffamily = (CFStringRef) CTFontDescriptorCopyAttribute(ctdesc, kCTFontFamilyNameAttribute);
@ -479,10 +479,10 @@ void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescript
uidesc->Family = uiDarwinNSStringToText((NSString *) cffamily);
CFRelease(cffamily);
d = [[fontStyleData alloc] initWithDescriptor:ctdesc];
d = [[uiprivFontStyleData alloc] initWithDescriptor:ctdesc];
axisDict = nil;
if ([d variation] != NULL)
axisDict = mkVariationAxisDict([d variationAxes], [d table:kCTFontTableAvar]);
axisDict = uiprivMakeVariationAxisDict([d variationAxes], [d table:kCTFontTableAvar]);
fillDescStyleFields(d, axisDict, uidesc);
if (axisDict != nil)
[axisDict release];

View File

@ -1,6 +1,6 @@
// 1 november 2017
#import "uipriv_darwin.h"
#import "fontstyle.h"
#import "attrstr.h"
// This is the part of the font style matching and normalization code
// that handles fonts that use a traits dictionary.
@ -19,7 +19,7 @@
// what. We'll just convert Core Text's values into libui constants
// and use those for matching.
static BOOL fontRegistered(fontStyleData *d)
static BOOL fontRegistered(uiprivFontStyleData *d)
{
if (![d hasRegistrationScope])
// header says this should be treated as the same as not registered
@ -54,7 +54,7 @@ static const CFStringRef exceptions[] = {
NULL,
};
static void trySecondaryOS2Values(fontStyleData *d, uiDrawFontDescriptor *out, BOOL *hasWeight, BOOL *hasWidth)
static void trySecondaryOS2Values(uiprivFontStyleData *d, uiDrawFontDescriptor *out, BOOL *hasWeight, BOOL *hasWidth)
{
CFDataRef os2;
uint16_t usWeightClass, usWidthClass;
@ -125,7 +125,7 @@ static BOOL testTTFOTFSubfamilyName(CFStringRef name, CFStringRef want)
(kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareNonliteral), NULL) != false;
}
static BOOL testTTFOTFSubfamilyNames(fontStyleData *d, CFStringRef want)
static BOOL testTTFOTFSubfamilyNames(uiprivFontStyleData *d, CFStringRef want)
{
switch ([d fontFormat]) {
case kCTFontFormatOpenTypePostScript:
@ -148,18 +148,18 @@ static BOOL testTTFOTFSubfamilyNames(fontStyleData *d, CFStringRef want)
}
// work around a bug in libFontRegistry.dylib
static BOOL shouldReallyBeThin(fontStyleData *d)
static BOOL shouldReallyBeThin(uiprivFontStyleData *d)
{
return testTTFOTFSubfamilyNames(d, CFSTR("W1"));
}
// work around a bug in libFontRegistry.dylib
static BOOL shouldReallyBeSemiCondensed(fontStyleData *d)
static BOOL shouldReallyBeSemiCondensed(uiprivFontStyleData *d)
{
return testTTFOTFSubfamilyNames(d, CFSTR("Semi Condensed"));
}
void processFontTraits(fontStyleData *d, uiDrawFontDescriptor *out)
void uiprivProcessFontTraits(uiprivFontStyleData *d, uiDrawFontDescriptor *out)
{
double weight, width;
BOOL hasWeight, hasWidth;

View File

@ -1,6 +1,6 @@
// 2 november 2017
#import "uipriv_darwin.h"
#import "fontstyle.h"
#import "attrstr.h"
// This is the part of the font style matching and normalization code
// that handles fonts that use the fvar table.
@ -205,6 +205,7 @@ static BOOL extractAxisDictValue(CFDictionaryRef dict, CFStringRef key, fixed161
return YES;
}
// TODO here and elsewhere: make sure all Objective-C classes and possibly also custom method names have uipriv prefixes
@interface fvarAxis : NSObject {
fixed1616 min;
fixed1616 max;
@ -262,7 +263,7 @@ fail:
@end
NSDictionary *mkVariationAxisDict(CFArrayRef axes, CFDataRef avarTable)
NSDictionary *uiprivMakeVariationAxisDict(CFArrayRef axes, CFDataRef avarTable)
{
CFDictionaryRef axis;
CFIndex i, n;
@ -304,7 +305,7 @@ static BOOL tryAxis(NSDictionary *axisDict, CFDictionaryRef var, NSNumber *key,
return YES;
}
void processFontVariation(fontStyleData *d, NSDictionary *axisDict, uiDrawFontDescriptor *out)
void uiprivProcessFontVariation(uiprivFontStyleData *d, NSDictionary *axisDict, uiDrawFontDescriptor *out)
{
CFDictionaryRef var;
double v;