📄 rthread.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
rthread.c
Abstract:
Recognization thread.
--*/
#include "multibox.h"
#include "recog.h"
static DWORD dwMask;
static TCHAR v_prevChar;
static HRC hrcActive; // HRC used for doing recognition.
static int giSent; // How many characters we have already sent.
static int bDirty; // True if there is ink to process.
static int viNumb; // TRUE if we're doing NUMLOCK style returns
// We want the box to be as close to 1000x1000 as possible. So scaling everything by 12 should do nicely.
static HWXGUIDE v_guide =
{
256, // cHorzBox
1, // cVertBox
0, // xOrigin
0, // yOrigin
BOX_SIZE * 12, // cxBox
BOX_SIZE * 12, // cyBox
BOX_OFFSET * 12, // cxOffset
BOX_OFFSET * 12, // cyOffset
BOX_WRITING_AREA * 12, // cxWriting
BOX_WRITING_AREA * 12, // cyWriting
0, // cyMid
0, // cyBase
HWX_HORIZONTAL // nDir
};
int giHalf; // TRUE if we're returning half width characters from recognizer
// Local functions
BOOL HandleThreadMsg(MSG *);
HWXRESULTPRI *GetCandidates(HWXRESULTS *);
BOOL GetContextChar(TCHAR chUnicode, WCHAR *pchDBCS);
void GetCharacters(int iSentAlready, int iReady);
DWORD WINAPI RecogThreadFn(LPVOID pArg)
{
MSG msg;
int count;
int status;
// No error checking for now
status = HwxConfig();
// Now we are sitting in our message loop to wait for
// the message sent by the main thread
do
{
if (!bDirty)
{
GetMessage(&msg, NULL, 0, 0);
}
else
{
if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
bDirty = FALSE;
HwxProcess(hrcActive);
count = 0; // count = HwxResultsAvailable(hrcActive);
//RETAILMSG(TRUE, (TEXT("No Msg Available %d giSent %d\n"), count, giSent));
if (count > giSent)
{
GetCharacters(giSent, count);
giSent = count;
}
continue;
}
}
HandleThreadMsg(&msg);
} while (msg.message != THRDMSG_EXIT);
return 0;
}
// This is all used to get into HWX to read the scores. We really, really, really need an API for this.
#define MAX_ALT_LIST 20
typedef struct tagALT_LIST
{
UINT cAlt; // Count of valid alternatives
float aeScore[MAX_ALT_LIST]; // Scores for each alternatives
wchar_t awchList[MAX_ALT_LIST]; // List of alternatives
} ALT_LIST;
// The PATHNODE is stored in the GLYPHSYM, but used by the PATH code. Very strange
typedef struct tagPATHNODE
{
float pathcost; // cummulative path cost including this node
BYTE indexPrev; // index in the prev GLYPHSYM of the previous node in this path
BYTE state; // state of the automaton for uppercase/lowercase/numeric context
} PATHNODE;
// GLYPHSYM object abstract data type
typedef struct tagGLYPHSYM
{
ALT_LIST altlist; // The best guesses from the shape matcher
DWORD status; // GSST status values (above)
int iBox; // Box number in the GUIDE
void *glyph; // digested ink associated with these guesses
RECT rect; // bounding rect of ink in the glyph(s)
DWORD syvBestPath; // What the syv is on the best path by context.
int iBegin; // index of the first frame in the glyph
int iEnd; // index of the last frame in the glyph
int cFrame; // number of frames in the glyph
int iLayer; // layer index in SINFO
void *prev; // previous glyphsym
PATHNODE rgPathnode[MAX_ALT_LIST];
char rgReferenced[MAX_ALT_LIST];
} GLYPHSYM;
typedef struct tagXRC
{
// These fields used to be in the PATHSRCH object
int cLayer; // number of layers (boxes) processed so far
int cResult;
int cResultBuf;
// For partial character recognition and aborting any recognition
int nPartial; // What type of completion should we do?
DWORD cstrkRaw; // Unprocessed stroke count
DWORD *pdwAbort; // Abort address
// These fields used to be in the SINFO object
BOOL fUpdate; // True when event (ink / EndOfInk) occurs that makes
// us need to try classifying dirty glyphsyms.
int ixBox; // boxed input: index of last ixBox in GUIDE
int iyBox; // boxed input: index of last iyBox in GUIDE
int cPntLastFrame; // number of points in the last frame processed
int cFrame; // number of frames processed
int cQueue; // number of queue elements
int cQueueMax; // size of the queue
GLYPHSYM **ppQueue; // Array of Glyphsyms.
} XRC;
int HackScoreFromHwx(HRC hrc, DWORD i)
{
XRC *xrc = (XRC *) hrc;
if ((xrc->ppQueue) && (xrc->ppQueue[0]))
return i < xrc->ppQueue[0]->altlist.cAlt ? (int) ((-65536.0 * xrc->ppQueue[0]->altlist.aeScore[i]) / 10.0) : 0;
else
return 0;
}
HWXRESULTPRI *GetCandidates(HWXRESULTS *pbox)
{
HWXRESULTPRI *pResult;
int i;
pResult = (HWXRESULTPRI *) LocalAlloc(LPTR, sizeof(HWXRESULTPRI));
if (!pResult)
return NULL;
for (i = 0; i < HWXPAD_NUM_CANDIDATES; i++)
{
//RETAILMSG(TRUE, (TEXT("GetCandidates %x\n"), pbox->rgSyv[i] & 0x0000ffff));
if (pbox->rgChar[i])
{
pResult->awchAlts[i] = (wchar_t) pbox->rgChar[i];
pResult->anScore[i] = HackScoreFromHwx(hrcActive, i);
}
else
break;
}
pResult->cbCount = i;
pResult->iSelection = 0;
return pResult;
}
#define HW 1
#define FW 2
#define DAKUTEN 4
#define HANDAKUTEN 8
#define DT (FW | DAKUTEN)
#define HDT (FW | HANDAKUTEN)
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
static BYTE vafRoma[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0000 - 0x000f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0010 - 0x001f
0, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, // 0x0020 - 0x002f
HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, // 0x0030 - 0x003f
HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, // 0x0040 - 0x004f
HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, // 0x0050 - 0x005f
HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, // 0x0060 - 0x006f
HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, HW, 0, // 0x0070 - 0x007f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0080 - 0x008f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0090 - 0x009f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00a0 - 0x00af
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00b0 - 0x00bf
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00c0 - 0x00cf
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00d0 - 0x00df
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00e0 - 0x00ef
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x00f0 - 0x00ff
};
static BYTE vafCJK[] =
{
0, FW, FW, 0, 0, 0, 0, 0, 0, 0, 0, 0, FW, FW, 0, 0, // 0x3000 - 0x300f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3010 - 0x301f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3020 - 0x302f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3030 - 0x303f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3040 - 0x304f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3050 - 0x305f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3060 - 0x306f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3070 - 0x307f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3080 - 0x308f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FW, FW, 0, 0, 0, // 0x3090 - 0x309f
0, FW, FW, FW, FW, FW, FW, FW, FW, FW, FW, FW, DT, FW, DT, FW, // 0x30a0 - 0x30af
DT, FW, DT, FW, DT, FW, DT, FW, DT, FW, DT, FW, DT, FW, DT, FW, // 0x30b0 - 0x30bf
DT, FW, DT, FW, FW, DT, FW, DT, FW, DT, FW, FW, FW, FW, FW, FW, // 0x30c0 - 0x30cf
DT, HDT, FW, DT, HDT, FW, DT, HDT, FW, DT, HDT, FW, DT, HDT, FW, FW, // 0x30d0 - 0x30df
FW, FW, FW, FW, FW, FW, FW, FW, FW, FW, FW, FW, FW, FW, 0, FW, // 0x30e0 - 0x30ef
0, 0, FW, FW, 0, 0, 0, 0, 0, 0, 0, FW, FW, 0, 0, 0 // 0x30f0 - 0x30ff
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -