⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uiime_cj.c

📁 嵌入工linux开发的源码
💻 C
字号:
#include "uiIme_cj.h"
#include "uiCJ_Tbl.res"
#include "uisw_kbd.h"
                       

/***********************************************************************
 *
 *	Internal Constants
 *
 ***********************************************************************/
#define CHANGJIE_TABLE_SIZE       13060
#define CHANGJIE_KEY_NUMBER     	 52  	// 仓颉键盘按键个数(不含选字区及功能键)
#define CHANGJIE_KEY_INDEX_ADDRESS	 44
#define CHANGJIE_KEY_INDEX_SYMBOL	 45
#define CHANGJIE_KEY_INDEX_SPACE 	 46		// 空白键的索引
#define CHANGJIE_KEY_INDEX_BACKSPACE 10		// back space

static WORD ChangJieKey[CHANGJIE_KEY_NUMBER];/* = {
   //  1      2     3     4     5     6     7     8     9      0
    0xa2b0, 0xa2b1,0xa2b2,0xa2b3,0xa2b4,0xa2b5,0xa2b6,0xa2b7,0xa2b8, 0xa2af,KEY_BACKSPACE,

    //手  田  水  口  廿  卜  山  戈  人  心     =
      17, 23,  5, 18, 20, 25, 21,  9, 15, 16, 0xa1d7,

    //日  尸  木  火  土  竹  十  大  中     ?      Tab
       1, 19,  4,  6,  7,  8, 10, 11, 12, 0xa153, KEY_TAB,

    //重  难  金  女  月  弓  一     ;       :       !      ENTER
      26, 24,  3, 22,  2, 14, 13, 0xa146, 0xa147, 0xa154, KEY_ENTER,

    //  址      符   space      、      ,       .      。       DEL
    0x0020, 0x0020, 0x0020, 0xa142, 0xa141, 0xa145, 0xa143, KEY_DELETE
};
*/
/*
static WORD ChangJieCodeMap[27] = {
	//          日      月      金      木      水      火      土      竹      戈      十
	0x0020, 0xa4e9, 0xa4eb, 0xaaf7, 0xa4ec, 0xa4f4, 0xa4f5, 0xa467, 0xa6cb, 0xa4e0, 0xa451,
	//  大      中      一      弓      人      心      手      口      尸      廿      山
	0xa46a, 0xa4a4, 0xa440, 0xa47d, 0xa448, 0xa4df, 0xa4e2, 0xa466, 0xa472, 0xa4dc, 0xa473,
	//  女      田      难      卜      重
	0xa46b, 0xa5d0, 0xc3f8, 0xa452, 0xadab
};
*/
                           
#ifdef __WIN32__
static WORD ChangJieCodeMap[27] = {
	//          日      月      金      木      水      火      土      竹      戈      十
	0x0020, 0xe9a4, 0xeba4, 0xf7aa, 0xeca4, 0xf4a4, 0xf5a4, 0x67a4,  0xcba6, 0xe0a4, 0x51a4,
	//  大      中      一      弓      人      心      手      口      尸      廿      山
	0x6aa4, 0xa4a4, 0x40a4, 0x7da4, 0x48a4, 0xdfa4, 0xe2a4, 0x66a4, 0x72a4, 0xdca4, 0x73a4,
	//  女      田      难      卜      重
	0x6ba4, 0xd0a5, 0xf8c3, 0x52a4, 0xabad
};              
#else
static WORD ChangJieCodeMap[27] = {
	//          日      月      金      木      水      火      土      竹      戈      十
	0x2000, 0xa4e9, 0xa4eb, 0xaaf7, 0xa4ec, 0xa4f4, 0xa4f5, 0xa467,  0xa6cb, 0xa4e0, 0xa451,
	//  大      中      一      弓      人      心      手      口      尸      廿      山
	0xa46a, 0xa4a4, 0xa440, 0xa47d, 0xa448, 0xa4df, 0xa4e2, 0xa466, 0xa472, 0xa4dc, 0xa473,
	//  女      田      难      卜      重
	0xa46b, 0xa5d0, 0xc3f8, 0xa452, 0xadab
};

#endif

