diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png
index 50cc49fdb0a201dae42f2613223a50d61f5d73dd..bc130cab67898c804460c6a51d7fa42fdf659033 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
index dabf77ec676fcd6d4c5f31bcf38ad0b0c5f92a72..43099899c8c2313e24cd1a7f2bc0b3b8564bbf2a 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
index 6e7d74c887ee3672d0b6dfbb0a85ba7dfba9bf04..2d1acf22fe2fba3a7873d24306c0050c3dc6fe42 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
index ddb77c224bc1e1d9cbf264fbd4b1c3104e371b31..af5ea6bd28d8431af34bfabacc43c36d3ae5372d 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
index 1e9227e1cbb3830595520b310459721a1093adab..3e25a981771cdc17e54b35f6cff7f5846496c45b 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
index 7207b2ece8b47c0aeb3a07a0c2867d417c01bd8a..fc7ba2aeb05646e1917d8e9e9e9d5a605ab5f37c 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
index a524168c9cf150925552f4b37c776d5808b82ab9..1163290163635942cf7a80e3b39bcd524294e20e 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png
index 4395e978a447ec0d25879575330f5685efe870ae..207c90d6ce9942bae42f46221d1f0c6cde748682 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png
index 9d85c7b742b7fdcb8642cdf3484a0edd241275bd..005c4e49809af765ae60e11a2b9219af29f03c90 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png
index 77e17dbaef701da8f1461bb076ecee7643f461a5..9a07acd914f74b321f905f450461dd5878ad332e 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png
index a409639e7a07101fc0aa45b3f05f71a2921cb65d..be420a7af2d8cda0fd6702561d8f6528fcb3a148 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png
index 6ec7e6592306d9c3f6948fff2ebd154956097f5b..3e25180f085f4546ca6464ce2e9ceb52512dd7e5 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png
index 995780cbfbee7f1038fcda56dc88857441401b05..bad360f77321cfdcaa83f8d048c042293d4aee7f 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png
index 1388b669450154bff5a418cf1a11484849ce74b2..cdd6c8b799ef2555920d6515e2b2b55057ce2ed5 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png
index 7215782eb9a07c6fccc3d70af3ab2c9692f20a5f..49f519860b94a20a0b221bbcd24b6a272a9a7579 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png
index 5a94cb6acb44dcdf7f6078eeece980154bd59783..d8421746a872e837a49afed25e4e1e86b1e09009 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png
index c6373a8afba7af21b6e273175fa4689542f9cf54..44c2ad6372ed827dd510ea6def7b917a85949f0e 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png
index 0bd49a0e7d0aeaf28d4e87c39182dd58ac3ad2ca..e784eddf8985c46388b443a876e47271223010cb 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png
index 634419f1b4ab31a3586acafe788ccfb785ea4080..a4731cf1ac85aa84e821a7b5656fabae84b55f0b 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png
index 8474f9f427bc23acf15376ec50d0373d8f299bb1..03e163c9cd60f56a6272e1cec0cca1d3072e6eea 100644
Binary files a/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png and b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png
index af6082d04edab700e36bd8797aabdea1a6f2e9ef..3e4eff698b2e8ee2edfe92e3b5c31d199f51503e 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png and b/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_delete.png b/java/res/drawable-hdpi/sym_bkeyboard_delete.png
index 999a182f42746727114a0767d668ee25914499b8..1d24cc85c020e8d4be1c390b6debe43595d87ce0 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_delete.png and b/java/res/drawable-hdpi/sym_bkeyboard_delete.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_mic.png
index 5c73600d9ee2393bc9955744c2e7740f59692948..512f46080022eb99c3af40d970362a783264a78b 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_mic.png and b/java/res/drawable-hdpi/sym_bkeyboard_mic.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_return.png b/java/res/drawable-hdpi/sym_bkeyboard_return.png
index 91bb397ff8903db86dd536dd44d0800232527400..426e1599ee26dcb27c8129fbea70f6df334d0746 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_return.png and b/java/res/drawable-hdpi/sym_bkeyboard_return.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_search.png b/java/res/drawable-hdpi/sym_bkeyboard_search.png
index 0ac08145b3daa55aff413ca63151cfe1bbbd204b..1b6f884fa39a191cf08aca04df2bae8d77bb08de 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_search.png and b/java/res/drawable-hdpi/sym_bkeyboard_search.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_settings.png b/java/res/drawable-hdpi/sym_bkeyboard_settings.png
index 5b6217aa0d374d2f8223565606551283690c481d..08ba18f28db90ae647f03e5ee4111cc29a2ebb27 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_settings.png and b/java/res/drawable-hdpi/sym_bkeyboard_settings.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_shift.png b/java/res/drawable-hdpi/sym_bkeyboard_shift.png
index 5ef01b8bdbeda5753aca1d12bb7c668cfa7207ac..5a22dd30970f4bd04822e15ad7721ac16df176d5 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_shift.png and b/java/res/drawable-hdpi/sym_bkeyboard_shift.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png b/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png
index 7d36dcb34c06870f4672a2eda80a18c012040fb3..5664491267bfe10b0660f1b0b0474b99cc174e0d 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png and b/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_space.png b/java/res/drawable-hdpi/sym_bkeyboard_space.png
index 77518cc9361072e0158b7c8ef7dba41267bf4cd2..cd0ebe2f496a2ad911043ffeee11b49c2585cab8 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_space.png and b/java/res/drawable-hdpi/sym_bkeyboard_space.png differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_tab.png b/java/res/drawable-hdpi/sym_bkeyboard_tab.png
index 5db4cef2b0d0220632639ce9ad30a8311f644199..3466e127101007166179df2ea81967b68ccd10ee 100644
Binary files a/java/res/drawable-hdpi/sym_bkeyboard_tab.png and b/java/res/drawable-hdpi/sym_bkeyboard_tab.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png
index 4e337fa0836e56404e74b1c9e250e9088dfc1794..49329f094894ae3cb884850ff36ce95bd394029b 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png
index fe18497d82a1c7d9c1138230ffdd14c24b59ecba..46e9db092dc267820a4998ae1e278d65c04d83a2 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png
index 00aab3d5af5cb97ad0bf3989b2a6f027887a3b40..ee60e48644ed6d2746ef43f75005cedeb864a48b 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png
index ac0bfd3c1e754d21c87d5e6f7e9ba1e93153dbe8..c6876f76ee20bf3a71a361eae57580230221c200 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png
index ea2f357895aa2c321234be50fe45c019bd8eb31e..1f8f318d11312b86a0a02e49ddf83c1e836f2c53 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png
index 6195ac0d4f52af9ae965d5a31e1ad9b88f1e3b84..2bb7b64f40ff6ee1cdca6808472adea094ece529 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png
index 20f3d50878abe67fb74359fecfaa4f9761389e65..4b1a78cfb7af2a1dc17fb4d1e419d3b54be045ed 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
index 1ed3065c5338775041490ef37013da0abbd54d33..697683e299cdb367b0605e7678930ee57838febc 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png
index 50cd06ae3685154ecdf450fe3055e3bc4adf5035..f5ce40cf6df509db08cd86690e6e05c9a1e579b4 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png
index 125ff13350e09b4e109b075f02bcf801bef12e44..ca73b9249a004884627923b86d0696972d063f6f 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png
index 7ce52f0f585605e632f2e9810677c62098b77419..73f2006d4264a3a5f57256989a9ba2b3753e79b1 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png
index 7ba18dd25ac8f79d769a2291c77ab2844e3d21b3..12bc97928b4dc45f26e5f056ab56ef2924790116 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png
index bda9b83941ff20ac6ce4a46912dfd292957be711..44bd414a1afce676289e43ba523dd856a04a4a04 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png
index fad0ec4586104a5cc559efe898d72ce436cd1df7..cdd6c8b799ef2555920d6515e2b2b55057ce2ed5 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png
index 0c16ed5093dfcac53807d9d9663c516e52bb07ca..43fdf5b885a8c851d3cbc24b1382c0fc34b329d0 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png
index 215f8157c3b7306760178bc0e1715afd675fbd76..d8421746a872e837a49afed25e4e1e86b1e09009 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png
index 88acdd7483f4eaf257c1b64331c7ae3046ff53f7..44c2ad6372ed827dd510ea6def7b917a85949f0e 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png
index 39b9314a1a699813ecc408a150b7ac8b7b4217d9..1c1f3d711e109122c0b694160302e1fcf04ef7f9 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png
index bdcf06e1b8986fd3d5fc87d41037c7c037c6584b..dacb675a99c93e2765ee8f15e41f5f9777391c9e 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png
index 79621a9e6300cc77259b6af19649931e47611c4a..3daa69f314a0f6d00fed463207e9497f704b670c 100644
Binary files a/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png and b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png
index eae1e3a5434f8ec54fa8cc98585e9fda99c84d60..d0090a3053c25b2abd1ae612eded0e213c1625d6 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png
index 13bad8f1a5939034b9539c371583c05d110f88bb..2baf7d90c3bdbb79e2b09714d4d273e02579beab 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png
index 853b8bc6e9d29907f2a250285a57e0f50828d1fd..6812f9e8fc92e1476c880e0ae4a0cc615c75657d 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png
index 1edfd64fed2b50209084569ba49f98258abd37fd..a932249a8567c35b57cf1f2a625f2cfc22c0e1fa 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png
index dfdbfadd361ebc26755afb5996cf9bc487e6c63a..16416f00070481bca5ce1db2f0ee830d875b3fa0 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png
index 0e2733e1786e3a38a9123c7e1be532f62c4cbd1a..3ca93fdb3e73dd66de559df6a8ea9432479a1a8d 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png
index 00c4476042a759cf40639bd41d4e1d87e4ee9675..df3b5ba2dbcddb776108bb397b07507b7758ec5a 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png
index ea13a7fdf5edb652975ff47544ae95174dbb7444..aa4f44fdd4661595d0f1bf07e6f3066b22545c61 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png
index 057c5716edf264cd7930e7dcca4a7de258b4f486..4539255c296fcb5cd2172d797229941112a27e7a 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png
index 5d8e46de0a8d4546594923100a99941af30fec7e..5683924447c54c1119eac777154083de39798ec6 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal.9.png
index f53b40419aa6e582df213e63613ea69f8cbd9c61..026005d6f4eb8104a851befaf1973b535b3d41f5 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_normal.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_normal.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off.9.png
index 3c6ae6be861a6bfed7160a948dcfa305f6c33486..38c5f244b4f1b61a33b770a82ab91b7b517384a8 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png
index eebe7d39106b0a973703aeb3df50d00f013a8746..dec219304e5290453bcb8398e85d9fff1cb25f89 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on.9.png
index 655bfb2c6fdcf3fe91490bec687dab3cc94d0b40..f1223e50e4ea7a48ea1df720b3195c43cab624f7 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png
index 336248aaebb9c5f4bca94e9767561d23c0a71fa7..3c77b3ccdab0ba91a0648bea8f0601a774858513 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png
index bb1c72bb3d76449446ac1aef7c07fb719333b52a..099472889ad0b8b4be8754159401b6b0e6ae478d 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed.9.png
index f73911674b0f15f4cdf09cc10667ce6bedf42bf7..ec35db54d60567fe63f48c54a6453c98dbe6d721 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_pressed.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_pressed.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off.9.png
index 34a948f4e68a9a91d138290327d5a6a77af086aa..bd30464d67e2af9e2d980dd5b12c49913aee1785 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off.9.png differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on.9.png
index 520f12d3f4aa1f15ddf843a8c2fbca71130d5083..a3ff5d1bb6fa451cf6d5a32258c74c3f427bcba1 100644
Binary files a/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on.9.png and b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on.9.png differ
diff --git a/java/res/drawable/btn_keyboard_key_fulltrans.xml b/java/res/drawable/btn_keyboard_key_fulltrans.xml
deleted file mode 100644
index bad2a931d19819aecd128c33fdd2841d514c8827..0000000000000000000000000000000000000000
--- a/java/res/drawable/btn_keyboard_key_fulltrans.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <!-- Normal keys -->
-
-    <item android:state_pressed="true"
-          android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
-    <item
-          android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
-          
-</selector>
diff --git a/java/res/drawable/btn_keyboard_key_popup.xml b/java/res/drawable/btn_keyboard_key_popup.xml
index 860cfd5d542c0abb298922847ff562cd3db7bbd8..9e3670d22fd6b578906f27583bec2fc804c86c65 100644
--- a/java/res/drawable/btn_keyboard_key_popup.xml
+++ b/java/res/drawable/btn_keyboard_key_popup.xml
@@ -17,5 +17,5 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true"
           android:drawable="@drawable/btn_keyboard_key_light_popup_selected" />
