diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkFontHost.cpp | 62 | ||||
-rwxr-xr-x | src/ports/SkFontHost_mac.cpp | 162 |
2 files changed, 220 insertions, 4 deletions
diff --git a/src/core/SkFontHost.cpp b/src/core/SkFontHost.cpp index 4f0dc8637d..9aff12cf49 100644 --- a/src/core/SkFontHost.cpp +++ b/src/core/SkFontHost.cpp @@ -46,3 +46,65 @@ SkFontHost::LCDOrder SkFontHost::GetSubpixelOrder() { void SkFontHost::SetSubpixelOrder(LCDOrder order) { SkFontLCDConfig::SetSubpixelOrder((SkFontLCDConfig::LCDOrder)order); } + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#include "SkFontMgr.h" + +SkFontStyle::SkFontStyle() { + fUnion.fU32 = 0; + fUnion.fR.fWeight = kNormal_Weight; + fUnion.fR.fWidth = kNormal_Width; + fUnion.fR.fSlant = kUpright_Slant; +} + +SkFontStyle::SkFontStyle(int weight, int width, Slant slant) { + fUnion.fU32 = 0; + fUnion.fR.fWeight = SkPin32(weight, kThin_Weight, kBlack_Weight); + fUnion.fR.fWidth = SkPin32(width, kUltraCondensed_Width, kUltaExpanded_Width); + fUnion.fR.fSlant = kUpright_Slant; +} + +int SkFontMgr::countFamilies() { + return this->onCountFamilies(); +} + +void SkFontMgr::getFamilyName(int index, SkString* familyName) { + this->onGetFamilyName(index, familyName); +} + +SkFontStyleSet* SkFontMgr::createStyleSet(int index) { + return this->onCreateStyleSet(index); +} + +SkTypeface* SkFontMgr::matchFamilyStyle(const char familyName[], + const SkFontStyle& fs) { + return this->onMatchFamilyStyle(familyName, fs); +} + +SkTypeface* SkFontMgr::matchFaceStyle(const SkTypeface* face, + const SkFontStyle& fs) { + return this->matchFaceStyle(face, fs); +} + +SkTypeface* SkFontMgr::createFromData(SkData* data, int ttcIndex) { + return this->onCreateFromData(data, ttcIndex); +} + +SkTypeface* SkFontMgr::createFromStream(SkStream* stream, int ttcIndex) { + return this->onCreateFromStream(stream, ttcIndex); +} + +SkTypeface* SkFontMgr::createFromFile(const char path[], int ttcIndex) { + return this->onCreateFromFile(path, ttcIndex); +} + +SkFontMgr* SkFontMgr::RefDefault() { + static SkFontMgr* gFM; + if (NULL == gFM) { + gFM = SkFontMgr::Factory(); + } + return SkRef(gFM); +} + diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index f67b9f9c27..ce4c669de9 100755 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -1823,24 +1823,178 @@ void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc, /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// - #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[], |