move most of SkFontHost to private (preceeding making it all private)

In this change, have to accomodate PDF wanting to call openStream and advancedMetrics
Review URL: https://codereview.chromium.org/12739006

git-svn-id: http://skia.googlecode.com/svn/trunk@8156 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h
index 3c2ed09..07957da 100644
--- a/include/core/SkFontHost.h
+++ b/include/core/SkFontHost.h
@@ -49,6 +49,92 @@
 */
 class SK_API SkFontHost {
 public:
+    /** LCDs either have their color elements arranged horizontally or
+     vertically. When rendering subpixel glyphs we need to know which way
+     round they are.
+     
+     Note, if you change this after startup, you'll need to flush the glyph
+     cache because it'll have the wrong type of masks cached.
+     
+     @deprecated use SkPixelGeometry instead.
+     */
+    enum LCDOrientation {
+        kHorizontal_LCDOrientation = 0,    //!< this is the default
+        kVertical_LCDOrientation   = 1
+    };
+    
+    /** @deprecated set on Device creation. */
+    static void SetSubpixelOrientation(LCDOrientation orientation);
+    /** @deprecated get from Device. */
+    static LCDOrientation GetSubpixelOrientation();
+    
+    /** LCD color elements can vary in order. For subpixel text we need to know
+     the order which the LCDs uses so that the color fringes are in the
+     correct place.
+     
+     Note, if you change this after startup, you'll need to flush the glyph
+     cache because it'll have the wrong type of masks cached.
+     
+     kNONE_LCDOrder means that the subpixel elements are not spatially
+     separated in any usable fashion.
+     
+     @deprecated use SkPixelGeometry instead.
+     */
+    enum LCDOrder {
+        kRGB_LCDOrder = 0,    //!< this is the default
+        kBGR_LCDOrder = 1,
+        kNONE_LCDOrder = 2
+    };
+    
+    /** @deprecated set on Device creation. */
+    static void SetSubpixelOrder(LCDOrder order);
+    /** @deprecated get from Device. */
+    static LCDOrder GetSubpixelOrder();
+    
+#ifdef SK_BUILD_FOR_ANDROID    
+    /**
+     * Return the number of font units per em.
+     *
+     * @param fontID the font to query.
+     * @return the number of font units per em or 0 on error.
+     */
+    static uint32_t GetUnitsPerEm(SkFontID fontID);
+#endif
+    
+    /** If Skia is running in a constrained environment and the typeface
+     implementation is handle based, the typeface data may become
+     unavailable asynchronously. If a font host or scaler context method is
+     unable to access font data, it may call this function as a request to
+     make the handle contained in the typeface useable.
+     */
+    static void EnsureTypefaceAccessible(const SkTypeface& typeface);
+    
+    /**
+     *  Return a subclass of SkScalarContext
+     *  DEPRECATED -- will be moved to SkTypeface
+     */
+    static SkScalerContext* CreateScalerContext(const SkDescriptor* desc);
+    
+    /**
+     *  DEPRECATED -- will be DESTROYED
+     *
+     *  Given a "current" fontID, return the next logical fontID to use
+     *  when searching fonts for a given unicode value. Typically the caller
+     *  will query a given font, and if a unicode value is not supported, they
+     *  will call this, and if 0 is not returned, will search that font, and so
+     *  on. This process must be finite, and when the fonthost sees a
+     *  font with no logical successor, it must return 0.
+     *
+     *  The original fontID is also provided. This is the initial font that was
+     *  stored in the typeface of the caller. It is provided as an aid to choose
+     *  the best next logical font. e.g. If the original font was bold or serif,
+     *  but the 2nd in the logical chain was plain, then a subsequent call to
+     *  get the 3rd can still inspect the original, and try to match its
+     *  stylistic attributes.
+     */
+    static SkFontID NextLogicalFont(SkFontID currFontID, SkFontID origFontID);
+
+private:
     /** Return a new, closest matching typeface given either an existing family
         (specified by a typeface in that family) or by a familyName and a
         requested style.
@@ -135,29 +221,6 @@
 
     ///////////////////////////////////////////////////////////////////////////
 
-    /** Return a subclass of SkScalarContext
-    */
-    static SkScalerContext* CreateScalerContext(const SkDescriptor* desc);
-
-    /**
-     *  Given a "current" fontID, return the next logical fontID to use
-     *  when searching fonts for a given unicode value. Typically the caller
-     *  will query a given font, and if a unicode value is not supported, they
-     *  will call this, and if 0 is not returned, will search that font, and so
-     *  on. This process must be finite, and when the fonthost sees a
-     *  font with no logical successor, it must return 0.
-     *
-     *  The original fontID is also provided. This is the initial font that was
-     *  stored in the typeface of the caller. It is provided as an aid to choose
-     *  the best next logical font. e.g. If the original font was bold or serif,
-     *  but the 2nd in the logical chain was plain, then a subsequent call to
-     *  get the 3rd can still inspect the original, and try to match its
-     *  stylistic attributes.
-     */
-    static SkFontID NextLogicalFont(SkFontID currFontID, SkFontID origFontID);
-
-    ///////////////////////////////////////////////////////////////////////////
-
     /** Given a filled-out rec, the fonthost may decide to modify it to reflect
         what the host is actually capable of fulfilling. For example, if the
         rec is requesting a level of hinting that, for this host, maps some
@@ -230,67 +293,7 @@
 
     ///////////////////////////////////////////////////////////////////////////
 
-    /** LCDs either have their color elements arranged horizontally or
-        vertically. When rendering subpixel glyphs we need to know which way
-        round they are.
-
-        Note, if you change this after startup, you'll need to flush the glyph
-        cache because it'll have the wrong type of masks cached.
-
-        @deprecated use SkPixelGeometry instead.
-    */
-    enum LCDOrientation {
-        kHorizontal_LCDOrientation = 0,    //!< this is the default
-        kVertical_LCDOrientation   = 1
-    };
-
-    /** @deprecated set on Device creation. */
-    static void SetSubpixelOrientation(LCDOrientation orientation);
-    /** @deprecated get from Device. */
-    static LCDOrientation GetSubpixelOrientation();
-
-    /** LCD color elements can vary in order. For subpixel text we need to know
-        the order which the LCDs uses so that the color fringes are in the
-        correct place.
-
-        Note, if you change this after startup, you'll need to flush the glyph
-        cache because it'll have the wrong type of masks cached.
-
-        kNONE_LCDOrder means that the subpixel elements are not spatially
-        separated in any usable fashion.
-
-        @deprecated use SkPixelGeometry instead.
-     */
-    enum LCDOrder {
-        kRGB_LCDOrder = 0,    //!< this is the default
-        kBGR_LCDOrder = 1,
-        kNONE_LCDOrder = 2
-    };
-
-    /** @deprecated set on Device creation. */
-    static void SetSubpixelOrder(LCDOrder order);
-    /** @deprecated get from Device. */
-    static LCDOrder GetSubpixelOrder();
-
-#ifdef SK_BUILD_FOR_ANDROID
-    ///////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Return the number of font units per em.
-     *
-     * @param fontID the font to query.
-     * @return the number of font units per em or 0 on error.
-     */
-    static uint32_t GetUnitsPerEm(SkFontID fontID);
-#endif
-
-    /** If Skia is running in a constrained environment and the typeface
-        implementation is handle based, the typeface data may become
-        unavailable asynchronously. If a font host or scaler context method is
-        unable to access font data, it may call this function as a request to
-        make the handle contained in the typeface useable.
-    */
-    static void EnsureTypefaceAccessible(const SkTypeface& typeface);
+    friend class SkTypeface;
 };
 
 #endif
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index 79b821f..a531cf2 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -80,6 +80,12 @@
      */
     static bool Equal(const SkTypeface* facea, const SkTypeface* faceb);
 