-    <item android:drawable="@drawable/btn_keyboard_key_light_popup_normal" />
+    <item android:drawable="@drawable/transparent" />
 </selector>
diff --git a/java/res/drawable/btn_keyboard_key_popup_ics.xml b/java/res/drawable/btn_keyboard_key_popup_ics.xml
index 8f797ac3c03956f78b33515ec716461fc7b71d15..b99679ba13265e0167312bb912fa14d4c3b5e8b7 100644
--- a/java/res/drawable/btn_keyboard_key_popup_ics.xml
+++ b/java/res/drawable/btn_keyboard_key_popup_ics.xml
@@ -17,5 +17,5 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true"
           android:drawable="@drawable/btn_keyboard_key_popup_selected_holo" />
-    <item android:drawable="@drawable/btn_keyboard_key_popup_background_holo" />
+    <item android:drawable="@drawable/transparent" />
 </selector>
diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
index d6e096278d15e800744a95e13fa445e462918669..d5ca250632e7128305f7c9be1fbeb663edadd36c 100644
--- a/java/res/values-land/dimens.xml
+++ b/java/res/values-land/dimens.xml
@@ -24,24 +24,33 @@
     <fraction name="minKeyboardHeight">45%p</fraction>
     <!-- key_height + key_bottom_gap = popup_key_height -->
 <!--    <dimen name="key_height">0.260in</dimen>-->
-    <dimen name="key_bottom_gap">0.020in</dimen>
     <dimen name="popup_key_height">0.280in</dimen>
-    <dimen name="keyboard_top_padding">0.00in</dimen>
+    <dimen name="keyboard_horizontal_edges_padding">0.0in</dimen>
+
+    <dimen name="keyboard_top_padding">0.02in</dimen>
     <dimen name="keyboard_bottom_padding">0.00in</dimen>
-    <dimen name="key_bottom_gap_ics">0.04in</dimen>
-    <dimen name="key_horizontal_gap_ics">0.01in</dimen>
+    <dimen name="key_bottom_gap">1.21mm</dimen>
+    <dimen name="key_horizontal_gap">0.35mm</dimen>
+
+    <dimen name="key_bottom_gap_stone">1.40mm</dimen>
+    <dimen name="key_horizontal_gap_stone">1.00mm</dimen>
+
+    <dimen name="key_bottom_gap_gb">1.66mm</dimen>
+    <dimen name="key_horizontal_gap_gb">0.86mm</dimen>
+
     <dimen name="keyboard_top_padding_ics">0.03in</dimen>
     <dimen name="keyboard_bottom_padding_ics">0.00in</dimen>
-    <dimen name="keyboard_horizontal_edges_padding">0.0in</dimen>
+    <dimen name="key_bottom_gap_ics">1.79mm</dimen>
+    <dimen name="key_horizontal_gap_ics">0.88mm</dimen>
 
     <!-- left or right padding of label alignment -->
-    <dimen name="key_label_horizontal_alignment_padding">8dip</dimen>
+    <dimen name="key_label_horizontal_padding">8dip</dimen>
 
-    <fraction name="key_letter_ratio">55%</fraction>
-    <fraction name="key_large_letter_ratio">68%</fraction>
-    <fraction name="key_label_ratio">35%</fraction>
-    <fraction name="key_hint_letter_ratio">28%</fraction>
-    <fraction name="key_hint_label_ratio">45%</fraction>
+    <fraction name="key_letter_ratio">65%</fraction>
+    <fraction name="key_large_letter_ratio">74%</fraction>
+    <fraction name="key_label_ratio">40%</fraction>
+    <fraction name="key_hint_letter_ratio">30%</fraction>
+    <fraction name="key_hint_label_ratio">52%</fraction>
     <fraction name="key_uppercase_letter_ratio">40%</fraction>
     <fraction name="key_preview_text_ratio">90%</fraction>
     <dimen name="key_preview_offset">0.08in</dimen>
diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml
index 5d1fbc74861437a166a24c26a37c11fd42facc1d..5016f4247b99d2f26385a0dd4295bbbe03223478 100644
--- a/java/res/values-sw600dp-land/dimens.xml
+++ b/java/res/values-sw600dp-land/dimens.xml
@@ -22,20 +22,28 @@
     <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
     <dimen name="keyboardHeight">45.0mm</dimen>
     <fraction name="minKeyboardHeight">45%p</fraction>
-    <!-- key_height + key_bottom_gap = popup_key_height -->
-    <!-- <dimen name="key_height">14.5mm</dimen> -->
-    <dimen name="key_bottom_gap">1.3mm</dimen>
-    <dimen name="key_horizontal_gap">1.3mm</dimen>
+
+    <dimen name="keyboard_horizontal_edges_padding">0dp</dimen>
     <dimen name="keyboard_top_padding">1.1mm</dimen>
     <dimen name="keyboard_bottom_padding">0.0mm</dimen>
-    <dimen name="key_bottom_gap_ics">1.3mm</dimen>
-    <dimen name="key_horizontal_gap_ics">1.3mm</dimen>
+    <dimen name="key_bottom_gap">2.21mm</dimen>
+    <dimen name="key_horizontal_gap">1.97mm</dimen>
+
+    <dimen name="key_bottom_gap_stone">1.96mm</dimen>
+    <dimen name="key_horizontal_gap_stone">2.31mm</dimen>
+
+    <dimen name="key_bottom_gap_gb">2.34mm</dimen>
+    <dimen name="key_horizontal_gap_gb">2.22mm</dimen>
+
+    <dimen name="key_bottom_gap_ics">1.66mm</dimen>
+    <dimen name="key_horizontal_gap_ics">1.66mm</dimen>
     <dimen name="keyboard_top_padding_ics">1.1mm</dimen>
     <dimen name="keyboard_bottom_padding_ics">0.0mm</dimen>
+
     <dimen name="popup_key_height">13.0mm</dimen>
 
     <!-- left or right padding of label alignment -->
-    <dimen name="key_label_horizontal_alignment_padding">18dip</dimen>
+    <dimen name="key_label_horizontal_padding">18dip</dimen>
 
     <fraction name="key_letter_ratio">45%</fraction>
     <fraction name="key_large_letter_ratio">45%</fraction>
diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml
index 675f40c2e7abc8bc37af03ba2a83f9853fc617ad..1a82b0c6c70d048b887daaf18036ad4e3c4cca6a 100644
--- a/java/res/values-sw600dp/dimens.xml
+++ b/java/res/values-sw600dp/dimens.xml
@@ -23,18 +23,27 @@
     <dimen name="keyboardHeight">48.0mm</dimen>
     <fraction name="maxKeyboardHeight">50%p</fraction>
     <fraction name="minKeyboardHeight">-35.0%p</fraction>
-    <!-- key_height + key_bottom_gap = popup_key_height -->
-    <!-- <dimen name="key_height">14.5mm</dimen> -->
-    <dimen name="key_bottom_gap">1.0mm</dimen>
-    <dimen name="key_horizontal_gap">1.0mm</dimen>
+
     <dimen name="popup_key_height">10.0mm</dimen>
+
+    <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen>
     <dimen name="keyboard_top_padding">1.1mm</dimen>
     <dimen name="keyboard_bottom_padding">0.0mm</dimen>
-    <dimen name="key_bottom_gap_ics">1.0mm</dimen>
-    <dimen name="key_horizontal_gap_ics">1.0mm</dimen>
+    <dimen name="key_bottom_gap">1.80mm</dimen>
+    <dimen name="key_horizontal_gap">1.67mm</dimen>
+
+    <dimen name="key_bottom_gap_stone">1.80mm</dimen>
+    <dimen name="key_horizontal_gap_stone">1.44mm</dimen>
+
+    <dimen name="key_bottom_gap_gb">2.22mm</dimen>
+    <dimen name="key_horizontal_gap_gb">1.90mm</dimen>
+
+    <dimen name="key_bottom_gap_ics">1.37mm</dimen>
+    <dimen name="key_horizontal_gap_ics">1.53mm</dimen>
     <dimen name="keyboard_top_padding_ics">1.1mm</dimen>
     <dimen name="keyboard_bottom_padding_ics">0.0mm</dimen>
-    <dimen name="mini_keyboard_key_horizontal_padding">12dip</dimen>
+
+    <dimen name="mini_keyboard_key_horizontal_padding">6dip</dimen>
     <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
     <!-- popup_key_height x 1.2 -->
     <dimen name="mini_keyboard_slide_allowance">15.6mm</dimen>
@@ -42,7 +51,9 @@
     <dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen>
 
     <!-- left or right padding of label alignment -->
-    <dimen name="key_label_horizontal_alignment_padding">6dip</dimen>
+    <dimen name="key_label_horizontal_padding">6dip</dimen>
+    <dimen name="key_hint_letter_padding">3dp</dimen>
+    <dimen name="key_uppercase_letter_padding">3dp</dimen>
 
     <fraction name="key_letter_ratio">37%</fraction>
     <fraction name="key_large_letter_ratio">37%</fraction>
diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml
index 2201ce8a364c37070e5dbb29d198a116537c225d..8cbd37e174706a069fa29ef7a7afa899d8dd51b6 100644
--- a/java/res/values-sw768dp-land/dimens.xml
+++ b/java/res/values-sw768dp-land/dimens.xml
@@ -22,27 +22,35 @@
     <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=14.5mm -->
     <dimen name="keyboardHeight">58.0mm</dimen>
     <fraction name="minKeyboardHeight">45%p</fraction>
