remove SkFontHost::CreateScalerContext
Review URL: https://codereview.chromium.org/12593013

git-svn-id: http://skia.googlecode.com/svn/trunk@8228 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 40d939c..a009fc9 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -159,7 +159,7 @@
 
 class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base {
 public:
-    SkScalerContext_FreeType(const SkDescriptor* desc);
+    SkScalerContext_FreeType(SkTypeface*, const SkDescriptor* desc);
     virtual ~SkScalerContext_FreeType();
 
     bool success() const {
@@ -650,7 +650,19 @@
             bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
 }
 
-void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
+SkScalerContext* SkTypeface_FreeType::onCreateScalerContext(
+                                               const SkDescriptor* desc) const {
+    SkScalerContext_FreeType* c = SkNEW_ARGS(SkScalerContext_FreeType,
+                                        (const_cast<SkTypeface_FreeType*>(this),
+                                         desc));
+    if (!c->success()) {
+        SkDELETE(c);
+        c = NULL;
+    }
+    return c;
+}
+
+void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const {
     //BOGUS: http://code.google.com/p/chromium/issues/detail?id=121119
     //Cap the requested size as larger sizes give bogus values.
     //Remove when http://code.google.com/p/skia/issues/detail?id=554 is fixed.
@@ -710,8 +722,9 @@
 }
 #endif
 
-SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
-        : SkScalerContext_FreeType_Base(desc) {
+SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
+                                                   const SkDescriptor* desc)
+        : SkScalerContext_FreeType_Base(typeface, desc) {
     SkAutoMutexAcquire  ac(gFTMutex);
 
     if (gFTCount == 0) {
@@ -1300,17 +1313,6 @@
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
-    SkScalerContext_FreeType* c = SkNEW_ARGS(SkScalerContext_FreeType, (desc));
-    if (!c->success()) {
-        SkDELETE(c);
-        c = NULL;
-    }
-    return c;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
 /*  Export this so that other parts of our FonttHost port can make use of our
     ability to extract the name+style from a stream, using FreeType's api.
 */
diff --git a/src/ports/SkFontHost_FreeType_common.h b/src/ports/SkFontHost_FreeType_common.h
index db32bc8..efc74be 100644
--- a/src/ports/SkFontHost_FreeType_common.h
+++ b/src/ports/SkFontHost_FreeType_common.h
@@ -11,6 +11,8 @@
 
 #include "SkGlyph.h"
 #include "SkScalerContext.h"
+#include "SkTypeface.h"
+
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
@@ -26,19 +28,34 @@
 
 
 class SkScalerContext_FreeType_Base : public SkScalerContext {
-public:
+protected:
     // See http://freetype.sourceforge.net/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden
     // This value was chosen by eyeballing the result in Firefox and trying to match it.
     static const FT_Pos kBitmapEmboldenStrength = 1 << 6;
-
-    SkScalerContext_FreeType_Base(const SkDescriptor *desc)
-        : SkScalerContext(desc)
+    
+    SkScalerContext_FreeType_Base(SkTypeface* typeface, const SkDescriptor *desc)
+    : INHERITED(typeface, desc)
     {}
-
-protected:
+    
     void generateGlyphImage(FT_Face face, const SkGlyph& glyph);
     void generateGlyphPath(FT_Face face, SkPath* path);
     void emboldenOutline(FT_Face face, FT_Outline* outline);
+
+private:
+    typedef SkScalerContext INHERITED;
+};
+
+class SkTypeface_FreeType : public SkTypeface {
+protected:
+    SkTypeface_FreeType(Style style, SkFontID uniqueID, bool isFixedWidth)
+        : INHERITED(style, uniqueID, isFixedWidth) {}
+
+    virtual SkScalerContext* onCreateScalerContext(
+                                        const SkDescriptor*) const SK_OVERRIDE;
+    virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
+
+private:
+    typedef SkTypeface INHERITED;
 };
 
 #endif // SKFONTHOST_FREETYPE_COMMON_H_
diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp
index a955b63..416d61d 100644
--- a/src/ports/SkFontHost_android.cpp
+++ b/src/ports/SkFontHost_android.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "SkFontHost.h"
+#include "SkFontHost_FreeType_common.h"
 #include "SkFontDescriptor.h"
 #include "SkGraphics.h"
 #include "SkDescriptor.h"
@@ -280,11 +281,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class FamilyTypeface : public SkTypeface {
+class FamilyTypeface : public SkTypeface_FreeType {
 public:
     FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember,
                    bool isFixedWidth)
-    : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) {
+    : INHERITED(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) {
         fIsSysFont = sysFont;
 
         // our caller has acquired the gFamilyHeadAndNameListMutex so this is safe
@@ -319,7 +320,7 @@
 private:
     bool    fIsSysFont;
 
-    typedef SkTypeface INHERITED;
+    typedef SkTypeface_FreeType INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -866,13 +867,13 @@
     }
 }
 
-SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) {
 #if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
     // Skia does not support font fallback for ndk applications in order to
     // enable clients such as WebKit to customize their font selection.
     // Clients can use GetFallbackFamilyNameForChar() to get the fallback
     // font for individual characters.
-    return 0;
+    return NULL;
 #else
     SkAutoMutexAcquire  ac(gFamilyHeadAndNameListMutex);
 
@@ -898,9 +899,9 @@
     for (int i = 0; list[i] != 0; i++) {
         if (list[i] == currFontID) {
             if (list[i+1] == 0)
-                return 0;
+                return NULL;
             const SkTypeface* nextTypeface = find_from_uniqueID(list[i+1]);
-            return find_typeface(nextTypeface, origTypeface->style())->uniqueID();
+            return SkRef(find_typeface(nextTypeface, origTypeface->style()));
         }
     }
 
@@ -908,7 +909,7 @@
     // beginning of our list. Assuming there is at least one fallback font,
     // i.e. gFallbackFonts[0] != 0.
     const SkTypeface* firstTypeface = find_from_uniqueID(list[0]);
-    return find_typeface(firstTypeface, origTypeface->style())->uniqueID();
+    return SkRef(find_typeface(firstTypeface, origTypeface->style()));
 #endif
 }
 
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index 4dd1888..93a93c1 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -8,6 +8,7 @@
 #include "SkFontConfigInterface.h"
 #include "SkFontDescriptor.h"
 #include "SkFontHost.h"
+#include "SkFontHost_FreeType_common.h"
 #include "SkFontStream.h"
 #include "SkStream.h"
 #include "SkTypeface.h"
@@ -46,7 +47,7 @@
     }
 }
 
