Index: src/ports/SkFontHost_mac.cpp |
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp |
index 4e573541ca2780b2a9383a9e471a1cb294317e58..aae7464e2516e6d8608ab0ea1ceb18aee98371f5 100755 |
--- a/src/ports/SkFontHost_mac.cpp |
+++ b/src/ports/SkFontHost_mac.cpp |
@@ -6,6 +6,7 @@ |
* found in the LICENSE file. |
*/ |
+#include <vector> |
#ifdef SK_BUILD_FOR_MAC |
#import <ApplicationServices/ApplicationServices.h> |
#endif |
@@ -351,70 +352,20 @@ |
/////////////////////////////////////////////////////////////////////////////// |
-static bool find_dict_traits(CFDictionaryRef dict, CTFontSymbolicTraits* traits) { |
- CFNumberRef num; |
- return CFDictionaryGetValueIfPresent(dict, kCTFontSymbolicTrait, (const void**)&num) |
- && CFNumberIsFloatType(num) |
- && CFNumberGetValue(num, kCFNumberSInt32Type, traits); |
-} |
- |
-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 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 fontstyle_from_descriptor(CTFontDescriptorRef desc, bool* isFixedPitch) { |
- AutoCFRelease<CFDictionaryRef> dict( |
- (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute)); |
- if (NULL == dict.get()) { |
- return SkFontStyle(); |
- } |
- |
- CTFontSymbolicTraits traits; |
- if (!find_dict_traits(dict, &traits)) { |
- traits = 0; |
+static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isFixedPitch) { |
+ unsigned style = SkTypeface::kNormal; |
+ CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font); |
+ |
+ if (traits & kCTFontBoldTrait) { |
+ style |= SkTypeface::kBold; |
+ } |
+ if (traits & kCTFontItalicTrait) { |
+ style |= SkTypeface::kItalic; |
} |
if (isFixedPitch) { |
- *isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait); |
- } |
- |
- float weight, width, slant; |
- if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { |
- weight = (traits & kCTFontBoldTrait) ? 0.5f : 0; |
- } |
- if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { |
- width = 0; |
- } |
- if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) { |
- slant = (traits & kCTFontItalicTrait) ? 0.5f : 0; |
- } |
- |
- return SkFontStyle(unit_weight_to_fontstyle(weight), |
- unit_width_to_fontstyle(width), |
- slant ? SkFontStyle::kItalic_Slant |
- : SkFontStyle::kUpright_Slant); |
+ *isFixedPitch = (traits & kCTFontMonoSpaceTrait) != 0; |
+ } |
+ return (SkTypeface::Style)style; |
} |
static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { |
@@ -445,22 +396,56 @@ |
return id; |
} |
+static SkFontStyle stylebits2fontstyle(SkTypeface::Style styleBits) { |
+ return SkFontStyle((styleBits & SkTypeface::kBold) |
+ ? SkFontStyle::kBold_Weight |
+ : SkFontStyle::kNormal_Weight, |
+ SkFontStyle::kNormal_Width, |
+ (styleBits & SkTypeface::kItalic) |
+ ? SkFontStyle::kItalic_Slant |
+ : SkFontStyle::kUpright_Slant); |
+} |
+ |
#define WEIGHT_THRESHOLD ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_Weight)/2) |
+ |
+static SkTypeface::Style fontstyle2stylebits(const SkFontStyle& fs) { |
+ unsigned style = 0; |
+ if (fs.width() >= WEIGHT_THRESHOLD) { |
+ style |= SkTypeface::kBold; |
+ } |
+ if (fs.isItalic()) { |
+ style |= SkTypeface::kItalic; |
+ } |
+ return (SkTypeface::Style)style; |
+} |
class SkTypeface_Mac : public SkTypeface { |
public: |
- SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch, |
+ SkTypeface_Mac(SkTypeface::Style style, SkFontID fontID, bool isFixedPitch, |
CTFontRef fontRef, const char name[], bool isLocalStream) |
- : SkTypeface(fs, fontID, isFixedPitch) |
+ : SkTypeface(style, fontID, isFixedPitch) |
, fName(name) |
, fFontRef(fontRef) // caller has already called CFRetain for us |
+ , fFontStyle(stylebits2fontstyle(style)) |
, fIsLocalStream(isLocalStream) |
{ |
SkASSERT(fontRef); |
} |
+ SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch, |
+ CTFontRef fontRef, const char name[], bool isLocalStream) |
+ : SkTypeface(fontstyle2stylebits(fs), fontID, isFixedPitch) |
+ , fName(name) |
+ , fFontRef(fontRef) // caller has already called CFRetain for us |
+ , fFontStyle(fs) |
+ , fIsLocalStream(isLocalStream) |
+ { |
+ SkASSERT(fontRef); |
+ } |
+ |
SkString fName; |
AutoCFRelease<CTFontRef> fFontRef; |
+ SkFontStyle fFontStyle; |
protected: |
friend class SkFontHost; // to access our protected members for deprecated methods |
@@ -491,25 +476,22 @@ |
static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isLocalStream) { |
SkASSERT(fontRef); |
bool isFixedPitch; |
- AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(fontRef)); |
- SkFontStyle style = fontstyle_from_descriptor(desc, &isFixedPitch); |
+ SkTypeface::Style style = computeStyleBits(fontRef, &isFixedPitch); |
SkFontID fontID = CTFontRef_to_SkFontID(fontRef); |
return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLocalStream); |
} |
-static SkTypeface* NewFromName(const char familyName[], const SkFontStyle& theStyle) { |
+static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theStyle) { |
CTFontRef ctFont = NULL; |
CTFontSymbolicTraits ctFontTraits = 0; |
- if (theStyle.weight() >= SkFontStyle::kBold_Weight) { |
+ if (theStyle & SkTypeface::kBold) { |
ctFontTraits |= kCTFontBoldTrait; |
} |
- if (theStyle.slant() != SkFontStyle::kUpright_Slant) { |
+ if (theStyle & SkTypeface::kItalic) { |
ctFontTraits |= kCTFontItalicTrait; |
} |
- |
- //TODO: add weight width slant |
// Create the font info |
AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName)); |
@@ -552,8 +534,8 @@ |
static SkTypeface* gDefaultFace; |
if (NULL == gDefaultFace) { |
- gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkFontStyle()); |
- SkTypefaceCache::Add(gDefaultFace, SkFontStyle()); |
+ gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkTypeface::kNormal); |
+ SkTypefaceCache::Add(gDefaultFace, SkTypeface::kNormal); |
} |
return gDefaultFace; |
} |
@@ -576,7 +558,7 @@ |
face->ref(); |
} else { |
face = NewFromFontRef(fontRef, NULL, false); |
- SkTypefaceCache::Add(face, face->fontStyle()); |
+ SkTypefaceCache::Add(face, face->style()); |
// NewFromFontRef doesn't retain the parameter, but the typeface it |
// creates does release it in its destructor, so we balance that with |
// a retain call here. |
@@ -588,10 +570,11 @@ |
struct NameStyleRec { |
const char* fName; |
- SkFontStyle fStyle; |
+ SkTypeface::Style fStyle; |
}; |
-static bool FindByNameStyle(SkTypeface* face, const SkFontStyle& style, void* ctx) { |
+static bool FindByNameStyle(SkTypeface* face, SkTypeface::Style style, |
+ void* ctx) { |
const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face); |
const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx); |
@@ -614,6 +597,39 @@ |
} |
} |
return name; // no change |
+} |
+ |
+static SkTypeface* create_typeface(const SkTypeface* familyFace, |
+ const char familyName[], |
+ SkTypeface::Style style) { |
+ if (familyName) { |
+ familyName = map_css_names(familyName); |
+ } |
+ |
+ // Clone an existing typeface |
+ // TODO: only clone if style matches the familyFace's style... |
+ if (familyName == NULL && familyFace != NULL) { |
+ familyFace->ref(); |
+ return const_cast<SkTypeface*>(familyFace); |
+ } |
+ |
+ if (!familyName || !*familyName) { |
+ familyName = FONT_DEFAULT_NAME; |
+ } |
+ |
+ NameStyleRec rec = { familyName, style }; |
+ SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByNameStyle, &rec); |
+ |
+ if (NULL == face) { |
+ face = NewFromName(familyName, style); |
+ if (face) { |
+ SkTypefaceCache::Add(face, style); |
+ } else { |
+ face = GetDefaultFace(); |
+ face->ref(); |
+ } |
+ } |
+ return face; |
} |
/////////////////////////////////////////////////////////////////////////////// |
@@ -1992,6 +2008,7 @@ |
/////////////////////////////////////////////////////////////////////////////// |
/////////////////////////////////////////////////////////////////////////////// |
+#if 1 |
static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString* value) { |
AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name)); |
@@ -2002,7 +2019,34 @@ |
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); |
+} |
+ |
#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 inline int sqr(int value) { |
SkASSERT(SkAbs32(value) < 0x7FFF); // check for overflow |
@@ -2016,25 +2060,53 @@ |
sqr((a.isItalic() != b.isItalic()) * 900); |
} |
+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); |
+} |
+ |
struct NameFontStyleRec { |
SkString fFamilyName; |
SkFontStyle fFontStyle; |
}; |
-static bool nameFontStyleProc(SkTypeface* face, const SkFontStyle&, void* ctx) { |
+static bool nameFontStyleProc(SkTypeface* face, SkTypeface::Style, |
+ void* ctx) { |
SkTypeface_Mac* macFace = (SkTypeface_Mac*)face; |
const NameFontStyleRec* rec = (const NameFontStyleRec*)ctx; |
- return macFace->fontStyle() == rec->fFontStyle && |
+ return macFace->fFontStyle == rec->fFontStyle && |
macFace->fName == rec->fFamilyName; |
} |
-static SkTypeface* createFromDesc(CFStringRef cfFamilyName, CTFontDescriptorRef desc) { |
+static SkTypeface* createFromDesc(CFStringRef cfFamilyName, |
+ CTFontDescriptorRef desc) { |
NameFontStyleRec rec; |
CFStringToSkString(cfFamilyName, &rec.fFamilyName); |
- rec.fFontStyle = fontstyle_from_descriptor(desc, NULL); |
- |
- SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc, &rec); |
+ rec.fFontStyle = desc2fontstyle(desc); |
+ |
+ SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc, |
+ &rec); |
if (face) { |
return face; |
} |
@@ -2055,13 +2127,12 @@ |
CFStringToSkString(cfFamilyName, &str); |
bool isFixedPitch; |
- AutoCFRelease<CTFontDescriptorRef> ctFontDesc(CTFontCopyFontDescriptor(ctFont)); |
- (void)fontstyle_from_descriptor(ctFontDesc, &isFixedPitch); |
+ (void)computeStyleBits(ctFont, &isFixedPitch); |
SkFontID fontID = CTFontRef_to_SkFontID(ctFont); |
face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch, |
ctFont, str.c_str(), false)); |
- SkTypefaceCache::Add(face, face->fontStyle()); |
+ SkTypefaceCache::Add(face, face->style()); |
return face; |
} |
@@ -2087,11 +2158,12 @@ |
return fCount; |
} |
- virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVERRIDE { |
+ virtual void getStyle(int index, SkFontStyle* style, |
+ SkString* name) SK_OVERRIDE { |
SkASSERT((unsigned)index < (unsigned)fCount); |
CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index); |
if (style) { |
- *style = fontstyle_from_descriptor(desc, NULL); |
+ *style = desc2fontstyle(desc); |
} |
if (name) { |
if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) { |
@@ -2125,7 +2197,7 @@ |
for (int i = 0; i < fCount; ++i) { |
CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, i); |
- int metric = compute_metric(pattern, fontstyle_from_descriptor(desc, NULL)); |
+ int metric = compute_metric(pattern, desc2fontstyle(desc)); |
if (0 == metric) { |
return desc; |
} |
@@ -2205,7 +2277,8 @@ |
return NULL; |
} |
- virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE { |
+ virtual SkTypeface* onCreateFromData(SkData* data, |
+ int ttcIndex) const SK_OVERRIDE { |
AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(data)); |
if (NULL == pr) { |
return NULL; |
@@ -2213,7 +2286,8 @@ |
return create_from_dataProvider(pr); |
} |
- virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE { |
+ virtual SkTypeface* onCreateFromStream(SkStream* stream, |
+ int ttcIndex) const SK_OVERRIDE { |
AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(stream)); |
if (NULL == pr) { |
return NULL; |
@@ -2221,7 +2295,8 @@ |
return create_from_dataProvider(pr); |
} |
- virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { |
+ virtual SkTypeface* onCreateFromFile(const char path[], |
+ int ttcIndex) const SK_OVERRIDE { |
AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path)); |
if (NULL == pr) { |
return NULL; |
@@ -2231,29 +2306,7 @@ |
virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
unsigned styleBits) const SK_OVERRIDE { |
- |
- SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits); |
- if (familyName) { |
- familyName = map_css_names(familyName); |
- } |
- |
- if (!familyName || !*familyName) { |
- familyName = FONT_DEFAULT_NAME; |
- } |
- |
- NameStyleRec rec = { familyName, style }; |
- SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByNameStyle, &rec); |
- |
- if (NULL == face) { |
- face = NewFromName(familyName, style); |
- if (face) { |
- SkTypefaceCache::Add(face, style); |
- } else { |
- face = GetDefaultFace(); |
- face->ref(); |
- } |
- } |
- return face; |
+ return create_typeface(NULL, familyName, (SkTypeface::Style)styleBits); |
} |
}; |
@@ -2262,3 +2315,4 @@ |
SkFontMgr* SkFontMgr::Factory() { |
return SkNEW(SkFontMgr_Mac); |
} |
+#endif |