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

📄 charset.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
** $Id: charset.c,v 1.46 2004/08/30 03:58:57 weiym Exp $
** 
** charset.c: The charset operation set.
** 
** Copyright (C) 2003 Feynman Software
** Copyright (C) 2000 ~ 2002 Wei Yongming.
**
** Current maintainer: Wei Yongming.
**
** Create date: 2000/06/13
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
** TODO:
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>

#include "common.h"
#include "minigui.h"
#include "gdi.h"
#include "charset.h"

/*************** Common Operations for single byte charsets ******************/
static int sb_len_first_char (const unsigned char* mstr, int len)
{
    if (len < 1) return 0;
    if (*mstr != '\0')  return 1;
    return 0;
}

static unsigned int sb_char_offset (const unsigned char* mchar)
{
    return (int)(*mchar);
}

static int sb_nr_chars_in_str (const unsigned char* mstr, int mstrlen)
{
    return mstrlen;
}

static int sb_len_first_substr (const unsigned char* mstr, int mstrlen)
{
    return mstrlen;
}

static int sb_pos_first_char (const unsigned char* mstr, int mstrlen)
{
    return 0;
}

static const unsigned char* sb_get_next_word (const unsigned char* mstr,
                int mstrlen, WORDINFO* word_info)
{
    int i;

    if (mstrlen == 0) return NULL;

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

    for (i = 0; i < mstrlen; i++) {
        switch (mstr [i]) {
        case ' ':
        case '\t':
        case '\n':
        case '\r':
            if (word_info->delimiter == '\0') {
                word_info->delimiter = mstr [i];
                word_info->nr_delimiters ++;
            }
            else if (word_info->delimiter == mstr[i])
                word_info->nr_delimiters ++;
            else
                return mstr + word_info->len + word_info->nr_delimiters;
        break;

        default:
            if (word_info->delimiter != '\0')
                break;

            word_info->len ++;
        }
    }
            
    return mstr + word_info->len + word_info->nr_delimiters;
}

/************************* US-ASCII Specific Operations **********************/
static int ascii_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, "ASCII"))
        return 0;

    return 1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short ascii_conv_to_uc16 (const unsigned char* mchar, int len)
{
    if (*mchar < 128)
        return (unsigned short) (*mchar);
    else
        return '?';
}
#endif

static CHARSETOPS CharsetOps_ascii = {
    128,
    1,
    1,
    FONT_CHARSET_US_ASCII,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    ascii_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    ascii_conv_to_uc16
#endif
};

/************************* ISO8859-1 Specific Operations **********************/
static int iso8859_1_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-1"))
        return 0;

    return 1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short iso8859_1_conv_to_uc16 (const unsigned char* mchar, int len)
{
    return (unsigned short) (*mchar);
}
#endif

static CHARSETOPS CharsetOps_iso8859_1 = {
    256,
    1,
    1,
    FONT_CHARSET_ISO8859_1,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    iso8859_1_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    iso8859_1_conv_to_uc16
#endif
};

#ifdef _LATIN2_SUPPORT

/************************* ISO8859-2 Specific Operations **********************/
static int iso8859_2_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-2"))
        return 0;

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

    return 1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short iso8859_2_unicode_map [] =
{
    0x0104, 0x02D8,
    0x0141, 0x00A4, 0x013D,
    0x015A, 0x00A7, 0x00A8,
    0x0160, 0x015E, 0x0164,
    0x0179, 0x00AD, 0x017D,
    0x017B, 0x00B0, 0x0105,
    0x02DB, 0x0142, 0x00B4,
    0x013E, 0x015B, 0x02C7,
    0x00B8, 0x0161, 0x015F,
    0x0165, 0x017A, 0x02DD,
    0x017E, 0x017C, 0x0154,
    0x00C1, 0x00C2, 0x0102,
    0x00C4, 0x0139, 0x0106,
    0x00C7, 0x010C, 0x00C9,
    0x0118, 0x00CB, 0x011A,
    0x00CD, 0x00CE, 0x010E,
    0x0110, 0x0143, 0x0147,
    0x00D3, 0x00D4, 0x0150,
    0x00D6, 0x00D7, 0x0158,
    0x016E, 0x00DA, 0x0170,
    0x00DC, 0x00DD, 0x0162,
    0x00DF, 0x0155, 0x00E1,
    0x00E2, 0x0103, 0x00E4,
    0x013A, 0x0107, 0x00E7,
    0x010D, 0x00E9, 0x0119,
    0x00EB, 0x011B, 0x00ED,
    0x00EE, 0x010F, 0x0111,
    0x0144, 0x0148, 0x00F3,
    0x00F4, 0x0151, 0x00F6,
    0x00F7, 0x0159, 0x016F,
    0x00FA, 0x0171, 0x00FC,
    0x00FD, 0x0163, 0x02D9
};

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

static CHARSETOPS CharsetOps_iso8859_2 = {
    256,
    1,
    1,
    FONT_CHARSET_ISO8859_2,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    iso8859_2_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    iso8859_2_conv_to_uc16
#endif
};

#endif /* _LATIN2_SUPPORT */

#ifdef _LATIN3_SUPPORT