-    <!-- key_height + key_bottom_gap = popup_key_height -->
-    <!-- <dimen name="key_height">14.5mm</dimen> -->
-    <dimen name="key_bottom_gap">1.6mm</dimen>
-    <dimen name="key_horizontal_gap">1.6mm</dimen>
+
+    <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen>
     <dimen name="keyboard_top_padding">1.1mm</dimen>
     <dimen name="keyboard_bottom_padding">0.0mm</dimen>
-    <dimen name="key_bottom_gap_ics">1.6mm</dimen>
-    <dimen name="key_horizontal_gap_ics">1.6mm</dimen>
+
+    <dimen name="key_bottom_gap">2.65mm</dimen>
+    <dimen name="key_horizontal_gap">2.34mm</dimen>
+
+    <dimen name="key_bottom_gap_stone">1.96mm</dimen>
+    <dimen name="key_horizontal_gap_stone">2.31mm</dimen>
+
+    <dimen name="key_bottom_gap_gb">2.80mm</dimen>
+    <dimen name="key_horizontal_gap_gb">2.60mm</dimen>
+
+    <dimen name="key_bottom_gap_ics">2.25mm</dimen>
+    <dimen name="key_horizontal_gap_ics">2.22mm</dimen>
     <dimen name="keyboard_top_padding_ics">1.1mm</dimen>
     <dimen name="keyboard_bottom_padding_ics">0.0mm</dimen>
+
     <dimen name="popup_key_height">13.0mm</dimen>
-    <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen>
 
     <!-- left or right padding of label alignment -->
-    <dimen name="key_label_horizontal_alignment_padding">18dip</dimen>
+    <dimen name="key_label_horizontal_padding">18dip</dimen>
 
-    <fraction name="key_letter_ratio">38%</fraction>
-    <fraction name="key_large_letter_ratio">38%</fraction>
-    <fraction name="key_label_ratio">26%</fraction>
+    <fraction name="key_letter_ratio">43%</fraction>
+    <fraction name="key_large_letter_ratio">42%</fraction>
+    <fraction name="key_label_ratio">28%</fraction>
     <fraction name="key_hint_letter_ratio">23%</fraction>
-    <fraction name="key_hint_label_ratio">26%</fraction>
+    <fraction name="key_hint_label_ratio">28%</fraction>
     <fraction name="key_uppercase_letter_ratio">24%</fraction>
     <dimen name="key_preview_height">17.0mm</dimen>
 
diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml
index 2e41db52a17161755a8f01d4bd3507e2ca167eaf..81a68e233c2dfeba68dfc694e18200489acae70e 100644
--- a/java/res/values-sw768dp/dimens.xml
+++ b/java/res/values-sw768dp/dimens.xml
@@ -23,19 +23,27 @@
     <dimen name="keyboardHeight">48.0mm</dimen>
     <fraction name="maxKeyboardHeight">50%p</fraction>
     <fraction name="minKeyboardHeight">-35.0%p</fraction>
-    <!-- key_height + key_bottom_gap = popup_key_height -->
-    <!-- <dimen name="key_height">14.5mm</dimen> -->
-    <dimen name="key_bottom_gap">1.1mm</dimen>
-    <dimen name="key_horizontal_gap">1.1mm</dimen>
+
+    <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen>
     <dimen name="keyboard_top_padding">1.1mm</dimen>
     <dimen name="keyboard_bottom_padding">0.0mm</dimen>
-    <dimen name="key_bottom_gap_ics">1.1mm</dimen>
-    <dimen name="key_horizontal_gap_ics">1.1mm</dimen>
+
+    <dimen name="key_bottom_gap">2.05mm</dimen>
+    <dimen name="key_horizontal_gap">2.11mm</dimen>
+
+    <dimen name="key_bottom_gap_stone">1.80mm</dimen>
+    <dimen name="key_horizontal_gap_stone">1.44mm</dimen>
+
+    <dimen name="key_bottom_gap_gb">2.25mm</dimen>
+    <dimen name="key_horizontal_gap_gb">1.96mm</dimen>
+
+    <dimen name="key_bottom_gap_ics">1.75mm</dimen>
+    <dimen name="key_horizontal_gap_ics">1.79mm</dimen>
     <dimen name="keyboard_top_padding_ics">1.1mm</dimen>
     <dimen name="keyboard_bottom_padding_ics">0.0mm</dimen>
+
     <dimen name="popup_key_height">10.0mm</dimen>
-    <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen>
-    <dimen name="mini_keyboard_horizontal_padding_ics">40dip</dimen>
+
     <dimen name="mini_keyboard_key_horizontal_padding">12dip</dimen>
     <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
     <!-- popup_key_height x 1.2 -->
@@ -44,14 +52,16 @@
     <dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen>
 
     <!-- left or right padding of label alignment -->
-    <dimen name="key_label_horizontal_alignment_padding">6dip</dimen>
+    <dimen name="key_label_horizontal_padding">6dip</dimen>
+    <dimen name="key_hint_letter_padding">3dp</dimen>
+    <dimen name="key_uppercase_letter_padding">3dp</dimen>
 
-    <fraction name="key_letter_ratio">38%</fraction>
-    <fraction name="key_large_letter_ratio">38%</fraction>
-    <fraction name="key_label_ratio">26%</fraction>
+    <fraction name="key_letter_ratio">40%</fraction>
+    <fraction name="key_large_letter_ratio">42%</fraction>
+    <fraction name="key_label_ratio">28%</fraction>
     <fraction name="key_hint_letter_ratio">23%</fraction>
-    <fraction name="key_hint_label_ratio">26%</fraction>
-    <fraction name="key_uppercase_letter_ratio">25%</fraction>
+    <fraction name="key_hint_label_ratio">28%</fraction>
+    <fraction name="key_uppercase_letter_ratio">26%</fraction>
     <fraction name="key_preview_text_ratio">50%</fraction>
     <dimen name="key_preview_height">15.0mm</dimen>
     <dimen name="key_preview_offset">0.1in</dimen>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 4470d7b4edc016fdcfa5c85333a36e905a326eda..c5897c853ca3d4df3bf20702fd1f1ed6c0a0aa6a 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -51,6 +51,12 @@
         <attr name="keyHintLabelRatio" format="float" />
         <!-- Size of the text for upper case letter, in the proportion of key height. -->
         <attr name="keyUppercaseLetterRatio" format="float" />
+        <!-- Horizontal padding of left/right aligned key label to the edge of the key. -->
+        <attr name="keyLabelHorizontalPadding" format="dimension" />
+        <!-- Top and right padding of hint letter to the edge of the key.-->
+        <attr name="keyHintLetterPadding" format="dimension" />
+        <!-- Top and right padding of upper case letter to the edge of the key.-->
+        <attr name="keyUppercaseLetterPadding" format="dimension" />
 
         <!-- Color to use for the label in a key. -->
         <attr name="keyTextColor" format="color" />
@@ -199,7 +205,6 @@
             <!-- This should be aligned with Key.LABEL_OPTION_* -->
             <flag name="alignLeft" value="0x01" />
             <flag name="alignRight" value="0x02" />
-            <flag name="alignBottom" value="0x04" />
             <flag name="alignLeftOfCenter" value="0x08" />
             <flag name="largeLetter" value="0x10" />
             <flag name="fontNormal" value="0x20" />
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index c1ef869300404ed20466eb1bd1b7f5fea66b9053..36074b3b8decf7b83fb871814d3acdb0eca7d4f1 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -19,26 +19,33 @@
 -->
 
 <resources>
-    <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=0.295in -->
+    <!-- keyboardHeight = row_height*4 + key_bottom_gap*3 -->
     <dimen name="keyboardHeight">1.285in</dimen>
     <fraction name="maxKeyboardHeight">50%p</fraction>
     <fraction name="minKeyboardHeight">-61.8%p</fraction>
-    <!-- key_height + key_bottom_gap = popup_key_height -->
-    <!-- <dimen name="key_height">0.295in</dimen> -->
-    <dimen name="key_bottom_gap">0.035in</dimen>
-    <dimen name="key_horizontal_gap">0.000in</dimen>
+
     <dimen name="popup_key_height">0.330in</dimen>
-    <dimen name="keyboard_top_padding">0.00in</dimen>
-    <dimen name="keyboard_bottom_padding">0.06in</dimen>
-    <dimen name="keyboard_horizontal_edges_padding">0.0in</dimen>
-    <dimen name="mini_keyboard_horizontal_padding">16dip</dimen>
+
+    <dimen name="mini_keyboard_horizontal_edges_padding">16dip</dimen>
     <dimen name="mini_keyboard_key_horizontal_padding">8dip</dimen>
 
-    <dimen name="key_bottom_gap_ics">0.06in</dimen>
-    <dimen name="key_horizontal_gap_ics">0.01in</dimen>
+    <dimen name="keyboard_horizontal_edges_padding">0dp</dimen>
+    <dimen name="keyboard_top_padding">0.02in</dimen>
+    <dimen name="keyboard_bottom_padding">0.06in</dimen>
+    <dimen name="key_bottom_gap">2.04mm</dimen>
+    <dimen name="key_horizontal_gap">0.70mm</dimen>
+
+    <dimen name="key_bottom_gap_stone">2.45mm</dimen>
+    <dimen name="key_horizontal_gap_stone">0.90mm</dimen>
+
+    <dimen name="key_bottom_gap_gb">2.12mm</dimen>
+    <dimen name="key_horizontal_gap_gb">1.02mm</dimen>
+
     <dimen name="keyboard_top_padding_ics">0.03in</dimen>
     <dimen name="keyboard_bottom_padding_ics">0.06in</dimen>
-    <dimen name="mini_keyboard_horizontal_padding_ics">38dip</dimen>
+    <dimen name="mini_keyboard_horizontal_edges_padding_ics">6dp</dimen>
+    <dimen name="key_bottom_gap_ics">2.37mm</dimen>
+    <dimen name="key_horizontal_gap_ics">0.90mm</dimen>
 
     <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
     <!-- popup_key_height x 1.2 -->
@@ -49,19 +56,20 @@
          to user's finger. -->
     <dimen name="keyboard_vertical_correction">-0.05in</dimen>
 
-    <!-- left or right padding of label alignment -->
-    <dimen name="key_label_horizontal_alignment_padding">4dip</dimen>
-
-    <fraction name="key_letter_ratio">45%</fraction>
-    <fraction name="key_large_letter_ratio">55%</fraction>
-    <fraction name="key_label_ratio">29%</fraction>
-    <fraction name="key_hint_letter_ratio">23%</fraction>
-    <fraction name="key_hint_label_ratio">36%</fraction>
+    <fraction name="key_letter_ratio">55%</fraction>
+    <fraction name="key_large_letter_ratio">65%</fraction>
+    <fraction name="key_label_ratio">34%</fraction>
+    <fraction name="key_hint_letter_ratio">25%</fraction>
+    <fraction name="key_hint_label_ratio">44%</fraction>
     <fraction name="key_uppercase_letter_ratio">35%</fraction>
     <fraction name="key_preview_text_ratio">82%</fraction>
     <dimen name="key_preview_height">80sp</dimen>
     <dimen name="key_preview_offset">0.1in</dimen>
 
