| @@ -99,11 +99,20 @@ static void conio_display(caca_display_t *dp) | |||||
| char *screen = dp->drv.p->screen; | char *screen = dp->drv.p->screen; | ||||
| uint32_t *attr = dp->cv->attr; | uint32_t *attr = dp->cv->attr; | ||||
| uint32_t *chars = dp->cv->chars; | uint32_t *chars = dp->cv->chars; | ||||
| int n; | |||||
| unsigned int n; | |||||
| for(n = dp->cv->height * dp->cv->width; n--; ) | for(n = dp->cv->height * dp->cv->width; n--; ) | ||||
| { | { | ||||
| *screen++ = cucul_utf32_to_cp437(*chars++); | |||||
| char ch = cucul_utf32_to_cp437(*chars++); | |||||
| if(n && *chars == CUCUL_MAGIC_FULLWIDTH) | |||||
| { | |||||
| *screen++ = '['; | |||||
| *screen++ = _cucul_argb32_to_ansi8(*attr++); | |||||
| ch = ']'; | |||||
| chars++; | |||||
| n--; | |||||
| } | |||||
| *screen++ = ch; | |||||
| *screen++ = _cucul_argb32_to_ansi8(*attr++); | *screen++ = _cucul_argb32_to_ansi8(*attr++); | ||||
| } | } | ||||
| # if defined(SCREENUPDATE_IN_PC_H) | # if defined(SCREENUPDATE_IN_PC_H) | ||||
| @@ -218,6 +218,7 @@ static void gl_display(caca_display_t *dp) | |||||
| { | { | ||||
| uint32_t *attr = dp->cv->attr + line * dp->cv->width; | uint32_t *attr = dp->cv->attr + line * dp->cv->width; | ||||
| /* FIXME: optimise using stride */ | |||||
| for(x = 0; x < dp->drv.p->width; x += dp->drv.p->font_width) | for(x = 0; x < dp->drv.p->width; x += dp->drv.p->font_width) | ||||
| { | { | ||||
| uint16_t bg = _cucul_argb32_to_rgb12bg(*attr++); | uint16_t bg = _cucul_argb32_to_rgb12bg(*attr++); | ||||
| @@ -250,16 +251,18 @@ static void gl_display(caca_display_t *dp) | |||||
| for(x = 0; x < dp->drv.p->width; x += dp->drv.p->font_width, attr++) | for(x = 0; x < dp->drv.p->width; x += dp->drv.p->font_width, attr++) | ||||
| { | { | ||||
| uint32_t cv = *chars++; | |||||
| uint32_t ch = *chars++; | |||||
| uint16_t fg; | uint16_t fg; | ||||
| int i, b; | |||||
| int i, b, fullwidth; | |||||
| fullwidth = cucul_utf32_is_fullwidth(ch); | |||||
| for(b = 0, i = 0; dp->drv.p->blocks[i + 1]; i += 2) | for(b = 0, i = 0; dp->drv.p->blocks[i + 1]; i += 2) | ||||
| { | { | ||||
| if(cv < (uint32_t)dp->drv.p->blocks[i]) | |||||
| if(ch < (uint32_t)dp->drv.p->blocks[i]) | |||||
| break; | break; | ||||
| if(cv >= (uint32_t)dp->drv.p->blocks[i + 1]) | |||||
| if(ch >= (uint32_t)dp->drv.p->blocks[i + 1]) | |||||
| { | { | ||||
| b += (uint32_t)(dp->drv.p->blocks[i + 1] | b += (uint32_t)(dp->drv.p->blocks[i + 1] | ||||
| - dp->drv.p->blocks[i]); | - dp->drv.p->blocks[i]); | ||||
| @@ -267,13 +270,14 @@ static void gl_display(caca_display_t *dp) | |||||
| } | } | ||||
| glBindTexture(GL_TEXTURE_2D, | glBindTexture(GL_TEXTURE_2D, | ||||
| dp->drv.p->txid[b + cv | |||||
| dp->drv.p->txid[b + ch | |||||
| - (uint32_t)dp->drv.p->blocks[i]]); | - (uint32_t)dp->drv.p->blocks[i]]); | ||||
| fg = _cucul_argb32_to_rgb12fg(*attr); | fg = _cucul_argb32_to_rgb12fg(*attr); | ||||
| glColor3b(((fg & 0xf00) >> 8) * 8, | glColor3b(((fg & 0xf00) >> 8) * 8, | ||||
| ((fg & 0x0f0) >> 4) * 8, | ((fg & 0x0f0) >> 4) * 8, | ||||
| (fg & 0x00f) * 8); | (fg & 0x00f) * 8); | ||||
| /* FIXME: handle fullwidth glyphs here */ | |||||
| glBegin(GL_QUADS); | glBegin(GL_QUADS); | ||||
| glTexCoord2f(0, dp->drv.p->sh); | glTexCoord2f(0, dp->drv.p->sh); | ||||
| glVertex2f(x, y); | glVertex2f(x, y); | ||||
| @@ -286,6 +290,11 @@ static void gl_display(caca_display_t *dp) | |||||
| glVertex2f(x, y + dp->drv.p->font_height); | glVertex2f(x, y + dp->drv.p->font_height); | ||||
| glEnd(); | glEnd(); | ||||
| } | } | ||||
| if(fullwidth) | |||||
| { | |||||
| chars++; attr++; x += dp->drv.p->font_width; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -434,7 +434,12 @@ static void ncurses_write_utf32(uint32_t ch) | |||||
| #if defined HAVE_NCURSESW_NCURSES_H | #if defined HAVE_NCURSESW_NCURSES_H | ||||
| char buf[10]; | char buf[10]; | ||||
| int bytes; | int bytes; | ||||
| #endif | |||||
| if(ch == CUCUL_MAGIC_FULLWIDTH) | |||||
| return; | |||||
| #if defined HAVE_NCURSESW_NCURSES_H | |||||
| bytes = cucul_utf32_to_utf8(buf, ch); | bytes = cucul_utf32_to_utf8(buf, ch); | ||||
| buf[bytes] = '\0'; | buf[bytes] = '\0'; | ||||
| addstr(buf); | addstr(buf); | ||||
| @@ -441,7 +441,12 @@ static void slang_write_utf32(uint32_t ch) | |||||
| #ifdef HAVE_SLSMG_UTF8_ENABLE | #ifdef HAVE_SLSMG_UTF8_ENABLE | ||||
| char buf[10]; | char buf[10]; | ||||
| int bytes; | int bytes; | ||||
| #endif | |||||
| if(ch == CUCUL_MAGIC_FULLWIDTH) | |||||
| return; | |||||
| #ifdef HAVE_SLSMG_UTF8_ENABLE | |||||
| bytes = cucul_utf32_to_utf8(buf, ch); | bytes = cucul_utf32_to_utf8(buf, ch); | ||||
| buf[bytes] = '\0'; | buf[bytes] = '\0'; | ||||
| SLsmg_write_string(buf); | SLsmg_write_string(buf); | ||||
| @@ -121,7 +121,16 @@ static void vga_display(caca_display_t *dp) | |||||
| for(n = dp->cv->height * dp->cv->width; n--; ) | for(n = dp->cv->height * dp->cv->width; n--; ) | ||||
| { | { | ||||
| *screen++ = cucul_utf32_to_cp437(*chars++); | |||||
| char ch = cucul_utf32_to_cp437(*chars++); | |||||
| if(n && *chars == CUCUL_MAGIC_FULLWIDTH) | |||||
| { | |||||
| *screen++ = '['; | |||||
| *screen++ = _cucul_argb32_to_ansi8(*attr++); | |||||
| ch = ']'; | |||||
| chars++; | |||||
| n--; | |||||
| } | |||||
| *screen++ = ch; | |||||
| *screen++ = _cucul_argb32_to_ansi8(*attr++); | *screen++ = _cucul_argb32_to_ansi8(*attr++); | ||||
| } | } | ||||
| } | } | ||||
| @@ -189,12 +189,15 @@ static void win32_display(caca_display_t *dp) | |||||
| { | { | ||||
| COORD size, pos; | COORD size, pos; | ||||
| SMALL_RECT rect; | SMALL_RECT rect; | ||||
| unsigned int i; | |||||
| CHAR_INFO *buffer = dp->drv.p->buffer; | |||||
| uint32_t *attr = dp->cv->attr; | |||||
| uint32_t *chars = dp->cv->chars; | |||||
| unsigned int n; | |||||
| /* Render everything to our screen buffer */ | /* Render everything to our screen buffer */ | ||||
| for(i = 0; i < dp->cv->width * dp->cv->height; i++) | |||||
| for(n = dp->cv->height * dp->cv->width; n--; ) | |||||
| { | { | ||||
| uint32_t ch = dp->cv->chars[i]; | |||||
| uint32_t ch = *chars++; | |||||
| #if 0 | #if 0 | ||||
| if(ch > 0x00000020 && ch < 0x00000080) | if(ch > 0x00000020 && ch < 0x00000080) | ||||
| @@ -202,15 +205,19 @@ static void win32_display(caca_display_t *dp) | |||||
| else | else | ||||
| dp->drv.p->buffer[i].Char.AsciiChar = ' '; | dp->drv.p->buffer[i].Char.AsciiChar = ' '; | ||||
| #else | #else | ||||
| if(ch > 0x00000020 && ch < 0x00010000) | |||||
| dp->drv.p->buffer[i].Char.UnicodeChar = (uint16_t)ch; | |||||
| if(n && *chars == CUCUL_MAGIC_FULLWIDTH) | |||||
| ; | |||||
| else if(ch > 0x00000020 && ch < 0x00010000) | |||||
| buffer->Char.UnicodeChar = (uint16_t)ch; | |||||
| else | else | ||||
| dp->drv.p->buffer[i].Char.UnicodeChar = (uint16_t)' '; | |||||
| buffer->Char.UnicodeChar = (uint16_t)' '; | |||||
| #endif | #endif | ||||
| dp->drv.p->buffer[i].Attributes = | |||||
| win32_fg_palette[_cucul_argb32_to_ansi4fg(dp->cv->attr[i])] | |||||
| | win32_bg_palette[_cucul_argb32_to_ansi4bg(dp->cv->attr[i])]; | |||||
| buffer->Attributes = | |||||
| win32_fg_palette[_cucul_argb32_to_ansi4fg(*attr)] | |||||
| | win32_bg_palette[_cucul_argb32_to_ansi4bg(*attr)]; | |||||
| attr++; | |||||
| buffer++; | |||||
| } | } | ||||
| /* Blit the screen buffer */ | /* Blit the screen buffer */ | ||||
| @@ -275,7 +275,10 @@ static void x11_display(caca_display_t *dp) | |||||
| uint32_t *attr = dp->cv->attr + x + y * dp->cv->width; | uint32_t *attr = dp->cv->attr + x + y * dp->cv->width; | ||||
| /* Skip spaces */ | /* Skip spaces */ | ||||
| if(*chars == 0x00000020) | |||||
| if(*chars <= 0x00000020) | |||||
| continue; | |||||
| if(*chars == CUCUL_MAGIC_FULLWIDTH) | |||||
| continue; | continue; | ||||
| XSetForeground(dp->drv.p->dpy, dp->drv.p->gc, | XSetForeground(dp->drv.p->dpy, dp->drv.p->gc, | ||||
| @@ -69,7 +69,10 @@ int cucul_putchar(cucul_canvas_t *cv, int x, int y, unsigned long int ch) | |||||
| uint32_t *curchar, *curattr, attr; | uint32_t *curchar, *curattr, attr; | ||||
| int fullwidth; | int fullwidth; | ||||
| if(!ch || x >= (int)cv->width || y < 0 || y >= (int)cv->height) | |||||
| if(x >= (int)cv->width || y < 0 || y >= (int)cv->height) | |||||
| return 0; | |||||
| if(ch == CUCUL_MAGIC_FULLWIDTH) | |||||
| return 0; | return 0; | ||||
| fullwidth = cucul_utf32_is_fullwidth(ch); | fullwidth = cucul_utf32_is_fullwidth(ch); | ||||
| @@ -89,7 +92,7 @@ int cucul_putchar(cucul_canvas_t *cv, int x, int y, unsigned long int ch) | |||||
| /* When overwriting the right part of a fullwidth character, | /* When overwriting the right part of a fullwidth character, | ||||
| * replace its left part with a space. */ | * replace its left part with a space. */ | ||||
| if(x && curchar[0] == MAGIC_FULLWIDTH) | |||||
| if(x && curchar[0] == CUCUL_MAGIC_FULLWIDTH) | |||||
| curchar[-1] = ' '; | curchar[-1] = ' '; | ||||
| if(fullwidth) | if(fullwidth) | ||||
| @@ -100,10 +103,10 @@ int cucul_putchar(cucul_canvas_t *cv, int x, int y, unsigned long int ch) | |||||
| { | { | ||||
| /* When overwriting the left part of a fullwidth character, | /* When overwriting the left part of a fullwidth character, | ||||
| * replace its right part with a space. */ | * replace its right part with a space. */ | ||||
| if(x + 2 < (int)cv->width && curchar[2] == MAGIC_FULLWIDTH) | |||||
| if(x + 2 < (int)cv->width && curchar[2] == CUCUL_MAGIC_FULLWIDTH) | |||||
| curchar[2] = ' '; | curchar[2] = ' '; | ||||
| curchar[1] = MAGIC_FULLWIDTH; | |||||
| curchar[1] = CUCUL_MAGIC_FULLWIDTH; | |||||
| curattr[1] = attr; | curattr[1] = attr; | ||||
| } | } | ||||
| } | } | ||||
| @@ -111,7 +114,7 @@ int cucul_putchar(cucul_canvas_t *cv, int x, int y, unsigned long int ch) | |||||
| { | { | ||||
| /* When overwriting the left part of a fullwidth character, | /* When overwriting the left part of a fullwidth character, | ||||
| * replace its right part with a space. */ | * replace its right part with a space. */ | ||||
| if(x + 1 != (int)cv->width && curchar[1] == MAGIC_FULLWIDTH) | |||||
| if(x + 1 != (int)cv->width && curchar[1] == CUCUL_MAGIC_FULLWIDTH) | |||||
| curchar[1] = ' '; | curchar[1] = ' '; | ||||
| } | } | ||||
| @@ -129,7 +132,7 @@ int cucul_putchar(cucul_canvas_t *cv, int x, int y, unsigned long int ch) | |||||
| * as a UTF-32 value. | * as a UTF-32 value. | ||||
| * | * | ||||
| * If the coordinates are outside the canvas boundaries, a space (0x20) | * If the coordinates are outside the canvas boundaries, a space (0x20) | ||||
| * is returned. FIXME: explain MAGIC_FULLWIDTH | |||||
| * is returned. FIXME: explain CUCUL_MAGIC_FULLWIDTH | |||||
| * | * | ||||
| * This function never fails. | * This function never fails. | ||||
| * | * | ||||
| @@ -97,6 +97,7 @@ int cucul_free_buffer(cucul_buffer_t *); | |||||
| * higher level graphics functions. | * higher level graphics functions. | ||||
| * | * | ||||
| * @{ */ | * @{ */ | ||||
| #define CUCUL_MAGIC_FULLWIDTH 0x000ffffe /**< Used to indicate that the previous character was a fullwidth glyph. */ | |||||
| int cucul_set_color(cucul_canvas_t *, unsigned char, unsigned char); | int cucul_set_color(cucul_canvas_t *, unsigned char, unsigned char); | ||||
| int cucul_set_truecolor(cucul_canvas_t *, unsigned int, unsigned int); | int cucul_set_truecolor(cucul_canvas_t *, unsigned int, unsigned int); | ||||
| unsigned long int cucul_get_color(cucul_canvas_t *, int, int); | unsigned long int cucul_get_color(cucul_canvas_t *, int, int); | ||||
| @@ -18,8 +18,6 @@ | |||||
| # include <inttypes.h> | # include <inttypes.h> | ||||
| #endif | #endif | ||||
| #define MAGIC_FULLWIDTH 0x00000000 | |||||
| struct cucul_canvas | struct cucul_canvas | ||||
| { | { | ||||
| /* Canvas size */ | /* Canvas size */ | ||||