Chinaunix首页 | 论坛 | 博客
  • 博客访问: 508025
  • 博文数量: 95
  • 博客积分: 5168
  • 博客等级: 大校
  • 技术积分: 1271
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-28 23:31
文章分类

全部博文(95)

文章存档

2013年(2)

2012年(3)

2011年(1)

2010年(8)

2009年(81)

分类: LINUX

2009-01-13 13:08:12

              魏永明

蓝点软件(北京)研发中心技术主管


图 1 逻辑字体以及相关数据结构

int GUIAPI GetFirstWord (PLOGFONT log_font, const char* mstr, int len,
WORDINFO* word_info)
{
DEVFONT* sbc_devfont = log_font->sbc_devfont;
DEVFONT* mbc_devfont = log_font->mbc_devfont;

if (mbc_devfont) {
int mbc_pos;

mbc_pos = (*mbc_devfont->charset_ops->pos_first_char) (mstr, len);
if (mbc_pos == 0) {
len = (*mbc_devfont->charset_ops->len_first_substr) (mstr, len);

(*mbc_devfont->charset_ops->get_next_word) (mstr, len, word_info);
return word_info->len + word_info->nr_delimiters;
}
else if (mbc_pos > 0)
len = mbc_pos;
}

(*sbc_devfont->charset_ops->get_next_word) (mstr, len, word_info);
return word_info->len + word_info->nr_delimiters;
}

该函数首先判断该逻辑字体是否包含多字节设备字体(mbc_devfont是否为空),如果是,则调用多字节字符集对应的操作函 数 pos_first_char、len_first_substr、get_next_word 等函数获得第一个单词信息,并填充 word_info 结构。如果该逻辑字体只包含单字节设备字体,则直接调用单字节字符集对应的操作函数 get_next_word。一般而言,在 GetFirstWord 等函数中,我们首先要进行多字节字符集的某些判断,比如 pos_first_char 返回的是字符串中属于该字符集的第一个字符的位置。如果返回值不为零,表明第一个字符是单字节字符;如果为零,才会调用其他函数进行操作。

 250 typedef struct _CHARSETOPS
251 {
252 int nr_chars; // 该字符集中字符的个数
253 int bytes_per_char; // 每个字符的平均字节数
254 int bytes_maxlen_char; // 字符的最大字节数
255 const char* name; // 字符集名称
256 char def_char [MAX_LEN_MCHAR]; // 默认字符
257
258 int (*len_first_char) (const unsigned char* mstr, int mstrlen);
259 int (*char_offset) (const unsigned char* mchar);
260
261 int (*nr_chars_in_str) (const unsigned char* mstr, int mstrlen);
262
263 int (*is_this_charset) (const unsigned char* charset);
264
265 int (*len_first_substr) (const unsigned char* mstr, int mstrlen);
266 const unsigned char* (*get_next_word) (const unsigned char* mstr,
267 int strlen, WORDINFO* word_info);
268
269 int (*pos_first_char) (const unsigned char* mstr, int mstrlen);
270
271 #ifndef _LITE_VERSION
272 unsigned short (*conv_to_uc16) (const unsigned char* mchar, int len);
273 #endif /* !LITE_VERSION */
274 } CHARSETOPS;

 716 static CHARSETOPS* Charsets [] =
717 {
718 &CharsetOps_iso8859_1,
719 &CharsetOps_iso8859_5,
720 #ifdef _GB_SUPPORT
721 &CharsetOps_gb2312,
722 #endif
723 #ifdef _BIG5_SUPPORT
724 &CharsetOps_big5,
725 #endif
726 #ifdef _EUCKR_SUPPORT
727 &CharsetOps_euckr,
728 #endif
729 #ifdef _UJIS_SUPPORT
730 &CharsetOps_ujis
731 #endif
732 };
733
734 #define NR_CHARSETS (sizeof(Charsets)/sizeof(CHARSETOPS*))
735
736 CHARSETOPS* GetCharsetOps (const char* charset_name)
737 {
738 int i;
739
740 for (i = 0; i < NR_CHARSETS; i++) {
741 if ((*Charsets [i]->is_this_charset) (charset_name) == 0)
742 return Charsets [i];
743 }
744
745 return NULL;
746 }
747

 468 #ifdef _EUCKR_SUPPORT
