* commit '5e44927699026fed2fbf8cbd9ee1202bb0f80c07': Implement better handling of text in assist.
This commit is contained in:
@@ -5822,6 +5822,8 @@ package android.app.assist {
|
||||
method public java.lang.CharSequence getText();
|
||||
method public int getTextBackgroundColor();
|
||||
method public int getTextColor();
|
||||
method public int[] getTextLineBaselines();
|
||||
method public int[] getTextLineCharOffsets();
|
||||
method public int getTextSelectionEnd();
|
||||
method public int getTextSelectionStart();
|
||||
method public float getTextSize();
|
||||
@@ -36953,6 +36955,7 @@ package android.view {
|
||||
method public abstract void setSelected(boolean);
|
||||
method public abstract void setText(java.lang.CharSequence);
|
||||
method public abstract void setText(java.lang.CharSequence, int, int);
|
||||
method public abstract void setTextLines(int[], int[]);
|
||||
method public abstract void setTextStyle(float, int, int, int);
|
||||
method public abstract void setTransformation(android.graphics.Matrix);
|
||||
method public abstract void setVisibility(int);
|
||||
|
||||
@@ -5954,6 +5954,8 @@ package android.app.assist {
|
||||
method public java.lang.CharSequence getText();
|
||||
method public int getTextBackgroundColor();
|
||||
method public int getTextColor();
|
||||
method public int[] getTextLineBaselines();
|
||||
method public int[] getTextLineCharOffsets();
|
||||
method public int getTextSelectionEnd();
|
||||
method public int getTextSelectionStart();
|
||||
method public float getTextSize();
|
||||
@@ -39243,6 +39245,7 @@ package android.view {
|
||||
method public abstract void setSelected(boolean);
|
||||
method public abstract void setText(java.lang.CharSequence);
|
||||
method public abstract void setText(java.lang.CharSequence, int, int);
|
||||
method public abstract void setTextLines(int[], int[]);
|
||||
method public abstract void setTextStyle(float, int, int, int);
|
||||
method public abstract void setTransformation(android.graphics.Matrix);
|
||||
method public abstract void setVisibility(int);
|
||||
|
||||
@@ -61,37 +61,53 @@ public class AssistStructure implements Parcelable {
|
||||
|
||||
final static class ViewNodeText {
|
||||
CharSequence mText;
|
||||
int mTextSelectionStart;
|
||||
int mTextSelectionEnd;
|
||||
int mTextColor;
|
||||
int mTextBackgroundColor;
|
||||
float mTextSize;
|
||||
int mTextStyle;
|
||||
int mTextColor = ViewNode.TEXT_COLOR_UNDEFINED;
|
||||
int mTextBackgroundColor = ViewNode.TEXT_COLOR_UNDEFINED;
|
||||
int mTextSelectionStart;
|
||||
int mTextSelectionEnd;
|
||||
int[] mLineCharOffsets;
|
||||
int[] mLineBaselines;
|
||||
String mHint;
|
||||
|
||||
ViewNodeText() {
|
||||
}
|
||||
|
||||
ViewNodeText(Parcel in) {
|
||||
mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
mTextSelectionStart = in.readInt();
|
||||
mTextSelectionEnd = in.readInt();
|
||||
mTextColor = in.readInt();
|
||||
mTextBackgroundColor = in.readInt();
|
||||
mTextSize = in.readFloat();
|
||||
mTextStyle = in.readInt();
|
||||
mHint = in.readString();
|
||||
boolean isSimple() {
|
||||
return mTextBackgroundColor == ViewNode.TEXT_COLOR_UNDEFINED
|
||||
&& mTextSelectionStart == 0 && mTextSelectionEnd == 0
|
||||
&& mLineCharOffsets == null && mLineBaselines == null && mHint == null;
|
||||
}
|
||||
|
||||
void writeToParcel(Parcel out) {
|
||||
ViewNodeText(Parcel in, boolean simple) {
|
||||
mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
mTextSize = in.readFloat();
|
||||
mTextStyle = in.readInt();
|
||||
mTextColor = in.readInt();
|
||||
if (!simple) {
|
||||
mTextBackgroundColor = in.readInt();
|
||||
mTextSelectionStart = in.readInt();
|
||||
mTextSelectionEnd = in.readInt();
|
||||
mLineCharOffsets = in.createIntArray();
|
||||
mLineBaselines = in.createIntArray();
|
||||
mHint = in.readString();
|
||||
}
|
||||
}
|
||||
|
||||
void writeToParcel(Parcel out, boolean simple) {
|
||||
TextUtils.writeToParcel(mText, out, 0);
|
||||
out.writeInt(mTextSelectionStart);
|
||||
out.writeInt(mTextSelectionEnd);
|
||||
out.writeInt(mTextColor);
|
||||
out.writeInt(mTextBackgroundColor);
|
||||
out.writeFloat(mTextSize);
|
||||
out.writeInt(mTextStyle);
|
||||
out.writeString(mHint);
|
||||
out.writeInt(mTextColor);
|
||||
if (!simple) {
|
||||
out.writeInt(mTextBackgroundColor);
|
||||
out.writeInt(mTextSelectionStart);
|
||||
out.writeInt(mTextSelectionEnd);
|
||||
out.writeIntArray(mLineCharOffsets);
|
||||
out.writeIntArray(mLineBaselines);
|
||||
out.writeString(mHint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,9 +268,10 @@ public class AssistStructure implements Parcelable {
|
||||
static final int FLAGS_HAS_LARGE_COORDS = 0x04000000;
|
||||
static final int FLAGS_HAS_CONTENT_DESCRIPTION = 0x02000000;
|
||||
static final int FLAGS_HAS_TEXT = 0x01000000;
|
||||
static final int FLAGS_HAS_EXTRAS = 0x00800000;
|
||||
static final int FLAGS_HAS_ID = 0x00400000;
|
||||
static final int FLAGS_HAS_CHILDREN = 0x00200000;
|
||||
static final int FLAGS_HAS_COMPLEX_TEXT = 0x00800000;
|
||||
static final int FLAGS_HAS_EXTRAS = 0x00400000;
|
||||
static final int FLAGS_HAS_ID = 0x00200000;
|
||||
static final int FLAGS_HAS_CHILDREN = 0x00100000;
|
||||
static final int FLAGS_ALL_CONTROL = 0xfff00000;
|
||||
|
||||
int mFlags;
|
||||
@@ -316,7 +333,7 @@ public class AssistStructure implements Parcelable {
|
||||
mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
}
|
||||
if ((flags&FLAGS_HAS_TEXT) != 0) {
|
||||
mText = new ViewNodeText(in);
|
||||
mText = new ViewNodeText(in, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0);
|
||||
}
|
||||
if ((flags&FLAGS_HAS_EXTRAS) != 0) {
|
||||
mExtras = in.readBundle();
|
||||
@@ -356,6 +373,9 @@ public class AssistStructure implements Parcelable {
|
||||
}
|
||||
if (mText != null) {
|
||||
flags |= FLAGS_HAS_TEXT;
|
||||
if (!mText.isSimple()) {
|
||||
flags |= FLAGS_HAS_COMPLEX_TEXT;
|
||||
}
|
||||
}
|
||||
if (mExtras != null) {
|
||||
flags |= FLAGS_HAS_EXTRAS;
|
||||
@@ -403,7 +423,7 @@ public class AssistStructure implements Parcelable {
|
||||
TextUtils.writeToParcel(mContentDescription, out, 0);
|
||||
}
|
||||
if ((flags&FLAGS_HAS_TEXT) != 0) {
|
||||
mText.writeToParcel(out);
|
||||
mText.writeToParcel(out, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0);
|
||||
}
|
||||
if ((flags&FLAGS_HAS_EXTRAS) != 0) {
|
||||
out.writeBundle(mExtras);
|
||||
@@ -702,6 +722,26 @@ public class AssistStructure implements Parcelable {
|
||||
return mText != null ? mText.mTextStyle : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return per-line offsets into the text returned by {@link #getText()}. Each entry
|
||||
* in the array is a formatted line of text, and the value it contains is the offset
|
||||
* into the text string where that line starts. May return null if there is no line
|
||||
* information.
|
||||
*/
|
||||
public int[] getTextLineCharOffsets() {
|
||||
return mText != null ? mText.mLineCharOffsets : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return per-line baselines into the text returned by {@link #getText()}. Each entry
|
||||
* in the array is a formatted line of text, and the value it contains is the baseline
|
||||
* where that text appears in the view. May return null if there is no line
|
||||
* information.
|
||||
*/
|
||||
public int[] getTextLineBaselines() {
|
||||
return mText != null ? mText.mLineBaselines : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return additional hint text associated with the node; this is typically used with
|
||||
* a node that takes user input, describing to the user what the input means.
|
||||
@@ -900,6 +940,13 @@ public class AssistStructure implements Parcelable {
|
||||
t.mTextStyle = style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTextLines(int[] charOffsets, int[] baselines) {
|
||||
ViewNodeText t = getNodeText();
|
||||
t.mLineCharOffsets = charOffsets;
|
||||
t.mLineBaselines = baselines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHint(CharSequence hint) {
|
||||
getNodeText().mHint = hint != null ? hint.toString() : null;
|
||||
|
||||
@@ -177,6 +177,17 @@ public abstract class ViewStructure {
|
||||
*/
|
||||
public abstract void setTextStyle(float size, int fgColor, int bgColor, int style);
|
||||
|
||||
/**
|
||||
* Set line information for test that was previously supplied through
|
||||
* {@link #setText(CharSequence)}. This provides the line breaking of the text as it
|
||||
* is shown on screen. This function takes ownership of the provided arrays; you should
|
||||
* not make further modification to them.
|
||||
*
|
||||
* @param charOffsets The offset in to {@link #setText} where a line starts.
|
||||
* @param baselines The baseline where the line is drawn on screen.
|
||||
*/
|
||||
public abstract void setTextLines(int[] charOffsets, int[] baselines);
|
||||
|
||||
/**
|
||||
* Set optional hint text associated with this view; this is for example the text that is
|
||||
* shown by an EditText when it is empty to indicate to the user the kind of text to input.
|
||||
|
||||
@@ -46,7 +46,6 @@ import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.inputmethodservice.ExtractEditText;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
@@ -116,6 +115,7 @@ import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewParent;
|
||||
import android.view.ViewStructure;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewDebug;
|
||||
@@ -5823,6 +5823,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
return super.getBaseline();
|
||||
}
|
||||
|
||||
return getBaselineOffset() + mLayout.getLineBaseline(0);
|
||||
}
|
||||
|
||||
int getBaselineOffset() {
|
||||
int voffset = 0;
|
||||
if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) {
|
||||
voffset = getVerticalOffset(true);
|
||||
@@ -5832,7 +5836,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
voffset -= getOpticalInsets().top;
|
||||
}
|
||||
|
||||
return getExtendedPaddingTop() + voffset + mLayout.getLineBaseline(0);
|
||||
return getExtendedPaddingTop() + voffset;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8767,7 +8771,79 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
final boolean isPassword = hasPasswordTransformationMethod()
|
||||
|| isPasswordInputType(getInputType());
|
||||
if (!isPassword) {
|
||||
structure.setText(getText(), getSelectionStart(), getSelectionEnd());
|
||||
if (mLayout == null) {
|
||||
assumeLayout();
|
||||
}
|
||||
Layout layout = mLayout;
|
||||
final int lineCount = layout.getLineCount();
|
||||
if (lineCount <= 1) {
|
||||
// Simple case: this is a single line.
|
||||
structure.setText(getText(), getSelectionStart(), getSelectionEnd());
|
||||
} else {
|
||||
// Complex case: multi-line, could be scrolled or within a scroll container
|
||||
// so some lines are not visible.
|
||||
final int[] tmpCords = new int[2];
|
||||
getLocationInWindow(tmpCords);
|
||||
final int topWindowLocation = tmpCords[1];
|
||||
View root = this;
|
||||
ViewParent viewParent = getParent();
|
||||
while (viewParent instanceof View) {
|
||||
root = (View) viewParent;
|
||||
viewParent = root.getParent();
|
||||
}
|
||||
final int windowHeight = root.getHeight();
|
||||
final int topLine;
|
||||
final int bottomLine;
|
||||
if (topWindowLocation >= 0) {
|
||||
// The top of the view is fully within its window; start text at line 0.
|
||||
topLine = getLineAtCoordinateUnclamped(0);
|
||||
bottomLine = getLineAtCoordinateUnclamped(windowHeight-1);
|
||||
} else {
|
||||
// The top of hte window has scrolled off the top of the window; figure out
|
||||
// the starting line for this.
|
||||
topLine = getLineAtCoordinateUnclamped(-topWindowLocation);
|
||||
bottomLine = getLineAtCoordinateUnclamped(windowHeight-1-topWindowLocation);
|
||||
}
|
||||
// We want to return some contextual lines above/below the lines that are
|
||||
// actually visible.
|
||||
int expandedTopLine = topLine - (bottomLine-topLine)/2;
|
||||
if (expandedTopLine < 0) {
|
||||
expandedTopLine = 0;
|
||||
}
|
||||
int expandedBottomLine = bottomLine + (bottomLine-topLine)/2;
|
||||
if (expandedBottomLine >= lineCount) {
|
||||
expandedBottomLine = lineCount-1;
|
||||
}
|
||||
// Convert lines into character offsets.
|
||||
int expandedTopChar = layout.getLineStart(expandedTopLine);
|
||||
int expandedBottomChar = layout.getLineEnd(expandedBottomLine);
|
||||
// Take into account selection -- if there is a selection, we need to expand
|
||||
// the text we are returning to include that selection.
|
||||
final int selStart = getSelectionStart();
|
||||
final int selEnd = getSelectionEnd();
|
||||
if (selStart < selEnd) {
|
||||
if (selStart < expandedTopChar) {
|
||||
expandedTopChar = selStart;
|
||||
}
|
||||
if (selEnd > expandedBottomChar) {
|
||||
expandedBottomChar = selEnd;
|
||||
}
|
||||
}
|
||||
// Get the text and trim it to the range we are reporting.
|
||||
CharSequence text = getText();
|
||||
if (expandedTopChar > 0 || expandedBottomChar < text.length()) {
|
||||
text = text.subSequence(expandedTopChar, expandedBottomChar);
|
||||
}
|
||||
structure.setText(text, selStart-expandedTopChar, selEnd-expandedTopChar);
|
||||
final int[] lineOffsets = new int[bottomLine-topLine+1];
|
||||
final int[] lineBaselines = new int[bottomLine-topLine+1];
|
||||
final int baselineOffset = getBaselineOffset();
|
||||
for (int i=topLine; i<=bottomLine; i++) {
|
||||
lineOffsets[i-topLine] = layout.getLineStart(i);
|
||||
lineBaselines[i-topLine] = layout.getLineBaseline(i) + baselineOffset;
|
||||
}
|
||||
structure.setTextLines(lineOffsets, lineBaselines);
|
||||
}
|
||||
|
||||
// Extract style information that applies to the TextView as a whole.
|
||||
int style = 0;
|
||||
@@ -9200,24 +9276,25 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
* If provided, this ActionMode.Callback will be used to create the ActionMode when text
|
||||
* selection is initiated in this View.
|
||||
*
|
||||
* The standard implementation populates the menu with a subset of Select All, Cut, Copy,
|
||||
* <p>The standard implementation populates the menu with a subset of Select All, Cut, Copy,
|
||||
* Paste, Replace and Share actions, depending on what this View supports.
|
||||
*
|
||||
* A custom implementation can add new entries in the default menu in its
|
||||
* {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The
|
||||
* default actions can also be removed from the menu using
|
||||
* <p>A custom implementation can add new entries in the default menu in its
|
||||
* {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, android.view.Menu)}
|
||||
* method. The default actions can also be removed from the menu using
|
||||
* {@link android.view.Menu#removeItem(int)} and passing {@link android.R.id#selectAll},
|
||||
* {@link android.R.id#cut}, {@link android.R.id#copy}, {@link android.R.id#paste},
|
||||
* {@link android.R.id#replaceText} or {@link android.R.id#shareText} ids as parameters.
|
||||
*
|
||||
* Returning false from
|
||||
* {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, Menu)} will prevent
|
||||
* the action mode from being started.
|
||||
* <p>Returning false from
|
||||
* {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, android.view.Menu)}
|
||||
* will prevent the action mode from being started.
|
||||
*
|
||||
* Action click events should be handled by the custom implementation of
|
||||
* {@link android.view.ActionMode.Callback#onActionItemClicked(ActionMode, MenuItem)}.
|
||||
* <p>Action click events should be handled by the custom implementation of
|
||||
* {@link android.view.ActionMode.Callback#onActionItemClicked(ActionMode,
|
||||
* android.view.MenuItem)}.
|
||||
*
|
||||
* Note that text selection mode is not started when a TextView receives focus and the
|
||||
* <p>Note that text selection mode is not started when a TextView receives focus and the
|
||||
* {@link android.R.attr#selectAllOnFocus} flag has been set. The content is highlighted in
|
||||
* that case, to allow for quick replacement.
|
||||
*/
|
||||
@@ -9448,6 +9525,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
return getLayout().getLineForVertical((int) y);
|
||||
}
|
||||
|
||||
int getLineAtCoordinateUnclamped(float y) {
|
||||
y -= getTotalPaddingTop();
|
||||
y += getScrollY();
|
||||
return getLayout().getLineForVertical((int) y);
|
||||
}
|
||||
|
||||
int getOffsetAtCoordinate(int line, float x) {
|
||||
x = convertToLocalHorizontalCoordinate(x);
|
||||
return getLayout().getOffsetForHorizontal(line, x);
|
||||
|
||||
@@ -30,10 +30,17 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="64dp"
|
||||
android:paddingBottom="64dp"
|
||||
android:text="@string/asyncStructure"
|
||||
/>
|
||||
|
||||
<EditText android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingTop="64dp"
|
||||
android:paddingBottom="64dp"
|
||||
android:text="@string/largetext" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
@@ -30,4 +30,233 @@
|
||||
<string name="cancelVoice">Cancel</string>
|
||||
<string name="jumpOut">Jump out</string>
|
||||
|
||||
<string name="largetext">This is a bunch of text that we will use to show how we handle it
|
||||
when reporting it for assist data. We need many many lines of text, like\n
|
||||
this\n
|
||||
and\n
|
||||
this other\n
|
||||
one\n
|
||||
two\n
|
||||
three\n
|
||||
four\n
|
||||
five\n
|
||||
six\n
|
||||
seven\n
|
||||
eight\n
|
||||
nine\n
|
||||
ten\n
|
||||
eleven\n
|
||||
twelve\n
|
||||
thirteen\n
|
||||
fourteen\n
|
||||
fifteen\n
|
||||
sixteen\n
|
||||
seventeen\n
|
||||
eighteen\n
|
||||
nineteen\n
|
||||
twenty\n
|
||||
<big><big><big>So shaken as we are, so wan with care,\n
|
||||
Find we a time for frighted peace to pant,\n</big>
|
||||
And breathe short-winded accents of new broils\n
|
||||
To be commenced in strands afar remote.\n</big>
|
||||
No more the thirsty entrance of this soil\n
|
||||
Shall daub her lips with her own children\'s blood;\n</big>
|
||||
<b>Nor more shall trenching war channel her fields,\n
|
||||
Nor bruise her flowerets with the armed hoofs\n</b>
|
||||
<i>Of hostile paces: those opposed eyes,\n
|
||||
Which, like the meteors of a troubled heaven,\n</i>
|
||||
All of one nature, of one substance bred,\n
|
||||
Did lately meet in the intestine shock\n
|
||||
And furious close of civil butchery\n
|
||||
Shall now, in mutual well-beseeming ranks,\n
|
||||
March all one way and be no more opposed\n
|
||||
Against acquaintance, kindred and allies:\n
|
||||
The edge of war, like an ill-sheathed knife,\n
|
||||
No more shall cut his master. Therefore, friends,\n
|
||||
As far as to the sepulchre of Christ,\n
|
||||
Whose soldier now, under whose blessed cross\n
|
||||
We are impressed and engaged to fight,\n
|
||||
Forthwith a power of English shall we levy;\n
|
||||
Whose arms were moulded in their mothers\' womb\n
|
||||
To chase these pagans in those holy fields\n
|
||||
Over whose acres walk\'d those blessed feet\n
|
||||
Which fourteen hundred years ago were nail\'d\n
|
||||
For our advantage on the bitter cross.\n
|
||||
But this our purpose now is twelve month old,\n
|
||||
And bootless \'tis to tell you we will go:\n
|
||||
Therefore we meet not now. Then let me hear\n
|
||||
Of you, my gentle cousin Westmoreland,\n
|
||||
What yesternight our council did decree\n
|
||||
In forwarding this dear expedience.\n
|
||||
\n
|
||||
Hear him but reason in divinity,\n
|
||||
And all-admiring with an inward wish\n
|
||||
You would desire the king were made a prelate:\n
|
||||
Hear him debate of commonwealth affairs,\n
|
||||
You would say it hath been all in all his study:\n
|
||||
List his discourse of war, and you shall hear\n
|
||||
A fearful battle render\'d you in music:\n
|
||||
Turn him to any cause of policy,\n
|
||||
The Gordian knot of it he will unloose,\n
|
||||
Familiar as his garter: that, when he speaks,\n
|
||||
The air, a charter\'d libertine, is still,\n
|
||||
And the mute wonder lurketh in men\'s ears,\n
|
||||
To steal his sweet and honey\'d sentences;\n
|
||||
So that the art and practic part of life\n
|
||||
Must be the mistress to this theoric:\n
|
||||
Which is a wonder how his grace should glean it,\n
|
||||
Since his addiction was to courses vain,\n
|
||||
His companies unletter\'d, rude and shallow,\n
|
||||
His hours fill\'d up with riots, banquets, sports,\n
|
||||
And never noted in him any study,\n
|
||||
Any retirement, any sequestration\n
|
||||
From open haunts and popularity.\n
|
||||
\n
|
||||
I come no more to make you laugh: things now,\n
|
||||
That bear a weighty and a serious brow,\n
|
||||
Sad, high, and working, full of state and woe,\n
|
||||
Such noble scenes as draw the eye to flow,\n
|
||||
e now present. Those that can pity, here\n
|
||||
May, if they think it well, let fall a tear;\n
|
||||
The subject will deserve it. Such as give\n
|
||||
Their money out of hope they may believe,\n
|
||||
May here find truth too. Those that come to see\n
|
||||
Only a show or two, and so agree\n
|
||||
The play may pass, if they be still and willing,\n
|
||||
I\'ll undertake may see away their shilling\n
|
||||
Richly in two short hours. Only they\n
|
||||
That come to hear a merry bawdy play,\n
|
||||
A noise of targets, or to see a fellow\n
|
||||
In a long motley coat guarded with yellow,\n
|
||||
Will be deceived; for, gentle hearers, know,\n
|
||||
To rank our chosen truth with such a show\n
|
||||
As fool and fight is, beside forfeiting\n
|
||||
Our own brains, and the opinion that we bring,\n
|
||||
To make that only true we now intend,\n
|
||||
Will leave us never an understanding friend.\n
|
||||
Therefore, for goodness\' sake, and as you are known\n
|
||||
The first and happiest hearers of the town,\n
|
||||
Be sad, as we would make ye: think ye see\n
|
||||
The very persons of our noble story\n
|
||||
As they were living; think you see them great,\n
|
||||
And follow\'d with the general throng and sweat\n
|
||||
Of thousand friends; then in a moment, see\n
|
||||
How soon this mightiness meets misery:\n
|
||||
And, if you can be merry then, I\'ll say\n
|
||||
A man may weep upon his wedding-day.\n
|
||||
\n
|
||||
<big>First, heaven be the record to my speech!\n
|
||||
In the devotion of a subject\'s love,\n</big>
|
||||
<b>Tendering the precious safety of my prince,\n
|
||||
And free from other misbegotten hate,\n</b>
|
||||
Come I appellant to this princely presence.\n
|
||||
Now, Thomas Mowbray, do I turn to thee,\n
|
||||
And mark my greeting well; for what I speak\n
|
||||
My body shall make good upon this earth,\n
|
||||
Or my divine soul answer it in heaven.\n
|
||||
Thou art a traitor and a miscreant,\n
|
||||
Too good to be so and too bad to live,\n
|
||||
Since the more fair and crystal is the sky,\n
|
||||
The uglier seem the clouds that in it fly.\n
|
||||
Once more, the more to aggravate the note,\n
|
||||
With a foul traitor\'s name stuff I thy throat;\n
|
||||
And wish, so please my sovereign, ere I move,\n
|
||||
What my tongue speaks my right drawn sword may prove.\n
|
||||
\n
|
||||
Now is the winter of our discontent\n
|
||||
Made glorious summer by this sun of York;\n
|
||||
And all the clouds that lour\'d upon our house\n
|
||||
In the deep bosom of the ocean buried.\n
|
||||
Now are our brows bound with victorious wreaths;\n
|
||||
Our bruised arms hung up for monuments;\n
|
||||
Our stern alarums changed to merry meetings,\n
|
||||
Our dreadful marches to delightful measures.\n
|
||||
Grim-visaged war hath smooth\'d his wrinkled front;\n
|
||||
And now, instead of mounting barded steeds\n
|
||||
To fright the souls of fearful adversaries,\n
|
||||
He capers nimbly in a lady\'s chamber\n
|
||||
To the lascivious pleasing of a lute.\n
|
||||
But I, that am not shaped for sportive tricks,\n
|
||||
Nor made to court an amorous looking-glass;\n
|
||||
I, that am rudely stamp\'d, and want love\'s majesty\n
|
||||
To strut before a wanton ambling nymph;\n
|
||||
I, that am curtail\'d of this fair proportion,\n
|
||||
Cheated of feature by dissembling nature,\n
|
||||
Deformed, unfinish\'d, sent before my time\n
|
||||
Into this breathing world, scarce half made up,\n
|
||||
And that so lamely and unfashionable\n
|
||||
That dogs bark at me as I halt by them;\n
|
||||
Why, I, in this weak piping time of peace,\n
|
||||
Have no delight to pass away the time,\n
|
||||
Unless to spy my shadow in the sun\n
|
||||
And descant on mine own deformity:\n
|
||||
And therefore, since I cannot prove a lover,\n
|
||||
To entertain these fair well-spoken days,\n
|
||||
I am determined to prove a villain\n
|
||||
And hate the idle pleasures of these days.\n
|
||||
Plots have I laid, inductions dangerous,\n
|
||||
By drunken prophecies, libels and dreams,\n
|
||||
To set my brother Clarence and the king\n
|
||||
In deadly hate the one against the other:\n
|
||||
And if King Edward be as true and just\n
|
||||
As I am subtle, false and treacherous,\n
|
||||
This day should Clarence closely be mew\'d up,\n
|
||||
About a prophecy, which says that \'G\'\n
|
||||
Of Edward\'s heirs the murderer shall be.\n
|
||||
Dive, thoughts, down to my soul: here\n
|
||||
Clarence comes.\n
|
||||
\n
|
||||
To bait fish withal: if it will feed nothing else,\n
|
||||
it will feed my revenge. He hath disgraced me, and\n
|
||||
hindered me half a million; laughed at my losses,\n
|
||||
mocked at my gains, scorned my nation, thwarted my\n
|
||||
bargains, cooled my friends, heated mine\n
|
||||
enemies; and what\'s his reason? I am a Jew. Hath\n
|
||||
not a Jew eyes? hath not a Jew hands, organs,\n
|
||||
dimensions, senses, affections, passions? fed with\n
|
||||
the same food, hurt with the same weapons, subject\n
|
||||
to the same diseases, healed by the same means,\n
|
||||
warmed and cooled by the same winter and summer, as\n
|
||||
a Christian is? If you prick us, do we not bleed?\n
|
||||
if you tickle us, do we not laugh? if you poison\n
|
||||
us, do we not die? and if you wrong us, shall we not\n
|
||||
revenge? If we are like you in the rest, we will\n
|
||||
resemble you in that. If a Jew wrong a Christian,\n
|
||||
what is his humility? Revenge. If a Christian\n
|
||||
wrong a Jew, what should his sufferance be by\n
|
||||
Christian example? Why, revenge. The villany you\n
|
||||
teach me, I will execute, and it shall go hard but I\n
|
||||
will better the instruction.\n
|
||||
\n
|
||||
Virtue! a fig! \'tis in ourselves that we are thus\n
|
||||
or thus. Our bodies are our gardens, to the which\n
|
||||
our wills are gardeners: so that if we will plant\n
|
||||
nettles, or sow lettuce, set hyssop and weed up\n
|
||||
thyme, supply it with one gender of herbs, or\n
|
||||
distract it with many, either to have it sterile\n
|
||||
with idleness, or manured with industry, why, the\n
|
||||
power and corrigible authority of this lies in our\n
|
||||
wills. If the balance of our lives had not one\n
|
||||
scale of reason to poise another of sensuality, the\n
|
||||
blood and baseness of our natures would conduct us\n
|
||||
to most preposterous conclusions: but we have\n
|
||||
reason to cool our raging motions, our carnal\n
|
||||
stings, our unbitted lusts, whereof I take this that\n
|
||||
you call love to be a sect or scion.\n
|
||||
\n
|
||||
Blow, winds, and crack your cheeks! rage! blow!\n
|
||||
You cataracts and hurricanoes, spout\n
|
||||
Till you have drench\'d our steeples, drown\'d the cocks!\n
|
||||
You sulphurous and thought-executing fires,\n
|
||||
Vaunt-couriers to oak-cleaving thunderbolts,\n
|
||||
Singe my white head! And thou, all-shaking thunder,\n
|
||||
Smite flat the thick rotundity o\' the world!\n
|
||||
Crack nature\'s moulds, an germens spill at once,\n
|
||||
That make ingrateful man!
|
||||
5...\n
|
||||
4...\n
|
||||
3...\n
|
||||
2...\n
|
||||
1...\n
|
||||
BEEEEEEEEEEEEEEEEEP!</string>
|
||||
</resources>
|
||||
|
||||
@@ -38,6 +38,9 @@ public class AssistVisualizer extends View {
|
||||
final Matrix matrix;
|
||||
final String className;
|
||||
final CharSequence text;
|
||||
final int scrollY;
|
||||
final int[] lineCharOffsets;
|
||||
final int[] lineBaselines;
|
||||
|
||||
TextEntry(AssistStructure.ViewNode node, int parentLeft, int parentTop, Matrix matrix) {
|
||||
int left = parentLeft+node.getLeft();
|
||||
@@ -48,16 +51,19 @@ public class AssistVisualizer extends View {
|
||||
this.matrix = new Matrix(matrix);
|
||||
this.className = node.getClassName();
|
||||
this.text = node.getText() != null ? node.getText() : node.getContentDescription();
|
||||
this.scrollY = node.getScrollY();
|
||||
this.lineCharOffsets = node.getTextLineCharOffsets();
|
||||
this.lineBaselines = node.getTextLineBaselines();
|
||||
}
|
||||
}
|
||||
|
||||
AssistStructure mAssistStructure;
|
||||
final Paint mFramePaint = new Paint();
|
||||
final Paint mFrameBaselinePaint = new Paint();
|
||||
final Paint mFrameNoTransformPaint = new Paint();
|
||||
final ArrayList<Matrix> mMatrixStack = new ArrayList<>();
|
||||
final ArrayList<TextEntry> mTextRects = new ArrayList<>();
|
||||
final int[] mTmpLocation = new int[2];
|
||||
final float[] mTmpMatrixPoint = new float[2];
|
||||
|
||||
public AssistVisualizer(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -65,6 +71,9 @@ public class AssistVisualizer extends View {
|
||||
mFramePaint.setColor(0xffff0000);
|
||||
mFramePaint.setStyle(Paint.Style.STROKE);
|
||||
mFramePaint.setStrokeWidth(0);
|
||||
mFrameBaselinePaint.setColor(0xa0b0b000);
|
||||
mFrameBaselinePaint.setStyle(Paint.Style.STROKE);
|
||||
mFrameBaselinePaint.setStrokeWidth(0);
|
||||
float density = getResources().getDisplayMetrics().density;
|
||||
mFramePaint.setShadowLayer(density, density, density, 0xff000000);
|
||||
mFrameNoTransformPaint.setColor(0xff0000ff);
|
||||
@@ -106,6 +115,14 @@ public class AssistVisualizer extends View {
|
||||
+ " in " + te.parentLeft + "," + te.parentTop
|
||||
+ " matrix=" + te.matrix.toShortString() + ": "
|
||||
+ te.text);
|
||||
if (te.lineCharOffsets != null && te.lineBaselines != null) {
|
||||
final int num = te.lineCharOffsets.length < te.lineBaselines.length
|
||||
? te.lineCharOffsets.length : te.lineBaselines.length;
|
||||
for (int j=0; j<num; j++) {
|
||||
Log.d(TAG, " Line #" + j + ": offset=" + te.lineCharOffsets[j]
|
||||
+ " baseline=" + te.lineBaselines[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +188,13 @@ public class AssistVisualizer extends View {
|
||||
canvas.concat(te.matrix);
|
||||
canvas.drawRect(0, 0, te.bounds.right - te.bounds.left, te.bounds.bottom - te.bounds.top,
|
||||
mFramePaint);
|
||||
if (te.lineBaselines != null) {
|
||||
for (int j=0; j<te.lineBaselines.length; j++) {
|
||||
canvas.drawLine(0, te.lineBaselines[j] - te.scrollY,
|
||||
te.bounds.right - te.bounds.left, te.lineBaselines[j] - te.scrollY,
|
||||
mFrameBaselinePaint);
|
||||
}
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user