+    /**
+     *  Returns a ref() to the default typeface. The caller must call unref()
+     *  when they are done referencing the object. Never returns NULL.
+     */
+    static SkTypeface* RefDefault();
+
     /** Return a new reference to the typeface that most closely matches the
         requested familyName and style. Pass null as the familyName to return
         the default font for the requested style. Will never return null
@@ -187,6 +193,8 @@
      */
     int getUnitsPerEm() const;
 
+    SkStream* openStream(int* ttcIndex) const;
+
 protected:
     /** uniqueID must be unique and non-zero
     */
@@ -209,6 +217,7 @@
     Style       fStyle;
     bool        fIsFixedWidth;
 
+    friend class SkPaint;
     // just so deprecated fonthost can call protected methods
     friend class SkFontHost;
 
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 37edfbb..b9dc5e5 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -1655,7 +1655,7 @@
         they can modify our rec up front, so we don't create duplicate cache
         entries.
      */
-    SkFontHost::FilterRec(rec, typeface);
+    typeface->onFilterRec(rec);
 
     // be sure to call PostMakeRec(rec) before you actually use it!
 }
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index 7699470..80fa438 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -49,6 +49,10 @@
     return gDefaultTypeface;
 }
 
+SkTypeface* SkTypeface::RefDefault() {
+    return SkRef(GetDefaultTypeface());
+}
+
 uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
     if (NULL == face) {
         face = GetDefaultTypeface();
@@ -121,6 +125,15 @@
     return SkFontHost::GetTableData(fUniqueID, tag, offset, length, data);
 }
 
