1d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi/* 2d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * Copyright (C) 2012 The Android Open Source Project 3d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * 48aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 58aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * you may not use this file except in compliance with the License. 68aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * You may obtain a copy of the License at 7d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * 88aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * 10d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * Unless required by applicable law or agreed to in writing, software 118aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 128aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * See the License for the specific language governing permissions and 148aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * limitations under the License. 15d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi */ 16d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 17d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bipackage com.android.inputmethod.keyboard.internal; 18d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 19d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport android.content.res.TypedArray; 20d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport android.graphics.Canvas; 21d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport android.graphics.Paint; 22d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport android.graphics.Paint.Align; 23d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport android.graphics.Rect; 24d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport android.graphics.RectF; 25d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport android.text.TextUtils; 26d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 27d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport com.android.inputmethod.keyboard.PointerTracker; 28d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport com.android.inputmethod.latin.R; 29d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Biimport com.android.inputmethod.latin.SuggestedWords; 305b91b551e5ffaf2c2e691dfbd434f21c82293986Jean Chalardimport com.android.inputmethod.latin.common.CoordinateUtils; 31d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 322ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaokaimport javax.annotation.Nonnull; 332ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka 34d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi/** 35d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * The class for single gesture preview text. The class for multiple gesture preview text will be 36d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * derived from it. 37375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * 38375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextSize 39375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextColor 40375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextOffset 41375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewColor 42375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewHorizontalPadding 43375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewVerticalPadding 44375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewRoundRadius 45d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi */ 46cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaokapublic class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview { 475c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka protected static final class GesturePreviewTextParams { 48d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi public final int mGesturePreviewTextOffset; 49d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi public final int mGesturePreviewTextHeight; 50d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi public final float mGesturePreviewHorizontalPadding; 51d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi public final float mGesturePreviewVerticalPadding; 52d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi public final float mGesturePreviewRoundRadius; 537fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka public final int mDisplayWidth; 545c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka 555c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private final int mGesturePreviewTextSize; 565c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private final int mGesturePreviewTextColor; 575c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private final int mGesturePreviewColor; 585c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private final Paint mPaint = new Paint(); 59d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 60d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' }; 61d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 629c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka public GesturePreviewTextParams(final TypedArray mainKeyboardViewAttr) { 639c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka mGesturePreviewTextSize = mainKeyboardViewAttr.getDimensionPixelSize( 649c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka R.styleable.MainKeyboardView_gestureFloatingPreviewTextSize, 0); 659c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka mGesturePreviewTextColor = mainKeyboardViewAttr.getColor( 669c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka R.styleable.MainKeyboardView_gestureFloatingPreviewTextColor, 0); 679c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka mGesturePreviewTextOffset = mainKeyboardViewAttr.getDimensionPixelOffset( 689c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka R.styleable.MainKeyboardView_gestureFloatingPreviewTextOffset, 0); 699c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka mGesturePreviewColor = mainKeyboardViewAttr.getColor( 709c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka R.styleable.MainKeyboardView_gestureFloatingPreviewColor, 0); 719c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka mGesturePreviewHorizontalPadding = mainKeyboardViewAttr.getDimension( 729c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka R.styleable.MainKeyboardView_gestureFloatingPreviewHorizontalPadding, 0.0f); 739c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka mGesturePreviewVerticalPadding = mainKeyboardViewAttr.getDimension( 749c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka R.styleable.MainKeyboardView_gestureFloatingPreviewVerticalPadding, 0.0f); 759c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka mGesturePreviewRoundRadius = mainKeyboardViewAttr.getDimension( 769c968b62d1b4049959b7b7b0f05388c90e31b46eTadashi G. Takaoka R.styleable.MainKeyboardView_gestureFloatingPreviewRoundRadius, 0.0f); 777fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka mDisplayWidth = mainKeyboardViewAttr.getResources().getDisplayMetrics().widthPixels; 78d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 795c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka final Paint textPaint = getTextPaint(); 80d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final Rect textRect = new Rect(); 81d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi textPaint.getTextBounds(TEXT_HEIGHT_REFERENCE_CHAR, 0, 1, textRect); 82d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi mGesturePreviewTextHeight = textRect.height(); 83d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi } 84d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 855c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka public Paint getTextPaint() { 865c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka mPaint.setAntiAlias(true); 875c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka mPaint.setTextAlign(Align.CENTER); 885c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka mPaint.setTextSize(mGesturePreviewTextSize); 895c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka mPaint.setColor(mGesturePreviewTextColor); 905c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka return mPaint; 915c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka } 92d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 935c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka public Paint getBackgroundPaint() { 945c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka mPaint.setColor(mGesturePreviewColor); 955c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka return mPaint; 965c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka } 975c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka } 98d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 995c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private final GesturePreviewTextParams mParams; 1005c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private final RectF mGesturePreviewRectangle = new RectF(); 1015c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private int mPreviewTextX; 1025c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private int mPreviewTextY; 10330f4a2a4d750dc8c3132d706d9148daf71fbd168Adrian Velicu private SuggestedWords mSuggestedWords = SuggestedWords.getEmptyInstance(); 1045c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka private final int[] mLastPointerCoords = CoordinateUtils.newInstance(); 105d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 1067fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka public GestureFloatingTextDrawingPreview(final TypedArray mainKeyboardViewAttr) { 1077fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka mParams = new GesturePreviewTextParams(mainKeyboardViewAttr); 108d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi } 109d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 110afca1ddd233c03d79433931a0b6ba97ed22663edTadashi G. Takaoka @Override 111afca1ddd233c03d79433931a0b6ba97ed22663edTadashi G. Takaoka public void onDeallocateMemory() { 112afca1ddd233c03d79433931a0b6ba97ed22663edTadashi G. Takaoka // Nothing to do here. 113afca1ddd233c03d79433931a0b6ba97ed22663edTadashi G. Takaoka } 114afca1ddd233c03d79433931a0b6ba97ed22663edTadashi G. Takaoka 1152ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka public void dismissGestureFloatingPreviewText() { 1162ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka setSuggetedWords(SuggestedWords.getEmptyInstance()); 1172ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka } 1182ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka 1192ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka public void setSuggetedWords(@Nonnull final SuggestedWords suggestedWords) { 1204987108f34c08825ccb1c859c971bf232438c4aaTadashi G. Takaoka if (!isPreviewEnabled()) { 1214987108f34c08825ccb1c859c971bf232438c4aaTadashi G. Takaoka return; 1224987108f34c08825ccb1c859c971bf232438c4aaTadashi G. Takaoka } 12350d902ac6fd018131bd7044dd968bb99e0fdba7bTadashi G. Takaoka mSuggestedWords = suggestedWords; 124d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi updatePreviewPosition(); 125d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi } 126d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 127d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi @Override 1284987108f34c08825ccb1c859c971bf232438c4aaTadashi G. Takaoka public void setPreviewPosition(final PointerTracker tracker) { 129212165b0b8308802a461a6a526d367ba67b5567aTadashi G. Takaoka if (!isPreviewEnabled()) { 1304987108f34c08825ccb1c859c971bf232438c4aaTadashi G. Takaoka return; 1314987108f34c08825ccb1c859c971bf232438c4aaTadashi G. Takaoka } 1324987108f34c08825ccb1c859c971bf232438c4aaTadashi G. Takaoka tracker.getLastCoordinates(mLastPointerCoords); 133d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi updatePreviewPosition(); 134d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi } 135d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 136d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi /** 137d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * Draws gesture preview text 138d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * @param canvas The canvas where preview text is drawn. 139d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi */ 140d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi @Override 1412ecbfe8e93f8d8fce0adc47659b5d2f52cb68849Tadashi G. Takaoka public void drawPreview(final Canvas canvas) { 142d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi if (!isPreviewEnabled() || mSuggestedWords.isEmpty() 143d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi || TextUtils.isEmpty(mSuggestedWords.getWord(0))) { 144d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi return; 145d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi } 146d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final float round = mParams.mGesturePreviewRoundRadius; 1475c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka canvas.drawRoundRect( 1485c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka mGesturePreviewRectangle, round, round, mParams.getBackgroundPaint()); 149d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final String text = mSuggestedWords.getWord(0); 1505c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka canvas.drawText(text, mPreviewTextX, mPreviewTextY, mParams.getTextPaint()); 151d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi } 152d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 153d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi /** 154d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi * Updates gesture preview text position based on mLastPointerCoords. 155d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi */ 156d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi protected void updatePreviewPosition() { 157d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi if (mSuggestedWords.isEmpty() || TextUtils.isEmpty(mSuggestedWords.getWord(0))) { 1587fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka invalidateDrawingView(); 159d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi return; 160d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi } 161d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final String text = mSuggestedWords.getWord(0); 162d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 163d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final RectF rectangle = mGesturePreviewRectangle; 164d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 165d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final int textHeight = mParams.mGesturePreviewTextHeight; 1665c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka final float textWidth = mParams.getTextPaint().measureText(text); 167d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final float hPad = mParams.mGesturePreviewHorizontalPadding; 168d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final float vPad = mParams.mGesturePreviewVerticalPadding; 169d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final float rectWidth = textWidth + hPad * 2.0f; 170d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final float rectHeight = textHeight + vPad * 2.0f; 171d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 172d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final float rectX = Math.min( 173d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi Math.max(CoordinateUtils.x(mLastPointerCoords) - rectWidth / 2.0f, 0.0f), 1747fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka mParams.mDisplayWidth - rectWidth); 175d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi final float rectY = CoordinateUtils.y(mLastPointerCoords) 176d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi - mParams.mGesturePreviewTextOffset - rectHeight; 177d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight); 178d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi 1795c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka mPreviewTextX = (int)(rectX + hPad + textWidth / 2.0f); 1805c58133c8098c73b687ac8483ed8b2c32a53c257Tadashi G. Takaoka mPreviewTextY = (int)(rectY + vPad) + textHeight; 1814987108f34c08825ccb1c859c971bf232438c4aaTadashi G. Takaoka // TODO: Should narrow the invalidate region. 1827fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka invalidateDrawingView(); 183d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi } 184d52730a2d7a6e98245719ce5c53bcf4b3a3ba1c9Xiaojun Bi} 185