AssistVisualizer.java revision 331ebfa7751a99a9e740d125c5ac4381a0151090
1ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn/* 2ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * Copyright (C) 2015 The Android Open Source Project 3ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * 4ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * you may not use this file except in compliance with the License. 6ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * You may obtain a copy of the License at 7ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * 8ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * 10ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * See the License for the specific language governing permissions and 14ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * limitations under the License. 15ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn */ 16ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 17ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornpackage com.android.test.voiceinteraction; 18ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 19ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.annotation.Nullable; 2016036f26847f3f1a88a093fb776bf081008ff8d8Dianne Hackbornimport android.app.assist.AssistStructure; 21ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.content.Context; 22ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.graphics.Canvas; 2370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackbornimport android.graphics.Matrix; 24ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.graphics.Paint; 25ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.graphics.Rect; 26ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.util.AttributeSet; 27ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.util.Log; 28ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.view.View; 29ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 30ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport java.util.ArrayList; 31ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 32ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornpublic class AssistVisualizer extends View { 33ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn static final String TAG = "AssistVisualizer"; 34ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 3570d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn static class TextEntry { 3670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final Rect bounds; 3770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final int parentLeft, parentTop; 3870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final Matrix matrix; 3970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final String className; 40331ebfa7751a99a9e740d125c5ac4381a0151090Dianne Hackborn final float textSize; 41331ebfa7751a99a9e740d125c5ac4381a0151090Dianne Hackborn final int textColor; 4270d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final CharSequence text; 436f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn final int scrollY; 446f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn final int[] lineCharOffsets; 456f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn final int[] lineBaselines; 4670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn 4770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn TextEntry(AssistStructure.ViewNode node, int parentLeft, int parentTop, Matrix matrix) { 4870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn int left = parentLeft+node.getLeft(); 4970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn int top = parentTop+node.getTop(); 5070d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn bounds = new Rect(left, top, left+node.getWidth(), top+node.getHeight()); 5170d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn this.parentLeft = parentLeft; 5270d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn this.parentTop = parentTop; 5370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn this.matrix = new Matrix(matrix); 5470d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn this.className = node.getClassName(); 55331ebfa7751a99a9e740d125c5ac4381a0151090Dianne Hackborn this.textSize = node.getTextSize(); 56331ebfa7751a99a9e740d125c5ac4381a0151090Dianne Hackborn this.textColor = node.getTextColor(); 5770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn this.text = node.getText() != null ? node.getText() : node.getContentDescription(); 586f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn this.scrollY = node.getScrollY(); 596f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn this.lineCharOffsets = node.getTextLineCharOffsets(); 606f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn this.lineBaselines = node.getTextLineBaselines(); 6170d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 6270d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 6370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn 64a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn AssistStructure mAssistStructure; 65ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final Paint mFramePaint = new Paint(); 666f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn final Paint mFrameBaselinePaint = new Paint(); 6770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final Paint mFrameNoTransformPaint = new Paint(); 6870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final ArrayList<Matrix> mMatrixStack = new ArrayList<>(); 6970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final ArrayList<TextEntry> mTextRects = new ArrayList<>(); 70ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final int[] mTmpLocation = new int[2]; 71ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 72ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn public AssistVisualizer(Context context, @Nullable AttributeSet attrs) { 73ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn super(context, attrs); 74ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn setWillNotDraw(false); 75ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mFramePaint.setColor(0xffff0000); 76ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mFramePaint.setStyle(Paint.Style.STROKE); 77ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mFramePaint.setStrokeWidth(0); 786f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn mFrameBaselinePaint.setColor(0xa0b0b000); 796f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn mFrameBaselinePaint.setStyle(Paint.Style.STROKE); 806f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn mFrameBaselinePaint.setStrokeWidth(0); 8170d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn float density = getResources().getDisplayMetrics().density; 8270d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mFramePaint.setShadowLayer(density, density, density, 0xff000000); 8370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mFrameNoTransformPaint.setColor(0xff0000ff); 8470d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mFrameNoTransformPaint.setStyle(Paint.Style.STROKE); 8570d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mFrameNoTransformPaint.setStrokeWidth(0); 8670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mFrameNoTransformPaint.setShadowLayer(density, density, density, 0xff000000); 87ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 88ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 89a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn public void setAssistStructure(AssistStructure as) { 90a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn mAssistStructure = as; 91ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mTextRects.clear(); 920b071a08d8dec3e68937590938199273f3b123ccDianne Hackborn final int N = as.getWindowNodeCount(); 93ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn if (N > 0) { 94ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn for (int i=0; i<N; i++) { 950b071a08d8dec3e68937590938199273f3b123ccDianne Hackborn AssistStructure.WindowNode windowNode = as.getWindowNodeAt(i); 9670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mMatrixStack.clear(); 9770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn Matrix matrix = new Matrix(); 9870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn matrix.setTranslate(windowNode.getLeft(), windowNode.getTop()); 9970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mMatrixStack.add(matrix); 10070d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn buildTextRects(windowNode.getRootViewNode(), 0, windowNode.getLeft(), 1010b071a08d8dec3e68937590938199273f3b123ccDianne Hackborn windowNode.getTop()); 102ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 103ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 1046251f0d42be7da54d7f1bc8f570a44883b7d9052Dianne Hackborn Log.d(TAG, "Building text rects in " + this + ": found " + mTextRects.size()); 10527eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn invalidate(); 106ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 107ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 10870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn public void logTree() { 10970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn if (mAssistStructure != null) { 11070d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mAssistStructure.dump(); 11170d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 11270d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 11370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn 11470d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn public void logText() { 11570d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn final int N = mTextRects.size(); 11670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn for (int i=0; i<N; i++) { 11770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn TextEntry te = mTextRects.get(i); 11870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn Log.d(TAG, "View " + te.className + " " + te.bounds.toShortString() 11970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn + " in " + te.parentLeft + "," + te.parentTop 120331ebfa7751a99a9e740d125c5ac4381a0151090Dianne Hackborn + " matrix=" + te.matrix.toShortString() 121331ebfa7751a99a9e740d125c5ac4381a0151090Dianne Hackborn + " size=" + te.textSize + " color=#" + Integer.toHexString(te.textColor) 122331ebfa7751a99a9e740d125c5ac4381a0151090Dianne Hackborn + ": " 12370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn + te.text); 1246f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn if (te.lineCharOffsets != null && te.lineBaselines != null) { 1256f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn final int num = te.lineCharOffsets.length < te.lineBaselines.length 1266f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn ? te.lineCharOffsets.length : te.lineBaselines.length; 1276f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn for (int j=0; j<num; j++) { 1286f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn Log.d(TAG, " Line #" + j + ": offset=" + te.lineCharOffsets[j] 1296f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn + " baseline=" + te.lineBaselines[j]); 1306f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn } 1316f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn } 13270d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 13370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 13470d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn 135ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn public void clearAssistData() { 136a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn mAssistStructure = null; 137ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn mTextRects.clear(); 138ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn } 139ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn 14070d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn void buildTextRects(AssistStructure.ViewNode root, int matrixStackIndex, 14170d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn int parentLeft, int parentTop) { 142ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn if (root.getVisibility() != View.VISIBLE) { 143ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn return; 144ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 14570d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn Matrix parentMatrix = mMatrixStack.get(matrixStackIndex); 14670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn matrixStackIndex++; 14770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn Matrix matrix; 14870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn if (mMatrixStack.size() > matrixStackIndex) { 14970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn matrix = mMatrixStack.get(matrixStackIndex); 15070d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn matrix.set(parentMatrix); 15170d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } else { 15270d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn matrix = new Matrix(parentMatrix); 15370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mMatrixStack.add(matrix); 15470d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 15570d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn matrix.preTranslate(root.getLeft(), root.getTop()); 15670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn int left = parentLeft + root.getLeft(); 15770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn int top = parentTop + root.getTop(); 15870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn Matrix transform = root.getTransformation(); 15970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn if (transform != null) { 16070d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn matrix.preConcat(transform); 16170d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 1626251f0d42be7da54d7f1bc8f570a44883b7d9052Dianne Hackborn if (root.getText() != null || root.getContentDescription() != null) { 16370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn TextEntry te = new TextEntry(root, parentLeft, parentTop, matrix); 16470d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mTextRects.add(te); 165ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 166ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final int N = root.getChildCount(); 167ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn if (N > 0) { 168ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn left -= root.getScrollX(); 169ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn top -= root.getScrollY(); 17070d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn matrix.preTranslate(-root.getScrollX(), -root.getScrollY()); 171ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn for (int i=0; i<N; i++) { 1720b071a08d8dec3e68937590938199273f3b123ccDianne Hackborn AssistStructure.ViewNode child = root.getChildAt(i); 17370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn buildTextRects(child, matrixStackIndex, left, top); 174ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 175ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 176ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 177ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 178ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn @Override 179ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn protected void onDraw(Canvas canvas) { 180ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn super.onDraw(canvas); 181ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn getLocationOnScreen(mTmpLocation); 182ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final int N = mTextRects.size(); 1836251f0d42be7da54d7f1bc8f570a44883b7d9052Dianne Hackborn Log.d(TAG, "Drawing text rects in " + this + ": found " + mTextRects.size()); 184ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn for (int i=0; i<N; i++) { 18570d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn TextEntry te = mTextRects.get(i); 18670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn canvas.drawRect(te.bounds.left - mTmpLocation[0], te.bounds.top - mTmpLocation[1], 18770d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn te.bounds.right - mTmpLocation[0], te.bounds.bottom - mTmpLocation[1], 18870d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mFrameNoTransformPaint); 18970d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn } 19070d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn for (int i=0; i<N; i++) { 19170d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn TextEntry te = mTextRects.get(i); 19270d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn canvas.save(); 19370d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn canvas.translate(-mTmpLocation[0], -mTmpLocation[1]); 19470d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn canvas.concat(te.matrix); 19570d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn canvas.drawRect(0, 0, te.bounds.right - te.bounds.left, te.bounds.bottom - te.bounds.top, 19670d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn mFramePaint); 1976f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn if (te.lineBaselines != null) { 1986f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn for (int j=0; j<te.lineBaselines.length; j++) { 1996f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn canvas.drawLine(0, te.lineBaselines[j] - te.scrollY, 2006f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn te.bounds.right - te.bounds.left, te.lineBaselines[j] - te.scrollY, 2016f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn mFrameBaselinePaint); 2026f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn } 2036f0fdc4167ad906fc7409856e86cd0cc601c3b53Dianne Hackborn } 20470d8be7616a450e9b7ef09c8bda5a8b25936a29aDianne Hackborn canvas.restore(); 205ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 206ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 207ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn} 208