Add CreateFallbackForScript to SkTypeface for Android.

WebKit uses HarfBuzz directly to do Complex Text Layout, so it needs to get the
proper SkTypeface to pass it to HarfBuzz. However, on Android, fallback scripts
have no name, and we can only get them by file name each time (CreateFromFile).
This actually breaks the semantics of SkTypeface, which states 'The ID should
be unique for the underlying font file/data, not unique per typeface instance.'

And add 2 helper function to convert between FallbackScripts enum and font file
name. These are useful for WebKit's FontCache, which needs string as key.

https://codereview.appspot.com/5797066/

git-svn-id: http://skia.googlecode.com/svn/trunk@3403 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp
index 1856cff..0ae1e4e 100644
--- a/src/ports/SkFontHost_android.cpp
+++ b/src/ports/SkFontHost_android.cpp
@@ -23,6 +23,7 @@
 #include "SkStream.h"
 #include "SkThread.h"
 #include "SkTSearch.h"
+#include "SkTypeface_android.h"
 #include "FontHostConfiguration_android.h"
 #include <stdio.h>
 
@@ -415,6 +416,21 @@
 // deliberately empty, but we use the address to identify fallback fonts
 static const char* gFBNames[] = { NULL };
 
+static const struct {
+    const char* fFileName;
+    FallbackScripts fScript;
+} gFBFileNames[] = {
+    { "DroidNaskh-Regular.ttf", kArabic_FallbackScript },
+    { "DroidSansEthiopic-Regular.ttf", kEthiopic_FallbackScript },
+    { "DroidSansHebrew-Regular.ttf", kHebrewRegular_FallbackScript },
+    { "DroidSansHebrew-Bold.ttf", kHebrewBold_FallbackScript },
+    { "DroidSansThai.ttf", kThai_FallbackScript },
+    { "DroidSansArmenian.ttf", kArmenian_FallbackScript },
+    { "DroidSansGeorgian.ttf", kGeorgian_FallbackScript },
+    { "Lohit-Devanagari.ttf", kDevanagari_FallbackScript },
+    { "Lohit-Bengali.ttf", kBengali_FallbackScript },
+    { "Lohit-Tamil.ttf", kTamil_FallbackScript },
+};
 
 /*  Fonts are grouped by family, with the first font in a family having the
     list of names (even if that list is empty), and the following members having
@@ -430,6 +446,7 @@
 static SkTypeface* gDefaultNormal;
 static char** gDefaultNames = NULL;
 static uint32_t *gFallbackFonts;
+static uint32_t *gFallbackScriptsMap;
 
 /*  Load info from a configuration file that populates the system/fallback font structures
 */
@@ -476,6 +493,7 @@
     gNumSystemFonts = fontInfo.count();
     gSystemFonts = (FontInitRec*) malloc(gNumSystemFonts * sizeof(FontInitRec));
     gFallbackFonts = (uint32_t*) malloc((gNumSystemFonts + 1) * sizeof(uint32_t));
+    gFallbackScriptsMap = (uint32_t*) calloc(kFallbackScriptNumber, sizeof(uint32_t));
     if (gSystemFonts == NULL) {
         // shouldn't get here
         gNumSystemFonts = 0;
@@ -534,6 +552,11 @@
 
 //        SkDebugf("---- SkTypeface[%d] %s fontID %d\n", i, rec[i].fFileName, tf->uniqueID());
 
+        FallbackScripts fallbackScript = SkGetScriptFromFileName(rec[i].fFileName);
+        if (SkTypeface_ValidScript(fallbackScript)) {
+            gFallbackScriptsMap[fallbackScript] = tf->uniqueID();
+        }
+
         if (rec[i].fNames != NULL) {
             // see if this is one of our fallback fonts
             if (rec[i].fNames == gFBNames) {
@@ -688,6 +711,43 @@
     return tf;
 }
 
+SkTypeface* SkCreateTypefaceForScript(FallbackScripts script) {
+    if (!SkTypeface_ValidScript(script)) {
+        return NULL;
+    }
+
+    SkAutoMutexAcquire  ac(gFamilyHeadAndNameListMutex);
+
+    load_system_fonts();
+
+    if (gFallbackScriptsMap[script] == 0) {
+        return NULL;
+    }
+
+    SkTypeface* tf = find_from_uniqueID(gFallbackScriptsMap[script]);
+    // we ref(), since the symantic is to return a new instance
+    tf->ref();
+    return tf;
+}
+
+const char* SkGetFallbackScriptID(FallbackScripts script) {
+    for (int i = 0; i < sizeof(gFBFileNames) / sizeof(gFBFileNames[0]); i++) {
+        if (gFBFileNames[i].fScript == script) {
+            return gFBFileNames[i].fFileName;
+        }
+    }
+    return NULL;
+}
+
+FallbackScripts SkGetFallbackScriptFromID(const char* fileName) {
+    for (int i = 0; i < sizeof(gFBFileNames) / sizeof(gFBFileNames[0]); i++) {
+        if (strcmp(gFBFileNames[i].fFileName, fileName) == 0) {
+            return gFBFileNames[i].fScript;
+        }
+    }
+    return kFallbackScriptNumber; // Use SkTypeface_ValidScript as an invalid value.
+}
+
 SkStream* SkFontHost::OpenStream(uint32_t fontID) {
     SkAutoMutexAcquire  ac(gFamilyHeadAndNameListMutex);