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