aboutsummaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorBilly Hewlett <billyh@google.com>2012-07-03 17:03:55 -0700
committerVictoria Lease <violets@google.com>2012-08-20 08:43:58 -0700
commit725b3e03acb91dc69296554932624b36612bd189 (patch)
tree56edf31f828b49d7b202522b91ac389a29e55714 /src/core
parent8ab6679ce80dafa0d97c426c9fe70c6b6ceb20e6 (diff)
downloadexternal_skia-725b3e03acb91dc69296554932624b36612bd189.zip
external_skia-725b3e03acb91dc69296554932624b36612bd189.tar.gz
external_skia-725b3e03acb91dc69296554932624b36612bd189.tar.bz2
DO NOT MERGE Han Preference
Cherry-pick Id8c91ae0be6cad8a7ef77a0cd5803676290986c1 from master. During font initialization, create a seperate fallback list for each locale. At runtime, use the fallbacklist associated with the locale set in the paint object. Fallback files are associated with locales in fallback_fonts.xml. Multiple files can be associated with the same locale, ordering within that langauge and apart from that language in the fallback order is preserved. This changelist also includes some refactoring, notably of the functions that call getNextContext(). Change-Id: I121f0e491a522c4a8558a0066b2d8969fb8a3667
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkLanguage.cpp54
-rw-r--r--src/core/SkPaint.cpp26
-rw-r--r--src/core/SkScalerContext.cpp58
3 files changed, 106 insertions, 32 deletions
diff --git a/src/core/SkLanguage.cpp b/src/core/SkLanguage.cpp
new file mode 100644
index 0000000..3b8ba3c
--- /dev/null
+++ b/src/core/SkLanguage.cpp
@@ -0,0 +1,54 @@
+
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkLanguage.h"
+
+#ifdef SK_BUILD_FOR_ANDROID // currently only for Android
+
+#include "SkTDict.h"
+#include "SkThread.h"
+#include <cstring>
+
+SkLanguage SkLanguage::getParent() const {
+ SkASSERT(fInfo != NULL);
+ SkASSERT(fInfo->fTag != NULL);
+ const char* tag = fInfo->fTag.c_str();
+ SkASSERT(tag != NULL);
+
+ // strip off the rightmost "-.*"
+ char* parentTagEnd = strrchr(tag, '-');
+ if (parentTagEnd == NULL) {
+ return SkLanguage("");
+ }
+ size_t parentTagLen = parentTagEnd - tag;
+ char parentTag[parentTagLen + 1];
+ strncpy(parentTag, tag, parentTagLen);
+ parentTag[parentTagLen] = '\0';
+ return SkLanguage(parentTag);
+}
+
+SK_DECLARE_STATIC_MUTEX(gGetInfoMutex);
+const SkLanguageInfo* SkLanguage::getInfo(const char* tag) {
+ SkAutoMutexAcquire lock(gGetInfoMutex);
+
+ static const size_t kDictSize = 128;
+ static SkTDict<SkLanguageInfo*> tagToInfo(kDictSize);
+
+ // try a lookup
+ SkLanguageInfo* info;
+ if (tagToInfo.find(tag, &info)) {
+ return info;
+ }
+
+ // no match - add this language
+ info = new SkLanguageInfo(tag);
+ tagToInfo.set(tag, info);
+ return info;
+}
+
+#endif
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 412ab2b..35b5b38 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -32,6 +32,7 @@
//#define SK_REPORT_API_RANGE_CHECK
#ifdef SK_BUILD_FOR_ANDROID
+#include "SkLanguage.h"
#define GEN_ID_INC fGenerationID++
#define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; }
#else
@@ -71,7 +72,7 @@ SkPaint::SkPaint() {
fTextEncoding = kUTF8_TextEncoding;
fHinting = SkPaintDefaults_Hinting;
#ifdef SK_BUILD_FOR_ANDROID
- new(&fTextLocale) SkString();
+ fLanguage = SkLanguage();
fFontVariant = kDefault_Variant;
fGenerationID = 0;
#endif
@@ -89,9 +90,6 @@ SkPaint::SkPaint(const SkPaint& src) {
SkSafeRef(fRasterizer);
SkSafeRef(fLooper);
SkSafeRef(fImageFilter);
-#ifdef SK_BUILD_FOR_ANDROID
- new(&fTextLocale) SkString(src.fTextLocale);
-#endif
}
SkPaint::~SkPaint() {
@@ -130,12 +128,10 @@ SkPaint& SkPaint::operator=(const SkPaint& src) {
SkSafeUnref(fImageFilter);
#ifdef SK_BUILD_FOR_ANDROID
- fTextLocale.~SkString();
uint32_t oldGenerationID = fGenerationID;
#endif
memcpy(this, &src, sizeof(src));
#ifdef SK_BUILD_FOR_ANDROID
- new(&fTextLocale) SkString(src.fTextLocale);
fGenerationID = oldGenerationID + 1;
#endif
@@ -367,9 +363,9 @@ void SkPaint::setTextEncoding(TextEncoding encoding) {
}
#ifdef SK_BUILD_FOR_ANDROID
-void SkPaint::setTextLocale(const SkString& locale) {
- if(!fTextLocale.equals(locale)) {
- fTextLocale.set(locale);
+void SkPaint::setLanguage(const SkLanguage& language) {
+ if(fLanguage != language) {
+ fLanguage = language;
GEN_ID_INC;
}
}
@@ -1575,6 +1571,7 @@ void SkScalerContext::MakeRec(const SkPaint& paint,
rec->setLuminanceBits(computeLuminance(paint));
#endif
#ifdef SK_BUILD_FOR_ANDROID
+ rec->fLanguage = paint.getLanguage();
rec->fFontVariant = paint.getFontVariant();
#endif //SK_BUILD_FOR_ANDROID
@@ -1852,6 +1849,12 @@ void SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
*ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
this->getStyle(), this->getTextEncoding());
+#ifdef SK_BUILD_FOR_ANDROID
+ buffer.writeInt(this->getFontVariant());
+ const SkString& langTag = this->getLanguage().getTag();
+ buffer.writeString(langTag.c_str(), langTag.size());
+#endif
+
// now we're done with ptr and the (pre)reserved space. If we need to write
// additional fields, use the buffer directly
if (flatFlags & kHasTypeface_FlatFlag) {
@@ -1906,6 +1909,11 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
+#ifdef SK_BUILD_FOR_ANDROID
+ this->setFontVariant(SkPaint::FontVariant(buffer.readInt()));
+ this->setLanguage(SkLanguage(buffer.readString()));
+#endif
+
if (flatFlags & kHasTypeface_FlatFlag) {
this->setTypeface(buffer.readTypeface());
} else {
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index e33ad7a..85baf94 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -162,6 +162,22 @@ SkScalerContext* SkScalerContext::getNextContext() {
return next;
}
+SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni, unsigned& glyphID) {
+ SkScalerContext* ctx = this;
+ for (;;) {
+ glyphID = ctx->generateCharToGlyph(uni);
+ if (glyphID) {
+ break; // found it
+ }
+ ctx = ctx->getNextContext();
+ if (NULL == ctx) {
+ SkDebugf("--- no context for char %x\n", uni);
+ return NULL;
+ }
+ }
+ return ctx;
+}
+
SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
unsigned glyphID = glyph.getGlyphID();
SkScalerContext* ctx = this;
@@ -182,6 +198,16 @@ SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
}
#ifdef SK_BUILD_FOR_ANDROID
+SkFontID SkScalerContext::findTypefaceIdForChar(SkUnichar uni) {
+ unsigned glyphID;
+ SkScalerContext* ctx = getContextFromChar(uni, glyphID);
+ if (ctx) {
+ return ctx->fRec.fFontID;
+ } else {
+ return 0;
+ }
+}
+
/* This loops through all available fallback contexts (if needed) until it
finds some context that can handle the unichar and return it.
@@ -189,21 +215,13 @@ SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
char of a run.
*/
unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
- SkScalerContext* ctx = this;
unsigned glyphID;
- for (;;) {
- glyphID = ctx->generateCharToGlyph(uni);
- if (glyphID) {
- break; // found it
- }
- ctx = ctx->getNextContext();
- if (NULL == ctx) {
- SkDebugf("--- no context for char %x\n", uni);
- // just return the original context (this)
- return this->fBaseGlyphCount;
- }
+ SkScalerContext* ctx = getContextFromChar(uni, glyphID);
+ if (ctx) {
+ return ctx->fBaseGlyphCount;
+ } else {
+ return this->fBaseGlyphCount;
}
- return ctx->fBaseGlyphCount;
}
#endif
@@ -211,17 +229,11 @@ unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
finds some context that can handle the unichar. If all fail, returns 0
*/
uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) {
- SkScalerContext* ctx = this;
+
unsigned glyphID;
- for (;;) {
- glyphID = ctx->generateCharToGlyph(uni);
- if (glyphID) {
- break; // found it
- }
- ctx = ctx->getNextContext();
- if (NULL == ctx) {
- return 0; // no more contexts, return missing glyph
- }
+ SkScalerContext* ctx = getContextFromChar(uni, glyphID);
+ if (!ctx) {
+ return 0; // no more contexts, return missing glyph
}
// add the ctx's base, making glyphID unique for chain of contexts
glyphID += ctx->fBaseGlyphCount;