-class FontConfigTypeface : public SkTypeface {
+class FontConfigTypeface : public SkTypeface_FreeType {
     SkFontConfigInterface::FontIdentity fIdentity;
     SkString fFamilyName;
     SkStream* fLocalStream;
@@ -55,13 +56,13 @@
     FontConfigTypeface(Style style,
                        const SkFontConfigInterface::FontIdentity& fi,
                        const SkString& familyName)
-            : SkTypeface(style, SkTypefaceCache::NewFontID())
+            : INHERITED(style, SkTypefaceCache::NewFontID(), false)
             , fIdentity(fi)
             , fFamilyName(familyName)
             , fLocalStream(NULL) {}
 
     FontConfigTypeface(Style style, SkStream* localStream)
-            : SkTypeface(style, SkTypefaceCache::NewFontID()) {
+            : INHERITED(style, SkTypefaceCache::NewFontID(), false) {
         // we default to empty fFamilyName and fIdentity
         fLocalStream = localStream;
         SkSafeRef(localStream);
@@ -91,7 +92,7 @@
     virtual void onGetFontDescriptor(SkFontDescriptor*) const SK_OVERRIDE;
 
 private:
-    typedef SkTypeface INHERITED;
+    typedef SkTypeface_FreeType INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -199,9 +200,9 @@
 }
 
 // DEPRECATED
-uint32_t SkFontHost::NextLogicalFont(SkFontID curr, SkFontID orig) {
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID curr, SkFontID orig) {
     // We don't handle font fallback.
-    return 0;
+    return NULL;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/ports/SkFontHost_freetype_mac.cpp b/src/ports/SkFontHost_freetype_mac.cpp
index 3d89bc6..fb67993 100644
--- a/src/ports/SkFontHost_freetype_mac.cpp
+++ b/src/ports/SkFontHost_freetype_mac.cpp
@@ -96,8 +96,8 @@
     return NULL;
 }
 
-SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
-    return 0;
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) {
+    return NULL;
 }
 
 #include "SkTypeface_mac.h"
diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp
index f409cd4..e27473e 100644
--- a/src/ports/SkFontHost_linux.cpp
+++ b/src/ports/SkFontHost_linux.cpp
@@ -545,8 +545,8 @@
     return 0;
 }
 
-SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
-    return 0;
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) {
+    return NULL;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index ae1e75e..674f1fd 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -610,8 +610,8 @@
 
 class SkScalerContext_Mac : public SkScalerContext {
 public:
-    SkScalerContext_Mac(const SkDescriptor* desc);
-    virtual ~SkScalerContext_Mac(void);
+    SkScalerContext_Mac(SkTypeface_Mac*, const SkDescriptor*);
+    virtual ~SkScalerContext_Mac();
 
 
 protected:
@@ -646,10 +646,13 @@
     bool fVertical;
 
     friend class Offscreen;
+
+    typedef SkScalerContext INHERITED;
 };
 
-SkScalerContext_Mac::SkScalerContext_Mac(const SkDescriptor* desc)
-        : SkScalerContext(desc)
+SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
+                                         const SkDescriptor* desc)
+        : INHERITED(typeface, desc)
         , fFBoundingBoxes(NULL)
         , fFBoundingBoxesGlyphOffset(0)
         , fGeneratedFBoundingBoxes(false)
