Index: src/ports/SkFontHost_mac.cpp |
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp |
index aae7464e2516e6d8608ab0ea1ceb18aee98371f5..4e573541ca2780b2a9383a9e471a1cb294317e58 100755 |
--- a/src/ports/SkFontHost_mac.cpp |
+++ b/src/ports/SkFontHost_mac.cpp |
@@ -6,7 +6,6 @@ |
* found in the LICENSE file. |
*/ |
-#include <vector> |
#ifdef SK_BUILD_FOR_MAC |
#import <ApplicationServices/ApplicationServices.h> |
#endif |
@@ -352,20 +351,70 @@ Offscreen::Offscreen() : fRGBSpace(NULL), fCG(NULL), |
/////////////////////////////////////////////////////////////////////////////// |
-static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isFixedPitch) { |
- unsigned style = SkTypeface::kNormal; |
- CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font); |
+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); |
+} |
- if (traits & kCTFontBoldTrait) { |
- style |= SkTypeface::kBold; |
+static int unit_width_to_fontstyle(float unit) { |
+ float value; |
+ if (unit < 0) { |
+ value = 1 + (1 + unit) * 4; |
+ } else { |
+ value = 5 + unit * 4; |
} |
- if (traits & kCTFontItalicTrait) { |
- style |= SkTypeface::kItalic; |
+ 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; |
} |
if (isFixedPitch) { |
- *isFixedPitch = (traits & kCTFontMonoSpaceTrait) != 0; |
+ *isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait); |
} |
- return (SkTypeface::Style)style; |
+ |
+ 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); |
} |
static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { |
@@ -396,48 +445,15 @@ static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { |
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(SkTypeface::Style style, SkFontID fontID, bool isFixedPitch, |
- CTFontRef fontRef, const char name[], bool isLocalStream) |
- : 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) |
+ : SkTypeface(fs, fontID, isFixedPitch) |
, fName(name) |
, fFontRef(fontRef) // caller has already called CFRetain for us |
- , fFontStyle(fs) |
, fIsLocalStream(isLocalStream) |
{ |
SkASSERT(fontRef); |
@@ -445,7 +461,6 @@ public: |
SkString fName; |
AutoCFRelease<CTFontRef> fFontRef; |
- SkFontStyle fFontStyle; |
protected: |
friend class SkFontHost; // to access our protected members for deprecated methods |
@@ -476,23 +491,26 @@ private: |
static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isLocalStream) { |
SkASSERT(fontRef); |
bool isFixedPitch; |
- SkTypeface::Style style = computeStyleBits(fontRef, &isFixedPitch); |
+ AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(fontRef)); |
+ SkFontStyle style = fontstyle_from_descriptor(desc, &isFixedPitch); |
SkFontID fontID = CTFontRef_to_SkFontID(fontRef); |
return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLocalStream); |
} |
-static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theStyle) { |
+static SkTypeface* NewFromName(const char familyName[], const SkFontStyle& theStyle) { |
CTFontRef ctFont = NULL; |
CTFontSymbolicTraits ctFontTraits = 0; |
- if (theStyle & SkTypeface::kBold) { |
+ if (theStyle.weight() >= SkFontStyle::kBold_Weight) { |
ctFontTraits |= kCTFontBoldTrait; |
} |
- if (theStyle & SkTypeface::kItalic) { |
+ if (theStyle.slant() != SkFontStyle::kUpright_Slant) { |
ctFontTraits |= kCTFontItalicTrait; |
} |
+ //TODO: add weight width slant |
+ |
// Create the font info |
AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName)); |
@@ -534,8 +552,8 @@ static SkTypeface* GetDefaultFace() { |
static SkTypeface* gDefaultFace; |
if (NULL == gDefaultFace) { |
- gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkTypeface::kNormal); |
- SkTypefaceCache::Add(gDefaultFace, SkTypeface::kNormal); |
+ gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkFontStyle()); |
+ SkTypefaceCache::Add(gDefaultFace, SkFontStyle()); |
} |
return gDefaultFace; |
} |
@@ -558,7 +576,7 @@ SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef) { |
face->ref(); |
} else { |
face = NewFromFontRef(fontRef, NULL, false); |
- SkTypefaceCache::Add(face, face->style()); |
+ SkTypefaceCache::Add(face, face->fontStyle()); |
// 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. |
@@ -570,11 +588,10 @@ SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef) { |
struct NameStyleRec { |
const char* fName; |
- SkTypeface::Style fStyle; |
+ SkFontStyle fStyle; |
}; |
-static bool FindByNameStyle(SkTypeface* face, SkTypeface::Style style, |
- void* ctx) { |
+static bool FindByNameStyle(SkTypeface* face, const SkFontStyle& style, void* ctx) { |
const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face); |
const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx); |
@@ -599,39 +616,6 @@ static const char* map_css_names(const char* name) { |
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; |
-} |
- |
/////////////////////////////////////////////////////////////////////////////// |
/** GlyphRect is in FUnits (em space, y up). */ |
@@ -2008,7 +1992,6 @@ int SkTypeface_Mac::onCountGlyphs() const { |
/////////////////////////////////////////////////////////////////////////////// |
/////////////////////////////////////////////////////////////////////////////// |
-#if 1 |
static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString* value) { |
AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name)); |
@@ -2019,35 +2002,8 @@ static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString* |
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 |
return value * value; |
@@ -2060,53 +2016,25 @@ static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) { |
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, SkTypeface::Style, |
- void* ctx) { |
+static bool nameFontStyleProc(SkTypeface* face, const SkFontStyle&, void* ctx) { |
SkTypeface_Mac* macFace = (SkTypeface_Mac*)face; |
const NameFontStyleRec* rec = (const NameFontStyleRec*)ctx; |
- return macFace->fFontStyle == rec->fFontStyle && |
+ return macFace->fontStyle() == 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 = desc2fontstyle(desc); |
+ rec.fFontStyle = fontstyle_from_descriptor(desc, NULL); |
- SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc, |
- &rec); |
+ SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc, &rec); |
if (face) { |
return face; |
} |
@@ -2127,12 +2055,13 @@ static SkTypeface* createFromDesc(CFStringRef cfFamilyName, |
CFStringToSkString(cfFamilyName, &str); |
bool isFixedPitch; |
- (void)computeStyleBits(ctFont, &isFixedPitch); |
+ AutoCFRelease<CTFontDescriptorRef> ctFontDesc(CTFontCopyFontDescriptor(ctFont)); |
+ (void)fontstyle_from_descriptor(ctFontDesc, &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->style()); |
+ SkTypefaceCache::Add(face, face->fontStyle()); |
return face; |
} |
@@ -2158,12 +2087,11 @@ public: |
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 = desc2fontstyle(desc); |
+ *style = fontstyle_from_descriptor(desc, NULL); |
} |
if (name) { |
if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) { |
@@ -2197,7 +2125,7 @@ private: |
for (int i = 0; i < fCount; ++i) { |
CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, i); |
- int metric = compute_metric(pattern, desc2fontstyle(desc)); |
+ int metric = compute_metric(pattern, fontstyle_from_descriptor(desc, NULL)); |
if (0 == metric) { |
return desc; |
} |
@@ -2277,8 +2205,7 @@ protected: |
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; |
@@ -2286,8 +2213,7 @@ protected: |
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; |
@@ -2295,8 +2221,7 @@ protected: |
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; |
@@ -2306,7 +2231,29 @@ protected: |
virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
unsigned styleBits) const SK_OVERRIDE { |
- return create_typeface(NULL, familyName, (SkTypeface::Style)styleBits); |
+ |
+ 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; |
} |
}; |
@@ -2315,4 +2262,3 @@ protected: |
SkFontMgr* SkFontMgr::Factory() { |
return SkNEW(SkFontMgr_Mac); |
} |
-#endif |