Merge "Add letter-spacing to Paint and TextView" into lmp-dev

This commit is contained in:
Behdad Esfahbod
2014-07-24 22:56:20 +00:00
committed by Android (Google) Code Review
8 changed files with 117 additions and 6 deletions

View File

@@ -222,6 +222,7 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
* @attr ref android.R.styleable#TextView_imeActionId
* @attr ref android.R.styleable#TextView_editorExtras
* @attr ref android.R.styleable#TextView_elegantTextHeight
* @attr ref android.R.styleable#TextView_letterSpacing
*/
@RemoteView
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
@@ -657,6 +658,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int shadowcolor = 0;
float dx = 0, dy = 0, r = 0;
boolean elegant = false;
float letterSpacing = 0;
final Resources.Theme theme = context.getTheme();
@@ -737,6 +739,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case com.android.internal.R.styleable.TextAppearance_elegantTextHeight:
elegant = appearance.getBoolean(attr, false);
break;
case com.android.internal.R.styleable.TextAppearance_letterSpacing:
letterSpacing = appearance.getFloat(attr, 0);
break;
}
}
@@ -1078,6 +1084,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case com.android.internal.R.styleable.TextView_elegantTextHeight:
elegant = a.getBoolean(attr, false);
break;
case com.android.internal.R.styleable.TextView_letterSpacing:
letterSpacing = a.getFloat(attr, 0);
break;
}
}
a.recycle();
@@ -1259,6 +1269,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
setRawTextSize(textSize);
setElegantTextHeight(elegant);
setLetterSpacing(letterSpacing);
if (allCaps) {
setTransformationMethod(new AllCapsTransformationMethod(getContext()));
@@ -2487,6 +2498,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
com.android.internal.R.styleable.TextAppearance_elegantTextHeight, false));
}
if (appearance.hasValue(com.android.internal.R.styleable.TextAppearance_letterSpacing)) {
setLetterSpacing(appearance.getFloat(
com.android.internal.R.styleable.TextAppearance_letterSpacing, 0));
}
appearance.recycle();
}
@@ -2666,6 +2682,41 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mTextPaint.setElegantTextHeight(elegant);
}
/**
* @return the extent by which text is currently being letter-spaced.
* This will normally be 0.
*
* @see #setLetterSpacing(float)
* @hide
*/
public float getLetterSpacing() {
return mTextPaint.getLetterSpacing();
}
/**
* Sets text letter-spacing. The value is in 'EM' units. Typical values
* for slight expansion will be around 0.05. Negative values tighten text.
*
* @see #getLetterSpacing()
* @see Paint#setFlags
*
* @attr ref android.R.styleable#TextView_letterSpacing
* @hide
*/
@android.view.RemotableViewMethod
public void setLetterSpacing(float letterSpacing) {
if (letterSpacing != mTextPaint.getLetterSpacing()) {
mTextPaint.setLetterSpacing(letterSpacing);
if (mLayout != null) {
nullLayouts();
requestLayout();
invalidate();
}
}
}
/**
* Sets the text color for all the states (normal, selected,
* focused) to be this color.

View File

@@ -29,6 +29,8 @@
namespace android {
// Do an sprintf starting at offset n, abort on overflow
static int snprintfcat(char* buf, int off, int size, const char* format, ...)
__attribute__((__format__(__printf__, 4, 5)));
static int snprintfcat(char* buf, int off, int size, const char* format, ...) {
va_list args;
va_start(args, format);
@@ -43,17 +45,18 @@ std::string MinikinUtils::setLayoutProperties(Layout* layout, const Paint* paint
TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
layout->setFontCollection(resolvedFace->fFontCollection);
FontStyle style = resolvedFace->fStyle;
char css[256];
char css[512];
int off = snprintfcat(css, 0, sizeof(css),
"font-size: %d; font-scale-x: %f; font-skew-x: %f; -paint-flags: %d;"
" font-weight: %d; font-style: %s; -minikin-bidi: %d;",
" font-weight: %d; font-style: %s; -minikin-bidi: %d; letter-spacing: %f;",
(int)paint->getTextSize(),
paint->getTextScaleX(),
paint->getTextSkewX(),
MinikinFontSkia::packPaintFlags(paint),
style.getWeight() * 100,
style.getItalic() ? "italic" : "normal",
bidiFlags);
bidiFlags,
paint->getLetterSpacing());
SkString langString = paint->getPaintOptionsAndroid().getLanguage().getTag();
off = snprintfcat(css, off, sizeof(css), " lang: %s;", langString.c_str());
SkPaintOptionsAndroid::FontVariant var = paint->getPaintOptionsAndroid().getFontVariant();

View File

@@ -423,6 +423,16 @@ public:
GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
}
static jfloat getLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle) {
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
return paint->getLetterSpacing();
}
static void setLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat letterSpacing) {
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
paint->setLetterSpacing(letterSpacing);
}
static SkScalar getMetricsInternal(JNIEnv* env, jobject jpaint, Paint::FontMetrics *metrics) {
const int kElegantTop = 2500;
const int kElegantBottom = -1000;
@@ -988,6 +998,8 @@ static JNINativeMethod methods[] = {
{"setTextScaleX","(F)V", (void*) PaintGlue::setTextScaleX},
{"getTextSkewX","()F", (void*) PaintGlue::getTextSkewX},
{"setTextSkewX","(F)V", (void*) PaintGlue::setTextSkewX},
{"native_getLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing},
{"native_setLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing},
{"ascent","()F", (void*) PaintGlue::ascent},
{"descent","()F", (void*) PaintGlue::descent},
{"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)PaintGlue::getFontMetrics},

View File

@@ -34,7 +34,16 @@ public:
return !(a == b);
}
void setLetterSpacing(float letterSpacing) {
mLetterSpacing = letterSpacing;
}
float getLetterSpacing() const {
return mLetterSpacing;
}
private:
float mLetterSpacing;
};
} // namespace android

View File

@@ -22,10 +22,12 @@
namespace android {
Paint::Paint() : SkPaint() {
Paint::Paint() : SkPaint(),
mLetterSpacing(0) {
}
Paint::Paint(const Paint& paint) : SkPaint(paint) {
Paint::Paint(const Paint& paint) : SkPaint(paint),
mLetterSpacing(0) {
}
Paint::~Paint() {
@@ -33,11 +35,13 @@ Paint::~Paint() {
Paint& Paint::operator=(const Paint& other) {
SkPaint::operator=(other);
mLetterSpacing = other.mLetterSpacing;
return *this;
}
bool operator==(const Paint& a, const Paint& b) {
return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b);
return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b)
&& a.mLetterSpacing == b.mLetterSpacing;
}
}

View File

@@ -3755,6 +3755,8 @@
<attr name="shadowRadius" format="float" />
<!-- Elegant text height, especially for less compacted complex script text. -->
<attr name="elegantTextHeight" format="boolean" />
<!-- @hide Text letter-spacing. -->
<attr name="letterSpacing" format="float" />
</declare-styleable>
<declare-styleable name="TextClock">
<!-- Specifies the formatting pattern used to show the time and/or date
@@ -4048,6 +4050,8 @@
<attr name="textAllCaps" />
<!-- Elegant text height, especially for less compacted complex script text. -->
<attr name="elegantTextHeight" />
<!-- @hide Text letter-spacing. -->
<attr name="letterSpacing" />
</declare-styleable>
<declare-styleable name="TextViewAppearance">
<!-- Base text color, typeface, size, and style. -->

View File

@@ -2268,6 +2268,7 @@
<public type="attr" name="checkMarkTintMode" />
<public type="attr" name="popupTheme" />
<public type="attr" name="toolbarStyle" />
<public type="attr" name="letterSpacing" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />

View File

@@ -1259,6 +1259,29 @@ public class Paint {
*/
public native void setTextSkewX(float skewX);
/**
* Return the paint's letter-spacing for text. The default value
* is 0.
*
* @return the paint's letter-spacing for drawing text.
* @hide
*/
public float getLetterSpacing() {
return native_getLetterSpacing(mNativePaint);
}
/**
* Set the paint's letter-spacing for text. The default value
* is 0. The value is in 'EM' units. Typical values for slight
* expansion will be around 0.05. Negative values tighten text.
*
* @param letterSpacing set the paint's letter-spacing for drawing text.
* @hide
*/
public void setLetterSpacing(float letterSpacing) {
native_setLetterSpacing(mNativePaint, letterSpacing);
}
/**
* Return the distance above (negative) the baseline (ascent) based on the
* current typeface and text size.
@@ -2232,4 +2255,8 @@ public class Paint {
private static native void native_setShadowLayer(long native_object,
float radius, float dx, float dy, int color);
private static native boolean native_hasShadowLayer(long native_object);
private static native float native_getLetterSpacing(long native_object);
private static native void native_setLetterSpacing(long native_object,
float letterSpacing);
}