//static char ImeCjStrAddress[] = "县市乡镇路街段巷弄号楼";
//static char ImeCjStrSymbol[] = "!:;、。,·?  "‘'“”『』※《》";

/***********************************************************************
 *
 *	Internal Functions
 *
 ***********************************************************************/
//BOOL ImeLookupCJ(char key, char *buffer, IMM_CANDIDATE* pCdd);
static BOOL CjKeyIsCJCode(char key);
//static void CjPushCJKeyToCmp(char key, IMM_COMPOSITION* pCmp);
static void CjConvertCJCode(IMM_COMPOSITION* pCmp, IMM_CANDIDATE* pCdd);

/***********************************************
* wbStr:  code of wb                           *
* offset: offset of candidate word             *
* return: total count of candidate word        *
************************************************/
//DLL_EXP(int) guiIme_cj(char *cjStr, DWORD *offset)
int guiIme_cj(char *cjStr, unsigned short *pBig5Code)
{
	//static void CjConvertCJCode(IMM_COMPOSITION* pCmp, IMM_CANDIDATE* pCdd)

	// union for the calculate compressed code
	union
	{
		DWORD dwordData;
		BYTE  byteData[4];
	} CompressedCode;
	
	BYTE *TableEntry = (unsigned char *)ChangJieTable;
    BYTE code[2] = {0, 0}, Big5Code[2];    
	BYTE len;
 	int i, foundCnt=0;
 //	BOOL bMatch = FALSE;   

	if((cjStr[0])==0)             
		return 0;

	
	len = strlen(cjStr);

	// calculate the compressed code using key index in key buffer
	CompressedCode.dwordData = 0;
	for(i = 0; i < 5; i++)
	{
		CompressedCode.dwordData *= 27;
		//if (i < pCmp->count)
			//CompressedCode.dwordData += pCmp->buff[i];
		if (i<len)
			CompressedCode.dwordData += cjStr[i];			
	}

	// scan the table to find the matches
	for(i = 0; i < CHANGJIE_TABLE_SIZE; i++)
	{
#ifdef __WIN32__
        if(TableEntry[0] == CompressedCode.byteData[0] && TableEntry[1] == CompressedCode.byteData[1] && TableEntry[2] == CompressedCode.byteData[2]) 
		{
#else
        if(TableEntry[0] == CompressedCode.byteData[3] && TableEntry[1] == CompressedCode.byteData[2] && TableEntry[2] == CompressedCode.byteData[1]) 
		{
#endif
			WORD TableIndex = i;
			code[0] = 0xa4;
			
			if(TableIndex >= 0x1519) 
			{
				code[0] = 0xc9;
				TableIndex -= 0x1519;
			}                         

			code[0] += (BYTE)(TableIndex / 0x9d);
			code[1] = (BYTE)(TableIndex % 0x9d);

			if(code[1] < 0x3f)
				code[1] += 0x40;
			else
				code[1] += 0xa1 - 0x3f;

			// add the character to candidate
			//bMatch = TRUE;
			//ImmAddCddByPCH((char *)&code[0]);
/*#ifndef  __WIN32__
			Big5Code[0] = code[1];
			Big5Code[1] = code[0];
#else
*/
			Big5Code[0] = code[0];
			Big5Code[1] = code[1];
//#endif
			pBig5Code[foundCnt] = *(unsigned short*)Big5Code;
			foundCnt++;			
			
		}
		TableEntry += 3;
	}

	pBig5Code[foundCnt] = 0;
	return foundCnt;
}

void ConvertNumberToCode(char *numStr, unsigned short *codeStr)
{
	int i, len, number;

	len = strlen(numStr);

	for(i=0; i<len; i++)
	{
		number = numStr[i];
		codeStr[i] = ChangJieCodeMap[number] ; 
	}

	codeStr[i] = 0;

}

/******************************************************************
* offset: offset of candidate word, get from guiIme_py()          *
* totalCount: total count of candidate word, get form guiIme_py() *
* startPos: start position of word to read                        *
* toReadCount: number of word to read                             *
* pWordText: buffer of word                                       *
* return: actual number of word read                              *
*******************************************************************/
/*int guiGetCandidate_cj(DWORD offset, unsigned short totalCount, unsigned short startPos, unsigned short toReadCount, unsigned short *pWordText)
{
	unsigned short *pWord;
	int readCount, i;
	
	if(!offset)
		return 0;

	if(startPos>totalCount)
		return 0;

	pWord = (unsigned short *)(offset+2*startPos);

	readCount = (totalCount>startPos+toReadCount)?toReadCount:(totalCount-startPos);

	for(i=0; i<readCount; i++)
		pWordText[i] = pWord[i];
	
	pWordText[readCount] = 0x0000; 
	
	return readCount;
}
*/                          

int KeyIsCJCode(unsigned short key)
{

	if(key>25)
		return 0;

	return 1;
}

/***********************************************************************
 *
 * FUNCTION:     ImmAddCddByPCH
 *
 * DESCRIPTION:  interface for IME to put *Chinese* character into cdd buffer
 *
 * PARAMETERS:   pch - the pointer to character buffer that stores
 *                     the candidate chinese character
 *
 * RETURNED:     TRUE, if the character is successfully put
 *               FALSE, if the buffer is full
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *
 ***********************************************************************/

static IMM_OBJ		ImmObj;		
BOOL ImmAddCddByPCH(char* pch)
{
	// if the buffer is full, then return
	if (ImmObj.cdd.count >= MAX_CANDIDATE_COUNT)
		return FALSE;
	// add the character & increase count flag
	ImmObj.cdd.buff[ImmObj.cdd.count].b.h = pch[0];
	ImmObj.cdd.buff[ImmObj.cdd.count].b.l = pch[1];
	ImmObj.cdd.count++;
	return TRUE;
}



/***********************************************************************
 *
 * FUNCTION:     CjConvertCJCode
 *
 * DESCRIPTION:  convert the cj codes in composition into chinese characters
 *               and put them in candidate
 *
 * PARAMETERS:   pCmp - pointer to composition
 *               pCdd - pointer to candidate
 *               
 * RETURNED:     nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *
 ***********************************************************************/
static void CjConvertCJCode(IMM_COMPOSITION* pCmp, IMM_CANDIDATE* pCdd)
{
	// union for the calculate compressed code
	union
	{
		DWORD dwordData;
		BYTE  byteData[4];
	} CompressedCode;
	
	BYTE *TableEntry = (unsigned char *)ChangJieTable;
    BYTE Big5Code[2] = {0, 0};
 	int i;
 	BOOL bMatch = FALSE;   

    // if there isn't key in the buffer, then return
	if (pCmp->count == 0)
		return;

	// calculate the compressed code using key index in key buffer
	CompressedCode.dwordData = 0;
	for(i = 0; i < 5; i++)
	{
		CompressedCode.dwordData *= 27;
		if (i < pCmp->count)
			CompressedCode.dwordData += pCmp->buff[i];
	}

	// scan the table to find the matches
	for(i = 0; i < CHANGJIE_TABLE_SIZE; i++)
	{
#ifdef __WIN32__
        if(TableEntry[0] == CompressedCode.byteData[0] && TableEntry[1] == CompressedCode.byteData[1] && TableEntry[2] == CompressedCode.byteData[2]) 
		{
#else
        if(TableEntry[0] == CompressedCode.byteData[3] && TableEntry[1] == CompressedCode.byteData[2] && TableEntry[2] == CompressedCode.byteData[1]) 
		{
#endif
			WORD TableIndex = i;
			Big5Code[0] = 0xa4;
			
			if(TableIndex >= 0x1519) 
			{
				Big5Code[0] = 0xc9;
				TableIndex -= 0x1519;
			}                         

			Big5Code[0] += (BYTE)(TableIndex / 0x9d);
			Big5Code[1] = (BYTE)(TableIndex % 0x9d);

			if(Big5Code[1] < 0x3f)
				Big5Code[1] += 0x40;
			else
				Big5Code[1] += 0xa1 - 0x3f;

			// add the character to candidate
			bMatch = TRUE;
			ImmAddCddByPCH((char *)&Big5Code[0]);
			
		}
		TableEntry += 3;
	}
	// if there is no matching
	if (!bMatch)
	{
		//ImmClearCandidate();
		//ImmClearComposition();
	}
}


/***********************************************************************
 *
 * FUNCTION:     CjKeyIsCJCode
 *
 * DESCRIPTION:  if specify key is the key that represent a CJ code
 *
 * PARAMETERS:   key - specify the key
 *               
 * RETURNED:     TRUE, if given key is a CJ code key
 *               FALSE, if not
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *
 ***********************************************************************/
static BOOL CjKeyIsCJCode(char key)
{
	if (key <= 10)
		return FALSE;
	if (key == CHANGJIE_KEY_INDEX_BACKSPACE)
		return FALSE;
	if (key == 31 || key == 32)
		return FALSE;
	if (key >= 40 && key <= 45)
		return FALSE;
	if (key >= 47 && key <= 51)
		return FALSE;

	return TRUE;
}



/***********************************************************************
 *
 * FUNCTION:     CjPushCJKeyToCmp
 *
 * DESCRIPTION:  add cj code into composition
 *
 * PARAMETERS:   key - the pressed key
 *               pCmp - pointer to composition
 *               
 * RETURNED:     nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *
 ***********************************************************************/
/*static void CjPushCJKeyToCmp(char key, IMM_COMPOSITION* pCmp)
{
	// if the cmp buffer is full, return
	if (pCmp->count >= 5)
		return;

	pCmp->buff[pCmp->count] = ChangJieKey[key];
    pCmp->count++;
}*/       // by zhang xue ping 


/***********************************************************************
 *
 * FUNCTION:     ImmAddCddByWord
 *
 * DESCRIPTION:  interface for IME to put character into cdd buffer
 *
 * PARAMETERS:   w - a WORD that stores the candidate chinese character 
 *
 * RETURNED:     TRUE, if the character is successfully put
 *               FALSE, if the buffer is full
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *
 ***********************************************************************/
BOOL ImmAddCddByWord(WORD w)
{
	// if the buffer is full, then return
	if (ImmObj.cdd.count >= MAX_CANDIDATE_COUNT)
		return FALSE;
	// add the character & increase count flag
	ImmObj.cdd.buff[ImmObj.cdd.count].w = w;
	ImmObj.cdd.count++;
	return TRUE;
}

/***********************************************************************
 *
 * FUNCTION:     ImeLookupCJ
 *
 * DESCRIPTION:  ChangJei IME's lookup function, responsible for converting 
 *               the composition string into candidate characters.
 *
 * PARAMETERS:   key  - the newly pressed key
 *               pCmp - pointer to composition
 *               pCdd - pointer to candidate
 *               
 * RETURNED:     TRUE, if keyboard need repaint
 *               FALSE, if keyboard need not repaint
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *
 ***********************************************************************/
/*
BOOL ImeLookupCJ(char key, char *buffer, IMM_CANDIDATE* pCdd)
{                          
	IMM_COMPOSITION* pCmp;
	unsigned char len;
    char ch[3];
    ch[2] = 0;                         

	len = strlen(buffer);
	pCmp->count = len;
	strcpy(pCmp->buff, buffer);             

	
	// 0. if key index is invalid, do nothing
	if (key == -1)
		return FALSE;
	// 1. "space", lookup the table to convert the cj code to big-5 code
	if (key == CHANGJIE_KEY_INDEX_SPACE)
	{
		if (pCmp->count == 0)
			ImmAddCddByPCH(" ");
		else
			CjConvertCJCode(pCmp, pCdd);
	}
	// 2. "backspace"
	else if (key == CHANGJIE_KEY_INDEX_BACKSPACE)
	{
		//CjRemoveCJCode(pCmp, pCdd);
	}
	// 3. "address" & "symbol"
	else if (key == CHANGJIE_KEY_INDEX_ADDRESS || key == CHANGJIE_KEY_INDEX_SYMBOL)
	{
		//CjKeyAddrSymbol(key);
	}                  
	// 4. else add the key into cmp window
	else if (CjKeyIsCJCode(key))
	{
		CjPushCJKeyToCmp(key, pCmp);
		// if up to 5 cj code, then convert
		if (pCmp->count == 5)
			CjConvertCJCode(pCmp, pCdd);
	} else {
		ImmAddCddByWord(ChangJieKey[key]);
	}

	return FALSE;
}
*/      // by zhang xue ping    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -