symbol.c 4.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

#include "fm.h"

#include "Symbols/alt.sym"
#include "Symbols/graph.sym"
#ifdef USE_M17N
#include "Symbols/eucjp.sym"
#include "Symbols/euckr.sym"
#include "Symbols/euccn.sym"
#include "Symbols/euctw.sym"
#include "Symbols/big5.sym"
#ifdef USE_UNICODE
#include "Symbols/utf8.sym"
#endif
#include "Symbols/cp850.sym"

typedef struct {
    wc_ces ces;
    char width;
    char **item;
21
    char **conved_item;
22 23 24 25 26 27 28 29
} symbol_set;

typedef struct {
    wc_ces charset;
    symbol_set *symbol;
} charset_symbol_set;

/* *INDENT-OFF* */
30 31 32 33 34 35 36
static symbol_set alt_symbol_set   = { WC_CES_US_ASCII, 1, alt_symbol,   alt_symbol };
static symbol_set alt2_symbol_set  = { WC_CES_US_ASCII, 2, alt2_symbol,  alt2_symbol };
static symbol_set eucjp_symbol_set = { WC_CES_EUC_JP,   2, eucjp_symbol, NULL };
static symbol_set euckr_symbol_set = { WC_CES_EUC_KR,   2, euckr_symbol, NULL };
static symbol_set euccn_symbol_set = { WC_CES_EUC_CN,   2, euccn_symbol, NULL };
static symbol_set euctw_symbol_set = { WC_CES_EUC_TW,   2, euctw_symbol, NULL };
static symbol_set big5_symbol_set  = { WC_CES_BIG5,     2, big5_symbol,  NULL };
37
#ifdef USE_UNICODE
38
static symbol_set utf8_symbol_set  = { WC_CES_UTF_8,    1, utf8_symbol,  NULL };
39
#endif
40
static symbol_set cp850_symbol_set = { WC_CES_CP850,    1, cp850_symbol, NULL };
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

static charset_symbol_set charset_symbol_list[] = {
    { WC_CES_EUC_JP,        &eucjp_symbol_set },
    { WC_CES_SHIFT_JIS,     &eucjp_symbol_set },
    { WC_CES_ISO_2022_JP,   &eucjp_symbol_set },
    { WC_CES_ISO_2022_JP_2, &eucjp_symbol_set },
    { WC_CES_ISO_2022_JP_3, &eucjp_symbol_set },
    { WC_CES_EUC_KR,        &euckr_symbol_set },
    { WC_CES_ISO_2022_KR,   &euckr_symbol_set },
    { WC_CES_JOHAB,         &euckr_symbol_set },
    { WC_CES_UHC,           &euckr_symbol_set },
    { WC_CES_EUC_CN,        &euccn_symbol_set },
    { WC_CES_GBK,           &euccn_symbol_set },
    { WC_CES_GB18030,       &euccn_symbol_set },
    { WC_CES_HZ_GB_2312,    &euccn_symbol_set },
    { WC_CES_ISO_2022_CN,   &euccn_symbol_set },
    { WC_CES_EUC_TW,        &euctw_symbol_set },
    { WC_CES_BIG5,          &big5_symbol_set  },
    { WC_CES_HKSCS,         &big5_symbol_set  },
#ifdef USE_UNICODE
    { WC_CES_UTF_8,         &utf8_symbol_set  },
#endif
    { WC_CES_CP850,         &cp850_symbol_set },
    { 0, NULL },
};
/* *INDENT-ON* */

static wc_ces save_charset = 0;
static symbol_set *save_symbol = NULL;

static void
encode_symbol(symbol_set * s)
{
    int i;

76 77
    for (i = 0; s->item[i]; i++) ;
    s->conved_item = New_N(char *, i);
78 79
    for (i = 0; s->item[i]; i++) {
	if (*(s->item[i]))
80
	    s->conved_item[i] = wc_conv(s->item[i], s->ces, InnerCharset)->ptr;
81 82 83 84 85 86 87 88 89
    }
}

char **
get_symbol(wc_ces charset, int *width)
{
    charset_symbol_set *p;
    symbol_set *s = NULL;

90 91 92 93
    if (UseGraphicChar != GRAPHIC_CHAR_ASCII) {
	if (charset == save_charset && save_symbol != NULL &&
	    *width == save_symbol->width) {
	    return save_symbol->conved_item;
94
	}
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
	save_charset = charset;
	for (p = charset_symbol_list; p->charset; p++) {
	    if (charset == p->charset &&
		(*width == 0 || *width == p->symbol->width)) {
		s = p->symbol;
		break;
	    }
	}
	if (s == NULL)
	    s = (*width == 2) ? &alt2_symbol_set : &alt_symbol_set;
	if (s != save_symbol) {
	    if (!s->conved_item)
		encode_symbol(s);
	    save_symbol = s;
	}
    } else {
	if (save_symbol != NULL && *width == save_symbol->width)
	    return save_symbol->conved_item;
113 114 115 116
	s = (*width == 2) ? &alt2_symbol_set : &alt_symbol_set;
	save_symbol = s;
    }
    *width = s->width;
117
    return s->conved_item;
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
}

char **
set_symbol(int width)
{
    static char **symbol_buf = NULL;
    static int save_width = -1;
    symbol_set *s = &alt_symbol_set;
    int i;
    Str tmp;

    if (width == save_width)
	return symbol_buf;
    if (symbol_buf == NULL) {
	for (i = 0; s->item[i]; i++) ;
	symbol_buf = New_N(char *, i);
    }
    for (i = 0; s->item[i]; i++) {
	tmp = Strnew_size(4);
	if (width == 2)
	    wtf_push(tmp, WC_CCS_SPECIAL_W, (wc_uint32) (SYMBOL_BASE + i));
	else
	    wtf_push(tmp, WC_CCS_SPECIAL, (wc_uint32) (SYMBOL_BASE + i));
	symbol_buf[i] = tmp->ptr;
    }
    save_width = width;
    return symbol_buf;
}

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
#ifdef USE_UNICODE
void
update_utf8_symbol(void)
{
    charset_symbol_set *p;
    utf8_symbol_set.width = WcOption.east_asian_width ? 2 : 1;
    for (p = charset_symbol_list; p->charset; p++) {
	if (p->charset == WC_CES_UTF_8) {
	    encode_symbol(p->symbol);
	    break;
	}
    }
}
#endif

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
#else

char **
get_symbol(void)
{
    return alt_symbol;
}
#endif

void
push_symbol(Str str, char symbol, int width, int n)
{
    char buf[2], *p;
    int i;

#ifdef USE_M17N
    if (width == 2)
179
	p = alt2_symbol[(unsigned char)symbol % N_SYMBOL];
180 181
    else
#endif
182
	p = alt_symbol[(unsigned char)symbol % N_SYMBOL];
183 184 185 186 187 188 189 190
    for (i = 0; i < 2 && *p; i++, p++)
	buf[i] = (*p == ' ') ? NBSP_CODE : *p;

    Strcat(str, Sprintf("<_SYMBOL TYPE=%d>", symbol));
    for (; n > 0; n--)
	Strcat_charp_n(str, buf, i);
    Strcat_charp(str, "</_SYMBOL>");
}