@@ -1713,23 +1716,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 // DEPRECATED
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
-    return new SkScalerContext_Mac(desc);
-}
-
-// DEPRECATED
-SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
-    SkFontID nextFontID = 0;
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) {
     SkTypeface* face = GetDefaultFace();
-    if (face->uniqueID() != currFontID) {
-        nextFontID = face->uniqueID();
+    if (face->uniqueID() == currFontID) {
+        face = NULL;
     }
-    return nextFontID;
-}
-
-// DEPRECATED
-void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface* face) {
-    face->onFilterRec(rec);
+    return SkSafeRef(face);
 }
 
 // DEPRECATED
@@ -1815,7 +1807,7 @@
 }
 
 SkScalerContext* SkTypeface_Mac::onCreateScalerContext(const SkDescriptor* desc) const {
-    return new SkScalerContext_Mac(desc);
+    return new SkScalerContext_Mac(const_cast<SkTypeface_Mac*>(this), desc);
 }
 
 void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
diff --git a/src/ports/SkFontHost_none.cpp b/src/ports/SkFontHost_none.cpp
index 6475c09..a0aedba 100644
--- a/src/ports/SkFontHost_none.cpp
+++ b/src/ports/SkFontHost_none.cpp
@@ -37,9 +37,6 @@
     return NULL;
 }
 
-void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 SkStream* SkFontHost::OpenStream(uint32_t uniqueID) {
@@ -66,11 +63,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
-    SkDEBUGFAIL("SkFontHost::CreateScalarContext unimplemented");
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID,
+                                            SkFontID origFontID) {
     return NULL;
 }
-
-SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
-    return 0;
-}
diff --git a/src/ports/SkFontHost_simple.cpp b/src/ports/SkFontHost_simple.cpp
index b4f6ce0..7d9cf6d 100644
--- a/src/ports/SkFontHost_simple.cpp
+++ b/src/ports/SkFontHost_simple.cpp
@@ -394,7 +394,7 @@
     fontIDs that can be used for fallback consideration, in sorted order (sorted
     meaning element[0] should be used first, then element[1], etc. When we hit
     a fontID==0 in the array, the list is done, hence our allocation size is
-    +1 the total number of possible system fonts. Also see NextLogicalFont().
+    +1 the total number of possible system fonts. Also see NextLogicalTypeface().
  */
 static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];
 
@@ -584,7 +584,7 @@
     }
 }
 
-SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) {
     load_system_fonts();
 
     /*  First see if fontID is already one of our fallbacks. If so, return
@@ -595,10 +595,10 @@
     const uint32_t* list = gFallbackFonts;
     for (int i = 0; list[i] != 0; i++) {
         if (list[i] == currFontID) {
-            return list[i+1];
+            return SkSafeRef(find_from_uniqueID(list[i+1]));
         }
     }
-    return list[0];
+    return SkSafeRef(list[0]);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 383aecd..6c93719 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -190,6 +190,10 @@
         SkFontID fontID = SkTypefaceCache::NewFontID();
         return new LogFontTypeface(style, fontID, lf);
     }
+
+protected:
+    virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
+    virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
 };
 
 class FontMemResourceTypeface : public LogFontTypeface {
@@ -274,11 +278,11 @@
     }
 }
 
-SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) {
   // Zero means that we don't have any fallback fonts for this fontID.
   // This function is implemented on Android, but doesn't have much
   // meaning here.
-  return 0;
+  return NULL;
 }
 
 static void ensure_typeface_accessible(SkFontID fontID) {
@@ -481,7 +485,7 @@
 
 class SkScalerContext_Windows : public SkScalerContext {
 public:
-    SkScalerContext_Windows(const SkDescriptor* desc);
+    SkScalerContext_Windows(SkTypeface*, const SkDescriptor* desc);
     virtual ~SkScalerContext_Windows();
 
 protected:
@@ -549,8 +553,9 @@
     }
 }
 
-SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc)
-        : SkScalerContext(desc), fDDC(0), fFont(0), fSavefont(0), fSC(0)
+SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* typeface,
+                                                 const SkDescriptor* desc)
+        : SkScalerContext(typeface, desc), fDDC(0), fFont(0), fSavefont(0), fSC(0)
         , fGlyphCount(-1) {
     SkAutoMutexAcquire  ac(gFTMutex);
 
@@ -1608,8 +1613,8 @@
     return 0;
 }
 
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
-    return SkNEW_ARGS(SkScalerContext_Windows, (desc));
+SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
+    return SkNEW_ARGS(SkScalerContext_Windows, (const_cast<LogFontTypeface*>(this), desc));
 }
 
 /** Return the closest matching typeface given either an existing family
@@ -1642,7 +1647,7 @@
     return stream.get() ? CreateTypefaceFromStream(stream) : NULL;
 }
 
-void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface* typeface) {
+void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
     unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
                                   SkScalerContext::kAutohinting_Flag |
                                   SkScalerContext::kEmbeddedBitmapText_Flag |
@@ -1682,8 +1687,7 @@
     }
 #endif
 
-    LogFontTypeface* logfontTypeface = static_cast<LogFontTypeface*>(typeface);
-    if (!logfontTypeface->fCanBeLCD && isLCD(*rec)) {
+    if (!fCanBeLCD && isLCD(*rec)) {
         rec->fMaskFormat = SkMask::kA8_Format;
         rec->fFlags &= ~SkScalerContext::kGenA8FromLCD_Flag;
     }
diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp
index f0e2002..1e06e38 100644
--- a/src/ports/SkFontHost_win_dw.cpp
+++ b/src/ports/SkFontHost_win_dw.cpp
@@ -41,11 +41,11 @@
            SkMask::kLCD32_Format == rec.fMaskFormat;
 }
 
-SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
+SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) {
   // Zero means that we don't have any fallback fonts for this fontID.
   // This function is implemented on Android, but doesn't have much
   // meaning here.
-  return 0;
+  return NULL;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -477,11 +477,15 @@
         HRV(factory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
         HRV(factory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
     }
+
+protected:
+    virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
+    virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
 };
 
 class SkScalerContext_Windows : public SkScalerContext {
 public:
-    SkScalerContext_Windows(const SkDescriptor* desc);
+    SkScalerContext_Windows(DWriteFontTypeface*, const SkDescriptor* desc);
     virtual ~SkScalerContext_Windows();
 
 protected:
@@ -707,8 +711,10 @@
     return static_cast<DWriteFontTypeface*>(SkTypefaceCache::FindByID(fontID));
 }
 
-SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc)
-        : SkScalerContext(desc)
+SkScalerContext_Windows::SkScalerContext_Windows(DWriteFontTypeface* typeface,
+                                                 const SkDescriptor* desc)
+        : SkScalerContext(typeface, desc)
+        , fTypeface(SkRef(typeface))
         , fGlyphCount(-1) {
     SkAutoMutexAcquire ac(gFTMutex);
 
@@ -719,9 +725,6 @@
     fXform.dx = 0;
     fXform.dy = 0;
 
-    fTypeface.reset(GetDWriteFontByID(fRec.fFontID));
-    fTypeface.get()->ref();
-
     fOffscreen.init(fTypeface->fDWriteFontFace.get(), fXform, SkScalarToFloat(fRec.fTextSize));
 }
 
@@ -1162,8 +1165,8 @@
     return 0;
 }
 
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
-    return SkNEW_ARGS(SkScalerContext_Windows, (desc));
+SkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
+    return SkNEW_ARGS(SkScalerContext_Windows, (const_cast<DWriteFontTypeface*>(this), desc));
 }
 
 static HRESULT get_by_family_name(const char familyName[], IDWriteFontFamily** fontFamily) {
@@ -1258,7 +1261,7 @@
     return NULL;
 }
 
-void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
+void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {
     unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
                                   SkScalerContext::kAutohinting_Flag |
                                   SkScalerContext::kEmbeddedBitmapText_Flag |