New attribute textFontWeight for selecting weight in the font family
Note that AppCompatTextView doesn't work well with this attribute since it overwrites the selected Typeface. Bug: 63135308 Test: atest android.widget.cts.TextViewFontWeightTest Change-Id: I76ee5e3007ea5f96249d2a0bfb66ff5975c62522
This commit is contained in:
@@ -1378,6 +1378,7 @@ package android {
|
||||
field public static final int textEditSidePasteWindowLayout = 16843614; // 0x101035e
|
||||
field public static final int textEditSuggestionItemLayout = 16843636; // 0x1010374
|
||||
field public static final int textFilterEnabled = 16843007; // 0x10100ff
|
||||
field public static final int textFontWeight = 16844166; // 0x1010586
|
||||
field public static final int textIsSelectable = 16843542; // 0x1010316
|
||||
field public static final int textOff = 16843045; // 0x1010125
|
||||
field public static final int textOn = 16843044; // 0x1010124
|
||||
|
||||
@@ -319,6 +319,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
|
||||
// Enum for the "typeface" XML parameter.
|
||||
// TODO: How can we get this from the XML instead of hardcoding it here?
|
||||
/** @hide */
|
||||
@IntDef(value = {DEFAULT_TYPEFACE, SANS, SERIF, MONOSPACE})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface XMLTypefaceAttr{}
|
||||
private static final int DEFAULT_TYPEFACE = -1;
|
||||
private static final int SANS = 1;
|
||||
private static final int SERIF = 2;
|
||||
private static final int MONOSPACE = 3;
|
||||
@@ -1976,33 +1981,52 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
}
|
||||
}
|
||||
|
||||
private void setTypefaceFromAttrs(Typeface fontTypeface, String familyName, int typefaceIndex,
|
||||
int styleIndex) {
|
||||
Typeface tf = fontTypeface;
|
||||
if (tf == null && familyName != null) {
|
||||
tf = Typeface.create(familyName, styleIndex);
|
||||
} else if (tf != null && tf.getStyle() != styleIndex) {
|
||||
tf = Typeface.create(tf, styleIndex);
|
||||
/**
|
||||
* Sets the Typeface taking into account the given attributes.
|
||||
*
|
||||
* @param typeface a typeface
|
||||
* @param familyName family name string, e.g. "serif"
|
||||
* @param typefaceIndex an index of the typeface enum, e.g. SANS, SERIF.
|
||||
* @param style a typeface style
|
||||
* @param weight a weight value for the Typeface or -1 if not specified.
|
||||
*/
|
||||
private void setTypefaceFromAttrs(@Nullable Typeface typeface, @Nullable String familyName,
|
||||
@XMLTypefaceAttr int typefaceIndex, @Typeface.Style int style,
|
||||
@IntRange(from = -1, to = Typeface.MAX_WEIGHT) int weight) {
|
||||
if (typeface == null && familyName != null) {
|
||||
// Lookup normal Typeface from system font map.
|
||||
final Typeface normalTypeface = Typeface.create(familyName, Typeface.NORMAL);
|
||||
resolveStyleAndSetTypeface(normalTypeface, style, weight);
|
||||
} else if (typeface != null) {
|
||||
resolveStyleAndSetTypeface(typeface, style, weight);
|
||||
} else { // both typeface and familyName is null.
|
||||
switch (typefaceIndex) {
|
||||
case SANS:
|
||||
resolveStyleAndSetTypeface(Typeface.SANS_SERIF, style, weight);
|
||||
break;
|
||||
case SERIF:
|
||||
resolveStyleAndSetTypeface(Typeface.SERIF, style, weight);
|
||||
break;
|
||||
case MONOSPACE:
|
||||
resolveStyleAndSetTypeface(Typeface.MONOSPACE, style, weight);
|
||||
break;
|
||||
case DEFAULT_TYPEFACE:
|
||||
default:
|
||||
resolveStyleAndSetTypeface(null, style, weight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tf != null) {
|
||||
setTypeface(tf);
|
||||
return;
|
||||
}
|
||||
|
||||
private void resolveStyleAndSetTypeface(@NonNull Typeface typeface, @Typeface.Style int style,
|
||||
@IntRange(from = -1, to = Typeface.MAX_WEIGHT) int weight) {
|
||||
if (weight >= 0) {
|
||||
weight = Math.min(Typeface.MAX_WEIGHT, weight);
|
||||
final boolean italic = (style & Typeface.ITALIC) != 0;
|
||||
setTypeface(Typeface.create(typeface, weight, italic));
|
||||
} else {
|
||||
setTypeface(Typeface.create(typeface, style));
|
||||
}
|
||||
switch (typefaceIndex) {
|
||||
case SANS:
|
||||
tf = Typeface.SANS_SERIF;
|
||||
break;
|
||||
|
||||
case SERIF:
|
||||
tf = Typeface.SERIF;
|
||||
break;
|
||||
|
||||
case MONOSPACE:
|
||||
tf = Typeface.MONOSPACE;
|
||||
break;
|
||||
}
|
||||
|
||||
setTypeface(tf, styleIndex);
|
||||
}
|
||||
|
||||
private void setRelativeDrawablesIfNeeded(Drawable start, Drawable end) {
|
||||
@@ -3392,6 +3416,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
boolean mFontFamilyExplicit = false;
|
||||
int mTypefaceIndex = -1;
|
||||
int mStyleIndex = -1;
|
||||
int mFontWeight = -1;
|
||||
boolean mAllCaps = false;
|
||||
int mShadowColor = 0;
|
||||
float mShadowDx = 0, mShadowDy = 0, mShadowRadius = 0;
|
||||
@@ -3416,6 +3441,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
+ " mFontFamilyExplicit:" + mFontFamilyExplicit + "\n"
|
||||
+ " mTypefaceIndex:" + mTypefaceIndex + "\n"
|
||||
+ " mStyleIndex:" + mStyleIndex + "\n"
|
||||
+ " mFontWeight:" + mFontWeight + "\n"
|
||||
+ " mAllCaps:" + mAllCaps + "\n"
|
||||
+ " mShadowColor:" + mShadowColor + "\n"
|
||||
+ " mShadowDx:" + mShadowDx + "\n"
|
||||
@@ -3451,6 +3477,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
com.android.internal.R.styleable.TextAppearance_fontFamily);
|
||||
sAppearanceValues.put(com.android.internal.R.styleable.TextView_textStyle,
|
||||
com.android.internal.R.styleable.TextAppearance_textStyle);
|
||||
sAppearanceValues.put(com.android.internal.R.styleable.TextView_textFontWeight,
|
||||
com.android.internal.R.styleable.TextAppearance_textFontWeight);
|
||||
sAppearanceValues.put(com.android.internal.R.styleable.TextView_textAllCaps,
|
||||
com.android.internal.R.styleable.TextAppearance_textAllCaps);
|
||||
sAppearanceValues.put(com.android.internal.R.styleable.TextView_shadowColor,
|
||||
@@ -3536,6 +3564,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
case com.android.internal.R.styleable.TextAppearance_textStyle:
|
||||
attributes.mStyleIndex = appearance.getInt(attr, attributes.mStyleIndex);
|
||||
break;
|
||||
case com.android.internal.R.styleable.TextAppearance_textFontWeight:
|
||||
attributes.mFontWeight = appearance.getInt(attr, attributes.mFontWeight);
|
||||
break;
|
||||
case com.android.internal.R.styleable.TextAppearance_textAllCaps:
|
||||
attributes.mAllCaps = appearance.getBoolean(attr, attributes.mAllCaps);
|
||||
break;
|
||||
@@ -3598,7 +3629,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
attributes.mFontFamily = null;
|
||||
}
|
||||
setTypefaceFromAttrs(attributes.mFontTypeface, attributes.mFontFamily,
|
||||
attributes.mTypefaceIndex, attributes.mStyleIndex);
|
||||
attributes.mTypefaceIndex, attributes.mStyleIndex, attributes.mFontWeight);
|
||||
|
||||
if (attributes.mShadowColor != 0) {
|
||||
setShadowLayer(attributes.mShadowRadius, attributes.mShadowDx, attributes.mShadowDy,
|
||||
@@ -5938,15 +5969,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
boolean forceUpdate = false;
|
||||
if (isPassword) {
|
||||
setTransformationMethod(PasswordTransformationMethod.getInstance());
|
||||
setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, MONOSPACE, 0);
|
||||
setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, MONOSPACE,
|
||||
Typeface.NORMAL, -1 /* weight, not specifeid */);
|
||||
} else if (isVisiblePassword) {
|
||||
if (mTransformation == PasswordTransformationMethod.getInstance()) {
|
||||
forceUpdate = true;
|
||||
}
|
||||
setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, MONOSPACE, 0);
|
||||
setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, MONOSPACE,
|
||||
Typeface.NORMAL, -1 /* weight, not specified */);
|
||||
} else if (wasPassword || wasVisiblePassword) {
|
||||
// not in password mode, clean up typeface and transformation
|
||||
setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, -1, -1);
|
||||
setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */,
|
||||
DEFAULT_TYPEFACE /* typeface index */, Typeface.NORMAL,
|
||||
-1 /* weight, not specified */);
|
||||
if (mTransformation == PasswordTransformationMethod.getInstance()) {
|
||||
forceUpdate = true;
|
||||
}
|
||||
|
||||
@@ -4472,6 +4472,8 @@
|
||||
<attr name="textSize" />
|
||||
<!-- Style (normal, bold, italic, bold|italic) for the text. -->
|
||||
<attr name="textStyle" />
|
||||
<!-- Weight for the font used in the TextView. -->
|
||||
<attr name="textFontWeight" />
|
||||
<!-- Typeface (normal, sans, serif, monospace) for the text. -->
|
||||
<attr name="typeface" />
|
||||
<!-- Font family (named by string or as a font resource reference) for the text. -->
|
||||
@@ -4561,6 +4563,8 @@
|
||||
<attr name="typeface" />
|
||||
<!-- Style (normal, bold, italic, bold|italic) for the text. -->
|
||||
<attr name="textStyle" />
|
||||
<!-- Weight for the font used in the TextView. -->
|
||||
<attr name="textFontWeight" />
|
||||
<!-- Font family (named by string or as a font resource reference) for the text. -->
|
||||
<attr name="fontFamily" />
|
||||
<!-- Text color for links. -->
|
||||
|
||||
@@ -2872,6 +2872,7 @@
|
||||
<public name="urlBarResourceId" />
|
||||
<!-- @hide @SystemApi -->
|
||||
<public name="userRestriction" />
|
||||
<public name="textFontWeight" />
|
||||
</public-group>
|
||||
|
||||
<public-group type="style" first-id="0x010302e0">
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.content.res.FontResourcesParser.FontFamilyFilesResourceEnt
|
||||
import static android.content.res.FontResourcesParser.FontFileResourceEntry;
|
||||
import static android.content.res.FontResourcesParser.ProviderResourceEntry;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -49,6 +50,8 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
@@ -117,6 +120,11 @@ public class Typeface {
|
||||
*/
|
||||
public long native_instance;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(value = {NORMAL, BOLD, ITALIC, BOLD_ITALIC})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Style {}
|
||||
|
||||
// Style
|
||||
public static final int NORMAL = 0;
|
||||
public static final int BOLD = 1;
|
||||
@@ -124,8 +132,15 @@ public class Typeface {
|
||||
public static final int BOLD_ITALIC = 3;
|
||||
/** @hide */ public static final int STYLE_MASK = 0x03;
|
||||
|
||||
private int mStyle = 0;
|
||||
private int mWeight = 0;
|
||||
private @Style int mStyle = 0;
|
||||
|
||||
/**
|
||||
* A maximum value for the weight value.
|
||||
* @hide
|
||||
*/
|
||||
public static final int MAX_WEIGHT = 1000;
|
||||
|
||||
private @IntRange(from = 0, to = MAX_WEIGHT) int mWeight = 0;
|
||||
|
||||
// Value for weight and italic. Indicates the value is resolved by font metadata.
|
||||
// Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
|
||||
@@ -153,7 +168,7 @@ public class Typeface {
|
||||
}
|
||||
|
||||
/** Returns the typeface's intrinsic style attributes */
|
||||
public int getStyle() {
|
||||
public @Style int getStyle() {
|
||||
return mStyle;
|
||||
}
|
||||
|
||||
@@ -659,7 +674,7 @@ public class Typeface {
|
||||
* e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC
|
||||
* @return The best matching typeface.
|
||||
*/
|
||||
public static Typeface create(String familyName, int style) {
|
||||
public static Typeface create(String familyName, @Style int style) {
|
||||
return create(sSystemFontMap.get(familyName), style);
|
||||
}
|
||||
|
||||
@@ -680,7 +695,7 @@ public class Typeface {
|
||||
* e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC
|
||||
* @return The best matching typeface.
|
||||
*/
|
||||
public static Typeface create(Typeface family, int style) {
|
||||
public static Typeface create(Typeface family, @Style int style) {
|
||||
if ((style & ~STYLE_MASK) != 0) {
|
||||
style = NORMAL;
|
||||
}
|
||||
@@ -776,7 +791,7 @@ public class Typeface {
|
||||
*
|
||||
* @return the default typeface that corresponds to the style
|
||||
*/
|
||||
public static Typeface defaultFromStyle(int style) {
|
||||
public static Typeface defaultFromStyle(@Style int style) {
|
||||
return sDefaults[style];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user