📄 imehandwrite.c
字号:
/*************************************************************************/
/* */
/* Copyright (C) 2004 SHENZHEN MEIJIN CO.LTD */
/* */
/* FILE NAME: ImeHandWrite.c */
/* MODULE NAME: 手写输入法 */
/* DESCRIPTION: 输入法 */
/*http://f.ddxdd.net/Html/bl/14560642.html */
/*************************************************************************/
/* DTAE AUTHOR VERSION REMARKS */
/* =========== ========== ========= ===================================*/
/* 2007-09-24 LiangRuhui Ver 1.00 create */
/*************************************************************************/
#include "Kernel.h"
#include "ImeIn.h"
#include "Global.h"
#include "hw.h"
#define HW_ACT_IDLE 0
#define HW_ACT_WRITING 1
#define HW_ACT_STROKEEND 2
#define HW_ACT_FULLEND 3
#define CM_HW_BUFFER_OK 101
#define CM_HW_RECOGNIZED 102
#define CM_HW_ASSOCIATION 103
#define CM_HW_REFRESH 104
#define HW_USERFONT_MAX 800 //手写字最大内存空间
#define HW_RECOGNIZE_BUFLEN (12 * 1024 + 1000)
#define HW_STROKE_MAX 120 //最多笔迹数
#define HW_STROKE_BUFLEN (HW_STROKE_MAX * 2 * sizeof(DOT))
#define HW_STENO_BUFLEN (HW_USERFONT_MAX + SIGN_SIZE)
#define HW_NEAR_FILTER 2 //定义点过滤距离
#define HW_FAR_FILTER 4
#define HW_CANDI_NUM 10
#define HW_CANDI_BUFLEN (HW_CANDI_NUM * 2 + 2)
#define HW_OUT_BUFLEN (sizeof(MEdExtraCharHead) + HW_CANDI_BUFLEN)
#define HW_SCREEN_WIDTH 128 //笔点区域宽
#define HW_SCREEN_HEIGHT 64 //笔点区域高
#define HW_CURSOR_PX 0 //笔点点击偏移坐标
#define HW_CURSOR_PY 325 //笔点点击偏移坐标
#define HW_IME_CHINESE 0
#define HW_IME_ENGLISH 3
#define HW_IME_NUMBER 1
#define HW_IME_SYMBOL 2
#define HW_INPUTBOX_TOTAL 9
#define NOTHING -1
#define HW_INPUTBOX_HANDWRITE -2
#define HW_INPUTBOX_CHARSELECTED -3
#define HW_INPUTBOX_BACKSPACE -4
#define HW_INPUTBOX_SPACE -5
#define HW_INPUTBOX_ENTER -6
#define HW_INPUTBOX_CHINESE -7
#define HW_INPUTBOX_NUMBER -8
#define HW_INPUTBOX_SYMBOL -9
#define HW_INPUTBOX_ENGLISH -10
#ifdef _WIN32
#define DOT UINT8
#define SIGN_SIZE 2
#else
#define DOT UINT16
#define SIGN_SIZE 4
#endif
typedef struct{
INT type;
MRect rect;
}HWRect;
typedef struct{
UINT8 szHwAction; //输入框状态
UINT8 szHwType; //识别类型
HTIMER hHwTimer; //手写计时时钟
HWRect inputBox[9]; //手写输入框及功能框
DOT *pHwStroke; //手写笔迹点暂存区
UINT16 wHwStroke; //记录一笔画中的笔迹点的个数
UINT16 wHwLastX; //记忆最后的手写点的坐标
UINT16 wHwLastY; //记忆最后的手写点的坐标
UINT16 wHwDotSize; //手写输入的点的大小
UINT8 *pHwStenoBuf; //手写笔迹数据区
UINT8 *pHwOutBuf; //消息传递用数据区
UINT8 *pHwBuffer; //识别函数输入数据区
UINT16 wHwRange; //手写识别范围
NU_SEMAPHORE hHwSemaph; //
}HWMANAGEDATA;
HWMANAGEDATA g_hwManageData;
INT g_nPressedKey;
/*************************************************************************/
/* FUNCTION: HwToStenoBuffer */
/* DESCRIPTION:过滤掉相隔太近的点 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/*************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ===========================================*/
/* LiangRuhui 2007-09-26 创建初始版本 */
/*************************************************************************/
BOOL HwFiltDot(int x, INT y)
{
UINT16 wDistX, wDistY;
if (x > g_hwManageData.wHwLastX)
wDistX = x - g_hwManageData.wHwLastX;
else
wDistX = g_hwManageData.wHwLastX - x;
if (y > g_hwManageData.wHwLastY)
wDistY = y - g_hwManageData.wHwLastY;
else
wDistY = g_hwManageData.wHwLastY - y;
if (wDistX > HW_FAR_FILTER || wDistY > HW_FAR_FILTER){
return FALSE;
}
if (wDistX < HW_NEAR_FILTER || wDistY < HW_NEAR_FILTER){
return TRUE;
}
return FALSE;
}
/*************************************************************************/
/* FUNCTION: HwToStenoBuffer */
/* DESCRIPTION:画点 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/*************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ===========================================*/
/* LiangRuhui 2007-09-26 创建初始版本 */
/*************************************************************************/
VOID HwDrawDot(INT x, INT y)
{
g_hwManageData.wHwLastX = x;
g_hwManageData.wHwLastX = y;
if (g_hwManageData.wHwDotSize == 1) {
GraphDrawDot(x, y);
}
else {
GraphFillRect(x, y,
x + g_hwManageData.wHwDotSize - 1, y + g_hwManageData.wHwDotSize - 1);
}
}
/*************************************************************************/
/* FUNCTION: HwToStenoBuffer */
/* DESCRIPTION:画线 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/*************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ===========================================*/
/* LiangRuhui 2007-09-26 创建初始版本 */
/*************************************************************************/
BOOL HwDrawLine(INT x, INT y)
{
if (HwFiltDot(x, y))
return FALSE;
GraphDrawLine(g_hwManageData.wHwLastX, g_hwManageData.wHwLastY, x, y);
g_hwManageData.wHwLastX = x;
g_hwManageData.wHwLastY = y;
return TRUE;
}
VOID HwClearBox(INT whichBox)
{
MRect *pRect;
pRect = (MRect *)&g_hwManageData.inputBox[whichBox];
GraphClearRect(pRect->x, pRect->y,
pRect->x + pRect->width - 1, pRect->y + pRect->height - 1);
}
/*************************************************************************/
/* FUNCTION: HwToStenoBuffer */
/* DESCRIPTION:将笔点写入笔迹缓冲区 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/*************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ===========================================*/
/* LiangRuhui 2007-09-26 创建初始版本 */
/*************************************************************************/
VOID HwStrokeToBuffer(int x, int y)
{
g_hwManageData.pHwStroke[g_hwManageData.wHwStroke*2] = (DOT)x;
g_hwManageData.pHwStroke[g_hwManageData.wHwStroke*2 + 1] = (DOT)y;
g_hwManageData.wHwStroke++;
}
/*************************************************************************/
/* FUNCTION: HwToStenoBuffer */
/* DESCRIPTION:输入一个新的笔点 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/*************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ===========================================*/
/* LiangRuhui 2007-09-26 创建初始版本 */
/*************************************************************************/
VOID HwNewStroke(int x, int y)
{
TimerStopTimer(g_hwManageData.hHwTimer);
g_hwManageData.szHwAction = HW_ACT_WRITING;
g_hwManageData.wHwStroke = 0;
HwDrawDot(x, y);
HwStrokeToBuffer(x, y);
}
/*************************************************************************/
/* FUNCTION: HwToStenoBuffer */
/* DESCRIPTION:继续输入笔迹点 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/*************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ===========================================*/
/* LiangRuhui 2007-09-26 创建初始版本 */
/*************************************************************************/
VOID HwInputStroke(INT x, INT y)
{
if (g_hwManageData.wHwStroke >= HW_STROKE_MAX) {
return;
}
if (HwDrawLine(x, y)) {
HwStrokeToBuffer(x, y);
}
}
/*************************************************************************/
/* FUNCTION: HwToStenoBuffer */
/* DESCRIPTION:将笔迹数据写入对应的缓冲区 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/*************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ===========================================*/
/* LiangRuhui 2007-09-25 创建初始版本 */
/*************************************************************************/
VOID HwToStenoBuffer(UINT16 wStrokeNum)
{
UINT8 *pTemp;
UINT16 wOldLen, wTemp;
wTemp = wStrokeNum * 2 * sizeof(DOT);
pTemp = g_hwManageData.pHwStenoBuf;
wOldLen = *(UINT32*)pTemp + 4;
if ((wOldLen + wTemp + SIGN_SIZE) <= (HW_USERFONT_MAX - SIGN_SIZE))
{
memmove(&pTemp[wOldLen], g_hwManageData.pHwStroke, wTemp);
wOldLen += wTemp;
#ifdef _WIN32
*(UINT16*)&pTemp[wOldLen] = 0xFF; //写一笔的结束标志
wOldLen += 2;
*(UINT16*)pTemp = wOldLen - 4;
*(UINT16*)&pTemp[wOldLen] = 0xFFFF; //写笔迹结束标志
#else
*(UINT32*)&pTemp[wOldLen] = 0xFFFF; //写一笔的结束标志
wOldLen += 4;
*(UINT32*)pTemp = wOldLen - 4;
*(UINT32*)&pTemp[wOldLen] = 0xFFFFFFFF;//写笔迹结束标志
#endif
}
}
/*************************************************************************/
/* FUNCTION: _HandWriteHandleEvent */
/* DESCRIPTION:手写输入法笔点点击事件处理函数 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/*************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ===========================================*/
/* LiangRuhui 2007-09-25 创建初始版本 */
/*************************************************************************/
UINT32 _HWHandlePenEvent(UINT *pEvent,UINT *pParam)
{
#if 1
UINT32 dwMsgX, dwMsgY;
INT i,nPressedKey;
BOOL bClearMsg;
bClearMsg = FALSE;
dwMsgX = *pParam&0xFFFF - HW_CURSOR_PX;
dwMsgY = *pParam>>16 - HW_CURSOR_PY;
if (!DotInArea(dwMsgX, dwMsgY, 0, 0, HW_SCREEN_WIDTH, HW_SCREEN_HEIGHT))
{
g_nPressedKey = NOTHING;
return 0;
}
for(i = 0;i < HW_INPUTBOX_TOTAL;i++){
if (DotInArea(dwMsgX, dwMsgY,
g_hwManageData.inputBox[i].rect.x, g_hwManageData.inputBox[i].rect.y,
g_hwManageData.inputBox[i].rect.width, g_hwManageData.inputBox[i].rect.height))
{
break;
}
}
if(i == HW_INPUTBOX_TOTAL){
g_nPressedKey = NOTHING;
return 0;
}
nPressedKey = g_hwManageData.inputBox[i].type;
if (*pEvent == EVENT_PENDOWN)
{
g_nPressedKey = g_hwManageData.inputBox[i].type;
switch(g_nPressedKey) {
case HW_INPUTBOX_HANDWRITE:
break;
case HW_INPUTBOX_CHARSELECTED:
break;
case HW_INPUTBOX_BACKSPACE:
case HW_INPUTBOX_SPACE:
case HW_INPUTBOX_ENTER:
case HW_INPUTBOX_CHINESE:
case HW_INPUTBOX_NUMBER:
case HW_INPUTBOX_SYMBOL:
case HW_INPUTBOX_ENGLISH:{
GraphInvertRect(g_hwManageData.inputBox[i].rect.x,g_hwManageData.inputBox[i].rect.y,
g_hwManageData.inputBox[i].rect.width,g_hwManageData.inputBox[i].rect.height);
break;
}
default:
break;
}
bClearMsg = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -