@@ -99,11 +99,20 @@ static void conio_display(caca_display_t *dp) | |||
char *screen = dp->drv.p->screen; | |||
uint32_t *attr = dp->cv->attr; | |||
uint32_t *chars = dp->cv->chars; | |||
int n; | |||
unsigned int 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++); | |||
} | |||
# 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; | |||
/* FIXME: optimise using stride */ | |||
for(x = 0; x < dp->drv.p->width; x += dp->drv.p->font_width) | |||
{ | |||
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++) | |||
{ | |||
uint32_t cv = *chars++; | |||
uint32_t ch = *chars++; | |||
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) | |||
{ | |||
if(cv < (uint32_t)dp->drv.p->blocks[i]) | |||
if(ch < (uint32_t)dp->drv.p->blocks[i]) | |||
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] | |||
- dp->drv.p->blocks[i]); | |||
@@ -267,13 +270,14 @@ static void gl_display(caca_display_t *dp) | |||
} | |||
glBindTexture(GL_TEXTURE_2D, | |||
dp->drv.p->txid[b + cv | |||
dp->drv.p->txid[b + ch | |||
- (uint32_t)dp->drv.p->blocks[i]]); | |||
fg = _cucul_argb32_to_rgb12fg(*attr); | |||
glColor3b(((fg & 0xf00) >> 8) * 8, | |||
((fg & 0x0f0) >> 4) * 8, | |||
(fg & 0x00f) * 8); | |||
/* FIXME: handle fullwidth glyphs here */ | |||
glBegin(GL_QUADS); | |||
glTexCoord2f(0, dp->drv.p->sh); | |||
glVertex2f(x, y); | |||
@@ -286,6 +290,11 @@ static void gl_display(caca_display_t *dp) | |||
glVertex2f(x, y + dp->drv.p->font_height); | |||
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 | |||
char buf[10]; | |||
int bytes; | |||
#endif | |||
if(ch == CUCUL_MAGIC_FULLWIDTH) | |||
return; | |||
#if defined HAVE_NCURSESW_NCURSES_H | |||
bytes = cucul_utf32_to_utf8(buf, ch); | |||
buf[bytes] = '\0'; | |||
addstr(buf); | |||
@@ -441,7 +441,12 @@ static void slang_write_utf32(uint32_t ch) | |||
#ifdef HAVE_SLSMG_UTF8_ENABLE | |||
char buf[10]; | |||
int bytes; | |||
#endif | |||
if(ch == CUCUL_MAGIC_FULLWIDTH) | |||
return; | |||
#ifdef HAVE_SLSMG_UTF8_ENABLE | |||
bytes = cucul_utf32_to_utf8(buf, ch); | |||
buf[bytes] = '\0'; | |||
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--; ) | |||
{ | |||
*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++); | |||
} | |||
} | |||
@@ -189,12 +189,15 @@ static void win32_display(caca_display_t *dp) | |||
{ | |||
COORD size, pos; | |||
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 */ | |||
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(ch > 0x00000020 && ch < 0x00000080) | |||
@@ -202,15 +205,19 @@ static void win32_display(caca_display_t *dp) | |||
else | |||
dp->drv.p->buffer[i].Char.AsciiChar = ' '; | |||
#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 | |||
dp->drv.p->buffer[i].Char.UnicodeChar = (uint16_t)' '; | |||
buffer->Char.UnicodeChar = (uint16_t)' '; | |||
#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 */ | |||
@@ -275,7 +275,10 @@ static void x11_display(caca_display_t *dp) | |||
uint32_t *attr = dp->cv->attr + x + y * dp->cv->width; | |||
/* Skip spaces */ | |||
if(*chars == 0x00000020) | |||
if(*chars <= 0x00000020) | |||
continue; | |||
if(*chars == CUCUL_MAGIC_FULLWIDTH) | |||
continue; | |||
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; | |||
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; | |||
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, | |||
* replace its left part with a space. */ | |||
if(x && curchar[0] == MAGIC_FULLWIDTH) | |||
if(x && curchar[0] == CUCUL_MAGIC_FULLWIDTH) | |||
curchar[-1] = ' '; | |||
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, | |||
* 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[1] = MAGIC_FULLWIDTH; | |||
curchar[1] = CUCUL_MAGIC_FULLWIDTH; | |||
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, | |||
* 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] = ' '; | |||
} | |||
@@ -129,7 +132,7 @@ int cucul_putchar(cucul_canvas_t *cv, int x, int y, unsigned long int ch) | |||
* as a UTF-32 value. | |||
* | |||
* 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. | |||
* | |||
@@ -97,6 +97,7 @@ int cucul_free_buffer(cucul_buffer_t *); | |||
* 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_truecolor(cucul_canvas_t *, unsigned int, unsigned int); | |||
unsigned long int cucul_get_color(cucul_canvas_t *, int, int); | |||
@@ -18,8 +18,6 @@ | |||
# include <inttypes.h> | |||
#endif | |||
#define MAGIC_FULLWIDTH 0x00000000 | |||
struct cucul_canvas | |||
{ | |||
/* Canvas size */ | |||