diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-09 20:54:20 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-09 20:54:20 +0000 |
commit | 14451703f1a53d0ff14ffe4f44436526383a5fd4 (patch) | |
tree | 768b16530b1f97d6e1c9ddca4b14fca1c1268c71 | |
parent | 4a8084ced3fa5c73a364f96cadfa1fbfbea24ff6 (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.gyp | 1 | ||||
-rw-r--r-- | include/core/SkPaint.h | 10 | ||||
-rw-r--r-- | include/core/SkPaintOptionsAndroid.h | 118 | ||||
-rw-r--r-- | include/ports/SkTypeface_android.h | 8 | ||||
-rw-r--r-- | src/core/SkPaint.cpp | 20 | ||||
-rw-r--r-- | src/core/SkPaintOptionsAndroid.cpp | 65 | ||||
-rw-r--r-- | src/core/SkScalerContext.cpp | 11 | ||||
-rw-r--r-- | src/core/SkScalerContext.h | 11 | ||||
-rw-r--r-- | src/ports/SkFontHost_android.cpp | 9 |
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 } /////////////////////////////////////////////////////////////////////////////// |