aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-09 20:54:20 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-09 20:54:20 +0000
commit14451703f1a53d0ff14ffe4f44436526383a5fd4 (patch)
tree768b16530b1f97d6e1c9ddca4b14fca1c1268c71
parent4a8084ced3fa5c73a364f96cadfa1fbfbea24ff6 (diff)
API modifications needed to upstream Android font changes.
R=reed@google.com Author: djsollen@google.com Review URL: https://chromiumcodereview.appspot.com/14761003 git-svn-id: http://skia.googlecode.com/svn/trunk@9083 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--gyp/core.gyp1
-rw-r--r--include/core/SkPaint.h10
-rw-r--r--include/core/SkPaintOptionsAndroid.h118
-rw-r--r--include/ports/SkTypeface_android.h8
-rw-r--r--src/core/SkPaint.cpp20
-rw-r--r--src/core/SkPaintOptionsAndroid.cpp65
-rw-r--r--src/core/SkScalerContext.cpp11
-rw-r--r--src/core/SkScalerContext.h11
-rw-r--r--src/ports/SkFontHost_android.cpp9
9 files changed, 243 insertions, 10 deletions
diff --git a/gyp/core.gyp b/gyp/core.gyp
index 7d9c9d774c..9e0792b773 100644
--- a/gyp/core.gyp
+++ b/gyp/core.gyp
@@ -79,6 +79,7 @@
[ 'skia_os == "android" and skia_arch_type == "arm" and armv7 == 1', {
# The code in SkUtilsArm.cpp can be used on an ARM-based Linux system, not only Android.
'sources': [
+ '../src/core/SkPaintOptionsAndroid.cpp',
'../src/core/SkUtilsArm.cpp',
'../src/core/SkUtilsArm.h',
],
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index a73a46a2c6..35a502d6b8 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -14,6 +14,9 @@
#include "SkColor.h"
#include "SkDrawLooper.h"
#include "SkXfermode.h"
+#ifdef SK_BUILD_FOR_ANDROID
+#include "SkPaintOptionsAndroid.h"
+#endif
class SkAnnotation;
class SkAutoGlyphCache;
@@ -860,6 +863,11 @@ public:
/** Returns the base glyph count for the strike associated with this paint
*/
unsigned getBaseGlyphCount(SkUnichar text) const;
+
+ const SkPaintOptionsAndroid& getPaintOptionsAndroid() const {
+ return fPaintOptionsAndroid;
+ }
+ void setPaintOptionsAndroid(const SkPaintOptionsAndroid& options);
#endif
// returns true if the paint's settings (e.g. xfermode + alpha) resolve to
@@ -990,6 +998,8 @@ private:
friend class SkTextToPathIter;
#ifdef SK_BUILD_FOR_ANDROID
+ SkPaintOptionsAndroid fPaintOptionsAndroid;
+
// In order for the == operator to work properly this must be the last field
// in the struct so that we can do a memcmp to this field's offset.
uint32_t fGenerationID;
diff --git a/include/core/SkPaintOptionsAndroid.h b/include/core/SkPaintOptionsAndroid.h
new file mode 100644
index 0000000000..235cae9a0a
--- /dev/null
+++ b/include/core/SkPaintOptionsAndroid.h
@@ -0,0 +1,118 @@
+
+/*
+ * 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.
+ */
+
+
+#ifndef SkPaintOptionsAndroid_DEFINED
+#define SkPaintOptionsAndroid_DEFINED
+
+#ifdef SK_BUILD_FOR_ANDROID
+
+#include "SkString.h"
+#include "SkTypes.h"
+
+class SkFlattenableReadBuffer;
+class SkFlattenableWriteBuffer;
+
+struct SkLanguageInfo {
+ SkLanguageInfo(const char* tag) : fTag(tag) { }
+ SkString fTag; //! BCP 47 language identifier
+};
+
+/** \class SkLanguage
+
+ The SkLanguage class represents a human written language, and is used by
+ text draw operations to determine which glyph to draw when drawing
+ characters with variants (ie Han-derived characters).
+*/
+class SkLanguage {
+public:
+ SkLanguage() : fInfo(getInfo("")) { }
+ SkLanguage(const char* tag) : fInfo(getInfo(tag)) { }
+ SkLanguage(const SkLanguage& b) : fInfo(b.fInfo) { }
+
+ /** Gets a BCP 47 language identifier for this SkLanguage.
+ @return a BCP 47 language identifier representing this language
+ */
+ const SkString& getTag() const { return fInfo->fTag; }
+
+ /** Performs BCP 47 fallback to return an SkLanguage one step more general.
+ @return an SkLanguage one step more general
+ */
+ SkLanguage getParent() const;
+
+ bool operator==(const SkLanguage& b) const {
+ return fInfo == b.fInfo;
+ }
+ bool operator!=(const SkLanguage& b) const {
+ return fInfo != b.fInfo;
+ }
+ bool operator<(const SkLanguage& b) const {
+ return fInfo < b.fInfo;
+ }
+ bool operator>(const SkLanguage& b) const {
+ return fInfo > b.fInfo;
+ }
+ SkLanguage& operator=(const SkLanguage& b) {
+ fInfo = b.fInfo;
+ return *this;
+ }
+
+private:
+ const SkLanguageInfo* fInfo;
+
+ static const SkLanguageInfo* getInfo(const char* tag);
+};
+
+class SkPaintOptionsAndroid {
+public:
+ SkPaintOptionsAndroid() {
+ fFontVariant = kDefault_Variant;
+ }
+
+ /** Return the paint's language value used for drawing text.
+ @return the paint's language value used for drawing text.
+ */
+ const SkLanguage& getLanguage() const { return fLanguage; }
+
+ /** Set the paint's language value used for drawing text.
+ @param language set the paint's language value for drawing text.
+ */
+ void setLanguage(const SkLanguage& language) { fLanguage = language; }
+ void setLanguage(const char* languageTag) { fLanguage = SkLanguage(languageTag); }
+
+
+ enum FontVariant {
+ kDefault_Variant, // Currently setting yourself to Default gives you Compact Variant
+ kCompact_Variant,
+ kElegant_Variant,
+ kLast_Variant = kElegant_Variant,
+ };
+
+ /** Return the font variant
+ @return the font variant used by this paint object
+ */
+ FontVariant getFontVariant() const { return fFontVariant; }
+
+ /** Set the font variant
+ @param fontVariant set the paint's font variant for choosing fonts
+ */
+ void setFontVariant(FontVariant fontVariant) {
+ SkASSERT((unsigned)fontVariant <= kLast_Variant);
+ fFontVariant = fontVariant;
+ }
+
+ void flatten(SkFlattenableWriteBuffer&) const;
+ void unflatten(SkFlattenableReadBuffer&);
+
+private:
+ SkLanguage fLanguage;
+ FontVariant fFontVariant;
+};
+
+#endif // #ifdef SK_BUILD_FOR_ANDROID
+#endif // #ifndef SkPaintOptionsAndroid_DEFINED
diff --git a/include/ports/SkTypeface_android.h b/include/ports/SkTypeface_android.h
index e87fa4805a..0d89736e7e 100644
--- a/include/ports/SkTypeface_android.h
+++ b/include/ports/SkTypeface_android.h
@@ -9,6 +9,8 @@
#ifndef SkTypeface_android_DEFINED
#define SkTypeface_android_DEFINED
+#ifdef SK_BUILD_FOR_ANDROID
+
#include "SkTypeface.h"
/**
@@ -39,6 +41,8 @@ SK_API void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackco
* get the 3rd can still inspect the original, and try to match its
* stylistic attributes.
*/
-SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID, SkFontID origFontID);
+SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID, SkFontID origFontID,
+ const SkPaintOptionsAndroid& options);
-#endif
+#endif // #ifdef SK_BUILD_FOR_ANDROID
+#endif // #ifndef SkTypeface_android_DEFINED
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 6c16428d81..18cf651616 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -180,14 +180,19 @@ uint32_t SkPaint::getGenerationID() const {
void SkPaint::setGenerationID(uint32_t generationID) {
fGenerationID = generationID;
}
-#endif
-#ifdef SK_BUILD_FOR_ANDROID
unsigned SkPaint::getBaseGlyphCount(SkUnichar text) const {
SkAutoGlyphCache autoCache(*this, NULL, NULL);
SkGlyphCache* cache = autoCache.getCache();
return cache->getBaseGlyphCount(text);
}
+
+void SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) {
+ if(!memcmp(&fPaintOptionsAndroid, &options, sizeof(SkPaintOptionsAndroid))) {
+ fPaintOptionsAndroid = options;
+ GEN_ID_INC;
+ }
+}
#endif
void SkPaint::setHinting(Hinting hintingLevel) {
@@ -1806,6 +1811,13 @@ void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion
}
+#ifdef SK_BUILD_FOR_ANDROID
+ SkOrderedWriteBuffer androidBuffer(128);
+ fPaintOptionsAndroid.flatten(androidBuffer);
+ descSize += androidBuffer.size();
+ entryCount += 1;
+#endif
+
///////////////////////////////////////////////////////////////////////////
// Now that we're done tweaking the rec, call the PostMakeRec cleanup
SkScalerContext::PostMakeRec(*this, &rec);
@@ -1818,6 +1830,10 @@ void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
desc->init();
desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
+#ifdef SK_BUILD_FOR_ANDROID
+ add_flattenable(desc, kAndroidOpts_SkDescriptorTag, &androidBuffer);
+#endif
+
if (pe) {
add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
}
diff --git a/src/core/SkPaintOptionsAndroid.cpp b/src/core/SkPaintOptionsAndroid.cpp
new file mode 100644
index 0000000000..ef9375ece6
--- /dev/null
+++ b/src/core/SkPaintOptionsAndroid.cpp
@@ -0,0 +1,65 @@
+
+/*
+ * 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.
+ */
+
+#ifdef SK_BUILD_FOR_ANDROID
+
+#include "SkPaintOptionsAndroid.h"
+#include "SkFlattenableBuffers.h"
+#include "SkTDict.h"
+#include "SkThread.h"
+#include <cstring>
+
+SkLanguage SkLanguage::getParent() const {
+ SkASSERT(fInfo != 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;
+}
+
+void SkPaintOptionsAndroid::flatten(SkFlattenableWriteBuffer& buffer) const {
+ buffer.writeUInt(fFontVariant);
+ buffer.writeString(fLanguage.getTag().c_str());
+}
+
+void SkPaintOptionsAndroid::unflatten(SkFlattenableReadBuffer& buffer) {
+ fFontVariant = (FontVariant)buffer.readUInt();
+ char* tag = buffer.readString();
+ fLanguage = SkLanguage(tag);
+ sk_free(tag);
+}
+
+#endif
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index ba14908c2e..a7e2432cc1 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -110,6 +110,14 @@ SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc)
desc->findEntry(kPathEffect_SkDescriptorTag, NULL),
desc->findEntry(kMaskFilter_SkDescriptorTag, NULL));
#endif
+#ifdef SK_BUILD_FOR_ANDROID
+ uint32_t len;
+ const void* data = desc->findEntry(kAndroidOpts_SkDescriptorTag, &len);
+ SkASSERT(data);
+ SkOrderedReadBuffer buffer(data, len);
+ fPaintOptionsAndroid.unflatten(buffer);
+ SkASSERT(buffer.offset() == buffer.size());
+#endif
}
SkScalerContext::~SkScalerContext() {
@@ -125,7 +133,8 @@ SkScalerContext::~SkScalerContext() {
SkScalerContext* SkScalerContext::allocNextContext() const {
#ifdef SK_BUILD_FOR_ANDROID
SkTypeface* newFace = SkAndroidNextLogicalTypeface(fRec.fFontID,
- fRec.fOrigFontID);
+ fRec.fOrigFontID,
+ fPaintOptionsAndroid);
if (0 == newFace) {
return NULL;
}
diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h
index d17b423496..06f5f94e17 100644
--- a/src/core/SkScalerContext.h
+++ b/src/core/SkScalerContext.h
@@ -14,6 +14,10 @@
#include "SkPaint.h"
#include "SkTypeface.h"
+#ifdef SK_BUILD_FOR_ANDROID
+ #include "SkPaintOptionsAndroid.h"
+#endif
+
struct SkGlyph;
class SkDescriptor;
class SkMaskFilter;
@@ -217,6 +221,10 @@ private:
// never null
SkAutoTUnref<SkTypeface> fTypeface;
+#ifdef SK_BUILD_FOR_ANDROID
+ SkPaintOptionsAndroid fPaintOptionsAndroid;
+#endif
+
// optional object, which may be null
SkPathEffect* fPathEffect;
SkMaskFilter* fMaskFilter;
@@ -262,6 +270,9 @@ private:
#define kPathEffect_SkDescriptorTag SkSetFourByteTag('p', 't', 'h', 'e')
#define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f')
#define kRasterizer_SkDescriptorTag SkSetFourByteTag('r', 'a', 's', 't')
+#ifdef SK_BUILD_FOR_ANDROID
+#define kAndroidOpts_SkDescriptorTag SkSetFourByteTag('a', 'n', 'd', 'r')
+#endif
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp
index ce478def6b..aeeec953d3 100644
--- a/src/ports/SkFontHost_android.cpp
+++ b/src/ports/SkFontHost_android.cpp
@@ -801,15 +801,15 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
return tf;
}
-SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID,
- SkFontID origFontID) {
-#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
+SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID, SkFontID origFontID,
+ const SkPaintOptionsAndroid& options) {
+#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
// Skia does not support font fallback for ndk applications in order to
// enable clients such as WebKit to customize their font selection.
// Clients can use GetFallbackFamilyNameForChar() to get the fallback
// font for individual characters.
return NULL;
-#else
+#endif
SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
load_system_fonts();
@@ -845,7 +845,6 @@ SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID,
// i.e. gFallbackFonts[0] != 0.
const SkTypeface* firstTypeface = find_from_uniqueID(list[0]);
return SkRef(find_typeface(firstTypeface, origTypeface->style()));
-#endif
}
///////////////////////////////////////////////////////////////////////////////