+    <dimen name="key_label_horizontal_padding">4dip</dimen>
+    <dimen name="key_hint_letter_padding">2dp</dimen>
+    <dimen name="key_uppercase_letter_padding">2dp</dimen>
+
     <dimen name="key_preview_height_ics">80sp</dimen>
     <dimen name="key_preview_offset_ics">0.05in</dimen>
 
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 08301be5c8fc2d7bbea27c678a0355c41d508ed4..29b9d589cd40984ffcc755f086ca3a7cd1307498 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -49,6 +49,9 @@
         <item name="keyHintLabelColor">#E0E0E4E5</item>
         <item name="keyUppercaseLetterInactivatedColor">#66E0E4E5</item>
         <item name="keyUppercaseLetterActivatedColor">#CCE0E4E5</item>
+        <item name="keyLabelHorizontalPadding">@dimen/key_label_horizontal_padding</item>
+        <item name="keyHintLetterPadding">@dimen/key_hint_letter_padding</item>
+        <item name="keyUppercaseLetterPadding">@dimen/key_uppercase_letter_padding</item>
         <item name="keyPreviewLayout">@layout/key_preview</item>
         <item name="keyPreviewBackground">@drawable/keyboard_key_feedback</item>
         <item name="keyPreviewLeftBackground">@null</item>
@@ -72,8 +75,8 @@
     </style>
     <style name="PopupMiniKeyboardPanelStyle">
         <item name="android:background">@drawable/keyboard_popup_panel_background</item>
-        <item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_padding</item>
-        <item name="android:paddingRight">@dimen/mini_keyboard_horizontal_padding</item>
+        <item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_edges_padding</item>
+        <item name="android:paddingRight">@dimen/mini_keyboard_horizontal_edges_padding</item>
     </style>
     <style name="SuggestionsStripBackgroundStyle">
         <item name="android:background">@drawable/keyboard_suggest_strip</item>
@@ -99,8 +102,8 @@
     </style>
     <!-- Theme "Stone" -->
     <style name="Keyboard.Stone" parent="Keyboard">
-        <item name="horizontalGap">@dimen/key_horizontal_gap</item>
-        <item name="verticalGap">@dimen/key_bottom_gap</item>
+        <item name="horizontalGap">@dimen/key_horizontal_gap_stone</item>
+        <item name="verticalGap">@dimen/key_bottom_gap_stone</item>
     </style>
     <style name="LatinKeyboard.Stone" parent="LatinKeyboard">
         <item name="spacebarTextColor">#FF000000</item>
@@ -126,6 +129,10 @@
         <item name="keyTextStyle">bold</item>
     </style>
     <!-- Theme "Gingerbread" -->
+    <style name="Keyboard.Gingerbread" parent="Keyboard">
+        <item name="horizontalGap">@dimen/key_horizontal_gap_gb</item>
+        <item name="verticalGap">@dimen/key_bottom_gap_gb</item>
+    </style>
     <style name="KeyboardView.Gingerbread" parent="KeyboardView">
         <item name="android:background">@drawable/keyboard_dark_background</item>
         <item name="keyBackground">@drawable/btn_keyboard_key_gingerbread</item>
@@ -168,9 +175,9 @@
         <item name="keyBackground">@drawable/btn_keyboard_key_popup_ics</item>
     </style>
     <style name="PopupMiniKeyboardPanelStyle.IceCreamSandwich">
-        <item name="android:background">@drawable/keyboard_popup_panel_background_holo</item>
-        <item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_padding_ics</item>
-        <item name="android:paddingRight">@dimen/mini_keyboard_horizontal_padding_ics</item>
+        <item name="android:background">@drawable/btn_keyboard_key_popup_background_holo</item>
+        <item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_edges_padding_ics</item>
+        <item name="android:paddingRight">@dimen/mini_keyboard_horizontal_edges_padding_ics</item>
     </style>
     <style name="SuggestionsStripBackgroundStyle.IceCreamSandwich">
         <item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
diff --git a/java/res/values/themes-gingerbread.xml b/java/res/values/themes-gingerbread.xml
index 091baa737d81159df79bf1afef561684786cde58..60f22615352ab7702e59347cc0b8cc6a634303ee 100644
--- a/java/res/values/themes-gingerbread.xml
+++ b/java/res/values/themes-gingerbread.xml
@@ -16,7 +16,7 @@
 
 <resources>
     <style name="KeyboardTheme.Gingerbread" parent="KeyboardIcons">
-        <item name="keyboardStyle">@style/Keyboard</item>
+        <item name="keyboardStyle">@style/Keyboard.Gingerbread</item>
         <item name="latinKeyboardStyle">@style/LatinKeyboard</item>
         <item name="keyboardViewStyle">@style/KeyboardView.Gingerbread</item>
         <item name="popupMiniKeyboardViewStyle">@style/PopupMiniKeyboardView.Gingerbread</item>
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 872fbf823b83f1b05ac9f0f4c4d7b43a7776ab38..9558853664f3e3a099de092b6c622d28a33e15b7 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -52,7 +52,6 @@ public class Key {
     public final int mLabelOption;
     public static final int LABEL_OPTION_ALIGN_LEFT = 0x01;
     public static final int LABEL_OPTION_ALIGN_RIGHT = 0x02;
-    public static final int LABEL_OPTION_ALIGN_BOTTOM = 0x04;
     public static final int LABEL_OPTION_ALIGN_LEFT_OF_CENTER = 0x08;
     private static final int LABEL_OPTION_LARGE_LETTER = 0x10;
     private static final int LABEL_OPTION_FONT_NORMAL = 0x20;
@@ -276,9 +275,9 @@ public class Key {
 
             final KeyboardIconsSet iconsSet = mKeyboard.mIconsSet;
             mVisualInsetsLeft = KeyboardParser.getDimensionOrFraction(keyAttr,
-                    R.styleable.Keyboard_Key_visualInsetsLeft, mKeyboard.getDisplayHeight(), 0);
+                    R.styleable.Keyboard_Key_visualInsetsLeft, keyboardWidth, 0);
             mVisualInsetsRight = KeyboardParser.getDimensionOrFraction(keyAttr,
-                    R.styleable.Keyboard_Key_visualInsetsRight, mKeyboard.getDisplayHeight(), 0);
+                    R.styleable.Keyboard_Key_visualInsetsRight, keyboardWidth, 0);
             mPreviewIcon = iconsSet.getIcon(style.getInt(
                     keyAttr, R.styleable.Keyboard_Key_keyIconPreview,
                     KeyboardIconsSet.ICON_UNDEFINED));
@@ -314,6 +313,10 @@ public class Key {
         }
     }
 
