Merge remote-tracking branch 'goog/master' into mergescriptpackage
commit
3709da91a5
|
@ -81,6 +81,11 @@
|
||||||
<!-- Description for option enabling or disabling the use of names of people in Contacts for suggestion and correction [CHAR LIMIT=65] -->
|
<!-- Description for option enabling or disabling the use of names of people in Contacts for suggestion and correction [CHAR LIMIT=65] -->
|
||||||
<string name="use_contacts_dict_summary">Use names from Contacts for suggestions and corrections</string>
|
<string name="use_contacts_dict_summary">Use names from Contacts for suggestions and corrections</string>
|
||||||
|
|
||||||
|
<!-- Option name for enabling or disabling the double-space period feature that lets double tap on spacebar insert a period followed by a space [CHAR LIMIT=25] -->
|
||||||
|
<string name="use_double_space_period">Double-space period</string>
|
||||||
|
<!-- Description for option enabling or disabling the double-space period feature that lets double tap on spacebar insert a period followed by a space [CHAR LIMIT=65] -->
|
||||||
|
<string name="use_double_space_period_summary">Double tap on spacebar inserts a period followed by a space</string>
|
||||||
|
|
||||||
<!-- Option to enable auto capitalization of sentences -->
|
<!-- Option to enable auto capitalization of sentences -->
|
||||||
<string name="auto_cap">Auto-capitalization</string>
|
<string name="auto_cap">Auto-capitalization</string>
|
||||||
<!-- Description for option to enable auto capitalization of sentences -->
|
<!-- Description for option to enable auto capitalization of sentences -->
|
||||||
|
|
|
@ -118,6 +118,12 @@
|
||||||
android:summary="@string/use_contacts_dict_summary"
|
android:summary="@string/use_contacts_dict_summary"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:defaultValue="true" />
|
android:defaultValue="true" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="pref_key_use_double_space_period"
|
||||||
|
android:title="@string/use_double_space_period"
|
||||||
|
android:summary="@string/use_double_space_period_summary"
|
||||||
|
android:persistent="true"
|
||||||
|
android:defaultValue="true" />
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="pref_show_language_switch_key"
|
android:key="pref_show_language_switch_key"
|
||||||
android:title="@string/show_language_switch_key"
|
android:title="@string/show_language_switch_key"
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
|
|
||||||
// Preview placer view
|
// Preview placer view
|
||||||
private final PreviewPlacerView mPreviewPlacerView;
|
private final PreviewPlacerView mPreviewPlacerView;
|
||||||
private final int[] mCoordinates = CoordinateUtils.newInstance();
|
private final int[] mOriginCoords = CoordinateUtils.newInstance();
|
||||||
|
|
||||||
// Key preview
|
// Key preview
|
||||||
private static final int PREVIEW_ALPHA = 240;
|
private static final int PREVIEW_ALPHA = 240;
|
||||||
|
@ -833,10 +833,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
// In transient state.
|
// In transient state.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int[] viewOrigin = CoordinateUtils.newInstance();
|
getLocationInWindow(mOriginCoords);
|
||||||
getLocationInWindow(viewOrigin);
|
|
||||||
final DisplayMetrics dm = getResources().getDisplayMetrics();
|
final DisplayMetrics dm = getResources().getDisplayMetrics();
|
||||||
if (CoordinateUtils.y(viewOrigin) < dm.heightPixels / 4) {
|
if (CoordinateUtils.y(mOriginCoords) < dm.heightPixels / 4) {
|
||||||
// In transient state.
|
// In transient state.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -851,11 +850,21 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
Log.w(TAG, "Cannot find android.R.id.content view to add PreviewPlacerView");
|
Log.w(TAG, "Cannot find android.R.id.content view to add PreviewPlacerView");
|
||||||
} else {
|
} else {
|
||||||
windowContentView.addView(mPreviewPlacerView);
|
windowContentView.addView(mPreviewPlacerView);
|
||||||
mPreviewPlacerView.setKeyboardViewGeometry(
|
mPreviewPlacerView.setKeyboardViewGeometry(mOriginCoords, width, height);
|
||||||
CoordinateUtils.x(viewOrigin), CoordinateUtils.y(viewOrigin), width, height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showSlidingKeyInputPreview(final PointerTracker tracker) {
|
||||||
|
locatePreviewPlacerView();
|
||||||
|
mPreviewPlacerView.showSlidingKeyInputPreview(tracker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dismissSlidingKeyInputPreview() {
|
||||||
|
mPreviewPlacerView.dismissSlidingKeyInputPreview();
|
||||||
|
}
|
||||||
|
|
||||||
public void showGestureFloatingPreviewText(final String gestureFloatingPreviewText) {
|
public void showGestureFloatingPreviewText(final String gestureFloatingPreviewText) {
|
||||||
locatePreviewPlacerView();
|
locatePreviewPlacerView();
|
||||||
mPreviewPlacerView.setGestureFloatingPreviewText(gestureFloatingPreviewText);
|
mPreviewPlacerView.setGestureFloatingPreviewText(gestureFloatingPreviewText);
|
||||||
|
@ -937,13 +946,13 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
// The distance between the top edge of the parent key and the bottom of the visible part
|
// The distance between the top edge of the parent key and the bottom of the visible part
|
||||||
// of the key preview background.
|
// of the key preview background.
|
||||||
previewParams.mPreviewVisibleOffset = mPreviewOffset - previewText.getPaddingBottom();
|
previewParams.mPreviewVisibleOffset = mPreviewOffset - previewText.getPaddingBottom();
|
||||||
getLocationInWindow(mCoordinates);
|
getLocationInWindow(mOriginCoords);
|
||||||
// The key preview is horizontally aligned with the center of the visible part of the
|
// The key preview is horizontally aligned with the center of the visible part of the
|
||||||
// parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and
|
// parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and
|
||||||
// the left/right background is used if such background is specified.
|
// the left/right background is used if such background is specified.
|
||||||
final int statePosition;
|
final int statePosition;
|
||||||
int previewX = key.getDrawX() - (previewWidth - keyDrawWidth) / 2
|
int previewX = key.getDrawX() - (previewWidth - keyDrawWidth) / 2
|
||||||
+ CoordinateUtils.x(mCoordinates);
|
+ CoordinateUtils.x(mOriginCoords);
|
||||||
if (previewX < 0) {
|
if (previewX < 0) {
|
||||||
previewX = 0;
|
previewX = 0;
|
||||||
statePosition = STATE_LEFT;
|
statePosition = STATE_LEFT;
|
||||||
|
@ -956,7 +965,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
// The key preview is placed vertically above the top edge of the parent key with an
|
// The key preview is placed vertically above the top edge of the parent key with an
|
||||||
// arbitrary offset.
|
// arbitrary offset.
|
||||||
final int previewY = key.mY - previewHeight + mPreviewOffset
|
final int previewY = key.mY - previewHeight + mPreviewOffset
|
||||||
+ CoordinateUtils.y(mCoordinates);
|
+ CoordinateUtils.y(mOriginCoords);
|
||||||
|
|
||||||
if (background != null) {
|
if (background != null) {
|
||||||
final int hasMoreKeys = (key.mMoreKeys != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
|
final int hasMoreKeys = (key.mMoreKeys != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
|
||||||
|
|
|
@ -49,6 +49,7 @@ import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
|
||||||
import com.android.inputmethod.keyboard.internal.KeyDrawParams;
|
import com.android.inputmethod.keyboard.internal.KeyDrawParams;
|
||||||
import com.android.inputmethod.keyboard.internal.TouchScreenRegulator;
|
import com.android.inputmethod.keyboard.internal.TouchScreenRegulator;
|
||||||
import com.android.inputmethod.latin.Constants;
|
import com.android.inputmethod.latin.Constants;
|
||||||
|
import com.android.inputmethod.latin.CoordinateUtils;
|
||||||
import com.android.inputmethod.latin.DebugSettings;
|
import com.android.inputmethod.latin.DebugSettings;
|
||||||
import com.android.inputmethod.latin.LatinIME;
|
import com.android.inputmethod.latin.LatinIME;
|
||||||
import com.android.inputmethod.latin.LatinImeLogger;
|
import com.android.inputmethod.latin.LatinImeLogger;
|
||||||
|
@ -672,12 +673,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
mMoreKeysPanel = moreKeysPanel;
|
mMoreKeysPanel = moreKeysPanel;
|
||||||
mMoreKeysPanelPointerTrackerId = tracker.mPointerId;
|
mMoreKeysPanelPointerTrackerId = tracker.mPointerId;
|
||||||
|
|
||||||
|
final int[] lastCoords = CoordinateUtils.newInstance();
|
||||||
|
tracker.getLastCoordinates(lastCoords);
|
||||||
final boolean keyPreviewEnabled = isKeyPreviewPopupEnabled() && !parentKey.noKeyPreview();
|
final boolean keyPreviewEnabled = isKeyPreviewPopupEnabled() && !parentKey.noKeyPreview();
|
||||||
// The more keys keyboard is usually horizontally aligned with the center of the parent key.
|
// The more keys keyboard is usually horizontally aligned with the center of the parent key.
|
||||||
// If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more
|
// If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more
|
||||||
// keys keyboard is placed at the touch point of the parent key.
|
// keys keyboard is placed at the touch point of the parent key.
|
||||||
final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled)
|
final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled)
|
||||||
? tracker.getLastX()
|
? CoordinateUtils.x(lastCoords)
|
||||||
: parentKey.mX + parentKey.mWidth / 2;
|
: parentKey.mX + parentKey.mWidth / 2;
|
||||||
// The more keys keyboard is usually vertically aligned with the top edge of the parent key
|
// The more keys keyboard is usually vertically aligned with the top edge of the parent key
|
||||||
// (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically
|
// (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically
|
||||||
|
@ -687,8 +690,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
final int pointY = parentKey.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset;
|
final int pointY = parentKey.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset;
|
||||||
moreKeysPanel.showMoreKeysPanel(
|
moreKeysPanel.showMoreKeysPanel(
|
||||||
this, this, pointX, pointY, mMoreKeysWindow, mKeyboardActionListener);
|
this, this, pointX, pointY, mMoreKeysWindow, mKeyboardActionListener);
|
||||||
final int translatedX = moreKeysPanel.translateX(tracker.getLastX());
|
final int translatedX = moreKeysPanel.translateX(CoordinateUtils.x(lastCoords));
|
||||||
final int translatedY = moreKeysPanel.translateY(tracker.getLastY());
|
final int translatedY = moreKeysPanel.translateY(CoordinateUtils.y(lastCoords));
|
||||||
tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel);
|
tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel);
|
||||||
dimEntireKeyboard(true);
|
dimEntireKeyboard(true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -788,10 +791,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
} else if (pointerCount == 2 && oldPointerCount == 1) {
|
} else if (pointerCount == 2 && oldPointerCount == 1) {
|
||||||
// Single-touch to multi-touch transition.
|
// Single-touch to multi-touch transition.
|
||||||
// Send an up event for the last pointer.
|
// Send an up event for the last pointer.
|
||||||
final int lastX = tracker.getLastX();
|
final int[] lastCoords = CoordinateUtils.newInstance();
|
||||||
final int lastY = tracker.getLastY();
|
mOldKey = tracker.getKeyOn(
|
||||||
mOldKey = tracker.getKeyOn(lastX, lastY);
|
CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords));
|
||||||
tracker.onUpEvent(lastX, lastY, eventTime);
|
tracker.onUpEvent(
|
||||||
|
CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords), eventTime);
|
||||||
} else if (pointerCount == 1 && oldPointerCount == 1) {
|
} else if (pointerCount == 1 && oldPointerCount == 1) {
|
||||||
tracker.processMotionEvent(action, x, y, eventTime, this);
|
tracker.processMotionEvent(action, x, y, eventTime, this);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
|
||||||
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
|
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
|
||||||
import com.android.inputmethod.latin.CollectionUtils;
|
import com.android.inputmethod.latin.CollectionUtils;
|
||||||
import com.android.inputmethod.latin.Constants;
|
import com.android.inputmethod.latin.Constants;
|
||||||
|
import com.android.inputmethod.latin.CoordinateUtils;
|
||||||
import com.android.inputmethod.latin.InputPointers;
|
import com.android.inputmethod.latin.InputPointers;
|
||||||
import com.android.inputmethod.latin.LatinImeLogger;
|
import com.android.inputmethod.latin.LatinImeLogger;
|
||||||
import com.android.inputmethod.latin.R;
|
import com.android.inputmethod.latin.R;
|
||||||
|
@ -80,6 +81,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
public void invalidateKey(Key key);
|
public void invalidateKey(Key key);
|
||||||
public void showKeyPreview(PointerTracker tracker);
|
public void showKeyPreview(PointerTracker tracker);
|
||||||
public void dismissKeyPreview(PointerTracker tracker);
|
public void dismissKeyPreview(PointerTracker tracker);
|
||||||
|
public void showSlidingKeyInputPreview(PointerTracker tracker);
|
||||||
|
public void dismissSlidingKeyInputPreview();
|
||||||
public void showGesturePreviewTrail(PointerTracker tracker, boolean isOldestTracker);
|
public void showGesturePreviewTrail(PointerTracker tracker, boolean isOldestTracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,6 +299,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
|
|
||||||
// The position and time at which first down event occurred.
|
// The position and time at which first down event occurred.
|
||||||
private long mDownTime;
|
private long mDownTime;
|
||||||
|
private int[] mDownCoordinates = CoordinateUtils.newInstance();
|
||||||
private long mUpTime;
|
private long mUpTime;
|
||||||
|
|
||||||
// The current key where this pointer is.
|
// The current key where this pointer is.
|
||||||
|
@ -540,6 +544,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
return mIsInSlidingKeyInput;
|
return mIsInSlidingKeyInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInSlidingKeyInputFromModifier() {
|
||||||
|
return mIsInSlidingKeyInputFromModifier;
|
||||||
|
}
|
||||||
|
|
||||||
public Key getKey() {
|
public Key getKey() {
|
||||||
return mCurrentKey;
|
return mCurrentKey;
|
||||||
}
|
}
|
||||||
|
@ -642,20 +650,21 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
return mGestureStrokeWithPreviewPoints;
|
return mGestureStrokeWithPreviewPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLastX() {
|
public void getLastCoordinates(final int[] outCoords) {
|
||||||
return mLastX;
|
CoordinateUtils.set(outCoords, mLastX, mLastY);
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastY() {
|
|
||||||
return mLastY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDownTime() {
|
public long getDownTime() {
|
||||||
return mDownTime;
|
return mDownTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getDownCoordinates(final int[] outCoords) {
|
||||||
|
CoordinateUtils.copy(outCoords, mDownCoordinates);
|
||||||
|
}
|
||||||
|
|
||||||
private Key onDownKey(final int x, final int y, final long eventTime) {
|
private Key onDownKey(final int x, final int y, final long eventTime) {
|
||||||
mDownTime = eventTime;
|
mDownTime = eventTime;
|
||||||
|
CoordinateUtils.set(mDownCoordinates, x, y);
|
||||||
mBogusMoveEventDetector.onDownKey();
|
mBogusMoveEventDetector.onDownKey();
|
||||||
return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
|
return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
|
||||||
}
|
}
|
||||||
|
@ -721,6 +730,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
updateBatchInput(eventTime);
|
updateBatchInput(eventTime);
|
||||||
}
|
}
|
||||||
|
if (mIsTrackingCanceled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mDrawingProxy.showGesturePreviewTrail(this, isOldestTrackerInQueue(this));
|
mDrawingProxy.showGesturePreviewTrail(this, isOldestTrackerInQueue(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,6 +771,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mIsTrackingCanceled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mDrawingProxy.showGesturePreviewTrail(this, isOldestTrackerInQueue(this));
|
mDrawingProxy.showGesturePreviewTrail(this, isOldestTrackerInQueue(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,6 +882,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
private void resetSlidingKeyInput() {
|
private void resetSlidingKeyInput() {
|
||||||
mIsInSlidingKeyInput = false;
|
mIsInSlidingKeyInput = false;
|
||||||
mIsInSlidingKeyInputFromModifier = false;
|
mIsInSlidingKeyInputFromModifier = false;
|
||||||
|
mDrawingProxy.dismissSlidingKeyInputPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onGestureMoveEvent(final int x, final int y, final long eventTime,
|
private void onGestureMoveEvent(final int x, final int y, final long eventTime,
|
||||||
|
@ -1061,6 +1077,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
slideOutFromOldKey(oldKey, x, y);
|
slideOutFromOldKey(oldKey, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mDrawingProxy.showSlidingKeyInputPreview(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUpEvent(final int x, final int y, final long eventTime) {
|
public void onUpEvent(final int x, final int y, final long eventTime) {
|
||||||
|
@ -1087,7 +1104,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
@Override
|
@Override
|
||||||
public void onPhantomUpEvent(final long eventTime) {
|
public void onPhantomUpEvent(final long eventTime) {
|
||||||
if (DEBUG_EVENT) {
|
if (DEBUG_EVENT) {
|
||||||
printTouchEvent("onPhntEvent:", getLastX(), getLastY(), eventTime);
|
printTouchEvent("onPhntEvent:", mLastX, mLastY, eventTime);
|
||||||
}
|
}
|
||||||
onUpEventInternal(eventTime);
|
onUpEventInternal(eventTime);
|
||||||
cancelTracking();
|
cancelTracking();
|
||||||
|
@ -1134,6 +1151,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLongPressed() {
|
public void onLongPressed() {
|
||||||
|
resetSlidingKeyInput();
|
||||||
cancelTracking();
|
cancelTracking();
|
||||||
setReleasedKeyGraphics(mCurrentKey);
|
setReleasedKeyGraphics(mCurrentKey);
|
||||||
sPointerTrackerQueue.remove(this);
|
sPointerTrackerQueue.remove(this);
|
||||||
|
|
|
@ -99,6 +99,7 @@ public final class ProximityInfo {
|
||||||
JniUtils.loadNativeLibrary();
|
JniUtils.loadNativeLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Stop passing proximityCharsArray
|
||||||
private native long setProximityInfoNative(
|
private native long setProximityInfoNative(
|
||||||
String locale, int maxProximityCharsSize, int displayWidth,
|
String locale, int maxProximityCharsSize, int displayWidth,
|
||||||
int displayHeight, int gridWidth, int gridHeight,
|
int displayHeight, int gridWidth, int gridHeight,
|
||||||
|
@ -109,22 +110,56 @@ public final class ProximityInfo {
|
||||||
|
|
||||||
private native void releaseProximityInfoNative(long nativeProximityInfo);
|
private native void releaseProximityInfoNative(long nativeProximityInfo);
|
||||||
|
|
||||||
private final long createNativeProximityInfo(
|
private static boolean needsProximityInfo(final Key key) {
|
||||||
final TouchPositionCorrection touchPositionCorrection) {
|
// Don't include special keys into ProximityInfo.
|
||||||
|
return key.mCode >= Constants.CODE_SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getProximityInfoKeysCount(final Key[] keys) {
|
||||||
|
int count = 0;
|
||||||
|
for (final Key key : keys) {
|
||||||
|
if (needsProximityInfo(key)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long createNativeProximityInfo(final TouchPositionCorrection touchPositionCorrection) {
|
||||||
final Key[][] gridNeighborKeys = mGridNeighbors;
|
final Key[][] gridNeighborKeys = mGridNeighbors;
|
||||||
final int keyboardWidth = mKeyboardMinWidth;
|
|
||||||
final int keyboardHeight = mKeyboardHeight;
|
|
||||||
final Key[] keys = mKeys;
|
|
||||||
final int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
final int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
||||||
Arrays.fill(proximityCharsArray, Constants.NOT_A_CODE);
|
Arrays.fill(proximityCharsArray, Constants.NOT_A_CODE);
|
||||||
for (int i = 0; i < mGridSize; ++i) {
|
for (int i = 0; i < mGridSize; ++i) {
|
||||||
final int proximityCharsLength = gridNeighborKeys[i].length;
|
final int proximityCharsLength = gridNeighborKeys[i].length;
|
||||||
|
int infoIndex = i * MAX_PROXIMITY_CHARS_SIZE;
|
||||||
for (int j = 0; j < proximityCharsLength; ++j) {
|
for (int j = 0; j < proximityCharsLength; ++j) {
|
||||||
proximityCharsArray[i * MAX_PROXIMITY_CHARS_SIZE + j] =
|
final Key neighborKey = gridNeighborKeys[i][j];
|
||||||
gridNeighborKeys[i][j].mCode;
|
// Excluding from proximityCharsArray
|
||||||
|
if (!needsProximityInfo(neighborKey)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
proximityCharsArray[infoIndex] = neighborKey.mCode;
|
||||||
|
infoIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final int keyCount = keys.length;
|
if (DEBUG) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < mGridSize; i++) {
|
||||||
|
sb.setLength(0);
|
||||||
|
for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE; j++) {
|
||||||
|
final int code = proximityCharsArray[i * MAX_PROXIMITY_CHARS_SIZE + j];
|
||||||
|
if (code == Constants.NOT_A_CODE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sb.length() > 0) sb.append(" ");
|
||||||
|
sb.append(Constants.printableCode(code));
|
||||||
|
}
|
||||||
|
Log.d(TAG, "proxmityChars["+i+"]: " + sb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Key[] keys = mKeys;
|
||||||
|
final int keyCount = getProximityInfoKeysCount(keys);
|
||||||
final int[] keyXCoordinates = new int[keyCount];
|
final int[] keyXCoordinates = new int[keyCount];
|
||||||
final int[] keyYCoordinates = new int[keyCount];
|
final int[] keyYCoordinates = new int[keyCount];
|
||||||
final int[] keyWidths = new int[keyCount];
|
final int[] keyWidths = new int[keyCount];
|
||||||
|
@ -134,13 +169,18 @@ public final class ProximityInfo {
|
||||||
final float[] sweetSpotCenterYs;
|
final float[] sweetSpotCenterYs;
|
||||||
final float[] sweetSpotRadii;
|
final float[] sweetSpotRadii;
|
||||||
|
|
||||||
for (int i = 0; i < keyCount; ++i) {
|
for (int infoIndex = 0, keyIndex = 0; keyIndex < keys.length; keyIndex++) {
|
||||||
final Key key = keys[i];
|
final Key key = keys[keyIndex];
|
||||||
keyXCoordinates[i] = key.mX;
|
// Excluding from key coordinate arrays
|
||||||
keyYCoordinates[i] = key.mY;
|
if (!needsProximityInfo(key)) {
|
||||||
keyWidths[i] = key.mWidth;
|
continue;
|
||||||
keyHeights[i] = key.mHeight;
|
}
|
||||||
keyCharCodes[i] = key.mCode;
|
keyXCoordinates[infoIndex] = key.mX;
|
||||||
|
keyYCoordinates[infoIndex] = key.mY;
|
||||||
|
keyWidths[infoIndex] = key.mWidth;
|
||||||
|
keyHeights[infoIndex] = key.mHeight;
|
||||||
|
keyCharCodes[infoIndex] = key.mCode;
|
||||||
|
infoIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (touchPositionCorrection != null && touchPositionCorrection.isValid()) {
|
if (touchPositionCorrection != null && touchPositionCorrection.isValid()) {
|
||||||
|
@ -153,28 +193,36 @@ public final class ProximityInfo {
|
||||||
final int rows = touchPositionCorrection.getRows();
|
final int rows = touchPositionCorrection.getRows();
|
||||||
final float defaultRadius = DEFAULT_TOUCH_POSITION_CORRECTION_RADIUS
|
final float defaultRadius = DEFAULT_TOUCH_POSITION_CORRECTION_RADIUS
|
||||||
* (float)Math.hypot(mMostCommonKeyWidth, mMostCommonKeyHeight);
|
* (float)Math.hypot(mMostCommonKeyWidth, mMostCommonKeyHeight);
|
||||||
for (int i = 0; i < keyCount; i++) {
|
for (int infoIndex = 0, keyIndex = 0; keyIndex < keys.length; keyIndex++) {
|
||||||
final Key key = keys[i];
|
final Key key = keys[keyIndex];
|
||||||
|
// Excluding from touch position correction arrays
|
||||||
|
if (!needsProximityInfo(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
final Rect hitBox = key.mHitBox;
|
final Rect hitBox = key.mHitBox;
|
||||||
sweetSpotCenterXs[i] = hitBox.exactCenterX();
|
sweetSpotCenterXs[infoIndex] = hitBox.exactCenterX();
|
||||||
sweetSpotCenterYs[i] = hitBox.exactCenterY();
|
sweetSpotCenterYs[infoIndex] = hitBox.exactCenterY();
|
||||||
sweetSpotRadii[i] = defaultRadius;
|
sweetSpotRadii[infoIndex] = defaultRadius;
|
||||||
final int row = hitBox.top / mMostCommonKeyHeight;
|
final int row = hitBox.top / mMostCommonKeyHeight;
|
||||||
if (row < rows) {
|
if (row < rows) {
|
||||||
final int hitBoxWidth = hitBox.width();
|
final int hitBoxWidth = hitBox.width();
|
||||||
final int hitBoxHeight = hitBox.height();
|
final int hitBoxHeight = hitBox.height();
|
||||||
final float hitBoxDiagonal = (float)Math.hypot(hitBoxWidth, hitBoxHeight);
|
final float hitBoxDiagonal = (float)Math.hypot(hitBoxWidth, hitBoxHeight);
|
||||||
sweetSpotCenterXs[i] += touchPositionCorrection.getX(row) * hitBoxWidth;
|
sweetSpotCenterXs[infoIndex] +=
|
||||||
sweetSpotCenterYs[i] += touchPositionCorrection.getY(row) * hitBoxHeight;
|
touchPositionCorrection.getX(row) * hitBoxWidth;
|
||||||
sweetSpotRadii[i] = touchPositionCorrection.getRadius(row) * hitBoxDiagonal;
|
sweetSpotCenterYs[infoIndex] +=
|
||||||
|
touchPositionCorrection.getY(row) * hitBoxHeight;
|
||||||
|
sweetSpotRadii[infoIndex] =
|
||||||
|
touchPositionCorrection.getRadius(row) * hitBoxDiagonal;
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, String.format(
|
Log.d(TAG, String.format(
|
||||||
" [%2d] row=%d x/y/r=%7.2f/%7.2f/%5.2f %s code=%s", i, row,
|
" [%2d] row=%d x/y/r=%7.2f/%7.2f/%5.2f %s code=%s", infoIndex, row,
|
||||||
sweetSpotCenterXs[i], sweetSpotCenterYs[i], sweetSpotRadii[i],
|
sweetSpotCenterXs[infoIndex], sweetSpotCenterYs[infoIndex],
|
||||||
(row < rows ? "correct" : "default"),
|
sweetSpotRadii[infoIndex], (row < rows ? "correct" : "default"),
|
||||||
Constants.printableCode(key.mCode)));
|
Constants.printableCode(key.mCode)));
|
||||||
}
|
}
|
||||||
|
infoIndex++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sweetSpotCenterXs = sweetSpotCenterYs = sweetSpotRadii = null;
|
sweetSpotCenterXs = sweetSpotCenterYs = sweetSpotRadii = null;
|
||||||
|
@ -183,11 +231,11 @@ public final class ProximityInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Stop passing proximityCharsArray
|
||||||
return setProximityInfoNative(mLocaleStr, MAX_PROXIMITY_CHARS_SIZE,
|
return setProximityInfoNative(mLocaleStr, MAX_PROXIMITY_CHARS_SIZE,
|
||||||
keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, mMostCommonKeyWidth,
|
mKeyboardMinWidth, mKeyboardHeight, mGridWidth, mGridHeight, mMostCommonKeyWidth,
|
||||||
proximityCharsArray,
|
proximityCharsArray, keyCount, keyXCoordinates, keyYCoordinates, keyWidths,
|
||||||
keyCount, keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes,
|
keyHeights, keyCharCodes, sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
|
||||||
sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNativeProximityInfo() {
|
public long getNativeProximityInfo() {
|
||||||
|
|
|
@ -36,6 +36,7 @@ import android.widget.RelativeLayout;
|
||||||
import com.android.inputmethod.keyboard.PointerTracker;
|
import com.android.inputmethod.keyboard.PointerTracker;
|
||||||
import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params;
|
import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params;
|
||||||
import com.android.inputmethod.latin.CollectionUtils;
|
import com.android.inputmethod.latin.CollectionUtils;
|
||||||
|
import com.android.inputmethod.latin.CoordinateUtils;
|
||||||
import com.android.inputmethod.latin.R;
|
import com.android.inputmethod.latin.R;
|
||||||
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
|
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
|
||||||
|
|
||||||
|
@ -47,8 +48,7 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
private final float mGestureFloatingPreviewVerticalPadding;
|
private final float mGestureFloatingPreviewVerticalPadding;
|
||||||
private final float mGestureFloatingPreviewRoundRadius;
|
private final float mGestureFloatingPreviewRoundRadius;
|
||||||
|
|
||||||
private int mKeyboardViewOriginX;
|
private final int[] mKeyboardViewOrigin = CoordinateUtils.newInstance();
|
||||||
private int mKeyboardViewOriginY;
|
|
||||||
|
|
||||||
private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails =
|
private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails =
|
||||||
CollectionUtils.newSparseArray();
|
CollectionUtils.newSparseArray();
|
||||||
|
@ -68,11 +68,14 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
private final int mGestureFloatingPreviewTextHeight;
|
private final int mGestureFloatingPreviewTextHeight;
|
||||||
// {@link RectF} is needed for {@link Canvas#drawRoundRect(RectF, float, float, Paint)}.
|
// {@link RectF} is needed for {@link Canvas#drawRoundRect(RectF, float, float, Paint)}.
|
||||||
private final RectF mGestureFloatingPreviewRectangle = new RectF();
|
private final RectF mGestureFloatingPreviewRectangle = new RectF();
|
||||||
private int mLastPointerX;
|
private final int[] mLastPointerCoords = CoordinateUtils.newInstance();
|
||||||
private int mLastPointerY;
|
|
||||||
private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' };
|
private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' };
|
||||||
private boolean mDrawsGestureFloatingPreviewText;
|
private boolean mDrawsGestureFloatingPreviewText;
|
||||||
|
|
||||||
|
private boolean mShowSlidingKeyInputPreview;
|
||||||
|
private final int[] mRubberBandFrom = CoordinateUtils.newInstance();
|
||||||
|
private final int[] mRubberBandTo = CoordinateUtils.newInstance();
|
||||||
|
|
||||||
private final DrawingHandler mDrawingHandler;
|
private final DrawingHandler mDrawingHandler;
|
||||||
|
|
||||||
private static final class DrawingHandler extends StaticInnerHandlerWrapper<PreviewPlacerView> {
|
private static final class DrawingHandler extends StaticInnerHandlerWrapper<PreviewPlacerView> {
|
||||||
|
@ -168,9 +171,8 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
setLayerType(LAYER_TYPE_HARDWARE, layerPaint);
|
setLayerType(LAYER_TYPE_HARDWARE, layerPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKeyboardViewGeometry(final int x, final int y, final int w, final int h) {
|
public void setKeyboardViewGeometry(final int[] originCoords, final int w, final int h) {
|
||||||
mKeyboardViewOriginX = x;
|
CoordinateUtils.copy(mKeyboardViewOrigin, originCoords);
|
||||||
mKeyboardViewOriginY = y;
|
|
||||||
mOffscreenOffsetY = (int)(h * GestureStroke.EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
|
mOffscreenOffsetY = (int)(h * GestureStroke.EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
|
||||||
mOffscreenWidth = w;
|
mOffscreenWidth = w;
|
||||||
mOffscreenHeight = mOffscreenOffsetY + h;
|
mOffscreenHeight = mOffscreenOffsetY + h;
|
||||||
|
@ -186,8 +188,7 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
final boolean needsToUpdateLastPointer =
|
final boolean needsToUpdateLastPointer =
|
||||||
isOldestTracker && mDrawsGestureFloatingPreviewText;
|
isOldestTracker && mDrawsGestureFloatingPreviewText;
|
||||||
if (needsToUpdateLastPointer) {
|
if (needsToUpdateLastPointer) {
|
||||||
mLastPointerX = tracker.getLastX();
|
tracker.getLastCoordinates(mLastPointerCoords);
|
||||||
mLastPointerY = tracker.getLastY();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDrawsGesturePreviewTrail) {
|
if (mDrawsGesturePreviewTrail) {
|
||||||
|
@ -208,6 +209,21 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showSlidingKeyInputPreview(final PointerTracker tracker) {
|
||||||
|
if (!tracker.isInSlidingKeyInputFromModifier()) {
|
||||||
|
mShowSlidingKeyInputPreview = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tracker.getDownCoordinates(mRubberBandFrom);
|
||||||
|
tracker.getLastCoordinates(mRubberBandTo);
|
||||||
|
mShowSlidingKeyInputPreview = true;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dismissSlidingKeyInputPreview() {
|
||||||
|
mShowSlidingKeyInputPreview = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
freeOffscreenBuffer();
|
freeOffscreenBuffer();
|
||||||
|
@ -234,6 +250,8 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
@Override
|
@Override
|
||||||
public void onDraw(final Canvas canvas) {
|
public void onDraw(final Canvas canvas) {
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
|
final int originX = CoordinateUtils.x(mKeyboardViewOrigin);
|
||||||
|
final int originY = CoordinateUtils.y(mKeyboardViewOrigin);
|
||||||
if (mDrawsGesturePreviewTrail) {
|
if (mDrawsGesturePreviewTrail) {
|
||||||
mayAllocateOffscreenBuffer();
|
mayAllocateOffscreenBuffer();
|
||||||
// Draw gesture trails to offscreen buffer.
|
// Draw gesture trails to offscreen buffer.
|
||||||
|
@ -241,11 +259,11 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
mOffscreenCanvas, mGesturePaint, mOffscreenDirtyRect);
|
mOffscreenCanvas, mGesturePaint, mOffscreenDirtyRect);
|
||||||
// Transfer offscreen buffer to screen.
|
// Transfer offscreen buffer to screen.
|
||||||
if (!mOffscreenDirtyRect.isEmpty()) {
|
if (!mOffscreenDirtyRect.isEmpty()) {
|
||||||
final int offsetY = mKeyboardViewOriginY - mOffscreenOffsetY;
|
final int offsetY = originY - mOffscreenOffsetY;
|
||||||
canvas.translate(mKeyboardViewOriginX, offsetY);
|
canvas.translate(originX, offsetY);
|
||||||
canvas.drawBitmap(mOffscreenBuffer, mOffscreenDirtyRect, mOffscreenDirtyRect,
|
canvas.drawBitmap(mOffscreenBuffer, mOffscreenDirtyRect, mOffscreenDirtyRect,
|
||||||
mGesturePaint);
|
mGesturePaint);
|
||||||
canvas.translate(-mKeyboardViewOriginX, -offsetY);
|
canvas.translate(-originX, -offsetY);
|
||||||
// Note: Defer clearing the dirty rectangle here because we will get cleared
|
// Note: Defer clearing the dirty rectangle here because we will get cleared
|
||||||
// rectangle on the canvas.
|
// rectangle on the canvas.
|
||||||
}
|
}
|
||||||
|
@ -254,9 +272,14 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mDrawsGestureFloatingPreviewText) {
|
if (mDrawsGestureFloatingPreviewText) {
|
||||||
canvas.translate(mKeyboardViewOriginX, mKeyboardViewOriginY);
|
canvas.translate(originX, originY);
|
||||||
drawGestureFloatingPreviewText(canvas, mGestureFloatingPreviewText);
|
drawGestureFloatingPreviewText(canvas, mGestureFloatingPreviewText);
|
||||||
canvas.translate(-mKeyboardViewOriginX, -mKeyboardViewOriginY);
|
canvas.translate(-originX, -originY);
|
||||||
|
}
|
||||||
|
if (mShowSlidingKeyInputPreview) {
|
||||||
|
canvas.translate(originX, originY);
|
||||||
|
drawSlidingKeyInputPreview(canvas);
|
||||||
|
canvas.translate(-originX, -originY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,8 +340,6 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
|
|
||||||
final Paint paint = mTextPaint;
|
final Paint paint = mTextPaint;
|
||||||
final RectF rectangle = mGestureFloatingPreviewRectangle;
|
final RectF rectangle = mGestureFloatingPreviewRectangle;
|
||||||
// TODO: Figure out how we should deal with the floating preview text with multiple moving
|
|
||||||
// fingers.
|
|
||||||
|
|
||||||
// Paint the round rectangle background.
|
// Paint the round rectangle background.
|
||||||
final int textHeight = mGestureFloatingPreviewTextHeight;
|
final int textHeight = mGestureFloatingPreviewTextHeight;
|
||||||
|
@ -328,9 +349,11 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
final float rectWidth = textWidth + hPad * 2.0f;
|
final float rectWidth = textWidth + hPad * 2.0f;
|
||||||
final float rectHeight = textHeight + vPad * 2.0f;
|
final float rectHeight = textHeight + vPad * 2.0f;
|
||||||
final int canvasWidth = canvas.getWidth();
|
final int canvasWidth = canvas.getWidth();
|
||||||
final float rectX = Math.min(Math.max(mLastPointerX - rectWidth / 2.0f, 0.0f),
|
final float rectX = Math.min(
|
||||||
|
Math.max(CoordinateUtils.x(mLastPointerCoords) - rectWidth / 2.0f, 0.0f),
|
||||||
canvasWidth - rectWidth);
|
canvasWidth - rectWidth);
|
||||||
final float rectY = mLastPointerY - mGestureFloatingPreviewTextOffset - rectHeight;
|
final float rectY = CoordinateUtils.y(mLastPointerCoords)
|
||||||
|
- mGestureFloatingPreviewTextOffset - rectHeight;
|
||||||
rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight);
|
rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight);
|
||||||
final float round = mGestureFloatingPreviewRoundRadius;
|
final float round = mGestureFloatingPreviewRoundRadius;
|
||||||
paint.setColor(mGestureFloatingPreviewColor);
|
paint.setColor(mGestureFloatingPreviewColor);
|
||||||
|
@ -341,4 +364,8 @@ public final class PreviewPlacerView extends RelativeLayout {
|
||||||
final float textY = rectY + vPad + textHeight;
|
final float textY = rectY + vPad + textHeight;
|
||||||
canvas.drawText(gestureFloatingPreviewText, textX, textY, paint);
|
canvas.drawText(gestureFloatingPreviewText, textX, textY, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void drawSlidingKeyInputPreview(final Canvas canvas) {
|
||||||
|
// TODO: Implement rubber band preview
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,4 +36,14 @@ public final class CoordinateUtils {
|
||||||
public static int y(final int[] coords) {
|
public static int y(final int[] coords) {
|
||||||
return coords[INDEX_Y];
|
return coords[INDEX_Y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void set(final int[] coords, final int x, final int y) {
|
||||||
|
coords[INDEX_X] = x;
|
||||||
|
coords[INDEX_Y] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copy(final int[] destination, final int[] source) {
|
||||||
|
destination[INDEX_X] = source[INDEX_X];
|
||||||
|
destination[INDEX_Y] = source[INDEX_Y];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1177,6 +1177,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
|
||||||
|
|
||||||
private boolean maybeDoubleSpace() {
|
private boolean maybeDoubleSpace() {
|
||||||
if (!mCurrentSettings.mCorrectionEnabled) return false;
|
if (!mCurrentSettings.mCorrectionEnabled) return false;
|
||||||
|
if (!mCurrentSettings.mUseDoubleSpacePeriod) return false;
|
||||||
if (!mHandler.isAcceptingDoubleSpaces()) return false;
|
if (!mHandler.isAcceptingDoubleSpaces()) return false;
|
||||||
final CharSequence lastThree = mConnection.getTextBeforeCursor(3, 0);
|
final CharSequence lastThree = mConnection.getTextBeforeCursor(3, 0);
|
||||||
if (lastThree != null && lastThree.length() == 3
|
if (lastThree != null && lastThree.length() == 3
|
||||||
|
|
|
@ -60,6 +60,8 @@ public final class Settings extends InputMethodSettingsFragment
|
||||||
"last_user_dictionary_write_time";
|
"last_user_dictionary_write_time";
|
||||||
public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
|
public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
|
||||||
public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
|
public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
|
||||||
|
public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD =
|
||||||
|
"pref_key_use_double_space_period";
|
||||||
public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY =
|
public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY =
|
||||||
"pref_show_language_switch_key";
|
"pref_show_language_switch_key";
|
||||||
public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
|
public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
|
||||||
|
|
|
@ -75,6 +75,7 @@ public final class SettingsValues {
|
||||||
@SuppressWarnings("unused") // TODO: Use this
|
@SuppressWarnings("unused") // TODO: Use this
|
||||||
private final String mKeyPreviewPopupDismissDelayRawValue;
|
private final String mKeyPreviewPopupDismissDelayRawValue;
|
||||||
public final boolean mUseContactsDict;
|
public final boolean mUseContactsDict;
|
||||||
|
public final boolean mUseDoubleSpacePeriod;
|
||||||
// Use bigrams to predict the next word when there is no input for it yet
|
// Use bigrams to predict the next word when there is no input for it yet
|
||||||
public final boolean mBigramPredictionEnabled;
|
public final boolean mBigramPredictionEnabled;
|
||||||
@SuppressWarnings("unused") // TODO: Use this
|
@SuppressWarnings("unused") // TODO: Use this
|
||||||
|
@ -154,6 +155,7 @@ public final class SettingsValues {
|
||||||
Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
|
Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
|
||||||
Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout)));
|
Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout)));
|
||||||
mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
|
mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
|
||||||
|
mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true);
|
||||||
mAutoCorrectEnabled = isAutoCorrectEnabled(res, mAutoCorrectionThresholdRawValue);
|
mAutoCorrectEnabled = isAutoCorrectEnabled(res, mAutoCorrectionThresholdRawValue);
|
||||||
mBigramPredictionEnabled = isBigramPredictionEnabled(prefs, res);
|
mBigramPredictionEnabled = isBigramPredictionEnabled(prefs, res);
|
||||||
mVibrationDurationSettingsRawValue =
|
mVibrationDurationSettingsRawValue =
|
||||||
|
|
|
@ -438,15 +438,23 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
|
||||||
if (!Character.isUpperCase(text.codePointAt(0))) return CAPITALIZE_NONE;
|
if (!Character.isUpperCase(text.codePointAt(0))) return CAPITALIZE_NONE;
|
||||||
final int len = text.length();
|
final int len = text.length();
|
||||||
int capsCount = 1;
|
int capsCount = 1;
|
||||||
|
int letterCount = 1;
|
||||||
for (int i = 1; i < len; i = text.offsetByCodePoints(i, 1)) {
|
for (int i = 1; i < len; i = text.offsetByCodePoints(i, 1)) {
|
||||||
if (1 != capsCount && i != capsCount) break;
|
if (1 != capsCount && letterCount != capsCount) break;
|
||||||
if (Character.isUpperCase(text.codePointAt(i))) ++capsCount;
|
final int codePoint = text.codePointAt(i);
|
||||||
|
if (Character.isUpperCase(codePoint)) {
|
||||||
|
++capsCount;
|
||||||
|
++letterCount;
|
||||||
|
} else if (Character.isLetter(codePoint)) {
|
||||||
|
// We need to discount non-letters since they may not be upper-case, but may
|
||||||
|
// still be part of a word (e.g. single quote or dash, as in "IT'S" or "FULL-TIME")
|
||||||
|
++letterCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// We know the first char is upper case. So we want to test if either everything
|
// We know the first char is upper case. So we want to test if either every letter other
|
||||||
// else is lower case, or if everything else is upper case. If the string is
|
// than the first is lower case, or if they are all upper case. If the string is exactly
|
||||||
// exactly one char long, then we will arrive here with capsCount 1, and this is
|
// one char long, then we will arrive here with letterCount 1, and this is correct, too.
|
||||||
// correct, too.
|
|
||||||
if (1 == capsCount) return CAPITALIZE_FIRST;
|
if (1 == capsCount) return CAPITALIZE_FIRST;
|
||||||
return (len == capsCount ? CAPITALIZE_ALL : CAPITALIZE_NONE);
|
return (letterCount == capsCount ? CAPITALIZE_ALL : CAPITALIZE_NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,11 @@ import android.view.textservice.TextInfo;
|
||||||
|
|
||||||
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
|
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
|
||||||
import com.android.inputmethod.latin.Constants;
|
import com.android.inputmethod.latin.Constants;
|
||||||
|
import com.android.inputmethod.latin.Dictionary;
|
||||||
import com.android.inputmethod.latin.LocaleUtils;
|
import com.android.inputmethod.latin.LocaleUtils;
|
||||||
import com.android.inputmethod.latin.WordComposer;
|
import com.android.inputmethod.latin.StringUtils;
|
||||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||||
|
import com.android.inputmethod.latin.WordComposer;
|
||||||
import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer;
|
import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -188,6 +190,35 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
|
||||||
return (letterCount * 4 < length * 3);
|
return (letterCount * 4 < length * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to test valid capitalizations of a word.
|
||||||
|
*
|
||||||
|
* If the "text" is lower-case, we test only the exact string.
|
||||||
|
* If the "Text" is capitalized, we test the exact string "Text" and the lower-cased
|
||||||
|
* version of it "text".
|
||||||
|
* If the "TEXT" is fully upper case, we test the exact string "TEXT", the lower-cased
|
||||||
|
* version of it "text" and the capitalized version of it "Text".
|
||||||
|
*/
|
||||||
|
private boolean isInDictForAnyCapitalization(final Dictionary dict, final String text,
|
||||||
|
final int capitalizeType) {
|
||||||
|
// If the word is in there as is, then it's in the dictionary. If not, we'll test lower
|
||||||
|
// case versions, but only if the word is not already all-lower case or mixed case.
|
||||||
|
if (dict.isValidWord(text)) return true;
|
||||||
|
if (AndroidSpellCheckerService.CAPITALIZE_NONE == capitalizeType) return false;
|
||||||
|
|
||||||
|
// If we come here, we have a capitalized word (either First- or All-).
|
||||||
|
// Downcase the word and look it up again. If the word is only capitalized, we
|
||||||
|
// tested all possibilities, so if it's still negative we can return false.
|
||||||
|
final String lowerCaseText = text.toLowerCase(mLocale);
|
||||||
|
if (dict.isValidWord(lowerCaseText)) return true;
|
||||||
|
if (AndroidSpellCheckerService.CAPITALIZE_FIRST == capitalizeType) return false;
|
||||||
|
|
||||||
|
// If the lower case version is not in the dictionary, it's still possible
|
||||||
|
// that we have an all-caps version of a word that needs to be capitalized
|
||||||
|
// according to the dictionary. E.g. "GERMANS" only exists in the dictionary as "Germans".
|
||||||
|
return dict.isValidWord(StringUtils.toTitleCase(lowerCaseText, mLocale));
|
||||||
|
}
|
||||||
|
|
||||||
// Note : this must be reentrant
|
// Note : this must be reentrant
|
||||||
/**
|
/**
|
||||||
* Gets a list of suggestions for a specific string. This returns a list of possible
|
* Gets a list of suggestions for a specific string. This returns a list of possible
|
||||||
|
@ -272,13 +303,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
|
||||||
suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
|
suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
|
||||||
suggestionStr.length(), suggestion.mScore);
|
suggestionStr.length(), suggestion.mScore);
|
||||||
}
|
}
|
||||||
isInDict = dictInfo.mDictionary.isValidWord(text);
|
isInDict = isInDictForAnyCapitalization(dictInfo.mDictionary, text, capitalizeType);
|
||||||
if (!isInDict && AndroidSpellCheckerService.CAPITALIZE_NONE != capitalizeType) {
|
|
||||||
// We want to test the word again if it's all caps or first caps only.
|
|
||||||
// If it's fully down, we already tested it, if it's mixed case, we don't
|
|
||||||
// want to test a lowercase version of it.
|
|
||||||
isInDict = dictInfo.mDictionary.isValidWord(text.toLowerCase(mLocale));
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
if (null != dictInfo) {
|
if (null != dictInfo) {
|
||||||
if (!mDictionaryPool.offer(dictInfo)) {
|
if (!mDictionaryPool.offer(dictInfo)) {
|
||||||
|
|
|
@ -925,18 +925,20 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
public static void latinIME_onWindowHidden(final int savedSelectionStart,
|
public static void latinIME_onWindowHidden(final int savedSelectionStart,
|
||||||
final int savedSelectionEnd, final InputConnection ic) {
|
final int savedSelectionEnd, final InputConnection ic) {
|
||||||
if (ic != null) {
|
if (ic != null) {
|
||||||
// Capture the TextView contents. This will trigger onUpdateSelection(), so we
|
|
||||||
// set sLatinIMEExpectingUpdateSelection so that when onUpdateSelection() is called,
|
|
||||||
// it can tell that it was generated by the logging code, and not by the user, and
|
|
||||||
// therefore keep user-visible state as is.
|
|
||||||
ic.beginBatchEdit();
|
|
||||||
ic.performContextMenuAction(android.R.id.selectAll);
|
|
||||||
CharSequence charSequence = ic.getSelectedText(0);
|
|
||||||
ic.setSelection(savedSelectionStart, savedSelectionEnd);
|
|
||||||
ic.endBatchEdit();
|
|
||||||
sLatinIMEExpectingUpdateSelection = true;
|
|
||||||
final Object[] values = new Object[2];
|
final Object[] values = new Object[2];
|
||||||
if (OUTPUT_ENTIRE_BUFFER) {
|
if (OUTPUT_ENTIRE_BUFFER) {
|
||||||
|
// Capture the TextView contents. This will trigger onUpdateSelection(), so we
|
||||||
|
// set sLatinIMEExpectingUpdateSelection so that when onUpdateSelection() is called,
|
||||||
|
// it can tell that it was generated by the logging code, and not by the user, and
|
||||||
|
// therefore keep user-visible state as is.
|
||||||
|
ic.beginBatchEdit();
|
||||||
|
ic.performContextMenuAction(android.R.id.selectAll);
|
||||||
|
CharSequence charSequence = ic.getSelectedText(0);
|
||||||
|
if (savedSelectionStart != -1 && savedSelectionEnd != -1) {
|
||||||
|
ic.setSelection(savedSelectionStart, savedSelectionEnd);
|
||||||
|
}
|
||||||
|
ic.endBatchEdit();
|
||||||
|
sLatinIMEExpectingUpdateSelection = true;
|
||||||
if (TextUtils.isEmpty(charSequence)) {
|
if (TextUtils.isEmpty(charSequence)) {
|
||||||
values[0] = false;
|
values[0] = false;
|
||||||
values[1] = "";
|
values[1] = "";
|
||||||
|
|
|
@ -21,23 +21,23 @@ namespace latinime {
|
||||||
// TODO: Have proximity character informations in each language's binary dictionary.
|
// TODO: Have proximity character informations in each language's binary dictionary.
|
||||||
const char *AdditionalProximityChars::LOCALE_EN_US = "en";
|
const char *AdditionalProximityChars::LOCALE_EN_US = "en";
|
||||||
|
|
||||||
const int32_t AdditionalProximityChars::EN_US_ADDITIONAL_A[EN_US_ADDITIONAL_A_SIZE] = {
|
const int AdditionalProximityChars::EN_US_ADDITIONAL_A[EN_US_ADDITIONAL_A_SIZE] = {
|
||||||
'e', 'i', 'o', 'u'
|
'e', 'i', 'o', 'u'
|
||||||
};
|
};
|
||||||
|
|
||||||
const int32_t AdditionalProximityChars::EN_US_ADDITIONAL_E[EN_US_ADDITIONAL_E_SIZE] = {
|
const int AdditionalProximityChars::EN_US_ADDITIONAL_E[EN_US_ADDITIONAL_E_SIZE] = {
|
||||||
'a', 'i', 'o', 'u'
|
'a', 'i', 'o', 'u'
|
||||||
};
|
};
|
||||||
|
|
||||||
const int32_t AdditionalProximityChars::EN_US_ADDITIONAL_I[EN_US_ADDITIONAL_I_SIZE] = {
|
const int AdditionalProximityChars::EN_US_ADDITIONAL_I[EN_US_ADDITIONAL_I_SIZE] = {
|
||||||
'a', 'e', 'o', 'u'
|
'a', 'e', 'o', 'u'
|
||||||
};
|
};
|
||||||
|
|
||||||
const int32_t AdditionalProximityChars::EN_US_ADDITIONAL_O[EN_US_ADDITIONAL_O_SIZE] = {
|
const int AdditionalProximityChars::EN_US_ADDITIONAL_O[EN_US_ADDITIONAL_O_SIZE] = {
|
||||||
'a', 'e', 'i', 'u'
|
'a', 'e', 'i', 'u'
|
||||||
};
|
};
|
||||||
|
|
||||||
const int32_t AdditionalProximityChars::EN_US_ADDITIONAL_U[EN_US_ADDITIONAL_U_SIZE] = {
|
const int AdditionalProximityChars::EN_US_ADDITIONAL_U[EN_US_ADDITIONAL_U_SIZE] = {
|
||||||
'a', 'e', 'i', 'o'
|
'a', 'e', 'i', 'o'
|
||||||
};
|
};
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#define LATINIME_ADDITIONAL_PROXIMITY_CHARS_H
|
#define LATINIME_ADDITIONAL_PROXIMITY_CHARS_H
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
|
@ -29,15 +28,15 @@ class AdditionalProximityChars {
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AdditionalProximityChars);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(AdditionalProximityChars);
|
||||||
static const char *LOCALE_EN_US;
|
static const char *LOCALE_EN_US;
|
||||||
static const int EN_US_ADDITIONAL_A_SIZE = 4;
|
static const int EN_US_ADDITIONAL_A_SIZE = 4;
|
||||||
static const int32_t EN_US_ADDITIONAL_A[];
|
static const int EN_US_ADDITIONAL_A[];
|
||||||
static const int EN_US_ADDITIONAL_E_SIZE = 4;
|
static const int EN_US_ADDITIONAL_E_SIZE = 4;
|
||||||
static const int32_t EN_US_ADDITIONAL_E[];
|
static const int EN_US_ADDITIONAL_E[];
|
||||||
static const int EN_US_ADDITIONAL_I_SIZE = 4;
|
static const int EN_US_ADDITIONAL_I_SIZE = 4;
|
||||||
static const int32_t EN_US_ADDITIONAL_I[];
|
static const int EN_US_ADDITIONAL_I[];
|
||||||
static const int EN_US_ADDITIONAL_O_SIZE = 4;
|
static const int EN_US_ADDITIONAL_O_SIZE = 4;
|
||||||
static const int32_t EN_US_ADDITIONAL_O[];
|
static const int EN_US_ADDITIONAL_O[];
|
||||||
static const int EN_US_ADDITIONAL_U_SIZE = 4;
|
static const int EN_US_ADDITIONAL_U_SIZE = 4;
|
||||||
static const int32_t EN_US_ADDITIONAL_U[];
|
static const int EN_US_ADDITIONAL_U[];
|
||||||
|
|
||||||
AK_FORCE_INLINE static bool isEnLocale(const char *localeStr) {
|
AK_FORCE_INLINE static bool isEnLocale(const char *localeStr) {
|
||||||
const size_t LOCALE_EN_US_SIZE = strlen(LOCALE_EN_US);
|
const size_t LOCALE_EN_US_SIZE = strlen(LOCALE_EN_US);
|
||||||
|
@ -46,7 +45,7 @@ class AdditionalProximityChars {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static int getAdditionalCharsSize(const char *localeStr, const int32_t c) {
|
static int getAdditionalCharsSize(const char *localeStr, const int c) {
|
||||||
if (!isEnLocale(localeStr)) {
|
if (!isEnLocale(localeStr)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +65,7 @@ class AdditionalProximityChars {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int32_t *getAdditionalChars(const char *localeStr, const int32_t c) {
|
static const int *getAdditionalChars(const char *localeStr, const int c) {
|
||||||
if (!isEnLocale(localeStr)) {
|
if (!isEnLocale(localeStr)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,8 @@ int BigramDictionary::getBigrams(const int *prevWord, int prevWordLength, int *i
|
||||||
|
|
||||||
// Returns a pointer to the start of the bigram list.
|
// Returns a pointer to the start of the bigram list.
|
||||||
// If the word is not found or has no bigrams, this function returns 0.
|
// If the word is not found or has no bigrams, this function returns 0.
|
||||||
int BigramDictionary::getBigramListPositionForWord(const int32_t *prevWord,
|
int BigramDictionary::getBigramListPositionForWord(const int *prevWord, const int prevWordLength,
|
||||||
const int prevWordLength, const bool forceLowerCaseSearch) const {
|
const bool forceLowerCaseSearch) const {
|
||||||
if (0 >= prevWordLength) return 0;
|
if (0 >= prevWordLength) return 0;
|
||||||
const uint8_t *const root = DICT;
|
const uint8_t *const root = DICT;
|
||||||
int pos = BinaryFormat::getTerminalPosition(root, prevWord, prevWordLength,
|
int pos = BinaryFormat::getTerminalPosition(root, prevWord, prevWordLength,
|
||||||
|
@ -167,7 +167,7 @@ int BigramDictionary::getBigramListPositionForWord(const int32_t *prevWord,
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigramDictionary::fillBigramAddressToFrequencyMapAndFilter(const int32_t *prevWord,
|
void BigramDictionary::fillBigramAddressToFrequencyMapAndFilter(const int *prevWord,
|
||||||
const int prevWordLength, std::map<int, int> *map, uint8_t *filter) const {
|
const int prevWordLength, std::map<int, int> *map, uint8_t *filter) const {
|
||||||
memset(filter, 0, BIGRAM_FILTER_BYTE_SIZE);
|
memset(filter, 0, BIGRAM_FILTER_BYTE_SIZE);
|
||||||
const uint8_t *const root = DICT;
|
const uint8_t *const root = DICT;
|
||||||
|
@ -207,7 +207,7 @@ bool BigramDictionary::checkFirstCharacter(int *word, int *inputCodes) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BigramDictionary::isValidBigram(const int32_t *word1, int length1, const int32_t *word2,
|
bool BigramDictionary::isValidBigram(const int *word1, int length1, const int *word2,
|
||||||
int length2) const {
|
int length2) const {
|
||||||
const uint8_t *const root = DICT;
|
const uint8_t *const root = DICT;
|
||||||
int pos = getBigramListPositionForWord(word1, length1, false /* forceLowerCaseSearch */);
|
int pos = getBigramListPositionForWord(word1, length1, false /* forceLowerCaseSearch */);
|
||||||
|
|
|
@ -201,7 +201,6 @@ inline void BinaryFormat::readHeaderValue(const uint8_t *const dict, const char
|
||||||
outValue[outValueIndex++] = codePoint;
|
outValue[outValueIndex++] = codePoint;
|
||||||
codePoint = getCodePointAndForwardPointer(dict, &index);
|
codePoint = getCodePointAndForwardPointer(dict, &index);
|
||||||
}
|
}
|
||||||
if (outValueIndex < outValueIndex) outValue[outValueIndex] = 0;
|
|
||||||
// Finished copying. Break to go to the termination code.
|
// Finished copying. Break to go to the termination code.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -219,7 +218,6 @@ inline void BinaryFormat::readHeaderValue(const uint8_t *const dict, const char
|
||||||
// Put a terminator 0 if possible at all (always unless outValueSize is <= 0)
|
// Put a terminator 0 if possible at all (always unless outValueSize is <= 0)
|
||||||
if (outValueIndex >= outValueSize) outValueIndex = outValueSize - 1;
|
if (outValueIndex >= outValueSize) outValueIndex = outValueSize - 1;
|
||||||
if (outValueIndex >= 0) outValue[outValueIndex] = 0;
|
if (outValueIndex >= 0) outValue[outValueIndex] = 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int BinaryFormat::readHeaderValueInt(const uint8_t *const dict, const char *const key) {
|
inline int BinaryFormat::readHeaderValueInt(const uint8_t *const dict, const char *const key) {
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
// TODO: Change the type of all keyCodes to uint32_t
|
|
||||||
Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int maxWordLength,
|
Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int maxWordLength,
|
||||||
int maxWords, int maxPredictions)
|
int maxWords, int maxPredictions)
|
||||||
: mDict(static_cast<unsigned char *>(dict)),
|
: mDict(static_cast<unsigned char *>(dict)),
|
||||||
|
@ -81,19 +80,18 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, void *traverseSessi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Dictionary::getBigrams(const int32_t *word, int length, int *codes, int codesSize,
|
int Dictionary::getBigrams(const int *word, int length, int *codes, int codesSize,
|
||||||
int *outWords, int *frequencies, int *outputTypes) const {
|
int *outWords, int *frequencies, int *outputTypes) const {
|
||||||
if (length <= 0) return 0;
|
if (length <= 0) return 0;
|
||||||
return mBigramDictionary->getBigrams(word, length, codes, codesSize, outWords, frequencies,
|
return mBigramDictionary->getBigrams(word, length, codes, codesSize, outWords, frequencies,
|
||||||
outputTypes);
|
outputTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Dictionary::getFrequency(const int32_t *word, int length) const {
|
int Dictionary::getFrequency(const int *word, int length) const {
|
||||||
return mUnigramDictionary->getFrequency(word, length);
|
return mUnigramDictionary->getFrequency(word, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dictionary::isValidBigram(const int32_t *word1, int length1, const int32_t *word2,
|
bool Dictionary::isValidBigram(const int *word1, int length1, const int *word2, int length2) const {
|
||||||
int length2) const {
|
|
||||||
return mBigramDictionary->isValidBigram(word1, length1, word2, length2);
|
return mBigramDictionary->isValidBigram(word1, length1, word2, length2);
|
||||||
}
|
}
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
|
|
|
@ -50,11 +50,11 @@ class Dictionary {
|
||||||
bool useFullEditDistance, int *outWords, int *frequencies, int *spaceIndices,
|
bool useFullEditDistance, int *outWords, int *frequencies, int *spaceIndices,
|
||||||
int *outputTypes) const;
|
int *outputTypes) const;
|
||||||
|
|
||||||
int getBigrams(const int32_t *word, int length, int *codes, int codesSize, int *outWords,
|
int getBigrams(const int *word, int length, int *codes, int codesSize, int *outWords,
|
||||||
int *frequencies, int *outputTypes) const;
|
int *frequencies, int *outputTypes) const;
|
||||||
|
|
||||||
int getFrequency(const int32_t *word, int length) const;
|
int getFrequency(const int *word, int length) const;
|
||||||
bool isValidBigram(const int32_t *word1, int length1, const int32_t *word2, int length2) const;
|
bool isValidBigram(const int *word1, int length1, const int *word2, int length2) const;
|
||||||
const uint8_t *getDict() const { // required to release dictionary buffer
|
const uint8_t *getDict() const { // required to release dictionary buffer
|
||||||
return mDict;
|
return mDict;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr, const int ma
|
||||||
HAS_TOUCH_POSITION_CORRECTION_DATA(keyCount > 0 && keyXCoordinates && keyYCoordinates
|
HAS_TOUCH_POSITION_CORRECTION_DATA(keyCount > 0 && keyXCoordinates && keyYCoordinates
|
||||||
&& keyWidths && keyHeights && keyCharCodes && sweetSpotCenterXs
|
&& keyWidths && keyHeights && keyCharCodes && sweetSpotCenterXs
|
||||||
&& sweetSpotCenterYs && sweetSpotRadii),
|
&& sweetSpotCenterYs && sweetSpotRadii),
|
||||||
mProximityCharsArray(new int32_t[GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE
|
mProximityCharsArray(new int[GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE
|
||||||
/* proximityGridLength */]),
|
/* proximityGridLength */]),
|
||||||
mCodeToKeyMap() {
|
mCodeToKeyMap() {
|
||||||
const int proximityGridLength = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
|
const int proximityGridLength = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
|
||||||
|
@ -115,7 +115,7 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
|
||||||
if (DEBUG_PROXIMITY_INFO) {
|
if (DEBUG_PROXIMITY_INFO) {
|
||||||
AKLOGI("hasSpaceProximity: index %d, %d, %d", startIndex, x, y);
|
AKLOGI("hasSpaceProximity: index %d, %d, %d", startIndex, x, y);
|
||||||
}
|
}
|
||||||
int32_t *proximityCharsArray = mProximityCharsArray;
|
int *proximityCharsArray = mProximityCharsArray;
|
||||||
for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
|
for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
|
||||||
if (DEBUG_PROXIMITY_INFO) {
|
if (DEBUG_PROXIMITY_INFO) {
|
||||||
AKLOGI("Index: %d", mProximityCharsArray[startIndex + i]);
|
AKLOGI("Index: %d", mProximityCharsArray[startIndex + i]);
|
||||||
|
@ -163,14 +163,14 @@ int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProximityInfo::calculateNearbyKeyCodes(
|
void ProximityInfo::calculateNearbyKeyCodes(
|
||||||
const int x, const int y, const int32_t primaryKey, int *inputCodes) const {
|
const int x, const int y, const int primaryKey, int *inputCodes) const {
|
||||||
int32_t *proximityCharsArray = mProximityCharsArray;
|
int *proximityCharsArray = mProximityCharsArray;
|
||||||
int insertPos = 0;
|
int insertPos = 0;
|
||||||
inputCodes[insertPos++] = primaryKey;
|
inputCodes[insertPos++] = primaryKey;
|
||||||
const int startIndex = getStartIndexFromCoordinates(x, y);
|
const int startIndex = getStartIndexFromCoordinates(x, y);
|
||||||
if (startIndex >= 0) {
|
if (startIndex >= 0) {
|
||||||
for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
|
for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
|
||||||
const int32_t c = proximityCharsArray[startIndex + i];
|
const int c = proximityCharsArray[startIndex + i];
|
||||||
if (c < KEYCODE_SPACE || c == primaryKey) {
|
if (c < KEYCODE_SPACE || c == primaryKey) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -198,13 +198,13 @@ void ProximityInfo::calculateNearbyKeyCodes(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int32_t *additionalProximityChars =
|
const int *additionalProximityChars =
|
||||||
AdditionalProximityChars::getAdditionalChars(mLocaleStr, primaryKey);
|
AdditionalProximityChars::getAdditionalChars(mLocaleStr, primaryKey);
|
||||||
for (int j = 0; j < additionalProximitySize; ++j) {
|
for (int j = 0; j < additionalProximitySize; ++j) {
|
||||||
const int32_t ac = additionalProximityChars[j];
|
const int ac = additionalProximityChars[j];
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for (; k < insertPos; ++k) {
|
for (; k < insertPos; ++k) {
|
||||||
if (static_cast<int>(ac) == inputCodes[k]) {
|
if (ac == inputCodes[k]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ int ProximityInfo::getKeyIndexOf(const int c) const {
|
||||||
if (c == NOT_A_CODE_POINT) {
|
if (c == NOT_A_CODE_POINT) {
|
||||||
return NOT_AN_INDEX;
|
return NOT_AN_INDEX;
|
||||||
}
|
}
|
||||||
const int lowerCode = static_cast<int>(toLowerCase(c));
|
const int lowerCode = toLowerCase(c);
|
||||||
hash_map_compat<int, int>::const_iterator mapPos = mCodeToKeyMap.find(lowerCode);
|
hash_map_compat<int, int>::const_iterator mapPos = mCodeToKeyMap.find(lowerCode);
|
||||||
if (mapPos != mCodeToKeyMap.end()) {
|
if (mapPos != mCodeToKeyMap.end()) {
|
||||||
return mapPos->second;
|
return mapPos->second;
|
||||||
|
@ -254,7 +254,7 @@ void ProximityInfo::initializeG() {
|
||||||
// TODO: Optimize
|
// TODO: Optimize
|
||||||
for (int i = 0; i < KEY_COUNT; ++i) {
|
for (int i = 0; i < KEY_COUNT; ++i) {
|
||||||
const int code = mKeyCodePoints[i];
|
const int code = mKeyCodePoints[i];
|
||||||
const int lowerCode = static_cast<int>(toLowerCase(code));
|
const int lowerCode = toLowerCase(code);
|
||||||
mCenterXsG[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2;
|
mCenterXsG[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2;
|
||||||
mCenterYsG[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2;
|
mCenterYsG[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2;
|
||||||
mCodeToKeyMap[lowerCode] = i;
|
mCodeToKeyMap[lowerCode] = i;
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
#ifndef LATINIME_PROXIMITY_INFO_H
|
#ifndef LATINIME_PROXIMITY_INFO_H
|
||||||
#define LATINIME_PROXIMITY_INFO_H
|
#define LATINIME_PROXIMITY_INFO_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "hash_map_compat.h"
|
#include "hash_map_compat.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
@ -59,7 +57,7 @@ class ProximityInfo {
|
||||||
return mSweetSpotCenterYs[keyIndex];
|
return mSweetSpotCenterYs[keyIndex];
|
||||||
}
|
}
|
||||||
void calculateNearbyKeyCodes(
|
void calculateNearbyKeyCodes(
|
||||||
const int x, const int y, const int32_t primaryKey, int *inputCodes) const;
|
const int x, const int y, const int primaryKey, int *inputCodes) const;
|
||||||
|
|
||||||
bool hasTouchPositionCorrectionData() const {
|
bool hasTouchPositionCorrectionData() const {
|
||||||
return HAS_TOUCH_POSITION_CORRECTION_DATA;
|
return HAS_TOUCH_POSITION_CORRECTION_DATA;
|
||||||
|
@ -141,12 +139,12 @@ class ProximityInfo {
|
||||||
const int KEYBOARD_HEIGHT;
|
const int KEYBOARD_HEIGHT;
|
||||||
const bool HAS_TOUCH_POSITION_CORRECTION_DATA;
|
const bool HAS_TOUCH_POSITION_CORRECTION_DATA;
|
||||||
char mLocaleStr[MAX_LOCALE_STRING_LENGTH];
|
char mLocaleStr[MAX_LOCALE_STRING_LENGTH];
|
||||||
int32_t *mProximityCharsArray;
|
int *mProximityCharsArray;
|
||||||
int32_t mKeyXCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
int mKeyXCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
int32_t mKeyYCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
int mKeyYCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
int32_t mKeyWidths[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
int mKeyWidths[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
int32_t mKeyHeights[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
int mKeyHeights[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
int32_t mKeyCodePoints[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
int mKeyCodePoints[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
float mSweetSpotCenterXs[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
float mSweetSpotCenterXs[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
float mSweetSpotCenterYs[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
float mSweetSpotCenterYs[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
|
|
Loading…
Reference in New Issue