FontStyle resolved = resolvedFace->fStyle;
/* Prepare minikin FontStyle */
- const std::string& langs = paint->getTextLocales();
- FontLanguages minikinLangs(langs.c_str(), langs.size());
FontVariant minikinVariant = (paint->getFontVariant() == VARIANT_ELEGANT) ? VARIANT_ELEGANT
: VARIANT_COMPACT;
- FontStyle minikinStyle(minikinLangs, minikinVariant, resolved.getWeight(), resolved.getItalic());
+ const uint32_t langListId = paint->getMinikinLangListId();
+ FontStyle minikinStyle(langListId, minikinVariant, resolved.getWeight(), resolved.getItalic());
/* Prepare minikin Paint */
// Note: it would be nice to handle fractional size values (it would improve smooth zoom
paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
}
-struct LocalesCacheEntry {
- std::string javaLocales;
- std::string languageTags;
-};
-
-static thread_local LocalesCacheEntry sSingleEntryLocalesCache;
-
namespace PaintGlue {
enum MoveOpt {
AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
}
}
- static void setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) {
+ static jint setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) {
Paint* obj = reinterpret_cast<Paint*>(objHandle);
ScopedUtfChars localesChars(env, locales);
- if (sSingleEntryLocalesCache.javaLocales != localesChars.c_str()) {
- sSingleEntryLocalesCache.javaLocales = localesChars.c_str();
- toLanguageTags(&sSingleEntryLocalesCache.languageTags, localesChars.c_str());
- }
+ std::string buf;
+ toLanguageTags(&buf, localesChars.c_str());
+ jint minikinLangListId = FontStyle::registerLanguageList(buf);
+ obj->setMinikinLangListId(minikinLangListId);
+ return minikinLangListId;
+ }
- obj->setTextLocales(sSingleEntryLocalesCache.languageTags);
+ static void setTextLocalesByMinikinLangListId(JNIEnv* env, jobject clazz, jlong objHandle,
+ jint minikinLangListId) {
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
+ obj->setMinikinLangListId(minikinLangListId);
}
static jboolean isElegantTextHeight(JNIEnv* env, jobject, jlong paintHandle) {
{"nSetRasterizer","!(JJ)J", (void*) PaintGlue::setRasterizer},
{"nGetTextAlign","!(J)I", (void*) PaintGlue::getTextAlign},
{"nSetTextAlign","!(JI)V", (void*) PaintGlue::setTextAlign},
- {"nSetTextLocales","!(JLjava/lang/String;)V", (void*) PaintGlue::setTextLocales},
+ {"nSetTextLocales","!(JLjava/lang/String;)I", (void*) PaintGlue::setTextLocales},
+ {"nSetTextLocalesByMinikinLangListId","!(JI)V",
+ (void*) PaintGlue::setTextLocalesByMinikinLangListId},
{"nIsElegantTextHeight","!(J)Z", (void*) PaintGlue::isElegantTextHeight},
{"nSetElegantTextHeight","!(JZ)V", (void*) PaintGlue::setElegantTextHeight},
{"nGetTextSize","!(J)F", (void*) PaintGlue::getTextSize},
return mFontFeatureSettings;
}
- void setTextLocales(const std::string &textLocales) {
- mTextLocales = textLocales;
+ void setMinikinLangListId(uint32_t minikinLangListId) {
+ mMinikinLangListId = minikinLangListId;
}
- const std::string& getTextLocales() const {
- return mTextLocales;
+ uint32_t getMinikinLangListId() const {
+ return mMinikinLangListId;
}
void setFontVariant(FontVariant variant) {
private:
float mLetterSpacing = 0;
std::string mFontFeatureSettings;
- std::string mTextLocales;
+ uint32_t mMinikinLangListId;
FontVariant mFontVariant;
uint32_t mHyphenEdit = 0;
};
namespace android {
-Paint::Paint() : SkPaint(),
- mLetterSpacing(0), mFontFeatureSettings(), mTextLocales(), mFontVariant(VARIANT_DEFAULT) {
+Paint::Paint() :
+ SkPaint(), mLetterSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
+ mFontVariant(VARIANT_DEFAULT) {
}
Paint::Paint(const Paint& paint) : SkPaint(paint),
mLetterSpacing(paint.mLetterSpacing), mFontFeatureSettings(paint.mFontFeatureSettings),
- mTextLocales(paint.mTextLocales), mFontVariant(paint.mFontVariant),
+ mMinikinLangListId(paint.mMinikinLangListId), mFontVariant(paint.mFontVariant),
mHyphenEdit(paint.mHyphenEdit) {
}
SkPaint::operator=(other);
mLetterSpacing = other.mLetterSpacing;
mFontFeatureSettings = other.mFontFeatureSettings;
- mTextLocales = other.mTextLocales;
+ mMinikinLangListId = other.mMinikinLangListId;
mFontVariant = other.mFontVariant;
mHyphenEdit = other.mHyphenEdit;
return *this;
return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b)
&& a.mLetterSpacing == b.mLetterSpacing
&& a.mFontFeatureSettings == b.mFontFeatureSettings
- && a.mTextLocales == b.mTextLocales
+ && a.mMinikinLangListId == b.mMinikinLangListId
&& a.mFontVariant == b.mFontVariant
&& a.mHyphenEdit == b.mHyphenEdit;
}
import android.text.TextUtils;
import android.util.LocaleList;
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.HashMap;
import java.util.Locale;
/**
private LocaleList mLocales;
private String mFontFeatureSettings;
+ private static final Object sCacheLock = new Object();
+
+ /**
+ * Cache for the Minikin language list ID.
+ *
+ * A map from a string representation of the LocaleList to Minikin's language list ID.
+ */
+ @GuardedBy("sCacheLock")
+ private static final HashMap<String, Integer> sMinikinLangListIdCache = new HashMap<>();
+
/**
* @hide
*/
return;
}
mLocales = new LocaleList(locale);
- nSetTextLocales(mNativePaint, locale.toString());
+ syncTextLocalesWithMinikin();
}
/**
}
if (locales.equals(mLocales)) return;
mLocales = locales;
- nSetTextLocales(mNativePaint, locales.toLanguageTags());
+ syncTextLocalesWithMinikin();
+ }
+
+ private void syncTextLocalesWithMinikin() {
+ final String languageTags = mLocales.toLanguageTags();
+ final Integer minikinLangListId;
+ synchronized (sCacheLock) {
+ minikinLangListId = sMinikinLangListIdCache.get(languageTags);
+ if (minikinLangListId == null) {
+ final int newID = nSetTextLocales(mNativePaint, languageTags);
+ sMinikinLangListIdCache.put(languageTags, newID);
+ return;
+ }
+ }
+ nSetTextLocalesByMinikinLangListId(mNativePaint, minikinLangListId.intValue());
}
/**
private static native void nSetTextAlign(long paintPtr,
int align);
- private static native void nSetTextLocales(long paintPtr,
- String locales);
+ private static native int nSetTextLocales(long paintPtr, String locales);
+ private static native void nSetTextLocalesByMinikinLangListId(long paintPtr,
+ int mMinikinLangListId);
private static native float nGetTextAdvances(long paintPtr, long typefacePtr,
char[] text, int index, int count, int contextIndex, int contextCount,