469 /************************* EUCKR Specific Operations ************************/
470 static int euckr_len_first_char (const unsigned char* mstr, int len)
471 {
472 unsigned char ch1;
473 unsigned char ch2;
474
475 if (len < 2) return 0;
476
477 ch1 = mstr [0];
478 if (ch1 == '\0')
479 return 0;
480
481 ch2 = mstr [1];
482 if (ch1 >= 0xA1 && ch1 <= 0xFE && ch2 >= 0xA1 && ch2 <= 0xFE)
483 return 2;
484
485 return 0;
486 }
487
488 static int euckr_char_offset (const unsigned char* mchar)
489 {
490 if(mchar [0] > 0xAD)
491 return ((mchar [0] - 0xA4) * 94 + mchar [1] - 0xA1 - 0x8E);
492 else
493 return ((mchar [0] - 0xA1) * 94 + mchar [1] - 0xA1 - 0x8E);
494 }
495
496 static int euckr_is_this_charset (const unsigned char* charset)
497 {
498 int i;
499 char name [LEN_FONT_NAME + 1];
500
501 for (i = 0; i < LEN_FONT_NAME + 1; i++) {
502 if (charset [i] == '\0')
503 break;
504 name [i] = toupper (charset [i]);
505 }
506 name [i] = '\0';
507
508 if (strstr (name, "EUCKR") )
509 return 0;
510
511 return 1;
512 }
513
514 static int euckr_len_first_substr (const unsigned char* mstr, int mstrlen)
515 {
516 unsigned char ch1;
517 unsigned char ch2;
518 int i, left;
519 int sub_len = 0;
520
521 left = mstrlen;
522 for (i = 0; i < mstrlen; i += 2) {
523 if (left < 2) return sub_len;
524
525 ch1 = mstr [i];
526 if (ch1 == '\0') return sub_len;
527
528 ch2 = mstr [i + 1];
529 if (ch1 >= 0xA1 && ch1 <= 0xFE && ch2 >= 0xA1 && ch2 <= 0xFE)
530 sub_len += 2;
531 else
532 return sub_len;
533
534 left -= 2;
535 }
536
537 return sub_len;
538 }
539
540 static int euckr_pos_first_char (const unsigned char* mstr, int mstrlen)
541 {
542 unsigned char ch1;
543 unsigned char ch2;
544 int i, left;
545
546 i = 0;
547 left = mstrlen;
548 while (left) {
549 if (left < 2) return -1;
550
551 ch1 = mstr [i];
552 if (ch1 == '\0') return -1;
553
554 ch2 = mstr [i + 1];
555 if (ch1 >= 0xA1 && ch1 <= 0xFE && ch2 >= 0xA1 && ch2 <= 0xFE)
556 return i;
557
558 i += 1;
559 left -= 1;
560 }
561
562 return -1;
563 }
564
565 #ifndef _LITE_VERSION
566 static unsigned short euckr_conv_to_uc16 (const unsigned char* mchar, int len)
567 {
568 return '?';
569 }
570 #endif
571
572 static CHARSETOPS CharsetOps_euckr = {
573 8836,
574 2,
575 2,
576 FONT_CHARSET_EUCKR,
577 {'\xA1', '\xA1'},
578 euckr_len_first_char,
579 euckr_char_offset,
580 db_nr_chars_in_str,
581 euckr_is_this_charset,
582 euckr_len_first_substr,
583 db_get_next_word,
584 euckr_pos_first_char,
585 #ifndef _LITE_VERSION
586 euckr_conv_to_uc16
587 #endif
588 };
589 /************************* End of EUCKR *************************************/
590 #endif /* _EUCKR_SUPPORT */

 319 struct _DEVFONT
320 {
321 char name [LEN_DEVFONT_NAME + 1];
322 DWORD style;
323 FONTOPS* font_ops;
324 CHARSETOPS* charset_ops;
325 struct _DEVFONT* sbc_next;
326 struct _DEVFONT* mbc_next;
327 void* data;
328 };

  • --