+SkStream* SkTypeface::openStream(int* ttcIndex) const {
+    if (ttcIndex) {
+        int32_t ndx = 0;
+        (void)SkFontHost::GetFileName(fUniqueID, NULL, 0, &ndx);
+        *ttcIndex = (int)ndx;
+    }
+    return SkFontHost::OpenStream(fUniqueID);
+}
+
 int SkTypeface::getUnitsPerEm() const {
     int upem = 0;
 
@@ -139,6 +152,16 @@
     return upem;
 }
 
+// TODO: move this impl into the subclass
+SkScalerContext* SkTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
+    return SkFontHost::CreateScalerContext(desc);
+}
+
+// TODO: move this impl into the subclass
+void SkTypeface::onFilterRec(SkScalerContextRec* rec) const {
+    SkFontHost::FilterRec(rec, const_cast<SkTypeface*>(this));
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -148,10 +171,6 @@
 int SkTypeface::onGetTableTags(SkFontTableTag tags[]) const { return 0; }
 size_t SkTypeface::onGetTableData(SkFontTableTag, size_t offset,
                                   size_t length, void* data) const { return 0; }
-SkScalerContext* SkTypeface::onCreateScalerContext(const SkDescriptor*) const {
-    return NULL;
-}
-void SkTypeface::onFilterRec(SkScalerContextRec*) const {}
 void SkTypeface::onGetFontDescriptor(SkFontDescriptor* desc) const {
     desc->setStyle(this->style());
 }
diff --git a/src/core/SkTypefacePriv.h b/src/core/SkTypefacePriv.h
new file mode 100644
index 0000000..2f48372
--- /dev/null
+++ b/src/core/SkTypefacePriv.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTypefacePriv_DEFINED
+#define SkTypefacePriv_DEFINED
+
+#include "SkTypeface.h"
+
+/**
+ *  Return a ref'd typeface, which must later be unref'd
+ *
+ *  If the parameter is non-null, it will be ref'd and returned, otherwise
+ *  it will be the default typeface.
+ */
+static inline SkTypeface* ref_or_default(SkTypeface* face) {
+    return face ? SkRef(face) : SkTypeface::RefDefault();
+}
+
+/**
+ *  Always resolves to a non-null typeface, either the value passed to its
+ *  constructor, or the default typeface if null was passed.
+ */
+class SkAutoResolveDefaultTypeface : public SkAutoTUnref<SkTypeface> {
+public:
+    SkAutoResolveDefaultTypeface() : INHERITED(SkTypeface::RefDefault()) {}
+    
+    SkAutoResolveDefaultTypeface(SkTypeface* face)
+        : INHERITED(ref_or_default(face)) {}
+
+private:
+    typedef SkAutoTUnref<SkTypeface> INHERITED;
+};
+
+#endif
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index be1bca5..8f0f3d2 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
@@ -6,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-
 #include "SkPDFDevice.h"
 
 #include "SkAnnotation.h"
@@ -30,8 +28,7 @@
 #include "SkString.h"
 #include "SkTextFormatParams.h"
 #include "SkTemplates.h"
-#include "SkTypeface.h"
-#include "SkTypes.h"
+#include "SkTypefacePriv.h"
 
 // Utility functions
 
@@ -104,10 +101,12 @@
     *y = *y - yAdj;
 }
 
