diff --git a/api/current.txt b/api/current.txt index 3a23b0fac6817..e8d49c3f0e285 100644 --- a/api/current.txt +++ b/api/current.txt @@ -793,6 +793,7 @@ package android { field public static final int layout_x = 16843135; // 0x101017f field public static final int layout_y = 16843136; // 0x1010180 field public static final int left = 16843181; // 0x10101ad + field public static final int leftIndents = 16844016; // 0x10104f0 field public static final int letterSpacing = 16843958; // 0x10104b6 field public static final int lineSpacingExtra = 16843287; // 0x1010217 field public static final int lineSpacingMultiplier = 16843288; // 0x1010218 @@ -1021,6 +1022,7 @@ package android { field public static final int reversible = 16843851; // 0x101044b field public static final int revisionCode = 16843989; // 0x10104d5 field public static final int right = 16843183; // 0x10101af + field public static final int rightIndents = 16844017; // 0x10104f1 field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093 field public static final int ringtoneType = 16843257; // 0x10101f9 field public static final int rotation = 16843558; // 0x1010326 @@ -41225,6 +41227,7 @@ package android.widget { method public int getInputType(); method public final android.text.method.KeyListener getKeyListener(); method public final android.text.Layout getLayout(); + method public int[] getLeftIndents(); method public float getLetterSpacing(); method public int getLineBounds(int, android.graphics.Rect); method public int getLineCount(); @@ -41247,6 +41250,7 @@ package android.widget { method public android.text.TextPaint getPaint(); method public int getPaintFlags(); method public java.lang.String getPrivateImeOptions(); + method public int[] getRightIndents(); method public int getSelectionEnd(); method public int getSelectionStart(); method public int getShadowColor(); @@ -41324,6 +41328,7 @@ package android.widget { method public void setImeActionLabel(java.lang.CharSequence, int); method public void setImeOptions(int); method public void setIncludeFontPadding(boolean); + method public void setIndents(int[], int[]); method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public void setInputType(int); method public void setKeyListener(android.text.method.KeyListener); diff --git a/api/system-current.txt b/api/system-current.txt index ef3d3df9ac810..0bc83c38f91a0 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -866,6 +866,7 @@ package android { field public static final int layout_x = 16843135; // 0x101017f field public static final int layout_y = 16843136; // 0x1010180 field public static final int left = 16843181; // 0x10101ad + field public static final int leftIndents = 16844016; // 0x10104f0 field public static final int letterSpacing = 16843958; // 0x10104b6 field public static final int lineSpacingExtra = 16843287; // 0x1010217 field public static final int lineSpacingMultiplier = 16843288; // 0x1010218 @@ -1094,6 +1095,7 @@ package android { field public static final int reversible = 16843851; // 0x101044b field public static final int revisionCode = 16843989; // 0x10104d5 field public static final int right = 16843183; // 0x10101af + field public static final int rightIndents = 16844017; // 0x10104f1 field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093 field public static final int ringtoneType = 16843257; // 0x10101f9 field public static final int rotation = 16843558; // 0x1010326 @@ -43692,6 +43694,7 @@ package android.widget { method public int getInputType(); method public final android.text.method.KeyListener getKeyListener(); method public final android.text.Layout getLayout(); + method public int[] getLeftIndents(); method public float getLetterSpacing(); method public int getLineBounds(int, android.graphics.Rect); method public int getLineCount(); @@ -43714,6 +43717,7 @@ package android.widget { method public android.text.TextPaint getPaint(); method public int getPaintFlags(); method public java.lang.String getPrivateImeOptions(); + method public int[] getRightIndents(); method public int getSelectionEnd(); method public int getSelectionStart(); method public int getShadowColor(); @@ -43791,6 +43795,7 @@ package android.widget { method public void setImeActionLabel(java.lang.CharSequence, int); method public void setImeOptions(int); method public void setIncludeFontPadding(boolean); + method public void setIndents(int[], int[]); method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public void setInputType(int); method public void setKeyListener(android.text.method.KeyListener); diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 7828851a28f35..67794b1c7d5fe 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -165,6 +165,19 @@ public class StaticLayout extends Layout { return this; } + public Builder setIndents(int[] leftIndents, int[] rightIndents) { + int leftLen = leftIndents == null ? 0 : leftIndents.length; + int rightLen = rightIndents == null ? 0 : rightIndents.length; + int[] indents = new int[Math.max(leftLen, rightLen)]; + for (int i = 0; i < indents.length; i++) { + int leftMargin = i < leftLen ? leftIndents[i] : 0; + int rightMargin = i < rightLen ? rightIndents[i] : 0; + indents[i] = leftMargin + rightMargin; + } + nSetIndents(mNativePtr, indents); + return this; + } + /** * Measurement and break iteration is done in native code. The protocol for using * the native code is as follows. @@ -1009,6 +1022,8 @@ public class StaticLayout extends Layout { private static native void nSetLocale(long nativePtr, String locale, long nativeHyphenator); + private static native void nSetIndents(long nativePtr, int[] indents); + // Set up paragraph text and settings; done as one big method to minimize jni crossings private static native void nSetupParagraph(long nativePtr, char[] text, int length, float firstWidth, int firstWidthLineCount, float restWidth, diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b44a8863eb811..0854eef9882c2 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -236,6 +236,9 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; * @attr ref android.R.styleable#TextView_elegantTextHeight * @attr ref android.R.styleable#TextView_letterSpacing * @attr ref android.R.styleable#TextView_fontFeatureSettings + * @attr ref android.R.styleable#TextView_breakStrategy + * @attr ref android.R.styleable#TextView_leftIndents + * @attr ref android.R.styleable#TextView_rightIndents */ @RemoteView public class TextView extends View implements ViewTreeObserver.OnPreDrawListener { @@ -551,6 +554,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private float mSpacingAdd = 0.0f; private int mBreakStrategy; + private int[] mLeftIndents; + private int[] mRightIndents; private int mMaximum = Integer.MAX_VALUE; private int mMaxMode = LINES; @@ -1146,6 +1151,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener case com.android.internal.R.styleable.TextView_breakStrategy: mBreakStrategy = a.getInt(attr, Layout.BREAK_STRATEGY_SIMPLE); + break; + + case com.android.internal.R.styleable.TextView_leftIndents: + TypedArray margins = res.obtainTypedArray(a.getResourceId(attr, View.NO_ID)); + mLeftIndents = parseDimensionArray(margins); + break; + + case com.android.internal.R.styleable.TextView_rightIndents: + margins = res.obtainTypedArray(a.getResourceId(attr, View.NO_ID)); + mRightIndents = parseDimensionArray(margins); + break; } } a.recycle(); @@ -1421,6 +1437,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } + private int[] parseDimensionArray(TypedArray dimens) { + if (dimens == null) { + return null; + } + int[] result = new int[dimens.length()]; + for (int i = 0; i < result.length; i++) { + result[i] = dimens.getDimensionPixelSize(i, 0); + } + return result; + } + /** * @hide */ @@ -3018,6 +3045,51 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return mBreakStrategy; } + /** + * Set indents. Arguments are arrays holding an indent amount, one per line, measured in + * pixels. For lines past the last element in the array, the last element repeats. + * + * @param leftIndents array of indent values for left margin, in pixels + * @param rightIndents array of indent values for right margin, in pixels + * + * @see #getLeftIndents() + * @see #getRightIndents() + * + * @attr ref android.R.styleable#TextView_leftIndents + * @attr ref android.R.styleable#TextView_rightIndents + */ + public void setIndents(@Nullable int[] leftIndents, @Nullable int[] rightIndents) { + mLeftIndents = leftIndents; + mRightIndents = rightIndents; + if (mLayout != null) { + nullLayouts(); + requestLayout(); + invalidate(); + } + } + + /** + * Get left indents. See {#link setMargins} for more details. + * + * @return left indents + * @see #setIndents(int[], int[]) + * @attr ref android.R.styleable#TextView_leftIndents + */ + public int[] getLeftIndents() { + return mLeftIndents; + } + + /** + * Get right indents. See {#link setMargins} for more details. + * + * @return right indents + * @see #setIndents(int[], int[]) + * @attr ref android.R.styleable#TextView_rightIndents + */ + public int[] getRightIndents() { + return mRightIndents; + } + /** * Sets font feature settings. The format is the same as the CSS * font-feature-settings attribute: @@ -6564,6 +6636,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setSpacingAdd(mSpacingAdd) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy); + if (mLeftIndents != null || mRightIndents != null) { + builder.setIndents(mLeftIndents, mRightIndents); + } if (shouldEllipsize) { builder.setEllipsize(mEllipsize) .setEllipsizedWidth(ellipsisWidth) @@ -6652,6 +6727,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setSpacingAdd(mSpacingAdd) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy); + if (mLeftIndents != null || mRightIndents != null) { + builder.setIndents(mLeftIndents, mRightIndents); + } if (shouldEllipsize) { builder.setEllipsize(effectiveEllipsize) .setEllipsizedWidth(ellipsisWidth) diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp index 87c58d62dee84..5e73ef250435c 100644 --- a/core/jni/android_text_StaticLayout.cpp +++ b/core/jni/android_text_StaticLayout.cpp @@ -132,6 +132,13 @@ static void nSetLocale(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleN } } +static void nSetIndents(JNIEnv* env, jclass, jlong nativePtr, jintArray indents) { + ScopedIntArrayRO indentArr(env, indents); + std::vector indentVec(indentArr.get(), indentArr.get() + indentArr.size()); + LineBreaker* b = reinterpret_cast(nativePtr); + b->setIndents(indentVec); +} + // Basically similar to Paint.getTextRunAdvances but with C++ interface static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr, jlong nativePaint, jlong nativeTypeface, jint start, jint end, jboolean isRtl) { @@ -171,6 +178,7 @@ static JNINativeMethod gMethods[] = { {"nLoadHyphenator", "(Ljava/lang/String;)J", (void*) nLoadHyphenator}, {"nSetLocale", "(JLjava/lang/String;J)V", (void*) nSetLocale}, {"nSetupParagraph", "(J[CIFIF[III)V", (void*) nSetupParagraph}, + {"nSetIndents", "(J[I)V", (void*) nSetIndents}, {"nAddStyleRun", "(JJJIIZ)F", (void*) nAddStyleRun}, {"nAddMeasuredRun", "(JII[F)V", (void*) nAddMeasuredRun}, {"nAddReplacementRun", "(JIIF)V", (void*) nAddReplacementRun}, diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index a623d0cb5f16a..674c695a6776f 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4322,6 +4322,10 @@ + + + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 8806869462826..282c80b9e50b9 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2665,4 +2665,7 @@ + + +