aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBilly Hewlett <billyh@google.com>2012-06-07 08:32:37 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-06-07 08:32:37 -0700
commit0c3afa6fd3b1f6a541e7bdabcde121ff98851376 (patch)
treebfd50bf63f3d89f1da7f2952475efe39011c5016
parent8e2bfb97a5c34cce607ffcbdc6b3a3a3954fc5c9 (diff)
parentcde7dcc5111806870f94721561056e990a9211c8 (diff)
downloadexternal_skia-0c3afa6fd3b1f6a541e7bdabcde121ff98851376.zip
external_skia-0c3afa6fd3b1f6a541e7bdabcde121ff98851376.tar.gz
external_skia-0c3afa6fd3b1f6a541e7bdabcde121ff98851376.tar.bz2
Merge "Fix hardcoded font path. Allow adding new font path thru Skia changes. Bug: 6609231 Change-Id: Ie37ada42e7e78ab78318f3ed76eb627bffaddb1a"
-rw-r--r--Android.mk1
-rw-r--r--include/core/SkScalerContext.h14
-rw-r--r--include/ports/SkTypeface_android.h56
-rw-r--r--src/core/SkGlyphCache.h2
-rw-r--r--src/ports/SkFontHost_android.cpp135
5 files changed, 208 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
index 08cf6f8..846c157 100644
--- a/Android.mk
+++ b/Android.mk
@@ -295,6 +295,7 @@ LOCAL_C_INCLUDES += \
$(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 @@ public:
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 @@ public:
// 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 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
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.
+}
+