| Index: src/ports/SkFontHost_mac.cpp
|
| ===================================================================
|
| --- src/ports/SkFontHost_mac.cpp (revision 8442)
|
| +++ src/ports/SkFontHost_mac.cpp (working copy)
|
| @@ -96,6 +96,10 @@
|
| CFRef fCFRef;
|
| };
|
|
|
| +static CFStringRef make_CFString(const char str[]) {
|
| + return CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8);
|
| +}
|
| +
|
| template<typename T> class AutoCGTable : SkNoncopyable {
|
| public:
|
| AutoCGTable(CGFontRef font)
|
| @@ -498,8 +502,7 @@
|
| }
|
|
|
| // Create the font info
|
| - AutoCFRelease<CFStringRef> cfFontName(
|
| - CFStringCreateWithCString(NULL, familyName, kCFStringEncodingUTF8));
|
| + AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName));
|
|
|
| AutoCFRelease<CFNumberRef> cfFontTraits(
|
| CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTraits));
|
| @@ -1913,6 +1916,18 @@
|
| return sk_float_round2int(value);
|
| }
|
|
|
| +static inline int sqr(int value) {
|
| + SkASSERT(SkAbs32(value) < 0x7FFF); // check for overflow
|
| + return value * value;
|
| +}
|
| +
|
| +// We normalize each axis (weight, width, italic) to be base-900
|
| +static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) {
|
| + return sqr(a.weight() - b.weight()) +
|
| + sqr((a.width() - b.width()) * 100) +
|
| + sqr((a.isItalic() != b.isItalic()) * 900);
|
| +}
|
| +
|
| static SkFontStyle desc2fontstyle(CTFontDescriptorRef desc) {
|
| AutoCFRelease<CFDictionaryRef> dict(
|
| (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc,
|
| @@ -2026,10 +2041,36 @@
|
| return createFromDesc(fFamilyName, desc);
|
| }
|
|
|
| + virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE {
|
| + if (0 == fCount) {
|
| + return NULL;
|
| + }
|
| + return createFromDesc(fFamilyName, findMatchingDesc(pattern));
|
| + }
|
| +
|
| private:
|
| CFArrayRef fArray;
|
| CFStringRef fFamilyName;
|
| int fCount;
|
| +
|
| + CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const {
|
| + int bestMetric = SK_MaxS32;
|
| + CTFontDescriptorRef bestDesc = NULL;
|
| +
|
| + for (int i = 0; i < fCount; ++i) {
|
| + CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, i);
|
| + int metric = compute_metric(pattern, desc2fontstyle(desc));
|
| + if (0 == metric) {
|
| + return desc;
|
| + }
|
| + if (metric < bestMetric) {
|
| + bestMetric = metric;
|
| + bestDesc = desc;
|
| + }
|
| + }
|
| + SkASSERT(bestDesc);
|
| + return bestDesc;
|
| + }
|
| };
|
|
|
| class SkFontMgr_Mac : public SkFontMgr {
|
| @@ -2048,6 +2089,19 @@
|
| }
|
| }
|
|
|
| + static SkFontStyleSet* CreateSet(CFStringRef cfFamilyName) {
|
| + AutoCFRelease<CFMutableDictionaryRef> cfAttr(
|
| + CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
|
| + &kCFTypeDictionaryKeyCallBacks,
|
| + &kCFTypeDictionaryValueCallBacks));
|
| +
|
| + CFDictionaryAddValue(cfAttr, kCTFontFamilyNameAttribute, cfFamilyName);
|
| +
|
| + AutoCFRelease<CTFontDescriptorRef> desc(
|
| + CTFontDescriptorCreateWithAttributes(cfAttr));
|
| + return SkNEW_ARGS(SkFontStyleSet_Mac, (cfFamilyName, desc));
|
| + }
|
| +
|
| public:
|
| SkFontMgr_Mac() : fCount(0), fNames(NULL) {}
|
|
|
| @@ -2075,20 +2129,14 @@
|
| if ((unsigned)index >= (unsigned)fCount) {
|
| return NULL;
|
| }
|
| -
|
| - AutoCFRelease<CFMutableDictionaryRef> cfAttr(
|
| - CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
|
| - &kCFTypeDictionaryKeyCallBacks,
|
| - &kCFTypeDictionaryValueCallBacks));
|
| -
|
| - CFDictionaryAddValue(cfAttr, kCTFontFamilyNameAttribute,
|
| - this->stringAt(index));
|
| -
|
| - AutoCFRelease<CTFontDescriptorRef> desc(
|
| - CTFontDescriptorCreateWithAttributes(cfAttr));
|
| - return SkNEW_ARGS(SkFontStyleSet_Mac, (this->stringAt(index), desc));
|
| + return CreateSet(this->stringAt(index));
|
| }
|
| -
|
| +
|
| + virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE {
|
| + AutoCFRelease<CFStringRef> cfName(make_CFString(familyName));
|
| + return CreateSet(cfName);
|
| + }
|
| +
|
| virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
|
| const SkFontStyle&) SK_OVERRIDE {
|
| return NULL;
|
|
|