Fix hardcoded font path. Allow adding new font path thru Skia changes.
Bug: 6609231
Change-Id: Ie37ada42e7e78ab78318f3ed76eb627bffaddb1a
diff --git a/Android.mk b/Android.mk
index 0630d51..4bc95ed 100644
--- a/Android.mk
+++ b/Android.mk
@@ -291,6 +291,7 @@
 	$(LOCAL_PATH)/include/config \
 	$(LOCAL_PATH)/include/effects \
 	$(LOCAL_PATH)/include/images \
+	$(LOCAL_PATH)/include/ports \
 	$(LOCAL_PATH)/include/utils \
 	$(LOCAL_PATH)/include/xml \
 	external/freetype/include \
diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h
index 29679d6..9bcf601 100644
--- a/include/core/SkScalerContext.h
+++ b/include/core/SkScalerContext.h
@@ -15,6 +15,7 @@
 #include "SkPaint.h"
 #include "SkPath.h"
 #include "SkPoint.h"
+#include "SkTypeface.h"
 
 //#define SK_USE_COLOR_LUMINANCE
 
@@ -299,6 +300,19 @@
                                SkPaint::FontMetrics* mY);
 
 #ifdef SK_BUILD_FOR_ANDROID
+    // This function must be public for SkTypeface_android.h, but should not be
+    // called by other callers
+    SkFontID findTypefaceIdForChar(SkUnichar uni) {
+        SkScalerContext* ctx = this;
+        while (NULL != ctx) {
+            if (ctx->generateCharToGlyph(uni)) {
+                return ctx->fRec.fFontID;
+            }
+            ctx = ctx->getNextContext();
+        }
+        return 0;
+    }
+
     unsigned getBaseGlyphCount(SkUnichar charCode);
 #endif
 
diff --git a/include/ports/SkTypeface_android.h b/include/ports/SkTypeface_android.h
new file mode 100644
index 0000000..3471a94
--- /dev/null
+++ b/include/ports/SkTypeface_android.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTypeface_android_DEFINED
+#define SkTypeface_android_DEFINED
+
+#include "SkTypeface.h"
+
+enum FallbackScripts {
+    kArabic_FallbackScript,
+    kArmenian_FallbackScript,
+    kBengali_FallbackScript,
+    kDevanagari_FallbackScript,
+    kEthiopic_FallbackScript,
+    kGeorgian_FallbackScript,
+    kHebrewRegular_FallbackScript,
+    kHebrewBold_FallbackScript,
+    kKannada_FallbackScript,
+    kMalayalam_FallbackScript,
+    kTamilRegular_FallbackScript,
+    kTamilBold_FallbackScript,
+    kThai_FallbackScript,
+    kTelugu_FallbackScript,
+    kFallbackScriptNumber
+};
+
+#define SkTypeface_ValidScript(s) (s >= 0 && s < kFallbackScriptNumber)
+
+/**
+ *  Return a new typeface for a fallback script. If the script is
+ *  not valid, or can not map to a font, returns null.
+ *  @param  script  The script id.
+ *  @return reference to the matching typeface. Caller must call
+ *          unref() when they are done.
+ */
+SK_API SkTypeface* SkCreateTypefaceForScript(FallbackScripts script);
+
+/**
+ *  Return the string representation for the fallback script on Android.
+ *  If the script is not valid, returns null.
+ */
+SK_API const char* SkGetFallbackScriptID(FallbackScripts script);
+
+/**
+ *  Return the fallback script enum for the ID on Android.
+ *  If the ID is not valid, or can not map to a fallback
+ *  script, returns kFallbackScriptNumber.
+ */
+SK_API FallbackScripts SkGetFallbackScriptFromID(const char* id);
+
+#endif
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 2895c54..23f3c55 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -123,6 +123,8 @@
     //  call the proc)
     void removeAuxProc(void (*auxProc)(void*));
 