+    public CharSequence getCaseAdjustedLabel() {
+        return mKeyboard.adjustLabelCase(mLabel);
+    }
+
     public Typeface selectTypeface(Typeface defaultTypeface) {
         // TODO: Handle "bold" here too?
         if ((mLabelOption & LABEL_OPTION_FONT_NORMAL) != 0) {
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 20327c5b235970d31c5a1ecccce0b0f55cd5df57..280c0c9d889474ff7a1957132e61b6e3c6e7026f 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
@@ -345,15 +346,23 @@ public class Keyboard {
     }
 
     public boolean isAlphaKeyboard() {
-        return mId != null && mId.isAlphabetKeyboard();
+        return mId.isAlphabetKeyboard();
     }
 
     public boolean isPhoneKeyboard() {
-        return mId != null && mId.isPhoneKeyboard();
+        return mId.isPhoneKeyboard();
     }
 
     public boolean isNumberKeyboard() {
-        return mId != null && mId.isNumberKeyboard();
+        return mId.isNumberKeyboard();
+    }
+
+    public CharSequence adjustLabelCase(CharSequence label) {
+        if (isShiftedOrShiftLocked() && !TextUtils.isEmpty(label) && label.length() < 3
+                && Character.isLowerCase(label.charAt(0))) {
+            return label.toString().toUpperCase(mId.mLocale);
+        }
+        return label;
     }
 
     // TODO: Move this function to ProximityInfo and make this private.
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 9c63c198cc70e0eb2fedcbeb483bc8c29b994b21..b2600dd3b4ed338afec2bb7984681e1d9494ecff 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -42,6 +42,8 @@ public class KeyboardId {
     public static final int F2KEY_MODE_SHORTCUT_IME = 2;
     public static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
 
+    private static final int MINI_KEYBOARD_ID_MARKER = -1;
+
     public final Locale mLocale;
     public final int mOrientation;
     public final int mWidth;
@@ -112,6 +114,11 @@ public class KeyboardId {
         });
     }
 
+    public KeyboardId cloneAsMiniKeyboard() {
+        return new KeyboardId("mini popup keyboard", MINI_KEYBOARD_ID_MARKER, mLocale, mOrientation,
+                mWidth, mMode, mAttribute, false, F2KEY_MODE_NONE, false, false, false, false);
+    }
+
     public KeyboardId cloneWithNewLayout(String xmlName, int xmlId) {
         return new KeyboardId(xmlName, xmlId, mLocale, mOrientation, mWidth, mMode, mAttribute,
                 mHasSettingsKey, mF2KeyMode, mClobberSettingsKey, mVoiceKeyEnabled, mHasVoiceKey,
@@ -130,6 +137,10 @@ public class KeyboardId {
         return mXmlId;
     }
 
+    public boolean isMiniKeyboard() {
+        return mXmlId == MINI_KEYBOARD_ID_MARKER;
+    }
+
     public boolean isAlphabetKeyboard() {
         return mXmlId == R.xml.kbd_qwerty;
     }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 58360275dcf73f22f25e81ae68ecdf2387374621..203cde915c1237736080d654103f394c354bd7b3 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -71,6 +71,9 @@ import java.util.WeakHashMap;
  * @attr ref R.styleable#KeyboardView_keyHintLetterRatio
  * @attr ref R.styleable#KeyboardView_keyUppercaseLetterRatio
  * @attr ref R.styleable#KeyboardView_keyHintLabelRatio
+ * @attr ref R.styleable#KeyboardView_keyLabelHorizontalPadding
+ * @attr ref R.styleable#KeyboardView_keyHintLetterPadding
+ * @attr ref R.styleable#KeyboardView_keyUppercaseLetterPadding
  * @attr ref R.styleable#KeyboardView_keyTextStyle
  * @attr ref R.styleable#KeyboardView_keyPreviewLayout
  * @attr ref R.styleable#KeyboardView_keyPreviewTextRatio
@@ -89,7 +92,6 @@ import java.util.WeakHashMap;
  */
 public class KeyboardView extends View implements PointerTracker.UIProxy {
     private static final String TAG = KeyboardView.class.getSimpleName();
-    private static final boolean DEBUG_SHOW_ALIGN = LatinImeLogger.sVISUALDEBUG;
     private static final boolean DEBUG_KEYBOARD_GRID = false;
 
     private static final boolean ENABLE_CAPSLOCK_BY_LONGPRESS = true;
@@ -102,55 +104,25 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
     private static final int[] LONG_PRESSABLE_STATE_SET = { android.R.attr.state_long_pressable };
 
     // XML attribute
-    private final int mKeyTextColor;
-    private final int mKeyTextInactivatedColor;
-    private final Typeface mKeyTextStyle;
-    private final float mKeyLetterRatio;
-    private final float mKeyLargeLetterRatio;
-    private final float mKeyLabelRatio;
-    private final float mKeyHintLetterRatio;
-    private final float mKeyUppercaseLetterRatio;
-    private final float mKeyHintLabelRatio;
-    private final int mShadowColor;
-    private final float mShadowRadius;
-    private final Drawable mKeyBackground;
     private final float mBackgroundDimAmount;
     private final float mKeyHysteresisDistance;
     private final float mVerticalCorrection;
-    private final Drawable mPreviewBackground;
-    private final Drawable mPreviewLeftBackground;
-    private final Drawable mPreviewRightBackground;
-    private final Drawable mPreviewSpacebarBackground;
-    private final int mPreviewTextColor;
-    private final float mPreviewTextRatio;
-    private final int mPreviewOffset;
-    private final int mPreviewHeight;
     private final int mPopupLayout;
-    private final int mKeyHintLetterColor;
-    private final int mKeyHintLabelColor;
-    private final int mKeyUppercaseLetterInactivatedColor;
-    private final int mKeyUppercaseLetterActivatedColor;
 
     // HORIZONTAL ELLIPSIS "...", character for popup hint.
     private static final String POPUP_HINT_CHAR = "\u2026";
 
     // Main keyboard
     private Keyboard mKeyboard;
-    private int mKeyLetterSize;
-    private int mKeyLargeLetterSize;
-    private int mKeyLabelSize;
-    private int mKeyHintLetterSize;
-    private int mKeyUppercaseLetterSize;
-    private int mKeyHintLabelSize;
+    private final KeyDrawParams mKeyDrawParams;
 
     // Key preview
+    private final KeyPreviewDrawParams mKeyPreviewDrawParams;
     private final TextView mPreviewText;
-    private int mPreviewTextSize;
     private boolean mShowKeyPreviewPopup = true;
     private final int mDelayBeforePreview;
     private int mDelayAfterPreview;
     private ViewGroup mPreviewPlacer;
-    private final int[] mCoordinates = new int[2];
 
     // Mini keyboard
     private PopupWindow mPopupWindow;
@@ -194,16 +166,13 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
     /** The canvas for the above mutable keyboard bitmap */
     private Canvas mCanvas;
     private final Paint mPaint = new Paint();
-    private final Rect mPadding = new Rect();
     // This map caches key label text height in pixel as value and key label text size as map key.
-    private final HashMap<Integer, Integer> mTextHeightCache = new HashMap<Integer, Integer>();
+    private static final HashMap<Integer, Float> sTextHeightCache =
+            new HashMap<Integer, Float>();
     // This map caches key label text width in pixel as value and key label text size as map key.
-    private final HashMap<Integer, Integer> mTextWidthCache = new HashMap<Integer, Integer>();
-    // Distance from horizontal center of the key, proportional to key label text height and width.
-    private static final float KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER = 0.45f;
-    private static final float KEY_LABEL_VERTICAL_PADDING_FACTOR = 1.60f;
+    private static final HashMap<Integer, Float> sTextWidthCache =
+            new HashMap<Integer, Float>();
     private static final String KEY_LABEL_REFERENCE_CHAR = "M";
-    private final int mKeyLabelHorizontalPadding;
 
     private static final int MEASURESPEC_UNSPECIFIED = MeasureSpec.makeMeasureSpec(
             0, MeasureSpec.UNSPECIFIED);
@@ -334,6 +303,122 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         }
     }
 
+    private 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 mKeyUppercaseLetterPadding;
+        public final int mShadowColor;
+        public final float mShadowRadius;
+        public final Drawable mKeyBackground;
+        public final int mKeyHintLetterColor;
+        public final int mKeyHintLabelColor;
+        public final int mKeyUppercaseLetterInactivatedColor;
+        public final int mKeyUppercaseLetterActivatedColor;
+
+        private final float mKeyLetterRatio;
+        private final float mKeyLargeLetterRatio;
+        private final float mKeyLabelRatio;
+        private final float mKeyHintLetterRatio;
+        private final float mKeyUppercaseLetterRatio;
+        private final float mKeyHintLabelRatio;
+
+        public final Rect mPadding = new Rect();
+        public int mKeyLetterSize;
+        public int mKeyLargeLetterSize;
+        public int mKeyLabelSize;
+        public int mKeyHintLetterSize;
+        public int mKeyUppercaseLetterSize;
+        public int mKeyHintLabelSize;
+
+        public KeyDrawParams(TypedArray a) {
+            mKeyBackground = a.getDrawable(R.styleable.KeyboardView_keyBackground);
+            mKeyLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLetterRatio);
+            mKeyLargeLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLargeLetterRatio);
+            mKeyLabelRatio = getRatio(a, R.styleable.KeyboardView_keyLabelRatio);
+            mKeyHintLetterRatio = getRatio(a, R.styleable.KeyboardView_keyHintLetterRatio);
+            mKeyUppercaseLetterRatio = getRatio(a,
+                    R.styleable.KeyboardView_keyUppercaseLetterRatio);
+            mKeyHintLabelRatio = getRatio(a, R.styleable.KeyboardView_keyHintLabelRatio);
+            mKeyLabelHorizontalPadding = a.getDimension(
+                    R.styleable.KeyboardView_keyLabelHorizontalPadding, 0);
+            mKeyHintLetterPadding = a.getDimension(
+                    R.styleable.KeyboardView_keyHintLetterPadding, 0);
+            mKeyUppercaseLetterPadding = a.getDimension(
+                    R.styleable.KeyboardView_keyUppercaseLetterPadding, 0);
+            mKeyTextColor = a.getColor(R.styleable.KeyboardView_keyTextColor, 0xFF000000);
+            mKeyTextInactivatedColor = a.getColor(
+                    R.styleable.KeyboardView_keyTextInactivatedColor, 0xFF000000);
+            mKeyHintLetterColor = a.getColor(R.styleable.KeyboardView_keyHintLetterColor, 0);
+            mKeyHintLabelColor = a.getColor(R.styleable.KeyboardView_keyHintLabelColor, 0);
+            mKeyUppercaseLetterInactivatedColor = a.getColor(
+                    R.styleable.KeyboardView_keyUppercaseLetterInactivatedColor, 0);
+            mKeyUppercaseLetterActivatedColor = a.getColor(
+                    R.styleable.KeyboardView_keyUppercaseLetterActivatedColor, 0);
+            mKeyTextStyle = Typeface.defaultFromStyle(
+                    a.getInt(R.styleable.KeyboardView_keyTextStyle, Typeface.NORMAL));
+            mShadowColor = a.getColor(R.styleable.KeyboardView_shadowColor, 0);
+            mShadowRadius = a.getFloat(R.styleable.KeyboardView_shadowRadius, 0f);
+
+            mKeyBackground.getPadding(mPadding);
+        }
+
+        public void updateKeyHeight(int keyHeight) {
+            mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
+            mKeyLargeLetterSize = (int)(keyHeight * mKeyLargeLetterRatio);
+            mKeyLabelSize = (int)(keyHeight * mKeyLabelRatio);
+            mKeyHintLetterSize = (int)(keyHeight * mKeyHintLetterRatio);
+            mKeyUppercaseLetterSize = (int)(keyHeight * mKeyUppercaseLetterRatio);
+            mKeyHintLabelSize = (int)(keyHeight * mKeyHintLabelRatio);
+        }
+    }
+
+    private static class KeyPreviewDrawParams {
+        // XML attributes.
+        public final Drawable mPreviewBackground;
+        public final Drawable mPreviewLeftBackground;
+        public final Drawable mPreviewRightBackground;
+        public final Drawable mPreviewSpacebarBackground;
+        public final int mPreviewTextColor;
+        public final int mPreviewOffset;
+        public final int mPreviewHeight;
+        public final Typeface mKeyTextStyle;
+
+        private final float mPreviewTextRatio;
+        private final float mKeyLetterRatio;
+
+        public int mPreviewTextSize;
+        public int mKeyLetterSize;
+        public final int[] mCoordinates = new int[2];
+
+        public KeyPreviewDrawParams(TypedArray a, KeyDrawParams keyDrawParams) {
+            mPreviewBackground = a.getDrawable(R.styleable.KeyboardView_keyPreviewBackground);
+            mPreviewLeftBackground = a.getDrawable(
+                    R.styleable.KeyboardView_keyPreviewLeftBackground);
+            mPreviewRightBackground = a.getDrawable(
+                    R.styleable.KeyboardView_keyPreviewRightBackground);
+            mPreviewSpacebarBackground = a.getDrawable(
+                    R.styleable.KeyboardView_keyPreviewSpacebarBackground);
+            mPreviewOffset = a.getDimensionPixelOffset(
+                    R.styleable.KeyboardView_keyPreviewOffset, 0);
+            mPreviewHeight = a.getDimensionPixelSize(
+                    R.styleable.KeyboardView_keyPreviewHeight, 80);
+            mPreviewTextRatio = getRatio(a, R.styleable.KeyboardView_keyPreviewTextRatio);
+            mPreviewTextColor = a.getColor(R.styleable.KeyboardView_keyPreviewTextColor, 0);
+
+            mKeyLetterRatio = keyDrawParams.mKeyLetterRatio;
+            mKeyTextStyle = keyDrawParams.mKeyTextStyle;
+        }
+
+        public void updateKeyHeight(int keyHeight) {
+            mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio);
+            mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
+        }
+    }
+
     public KeyboardView(Context context, AttributeSet attrs) {
         this(context, attrs, R.attr.keyboardViewStyle);
     }
@@ -344,49 +429,20 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
 
-        mKeyBackground = a.getDrawable(R.styleable.KeyboardView_keyBackground);
+        mKeyDrawParams = new KeyDrawParams(a);
+        mKeyPreviewDrawParams = new KeyPreviewDrawParams(a, mKeyDrawParams);
         mKeyHysteresisDistance = a.getDimensionPixelOffset(
                 R.styleable.KeyboardView_keyHysteresisDistance, 0);
         mVerticalCorrection = a.getDimensionPixelOffset(
                 R.styleable.KeyboardView_verticalCorrection, 0);
-        mPreviewTextColor = a.getColor(R.styleable.KeyboardView_keyPreviewTextColor, 0);
         final int previewLayout = a.getResourceId(R.styleable.KeyboardView_keyPreviewLayout, 0);
         if (previewLayout != 0) {
             mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null);
-            mPreviewText.setTextColor(mPreviewTextColor);
         } else {
             mPreviewText = null;
             mShowKeyPreviewPopup = false;
         }
