charset.c

来自「这是ARM嵌入式系统的实验教程中的MINIGUI的实验源代码!」· C语言 代码 · 共 2,766 行 · 第 1/5 页

C
2,766
字号
    0x00A7, 0x1E80, 0x00A9,
    0x1E82, 0x1E0B, 0x1EF2,
    0x00AD, 0x00AE, 0x0178,
    0x1E1E, 0x1E1F, 0x0120,
    0x0121, 0x1E40, 0x1E41,
    0x00B6, 0x1E56, 0x1E81,
    0x1E57, 0x1E83, 0x1E60,
    0x1EF3, 0x1E84, 0x1E85,
    0x1E61, 0x00C0, 0x00C1,
    0x00C2, 0x00C3, 0x00C4,
    0x00C5, 0x00C6, 0x00C7,
    0x00C8, 0x00C9, 0x00CA,
    0x00CB, 0x00CC, 0x00CD,
    0x00CE, 0x00CF, 0x0174,
    0x00D1, 0x00D2, 0x00D3,
    0x00D4, 0x00D5, 0x00D6,
    0x1E6A, 0x00D8, 0x00D9,
    0x00DA, 0x00DB, 0x00DC,
    0x00DD, 0x0176, 0x00DF,
    0x00E0, 0x00E1, 0x00E2,
    0x00E3, 0x00E4, 0x00E5,
    0x00E6, 0x00E7, 0x00E8,
    0x00E9, 0x00EA, 0x00EB,
    0x00EC, 0x00ED, 0x00EE,
    0x00EF, 0x0175, 0x00F1,
    0x00F2, 0x00F3, 0x00F4,
    0x00F5, 0x00F6, 0x1E6B,
    0x00F8, 0x00F9, 0x00FA,
    0x00FB, 0x00FC, 0x00FD,
    0x0177, 0x00FF
};

static unsigned short iso8859_14_conv_to_uc16 (const unsigned char* mchar, int len)
{
    if (*mchar < 0xA1)
        return (unsigned short) (*mchar);
    else
        return iso8859_14_unicode_map [*mchar - 0xA1];
}
#endif

static CHARSETOPS CharsetOps_iso8859_14 = {
    256,
    1,
    1,
    FONT_CHARSET_ISO8859_14,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    iso8859_14_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    iso8859_14_conv_to_uc16
#endif
};

#endif /* _LATIN8_SUPPORT */

#ifdef _LATIN9_SUPPORT