-static size_t max_glyphid_for_typeface(const SkTypeface* typeface) {
+static size_t max_glyphid_for_typeface(SkTypeface* typeface) {
+    SkAutoResolveDefaultTypeface autoResolve(typeface);
+    typeface = autoResolve.get();
+
     SkAdvancedTypefaceMetrics* metrics;
-    metrics = SkFontHost::GetAdvancedTypefaceMetrics(
-            SkTypeface::UniqueID(typeface),
+    metrics = typeface->getAdvancedTypefaceMetrics(
             SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo,
             NULL, 0);
 
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index 10252ad..34f2fee 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
@@ -6,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-
 #include <ctype.h>
 
 #include "SkData.h"
@@ -23,7 +21,7 @@
 #include "SkRefCnt.h"
 #include "SkScalar.h"
 #include "SkStream.h"
-#include "SkTypeface.h"
+#include "SkTypefacePriv.h"
 #include "SkTypes.h"
 #include "SkUtils.h"
 
@@ -549,8 +547,8 @@
                                   const SkTypeface* typeface,
                                   const SkTDArray<uint32_t>& subset,
                                   SkPDFStream** fontStream) {
-    SkAutoTUnref<SkStream> fontData(
-            SkFontHost::OpenStream(SkTypeface::UniqueID(typeface)));
+    int ttcIndex;
+    SkAutoTUnref<SkStream> fontData(typeface->openStream(&ttcIndex));
 
     int fontSize = fontData->getLength();
 
@@ -714,7 +712,7 @@
 
     SkDEBUGCODE(int indexFound;)
     SkASSERT(index == -1 ||
-             (Find(SkTypeface::UniqueID(fTypeface.get()),
+             (Find(fTypeface->uniqueID(),
                    fFirstGlyphID,
                    &indexFound) &&
              index == indexFound));
@@ -763,7 +761,11 @@
 // static
 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) {
     SkAutoMutexAcquire lock(CanonicalFontsMutex());
-    const uint32_t fontID = SkTypeface::UniqueID(typeface);
+
+    SkAutoResolveDefaultTypeface autoResolve(typeface);
+    typeface = autoResolve.get();
+
+    const uint32_t fontID = typeface->uniqueID();
     int relatedFontIndex;
     if (Find(fontID, glyphID, &relatedFontIndex)) {
         CanonicalFonts()[relatedFontIndex].fFont->ref();
@@ -800,7 +802,7 @@
                   info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo);
 #endif
         fontMetrics.reset(
-            SkFontHost::GetAdvancedTypefaceMetrics(fontID, info, NULL, 0));
+            typeface->getAdvancedTypefaceMetrics(info, NULL, 0));
 #if defined (SK_SFNTLY_SUBSETTER)
         if (fontMetrics.get() &&
             fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) {
@@ -808,7 +810,7 @@
             info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
                       info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo);
             fontMetrics.reset(
-                SkFontHost::GetAdvancedTypefaceMetrics(fontID, info, NULL, 0));
+                typeface->getAdvancedTypefaceMetrics(info, NULL, 0));
         }
 #endif
     }
@@ -855,7 +857,7 @@
 SkPDFFont::SkPDFFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
                      SkPDFDict* relatedFontDescriptor)
         : SkPDFDict("Font"),