-        mPreviewBackground = a.getDrawable(R.styleable.KeyboardView_keyPreviewBackground);
-        mPreviewLeftBackground = a.getDrawable(R.styleable.KeyboardView_keyPreviewLeftBackground);
-        mPreviewRightBackground = a.getDrawable(R.styleable.KeyboardView_keyPreviewRightBackground);
-        mPreviewSpacebarBackground = a.getDrawable(
-                R.styleable.KeyboardView_keyPreviewSpacebarBackground);
-        mPreviewOffset = a.getDimensionPixelOffset(R.styleable.KeyboardView_keyPreviewOffset, 0);
-        mPreviewHeight = a.getDimensionPixelSize(R.styleable.KeyboardView_keyPreviewHeight, 80);
-        mKeyLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLetterRatio);
-        mKeyLargeLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLargeLetterRatio);
-        mKeyLabelRatio = getRatio(a, R.styleable.KeyboardView_keyLabelRatio);
-        mKeyHintLetterRatio = getRatio(a, R.styleable.KeyboardView_keyHintLetterRatio);
-        mKeyUppercaseLetterRatio = getRatio(a,
-                R.styleable.KeyboardView_keyUppercaseLetterRatio);
-        mKeyHintLabelRatio = getRatio(a, R.styleable.KeyboardView_keyHintLabelRatio);
-        mPreviewTextRatio = getRatio(a, R.styleable.KeyboardView_keyPreviewTextRatio);
-        mKeyTextColor = a.getColor(R.styleable.KeyboardView_keyTextColor, 0xFF000000);
-        mKeyTextInactivatedColor = a.getColor(
-                R.styleable.KeyboardView_keyTextInactivatedColor, 0xFF000000);
-        mKeyHintLetterColor = a.getColor(R.styleable.KeyboardView_keyHintLetterColor, 0);
-        mKeyHintLabelColor = a.getColor(R.styleable.KeyboardView_keyHintLabelColor, 0);
-        mKeyUppercaseLetterInactivatedColor = a.getColor(
-                R.styleable.KeyboardView_keyUppercaseLetterInactivatedColor, 0);
-        mKeyUppercaseLetterActivatedColor = a.getColor(
-                R.styleable.KeyboardView_keyUppercaseLetterActivatedColor, 0);
-        mKeyTextStyle = Typeface.defaultFromStyle(
-                a.getInt(R.styleable.KeyboardView_keyTextStyle, Typeface.NORMAL));
         mPopupLayout = a.getResourceId(R.styleable.KeyboardView_popupLayout, 0);
-        mShadowColor = a.getColor(R.styleable.KeyboardView_shadowColor, 0);
-        mShadowRadius = a.getFloat(R.styleable.KeyboardView_shadowRadius, 0f);
         // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount)
         mBackgroundDimAmount = a.getFloat(R.styleable.KeyboardView_backgroundDimAmount, 0.5f);
         a.recycle();
@@ -395,15 +451,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
 
         mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview);
         mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview);
-        mKeyLabelHorizontalPadding = (int)res.getDimension(
-                R.dimen.key_label_horizontal_alignment_padding);
 
         mPaint.setAntiAlias(true);
         mPaint.setTextAlign(Align.CENTER);
         mPaint.setAlpha(255);
 
-        mKeyBackground.getPadding(mPadding);
-
         mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density);
         // TODO: Refer to frameworks/base/core/res/res/values/config.xml
         mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation);
@@ -539,14 +591,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         mKeyDetector.setProximityThreshold(keyboard.getMostCommonKeyWidth());
         mPopupPanelCache.clear();
         final int keyHeight = keyboard.getRowHeight() - keyboard.getVerticalGap();
