Text.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:31k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /*****************************************************************************************
  2. // 文字串处理
  3. // Copyright : Kingsoft 2002
  4. // Author :   Wooy(Wu yue)
  5. // CreateTime: 2002-8-31
  6. ------------------------------------------------------------------------------------------
  7. *****************************************************************************************/
  8. #include "KWin32.h"
  9. #include <string.h>
  10. #ifndef __linux
  11. #include <crtdbg.h>
  12. #else
  13. #define HRESULT long
  14. #define S_OK 0
  15. #endif
  16. #include "Text.h"
  17. #define MAX_ENCODED_CTRL_LEN 4 //单个控制符(控制标识+控制参数)的最大存储长度
  18. IInlinePicEngineSink* g_pIInlinePicSink = NULL; //嵌入式图片的处理接口[wxb 2003-6-19]
  19. extern "C" ENGINE_API HRESULT 
  20. AdviseEngine(IInlinePicEngineSink* pSink)
  21. {
  22. _ASSERT(NULL == g_pIInlinePicSink); //一般不会挂接两次
  23. g_pIInlinePicSink = pSink;
  24. return S_OK;
  25. }
  26. extern "C" ENGINE_API HRESULT 
  27. UnAdviseEngine(IInlinePicEngineSink* pSink)
  28. {
  29. if (pSink == g_pIInlinePicSink)
  30. g_pIInlinePicSink = NULL;
  31. return S_OK;
  32. }
  33. //检测某个字符是否为不许放置行首的字符
  34. #define NUM_CHARACTER_IN_A1 11
  35. unsigned char s_NotAllowAtLineHeadA1Characters[NUM_CHARACTER_IN_A1] = 
  36. {
  37.  //、。’〕〉》」』〗】
  38. 0xa2, 0xa3, 0xaf, 0xb1, 0xb3, 0xb5, 0xb7, 0xb9, 0xbb, 0xbd, 0xbf
  39. };
  40. #define NUM_CHARACTER_IN_A3 10
  41. unsigned char s_NotAllowAtLineHeadA3Characters[NUM_CHARACTER_IN_A3] = 
  42. {
  43. //!   )    ,   .     :    ;   >    ?    ]    }
  44. 0xa1, 0xa9, 0xac, 0xae, 0xba, 0xbb, 0xbe, 0xbf, 0xdd, 0xfd
  45. };
  46. #define NUM_CHARACTER_IN_00 7
  47. unsigned char s_NotAllowAtLineHead00Characters[NUM_CHARACTER_IN_00] =
  48. {
  49. //!),.:;>?
  50. 0x21, 0x29, 0x2c, /*0x2e,*/ 0x3a, 0x3b, 0x3e, 0x3f
  51. };
  52. //检测某个字符是否为不许放置行首的字符,不是限制字符则返回0,否则返回字符占的子节数
  53. extern "C" ENGINE_API
  54. int TIsCharacterNotAlowAtLineHead(const char* pCharacter)
  55. {
  56. int i;
  57. unsigned char cChar;
  58. cChar = (unsigned char)(*pCharacter);
  59. if (cChar == 0xa3)
  60. {
  61. cChar = (unsigned char)pCharacter[1];
  62. if (cChar >= 0xa1 && cChar <= 0xfd)
  63. {
  64. for (i = 0; i < NUM_CHARACTER_IN_A3; i++)
  65. if (s_NotAllowAtLineHeadA3Characters[i] == cChar)
  66. return 2;
  67. }
  68. }
  69. else if (cChar == 0xa1)
  70. {
  71. cChar = (unsigned char)pCharacter[1];
  72. if (cChar >= 0xa2 && cChar <= 0xbf)
  73. {
  74. for (i = 0; i < NUM_CHARACTER_IN_A1; i++)
  75. if (s_NotAllowAtLineHeadA1Characters[i] == cChar)
  76. return 2;
  77. }
  78. }
  79. else if (cChar >= 0x21 && cChar <= 0x3f)
  80. {
  81. for (i = 0; i < NUM_CHARACTER_IN_00; i++)
  82. if (s_NotAllowAtLineHead00Characters[i] == cChar)
  83. return 1;
  84. }
  85. return false;
  86. }
  87. //获取本行的下个显示字符
  88. extern "C" ENGINE_API
  89. const char* TGetSecondVisibleCharacterThisLine(const char* pCharacter, int nPos, int nLen)
  90. {
  91. if (pCharacter && nLen > 0)
  92. {
  93. bool bFoundFirst = false;
  94. while(nPos < nLen)
  95. {
  96. unsigned char cChar = (unsigned char)(pCharacter[nPos]);
  97. if (cChar >= 0x20)
  98. {
  99. if (bFoundFirst)
  100. return (pCharacter + nPos);
  101. bFoundFirst = true;
  102. if (cChar > 0x80)
  103. nPos += 2;
  104. else
  105. nPos ++;
  106. continue;
  107. }
  108. if (cChar == KTC_COLOR || cChar == KTC_BORDER_COLOR)
  109. nPos += 4;
  110. else if (cChar == KTC_INLINE_PIC)
  111. nPos += 1 + sizeof(WORD);
  112. else if (cChar == KTC_COLOR_RESTORE || cChar == KTC_BORDER_RESTORE)
  113. nPos++;
  114. break;
  115. };
  116. }
  117. return NULL;
  118. }
  119. //--------------------------------------------------------------------------
  120. // 功能:寻找分割字符串的合适位置
  121. // 参数:pString    --> 想要分割的字符串
  122. //  nDesirePos --> 期望分割的位置(以字节为单位)
  123. //   bLess      --> 如果期望分割的位置处于一个字符编码的中间时,结果位置
  124. // 为前靠还是后靠,0: 向后靠; 非0: 向前靠。
  125. // 注释:Chinese GBK编码版本,此字符串中字符全部视为显示字符,不包含控制字符
  126. //--------------------------------------------------------------------------
  127. extern "C" ENGINE_API
  128. int TSplitString(const char* pString, int nDesirePos, int bLess)
  129. {
  130. register int nPos = 0;
  131. if (pString)
  132. {
  133. nDesirePos -= 2;
  134. while(nPos < nDesirePos)
  135. {
  136. if ((unsigned char)pString[nPos] > 0x80)
  137. nPos += 2;
  138. else if (pString[nPos])
  139. nPos++;
  140. else
  141. break;
  142. };
  143. nDesirePos += 2;
  144. while(nPos < nDesirePos)
  145. {
  146. if ((unsigned char)pString[nPos] > 0x80)
  147. {
  148. if (bLess && (nPos + 2 > nDesirePos))
  149. break;
  150. if (pString[nPos + 1] == 0)
  151. {//防止出现单BYTE的高于0x80的字符
  152. nPos ++;
  153. break;
  154. }
  155. nPos += 2;
  156. }
  157. else if (pString[nPos])
  158. nPos ++;
  159. else
  160. break;
  161. }
  162. }
  163. return nPos;
  164. }
  165. //--------------------------------------------------------------------------
  166. // 功能:在编码字串寻找分割字符串的合适位置
  167. // 参数:pString    --> 想要分割的字符串
  168. //   nCount  -->字符串内容的长度(以字节为单位)
  169. //  nDesirePos --> 期望分割的位置(以缓冲驱存储字节为单位)
  170. //   bLess      --> 如果期望分割的位置处于一个中文字符编码的中间时,
  171. // 结果位置为前靠还是后靠,0: 向后靠; 非0: 向前靠。
  172. // 注释:Chinese GBK编码版本,此字符串中可包含已经编码的控制符
  173. //--------------------------------------------------------------------------
  174. extern "C" ENGINE_API
  175. int TSplitEncodedString(const char* pString, int nCount, int nDesirePos, int bLess)
  176. {
  177. int nPos = 0;
  178. if (pString)
  179. {
  180. if (nDesirePos <= nCount)
  181. {
  182. register unsigned char cCharacter;
  183. nDesirePos -= MAX_ENCODED_CTRL_LEN;
  184. while (nPos < nDesirePos)
  185. {
  186. cCharacter = (unsigned char)pString[nPos];
  187. if (cCharacter > 0x80)
  188. nPos += 2;
  189. else if (cCharacter == KTC_COLOR || cCharacter == KTC_BORDER_COLOR)
  190. nPos += 4;
  191. else if (cCharacter == KTC_INLINE_PIC)
  192. nPos += 3;//1 + sizeof(WORD);
  193. else
  194. nPos ++;
  195. }
  196. nPos += MAX_ENCODED_CTRL_LEN;
  197. while(nPos < nDesirePos)
  198. {
  199. cCharacter = (unsigned char)pString[nPos];
  200. if (cCharacter > 0x80)
  201. {
  202. if (bLess && (nPos + 2 > nDesirePos))
  203. break;
  204. if (nPos + 1 == nCount)
  205. {//防止出现单BYTE的高于0x80的字符
  206. nPos = nCount;
  207. break;
  208. }
  209. nPos += 2;
  210. }
  211. else if (cCharacter == KTC_INLINE_PIC)
  212. {
  213. if (bLess && nPos + 3 > nDesirePos)
  214. break;
  215. if (nPos + 3 >= nCount)
  216. {
  217. nPos = nCount;
  218. break;
  219. }
  220. nPos += 3;//1 + sizeof(WORD);
  221. }
  222. else if (cCharacter == KTC_COLOR || cCharacter == KTC_BORDER_COLOR)
  223. {
  224. if (bLess && (nPos + 4 > nDesirePos))
  225. break;
  226. if (nPos + 4 >= nCount)
  227. {
  228. nPos = nCount;
  229. break;
  230. }
  231. nPos += 4;
  232. }
  233. else
  234. nPos ++;
  235. }
  236. }
  237. else
  238. {
  239. nPos = nCount;
  240. }
  241. }
  242. return nPos;
  243. }
  244. //字符换控制码的字符标记表示与内部编码的对应结构
  245. #define KTC_CTRL_CODE_MAX_LEN 7
  246. typedef struct _KCtrlTable
  247. {
  248. char    szCtrl[KTC_CTRL_CODE_MAX_LEN + 1]; //字符换控制码的字符表示
  249. short nCtrlLen; //字符换控制码的字符表示的长度
  250. short   nCtrl; //字符换控制码的内部编码
  251. }KCtrlTable;
  252. //控制码列表
  253. static const KCtrlTable s_CtrlTable[] =
  254. {
  255. { "enter", 5, KTC_ENTER },
  256. { "color", 5, KTC_COLOR },
  257. { "bclr", 4, KTC_BORDER_COLOR },
  258. { "pic", 3, KTC_INLINE_PIC },
  259. };
  260. //控制码的数目
  261. static const int s_nCtrlCount = sizeof(s_CtrlTable)/sizeof(KCtrlTable);
  262. //颜色结构
  263. typedef struct _KColorTable
  264. {
  265. char Token[8]; //颜色的字符表示
  266. unsigned char Red; //颜色的R分量
  267. unsigned char Green; //颜色的G分量
  268. unsigned char Blue; //颜色的B分量
  269. }KColorTable;
  270. //颜色列表
  271. static const KColorTable s_ColorTable[] =
  272. {
  273. { "Black", 0, 0, 0 },
  274. { "White", 255, 255, 255 },
  275. { "Red", 255, 0, 0 },
  276. { "Green", 0, 255, 0 },
  277. { "Blue", 100, 100, 255 },
  278. { "Yellow", 255, 255, 0 },
  279. { "Pink", 255, 0, 255 },
  280. { "Cyan", 0, 255, 255 },
  281. { "Metal", 246, 255, 117 },
  282. { "Wood", 0, 255, 120 },
  283. { "Water", 78, 124, 255 },
  284. { "Fire", 255, 90, 0 },
  285. { "Earth", 254, 207, 179 },
  286. { "DBlue", 120, 120, 120 },
  287. { "HBlue", 100, 100, 255 },
  288. };
  289. //颜色的数目
  290. static const int s_nColorCount = sizeof(s_ColorTable)/sizeof(KColorTable);
  291. //嵌入图片[wxb 2003-6-19]
  292. #define MAXPICTOKENLEN 16
  293. static bool TEncodeCtrl(char* pBuffer, int nCount, int& nReadPos, int& nShortCount);
  294. static int  TEncodeCtrl(int nCtrl, char* pParamBuffer, int nParamLen, char* pEncodedBuffer);
  295. //--------------------------------------------------------------------------
  296. // 功能:对文本串中的控制标记进行转换,去除无效字符,缩短文本串存储长度
  297. //--------------------------------------------------------------------------
  298. extern "C" ENGINE_API
  299. int TEncodeText(char* pBuffer, int nCount)
  300. {
  301. int nShortCount = 0;
  302. if (pBuffer)
  303. {
  304. unsigned char cCharacter;
  305. int nReadPos = 0;
  306. while(nReadPos < nCount)
  307. {
  308. cCharacter = pBuffer[nReadPos];
  309. if (cCharacter > 0x80)
  310. {
  311. if (nReadPos + 1 < nCount) //是可能是中文文字
  312. {
  313. pBuffer[nShortCount++] = cCharacter;
  314. pBuffer[nShortCount++] = pBuffer[nReadPos+ 1];
  315. nReadPos += 2;
  316. }
  317. else //大于0x80的单字节西文字符被过滤掉
  318. break;
  319. }
  320. else if (cCharacter == 0x0d) //换行
  321. {
  322. if (nReadPos + 1 < nCount && pBuffer[nReadPos + 1] == 0x0a)
  323. nReadPos += 2;
  324. else
  325. nReadPos ++;
  326. pBuffer[nShortCount++] = 0x0a;
  327. }
  328. else if (pBuffer[nReadPos] == '<')
  329. TEncodeCtrl(pBuffer, nCount, nReadPos, nShortCount);
  330. else if((cCharacter >= 0x20 && cCharacter < 0x7F) ||
  331. cCharacter == 0x0a || cCharacter == 0x09)
  332. {
  333. pBuffer[nShortCount++] = cCharacter;
  334. nReadPos++;
  335. }
  336. else
  337. nReadPos++;
  338. }
  339. if (nShortCount <nCount)
  340. pBuffer[nShortCount] = 0;
  341. }
  342. return nShortCount;
  343. }
  344. //--------------------------------------------------------------------------
  345. // 功能:对文本串中的控制标记进行转换,去除无效字符,缩短文本串存储长度
  346. //--------------------------------------------------------------------------
  347. extern "C" ENGINE_API
  348. int TFilterEncodedText(char* pBuffer, int nCount)
  349. {
  350. int nShortCount = 0;
  351. if (pBuffer)
  352. {
  353. unsigned char cCharacter;
  354. int nReadPos = 0;
  355. while(nReadPos < nCount)
  356. {
  357. cCharacter = pBuffer[nReadPos];
  358. if (cCharacter > 0x80)
  359. {
  360. if (nReadPos + 1 < nCount) //是可能是中文文字
  361. {
  362. pBuffer[nShortCount++] = cCharacter;
  363. pBuffer[nShortCount++] = pBuffer[nReadPos+ 1];
  364. nReadPos += 2;
  365. }
  366. else //大于0x80的单字节西文字符被过滤掉
  367. {
  368. nReadPos++;
  369. break;
  370. }
  371. }
  372. else if ((cCharacter >= 0x20 && cCharacter < 0x7F) ||
  373. cCharacter == 0x0a || cCharacter == 0x09)
  374. {
  375. pBuffer[nShortCount++] = cCharacter;
  376. nReadPos++;
  377. }
  378. else if (cCharacter == KTC_COLOR || cCharacter == KTC_BORDER_COLOR)
  379. {
  380. if (nReadPos + 4 < nCount)
  381. {
  382. *(int*)(pBuffer + nShortCount) = *(int*)(pBuffer + nReadPos);
  383. nShortCount += 4;
  384. nReadPos += 4;
  385. }
  386. else
  387. {
  388. nReadPos++;
  389. break;
  390. }
  391. }
  392. else if (cCharacter == KTC_INLINE_PIC)
  393. {
  394. if ((int)(nReadPos + 1 + sizeof(WORD)) < nCount)
  395. {
  396. memcpy(pBuffer + nShortCount, pBuffer + nReadPos, 1 + sizeof(WORD));;
  397. nShortCount += 1 + sizeof(WORD);
  398. nReadPos += 1 + sizeof(WORD);
  399. }
  400. else
  401. {
  402. nReadPos++;
  403. break;
  404. }
  405. }
  406. else
  407. nReadPos ++;
  408. }
  409. if (nShortCount < nCount)
  410. pBuffer[nShortCount] = 0;
  411. }
  412. return nShortCount;
  413. }
  414. //--------------------------------------------------------------------------
  415. // 功能:分析转换控制符
  416. //--------------------------------------------------------------------------
  417. static bool TEncodeCtrl(char* pBuffer, int nCount, int& nReadPos, int& nShortCount)
  418. {
  419. _ASSERT(pBuffer != NULL && nReadPos < nCount && nShortCount < nCount && nShortCount <= nReadPos);
  420. int nCtrlCodeSize, nEndPos, nCtrl;
  421. //寻找结束符号'='的位置或'>'的位置
  422. int nEqualPos = nReadPos + 1;
  423. for (; nEqualPos < nCount && nEqualPos <= nReadPos + KTC_CTRL_CODE_MAX_LEN; nEqualPos++)
  424. if (pBuffer[nEqualPos] == '>' || pBuffer[nEqualPos] == '=')
  425. break;
  426. if(nEqualPos >= nCount || nEqualPos > nReadPos + KTC_CTRL_CODE_MAX_LEN)
  427. goto NO_MATCHING_CTRL; //未找到'='或者'>'结束符号
  428. nCtrlCodeSize = nEqualPos - nReadPos - 1; //控制命令符号的长度
  429. for (nCtrl = 0; nCtrl < s_nCtrlCount; nCtrl++)
  430. {
  431. if (nCtrlCodeSize ==  s_CtrlTable[nCtrl].nCtrlLen &&
  432. memcmp(pBuffer + nReadPos + 1, s_CtrlTable[nCtrl].szCtrl, nCtrlCodeSize) == 0)
  433. break;
  434. }
  435. if (nCtrl >= s_nCtrlCount) //未找到匹配一致的控制命令
  436. goto NO_MATCHING_CTRL;
  437. nCtrl = s_CtrlTable[nCtrl].nCtrl;
  438. nEndPos = nEqualPos;
  439. if (pBuffer[nEqualPos] != '>')
  440. {
  441. for(nEndPos++; nEndPos < nCount; nEndPos++)
  442. if (pBuffer[nEndPos] == '>')
  443. break;
  444. if (nEndPos >= nCount)
  445. goto NO_MATCHING_CTRL;
  446. nShortCount += TEncodeCtrl(nCtrl, pBuffer + nEqualPos + 1,
  447. nEndPos - nEqualPos - 1, pBuffer + nShortCount);
  448. }
  449. else
  450. nShortCount += TEncodeCtrl(nCtrl, NULL, 0, pBuffer + nShortCount);
  451. nReadPos = nEndPos + 1;
  452. return true;
  453. NO_MATCHING_CTRL:
  454. pBuffer[nShortCount++] = '<';
  455. nReadPos++;
  456. return false;
  457. }
  458. //--------------------------------------------------------------------------
  459. // 功能:转换并存储控制命令及各控制参数
  460. //--------------------------------------------------------------------------
  461. static int TEncodeCtrl(int nCtrl, char* pParamBuffer, int nParamLen, char* pEncodedBuffer)
  462. {
  463. _ASSERT(pEncodedBuffer && (nParamLen == 0 || pParamBuffer != NULL));
  464. int nEncodedSize = 0;
  465. static char Color[8];
  466. static char szPic[MAXPICTOKENLEN];
  467. switch(nCtrl)
  468. {
  469. case KTC_ENTER:
  470. pEncodedBuffer[nEncodedSize ++] = nCtrl;
  471. break;
  472. case KTC_INLINE_PIC: //[wxb 2003-6-19]
  473. if (nParamLen == 0 && nParamLen >= MAXPICTOKENLEN)
  474. break;
  475. {
  476. memcpy(szPic, pParamBuffer, nParamLen);
  477. szPic[nParamLen] = 0;
  478. pEncodedBuffer[nEncodedSize] = KTC_INLINE_PIC;
  479. *((WORD*)(pEncodedBuffer + nEncodedSize + 1)) = atoi(szPic);
  480. nEncodedSize += 1 + sizeof(WORD);
  481. }
  482. break;
  483. case KTC_COLOR:
  484. if (nParamLen == 0)
  485. {
  486. pEncodedBuffer[nEncodedSize ++] = KTC_COLOR_RESTORE;
  487. }
  488. else if (nParamLen < 8)
  489. {
  490. memcpy(Color, pParamBuffer, nParamLen);
  491. Color[nParamLen] = 0;
  492. for (int i = 0; i < s_nColorCount; i++)
  493. {
  494. #ifndef __linux
  495. if (stricmp(Color,s_ColorTable[i].Token) == 0)
  496. #else
  497. if(strcasecmp(Color,s_ColorTable[i].Token) == 0)
  498. #endif
  499. {
  500. pEncodedBuffer[nEncodedSize] = KTC_COLOR;
  501. pEncodedBuffer[nEncodedSize + 1]= s_ColorTable[i].Red;
  502. pEncodedBuffer[nEncodedSize + 2]= s_ColorTable[i].Green;
  503. pEncodedBuffer[nEncodedSize + 3]= s_ColorTable[i].Blue;
  504. nEncodedSize += 4;
  505. break;
  506. }
  507. }
  508. }
  509. break;
  510. case KTC_BORDER_COLOR:
  511. if (nParamLen == 0)
  512. {
  513. pEncodedBuffer[nEncodedSize ++] = KTC_BORDER_RESTORE;
  514. }
  515. else if (nParamLen < 8)
  516. {
  517. memcpy(Color, pParamBuffer, nParamLen);
  518. Color[nParamLen] = 0;
  519. for (int i = 0; i < s_nColorCount; i++)
  520. {
  521. #ifndef __linux
  522. if (stricmp(Color,s_ColorTable[i].Token) == 0)
  523. #else
  524. if(strcasecmp(Color,s_ColorTable[i].Token) == 0)
  525. #endif
  526. // if (stricmp(Color,s_ColorTable[i].Token) == 0)
  527. {
  528. pEncodedBuffer[nEncodedSize] = KTC_BORDER_COLOR;
  529. pEncodedBuffer[nEncodedSize + 1]= s_ColorTable[i].Red;
  530. pEncodedBuffer[nEncodedSize + 2]= s_ColorTable[i].Green;
  531. pEncodedBuffer[nEncodedSize + 3]= s_ColorTable[i].Blue;
  532. nEncodedSize += 4;
  533. break;
  534. }
  535. }
  536. }
  537. break;
  538. }
  539. return nEncodedSize;
  540. }
  541. extern "C" ENGINE_API
  542. int TRemoveCtrlInEncodedText(char* pBuffer, int nCount)
  543. {
  544. int nLen = 0;
  545. nCount = TFilterEncodedText(pBuffer, nCount);
  546. for (int nPos = 0; nPos < nCount; nPos++)
  547. {
  548. char cCharacter = pBuffer[nPos];
  549. if (cCharacter == KTC_COLOR || cCharacter == KTC_BORDER_COLOR)
  550. nPos += 3;
  551. else if (cCharacter == KTC_INLINE_PIC)
  552. nPos += sizeof(WORD);
  553. else if (cCharacter != KTC_COLOR_RESTORE && cCharacter != KTC_BORDER_RESTORE)
  554. {
  555. pBuffer[nLen] = cCharacter;
  556. nLen ++;
  557. }
  558. }
  559. return nLen;
  560. }
  561. //获取编码文本的行数与最大行宽
  562. //参数:pBuffer 文本缓冲区
  563. // nCount 文本数据的长度
  564. // nWrapCharaNum 限制每行不许超过的字符数目
  565. // nMaxLineLen 用于获取文本的实际最大行宽(字符数目)
  566. // nFontSize 采用字体的大小 [wxb 2003-6-19]
  567. // nSkipLine 跳过前面多少行的数据
  568. // nNumLineLimit 检测的文本的行数,超过限制行数目之后的内容被忽略。如果此值小于等于0则表示无此限制。
  569. //返回:文本的行数
  570. //extern "C" ENGINE_API
  571. //int TGetEncodedTextLineCount(const char* pBuffer, int nCount, int nWrapCharaNum, int& nMaxLineLen, int nFontSize, int nSkipLine = 0, int nNumLineLimit = 0)
  572. extern "C" ENGINE_API
  573. int TGetEncodedTextLineCount(const char* pBuffer, int nCount, int nWrapCharaNum, int& nMaxLineLen, int nFontSize, int nSkipLine, int nNumLineLimit,
  574.  BOOL bPicSingleLine/* = FALSE*/)
  575. {
  576. //设一个极值免得出错 [wxb 2003-6-20]
  577. _ASSERT(nFontSize >= 4 && nFontSize < 64);
  578. nFontSize = max(4, nFontSize);
  579. nFontSize = min(64, nFontSize);
  580. float fMaxLineLen = 0;
  581. nMaxLineLen = 0;
  582. if (pBuffer == 0)
  583. return 0;
  584. if (nCount < 0)
  585. nCount = strlen(pBuffer);
  586. float fNumChars = 0;
  587. int nNumLine = 0;
  588. int nPos = 0;
  589. unsigned char cCode;
  590. if (nWrapCharaNum <= 0)
  591. nWrapCharaNum = 0x7fffffff;
  592. if (nSkipLine < 0)
  593. nSkipLine = 0;
  594. if (nNumLineLimit <= 0)
  595. nNumLineLimit = 0x7fffffff;
  596. bool bNextLine = false;
  597. float fNumNextLineChar = 0;
  598. int  nExtraLineForInlinePic = 0;
  599. while(nPos < nCount)
  600. {
  601. cCode = pBuffer[nPos];
  602. if (cCode > 0x80) //可能是中文字符
  603. {
  604. nPos += 2;
  605. if (fNumChars + 2 < nWrapCharaNum)
  606. fNumChars += 2;
  607. else if (fNumChars + 2 == nWrapCharaNum || fNumChars == 0)
  608. {
  609. bNextLine = true;
  610. fNumChars += 2;
  611. }
  612. else
  613. {
  614. bNextLine = true;
  615. fNumNextLineChar = 2;
  616. }
  617. }
  618. else if (cCode == KTC_COLOR || cCode == KTC_BORDER_COLOR)//颜色控制
  619. nPos += 4;
  620. else if (cCode == KTC_INLINE_PIC)
  621. {
  622. //嵌入式图片处理 [wxb 2003-6-19]
  623. WORD wPicIndex = *((WORD*)(pBuffer + nPos + 1));
  624. nPos += 1 + sizeof(WORD);
  625. if (g_pIInlinePicSink)
  626. {
  627. int nWidth, nHeight;
  628. if (SUCCEEDED(g_pIInlinePicSink->GetPicSize(wPicIndex, nWidth, nHeight)))
  629. {
  630. if (nHeight > nFontSize)
  631. {
  632. int nExtraLines = nHeight - nFontSize;
  633. nExtraLines = nExtraLines / nFontSize + ((nExtraLines % nFontSize) ? 1 : 0);
  634. if (nExtraLines > nExtraLineForInlinePic && !bPicSingleLine)
  635. nExtraLineForInlinePic = nExtraLines;
  636. }
  637. if (fNumChars + (((float)nWidth) * 2 / nFontSize) < nWrapCharaNum)
  638. fNumChars += ((float)nWidth) * 2 / nFontSize;
  639. else if (fNumChars + (((float)nWidth) * 2 / nFontSize) == nWrapCharaNum || fNumChars == 0)
  640. {
  641. bNextLine = true;
  642. fNumChars += ((float)nWidth) * 2 / nFontSize;
  643. }
  644. else
  645. {
  646. bNextLine = true;
  647. fNumNextLineChar = ((float)nWidth) * 2 / nFontSize;
  648. }
  649. }
  650. }
  651. }
  652. else if (cCode == KTC_ENTER)
  653. {
  654. nPos ++;
  655. bNextLine = true;
  656. }
  657. else if (cCode != KTC_COLOR_RESTORE && cCode != KTC_BORDER_RESTORE)
  658. {
  659. nPos ++;
  660. fNumChars += 1;
  661. if (fNumChars >= nWrapCharaNum)
  662. {
  663. bNextLine = true;
  664. }
  665. }
  666. else
  667. {
  668. nPos++;
  669. }
  670. if (bNextLine == false && fNumChars && fNumChars + 3 >= nWrapCharaNum)
  671. {
  672. const char* pNext = TGetSecondVisibleCharacterThisLine(pBuffer, nPos, nCount);
  673. if (pNext && TIsCharacterNotAlowAtLineHead(pNext))
  674. bNextLine = true;
  675. }
  676. if (bNextLine)
  677. {
  678. if (nSkipLine > 0)
  679. {
  680. nSkipLine -= 1 + nExtraLineForInlinePic;
  681. //处理图片占多行的情况 [wxb 2003-6-19]
  682. if (nSkipLine < 0)
  683. {
  684. if (fMaxLineLen < fNumChars)
  685. fMaxLineLen = fNumChars;
  686. nNumLine += (-nSkipLine);
  687. if (nNumLine >= nNumLineLimit)
  688. break;
  689. }
  690. }
  691. else
  692. {
  693. if (fMaxLineLen < fNumChars)
  694. fMaxLineLen = fNumChars;
  695. nNumLine += 1 + nExtraLineForInlinePic;
  696. if (nNumLine >= nNumLineLimit)
  697. break;
  698. }
  699. nExtraLineForInlinePic = 0;
  700. fNumChars = (float)fNumNextLineChar;
  701. fNumNextLineChar = 0;
  702. bNextLine = false;
  703. }
  704. }
  705. if (nNumLine < nNumLineLimit && fNumChars && nSkipLine == 0)
  706. {
  707. if (fMaxLineLen < fNumChars)
  708. fMaxLineLen = fNumChars;
  709. nNumLine += 1 + nExtraLineForInlinePic;
  710. }
  711. nMaxLineLen = (int)(fMaxLineLen + (float)0.9999); //进1
  712. return nNumLine;
  713. }
  714. //获得指定行的开始位置
  715. int TGetEncodeStringLineHeadPos(const char* pBuffer, int nCount, int nLine, int nWrapCharaNum, int nFontSize, BOOL bPicSingleLine)
  716. {
  717. //设一个极值免得出错 [wxb 2003-6-20]
  718. _ASSERT(nFontSize > 1 && nFontSize < 64);
  719. nFontSize = max(1, nFontSize);
  720. nFontSize = min(64, nFontSize);
  721. float fMaxLineLen = 0;
  722. if (pBuffer == 0 || nLine <= 0)
  723. return 0;
  724. if (nCount < 0)
  725. nCount = strlen(pBuffer);
  726. float fNumChars = 0;
  727. int  nExtraLineForInlinePic = 0;
  728. int nPos = 0;
  729. unsigned char cCode;
  730. if (nWrapCharaNum <= 0)
  731. nWrapCharaNum = 0x7fffffff;
  732. bool bNextLine = false;
  733. float fNumNextLineChar = 0;
  734. while(nPos < nCount)
  735. {
  736. cCode = pBuffer[nPos];
  737. if (cCode > 0x80) //可能是中文字符
  738. {
  739. nPos += 2;
  740. if (fNumChars + 2 < nWrapCharaNum)
  741. fNumChars += 2;
  742. else if (fNumChars + 2 == nWrapCharaNum || fNumChars == 0)
  743. {
  744. bNextLine = true;
  745. fNumChars += 2;
  746. }
  747. else
  748. {
  749. bNextLine = true;
  750. fNumNextLineChar = 2;
  751. }
  752. }
  753. else if (cCode == KTC_COLOR || cCode == KTC_BORDER_COLOR)//颜色控制
  754. nPos += 4;
  755. else if (cCode == KTC_INLINE_PIC)
  756. {
  757. //嵌入式图片处理 [wxb 2003-6-19]
  758. WORD wPicIndex = *((WORD*)(pBuffer + nPos + 1));
  759. nPos += 1 + sizeof(WORD);
  760. if (g_pIInlinePicSink)
  761. {
  762. int nWidth, nHeight;
  763. if (SUCCEEDED(g_pIInlinePicSink->GetPicSize(wPicIndex, nWidth, nHeight)))
  764. {
  765. if (nHeight > nFontSize)
  766. {
  767. int nExtraLines = nHeight - nFontSize;
  768. nExtraLines = nExtraLines / nFontSize + ((nExtraLines % nFontSize) ? 1 : 0);
  769. if (nExtraLines > nExtraLineForInlinePic && !bPicSingleLine)
  770. nExtraLineForInlinePic = nExtraLines;
  771. }
  772. if (fNumChars + (((float)nWidth) * 2 / nFontSize) < nWrapCharaNum)
  773. fNumChars += ((float)nWidth) * 2 / nFontSize;
  774. else if (fNumChars + (((float)nWidth) * 2 / nFontSize) == nWrapCharaNum || fNumChars == 0)
  775. {
  776. bNextLine = true;
  777. fNumChars += ((float)nWidth) * 2 / nFontSize;
  778. }
  779. else
  780. {
  781. bNextLine = true;
  782. fNumNextLineChar = ((float)nWidth) * 2 / nFontSize;
  783. }
  784. }
  785. }
  786. }
  787. else if (cCode == KTC_ENTER)
  788. {
  789. nPos ++;
  790. bNextLine = true;
  791. }
  792. else if (cCode != KTC_COLOR_RESTORE && cCode != KTC_BORDER_RESTORE)
  793. {
  794. nPos ++;
  795. fNumChars += 1;
  796. if (fNumChars >= nWrapCharaNum)
  797. {
  798. bNextLine = true;
  799. }
  800. }
  801. else
  802. {
  803. nPos++;
  804. }
  805. if (bNextLine == false && fNumChars && fNumChars + 3 >= nWrapCharaNum)
  806. {
  807. const char* pNext = TGetSecondVisibleCharacterThisLine(pBuffer, nPos, nCount);
  808. if (pNext && TIsCharacterNotAlowAtLineHead(pNext))
  809. bNextLine = true;
  810. }
  811. if (bNextLine)
  812. {
  813. // if (nSkipLine > 0)
  814. // {
  815. // nSkipLine -= 1 + nExtraLineForInlinePic;
  816. //
  817. // //处理图片占多行的情况 [wxb 2003-6-19]
  818. // if (nSkipLine < 0)
  819. // {
  820. // if (fMaxLineLen < fNumChars)
  821. // fMaxLineLen = fNumChars;
  822. // nNumLine += (-nSkipLine);
  823. // if (nNumLine >= nNumLineLimit)
  824. // break;
  825. // }
  826. // }
  827. if ((--nLine) == 0)
  828. break;
  829. fNumChars = (float)fNumNextLineChar;
  830. fNumNextLineChar = 0;
  831. bNextLine = false;
  832. }
  833. }
  834. return nPos;
  835. }
  836. extern "C" ENGINE_API
  837. //如果原(包含控制符)字符串长度(包括结尾符)超过限定的长度,则截短它并加上..后缀
  838. const char* TGetLimitLenEncodedString(const char* pOrigString, int nOrigLen, int nFontSize,
  839. int nWrapCharaNum, char* pLimitLenString, int& nShortLen, int nLineLimit, int bPicPackInSingleLine/*=false*/)
  840. {
  841. if (pOrigString == NULL || pLimitLenString == NULL ||
  842. nOrigLen <= 0 || nShortLen < 2 || nLineLimit < 1 || nWrapCharaNum < 2)
  843. {
  844. nShortLen = 0;
  845. return NULL;
  846. }
  847. int nPreLineEndPos = 0, nFinalLineEndPos;
  848. if (nLineLimit > 1) //跳过前面几行
  849. {
  850. nPreLineEndPos = TGetEncodeStringLineHeadPos(pOrigString, nOrigLen, nLineLimit - 1, nWrapCharaNum, nFontSize, bPicPackInSingleLine);
  851. if (nPreLineEndPos > nShortLen)
  852. {
  853. nShortLen = TSplitEncodedString(pOrigString, nOrigLen, nShortLen - 2, true);
  854. memcpy(pLimitLenString, pOrigString, nShortLen);
  855. pLimitLenString[nShortLen] = '.';
  856. pLimitLenString[nShortLen + 1] = '.';
  857. nShortLen += 2;
  858. return pLimitLenString;
  859. }
  860. }
  861. if (nPreLineEndPos < nOrigLen)
  862. {
  863. nFinalLineEndPos = TGetEncodeStringLineHeadPos(pOrigString + nPreLineEndPos,
  864. nOrigLen - nPreLineEndPos, 1, nWrapCharaNum, nFontSize, bPicPackInSingleLine) + nPreLineEndPos;
  865. }
  866. else
  867. nFinalLineEndPos = nOrigLen;
  868. if (nFinalLineEndPos >= nOrigLen)
  869. {
  870. nShortLen = TSplitEncodedString(pOrigString, nOrigLen, nShortLen, true);
  871. memcpy(pLimitLenString, pOrigString, nShortLen);
  872. return pLimitLenString;
  873. }
  874. int nDesireLen = (nFinalLineEndPos <= nShortLen) ? nFinalLineEndPos - 2 : nShortLen - 2;
  875. const char* pFinalLineHead = pOrigString + nPreLineEndPos;
  876. int nRemainCount = nOrigLen - nPreLineEndPos;
  877. nDesireLen -= nPreLineEndPos;
  878. while(true)
  879. {
  880. nShortLen = TSplitEncodedString(pFinalLineHead, nRemainCount, nDesireLen, true);
  881. int nMaxLineLen;
  882. TGetEncodedTextLineCount(pFinalLineHead, nShortLen, 0, nMaxLineLen, nFontSize, 0, 1, FALSE);
  883. if (nMaxLineLen <= nWrapCharaNum - 2)
  884. break;
  885. nDesireLen --;
  886. }
  887. nShortLen += nPreLineEndPos;
  888.     memcpy(pLimitLenString, pOrigString, nShortLen);
  889. pLimitLenString[nShortLen] = '.';
  890. pLimitLenString[nShortLen + 1] = '.';
  891. nShortLen += 2;
  892. return pLimitLenString;
  893. }
  894. //--------------------------------------------------------------------------
  895. // 功能:如果原字符串长度(包括结尾符)超过限定的长度,则截短它并加上..后缀
  896. // 参数:pOrigString     --> 原字符串,要求不为空指针
  897. //  nOrigLen   --> 原字符串长度(不包括结尾符)
  898. //   pLimitLenString --> 如果原字符串超出限长,用来存储截短后的字符串的缓冲区,要求不为空指针
  899. //   nLimitLen   --> 限定长度,此值要求大于等于3
  900. // 返回:如原字符串不超过限长,则返回原缓冲区指针,否则返回用来存储截短后的字符串的缓冲区的指针
  901. // 注释:Chinese GBK编码版本,此字符串中字符全部视为显示字符,不包含控制字符
  902. //--------------------------------------------------------------------------
  903. extern "C" ENGINE_API
  904. const char* TGetLimitLenString(const char* pOrigString, int nOrigLen, char* pLimitLenString, int nLimitLen)
  905. {
  906. if (pOrigString && pLimitLenString && nLimitLen > 0)
  907. {
  908. if (nOrigLen < 0)
  909. nOrigLen = strlen(pOrigString);
  910. if (nOrigLen < nLimitLen)
  911. return pOrigString;
  912. if (nLimitLen > 2)
  913. {
  914. nOrigLen = TSplitString(pOrigString, nLimitLen - 3, true);
  915. memcpy(pLimitLenString, pOrigString, nOrigLen);
  916. pLimitLenString[nOrigLen] = '.';
  917. pLimitLenString[nOrigLen + 1] = '.';
  918. pLimitLenString[nOrigLen + 2] = 0;
  919. }
  920. else if (nLimitLen == 2)
  921. {
  922. pLimitLenString[0] = '.';
  923. pLimitLenString[1] = 0;
  924. }
  925. return ((nLimitLen >= 2) ? pLimitLenString : NULL);
  926. }
  927. return NULL;
  928. }
  929. //对已经编码的文本,从指定位置开始查找指定的控制符号的位置,返回-1表示未找到
  930. extern "C" ENGINE_API
  931. int TFindSpecialCtrlInEncodedText(const char* pBuffer, int nCount, int nStartPos, char cControl)
  932. {
  933. int nFindPos = -1;
  934. if (pBuffer)
  935. {
  936. while(nStartPos < nCount)
  937. {
  938. unsigned char cCharacter = pBuffer[nStartPos];
  939. if ((unsigned char)cControl == cCharacter)
  940. {
  941. nFindPos = nStartPos;
  942. break;
  943. }
  944. if (cCharacter > 0x80) //可能是中文文字
  945. nStartPos += 2;
  946. else if (cCharacter == KTC_COLOR || cCharacter == KTC_BORDER_COLOR)
  947. nStartPos += 4;
  948. else if (cCharacter == KTC_INLINE_PIC)
  949. nStartPos += 3;
  950. else
  951. nStartPos ++;
  952. }
  953. }
  954. return nFindPos;
  955. }
  956. //对已经编码的文本,去除指定类型的控制符
  957. extern "C" ENGINE_API
  958. int TClearSpecialCtrlInEncodedText(char* pBuffer, int nCount, char cControl)
  959. {
  960. int nFinalLen = 0;
  961. int nReadPos = 0;
  962. if (pBuffer)
  963. {
  964. if ((unsigned char)(cControl) <= 0x80)
  965. {
  966. int nMatchLen = 1;
  967. if (cControl == KTC_COLOR || cControl == KTC_BORDER_COLOR)
  968. nMatchLen = 4;
  969. else if (cControl == KTC_INLINE_PIC)
  970. nMatchLen = 3;
  971. while(nReadPos < nCount)
  972. {
  973. unsigned char cCharacter = pBuffer[nReadPos];
  974. if ((unsigned char)cControl == cCharacter)
  975. {
  976. nReadPos += nMatchLen;
  977. }
  978. else if (cCharacter > 0x80)
  979. {
  980. short sTemp = *(short*)(pBuffer + nReadPos);
  981. *(short*)(pBuffer + nFinalLen) = sTemp;
  982. nReadPos += 2;
  983. nFinalLen += 2;
  984. }
  985. else if (cCharacter == KTC_COLOR || cCharacter == KTC_BORDER_COLOR)
  986. {
  987. int nTemp = *(int*)(pBuffer + nReadPos);
  988. *(int*)(pBuffer + nFinalLen) = nTemp;
  989. nFinalLen += 4;
  990. nReadPos += 4;
  991. }
  992. else if (cCharacter == KTC_INLINE_PIC)
  993. {
  994. memmove((pBuffer + nFinalLen), (pBuffer + nReadPos), 3);
  995. nFinalLen += 3;
  996. nReadPos += 3;
  997. }
  998. else
  999. {
  1000. pBuffer[nFinalLen++] = pBuffer[nReadPos++];
  1001. }
  1002. }
  1003. }
  1004. }
  1005. return nFinalLen;
  1006. }
  1007. //对已经编码的文本,指定输出长度的在缓冲区中位置
  1008. extern "C" ENGINE_API
  1009. int TGetEncodedTextOutputLenPos(const char* pBuffer, int nCount, int& nLen, bool bLess, int nFontSize)
  1010. {
  1011. int nIndex = 0, nLenTemp = 0;
  1012. _ASSERT(nFontSize >= 4);
  1013. nFontSize = max(4, nFontSize);
  1014.     if (pBuffer)
  1015. {
  1016. int nWidth, nHeight;
  1017. int nByteCount = 0, nCurCharLen = 0;
  1018.     unsigned char cCharacter        = 0;
  1019. while(nLenTemp < nLen)
  1020. {
  1021. cCharacter = pBuffer[nIndex];
  1022. //计算出当前元素的所占字节数nByteCount和在显示画面上所占宽度nCurCharLen
  1023. if (cCharacter > 0x80) //可能是中文文字
  1024. {
  1025.                 nByteCount  = 2;
  1026. nCurCharLen = 2;
  1027. }
  1028. else if (cCharacter == KTC_COLOR || cCharacter == KTC_BORDER_COLOR)
  1029. {
  1030.     nByteCount  = 4;
  1031. nCurCharLen = 0;
  1032. }
  1033. else if (cCharacter == KTC_COLOR_RESTORE && cCharacter == KTC_BORDER_RESTORE)
  1034. {
  1035. nByteCount  = 1;
  1036. nCurCharLen = 0;
  1037. }
  1038. else if (cCharacter == KTC_INLINE_PIC)
  1039. {
  1040. nByteCount  = 3;
  1041. if(SUCCEEDED(g_pIInlinePicSink->GetPicSize(
  1042. *((unsigned short *)(pBuffer + nIndex + 1)), nWidth, nHeight)))
  1043. {
  1044. nCurCharLen = ((nWidth * 2 + nFontSize - 1) /  nFontSize);
  1045. }
  1046. else
  1047. nCurCharLen = 0;
  1048. }
  1049. else
  1050. {
  1051. nByteCount  = 1;
  1052. nCurCharLen = 1;
  1053. }
  1054. //如果超出缓冲区,就停止吧
  1055. if(nIndex + nByteCount > nCount)
  1056. break;
  1057. //如果宽度还没超过要求宽度
  1058. if(nLenTemp + nCurCharLen < nLen)
  1059. {
  1060. nLenTemp += nCurCharLen;
  1061.         nIndex   += nByteCount;
  1062. }
  1063. //如果宽度等于要求宽度了
  1064. else if(nLenTemp + nCurCharLen == nLen)
  1065. {
  1066. nLenTemp += nCurCharLen;
  1067. nIndex   += nByteCount;
  1068. break;
  1069. }
  1070. //这里就是超过了
  1071. else
  1072. {
  1073. nLenTemp = bLess ? nLenTemp : (nLenTemp + nCurCharLen);
  1074. nIndex   = bLess ? nIndex   : (nIndex + nByteCount);
  1075. break;
  1076. }
  1077. }
  1078. }
  1079. nLen = nLenTemp;
  1080. return nIndex;
  1081. }
  1082. //对已经编码的文本,指定的前段缓冲区中控制符,对后面的输出产生效果影响
  1083. extern "C" ENGINE_API
  1084. int TGetEncodedTextEffectCtrls(const char* pBuffer, int nSkipCount, KTP_CTRL& Ctrl0, KTP_CTRL& Ctrl1)
  1085. {
  1086. int nIndex = 0;
  1087. Ctrl0.cCtrl = Ctrl1.cCtrl = KTC_INVALID;
  1088. if (pBuffer)
  1089. {
  1090. KTP_CTRL PreCtrl0, PreCtrl1;
  1091. PreCtrl0.cCtrl = PreCtrl1.cCtrl = KTC_INVALID;
  1092. while(nIndex < nSkipCount)
  1093. {
  1094. unsigned char cCharacter = pBuffer[nIndex];
  1095. if (cCharacter == KTC_COLOR)
  1096. {
  1097. PreCtrl0  =  Ctrl0;
  1098. *(int*)(&Ctrl0) = *(int*)(pBuffer + nIndex);
  1099. nIndex += 4;
  1100. }
  1101. else if (cCharacter == KTC_BORDER_COLOR)
  1102. {
  1103. PreCtrl1  =  Ctrl1;
  1104. *(int*)(&Ctrl1) = *(int*)(pBuffer + nIndex);
  1105. nIndex += 4;
  1106. }
  1107. else if(cCharacter == KTC_COLOR_RESTORE)
  1108. {
  1109. Ctrl0 = PreCtrl0;
  1110. nIndex ++;
  1111. }
  1112. else if(cCharacter == KTC_BORDER_RESTORE)
  1113. {
  1114. Ctrl1 = PreCtrl1;
  1115. nIndex ++;
  1116. }
  1117. else
  1118. nIndex ++;
  1119. }
  1120. }
  1121. return nIndex;
  1122. }