Browse Source

* Support for fullwidth glyphs in the libcaca output drivers.

tags/v0.99.beta14
Sam Hocevar sam 19 years ago
parent
commit
4711611e3f
10 changed files with 75 additions and 26 deletions
  1. +11
    -2
      caca/driver_conio.c
  2. +14
    -5
      caca/driver_gl.c
  3. +5
    -0
      caca/driver_ncurses.c
  4. +5
    -0
      caca/driver_slang.c
  5. +10
    -1
      caca/driver_vga.c
  6. +16
    -9
      caca/driver_win32.c
  7. +4
    -1
      caca/driver_x11.c
  8. +9
    -6
      cucul/canvas.c
  9. +1
    -0
      cucul/cucul.h
  10. +0
    -2
      cucul/cucul_internals.h

+ 11
- 2
caca/driver_conio.c View File

@@ -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)


+ 14
- 5
caca/driver_gl.c View File

@@ -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;
}
} }
} }




+ 5
- 0
caca/driver_ncurses.c View File

@@ -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);


+ 5
- 0
caca/driver_slang.c View File

@@ -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);


+ 10
- 1
caca/driver_vga.c View File

@@ -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++);
} }
} }


+ 16
- 9
caca/driver_win32.c View File

@@ -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 */


+ 4
- 1
caca/driver_x11.c View File

@@ -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,


+ 9
- 6
cucul/canvas.c View File

@@ -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.
* *


+ 1
- 0
cucul/cucul.h View File

@@ -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);


+ 0
- 2
cucul/cucul_internals.h View File

@@ -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 */


Loading…
Cancel
Save