diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 76e76cc824eaf4f4e73953180f2919b9ea2a8297..27bf329354671da807b31f358a689b9bd83e8a0e 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -109,7 +109,7 @@
         <attr name="shadowRadius" format="float" />
         <attr name="backgroundDimAlpha" format="integer" />
 
-        <attr name="keyTextStyle" format="enum">
+        <attr name="keyTypeface" format="enum">
             <!-- This should be aligned with Typeface.NORMAL etc. -->
             <enum name="normal" value="0" />
             <enum name="bold" value="1" />
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 0220c836ea895dffb2321dd67b8a9b21223b445c..a52ee06d40263feadfed6a4659faaa76ce77e380 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -42,7 +42,7 @@
         <item name="keyHintLetterRatio">@fraction/key_hint_letter_ratio</item>
         <item name="keyHintLabelRatio">@fraction/key_hint_label_ratio</item>
         <item name="keyShiftedLetterHintRatio">@fraction/key_uppercase_letter_ratio</item>
-        <item name="keyTextStyle">normal</item>
+        <item name="keyTypeface">normal</item>
         <item name="keyTextColor">#FFFFFFFF</item>
         <item name="keyTextInactivatedColor">#FFFFFFFF</item>
         <item name="keyHintLetterColor">#80000000</item>
@@ -243,7 +243,7 @@
         name="KeyboardView.Stone.Bold"
         parent="KeyboardView.Stone"
     >
-        <item name="keyTextStyle">bold</item>
+        <item name="keyTypeface">bold</item>
     </style>
     <style
         name="MainKeyboardView.Stone.Bold"
@@ -272,7 +272,7 @@
     >
         <item name="android:background">@drawable/keyboard_dark_background</item>
         <item name="keyBackground">@drawable/btn_keyboard_key_gingerbread</item>
-        <item name="keyTextStyle">bold</item>
+        <item name="keyTypeface">bold</item>
     </style>
     <style
         name="MainKeyboardView.Gingerbread"
@@ -317,7 +317,7 @@
     >
         <item name="android:background">@drawable/keyboard_background_holo</item>
         <item name="keyBackground">@drawable/btn_keyboard_key_ics</item>
-        <item name="keyTextStyle">bold</item>
+        <item name="keyTypeface">bold</item>
         <item name="keyTextInactivatedColor">#66E0E4E5</item>
         <item name="keyHintLetterColor">#80000000</item>
         <item name="keyHintLabelColor">#A0FFFFFF</item>
diff --git a/java/res/xml-sw600dp-land/kbd_thai.xml b/java/res/xml-sw600dp-land/kbd_thai.xml
index b75980f2fb98f3fedceffefe9c8a8324184108cc..3143061400bc22364112b93b78b4c3c20047dfe4 100644
--- a/java/res/xml-sw600dp-land/kbd_thai.xml
+++ b/java/res/xml-sw600dp-land/kbd_thai.xml
@@ -22,6 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:rowHeight="20%p"
     latin:verticalGap="3.20%p"
+    latin:keyTypeface="normal"
     latin:touchPositionCorrectionData="@null"
 >
     <include
diff --git a/java/res/xml-sw600dp/kbd_thai.xml b/java/res/xml-sw600dp/kbd_thai.xml
index b75980f2fb98f3fedceffefe9c8a8324184108cc..3143061400bc22364112b93b78b4c3c20047dfe4 100644
--- a/java/res/xml-sw600dp/kbd_thai.xml
+++ b/java/res/xml-sw600dp/kbd_thai.xml
@@ -22,6 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:rowHeight="20%p"
     latin:verticalGap="3.20%p"
+    latin:keyTypeface="normal"
     latin:touchPositionCorrectionData="@null"
 >
     <include
diff --git a/java/res/xml-sw768dp-land/kbd_thai.xml b/java/res/xml-sw768dp-land/kbd_thai.xml
index b2cdbc373e21a488f1932a0ec399c3476b41ca44..b7633df33ee547317bcf449eb8a52bb5bfa0a602 100644
--- a/java/res/xml-sw768dp-land/kbd_thai.xml
+++ b/java/res/xml-sw768dp-land/kbd_thai.xml
@@ -22,6 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:rowHeight="20%p"
     latin:verticalGap="2.65%p"
+    latin:keyTypeface="normal"
     latin:touchPositionCorrectionData="@null"
 >
     <include
diff --git a/java/res/xml-sw768dp/kbd_thai.xml b/java/res/xml-sw768dp/kbd_thai.xml
index 593ccbd480825c7afa545e071ef9d44d58df7cb1..2be6a254983a0a7e108e924c864b62a593075626 100644
--- a/java/res/xml-sw768dp/kbd_thai.xml
+++ b/java/res/xml-sw768dp/kbd_thai.xml
@@ -22,6 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:rowHeight="20%p"
     latin:verticalGap="2.95%p"