/************************* ISO8859-15 Specific Operations **********************/
static int iso8859_15_is_this_charset (const unsigned char* charset)
{
    int i;
    char name [LEN_FONT_NAME + 1];

    for (i = 0; i < LEN_FONT_NAME + 1; i++) {
        if (charset [i] == '\0')
            break;
        name [i] = toupper (charset [i]);
    }
    name [i] = '\0';

    if (strstr (name, "ISO") && strstr (name, "8859-15"))
        return 0;

    if (strstr (name, "LATIN") && strstr (name, "9"))
        return 0;

    return 1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short iso8859_15_conv_to_uc16 (const unsigned char* mchar, int len)
{
    switch (*mchar) {
        case 0xA4:
            return 0x20AC;  /* EURO SIGN */
        case 0xA6:
            return 0x0160;  /* LATIN CAPITAL LETTER S WITH CARO */
        case 0xA8:
            return 0x0161;  /* LATIN SMALL LETTER S WITH CARON */
        case 0xB4:
            return 0x017D;  /* LATIN CAPITAL LETTER Z WITH CARON */
        case 0xB8:
            return 0x017E;  /* LATIN SMALL LETTER Z WITH CARON */
        case 0xBC:
            return 0x0152;  /* LATIN CAPITAL LIGATURE OE */
        case 0xBD:
            return 0x0153;  /* LATIN SMALL LIGATURE OE */
        case 0xBE:
            return 0x0178;  /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
        default:
            return *mchar;
    }
}
#endif

static CHARSETOPS CharsetOps_iso8859_15 = {
    256,
    1,
    1,
    FONT_CHARSET_ISO8859_15,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    iso8859_15_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    iso8859_15_conv_to_uc16
#endif
};
#endif /* _LATIN9_SUPPORT */

#ifdef _LATIN10_SUPPORT

/************************* ISO8859-16 Specific Operations **********************/
static int iso8859_16_is_this_charset (const unsigned char* charset)
{
    int i;
    char name [LEN_FONT_NAME + 1];

    for (i = 0; i < LEN_FONT_NAME + 1; i++) {
        if (charset [i] == '\0')
            break;
        name [i] = toupper (charset [i]);
    }
    name [i] = '\0';

    if (strstr (name, "ISO") && strstr (name, "8859-16"))
        return 0;

    if (strstr (name, "LATIN") && strstr (name, "10"))
        return 0;

    return 1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short iso8859_16_conv_to_uc16 (const unsigned char* mchar, int len)
{
    switch (*mchar) {
        case 0xA1: return 0x0104;
        case 0xA2: return 0x0105;
        case 0xA3: return 0x0141;
        case 0xA4: return 0x20AC;
        case 0xA5: return 0x201E;
        case 0xA6: return 0x0160;
        case 0xA8: return 0x0161;
        case 0xAA: return 0x0218;
        case 0xAC: return 0x0179;
        case 0xAE: return 0x017A;
        case 0xAF: return 0x017B;
        case 0xB2: return 0x010C;
        case 0xB3: return 0x0142;
        case 0xB4: return 0x017D;
        case 0xB5: return 0x201D;
        case 0xB8: return 0x017E;
        case 0xB9: return 0x010D;
        case 0xBA: return 0x0219;
        case 0xBC: return 0x0152;
        case 0xBD: return 0x0153;
        case 0xBE: return 0x0178;
        case 0xBF: return 0x017C;
        case 0xC3: return 0x0102;
        case 0xC5: return 0x0106;
        case 0xD0: return 0x0110;
        case 0xD1: return 0x0143;
        case 0xD5: return 0x0150;
        case 0xD7: return 0x015A;
        case 0xD8: return 0x0170;
        case 0xDD: return 0x0118;
        case 0xDE: return 0x021A;
        case 0xE3: return 0x0103;
        case 0xE5: return 0x0107;
        case 0xF0: return 0x0111;
        case 0xF1: return 0x0144;
        case 0xF5: return 0x0151;
        case 0xF7: return 0x015B;
        case 0xF8: return 0x0171;
        case 0xFD: return 0x0119;
        case 0xFE: return 0x021B;
    }

    return (unsigned short) (*mchar);
}
#endif

static CHARSETOPS CharsetOps_iso8859_16 = {
    256,
    1,
    1,
    FONT_CHARSET_ISO8859_16,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    iso8859_16_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    iso8859_16_conv_to_uc16
#endif
};

#endif /* _LATIN10_SUPPORT */

/*************** Common Operations for double bytes charsets ******************/
#if defined(_GB_SUPPORT) | defined(_GBK_SUPPORT) | defined(_BIG5_SUPPORT) \
        | defined(_EUCKR_SUPPORT) | defined(_EUCJP_SUPPORT) | defined(_SHIFTJIS_SUPPORT) \
        | defined(_UNICODE_SUPPORT)
static int db_nr_chars_in_str (const unsigned char* mstr, int mstrlen)
{
    assert ((mstrlen % 2) == 0);
    return mstrlen >> 1;
}

static const unsigned char* db_get_next_word (const unsigned char* mstr,
                int mstrlen, WORDINFO* word_info)
{
    assert ((mstrlen % 2) == 0);

    if (mstrlen < 2) return NULL;

    word_info->len = 2;
    word_info->delimiter = '\0';
    word_info->nr_delimiters = 0;

    return mstr + 2;
}
#endif

#ifdef _GB_SUPPORT
/************************* GB2312 Specific Operations ************************/
#define IS_GB2312_CHAR(ch1, ch2) \
        if (((ch1 >= 0xA1 && ch1 <= 0xA9) || (ch1 >= 0xB0 && ch1 <= 0xF7)) \
                        && ch2 >= 0xA1 && ch2 <= 0xFE)

static int gb2312_0_len_first_char (const unsigned char* mstr, int len)
{
    unsigned char ch1;
    unsigned char ch2;

    if (len < 2) return 0;

    ch1 = mstr [0];
    if (ch1 == '\0')
        return 0;

    ch2 = mstr [1];
    IS_GB2312_CHAR (ch1, ch2)
        return 2;

    return 0;
}

static unsigned int gb2312_0_char_offset (const unsigned char* mchar)
{
    int area = mchar [0] - 0xA1;

    if (area < 9) {
        return (area * 94 + mchar [1] - 0xA1);
    }
    else if (area >= 15)
        return ((area - 6)* 94 + mchar [1] - 0xA1);

    return 0;
}

static int gb2312_0_is_this_charset (const unsigned char* charset)
{
    int i;
    char name [LEN_FONT_NAME + 1];

    for (i = 0; i < LEN_FONT_NAME + 1; i++) {
        if (charset [i] == '\0')
            break;
        name [i] = toupper (charset [i]);
    }
    name [i] = '\0';

    if (strstr (name, "GB") && strstr (name, "2312"))
        return 0;

    return 1;
}

static int gb2312_0_len_first_substr (const unsigned char* mstr, int mstrlen)
{
    unsigned char ch1;
    unsigned char ch2;
    int i, left;
    int sub_len = 0;

    left = mstrlen;
    for (i = 0; i < mstrlen; i += 2) {
        if (left < 2) return sub_len;

        ch1 = mstr [i];
        if (ch1 == '\0') return sub_len;

        ch2 = mstr [i + 1];
        IS_GB2312_CHAR (ch1, ch2)
            sub_len += 2;
        else
            return sub_len;

        left -= 2;
    }

    return sub_len;
}

static int gb2312_0_pos_first_char (const unsigned char* mstr, int mstrlen)
{
    unsigned char ch1;
    unsigned char ch2;
    int i, left;

    i = 0;
    left = mstrlen;
    while (left) {
        if (left < 2) return -1;

        ch1 = mstr [i];
        if (ch1 == '\0') return -1;

        ch2 = mstr [i + 1];
        IS_GB2312_CHAR (ch1, ch2)
            return i;

        i += 1;
        left -= 1;
    }

    return -1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short gb2312_0_conv_to_uc16 (const unsigned char* mchar, int len)
{
    return gbunicode_map [gb2312_0_char_offset (mchar)];
}
#endif

static CHARSETOPS CharsetOps_gb2312_0 = {
    (0xFF-0xA1)*(72 + 9),
    2,
    2,
    FONT_CHARSET_GB2312_0,
    {'\xA1', '\xA1'},
    gb2312_0_len_first_char,
    gb2312_0_char_offset,
    db_nr_chars_in_str,
    gb2312_0_is_this_charset,
    gb2312_0_len_first_substr,
    db_get_next_word,
    gb2312_0_pos_first_char,
#ifdef _UNICODE_SUPPORT
    gb2312_0_conv_to_uc16
#endif
};
#endif /* _GB_SUPPORT */

#ifdef _GBK_SUPPORT
/************************* GBK Specific Operations ************************/

#define IS_GBK_CHAR(ch1, ch2) \
    if (ch1 >= 0x81 && ch1 <= 0xFE && ch2 >= 0x40 && ch2 <= 0xFE && ch2 != 0x7F)

static int gbk_len_first_char (const unsigned char* mstr, int len)
{
    unsigned char ch1;
    unsigned char ch2;

    if (len < 2) return 0;

    ch1 = mstr [0];
    if (ch1 == '\0')
        return 0;

    ch2 = mstr [1];
    IS_GBK_CHAR(ch1, ch2)
        return 2;

    return 0;
}

static unsigned int gbk_char_offset (const unsigned char* mchar)
{
    if (mchar [1] > 0x7F)
        return ((mchar [0] - 0x81) * 190 + mchar [1] - 0x41);
    else
        return ((mchar [0] - 0x81) * 190 + mchar [1] - 0x40);
}

static int gbk_is_this_charset (const unsigned char* charset)
{
    int i;
    char name [LEN_FONT_NAME + 1];

    for (i = 0; i < LEN_FONT_NAME + 1; i++) {
        if (charset [i] == '\0')
            break;
        name [i] = toupper (charset [i]);
    }
    name [i] = '\0';

    if (strstr (name, "GBK"))
        return 0;

    return 1;
}

static int gbk_len_first_substr (const unsigned char* mstr, int mstrlen)
{
    unsigned char ch1;
    unsigned char ch2;
    int i, left;
    int sub_len = 0;

    left = mstrlen;
    for (i = 0; i < mstrlen; i += 2) {
        if (left < 2) return sub_len;

        ch1 = mstr [i];
        if (ch1 == '\0') return sub_len;

        ch2 = mstr [i + 1];
        IS_GBK_CHAR(ch1, ch2)
            sub_len += 2;
        else
            return sub_len;

        left -= 2;
    }

    return sub_len;
}

static int gbk_pos_first_char (const unsigned char* mstr, int mstrlen)
{
    unsigned char ch1;
    unsigned char ch2;
    int i, left;

    i = 0;
    left = mstrlen;
    while (left) {
        if (left < 2) return -1;

        ch1 = mstr [i];
        if (ch1 == '\0') return -1;

        ch2 = mstr [i + 1];
        IS_GBK_CHAR(ch1, ch2)
            return i;

        i += 1;
        left -= 1;
    }

    return -1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short gbk_conv_to_uc16 (const unsigned char* mchar, int len)
{
    return gbkunicode_map [(mchar [0] - 0x81) * 192 + mchar [1] - 0x40];
}
#endif

static CHARSETOPS CharsetOps_gbk = {
    (0xFF - 0x80) * 190,
    2,
    2,
    FONT_CHARSET_GBK,
    {'\xA1', '\xA1'},
    gbk_len_first_char,
    gbk_char_offset,
    db_nr_chars_in_str,
    gbk_is_this_charset,
    gbk_len_first_substr,
    db_get_next_word,
    gbk_pos_first_char,
#ifdef _UNICODE_SUPPORT
    gbk_conv_to_uc16
#endif
};

#endif /* _GBK_SUPPORT */

#ifdef _GB18030_SUPPORT

/************************* GBK Specific Operations ************************/
static int gb18030_0_len_first_char (const unsigned char* mstr, int len)
{
    unsigned char ch1;
    unsigned char ch2;
    unsigned char ch3;
    unsigned char ch4;

    if (len < 2) return 0;

    ch1 = mstr [0];
    if (ch1 == '\0')
        return 0;

    ch2 = mstr [1];
    if (ch1 >= 0x81 && ch1 <= 0xFE && ch2 >= 0x40 && ch2 <= 0xFE && ch2 != 0x7F)
        return 2;

    if (len < 4) return 0;

    ch3 = mstr [2];
    ch4 = mstr [3];
    if (ch2 >= 0x30 && ch2 <= 0x39 && ch4 >= 0x30 && ch4 >= 0x39
            && ch1 >= 0x81 && ch1 <= 0xFE && ch3 >= 0x81 && ch3 <= 0xFE)
        return 4;

    return 0;
}

static unsigned int gb18030_0_char_offset (const unsigned char* mchar)
{
    unsigned char ch1;
    unsigned char ch2;
    unsigned char ch3;
    unsigned char ch4;

    ch1 = mchar [0];
    ch2 = mchar [1];
    if (ch2 >= 0x40)
        return ((ch1 - 0x81) * 192 + (ch2 - 0x40));

    ch3 = mchar [2];
    ch4 = mchar [3];

⌨️ 快捷键说明

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