+    SkScalerContext* getScalerContext() const { return fScalerContext; }
+
     /** Call proc on all cache entries, stopping early if proc returns true.
         The proc should not create or delete caches, since it could produce
         deadlock.
diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp
index 2c58079..afd0ebe 100644
--- a/src/ports/SkFontHost_android.cpp
+++ b/src/ports/SkFontHost_android.cpp
@@ -27,6 +27,9 @@
 #include "FontHostConfiguration_android.h"
 #include <stdio.h>
 #include <string.h>
+#include "SkGlyphCache.h"
+#include "SkTypeface_android.h"
+
 
 //#define SkDEBUGF(args       )       SkDebugf args
 
@@ -958,3 +961,135 @@
     stream->unref();
     return face;
 }
+
+///////////////////////////////////////////////////////////////////////////////
+// Function from SkTypeface_android.h
+///////////////////////////////////////////////////////////////////////////////
+
+struct FBScriptInfo {
+    const FallbackScripts fScript;
+    const char* fScriptID;
+    const SkTypeface::Style fStyle;
+    const SkUnichar fChar; // representative character for that script type
+    SkFontID fFontID;
+};
+
+#define SK_DEFINE_SCRIPT_ENTRY(script, style, unichar) \
+    { script, #script, style, unichar, 0 }
+
+static FBScriptInfo gFBScriptInfo[] = {
+    SK_DEFINE_SCRIPT_ENTRY(kArabic_FallbackScript,        SkTypeface::kNormal, 0x0600),
+    SK_DEFINE_SCRIPT_ENTRY(kArmenian_FallbackScript,      SkTypeface::kNormal, 0x0531),
+    SK_DEFINE_SCRIPT_ENTRY(kBengali_FallbackScript,       SkTypeface::kNormal, 0x0981),
+    SK_DEFINE_SCRIPT_ENTRY(kDevanagari_FallbackScript,    SkTypeface::kNormal, 0x0901),
+    SK_DEFINE_SCRIPT_ENTRY(kEthiopic_FallbackScript,      SkTypeface::kNormal, 0x1200),
+    SK_DEFINE_SCRIPT_ENTRY(kGeorgian_FallbackScript,      SkTypeface::kNormal, 0x10A0),
+    SK_DEFINE_SCRIPT_ENTRY(kHebrewRegular_FallbackScript, SkTypeface::kNormal, 0x0591),
+    SK_DEFINE_SCRIPT_ENTRY(kHebrewBold_FallbackScript,    SkTypeface::kBold,   0x0591),
+    SK_DEFINE_SCRIPT_ENTRY(kKannada_FallbackScript,       SkTypeface::kNormal, 0x0C90),
+    SK_DEFINE_SCRIPT_ENTRY(kMalayalam_FallbackScript,     SkTypeface::kNormal, 0x0D10),
+    SK_DEFINE_SCRIPT_ENTRY(kTamilRegular_FallbackScript,  SkTypeface::kNormal, 0x0B82),
+    SK_DEFINE_SCRIPT_ENTRY(kTamilBold_FallbackScript,     SkTypeface::kBold,   0x0B82),
+    SK_DEFINE_SCRIPT_ENTRY(kThai_FallbackScript,          SkTypeface::kNormal, 0x0E01),
+    SK_DEFINE_SCRIPT_ENTRY(kTelugu_FallbackScript,        SkTypeface::kNormal, 0x0C10),
+};
+
+static bool gFBScriptInitialized = false;
+static const int gFBScriptInfoCount = sizeof(gFBScriptInfo) / sizeof(FBScriptInfo);
+
+// ensure that if any value is added to the public enum it is also added here
+SK_COMPILE_ASSERT(gFBScriptInfoCount == kFallbackScriptNumber, FBScript_count_mismatch);
+
+
+// this function can't be called if the gFamilyHeadAndNameListMutex is already locked
+static SkFontID findFontIDForChar(SkUnichar uni, SkTypeface::Style style) {
+    gFamilyHeadAndNameListMutex.acquire();
+    SkTypeface* face = findBestFaceLocked(gDefaultFamily, style);
+    gFamilyHeadAndNameListMutex.release();
+    if (!face) {
+        return 0;
+    }
+
+    SkPaint paint;
+    paint.setTypeface(face);
+    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+
+    SkAutoGlyphCache autoCache(paint, NULL);
+    SkGlyphCache*    cache = autoCache.getCache();
+    SkFontID         fontID = 0;
+
+    SkScalerContext* ctx = cache->getScalerContext();
+    if (ctx) {
+        return ctx->findTypefaceIdForChar(uni);
+    }
+    return 0;
+}
+
+// this function can't be called if the gFamilyHeadAndNameListMutex is already locked
+static void initFBScriptInfo() {
+    if (gFBScriptInitialized) {
+        return;
+    }
+
+    // ensure the system fonts are loaded
+    gFamilyHeadAndNameListMutex.acquire();
+    loadSystemFontsLocked();
+    gFamilyHeadAndNameListMutex.release();
+
+    for (int i = 0; i < gFBScriptInfoCount; i++) {
+        FBScriptInfo& scriptInfo = gFBScriptInfo[i];
+        // selects the best available style for the desired font. However, if
+        // bold is requested and no bold font exists for the typeface containing
+        // the character the next best style is chosen (e.g. normal).
+        scriptInfo.fFontID = findFontIDForChar(scriptInfo.fChar, scriptInfo.fStyle);
+        SkDEBUGF(("gFBScriptInfo[%s] --> %d", scriptInfo.fScriptID, scriptInfo.fFontID));
+    }
+    // mark the value as initialized so we don't repeat our work unnecessarily
+    gFBScriptInitialized = true;
+}
+
+SkTypeface* SkCreateTypefaceForScript(FallbackScripts script) {
+    if (!SkTypeface_ValidScript(script)) {
+        return NULL;
+    }
+
+    // ensure that our table is populated
+    initFBScriptInfo();
+
+    FBScriptInfo& scriptInfo = gFBScriptInfo[script];
+
+    // ensure the element with that index actually maps to the correct script
+    SkASSERT(scriptInfo.fScript == script);
+
+    // if a suitable script could not be found then return NULL
+    if (scriptInfo.fFontID == 0) {
+        return NULL;
+    }
+
+    SkAutoMutexAcquire  ac(gFamilyHeadAndNameListMutex);
+
+    // retrieve the typeface the corresponds to this fontID
+    SkTypeface* tf = findFromUniqueIDLocked(scriptInfo.fFontID);
+    // we ref(), since the semantic is to return a new instance
+    tf->ref();
+    return tf;
+}
+
+const char* SkGetFallbackScriptID(FallbackScripts script) {
+    for (int i = 0; i < gFBScriptInfoCount; i++) {
+        if (gFBScriptInfo[i].fScript == script) {
+            return gFBScriptInfo[i].fScriptID;
+        }
+    }
+    return NULL;
+}
+
+FallbackScripts SkGetFallbackScriptFromID(const char* id) {
+    for (int i = 0; i < gFBScriptInfoCount; i++) {
+        if (strcmp(gFBScriptInfo[i].fScriptID, id) == 0) {
+            return gFBScriptInfo[i].fScript;
+        }
+    }
+    return kFallbackScriptNumber; // Use kFallbackScriptNumber as an invalid value.
+}
+