-        mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
-        mKeyLargeLetterSize = (int)(keyHeight * mKeyLargeLetterRatio);
-        mKeyLabelSize = (int)(keyHeight * mKeyLabelRatio);
-        mKeyHintLetterSize = (int)(keyHeight * mKeyHintLetterRatio);
-        mKeyUppercaseLetterSize = (int)(
-                keyHeight * mKeyUppercaseLetterRatio);
-        mKeyHintLabelSize = (int)(keyHeight * mKeyHintLabelRatio);
-        mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio);
+        mKeyDrawParams.updateKeyHeight(keyHeight);
+        mKeyPreviewDrawParams.updateKeyHeight(keyHeight);
     }
 
     /**
@@ -605,14 +651,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         return mKeyDetector.isProximityCorrectionEnabled();
     }
 
-    protected CharSequence adjustCase(CharSequence label) {
-        if (mKeyboard.isShiftedOrShiftLocked() && label != null && label.length() < 3
-                && Character.isLowerCase(label.charAt(0))) {
-            return label.toString().toUpperCase(mKeyboard.mId.mLocale);
-        }
-        return label;
-    }
-
     @Override
     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         // Round up a little
@@ -663,13 +701,24 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
 
         if (mKeyboard == null) return;
 
+        final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
+        final KeyDrawParams params = mKeyDrawParams;
         if (mInvalidatedKey != null && mInvalidatedKeyRect.contains(mDirtyRect)) {
             // Draw a single key.
-            onBufferDrawKey(canvas, mInvalidatedKey);
+            final int keyDrawX = mInvalidatedKey.mX + mInvalidatedKey.mVisualInsetsLeft
+                    + getPaddingLeft();
+            final int keyDrawY = mInvalidatedKey.mY + getPaddingTop();
+            canvas.translate(keyDrawX, keyDrawY);
+            onBufferDrawKey(mInvalidatedKey, canvas, mPaint, params, isManualTemporaryUpperCase);
+            canvas.translate(-keyDrawX, -keyDrawY);
         } else {
             // Draw all keys.
             for (final Key key : mKeyboard.getKeys()) {
-                onBufferDrawKey(canvas, key);
+                final int keyDrawX = key.mX + key.mVisualInsetsLeft + getPaddingLeft();
+                final int keyDrawY = key.mY + getPaddingTop();
+                canvas.translate(keyDrawX, keyDrawY);
+                onBufferDrawKey(key, canvas, mPaint, params, isManualTemporaryUpperCase);
+                canvas.translate(-keyDrawX, -keyDrawY);
             }
         }
 
@@ -702,58 +751,61 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         mDirtyRect.setEmpty();
     }
 
-    private void onBufferDrawKey(final Canvas canvas, final Key key) {
-        final Paint paint = mPaint;
-        final Drawable keyBackground = mKeyBackground;
-        final Rect padding = mPadding;
-        final int kbdPaddingLeft = getPaddingLeft();
-        final int kbdPaddingTop = getPaddingTop();
-        final int keyDrawX = key.mX + key.mVisualInsetsLeft;
-        final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
-        final int centerX = (keyDrawWidth + padding.left - padding.right) / 2;
-        final float centerY = (key.mHeight + padding.top - padding.bottom) / 2;
-        final int rowHeight = padding.top + key.mHeight;
-        final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
-
-        canvas.translate(keyDrawX + kbdPaddingLeft, key.mY + kbdPaddingTop);
-
+    private static void onBufferDrawKey(final Key key, final Canvas canvas, Paint paint,
+            KeyDrawParams params, boolean isManualTemporaryUpperCase) {
+        final boolean debugShowAlign = LatinImeLogger.sVISUALDEBUG;
         // Draw key background.
+        final int bgWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight
+                + params.mPadding.left + params.mPadding.right;
+        final int bgHeight = key.mHeight + params.mPadding.top + params.mPadding.bottom;
+        final int bgX = -params.mPadding.left;
+        final int bgY = -params.mPadding.top;
         final int[] drawableState = key.getCurrentDrawableState();
-        keyBackground.setState(drawableState);
-        final Rect bounds = keyBackground.getBounds();
-        if (keyDrawWidth != bounds.right || key.mHeight != bounds.bottom) {
-            keyBackground.setBounds(0, 0, keyDrawWidth, key.mHeight);
+        final Drawable background = params.mKeyBackground;
+        background.setState(drawableState);
+        final Rect bounds = background.getBounds();
+        if (bgWidth != bounds.right || bgHeight != bounds.bottom) {
+            background.setBounds(0, 0, bgWidth, bgHeight);
+        }
+        canvas.translate(bgX, bgY);
+        background.draw(canvas);
+        if (debugShowAlign) {
+            drawRectangle(canvas, 0, 0, bgWidth, bgHeight, 0x80c00000, new Paint());
+        }
+        canvas.translate(-bgX, -bgY);
+
+        // Draw key top visuals.
+        final int keyWidth = key.mWidth;
+        final int keyHeight = key.mHeight;
+        final float centerX = keyWidth * 0.5f;
+        final float centerY = keyHeight * 0.5f;
+
+        if (debugShowAlign) {
+            drawRectangle(canvas, 0, 0, keyWidth, keyHeight, 0x800000c0, new Paint());
         }
-        keyBackground.draw(canvas);
 
         // Draw key label.
-        int positionX = centerX;
+        float positionX = centerX;
         if (key.mLabel != null) {
             // Switch the character to uppercase if shift is pressed
-            final CharSequence label = key.mLabel == null ? null : adjustCase(key.mLabel);
+            final CharSequence label = key.getCaseAdjustedLabel();
             // For characters, use large font. For labels like "Done", use smaller font.
-            paint.setTypeface(key.selectTypeface(mKeyTextStyle));
-            final int labelSize = key.selectTextSize(mKeyLetterSize, mKeyLargeLetterSize,
-                    mKeyLabelSize, mKeyHintLabelSize);
+            paint.setTypeface(key.selectTypeface(params.mKeyTextStyle));
+            final int labelSize = key.selectTextSize(params.mKeyLetterSize,
+                    params.mKeyLargeLetterSize, params.mKeyLabelSize, params.mKeyHintLabelSize);
             paint.setTextSize(labelSize);
-            final int labelCharHeight = getLabelCharHeight(paint);
-            final int labelCharWidth = getLabelCharWidth(paint);
+            final float labelCharHeight = getCharHeight(paint);
+            final float labelCharWidth = getCharWidth(paint);
 
             // Vertical label text alignment.
-            final float baseline;
-            // TODO: Generalize the following calculations.
-            if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_BOTTOM) != 0) {
-                baseline = key.mHeight - labelCharHeight * KEY_LABEL_VERTICAL_PADDING_FACTOR;
-            } else { // Align center
-                baseline = centerY + labelCharHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER;
-            }
+            final float baseline = centerY + labelCharHeight / 2;
 
             // Horizontal label text alignment
             if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT) != 0) {
-                positionX = padding.left + mKeyLabelHorizontalPadding;
+                positionX = (int)params.mKeyLabelHorizontalPadding;
                 paint.setTextAlign(Align.LEFT);
             } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_RIGHT) != 0) {
-                positionX = keyDrawWidth - mKeyLabelHorizontalPadding - padding.right;
+                positionX = keyWidth - (int)params.mKeyLabelHorizontalPadding;
                 paint.setTextAlign(Align.RIGHT);
             } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT_OF_CENTER) != 0) {
                 // TODO: Parameterise this?
@@ -763,20 +815,15 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
                 positionX = centerX;
                 paint.setTextAlign(Align.CENTER);
             }
-            if (DEBUG_SHOW_ALIGN) {
-                final Paint line = new Paint();
-                drawHorizontalLine(canvas, (int)baseline, keyDrawWidth, 0xc0008000, line);
-                drawVerticalLine(canvas, positionX, rowHeight, 0xc0800080, line);
-            }
 
             if (key.hasUppercaseLetter() && isManualTemporaryUpperCase) {
-                paint.setColor(mKeyTextInactivatedColor);
+                paint.setColor(params.mKeyTextInactivatedColor);
             } else {
-                paint.setColor(mKeyTextColor);
+                paint.setColor(params.mKeyTextColor);
             }
             if (key.isEnabled()) {
                 // Set a drop shadow for the text
-                paint.setShadowLayer(mShadowRadius, 0, 0, mShadowColor);
+                paint.setShadowLayer(params.mShadowRadius, 0, 0, params.mShadowColor);
             } else {
                 // Make label invisible
                 paint.setColor(Color.TRANSPARENT);
@@ -785,6 +832,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             // Turn off drop shadow
             paint.setShadowLayer(0, 0, 0, 0);
 
+            if (debugShowAlign) {
+                final Paint line = new Paint();
+                drawHorizontalLine(canvas, baseline, keyWidth, 0xc0008000, line);
+                drawVerticalLine(canvas, positionX, keyHeight, 0xc0800080, line);
+            }
         }
 
         // Draw hint label.
@@ -792,31 +844,44 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             final CharSequence hint = key.mHintLabel;
             final int hintColor;
             final int hintSize;
-            if (key.hasUppercaseLetter()) {
-                hintColor = isManualTemporaryUpperCase ? mKeyUppercaseLetterActivatedColor
-                        : mKeyUppercaseLetterInactivatedColor;
-                hintSize = mKeyUppercaseLetterSize;
-            } else if (key.hasHintLabel()) {
-                hintColor = mKeyHintLabelColor;
-                hintSize = mKeyHintLabelSize;
+            if (key.hasHintLabel()) {
+                hintColor = params.mKeyHintLabelColor;
+                hintSize = params.mKeyHintLabelSize;
                 paint.setTypeface(Typeface.DEFAULT);
-            } else {
-                hintColor = mKeyHintLetterColor;
-                hintSize = mKeyHintLetterSize;
+            } else if (key.hasUppercaseLetter()) {
+                hintColor = isManualTemporaryUpperCase
+                        ? params.mKeyUppercaseLetterActivatedColor
+                        : params.mKeyUppercaseLetterInactivatedColor;
+                hintSize = params.mKeyUppercaseLetterSize;
+            } else { // key.hasHintLetter()
+                hintColor = params.mKeyHintLetterColor;
+                hintSize = params.mKeyHintLetterSize;
             }
             paint.setColor(hintColor);
             paint.setTextSize(hintSize);
-            // Note: padding.right for drawX?
+            final float hintCharWidth = getCharWidth(paint);
             final float hintX, hintY;
             if (key.hasHintLabel()) {
                 // TODO: Generalize the following calculations.
-                hintX = positionX + getLabelCharWidth(paint) * 2;
-                hintY = centerY + getLabelCharHeight(paint) / 2;
-            } else {
-                hintX = keyDrawWidth - getLabelCharWidth(paint);
-                hintY = -paint.ascent() + padding.top;
+                hintX = positionX + hintCharWidth * 2;
+                hintY = centerY + getCharHeight(paint) / 2;
+                paint.setTextAlign(Align.LEFT);
+            } else if (key.hasUppercaseLetter()) {
+                hintX = keyWidth - params.mKeyUppercaseLetterPadding - hintCharWidth / 2;
+                hintY = -paint.ascent() + params.mKeyUppercaseLetterPadding;
+                paint.setTextAlign(Align.CENTER);
+            } else { // key.hasHintLetter()
+                hintX = keyWidth - params.mKeyHintLetterPadding - hintCharWidth / 2;
+                hintY = -paint.ascent() + params.mKeyHintLetterPadding;
+                paint.setTextAlign(Align.CENTER);
             }
             canvas.drawText(hint, 0, hint.length(), hintX, hintY, paint);
+
+            if (debugShowAlign) {
+                final Paint line = new Paint();
+                drawHorizontalLine(canvas, (int)hintY, keyWidth, 0xc0808000, line);
+                drawVerticalLine(canvas, (int)hintX, keyHeight, 0xc0808000, line);
+            }
         }
 
         // Draw key icon.
@@ -825,63 +890,67 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             final int iconWidth = icon.getIntrinsicWidth();
             final int iconHeight = icon.getIntrinsicHeight();
             final int iconX, alignX;
-            final int iconY = (key.mHeight + padding.top - padding.bottom - iconHeight) / 2;
+            final int iconY = (keyHeight - iconHeight) / 2;
             if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT) != 0) {
-                iconX = padding.left + mKeyLabelHorizontalPadding;
+                iconX = (int)params.mKeyLabelHorizontalPadding;
                 alignX = iconX;
             } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_RIGHT) != 0) {
-                iconX = keyDrawWidth - padding.right - mKeyLabelHorizontalPadding - iconWidth;
+                iconX = keyWidth - (int)params.mKeyLabelHorizontalPadding - iconWidth;
                 alignX = iconX + iconWidth;
             } else { // Align center
-                iconX = (keyDrawWidth + padding.left - padding.right - iconWidth) / 2;
+                iconX = (keyWidth - iconWidth) / 2;
                 alignX = iconX + iconWidth / 2;
             }
             drawIcon(canvas, icon, iconX, iconY, iconWidth, iconHeight);
-            if (DEBUG_SHOW_ALIGN) {
+
+            if (debugShowAlign) {
                 final Paint line = new Paint();
-                drawVerticalLine(canvas, alignX, rowHeight, 0xc0800080, line);
+                drawVerticalLine(canvas, alignX, keyHeight, 0xc0800080, line);
                 drawRectangle(canvas, iconX, iconY, iconWidth, iconHeight, 0x80c00000, line);
             }
         }
 
         // Draw popup hint "..." at the bottom right corner of the key.
         if (key.hasPopupHint()) {
-            paint.setTextSize(mKeyHintLetterSize);
-            paint.setColor(mKeyHintLabelColor);
-            final int hintX = keyDrawWidth - getLabelCharWidth(paint);
-            // Using y-coordinate "key.mHeight - paint.descent()" draws "..." just on the bottom
-            // edge of the key. So we use slightly higher position by multiply descent length by 2.
-            final int hintY = key.mHeight - (int)paint.descent() * 2;
+            paint.setTextSize(params.mKeyHintLetterSize);
+            paint.setColor(params.mKeyHintLabelColor);
+            paint.setTextAlign(Align.CENTER);
+            final float hintX = keyWidth - params.mKeyHintLetterPadding - getCharWidth(paint) / 2;
+            final float hintY = keyHeight - params.mKeyHintLetterPadding;
             canvas.drawText(POPUP_HINT_CHAR, hintX, hintY, paint);
-        }
 
-        canvas.translate(-keyDrawX - kbdPaddingLeft, -key.mY - kbdPaddingTop);
+            if (debugShowAlign) {
+                final Paint line = new Paint();
+                drawHorizontalLine(canvas, (int)hintY, keyWidth, 0xc0808000, line);
+                drawVerticalLine(canvas, (int)hintX, keyHeight, 0xc0808000, line);
+            }
+        }
     }
 
     // This method is currently being used only by MiniKeyboardBuilder
     public int getDefaultLabelSizeAndSetPaint(Paint paint) {
         // For characters, use large font. For labels like "Done", use small font.
-        final int labelSize = mKeyLabelSize;
+        final int labelSize = mKeyDrawParams.mKeyLabelSize;
         paint.setTextSize(labelSize);
-        paint.setTypeface(mKeyTextStyle);
+        paint.setTypeface(mKeyDrawParams.mKeyTextStyle);
         return labelSize;
     }
 
-    private final Rect mTextBounds = new Rect();
+    private static final Rect sTextBounds = new Rect();
 
-    private int getLabelCharHeight(Paint paint) {
+    private static float getCharHeight(Paint paint) {
         final int labelSize = (int)paint.getTextSize();
-        final Integer cachedValue = mTextHeightCache.get(labelSize);
+        final Float cachedValue = sTextHeightCache.get(labelSize);
         if (cachedValue != null)
             return cachedValue;
 
-        paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, mTextBounds);
-        final int height = mTextBounds.height();
-        mTextHeightCache.put(labelSize, height);
+        paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, sTextBounds);
+        final float height = sTextBounds.height();
+        sTextHeightCache.put(labelSize, height);
         return height;
     }
 
-    private int getLabelCharWidth(Paint paint) {
+    private static float getCharWidth(Paint paint) {
         final int labelSize = (int)paint.getTextSize();
         final Typeface face = paint.getTypeface();
         final Integer key;
@@ -895,13 +964,13 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             key = labelSize;
         }
 
-        final Integer cached = mTextWidthCache.get(key);
+        final Float cached = sTextWidthCache.get(key);
         if (cached != null)
             return cached;
 
-        paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, mTextBounds);
-        final int width = mTextBounds.width();
-        mTextWidthCache.put(key, width);
+        paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, sTextBounds);
+        final float width = sTextBounds.width();
+        sTextWidthCache.put(key, width);
         return width;
     }
 
@@ -913,21 +982,21 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         canvas.translate(-x, -y);
     }
 
-    private static void drawHorizontalLine(Canvas canvas, int y, int w, int color, Paint paint) {
+    private static void drawHorizontalLine(Canvas canvas, float y, float w, int color, Paint paint) {
         paint.setStyle(Paint.Style.STROKE);
         paint.setStrokeWidth(1.0f);
         paint.setColor(color);
         canvas.drawLine(0, y, w, y, paint);
     }
 
-    private static void drawVerticalLine(Canvas canvas, int x, int h, int color, Paint paint) {
+    private static void drawVerticalLine(Canvas canvas, float x, float h, int color, Paint paint) {
         paint.setStyle(Paint.Style.STROKE);
         paint.setStrokeWidth(1.0f);
         paint.setColor(color);
         canvas.drawLine(x, 0, x, h, paint);
     }
 
-    private static void drawRectangle(Canvas canvas, int x, int y, int w, int h, int color,
+    private static void drawRectangle(Canvas canvas, float x, float y, float w, float h, int color,
             Paint paint) {
         paint.setStyle(Paint.Style.STROKE);
         paint.setStrokeWidth(1.0f);
@@ -997,7 +1066,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             return;
 
         mHandler.cancelAllDismissKeyPreviews();
-
+        final KeyPreviewDrawParams params = mKeyPreviewDrawParams;
         final int keyDrawX = key.mX + key.mVisualInsetsLeft;
         final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
         // What we show as preview should match what we show on key top in onBufferDraw(). 
@@ -1005,13 +1074,13 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             // TODO Should take care of temporaryShiftLabel here.
             previewText.setCompoundDrawables(null, null, null, null);
             if (key.mLabel.length() > 1) {
-                previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize);
+                previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mKeyLetterSize);
                 previewText.setTypeface(Typeface.DEFAULT_BOLD);
             } else {
-                previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSize);
-                previewText.setTypeface(mKeyTextStyle);
+                previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mPreviewTextSize);
+                previewText.setTypeface(params.mKeyTextStyle);
             }
-            previewText.setText(adjustCase(tracker.getPreviewText(key)));
+            previewText.setText(key.getCaseAdjustedLabel());
         } else {
             final Drawable previewIcon = key.getPreviewIcon();
             previewText.setCompoundDrawables(null, null, null,
@@ -1019,29 +1088,31 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             previewText.setText(null);
         }
         if (key.mCode == Keyboard.CODE_SPACE) {
-            previewText.setBackgroundDrawable(mPreviewSpacebarBackground);
+            previewText.setBackgroundDrawable(params.mPreviewSpacebarBackground);
         } else {
-            previewText.setBackgroundDrawable(mPreviewBackground);
+            previewText.setBackgroundDrawable(params.mPreviewBackground);
         }
 
         previewText.measure(MEASURESPEC_UNSPECIFIED, MEASURESPEC_UNSPECIFIED);
         final int previewWidth = Math.max(previewText.getMeasuredWidth(), keyDrawWidth
                 + previewText.getPaddingLeft() + previewText.getPaddingRight());
-        final int previewHeight = mPreviewHeight;
-        getLocationInWindow(mCoordinates);
-        int previewX = keyDrawX - (previewWidth - keyDrawWidth) / 2 + mCoordinates[0];
-        final int previewY = key.mY - previewHeight + mCoordinates[1] + mPreviewOffset;
-        if (previewX < 0 && mPreviewLeftBackground != null) {
-            previewText.setBackgroundDrawable(mPreviewLeftBackground);
+        final int previewHeight = params.mPreviewHeight;
+        getLocationInWindow(params.mCoordinates);
+        int previewX = keyDrawX - (previewWidth - keyDrawWidth) / 2 + params.mCoordinates[0];
+        final int previewY = key.mY - previewHeight
+                + params.mCoordinates[1] + params.mPreviewOffset;
+        if (previewX < 0 && params.mPreviewLeftBackground != null) {
+            previewText.setBackgroundDrawable(params.mPreviewLeftBackground);
             previewX = 0;
-        } else if (previewX + previewWidth > getWidth() && mPreviewRightBackground != null) {
-            previewText.setBackgroundDrawable(mPreviewRightBackground);
+        } else if (previewX + previewWidth > getWidth() && params.mPreviewRightBackground != null) {
+            previewText.setBackgroundDrawable(params.mPreviewRightBackground);
             previewX = getWidth() - previewWidth;
         }
 
         // Set the preview background state
         previewText.getBackground().setState(
                 key.mPopupCharacters != null ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
+        previewText.setTextColor(params.mPreviewTextColor);
         FrameLayoutCompatUtils.placeViewAt(
                 previewText, previewX, previewY, previewWidth, previewHeight);
         previewText.setVisibility(VISIBLE);
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index 9d58f69ff5068b05fb35798fdc490467c5eb7235..d925b8c3338c7aa646f9b4e87aee2803b1f0bb00 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -29,6 +29,7 @@ import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
 
 import com.android.inputmethod.keyboard.internal.SlidingLocaleDrawable;
 import com.android.inputmethod.latin.R;
@@ -182,6 +183,15 @@ public class LatinKeyboard extends Keyboard {
         return mSpaceKey;
     }
 
+    @Override
+    public CharSequence adjustLabelCase(CharSequence label) {
+        if (isAlphaKeyboard() && isShiftedOrShiftLocked() && !TextUtils.isEmpty(label)
+                && label.length() < 3 && Character.isLowerCase(label.charAt(0))) {
+            return label.toString().toUpperCase(mId.mLocale);
+        }
+        return label;
+    }
+
     private void updateSpacebarForLocale(boolean isAutoCorrection) {
         if (mSpaceKey == null)
             return;
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 901df6ab72eaaecbe233f47b49038d5a1e061c07..75d022b520fbc1c264f885f69f716c124b7fe00a 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard;
 
 import android.content.Context;
 import android.graphics.Canvas;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -113,18 +112,6 @@ public class LatinKeyboardView extends KeyboardView {
         return true;
     }
 
-    @Override
-    protected CharSequence adjustCase(CharSequence label) {
-        LatinKeyboard keyboard = getLatinKeyboard();
-        if (keyboard.isAlphaKeyboard()
-                && keyboard.isShiftedOrShiftLocked()
-                && !TextUtils.isEmpty(label) && label.length() < 3
-                && Character.isLowerCase(label.charAt(0))) {
-            return label.toString().toUpperCase(keyboard.mId.mLocale);
-        }
-        return label;
-    }
-
     /**
      * This function checks to see if we need to handle any sudden jumps in the pointer location
      * that could be due to a multi-touch being treated as a move by the firmware or hardware.
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
index 2d6766f2d2fd34c31693028e0c2d11845f3902d7..44f9f195cfc3d04ae4b072a54389e2a982c70c34 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
@@ -18,13 +18,22 @@ package com.android.inputmethod.keyboard;
 
 import android.content.Context;
 
-import java.util.List;
-
 public class MiniKeyboard extends Keyboard {
     private int mDefaultKeyCoordX;
 
     public MiniKeyboard(Context context, int xmlLayoutResId, Keyboard parentKeyboard) {
-        super(context, xmlLayoutResId, null, parentKeyboard.getMinWidth());
+        super(context, xmlLayoutResId, parentKeyboard.mId.cloneAsMiniKeyboard(),
+                parentKeyboard.getMinWidth());
+        // HACK: Current mini keyboard design totally relies on the 9-patch padding about horizontal
+        // and vertical key spacing. To keep the visual of mini keyboard as is, these hacks are
+        // needed to keep having the same horizontal and vertical key spacing.
+        setHorizontalGap(0);
+        setVerticalGap(parentKeyboard.getVerticalGap() / 2);
+
+        // TODO: When we have correctly padded key background 9-patch drawables for mini keyboard,
+        // revert the above hacks and uncomment the following lines.
+        //setHorizontalGap(parentKeyboard.getHorizontalGap());
+        //setVerticalGap(parentKeyboard.getVerticalGap());
     }
 
     public void setDefaultCoordX(int pos) {
@@ -34,19 +43,4 @@ public class MiniKeyboard extends Keyboard {
     public int getDefaultCoordX() {
         return mDefaultKeyCoordX;
     }
-
-    public boolean isOneRowKeyboard() {
-        final List<Key> keys = getKeys();
-        if (keys.size() == 0) return false;
-        final int edgeFlags = keys.get(0).mEdgeFlags;
-        // HACK: The first key of mini keyboard which was inflated from xml and has multiple rows,
-        // does not have both top and bottom edge flags on at the same time.  On the other hand,
-        // the first key of mini keyboard that was created with popupCharacters must have both top
-        // and bottom edge flags on.
-        // When you want to use one row mini-keyboard from xml file, make sure that the row has
-        // both top and bottom edge flags set.
-        return (edgeFlags & Keyboard.EDGE_TOP) != 0
-                && (edgeFlags & Keyboard.EDGE_BOTTOM) != 0;
-
-    }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 8b03360bf388cab66d85b13a9548f66bf5521671..6228cc8b2cb73abb2e0d1bf76a78e1ea566471a6 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -686,10 +686,6 @@ public class PointerTracker {
         }
     }
 
-    public CharSequence getPreviewText(Key key) {
-        return key.mLabel;
-    }
-
     private long mPreviousEventTime;
 
     private void printTouchEvent(String title, int x, int y, long eventTime) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
index a6708171f98c1cafcd202e8670e4ad92b5ef12ab..3e433361a5a1d7a364c403a8e9d8e6de0eb65600 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
@@ -195,6 +195,7 @@ public class KeyboardParser {
 
     private void parseKeyboardAttributes(XmlResourceParser parser) {
         final Keyboard keyboard = mKeyboard;
+        final int displayWidth = keyboard.getDisplayWidth();
         final TypedArray keyboardAttr = mContext.obtainStyledAttributes(
                 Xml.asAttributeSet(parser), R.styleable.Keyboard, R.attr.keyboardStyle,
                 R.style.Keyboard);
@@ -211,7 +212,6 @@ public class KeyboardParser {
             if (minKeyboardHeight < 0) {
                 // Specified fraction was negative, so it should be calculated against display
                 // width.
-                final int displayWidth = keyboard.getDisplayWidth();
                 minKeyboardHeight = -getDimensionOrFraction(keyboardAttr,
                         R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
             }
@@ -219,20 +219,19 @@ public class KeyboardParser {
             // minKeyboardHeight.
             final int height = Math.max(
                     Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
-            final int width = keyboard.getDisplayWidth();
+
 
             keyboard.setKeyboardHeight(height);
             keyboard.setKeyWidth(getDimensionOrFraction(keyboardAttr,
-                    R.styleable.Keyboard_keyWidth, width, width / 10));
+                    R.styleable.Keyboard_keyWidth, displayWidth, displayWidth / 10));
             keyboard.setRowHeight(getDimensionOrFraction(keyboardAttr,
                     R.styleable.Keyboard_rowHeight, height, 50));
             keyboard.setHorizontalGap(getDimensionOrFraction(keyboardAttr,
-                    R.styleable.Keyboard_horizontalGap, width, 0));
+                    R.styleable.Keyboard_horizontalGap, displayWidth, 0));
             keyboard.setVerticalGap(getDimensionOrFraction(keyboardAttr,
                     R.styleable.Keyboard_verticalGap, height, 0));
             keyboard.setPopupKeyboardResId(keyboardAttr.getResourceId(
                     R.styleable.Keyboard_popupKeyboardTemplate, 0));
-
             keyboard.setMaxPopupKeyboardColumn(keyAttr.getInt(
                     R.styleable.Keyboard_Key_maxPopupKeyboardColumn, 5));
 
@@ -352,18 +351,18 @@ public class KeyboardParser {
                     R.styleable.Keyboard);
             if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap))
                 throw new IllegalAttribute(parser, "horizontalGap");
-            final int defaultWidth = (row != null) ? row.mDefaultWidth : 0;
+            final int keyboardWidth = mKeyboard.getDisplayWidth();
             final int keyWidth = getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth,
-                    mKeyboard.getDisplayWidth(), defaultWidth);
+                    keyboardWidth, row.mDefaultWidth);
             keyboardAttr.recycle();
 
             final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
                     R.styleable.Keyboard_Key);
             int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr,
-                    R.styleable.Keyboard_Key_keyXPos, mKeyboard.getDisplayWidth(), mCurrentX);
+                    R.styleable.Keyboard_Key_keyXPos, keyboardWidth, mCurrentX);
             if (keyXPos < 0) {
                 // If keyXPos is negative, the actual x-coordinate will be display_width + keyXPos.
-                keyXPos += mKeyboard.getDisplayWidth();
+                keyXPos += keyboardWidth;
             }
 
             checkEndTag(TAG_SPACER, parser);