summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorAnish Athalye <aathalye@google.com>2014-08-08 12:09:58 -0700
committerAnish Athalye <aathalye@google.com>2014-08-14 11:58:37 -0700
commitab08c6d38ab2e575f809ca8ce4c7f095e49d258c (patch)
tree23fec1feb594d494ce8f8508850ce190e3ea4fba /core
parentf0433e50c7855579ad9847e939bb2c84e576e9d0 (diff)
downloadframeworks_base-ab08c6d38ab2e575f809ca8ce4c7f095e49d258c.zip
frameworks_base-ab08c6d38ab2e575f809ca8ce4c7f095e49d258c.tar.gz
frameworks_base-ab08c6d38ab2e575f809ca8ce4c7f095e49d258c.tar.bz2
Make LeadingMarginSpan2 behavior more consistent
This addresses b/16486549. This change updates public documentation to specify the behavior of LeadingMarginSpan2s. This change specifies what happens when a LeadingMarginSpan2 is combined with other LeadingMarginSpans. This behavior was not previously documented. LeadingMarginSpan2s specify the number of lines used for the leading margin. When laying out and rendering, for all LeadingMarginSpans, the first line margin is applied for the number of lines specified by the LeadingMarginSpan2. Previously, this behavior was slightly buggy -- the LeadingMarginSpan2 affected all LeadingMarginSpans when laying out text, but not when rendering. This change is designed to cause the least amount of breakage in existing code while achieving consistency with the way LeadingMarginSpan2 is handled in layout and drawing. For the most common use of LeadingMarginSpan2 -- getting a multi-line first margin in the first paragraph of text in a layout -- this should cause no change in behavior. For any other uses, the old (buggy) implementation most likely did not exhibit correct behavior to begin with, so developers were most likely not relying on that functionality. Change-Id: I6f69df09c0130e703458e65bf3eaac4a905df56e
Diffstat (limited to 'core')
-rw-r--r--core/java/android/text/Layout.java35
-rw-r--r--core/java/android/text/StaticLayout.java7
-rw-r--r--core/java/android/text/style/LeadingMarginSpan.java23
3 files changed, 40 insertions, 25 deletions
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index a36f06c..7dce348 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -273,16 +273,22 @@ public abstract class Layout {
// Draw all leading margin spans. Adjust left or right according
// to the paragraph direction of the line.
final int length = spans.length;
+ boolean useFirstLineMargin = isFirstParaLine;
+ for (int n = 0; n < length; n++) {
+ if (spans[n] instanceof LeadingMarginSpan2) {
+ int count = ((LeadingMarginSpan2) spans[n]).getLeadingMarginLineCount();
+ int startLine = getLineForOffset(sp.getSpanStart(spans[n]));
+ // if there is more than one LeadingMarginSpan2, use
+ // the count that is greatest
+ if (i < startLine + count) {
+ useFirstLineMargin = true;
+ break;
+ }
+ }
+ }
for (int n = 0; n < length; n++) {
if (spans[n] instanceof LeadingMarginSpan) {
LeadingMarginSpan margin = (LeadingMarginSpan) spans[n];
- boolean useFirstLineMargin = isFirstParaLine;
- if (margin instanceof LeadingMarginSpan2) {
- int count = ((LeadingMarginSpan2) margin).getLeadingMarginLineCount();
- int startLine = getLineForOffset(sp.getSpanStart(margin));
- useFirstLineMargin = i < startLine + count;
- }
-
if (dir == DIR_RIGHT_TO_LEFT) {
margin.drawLeadingMargin(canvas, paint, right, dir, ltop,
lbaseline, lbottom, buf,
@@ -1535,15 +1541,18 @@ public abstract class Layout {
boolean isFirstParaLine = lineStart == 0 ||
spanned.charAt(lineStart - 1) == '\n';
+ boolean useFirstLineMargin = isFirstParaLine;
for (int i = 0; i < spans.length; i++) {
- LeadingMarginSpan span = spans[i];
- boolean useFirstLineMargin = isFirstParaLine;
- if (span instanceof LeadingMarginSpan2) {
- int spStart = spanned.getSpanStart(span);
+ if (spans[i] instanceof LeadingMarginSpan2) {
+ int spStart = spanned.getSpanStart(spans[i]);
int spanLine = getLineForOffset(spStart);
- int count = ((LeadingMarginSpan2)span).getLeadingMarginLineCount();
- useFirstLineMargin = line < spanLine + count;
+ int count = ((LeadingMarginSpan2) spans[i]).getLeadingMarginLineCount();
+ // if there is more than one LeadingMarginSpan2, use the count that is greatest
+ useFirstLineMargin |= line < spanLine + count;
}
+ }
+ for (int i = 0; i < spans.length; i++) {
+ LeadingMarginSpan span = spans[i];
margin += span.getLeadingMargin(useFirstLineMargin);
}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 4144a75..aecf488 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -201,13 +201,12 @@ public class StaticLayout extends Layout {
restWidth -= sp[i].getLeadingMargin(false);
// LeadingMarginSpan2 is odd. The count affects all
- // leading margin spans, not just this particular one,
- // and start from the top of the span, not the top of the
- // paragraph.
+ // leading margin spans, not just this particular one
if (lms instanceof LeadingMarginSpan2) {
LeadingMarginSpan2 lms2 = (LeadingMarginSpan2) lms;
int lmsFirstLine = getLineForOffset(spanned.getSpanStart(lms2));
- firstWidthLineLimit = lmsFirstLine + lms2.getLeadingMarginLineCount();
+ firstWidthLineLimit = Math.max(firstWidthLineLimit,
+ lmsFirstLine + lms2.getLeadingMarginLineCount());
}
}
diff --git a/core/java/android/text/style/LeadingMarginSpan.java b/core/java/android/text/style/LeadingMarginSpan.java
index 2f429ff..96a7cd9 100644
--- a/core/java/android/text/style/LeadingMarginSpan.java
+++ b/core/java/android/text/style/LeadingMarginSpan.java
@@ -28,6 +28,9 @@ import android.text.TextUtils;
* margin spans on a single paragraph; they will be rendered in order, each
* adding its margin to the ones before it. The leading margin is on the right
* for lines in a right-to-left paragraph.
+ * <p>
+ * LeadingMarginSpans should be attached from the first character to the last
+ * character of a single paragraph.
*/
public interface LeadingMarginSpan
extends ParagraphStyle
@@ -69,18 +72,22 @@ extends ParagraphStyle
/**
- * An extended version of {@link LeadingMarginSpan}, which allows
- * the implementor to specify the number of lines of text to which
- * this object is attached that the "first line of paragraph" margin
- * width will be applied to.
+ * An extended version of {@link LeadingMarginSpan}, which allows the
+ * implementor to specify the number of lines of the paragraph to which
+ * this object is attached that the "first line of paragraph" margin width
+ * will be applied to.
+ * <p>
+ * There should only be one LeadingMarginSpan2 per paragraph. The leading
+ * margin line count affects all LeadingMarginSpans in the paragraph,
+ * adjusting the number of lines to which the first line margin is applied.
+ * <p>
+ * As with LeadingMarginSpans, LeadingMarginSpan2s should be attached from
+ * the beginning to the end of a paragraph.
*/
public interface LeadingMarginSpan2 extends LeadingMarginSpan, WrapTogetherSpan {
/**
- * Returns the number of lines of text to which this object is
+ * Returns the number of lines of the paragraph to which this object is
* attached that the "first line" margin will apply to.
- * Note that if this returns N, the first N lines of the region,
- * not the first N lines of each paragraph, will be given the
- * special margin width.
*/
public int getLeadingMarginLineCount();
};