diff --git a/api/current.txt b/api/current.txt index 3ad7c72497f23..e13b3c282df17 100644 --- a/api/current.txt +++ b/api/current.txt @@ -10067,6 +10067,7 @@ package android.graphics { method public android.graphics.Xfermode getXfermode(); method public final boolean isAntiAlias(); method public final boolean isDither(); + method public boolean isElegantTextHeight(); method public final boolean isFakeBoldText(); method public final boolean isFilterBitmap(); method public final boolean isLinearText(); @@ -10085,6 +10086,7 @@ package android.graphics { method public void setColor(int); method public android.graphics.ColorFilter setColorFilter(android.graphics.ColorFilter); method public void setDither(boolean); + method public void setElegantTextHeight(boolean); method public void setFakeBoldText(boolean); method public void setFilterBitmap(boolean); method public void setFlags(int); @@ -34966,6 +34968,7 @@ package android.widget { method public void setCursorVisible(boolean); method public void setCustomSelectionActionModeCallback(android.view.ActionMode.Callback); method public final void setEditableFactory(android.text.Editable.Factory); + method public void setElegantTextHeight(boolean); method public void setEllipsize(android.text.TextUtils.TruncateAt); method public void setEms(int); method public void setError(java.lang.CharSequence); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index a7278dae4497c..b91111d5e336c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -652,6 +652,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener boolean allCaps = false; int shadowcolor = 0; float dx = 0, dy = 0, r = 0; + boolean elegant = false; final Resources.Theme theme = context.getTheme(); @@ -728,6 +729,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener case com.android.internal.R.styleable.TextAppearance_shadowRadius: r = appearance.getFloat(attr, 0); break; + + case com.android.internal.R.styleable.TextAppearance_elegantTextHeight: + elegant = appearance.getBoolean(attr, false); + break; } } @@ -1065,6 +1070,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener case com.android.internal.R.styleable.TextView_textAllCaps: allCaps = a.getBoolean(attr, false); break; + + case com.android.internal.R.styleable.TextView_elegantTextHeight: + elegant = a.getBoolean(attr, false); + break; } } a.recycle(); @@ -1245,6 +1254,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener setHighlightColor(textColorHighlight); } setRawTextSize(textSize); + setElegantTextHeight(elegant); if (allCaps) { setTransformationMethod(new AllCapsTransformationMethod(getContext())); @@ -2468,6 +2478,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener setTransformationMethod(new AllCapsTransformationMethod(getContext())); } + if (appearance.hasValue(com.android.internal.R.styleable.TextAppearance_elegantTextHeight)) { + setElegantTextHeight(appearance.getBoolean( + com.android.internal.R.styleable.TextAppearance_elegantTextHeight, false)); + } + appearance.recycle(); } @@ -2614,6 +2629,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return mTextPaint.getTypeface(); } + /** + * Set the TextView's elegant height metrics flag. This setting selects font + * variants that have not been compacted to fit Latin-based vertical + * metrics, and also increases top and bottom bounds to provide more space. + * + * @param elegant set the paint's elegant metrics flag. + */ + public void setElegantTextHeight(boolean elegant) { + mTextPaint.setElegantTextHeight(elegant); + } + /** * Sets the text color for all the states (normal, selected, * focused) to be this color. diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index f77a389cc45a5..08a88d15974e2 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -357,6 +357,24 @@ public: obj->setPaintOptionsAndroid(paintOpts); } + static jboolean isElegantTextHeight(JNIEnv* env, jobject paint) { + NPE_CHECK_RETURN_ZERO(env, paint); + SkPaint* obj = GraphicsJNI::getNativePaint(env, paint); + SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid(); + return paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant; + } + + static void setElegantTextHeight(JNIEnv* env, jobject paint, jboolean aa) { + NPE_CHECK_RETURN_VOID(env, paint); + SkPaint* obj = GraphicsJNI::getNativePaint(env, paint); + SkPaintOptionsAndroid::FontVariant variant = + aa ? SkPaintOptionsAndroid::kElegant_Variant : + SkPaintOptionsAndroid::kDefault_Variant; + SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid(); + paintOpts.setFontVariant(variant); + obj->setPaintOptionsAndroid(paintOpts); + } + static jfloat getTextSize(JNIEnv* env, jobject paint) { NPE_CHECK_RETURN_ZERO(env, paint); return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize()); @@ -401,10 +419,30 @@ public: return SkScalarToFloat(metrics.fDescent); } + static SkScalar getMetricsInternal(SkPaint *paint, SkPaint::FontMetrics *metrics) { + const int kElegantTop = 2500; + const int kElegantBottom = -1000; + const int kElegantAscent = 1946; + const int kElegantDescent = -512; + const int kElegantLeading = 0; + SkScalar spacing = paint->getFontMetrics(metrics); + SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid(); + if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) { + SkScalar size = paint->getTextSize(); + metrics->fTop = -size * kElegantTop / 2048; + metrics->fBottom = -size * kElegantBottom / 2048; + metrics->fAscent = -size * kElegantAscent / 2048; + metrics->fDescent = -size * kElegantDescent / 2048; + metrics->fLeading = size * kElegantLeading / 2048; + spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading; + } + return spacing; + } + static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) { NPE_CHECK_RETURN_ZERO(env, paint); SkPaint::FontMetrics metrics; - SkScalar spacing = GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics); + SkScalar spacing = getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics); if (metricsObj) { SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class)); @@ -421,7 +459,7 @@ public: NPE_CHECK_RETURN_ZERO(env, paint); SkPaint::FontMetrics metrics; - GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics); + getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics); int ascent = SkScalarRoundToInt(metrics.fAscent); int descent = SkScalarRoundToInt(metrics.fDescent); int leading = SkScalarRoundToInt(metrics.fLeading); @@ -894,6 +932,8 @@ static JNINativeMethod methods[] = { {"native_getTextAlign","(J)I", (void*) SkPaintGlue::getTextAlign}, {"native_setTextAlign","(JI)V", (void*) SkPaintGlue::setTextAlign}, {"native_setTextLocale","(JLjava/lang/String;)V", (void*) SkPaintGlue::setTextLocale}, + {"isElegantTextHeight","()Z", (void*) SkPaintGlue::isElegantTextHeight}, + {"setElegantTextHeight","(Z)V", (void*) SkPaintGlue::setElegantTextHeight}, {"getTextSize","()F", (void*) SkPaintGlue::getTextSize}, {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize}, {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX}, diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 53fed98cd5fe4..782066e30fa03 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -3428,6 +3428,8 @@ + + + + diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml index e42703e053c2b..bdc7ad0d253c0 100644 --- a/core/res/res/values/styles_quantum.xml +++ b/core/res/res/values/styles_quantum.xml @@ -97,6 +97,7 @@ please see styles_device_defaults.xml. ?textColorLink @dimen/text_size_body_1_quantum @string/font_family_body_1_quantum + true