aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--ThirdPartyProject.prop9
-rw-r--r--include/core/SkScalerContext.h14
-rw-r--r--include/ports/SkTypeface_android.h24
-rw-r--r--src/core/SkGlyphCache.h2
-rw-r--r--src/ports/SkFontHost_android.cpp135
6 files changed, 175 insertions, 10 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/ThirdPartyProject.prop b/ThirdPartyProject.prop
deleted file mode 100644
index 6bd7584..0000000
--- a/ThirdPartyProject.prop
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2010 Google Inc. All Rights Reserved.
-#Fri Jul 16 10:03:09 PDT 2010
-currentVersion=Unknown
-version=Unknown
-isNative=true
-name=skia
-keywords=skia
-onDevice=true
-homepage=http\://code.google.com/p/skia/
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
index 1a02a55..3471a94 100644
--- a/include/ports/SkTypeface_android.h
+++ b/include/ports/SkTypeface_android.h
@@ -29,6 +29,28 @@ enum FallbackScripts {
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);
-SK_API SkTypeface* SkCreateTypefaceForScript(FallbackScripts script) {return NULL; }
#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.
+}
+