+    latin:keyTypeface="normal"
     latin:touchPositionCorrectionData="@null"
 >
     <include
diff --git a/java/res/xml/kbd_arabic.xml b/java/res/xml/kbd_arabic.xml
index ce5f30b2fff9c0008e820250121830127d32911b..e3b90b07be19bd45565fb6478847d68d21b32273 100644
--- a/java/res/xml/kbd_arabic.xml
+++ b/java/res/xml/kbd_arabic.xml
@@ -20,6 +20,7 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+    latin:keyTypeface="normal"
 >
     <include
         latin:keyboardLayout="@xml/rows_arabic" />
diff --git a/java/res/xml/kbd_thai.xml b/java/res/xml/kbd_thai.xml
index 058ca16a3ee7d5079e97caa36db2101d467d998c..b015d70632d5acaeccc91f60a874574b608cd086 100644
--- a/java/res/xml/kbd_thai.xml
+++ b/java/res/xml/kbd_thai.xml
@@ -20,6 +20,7 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+    latin:keyTypeface="normal"
 >
     <include
         latin:keyboardLayout="@xml/rows_thai" />
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index e12e5f3010d8eb955582a67418cdff295ab2eeab..a5f9e9e75da916094b11c93a8c4be7378817a841 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -20,6 +20,7 @@ import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.graphics.Typeface;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -120,6 +121,9 @@ public class Keyboard {
     /** Default gap between rows */
     public final int mVerticalGap;
 
+    /** Per keyboard key visual parameters */
+    public final Typeface mKeyTypeface;
+
     public final int mMostCommonKeyHeight;
     public final int mMostCommonKeyWidth;
 
@@ -150,6 +154,8 @@ public class Keyboard {
         mMoreKeysTemplate = params.mMoreKeysTemplate;
         mMaxMoreKeysKeyboardColumn = params.mMaxMoreKeysKeyboardColumn;
 
+        mKeyTypeface = params.mKeyTypeface;
+
         mTopPadding = params.mTopPadding;
         mVerticalGap = params.mVerticalGap;
 
@@ -225,6 +231,7 @@ public class Keyboard {
         return mId.toString();
     }
 
+    // TODO: Move this class to internal package
     public static class Params {
         public KeyboardId mId;
         public int mThemeId;
@@ -244,6 +251,8 @@ public class Keyboard {
         public int mHorizontalEdgesPadding;
         public int mHorizontalCenterPadding;
 
+        public Typeface mKeyTypeface = null;
+
         public int mDefaultRowHeight;
         public int mDefaultKeyWidth;
         public int mHorizontalGap;
@@ -497,6 +506,7 @@ public class Keyboard {
      * </pre>
      */
 
+    // TODO: Move this class to internal package.
     public static class Builder<KP extends Params> {
         private static final String BUILDER_TAG = "Keyboard.Builder";
         private static final boolean DEBUG = false;
@@ -744,6 +754,8 @@ public class Keyboard {
                     R.style.Keyboard);
             final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
                     R.styleable.Keyboard_Key);
+            final TypedArray keyboardViewAttr = mResources.obtainAttributes(
+                    Xml.asAttributeSet(parser), R.styleable.KeyboardView);
             try {
                 final int displayHeight = mDisplayMetrics.heightPixels;
                 final String keyboardHeightString = ResourceUtils.getDeviceOverrideValue(
@@ -795,6 +807,11 @@ public class Keyboard {
                         R.styleable.Keyboard_rowHeight, params.mBaseHeight,
                         params.mBaseHeight / DEFAULT_KEYBOARD_ROWS);
 
+                if (keyboardViewAttr.hasValue(R.styleable.KeyboardView_keyTypeface)) {
+                    params.mKeyTypeface = Typeface.defaultFromStyle(keyboardViewAttr.getInt(
+                            R.styleable.KeyboardView_keyTypeface, Typeface.NORMAL));
+                }
+
                 params.mMoreKeysTemplate = keyboardAttr.getResourceId(
                         R.styleable.Keyboard_moreKeysTemplate, 0);
                 params.mMaxMoreKeysKeyboardColumn = keyAttr.getInt(
@@ -825,6 +842,7 @@ public class Keyboard {
                     params.mTouchPositionCorrection.load(data);
                 }
             } finally {
+                keyboardViewAttr.recycle();
                 keyAttr.recycle();
                 keyboardAttr.recycle();
             }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 127ac7160e5a8a9d50c43d33b65fbf6308d04576..a4797095f37628aad49b8d1d810103890227573c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -65,7 +65,7 @@ import java.util.HashSet;
  * @attr ref R.styleable#KeyboardView_keyHintLetterPadding
  * @attr ref R.styleable#KeyboardView_keyPopupHintLetterPadding
  * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintPadding
- * @attr ref R.styleable#KeyboardView_keyTextStyle
+ * @attr ref R.styleable#KeyboardView_keyTypeface
  * @attr ref R.styleable#KeyboardView_keyPreviewLayout
  * @attr ref R.styleable#KeyboardView_keyPreviewTextRatio
  * @attr ref R.styleable#KeyboardView_keyPreviewOffset
@@ -180,11 +180,11 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         }
     }
 
+    // Move this class to internal package
     protected static class KeyDrawParams {
         // XML attributes
         public final int mKeyTextColor;
         public final int mKeyTextInactivatedColor;
-        public final Typeface mKeyTextStyle;
         public final float mKeyLabelHorizontalPadding;
         public final float mKeyHintLetterPadding;
         public final float mKeyPopupHintLetterPadding;
@@ -197,7 +197,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         public final int mKeyShiftedLetterHintInactivatedColor;
         public final int mKeyShiftedLetterHintActivatedColor;
 
-        /* package */ final float mKeyLetterRatio;
+        private final Typeface mKeyTypefaceFromKeyboardView;
+        private final float mKeyLetterRatio;
         private final float mKeyLargeLetterRatio;
         private final float mKeyLabelRatio;
         private final float mKeyLargeLabelRatio;
@@ -206,6 +207,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         private final float mKeyHintLabelRatio;
 
         public final Rect mPadding = new Rect();
+        public Typeface mKeyTypeface;
         public int mKeyLetterSize;
         public int mKeyLargeLetterSize;
         public int mKeyLabelSize;
@@ -248,15 +250,19 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
                     R.styleable.KeyboardView_keyShiftedLetterHintInactivatedColor, 0);
             mKeyShiftedLetterHintActivatedColor = a.getColor(
                     R.styleable.KeyboardView_keyShiftedLetterHintActivatedColor, 0);
-            mKeyTextStyle = Typeface.defaultFromStyle(
-                    a.getInt(R.styleable.KeyboardView_keyTextStyle, Typeface.NORMAL));
+            mKeyTypefaceFromKeyboardView = Typeface.defaultFromStyle(
+                    a.getInt(R.styleable.KeyboardView_keyTypeface, Typeface.NORMAL));
+            mKeyTypeface = mKeyTypefaceFromKeyboardView;
             mShadowColor = a.getColor(R.styleable.KeyboardView_shadowColor, 0);
             mShadowRadius = a.getFloat(R.styleable.KeyboardView_shadowRadius, 0f);
 
             mKeyBackground.getPadding(mPadding);
         }
 
-        public void updateKeyHeight(int keyHeight) {
+        public void updateParams(final Keyboard keyboard) {
+            mKeyTypeface = (keyboard.mKeyTypeface != null)
+                    ? keyboard.mKeyTypeface : mKeyTypefaceFromKeyboardView;
+            final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
             if (isValidFraction(mKeyLetterRatio)) {
                 mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
             }
@@ -270,13 +276,14 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
             mKeyHintLabelSize = (int)(keyHeight * mKeyHintLabelRatio);
         }
 
-        public void blendAlpha(Paint paint) {
+        public void blendAlpha(final Paint paint) {
             final int color = paint.getColor();
             paint.setARGB((paint.getAlpha() * mAnimAlpha) / Constants.Color.ALPHA_OPAQUE,
                     Color.red(color), Color.green(color), Color.blue(color));
         }
     }
 
+    // TODO: Move this class to internal package.
     /* package */ static class KeyPreviewDrawParams {
         // XML attributes.
         public final Drawable mPreviewBackground;
@@ -285,11 +292,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         public final int mPreviewTextColor;
         public final int mPreviewOffset;
         public final int mPreviewHeight;
-        public final Typeface mKeyTextStyle;
         public final int mLingerTimeout;
 
         private final float mPreviewTextRatio;
-        private final float mKeyLetterRatio;
 
         // The graphical geometry of the key preview.
         // <-width->
@@ -316,13 +321,14 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         // preview background.
         public int mPreviewVisibleOffset;
 
+        public Typeface mKeyTypeface;
         public int mPreviewTextSize;
         public int mKeyLetterSize;
         public final int[] mCoordinates = new int[2];
 
         private static final int PREVIEW_ALPHA = 240;
 
-        public KeyPreviewDrawParams(TypedArray a, KeyDrawParams keyDrawParams) {
+        public KeyPreviewDrawParams(final TypedArray a) {
             mPreviewBackground = a.getDrawable(R.styleable.KeyboardView_keyPreviewBackground);
             mPreviewLeftBackground = a.getDrawable(
                     R.styleable.KeyboardView_keyPreviewLeftBackground);
@@ -338,21 +344,18 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
             mPreviewTextRatio = getFraction(a, R.styleable.KeyboardView_keyPreviewTextRatio);
             mPreviewTextColor = a.getColor(R.styleable.KeyboardView_keyPreviewTextColor, 0);
             mLingerTimeout = a.getInt(R.styleable.KeyboardView_keyPreviewLingerTimeout, 0);
-
-            mKeyLetterRatio = keyDrawParams.mKeyLetterRatio;
-            mKeyTextStyle = keyDrawParams.mKeyTextStyle;
         }
 
-        public void updateKeyHeight(int keyHeight) {
-            if (mPreviewTextRatio >= 0.0f) {
+        public void updateParams(final Keyboard keyboard, final KeyDrawParams keyDrawParams) {
+            final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
+            if (isValidFraction(mPreviewTextRatio)) {
                 mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio);
             }
-            if (mKeyLetterRatio >= 0.0f) {
-                mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
-            }
+            mKeyLetterSize = keyDrawParams.mKeyLetterSize;
+            mKeyTypeface = keyDrawParams.mKeyTypeface;
         }
 
-        private static void setAlpha(Drawable drawable, int alpha) {
+        private static void setAlpha(final Drawable drawable, final int alpha) {
             if (drawable == null) return;
             drawable.setAlpha(alpha);
         }
@@ -368,7 +371,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
         mKeyDrawParams = new KeyDrawParams(a);
-        mKeyPreviewDrawParams = new KeyPreviewDrawParams(a, mKeyDrawParams);
+        mKeyPreviewDrawParams = new KeyPreviewDrawParams(a);
         mDelayAfterPreview = mKeyPreviewDrawParams.mLingerTimeout;
         mKeyPreviewLayoutId = a.getResourceId(R.styleable.KeyboardView_keyPreviewLayout, 0);
         if (mKeyPreviewLayoutId == 0) {
@@ -416,9 +419,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         LatinImeLogger.onSetKeyboard(keyboard);
         requestLayout();
         invalidateAllKeys();
-        final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
-        mKeyDrawParams.updateKeyHeight(keyHeight);
-        mKeyPreviewDrawParams.updateKeyHeight(keyHeight);
+        mKeyDrawParams.updateParams(keyboard);
+        mKeyPreviewDrawParams.updateParams(keyboard, mKeyDrawParams);
     }
 
     /**
@@ -648,7 +650,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         if (key.mLabel != null) {
             final String label = key.mLabel;
             // For characters, use large font. For labels like "Done", use smaller font.
-            paint.setTypeface(key.selectTypeface(params.mKeyTextStyle));
+            paint.setTypeface(key.selectTypeface(params.mKeyTypeface));
             final int labelSize = key.selectTextSize(params.mKeyLetterSize,
                     params.mKeyLargeLetterSize, params.mKeyLabelSize, params.mKeyLargeLabelSize,
                     params.mKeyHintLabelSize);
@@ -812,7 +814,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         final int keyWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
         final int keyHeight = key.mHeight;
 
-        paint.setTypeface(params.mKeyTextStyle);
+        paint.setTypeface(params.mKeyTypeface);
         paint.setTextSize(params.mKeyHintLetterSize);
         paint.setColor(params.mKeyHintLabelColor);
         paint.setTextAlign(Align.CENTER);
@@ -911,7 +913,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
     public Paint newDefaultLabelPaint() {
         final Paint paint = new Paint();
         paint.setAntiAlias(true);
-        paint.setTypeface(mKeyDrawParams.mKeyTextStyle);
+        paint.setTypeface(mKeyDrawParams.mKeyTypeface);
         paint.setTextSize(mKeyDrawParams.mKeyLabelSize);
         return paint;
     }
@@ -1019,7 +1021,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
 
         final KeyPreviewDrawParams params = mKeyPreviewDrawParams;
         final String label = key.isShiftedLetterActivated() ? key.mHintLabel : key.mLabel;
-        // What we show as preview should match what we show on a key top in onBufferDraw().
+        // What we show as preview should match what we show on a key top in onDraw().
         if (label != null) {
             // TODO Should take care of temporaryShiftLabel here.
             previewText.setCompoundDrawables(null, null, null, null);
@@ -1028,7 +1030,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
                 previewText.setTypeface(Typeface.DEFAULT_BOLD);
             } else {
                 previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mPreviewTextSize);
-                previewText.setTypeface(params.mKeyTextStyle);
+                previewText.setTypeface(params.mKeyTypeface);
             }
             previewText.setText(label);
         } else {