Support keys that have uncommon width.
Bug: 8591918 Change-Id: I1e01e1560200333f9e35993af0aa7e5a17e6944fmain
parent
1ff81e8890
commit
0052dbda76
|
@ -134,24 +134,13 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
|
|||
}
|
||||
|
||||
float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloatG(
|
||||
const int keyId, const int x, const int y, const float verticalScale) const {
|
||||
const bool correctTouchPosition = hasTouchPositionCorrectionData();
|
||||
const float centerX = static_cast<float>(correctTouchPosition ? getSweetSpotCenterXAt(keyId)
|
||||
: getKeyCenterXOfKeyIdG(keyId));
|
||||
const float visualKeyCenterY = static_cast<float>(getKeyCenterYOfKeyIdG(keyId));
|
||||
float centerY;
|
||||
if (correctTouchPosition) {
|
||||
const float sweetSpotCenterY = static_cast<float>(getSweetSpotCenterYAt(keyId));
|
||||
const float gapY = sweetSpotCenterY - visualKeyCenterY;
|
||||
centerY = visualKeyCenterY + gapY * verticalScale;
|
||||
} else {
|
||||
centerY = visualKeyCenterY;
|
||||
}
|
||||
const int keyId, const int x, const int y, const bool isGeometric) const {
|
||||
const float centerX = static_cast<float>(getKeyCenterXOfKeyIdG(keyId, x, isGeometric));
|
||||
const float centerY = static_cast<float>(getKeyCenterYOfKeyIdG(keyId, y, isGeometric));
|
||||
const float touchX = static_cast<float>(x);
|
||||
const float touchY = static_cast<float>(y);
|
||||
const float keyWidth = static_cast<float>(getMostCommonKeyWidth());
|
||||
return ProximityInfoUtils::getSquaredDistanceFloat(centerX, centerY, touchX, touchY)
|
||||
/ GeometryUtils::SQUARE_FLOAT(keyWidth);
|
||||
/ GeometryUtils::SQUARE_FLOAT(static_cast<float>(getMostCommonKeyWidth()));
|
||||
}
|
||||
|
||||
int ProximityInfo::getCodePointOf(const int keyIndex) const {
|
||||
|
@ -168,41 +157,80 @@ void ProximityInfo::initializeG() {
|
|||
const int lowerCode = CharUtils::toLowerCase(code);
|
||||
mCenterXsG[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2;
|
||||
mCenterYsG[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2;
|
||||
if (hasTouchPositionCorrectionData()) {
|
||||
// Computes sweet spot center points for geometric input.
|
||||
const float verticalScale = ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE_G;
|
||||
const float sweetSpotCenterY = static_cast<float>(mSweetSpotCenterYs[i]);
|
||||
const float gapY = sweetSpotCenterY - mCenterYsG[i];
|
||||
mSweetSpotCenterYsG[i] = static_cast<int>(mCenterYsG[i] + gapY * verticalScale);
|
||||
}
|
||||
mCodeToKeyMap[lowerCode] = i;
|
||||
mKeyIndexToCodePointG[i] = lowerCode;
|
||||
}
|
||||
for (int i = 0; i < KEY_COUNT; i++) {
|
||||
mKeyKeyDistancesG[i][i] = 0;
|
||||
for (int j = i + 1; j < KEY_COUNT; j++) {
|
||||
if (hasTouchPositionCorrectionData()) {
|
||||
// Computes distances using sweet spots if they exist.
|
||||
// We have two types of Y coordinate sweet spots, for geometric and for the others.
|
||||
// The sweet spots for geometric input are used for calculating key-key distances
|
||||
// here.
|
||||
mKeyKeyDistancesG[i][j] = GeometryUtils::getDistanceInt(
|
||||
mSweetSpotCenterXs[i], mSweetSpotCenterYsG[i],
|
||||
mSweetSpotCenterXs[j], mSweetSpotCenterYsG[j]);
|
||||
} else {
|
||||
mKeyKeyDistancesG[i][j] = GeometryUtils::getDistanceInt(
|
||||
mCenterXsG[i], mCenterYsG[i], mCenterXsG[j], mCenterYsG[j]);
|
||||
}
|
||||
mKeyKeyDistancesG[j][i] = mKeyKeyDistancesG[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ProximityInfo::getKeyCenterXOfCodePointG(int charCode) const {
|
||||
return getKeyCenterXOfKeyIdG(
|
||||
ProximityInfoUtils::getKeyIndexOf(KEY_COUNT, charCode, &mCodeToKeyMap));
|
||||
}
|
||||
|
||||
int ProximityInfo::getKeyCenterYOfCodePointG(int charCode) const {
|
||||
return getKeyCenterYOfKeyIdG(
|
||||
ProximityInfoUtils::getKeyIndexOf(KEY_COUNT, charCode, &mCodeToKeyMap));
|
||||
}
|
||||
|
||||
int ProximityInfo::getKeyCenterXOfKeyIdG(int keyId) const {
|
||||
if (keyId >= 0) {
|
||||
return mCenterXsG[keyId];
|
||||
}
|
||||
// referencePointX is used only for keys wider than most common key width. When the referencePointX
|
||||
// is NOT_A_COORDINATE, this method calculates the return value without using the line segment.
|
||||
// isGeometric is currently not used because we don't have extra X coordinates sweet spots for
|
||||
// geometric input.
|
||||
int ProximityInfo::getKeyCenterXOfKeyIdG(
|
||||
const int keyId, const int referencePointX, const bool isGeometric) const {
|
||||
if (keyId < 0) {
|
||||
return 0;
|
||||
}
|
||||
int centerX = (hasTouchPositionCorrectionData()) ? static_cast<int>(mSweetSpotCenterXs[keyId])
|
||||
: mCenterXsG[keyId];
|
||||
const int keyWidth = mKeyWidths[keyId];
|
||||
if (referencePointX != NOT_A_COORDINATE
|
||||
&& keyWidth > getMostCommonKeyWidth()) {
|
||||
// For keys wider than most common keys, we use a line segment instead of the center point;
|
||||
// thus, centerX is adjusted depending on referencePointX.
|
||||
const int keyWidthHalfDiff = (keyWidth - getMostCommonKeyWidth()) / 2;
|
||||
if (referencePointX < centerX - keyWidthHalfDiff) {
|
||||
centerX -= keyWidthHalfDiff;
|
||||
} else if (referencePointX > centerX + keyWidthHalfDiff) {
|
||||
centerX += keyWidthHalfDiff;
|
||||
} else {
|
||||
centerX = referencePointX;
|
||||
}
|
||||
}
|
||||
return centerX;
|
||||
}
|
||||
|
||||
int ProximityInfo::getKeyCenterYOfKeyIdG(int keyId) const {
|
||||
if (keyId >= 0) {
|
||||
// referencePointY is currently not used because we don't specially handle keys higher than the
|
||||
// most common key height. When the referencePointY is NOT_A_COORDINATE, this method should
|
||||
// calculate the return value without using the line segment.
|
||||
int ProximityInfo::getKeyCenterYOfKeyIdG(
|
||||
const int keyId, const int referencePointY, const bool isGeometric) const {
|
||||
// TODO: Remove "isGeometric" and have separate "proximity_info"s for gesture and typing.
|
||||
if (keyId < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (!hasTouchPositionCorrectionData()) {
|
||||
return mCenterYsG[keyId];
|
||||
} else if (isGeometric) {
|
||||
return static_cast<int>(mSweetSpotCenterYsG[keyId]);
|
||||
} else {
|
||||
return static_cast<int>(mSweetSpotCenterYs[keyId]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ProximityInfo::getKeyKeyDistanceG(const int keyId0, const int keyId1) const {
|
||||
|
|
|
@ -37,8 +37,7 @@ class ProximityInfo {
|
|||
bool hasSpaceProximity(const int x, const int y) const;
|
||||
int getNormalizedSquaredDistance(const int inputIndex, const int proximityIndex) const;
|
||||
float getNormalizedSquaredDistanceFromCenterFloatG(
|
||||
const int keyId, const int x, const int y,
|
||||
const float verticalScale) const;
|
||||
const int keyId, const int x, const int y, const bool isGeometric) const;
|
||||
int getCodePointOf(const int keyIndex) const;
|
||||
bool hasSweetSpotData(const int keyIndex) const {
|
||||
// When there are no calibration data for a key,
|
||||
|
@ -65,10 +64,10 @@ class ProximityInfo {
|
|||
int getKeyboardHeight() const { return KEYBOARD_HEIGHT; }
|
||||
float getKeyboardHypotenuse() const { return KEYBOARD_HYPOTENUSE; }
|
||||
|
||||
int getKeyCenterXOfCodePointG(int charCode) const;
|
||||
int getKeyCenterYOfCodePointG(int charCode) const;
|
||||
int getKeyCenterXOfKeyIdG(int keyId) const;
|
||||
int getKeyCenterYOfKeyIdG(int keyId) const;
|
||||
int getKeyCenterXOfKeyIdG(
|
||||
const int keyId, const int referencePointX, const bool isGeometric) const;
|
||||
int getKeyCenterYOfKeyIdG(
|
||||
const int keyId, const int referencePointY, const bool isGeometric) const;
|
||||
int getKeyKeyDistanceG(int keyId0, int keyId1) const;
|
||||
|
||||
AK_FORCE_INLINE void initializeProximities(const int *const inputCodes,
|
||||
|
@ -115,6 +114,8 @@ class ProximityInfo {
|
|||
int mKeyCodePoints[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||
float mSweetSpotCenterXs[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||
float mSweetSpotCenterYs[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||
// Sweet spots for geometric input. Note that we have extra sweet spots only for Y coordinates.
|
||||
float mSweetSpotCenterYsG[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||
float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||
hash_map_compat<int, int> mCodeToKeyMap;
|
||||
|
||||
|
|
|
@ -97,15 +97,10 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
|
|||
pushTouchPointStartIndex, lastSavedInputSize);
|
||||
}
|
||||
|
||||
// TODO: Remove the dependency of "isGeometric"
|
||||
const float verticalSweetSpotScale = isGeometric
|
||||
? ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE_G
|
||||
: ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE;
|
||||
|
||||
if (xCoordinates && yCoordinates) {
|
||||
mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(mProximityInfo,
|
||||
mMaxPointToKeyLength, mInputProximities, xCoordinates, yCoordinates, times,
|
||||
pointerIds, verticalSweetSpotScale, inputSize, isGeometric, pointerId,
|
||||
pointerIds, inputSize, isGeometric, pointerId,
|
||||
pushTouchPointStartIndex, &mSampledInputXs, &mSampledInputYs, &mSampledTimes,
|
||||
&mSampledLengthCache, &mSampledInputIndice);
|
||||
}
|
||||
|
@ -123,7 +118,7 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
|
|||
|
||||
if (mSampledInputSize > 0) {
|
||||
ProximityInfoStateUtils::initGeometricDistanceInfos(mProximityInfo, mSampledInputSize,
|
||||
lastSavedInputSize, verticalSweetSpotScale, &mSampledInputXs, &mSampledInputYs,
|
||||
lastSavedInputSize, isGeometric, &mSampledInputXs, &mSampledInputYs,
|
||||
&mSampledNearKeySets, &mSampledNormalizedSquaredLengthCache);
|
||||
if (isGeometric) {
|
||||
// updates probabilities of skipping or mapping each key for all points.
|
||||
|
|
|
@ -43,8 +43,8 @@ namespace latinime {
|
|||
const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
|
||||
const int *const inputProximities, const int *const inputXCoordinates,
|
||||
const int *const inputYCoordinates, const int *const times, const int *const pointerIds,
|
||||
const float verticalSweetSpotScale, const int inputSize, const bool isGeometric,
|
||||
const int pointerId, const int pushTouchPointStartIndex, std::vector<int> *sampledInputXs,
|
||||
const int inputSize, const bool isGeometric, const int pointerId,
|
||||
const int pushTouchPointStartIndex, std::vector<int> *sampledInputXs,
|
||||
std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
|
||||
std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice) {
|
||||
if (DEBUG_SAMPLING_POINTS) {
|
||||
|
@ -113,7 +113,7 @@ namespace latinime {
|
|||
}
|
||||
|
||||
if (pushTouchPoint(proximityInfo, maxPointToKeyLength, i, c, x, y, time,
|
||||
verticalSweetSpotScale, isGeometric /* doSampling */, i == lastInputIndex,
|
||||
isGeometric, isGeometric /* doSampling */, i == lastInputIndex,
|
||||
sumAngle, currentNearKeysDistances, prevNearKeysDistances,
|
||||
prevPrevNearKeysDistances, sampledInputXs, sampledInputYs, sampledInputTimes,
|
||||
sampledLengthCache, sampledInputIndice)) {
|
||||
|
@ -183,7 +183,7 @@ namespace latinime {
|
|||
|
||||
/* static */ void ProximityInfoStateUtils::initGeometricDistanceInfos(
|
||||
const ProximityInfo *const proximityInfo, const int sampledInputSize,
|
||||
const int lastSavedInputSize, const float verticalSweetSpotScale,
|
||||
const int lastSavedInputSize, const bool isGeometric,
|
||||
const std::vector<int> *const sampledInputXs,
|
||||
const std::vector<int> *const sampledInputYs,
|
||||
std::vector<NearKeycodesSet> *sampledNearKeySets,
|
||||
|
@ -199,7 +199,7 @@ namespace latinime {
|
|||
const int y = (*sampledInputYs)[i];
|
||||
const float normalizedSquaredDistance =
|
||||
proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(
|
||||
k, x, y, verticalSweetSpotScale);
|
||||
k, x, y, isGeometric);
|
||||
(*sampledNormalizedSquaredLengthCache)[index] = normalizedSquaredDistance;
|
||||
if (normalizedSquaredDistance
|
||||
< ProximityInfoParams::NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) {
|
||||
|
@ -317,14 +317,13 @@ namespace latinime {
|
|||
// the given point and the nearest key position.
|
||||
/* static */ float ProximityInfoStateUtils::updateNearKeysDistances(
|
||||
const ProximityInfo *const proximityInfo, const float maxPointToKeyLength, const int x,
|
||||
const int y, const float verticalSweetspotScale,
|
||||
NearKeysDistanceMap *const currentNearKeysDistances) {
|
||||
const int y, const bool isGeometric, NearKeysDistanceMap *const currentNearKeysDistances) {
|
||||
currentNearKeysDistances->clear();
|
||||
const int keyCount = proximityInfo->getKeyCount();
|
||||
float nearestKeyDistance = maxPointToKeyLength;
|
||||
for (int k = 0; k < keyCount; ++k) {
|
||||
const float dist = proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y,
|
||||
verticalSweetspotScale);
|
||||
isGeometric);
|
||||
if (dist < ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_DISTANCE) {
|
||||
currentNearKeysDistances->insert(std::pair<int, float>(k, dist));
|
||||
}
|
||||
|
@ -405,7 +404,7 @@ namespace latinime {
|
|||
// Returning if previous point is popped or not.
|
||||
/* static */ bool ProximityInfoStateUtils::pushTouchPoint(const ProximityInfo *const proximityInfo,
|
||||
const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x, int y,
|
||||
const int time, const float verticalSweetSpotScale, const bool doSampling,
|
||||
const int time, const bool isGeometric, const bool doSampling,
|
||||
const bool isLastPoint, const float sumAngle,
|
||||
NearKeysDistanceMap *const currentNearKeysDistances,
|
||||
const NearKeysDistanceMap *const prevNearKeysDistances,
|
||||
|
@ -419,7 +418,7 @@ namespace latinime {
|
|||
bool popped = false;
|
||||
if (nodeCodePoint < 0 && doSampling) {
|
||||
const float nearest = updateNearKeysDistances(proximityInfo, maxPointToKeyLength, x, y,
|
||||
verticalSweetSpotScale, currentNearKeysDistances);
|
||||
isGeometric, currentNearKeysDistances);
|
||||
const float score = getPointScore(mostCommonKeyWidth, x, y, time, isLastPoint, nearest,
|
||||
sumAngle, currentNearKeysDistances, prevNearKeysDistances,
|
||||
prevPrevNearKeysDistances, sampledInputXs, sampledInputYs);
|
||||
|
@ -453,8 +452,8 @@ namespace latinime {
|
|||
if (nodeCodePoint >= 0 && (x < 0 || y < 0)) {
|
||||
const int keyId = proximityInfo->getKeyIndexOf(nodeCodePoint);
|
||||
if (keyId >= 0) {
|
||||
x = proximityInfo->getKeyCenterXOfKeyIdG(keyId);
|
||||
y = proximityInfo->getKeyCenterYOfKeyIdG(keyId);
|
||||
x = proximityInfo->getKeyCenterXOfKeyIdG(keyId, NOT_AN_INDEX, isGeometric);
|
||||
y = proximityInfo->getKeyCenterYOfKeyIdG(keyId, NOT_AN_INDEX, isGeometric);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,8 +38,7 @@ class ProximityInfoStateUtils {
|
|||
static int updateTouchPoints(const ProximityInfo *const proximityInfo,
|
||||
const int maxPointToKeyLength, const int *const inputProximities,
|
||||
const int *const inputXCoordinates, const int *const inputYCoordinates,
|
||||
const int *const times, const int *const pointerIds,
|
||||
const float verticalSweetSpotScale, const int inputSize,
|
||||
const int *const times, const int *const pointerIds, const int inputSize,
|
||||
const bool isGeometric, const int pointerId, const int pushTouchPointStartIndex,
|
||||
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
|
||||
std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
|
||||
|
@ -84,8 +83,7 @@ class ProximityInfoStateUtils {
|
|||
const std::vector<float> *const sampledNormalizedSquaredLengthCache, const int keyCount,
|
||||
const int inputIndex, const int keyId);
|
||||
static void initGeometricDistanceInfos(const ProximityInfo *const proximityInfo,
|
||||
const int sampledInputSize, const int lastSavedInputSize,
|
||||
const float verticalSweetSpotScale,
|
||||
const int sampledInputSize, const int lastSavedInputSize, const bool isGeometric,
|
||||
const std::vector<int> *const sampledInputXs,
|
||||
const std::vector<int> *const sampledInputYs,
|
||||
std::vector<NearKeycodesSet> *sampledNearKeySets,
|
||||
|
@ -120,7 +118,7 @@ class ProximityInfoStateUtils {
|
|||
|
||||
static float updateNearKeysDistances(const ProximityInfo *const proximityInfo,
|
||||
const float maxPointToKeyLength, const int x, const int y,
|
||||
const float verticalSweetSpotScale,
|
||||
const bool isGeometric,
|
||||
NearKeysDistanceMap *const currentNearKeysDistances);
|
||||
static bool isPrevLocalMin(const NearKeysDistanceMap *const currentNearKeysDistances,
|
||||
const NearKeysDistanceMap *const prevNearKeysDistances,
|
||||
|
@ -133,7 +131,7 @@ class ProximityInfoStateUtils {
|
|||
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs);
|
||||
static bool pushTouchPoint(const ProximityInfo *const proximityInfo,
|
||||
const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x,
|
||||
int y, const int time, const float verticalSweetSpotScale,
|
||||
int y, const int time, const bool isGeometric,
|
||||
const bool doSampling, const bool isLastPoint,
|
||||
const float sumAngle, NearKeysDistanceMap *const currentNearKeysDistances,
|
||||
const NearKeysDistanceMap *const prevNearKeysDistances,
|
||||
|
|
Loading…
Reference in New Issue