Loading java/src/com/android/inputmethod/keyboard/KeyboardView.java +58 −56 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.NinePatchDrawable; Loading @@ -41,6 +40,7 @@ import com.android.inputmethod.latin.utils.TypefaceUtils; import java.util.HashSet; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** Loading Loading @@ -100,6 +100,8 @@ public class KeyboardView extends View { private static final float MAX_LABEL_RATIO = 0.90f; // Main keyboard // TODO: Consider having a dummy keyboard object to make this @Nonnull @Nullable private Keyboard mKeyboard; protected final KeyDrawParams mKeyDrawParams = new KeyDrawParams(); Loading @@ -108,14 +110,14 @@ public class KeyboardView extends View { private boolean mInvalidateAllKeys; /** The keys that should be drawn */ private final HashSet<Key> mInvalidatedKeys = new HashSet<>(); /** The working rectangle variable */ private final Rect mWorkingRect = new Rect(); /** The working rectangle for clipping */ private final Rect mClipRect = new Rect(); /** The keyboard bitmap buffer for faster updates */ /** The clip region to draw keys */ private final Region mClipRegion = new Region(); private Bitmap mOffscreenBuffer; /** The canvas for the above mutable keyboard bitmap */ @Nonnull private final Canvas mOffscreenCanvas = new Canvas(); @Nonnull private final Paint mPaint = new Paint(); private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics(); public KeyboardView(final Context context, final AttributeSet attrs) { Loading Loading @@ -161,11 +163,12 @@ public class KeyboardView extends View { mPaint.setAntiAlias(true); } @Nullable public KeyVisualAttributes getKeyVisualAttribute() { return mKeyVisualAttributes; } private static void blendAlpha(final Paint paint, final int alpha) { private static void blendAlpha(@Nonnull final Paint paint, final int alpha) { final int color = paint.getColor(); paint.setARGB((paint.getAlpha() * alpha) / Constants.Color.ALPHA_OPAQUE, Color.red(color), Color.green(color), Color.blue(color)); Loading @@ -184,7 +187,7 @@ public class KeyboardView extends View { * @see #getKeyboard() * @param keyboard the keyboard to display in this view */ public void setKeyboard(final Keyboard keyboard) { public void setKeyboard(@Nonnull final Keyboard keyboard) { mKeyboard = keyboard; final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes); Loading @@ -198,6 +201,7 @@ public class KeyboardView extends View { * @return the currently attached keyboard * @see #setKeyboard(Keyboard) */ @Nullable public Keyboard getKeyboard() { return mKeyboard; } Loading @@ -212,13 +216,14 @@ public class KeyboardView extends View { @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { if (mKeyboard == null) { final Keyboard keyboard = getKeyboard(); if (keyboard == null) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); return; } // The main keyboard expands to the entire this {@link KeyboardView}. final int width = mKeyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); final int height = mKeyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); setMeasuredDimension(width, height); } Loading Loading @@ -266,52 +271,45 @@ public class KeyboardView extends View { } } private void onDrawKeyboard(final Canvas canvas) { if (mKeyboard == null) return; private void onDrawKeyboard(@Nonnull final Canvas canvas) { final Keyboard keyboard = getKeyboard(); if (keyboard == null) { return; } final int width = getWidth(); final int height = getHeight(); final Paint paint = mPaint; final Drawable background = getBackground(); // Calculate clip region and set. final boolean drawAllKeys = mInvalidateAllKeys || mInvalidatedKeys.isEmpty(); final boolean isHardwareAccelerated = canvas.isHardwareAccelerated(); // TODO: Confirm if it's really required to draw all keys when hardware acceleration is on. if (drawAllKeys || isHardwareAccelerated) { mClipRegion.set(0, 0, width, height); } else { mClipRegion.setEmpty(); for (final Key key : mInvalidatedKeys) { if (mKeyboard.hasKey(key)) { final int x = key.getX() + getPaddingLeft(); final int y = key.getY() + getPaddingTop(); mWorkingRect.set(x, y, x + key.getWidth(), y + key.getHeight()); mClipRegion.union(mWorkingRect); } } } if (!isHardwareAccelerated) { canvas.clipRegion(mClipRegion, Region.Op.REPLACE); // Draw keyboard background. if (!isHardwareAccelerated && background != null) { // Need to draw keyboard background on {@link #mOffscreenBuffer}. canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR); final Drawable background = getBackground(); if (background != null) { background.draw(canvas); } } // TODO: Confirm if it's really required to draw all keys when hardware acceleration is on. if (drawAllKeys || isHardwareAccelerated) { // Draw all keys. for (final Key key : mKeyboard.getSortedKeys()) { for (final Key key : keyboard.getSortedKeys()) { onDrawKey(key, canvas, paint); } } else { // Draw invalidated keys. for (final Key key : mInvalidatedKeys) { if (mKeyboard.hasKey(key)) { onDrawKey(key, canvas, paint); if (!keyboard.hasKey(key)) { continue; } if (background != null) { // Need to redraw key's background on {@link #mOffscreenBuffer}. final int x = key.getX() + getPaddingLeft(); final int y = key.getY() + getPaddingTop(); mClipRect.set(x, y, x + key.getWidth(), y + key.getHeight()); canvas.save(); canvas.clipRect(mClipRect); canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR); background.draw(canvas); canvas.restore(); } onDrawKey(key, canvas, paint); } } Loading @@ -319,29 +317,31 @@ public class KeyboardView extends View { mInvalidateAllKeys = false; } private void onDrawKey(final Key key, final Canvas canvas, final Paint paint) { private void onDrawKey(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Paint paint) { final int keyDrawX = key.getDrawX() + getPaddingLeft(); final int keyDrawY = key.getY() + getPaddingTop(); canvas.translate(keyDrawX, keyDrawY); final int keyHeight = mKeyboard.mMostCommonKeyHeight - mKeyboard.mVerticalGap; final KeyVisualAttributes attr = key.getVisualAttributes(); final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams(keyHeight, attr); final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams(key.getHeight(), attr); params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE; if (!key.isSpacer()) { final Drawable background = key.selectBackgroundDrawable( mKeyBackground, mFunctionalKeyBackground, mSpacebarBackground); if (background != null) { onDrawKeyBackground(key, canvas, background); } } onDrawKeyTopVisuals(key, canvas, paint, params); canvas.translate(-keyDrawX, -keyDrawY); } // Draw key background. protected void onDrawKeyBackground(final Key key, final Canvas canvas, final Drawable background) { protected void onDrawKeyBackground(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Drawable background) { final int keyWidth = key.getDrawWidth(); final int keyHeight = key.getHeight(); final int bgWidth, bgHeight, bgX, bgY; Loading Loading @@ -373,15 +373,17 @@ public class KeyboardView extends View { } // Draw key top visuals. protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint, final KeyDrawParams params) { protected void onDrawKeyTopVisuals(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Paint paint, @Nonnull final KeyDrawParams params) { final int keyWidth = key.getDrawWidth(); final int keyHeight = key.getHeight(); final float centerX = keyWidth * 0.5f; final float centerY = keyHeight * 0.5f; // Draw key label. final Drawable icon = key.getIcon(mKeyboard.mIconsSet, params.mAnimAlpha); final Keyboard keyboard = getKeyboard(); final Drawable icon = (keyboard == null) ? null : key.getIcon(keyboard.mIconsSet, params.mAnimAlpha); float labelX = centerX; float labelBaseline = centerY; final String label = key.getLabel(); Loading Loading @@ -500,8 +502,8 @@ public class KeyboardView extends View { } // Draw popup hint "..." at the bottom right corner of the key. protected void drawKeyPopupHint(final Key key, final Canvas canvas, final Paint paint, final KeyDrawParams params) { protected void drawKeyPopupHint(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Paint paint, @Nonnull final KeyDrawParams params) { if (TextUtils.isEmpty(mKeyPopupHintLetter)) { return; } Loading @@ -518,15 +520,15 @@ public class KeyboardView extends View { canvas.drawText(mKeyPopupHintLetter, hintX, hintY, paint); } protected static void drawIcon(final Canvas canvas, final Drawable icon, final int x, final int y, final int width, final int height) { protected static void drawIcon(@Nonnull final Canvas canvas,@Nonnull final Drawable icon, final int x, final int y, final int width, final int height) { canvas.translate(x, y); icon.setBounds(0, 0, width, height); icon.draw(canvas); canvas.translate(-x, -y); } public Paint newLabelPaint(final Key key) { public Paint newLabelPaint(@Nullable final Key key) { final Paint paint = new Paint(); paint.setAntiAlias(true); if (key == null) { Loading Loading @@ -560,7 +562,7 @@ public class KeyboardView extends View { * @see #invalidateAllKeys */ public void invalidateKey(@Nullable final Key key) { if (key == null || mInvalidateAllKeys) { if (mInvalidateAllKeys || key == null) { return; } mInvalidatedKeys.add(key); Loading Loading
java/src/com/android/inputmethod/keyboard/KeyboardView.java +58 −56 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.NinePatchDrawable; Loading @@ -41,6 +40,7 @@ import com.android.inputmethod.latin.utils.TypefaceUtils; import java.util.HashSet; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** Loading Loading @@ -100,6 +100,8 @@ public class KeyboardView extends View { private static final float MAX_LABEL_RATIO = 0.90f; // Main keyboard // TODO: Consider having a dummy keyboard object to make this @Nonnull @Nullable private Keyboard mKeyboard; protected final KeyDrawParams mKeyDrawParams = new KeyDrawParams(); Loading @@ -108,14 +110,14 @@ public class KeyboardView extends View { private boolean mInvalidateAllKeys; /** The keys that should be drawn */ private final HashSet<Key> mInvalidatedKeys = new HashSet<>(); /** The working rectangle variable */ private final Rect mWorkingRect = new Rect(); /** The working rectangle for clipping */ private final Rect mClipRect = new Rect(); /** The keyboard bitmap buffer for faster updates */ /** The clip region to draw keys */ private final Region mClipRegion = new Region(); private Bitmap mOffscreenBuffer; /** The canvas for the above mutable keyboard bitmap */ @Nonnull private final Canvas mOffscreenCanvas = new Canvas(); @Nonnull private final Paint mPaint = new Paint(); private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics(); public KeyboardView(final Context context, final AttributeSet attrs) { Loading Loading @@ -161,11 +163,12 @@ public class KeyboardView extends View { mPaint.setAntiAlias(true); } @Nullable public KeyVisualAttributes getKeyVisualAttribute() { return mKeyVisualAttributes; } private static void blendAlpha(final Paint paint, final int alpha) { private static void blendAlpha(@Nonnull final Paint paint, final int alpha) { final int color = paint.getColor(); paint.setARGB((paint.getAlpha() * alpha) / Constants.Color.ALPHA_OPAQUE, Color.red(color), Color.green(color), Color.blue(color)); Loading @@ -184,7 +187,7 @@ public class KeyboardView extends View { * @see #getKeyboard() * @param keyboard the keyboard to display in this view */ public void setKeyboard(final Keyboard keyboard) { public void setKeyboard(@Nonnull final Keyboard keyboard) { mKeyboard = keyboard; final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes); Loading @@ -198,6 +201,7 @@ public class KeyboardView extends View { * @return the currently attached keyboard * @see #setKeyboard(Keyboard) */ @Nullable public Keyboard getKeyboard() { return mKeyboard; } Loading @@ -212,13 +216,14 @@ public class KeyboardView extends View { @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { if (mKeyboard == null) { final Keyboard keyboard = getKeyboard(); if (keyboard == null) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); return; } // The main keyboard expands to the entire this {@link KeyboardView}. final int width = mKeyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); final int height = mKeyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); setMeasuredDimension(width, height); } Loading Loading @@ -266,52 +271,45 @@ public class KeyboardView extends View { } } private void onDrawKeyboard(final Canvas canvas) { if (mKeyboard == null) return; private void onDrawKeyboard(@Nonnull final Canvas canvas) { final Keyboard keyboard = getKeyboard(); if (keyboard == null) { return; } final int width = getWidth(); final int height = getHeight(); final Paint paint = mPaint; final Drawable background = getBackground(); // Calculate clip region and set. final boolean drawAllKeys = mInvalidateAllKeys || mInvalidatedKeys.isEmpty(); final boolean isHardwareAccelerated = canvas.isHardwareAccelerated(); // TODO: Confirm if it's really required to draw all keys when hardware acceleration is on. if (drawAllKeys || isHardwareAccelerated) { mClipRegion.set(0, 0, width, height); } else { mClipRegion.setEmpty(); for (final Key key : mInvalidatedKeys) { if (mKeyboard.hasKey(key)) { final int x = key.getX() + getPaddingLeft(); final int y = key.getY() + getPaddingTop(); mWorkingRect.set(x, y, x + key.getWidth(), y + key.getHeight()); mClipRegion.union(mWorkingRect); } } } if (!isHardwareAccelerated) { canvas.clipRegion(mClipRegion, Region.Op.REPLACE); // Draw keyboard background. if (!isHardwareAccelerated && background != null) { // Need to draw keyboard background on {@link #mOffscreenBuffer}. canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR); final Drawable background = getBackground(); if (background != null) { background.draw(canvas); } } // TODO: Confirm if it's really required to draw all keys when hardware acceleration is on. if (drawAllKeys || isHardwareAccelerated) { // Draw all keys. for (final Key key : mKeyboard.getSortedKeys()) { for (final Key key : keyboard.getSortedKeys()) { onDrawKey(key, canvas, paint); } } else { // Draw invalidated keys. for (final Key key : mInvalidatedKeys) { if (mKeyboard.hasKey(key)) { onDrawKey(key, canvas, paint); if (!keyboard.hasKey(key)) { continue; } if (background != null) { // Need to redraw key's background on {@link #mOffscreenBuffer}. final int x = key.getX() + getPaddingLeft(); final int y = key.getY() + getPaddingTop(); mClipRect.set(x, y, x + key.getWidth(), y + key.getHeight()); canvas.save(); canvas.clipRect(mClipRect); canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR); background.draw(canvas); canvas.restore(); } onDrawKey(key, canvas, paint); } } Loading @@ -319,29 +317,31 @@ public class KeyboardView extends View { mInvalidateAllKeys = false; } private void onDrawKey(final Key key, final Canvas canvas, final Paint paint) { private void onDrawKey(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Paint paint) { final int keyDrawX = key.getDrawX() + getPaddingLeft(); final int keyDrawY = key.getY() + getPaddingTop(); canvas.translate(keyDrawX, keyDrawY); final int keyHeight = mKeyboard.mMostCommonKeyHeight - mKeyboard.mVerticalGap; final KeyVisualAttributes attr = key.getVisualAttributes(); final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams(keyHeight, attr); final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams(key.getHeight(), attr); params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE; if (!key.isSpacer()) { final Drawable background = key.selectBackgroundDrawable( mKeyBackground, mFunctionalKeyBackground, mSpacebarBackground); if (background != null) { onDrawKeyBackground(key, canvas, background); } } onDrawKeyTopVisuals(key, canvas, paint, params); canvas.translate(-keyDrawX, -keyDrawY); } // Draw key background. protected void onDrawKeyBackground(final Key key, final Canvas canvas, final Drawable background) { protected void onDrawKeyBackground(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Drawable background) { final int keyWidth = key.getDrawWidth(); final int keyHeight = key.getHeight(); final int bgWidth, bgHeight, bgX, bgY; Loading Loading @@ -373,15 +373,17 @@ public class KeyboardView extends View { } // Draw key top visuals. protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint, final KeyDrawParams params) { protected void onDrawKeyTopVisuals(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Paint paint, @Nonnull final KeyDrawParams params) { final int keyWidth = key.getDrawWidth(); final int keyHeight = key.getHeight(); final float centerX = keyWidth * 0.5f; final float centerY = keyHeight * 0.5f; // Draw key label. final Drawable icon = key.getIcon(mKeyboard.mIconsSet, params.mAnimAlpha); final Keyboard keyboard = getKeyboard(); final Drawable icon = (keyboard == null) ? null : key.getIcon(keyboard.mIconsSet, params.mAnimAlpha); float labelX = centerX; float labelBaseline = centerY; final String label = key.getLabel(); Loading Loading @@ -500,8 +502,8 @@ public class KeyboardView extends View { } // Draw popup hint "..." at the bottom right corner of the key. protected void drawKeyPopupHint(final Key key, final Canvas canvas, final Paint paint, final KeyDrawParams params) { protected void drawKeyPopupHint(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Paint paint, @Nonnull final KeyDrawParams params) { if (TextUtils.isEmpty(mKeyPopupHintLetter)) { return; } Loading @@ -518,15 +520,15 @@ public class KeyboardView extends View { canvas.drawText(mKeyPopupHintLetter, hintX, hintY, paint); } protected static void drawIcon(final Canvas canvas, final Drawable icon, final int x, final int y, final int width, final int height) { protected static void drawIcon(@Nonnull final Canvas canvas,@Nonnull final Drawable icon, final int x, final int y, final int width, final int height) { canvas.translate(x, y); icon.setBounds(0, 0, width, height); icon.draw(canvas); canvas.translate(-x, -y); } public Paint newLabelPaint(final Key key) { public Paint newLabelPaint(@Nullable final Key key) { final Paint paint = new Paint(); paint.setAntiAlias(true); if (key == null) { Loading Loading @@ -560,7 +562,7 @@ public class KeyboardView extends View { * @see #invalidateAllKeys */ public void invalidateKey(@Nullable final Key key) { if (key == null || mInvalidateAllKeys) { if (mInvalidateAllKeys || key == null) { return; } mInvalidatedKeys.add(key); Loading