* Use that in the SLang driver so that it supports UTF-8 input.tags/v0.99.beta14
@@ -211,17 +211,16 @@ static void slang_display(caca_display_t *dp) | |||
uint32_t ch = *chars++; | |||
#if defined(OPTIMISE_SLANG_PALETTE) | |||
/* If foreground == background, just don't use this colour | |||
* pair, and print a space instead of the real character. | |||
* XXX: disabled, because I can't remember what it was | |||
* here for, and in cases where SLang does not render | |||
* bright backgrounds, it's just fucked up. */ | |||
#if 0 | |||
uint8_t fgcolor = _cucul_argb32_to_ansi4fg(*attr); | |||
uint8_t bgcolor = _cucul_argb32_to_ansi4bg(*attr); | |||
/* If foreground == background, just don't use this colour | |||
* pair, and print a space instead of the real character. */ | |||
if(fgcolor != bgcolor) | |||
{ | |||
SLsmg_set_color(slang_assoc[_cucul_argb32_to_ansi8(*attr++)]); | |||
slang_write_utf32(ch); | |||
} | |||
else | |||
if(fgcolor == bgcolor) | |||
{ | |||
if(fgcolor == CUCUL_COLOR_BLACK) | |||
fgcolor = CUCUL_COLOR_WHITE; | |||
@@ -234,6 +233,12 @@ static void slang_display(caca_display_t *dp) | |||
SLsmg_write_char(' '); | |||
attr++; | |||
} | |||
else | |||
#endif | |||
{ | |||
SLsmg_set_color(slang_assoc[_cucul_argb32_to_ansi8(*attr++)]); | |||
slang_write_utf32(ch); | |||
} | |||
#else | |||
SLsmg_set_color(_cucul_argb32_to_ansi8(*attr++)); | |||
slang_write_utf32(ch); | |||
@@ -285,6 +290,41 @@ static int slang_get_event(caca_display_t *dp, caca_event_t *ev) | |||
return 1; | |||
} | |||
/* If the key was UTF-8, parse the whole sequence */ | |||
if(intkey >= 0x80 && intkey < 0x100) | |||
{ | |||
int keys[7]; /* Necessary for ungetkey(); */ | |||
char utf8[7]; | |||
uint32_t utf32; | |||
unsigned int i, bytes = 0; | |||
keys[0] = intkey; | |||
utf8[0] = intkey; | |||
for(i = 1; i < 6; i++) | |||
{ | |||
if(!SLang_input_pending(0)) | |||
break; | |||
keys[i] = SLang_getkey(); | |||
utf8[i] = (unsigned char)keys[i]; | |||
} | |||
utf8[i] = '\0'; | |||
utf32 = cucul_utf8_to_utf32(utf8, &bytes); | |||
while(i > bytes) | |||
SLang_ungetkey(keys[--i]); | |||
if(bytes) | |||
{ | |||
ev->type = CACA_EVENT_KEY_PRESS; | |||
ev->data.key.ch = 0; | |||
ev->data.key.utf32 = utf32; | |||
strcpy(ev->data.key.utf8, utf8); | |||
return 1; | |||
} | |||
} | |||
if(intkey == 0x3e9) | |||
{ | |||
int button = (SLang_getkey() - ' ' + 1) & 0xf; | |||
@@ -338,7 +378,9 @@ static int slang_get_event(caca_display_t *dp, caca_event_t *ev) | |||
case SL_KEY_F(11): ev->data.key.ch = CACA_KEY_F11; break; | |||
case SL_KEY_F(12): ev->data.key.ch = CACA_KEY_F12; break; | |||
default: ev->type = CACA_EVENT_NONE; return 0; | |||
default: | |||
/* Unknown key */ | |||
ev->type = CACA_EVENT_NONE; return 0; | |||
} | |||
ev->type = CACA_EVENT_KEY_PRESS; | |||
@@ -155,7 +155,7 @@ int cucul_fill_box(cucul_canvas_t *cv, int x1, int y1, int x2, int y2, | |||
if(x2 > xmax) x2 = xmax; | |||
if(y2 > ymax) y2 = ymax; | |||
ch = cucul_utf8_to_utf32(str); | |||
ch = cucul_utf8_to_utf32(str, NULL); | |||
for(y = y1; y <= y2; y++) | |||
for(x = x1; x <= x2; x++) | |||
@@ -116,7 +116,7 @@ int cucul_putstr(cucul_canvas_t *cv, int x, int y, char const *s) | |||
while(len) | |||
{ | |||
*chars++ = cucul_utf8_to_utf32(s); | |||
*chars++ = cucul_utf8_to_utf32(s, NULL); | |||
*attr++ = (cv->bgcolor << 16) | cv->fgcolor; | |||
s = _cucul_skip_utf8(s, 1); | |||
@@ -95,31 +95,45 @@ static uint32_t const cp437_lookup2[] = | |||
/** \brief Convert a UTF-8 character to UTF-32. | |||
* | |||
* This function converts a UTF-8 character read from a string and returns | |||
* its value in the UTF-32 character set. | |||
* its value in the UTF-32 character set. If the second argument is not null, | |||
* the total number of read bytes is written in it. | |||
* | |||
* If a null byte was reached before the expected end of the UTF-8 sequence, | |||
* this function returns zero and the number of read bytes is set to zero. | |||
* | |||
* This function never fails, but its behaviour with illegal UTF-8 sequences | |||
* is undefined. | |||
* | |||
* \param s A string containing the UTF-8 character. | |||
* \return The corresponding UTF-32 character. | |||
* \param read A pointer to an unsigned integer to store the number of | |||
* bytes in the character, or NULL. | |||
* \return The corresponding UTF-32 character, or zero if the character | |||
* is incomplete. | |||
*/ | |||
unsigned long int cucul_utf8_to_utf32(char const *s) | |||
unsigned long int cucul_utf8_to_utf32(char const *s, unsigned int *read) | |||
{ | |||
int bytes = trailing[(int)(unsigned char)*s]; | |||
unsigned int bytes = trailing[(int)(unsigned char)*s]; | |||
unsigned int i = 0; | |||
uint32_t ret = 0; | |||
switch(bytes) | |||
for(;;) | |||
{ | |||
/* FIXME: do something for invalid sequences (4 and 5) */ | |||
case 3: ret += (uint8_t)*s++; ret <<= 6; | |||
case 2: ret += (uint8_t)*s++; ret <<= 6; | |||
case 1: ret += (uint8_t)*s++; ret <<= 6; | |||
case 0: ret += (uint8_t)*s++; | |||
if(!*s) | |||
{ | |||
if(read) | |||
*read = 0; | |||
return 0; | |||
} | |||
ret += ((uint32_t)(unsigned char)*s++) << (6 * (bytes - i)); | |||
if(bytes == i++) | |||
{ | |||
if(read) | |||
*read = i; | |||
return ret - offsets[bytes]; | |||
} | |||
} | |||
ret -= offsets[bytes]; | |||
return ret; | |||
} | |||
/** \brief Convert a UTF-32 character to UTF-8. | |||
@@ -43,7 +43,7 @@ static void ellipsepoints(cucul_canvas_t *, int, int, int, int, uint32_t); | |||
int cucul_draw_circle(cucul_canvas_t *cv, int x, int y, int r, char const *str) | |||
{ | |||
int test, dx, dy; | |||
uint32_t ch = cucul_utf8_to_utf32(str); | |||
uint32_t ch = cucul_utf8_to_utf32(str, NULL); | |||
/* Optimized Bresenham. Kick ass. */ | |||
for(test = 0, dx = 0, dy = r ; dx <= dy ; dx++) | |||
@@ -138,7 +138,7 @@ int cucul_draw_ellipse(cucul_canvas_t *cv, int xo, int yo, int a, int b, | |||
int x = 0; | |||
int y = b; | |||
int d1 = b*b - (a*a*b) + (a*a/4); | |||
uint32_t ch = cucul_utf8_to_utf32(str); | |||
uint32_t ch = cucul_utf8_to_utf32(str, NULL); | |||
ellipsepoints(cv, xo, yo, x, y, ch); | |||
@@ -123,7 +123,7 @@ int cucul_rotate(cucul_canvas_t *); | |||
* These functions perform conversions between usual character sets. | |||
* | |||
* @{ */ | |||
extern unsigned long int cucul_utf8_to_utf32(char const *); | |||
extern unsigned long int cucul_utf8_to_utf32(char const *, unsigned int *); | |||
extern unsigned int cucul_utf32_to_utf8(char *, unsigned long int); | |||
extern unsigned char cucul_utf32_to_cp437(unsigned long int); | |||
extern unsigned long int cucul_cp437_to_utf32(unsigned char); | |||
@@ -61,7 +61,7 @@ int cucul_draw_line(cucul_canvas_t *cv, int x1, int y1, int x2, int y2, | |||
s.y1 = y1; | |||
s.x2 = x2; | |||
s.y2 = y2; | |||
s.ch = cucul_utf8_to_utf32(str); | |||
s.ch = cucul_utf8_to_utf32(str, NULL); | |||
s.draw = draw_solid_line; | |||
clip_line(cv, &s); | |||
@@ -89,7 +89,7 @@ int cucul_draw_polyline(cucul_canvas_t *cv, int const x[], int const y[], | |||
{ | |||
int i; | |||
struct line s; | |||
s.ch = cucul_utf8_to_utf32(str); | |||
s.ch = cucul_utf8_to_utf32(str, NULL); | |||
s.draw = draw_solid_line; | |||
for(i = 0; i < n; i++) | |||
@@ -109,7 +109,7 @@ int cucul_fill_triangle(cucul_canvas_t *cv, int x1, int y1, int x2, int y2, | |||
xmax = cv->width - 1; | |||
ymax = cv->height - 1; | |||
ch = cucul_utf8_to_utf32(str); | |||
ch = cucul_utf8_to_utf32(str, NULL); | |||
/* Rasterize our triangle */ | |||
for(y = y1 < 0 ? 0 : y1; y <= y3 && y <= ymax; y++) | |||