-          fTypeface(typeface),
+          fTypeface(ref_or_default(typeface)),
           fFirstGlyphID(1),
           fLastGlyphID(info ? info->fLastGlyphID : 0),
           fFontInfo(info),
@@ -1099,8 +1101,8 @@
         }
         case SkAdvancedTypefaceMetrics::kCFF_Font:
         case SkAdvancedTypefaceMetrics::kType1CID_Font: {
-            SkAutoTUnref<SkStream> fontData(
-                SkFontHost::OpenStream(SkTypeface::UniqueID(typeface())));
+            int ttcIndex;
+            SkAutoTUnref<SkStream> fontData(typeface()->openStream(&ttcIndex));
             SkAutoTUnref<SkPDFStream> fontStream(
                 new SkPDFStream(fontData.get()));
             addResource(fontStream.get());
@@ -1139,11 +1141,7 @@
         uint32_t* glyphs = (glyphIDs.count() == 1) ? NULL : glyphIDs.begin();
         uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0;
         SkAutoTUnref<SkAdvancedTypefaceMetrics> fontMetrics(
-            SkFontHost::GetAdvancedTypefaceMetrics(
-                    SkTypeface::UniqueID(typeface()),
-                    info,
-                    glyphs,
-                    glyphsCount));
+            typeface()->getAdvancedTypefaceMetrics(info, glyphs, glyphsCount));
         setFontInfo(fontMetrics.get());
         addFontDescriptor(0, &glyphIDs);
     } else {
@@ -1229,11 +1227,11 @@
     SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor"));
     setFontDescriptor(descriptor.get());
 
+    int ttcIndex;
     size_t header SK_INIT_TO_AVOID_WARNING;
     size_t data SK_INIT_TO_AVOID_WARNING;
     size_t trailer SK_INIT_TO_AVOID_WARNING;
-    SkAutoTUnref<SkStream> rawFontData(
-        SkFontHost::OpenStream(SkTypeface::UniqueID(typeface())));
+    SkAutoTUnref<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
     SkStream* fontData = handleType1Stream(rawFontData.get(), &header, &data,
                                            &trailer);
     if (fontData == NULL) {
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 4a6b8d8..ae1e75e 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -1681,7 +1681,6 @@
 }
 
 size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length, int32_t* index) {
-    SkDEBUGFAIL("SkFontHost::GetFileName unimplemented");
     return 0;
 }
 
diff --git a/tests/FontHostStreamTest.cpp b/tests/FontHostStreamTest.cpp
index bbf1a03..4fd88cc 100644
--- a/tests/FontHostStreamTest.cpp
+++ b/tests/FontHostStreamTest.cpp
@@ -91,8 +91,13 @@
         origCanvas.drawText("A", 1, point.fX, point.fY, paint);
 
         SkTypeface* origTypeface = paint.getTypeface();
-        const SkFontID typefaceID = SkTypeface::UniqueID(origTypeface);
-        SkStream* fontData = SkFontHost::OpenStream(typefaceID);
+        SkAutoTUnref<SkTypeface> aur;
+        if (NULL == origTypeface) {
+            origTypeface = aur.reset(SkTypeface::RefDefault());
+        }
+
+        int ttcIndex;
+        SkStream* fontData = origTypeface->openStream(&ttcIndex);
         SkTypeface* streamTypeface = SkTypeface::CreateFromStream(fontData);
         SkSafeUnref(paint.setTypeface(streamTypeface));
         drawBG(&streamCanvas);