* 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++) | |||