aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkFontHost.cpp62
-rwxr-xr-xsrc/ports/SkFontHost_mac.cpp162
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[],