| Index: src/ports/SkFontHost_mac.cpp
|
| ===================================================================
|
| --- src/ports/SkFontHost_mac.cpp (revision 8387)
|
| +++ src/ports/SkFontHost_mac.cpp (working copy)
|
| @@ -1823,24 +1823,178 @@
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| ///////////////////////////////////////////////////////////////////////////////
|
| +#if 1
|
|
|
| -#if 1
|
| +static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString* value) {
|
| + AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name));
|
| + if (NULL == ref.get()) {
|
| + return false;
|
| + }
|
| + CFStringToSkString(ref, value);
|
| + return true;
|
| +}
|
| +
|
| +static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value) {
|
| + CFNumberRef num;
|
| + return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num)
|
| + && CFNumberIsFloatType(num)
|
| + && CFNumberGetValue(num, kCFNumberFloatType, value);
|
| +}
|
| +
|
| +static SkTypeface* createFromDesc(CFStringRef cfFamilyName,
|
| + CTFontDescriptorRef desc) {
|
| + AutoCFRelease<CTFontRef> ctNamed(CTFontCreateWithName(cfFamilyName, 1, NULL));
|
| + CTFontRef ctFont = CTFontCreateCopyWithAttributes(ctNamed, 1, NULL, desc);
|
| +
|
| + SkString str;
|
| + CFStringToSkString(cfFamilyName, &str);
|
| + return ctFont ? NewFromFontRef(ctFont, str.c_str()) : NULL;
|
| +}
|
| +
|
| #include "SkFontMgr.h"
|
|
|
| +static int unit_weight_to_fontstyle(float unit) {
|
| + float value;
|
| + if (unit < 0) {
|
| + value = 100 + (1 + unit) * 300;
|
| + } else {
|
| + value = 400 + unit * 500;
|
| + }
|
| + return sk_float_round2int(value);
|
| +}
|
| +
|
| +static int unit_width_to_fontstyle(float unit) {
|
| + float value;
|
| + if (unit < 0) {
|
| + value = 1 + (1 + unit) * 4;
|
| + } else {
|
| + value = 5 + unit * 4;
|
| + }
|
| + return sk_float_round2int(value);
|
| +}
|
| +
|
| +static SkFontStyle desc2fontstyle(CTFontDescriptorRef desc) {
|
| + AutoCFRelease<CFDictionaryRef> dict(
|
| + (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc,
|
| + kCTFontTraitsAttribute));
|
| + if (NULL == dict.get()) {
|
| + return SkFontStyle();
|
| + }
|
| +
|
| + float weight, width, slant;
|
| + if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) {
|
| + weight = 0;
|
| + }
|
| + if (!find_dict_float(dict, kCTFontWidthTrait, &width)) {
|
| + width = 0;
|
| + }
|
| + if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) {
|
| + slant = 0;
|
| + }
|
| +
|
| + return SkFontStyle(unit_weight_to_fontstyle(weight),
|
| + unit_width_to_fontstyle(width),
|
| + slant ? SkFontStyle::kItalic_Slant
|
| + : SkFontStyle::kUpright_Slant);
|
| +}
|
| +
|
| +class SkFontStyleSet_Mac : public SkFontStyleSet {
|
| +public:
|
| + SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc)
|
| + : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, NULL))
|
| + , fFamilyName(familyName) {
|
| + CFRetain(familyName);
|
| + }
|
| +
|
| + virtual ~SkFontStyleSet_Mac() {
|
| + CFSafeRelease(fArray);
|
| + CFRelease(fFamilyName);
|
| + }
|
| +
|
| + virtual int count() SK_OVERRIDE {
|
| + return CFArrayGetCount(fArray);
|
| + }
|
| +
|
| + virtual void getStyle(int index, SkFontStyle* style,
|
| + SkString* name) SK_OVERRIDE {
|
| + SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray));
|
| + CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index);
|
| + if (style) {
|
| + *style = desc2fontstyle(desc);
|
| + }
|
| + if (name) {
|
| + if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) {
|
| + name->reset();
|
| + }
|
| + }
|
| + }
|
| +
|
| + virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
|
| + SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray));
|
| + CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index);
|
| + return createFromDesc(fFamilyName, desc);
|
| + }
|
| +
|
| +private:
|
| + CFArrayRef fArray;
|
| + CFStringRef fFamilyName;
|
| +};
|
| +
|
| class SkFontMgr_Mac : public SkFontMgr {
|
| + int fCount;
|
| + CFArrayRef fNames;
|
| +
|
| + CFStringRef stringAt(int index) const {
|
| + SkASSERT((unsigned)index < (unsigned)fCount);
|
| + return (CFStringRef)CFArrayGetValueAtIndex(fNames, index);
|
| + }
|
| +
|
| + void lazyInit() {
|
| + if (NULL == fNames) {
|
| + fNames = CTFontManagerCopyAvailableFontFamilyNames();
|
| + fCount = fNames ? CFArrayGetCount(fNames) : 0;
|
| + }
|
| + }
|
| +
|
| public:
|
| - SkFontMgr_Mac() {}
|
| + SkFontMgr_Mac() : fCount(0), fNames(NULL) {}
|
|
|
| + virtual ~SkFontMgr_Mac() {
|
| + CFSafeRelease(fNames);
|
| + }
|
| +
|
| protected:
|
| virtual int onCountFamilies() SK_OVERRIDE {
|
| - return 0;
|
| + this->lazyInit();
|
| + return fCount;
|
| }
|
|
|
| virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE {
|
| + this->lazyInit();
|
| + if ((unsigned)index < (unsigned)fCount) {
|
| + CFStringToSkString(this->stringAt(index), familyName);
|
| + } else {
|
| + familyName->reset();
|
| + }
|
| }
|
|
|
| virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE {
|
| - return NULL;
|
| + this->lazyInit();
|
| + 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));
|
| }
|
|
|
| virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
|
|
|