/************************* ISO8859-3 Specific Operations **********************/
static int iso8859_3_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-3"))
        return 0;

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

    return 1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short iso8859_3_unicode_map [] =
{
    0x0126, 0x02D8, 0x00A3,
    0x00A4, 0x00A5, 0x0124,
    0x00A7, 0x00A8, 0x0130,
    0x015E, 0x011E, 0x0134,
    0x00AD, 0x00AE, 0x017B,
    0x00B0, 0x0127, 0x00B2,
    0x00B3, 0x00B4, 0x00B5,
    0x0125, 0x00B7, 0x00B8,
    0x0131, 0x015F, 0x011F,
    0x0135, 0x00BD, 0x00BE,
    0x017C, 0x00C0, 0x00C1,
    0x00C2, 0x00C3, 0x00C4,
    0x010A, 0x0108, 0x00C7,
    0x00C8, 0x00C9, 0x00CA,
    0x00CB, 0x00CC, 0x00CD,
    0x00CE, 0x00CF, 0x00D0,
    0x00D1, 0x00D2, 0x00D3,
    0x00D4, 0x0120, 0x00D6,
    0x00D7, 0x011C, 0x00D9,
    0x00DA, 0x00DB, 0x00DC,
    0x016C, 0x015C, 0x00DF,
    0x00E0, 0x00E1, 0x00E2,
    0x00E3, 0x00E4, 0x010B,
    0x0109, 0x00E7, 0x00E8,
    0x00E9, 0x00EA, 0x00EB,
    0x00EC, 0x00ED, 0x00EE,
    0x00EF, 0x00F0, 0x00F1,
    0x00F2, 0x00F3, 0x00F4,
    0x0121, 0x00F6, 0x00F7,
    0x011D, 0x00F9, 0x00FA,
    0x00FB, 0x00FC, 0x016D,
    0x015D, 0x02D9
};

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

static CHARSETOPS CharsetOps_iso8859_3 = {
    256,
    1,
    1,
    FONT_CHARSET_ISO8859_3,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    iso8859_3_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    iso8859_3_conv_to_uc16
#endif
};

#endif /* _LATIN4_SUPPORT */

#ifdef _LATIN4_SUPPORT

/************************* ISO8859-4 Specific Operations **********************/
static int iso8859_4_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-4"))
        return 0;

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

    return 1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short iso8859_4_unicode_map [] =
{
    0x0104, 0x0138, 0x0156,
    0x00A4, 0x0128, 0x013B,
    0x00A7, 0x00A8, 0x0160,
    0x0112, 0x0122, 0x0166,
    0x00AD, 0x017D, 0x00AF,
    0x00B0, 0x0105, 0x02DB,
    0x0157, 0x00B4, 0x0129,
    0x013C, 0x02C7, 0x00B8,
    0x0161, 0x0113, 0x0123,
    0x0167, 0x014A, 0x017E,
    0x014B, 0x0100, 0x00C1,
    0x00C2, 0x00C3, 0x00C4,
    0x00C5, 0x00C6, 0x012E,
    0x010C, 0x00C9, 0x0118,
    0x00CB, 0x0116, 0x00CD,
    0x00CE, 0x012A, 0x0110,
    0x0145, 0x014C, 0x0136,
    0x00D4, 0x00D5, 0x00D6,
    0x00D7, 0x00D8, 0x0172,
    0x00DA, 0x00DB, 0x00DC,
    0x0168, 0x016A, 0x00DF,
    0x0101, 0x00E1, 0x00E2,
    0x00E3, 0x00E4, 0x00E5,
    0x00E6, 0x012F, 0x010D,
    0x00E9, 0x0119, 0x00EB,
    0x0117, 0x00ED, 0x00EE,
    0x012B, 0x0111, 0x0146,
    0x014D, 0x0137, 0x00F4,
    0x00F5, 0x00F6, 0x00F7,
    0x00F8, 0x0173, 0x00FA,
    0x00FB, 0x00FC, 0x0169,
    0x016B, 0x02D9
};

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

static CHARSETOPS CharsetOps_iso8859_4 = {
    256,
    1,
    1,
    FONT_CHARSET_ISO8859_4,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    iso8859_4_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    iso8859_4_conv_to_uc16
#endif
};

#endif /* _LATIN4_SUPPORT */

#ifdef _CYRILLIC_SUPPORT

/************************* ISO8859-5 Specific Operations **********************/
static int iso8859_5_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-5"))
        return 0;

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

    return 1;
}

#ifdef _UNICODE_SUPPORT
static unsigned short iso8859_5_conv_to_uc16 (const unsigned char* mchar, int len)
{
    if (*mchar < 0xA1)
        return (unsigned short) (*mchar);
   
    if (*mchar == 0xAD)
        return 0x00AD;  /* SOFT HYPHEN */

    if (*mchar == 0xF0)
        return 0x2116;  /* NUMERO SIGN */

    if (*mchar == 0xFD)
        return 0x00A7;  /* SECTION SIGN */

    return *mchar + (0x0401 - 0xA1);
}
#endif

static CHARSETOPS CharsetOps_iso8859_5 = {
    256,
    1,
    1,
    FONT_CHARSET_ISO8859_5,
    {' '},
    sb_len_first_char,
    sb_char_offset,
    sb_nr_chars_in_str,
    iso8859_5_is_this_charset,
    sb_len_first_substr,
    sb_get_next_word,
    sb_pos_first_char,
#ifdef _UNICODE_SUPPORT
    iso8859_5_conv_to_uc16
#endif
};

#endif /* _CYRILLIC_SUPPORT */

#ifdef _ARABIC_SUPPORT

/************************* ISO8859-6 Specific Operations **********************/
static int iso8859_6_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-6"))
        return 0;

⌨️ 快捷键说明

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