Selaa lähdekoodia

* Use the LSB of alpha and blue components to encode additional flags such

as bold or underline. No higher level support for these yet, but at
    least everything is consistent.
  * Created cucul_set_attr_ansi() and cucul_set_attr_argb() which are bound
    to replace cucul_set_color() and cucul_set_truecolor().
tags/v0.99.beta14
Sam Hocevar sam 19 vuotta sitten
vanhempi
commit
86301dd48c
18 muutettua tiedostoa jossa 286 lisäystä ja 195 poistoa
  1. +2
    -1
      caca/caca0.h
  2. +3
    -3
      caca/driver_conio.c
  3. +6
    -6
      caca/driver_gl.c
  4. +2
    -2
      caca/driver_ncurses.c
  5. +6
    -6
      caca/driver_slang.c
  6. +3
    -3
      caca/driver_vga.c
  7. +4
    -4
      caca/driver_win32.c
  8. +5
    -5
      caca/driver_x11.c
  9. +9
    -9
      cucul/canvas.c
  10. +148
    -68
      cucul/colour.c
  11. +22
    -23
      cucul/cucul.c
  12. +17
    -5
      cucul/cucul.h
  13. +11
    -12
      cucul/cucul_internals.h
  14. +29
    -29
      cucul/export.c
  15. +2
    -2
      cucul/font.c
  16. +1
    -1
      cucul/import.c
  17. +10
    -10
      cucul/sprite.c
  18. +6
    -6
      cucul/transform.c

+ 2
- 1
caca/caca0.h Näytä tiedosto

@@ -130,7 +130,8 @@ enum caca_feature
#define caca_get_mouse_y() caca_get_mouse_y(__caca0_dp) #define caca_get_mouse_y() caca_get_mouse_y(__caca0_dp)


#define caca_set_color(x, y) \ #define caca_set_color(x, y) \
(__caca0_fg = (x), __caca0_bg = (y), cucul_set_color(__caca0_cv, x, y))
(__caca0_fg = (x), __caca0_bg = (y), \
cucul_set_attr_ansi(__caca0_cv, x, y, 0))
#define caca_get_fg_color() __caca0_fg #define caca_get_fg_color() __caca0_fg
#define caca_get_bg_color() __caca0_bg #define caca_get_bg_color() __caca0_bg
#define caca_get_color_name cucul_get_color_name #define caca_get_color_name cucul_get_color_name


+ 3
- 3
caca/driver_conio.c Näytä tiedosto

@@ -97,7 +97,7 @@ static unsigned int conio_get_display_height(caca_display_t *dp)
static void conio_display(caca_display_t *dp) 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 *attrs = dp->cv->attrs;
uint32_t *chars = dp->cv->chars; uint32_t *chars = dp->cv->chars;
unsigned int n; unsigned int n;


@@ -107,13 +107,13 @@ static void conio_display(caca_display_t *dp)
if(n && *chars == CUCUL_MAGIC_FULLWIDTH) if(n && *chars == CUCUL_MAGIC_FULLWIDTH)
{ {
*screen++ = '['; *screen++ = '[';
*screen++ = _cucul_argb32_to_ansi8(*attr++);
*screen++ = _cucul_attr_to_ansi8(*attrs++);
ch = ']'; ch = ']';
chars++; chars++;
n--; n--;
} }
*screen++ = ch; *screen++ = ch;
*screen++ = _cucul_argb32_to_ansi8(*attr++);
*screen++ = _cucul_attr_to_ansi8(*attrs++);
} }
# if defined(SCREENUPDATE_IN_PC_H) # if defined(SCREENUPDATE_IN_PC_H)
ScreenUpdate(dp->drv.p->screen); ScreenUpdate(dp->drv.p->screen);


+ 6
- 6
caca/driver_gl.c Näytä tiedosto

@@ -214,12 +214,12 @@ static void gl_display(caca_display_t *dp)
line = 0; line = 0;
for(y = 0; y < dp->drv.p->height; y += dp->drv.p->font_height) for(y = 0; y < dp->drv.p->height; y += dp->drv.p->font_height)
{ {
uint32_t *attr = dp->cv->attr + line * dp->cv->width;
uint32_t *attrs = dp->cv->attrs + line * dp->cv->width;


/* FIXME: optimise using stride */ /* 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_attr_to_rgb12bg(*attrs++);


glColor4b(((bg & 0xf00) >> 8) * 8, glColor4b(((bg & 0xf00) >> 8) * 8,
((bg & 0x0f0) >> 4) * 8, ((bg & 0x0f0) >> 4) * 8,
@@ -244,10 +244,10 @@ static void gl_display(caca_display_t *dp)
line = 0; line = 0;
for(y = 0; y < dp->drv.p->height; y += dp->drv.p->font_height, line++) for(y = 0; y < dp->drv.p->height; y += dp->drv.p->font_height, line++)
{ {
uint32_t *attr = dp->cv->attr + line * dp->cv->width;
uint32_t *attrs = dp->cv->attrs + line * dp->cv->width;
uint32_t *chars = dp->cv->chars + line * dp->cv->width; uint32_t *chars = dp->cv->chars + line * dp->cv->width;


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, attrs++)
{ {
uint32_t ch = *chars++; uint32_t ch = *chars++;
uint16_t fg; uint16_t fg;
@@ -271,7 +271,7 @@ static void gl_display(caca_display_t *dp)
dp->drv.p->txid[b + ch 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_attr_to_rgb12fg(*attrs);
glColor3b(((fg & 0xf00) >> 8) * 8, glColor3b(((fg & 0xf00) >> 8) * 8,
((fg & 0x0f0) >> 4) * 8, ((fg & 0x0f0) >> 4) * 8,
(fg & 0x00f) * 8); (fg & 0x00f) * 8);
@@ -291,7 +291,7 @@ static void gl_display(caca_display_t *dp)


if(fullwidth) if(fullwidth)
{ {
chars++; attr++; x += dp->drv.p->font_width;
chars++; attrs++; x += dp->drv.p->font_width;
} }
} }
} }


+ 2
- 2
caca/driver_ncurses.c Näytä tiedosto

@@ -196,14 +196,14 @@ static unsigned int ncurses_get_display_height(caca_display_t *dp)
static void ncurses_display(caca_display_t *dp) static void ncurses_display(caca_display_t *dp)
{ {
int x, y; int x, y;
uint32_t *attr = dp->cv->attr;
uint32_t *attrs = dp->cv->attrs;
uint32_t *chars = dp->cv->chars; uint32_t *chars = dp->cv->chars;
for(y = 0; y < (int)dp->cv->height; y++) for(y = 0; y < (int)dp->cv->height; y++)
{ {
move(y, 0); move(y, 0);
for(x = dp->cv->width; x--; ) for(x = dp->cv->width; x--; )
{ {
attrset(dp->drv.p->attr[_cucul_argb32_to_ansi8(*attr++)]);
attrset(dp->drv.p->attr[_cucul_attr_to_ansi8(*attrs++)]);
ncurses_write_utf32(*chars++); ncurses_write_utf32(*chars++);
} }
} }


+ 6
- 6
caca/driver_slang.c Näytä tiedosto

@@ -201,7 +201,7 @@ static unsigned int slang_get_display_height(caca_display_t *dp)
static void slang_display(caca_display_t *dp) static void slang_display(caca_display_t *dp)
{ {
int x, y; int x, y;
uint32_t *attr = dp->cv->attr;
uint32_t *attrs = dp->cv->attrs;
uint32_t *chars = dp->cv->chars; uint32_t *chars = dp->cv->chars;
for(y = 0; y < (int)dp->cv->height; y++) for(y = 0; y < (int)dp->cv->height; y++)
{ {
@@ -217,8 +217,8 @@ static void slang_display(caca_display_t *dp)
* here for, and in cases where SLang does not render * here for, and in cases where SLang does not render
* bright backgrounds, it's just fucked up. */ * bright backgrounds, it's just fucked up. */
#if 0 #if 0
uint8_t fgcolor = _cucul_argb32_to_ansi4fg(*attr);
uint8_t bgcolor = _cucul_argb32_to_ansi4bg(*attr);
uint8_t fgcolor = _cucul_attr_to_ansi4fg(*attrs);
uint8_t bgcolor = _cucul_attr_to_ansi4bg(*attrs);


if(fgcolor == bgcolor) if(fgcolor == bgcolor)
{ {
@@ -231,16 +231,16 @@ static void slang_display(caca_display_t *dp)
fgcolor = CUCUL_COLOR_WHITE; fgcolor = CUCUL_COLOR_WHITE;
SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]); SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]);
SLsmg_write_char(' '); SLsmg_write_char(' ');
attr++;
attrs++;
} }
else else
#endif #endif
{ {
SLsmg_set_color(slang_assoc[_cucul_argb32_to_ansi8(*attr++)]);
SLsmg_set_color(slang_assoc[_cucul_attr_to_ansi8(*attrs++)]);
slang_write_utf32(ch); slang_write_utf32(ch);
} }
#else #else
SLsmg_set_color(_cucul_argb32_to_ansi8(*attr++));
SLsmg_set_color(_cucul_attr_to_ansi8(*attrs++));
slang_write_utf32(ch); slang_write_utf32(ch);
#endif #endif
} }


+ 3
- 3
caca/driver_vga.c Näytä tiedosto

@@ -115,7 +115,7 @@ static unsigned int vga_get_display_height(caca_display_t *dp)
static void vga_display(caca_display_t *dp) static void vga_display(caca_display_t *dp)
{ {
char *screen = (char *)(intptr_t)0x000b8000; char *screen = (char *)(intptr_t)0x000b8000;
uint32_t *attr = dp->cv->attr;
uint32_t *attrs = dp->cv->attrs;
uint32_t *chars = dp->cv->chars; uint32_t *chars = dp->cv->chars;
int n; int n;


@@ -125,13 +125,13 @@ static void vga_display(caca_display_t *dp)
if(n && *chars == CUCUL_MAGIC_FULLWIDTH) if(n && *chars == CUCUL_MAGIC_FULLWIDTH)
{ {
*screen++ = '['; *screen++ = '[';
*screen++ = _cucul_argb32_to_ansi8(*attr++);
*screen++ = _cucul_attr_to_ansi8(*attrs++);
ch = ']'; ch = ']';
chars++; chars++;
n--; n--;
} }
*screen++ = ch; *screen++ = ch;
*screen++ = _cucul_argb32_to_ansi8(*attr++);
*screen++ = _cucul_attr_to_ansi8(*attrs++);
} }
} }




+ 4
- 4
caca/driver_win32.c Näytä tiedosto

@@ -190,7 +190,7 @@ static void win32_display(caca_display_t *dp)
COORD size, pos; COORD size, pos;
SMALL_RECT rect; SMALL_RECT rect;
CHAR_INFO *buffer = dp->drv.p->buffer; CHAR_INFO *buffer = dp->drv.p->buffer;
uint32_t *attr = dp->cv->attr;
uint32_t *attrs = dp->cv->attrs;
uint32_t *chars = dp->cv->chars; uint32_t *chars = dp->cv->chars;
unsigned int n; unsigned int n;


@@ -214,9 +214,9 @@ static void win32_display(caca_display_t *dp)
#endif #endif


buffer->Attributes = buffer->Attributes =
win32_fg_palette[_cucul_argb32_to_ansi4fg(*attr)]
| win32_bg_palette[_cucul_argb32_to_ansi4bg(*attr)];
attr++;
win32_fg_palette[_cucul_attr_to_ansi4fg(*attrs)]
| win32_bg_palette[_cucul_attr_to_ansi4bg(*attrs)];
attrs++;
buffer++; buffer++;
} }




+ 5
- 5
caca/driver_x11.c Näytä tiedosto

@@ -246,12 +246,12 @@ static void x11_display(caca_display_t *dp)
{ {
for(x = 0; x < dp->cv->width; x += len) for(x = 0; x < dp->cv->width; x += len)
{ {
uint32_t *attr = dp->cv->attr + x + y * dp->cv->width;
uint16_t bg = _cucul_argb32_to_rgb12bg(*attr);
uint32_t *attrs = dp->cv->attrs + x + y * dp->cv->width;
uint16_t bg = _cucul_attr_to_rgb12bg(*attrs);


len = 1; len = 1;
while(x + len < dp->cv->width while(x + len < dp->cv->width
&& _cucul_argb32_to_rgb12bg(attr[len]) == bg)
&& _cucul_attr_to_rgb12bg(attrs[len]) == bg)
len++; len++;


XSetForeground(dp->drv.p->dpy, dp->drv.p->gc, XSetForeground(dp->drv.p->dpy, dp->drv.p->gc,
@@ -271,7 +271,7 @@ static void x11_display(caca_display_t *dp)


for(x = 0; x < dp->cv->width; x++, chars++) for(x = 0; x < dp->cv->width; x++, chars++)
{ {
uint32_t *attr = dp->cv->attr + x + y * dp->cv->width;
uint32_t *attrs = dp->cv->attrs + x + y * dp->cv->width;


/* Skip spaces */ /* Skip spaces */
if(*chars <= 0x00000020) if(*chars <= 0x00000020)
@@ -281,7 +281,7 @@ static void x11_display(caca_display_t *dp)
continue; continue;


XSetForeground(dp->drv.p->dpy, dp->drv.p->gc, XSetForeground(dp->drv.p->dpy, dp->drv.p->gc,
dp->drv.p->colors[_cucul_argb32_to_rgb12fg(*attr)]);
dp->drv.p->colors[_cucul_attr_to_rgb12fg(*attrs)]);


/* Plain ASCII, no problem. */ /* Plain ASCII, no problem. */
if(*chars > 0x00000020 && *chars < 0x00000080) if(*chars > 0x00000020 && *chars < 0x00000080)


+ 9
- 9
cucul/canvas.c Näytä tiedosto

@@ -86,8 +86,8 @@ int cucul_putchar(cucul_canvas_t *cv, int x, int y, unsigned long int ch)
return 0; return 0;


curchar = cv->chars + x + y * cv->width; curchar = cv->chars + x + y * cv->width;
curattr = cv->attr + x + y * cv->width;
attr = (cv->bgcolor << 16) | cv->fgcolor;
curattr = cv->attrs + x + y * cv->width;
attr = cv->curattr;


/* 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. */
@@ -253,13 +253,13 @@ int cucul_printf(cucul_canvas_t *cv, int x, int y, char const *format, ...)
*/ */
int cucul_clear_canvas(cucul_canvas_t *cv) int cucul_clear_canvas(cucul_canvas_t *cv)
{ {
uint32_t color = (cv->bgcolor << 16) | cv->fgcolor;
uint32_t attr = cv->curattr;
unsigned int n; unsigned int n;


for(n = cv->width * cv->height; n--; ) for(n = cv->width * cv->height; n--; )
{ {
cv->chars[n] = (uint32_t)' '; cv->chars[n] = (uint32_t)' ';
cv->attr[n] = color;
cv->attrs[n] = attr;
} }


return 0; return 0;
@@ -325,13 +325,13 @@ int cucul_blit(cucul_canvas_t *dst, int x, int y,
continue; continue;


dst->chars[dstix + i] = src->chars[srcix + i]; dst->chars[dstix + i] = src->chars[srcix + i];
dst->attr[dstix + i] = src->attr[srcix + i];
dst->attrs[dstix + i] = src->attrs[srcix + i];
} }
} }
else else
{ {
memcpy(dst->chars + dstix, src->chars + srcix, (stride) * 4);
memcpy(dst->attr + dstix, src->attr + srcix, (stride) * 4);
memcpy(dst->chars + dstix, src->chars + srcix, stride * 4);
memcpy(dst->attrs + dstix, src->attrs + srcix, stride * 4);
} }


/* Fix split fullwidth chars */ /* Fix split fullwidth chars */
@@ -392,10 +392,10 @@ int cucul_set_canvas_boundaries(cucul_canvas_t *cv, int x, int y,
cucul_blit(new, -x, -y, cv, NULL); cucul_blit(new, -x, -y, cv, NULL);


free(cv->allchars[f]); free(cv->allchars[f]);
free(cv->allattr[f]);
free(cv->allattrs[f]);
} }
free(cv->allchars); free(cv->allchars);
free(cv->allattr);
free(cv->allattrs);


memcpy(cv, new, sizeof(cucul_canvas_t)); memcpy(cv, new, sizeof(cucul_canvas_t));
free(new); free(new);


+ 148
- 68
cucul/colour.c Näytä tiedosto

@@ -28,33 +28,75 @@


/* RGB colours for the ANSI palette. There is no real standard, so we /* RGB colours for the ANSI palette. There is no real standard, so we
* use the same values as gnome-terminal. The 7th colour (brown) is a bit * use the same values as gnome-terminal. The 7th colour (brown) is a bit
* special. */
* special: 0xfa50 instead of 0xfaa0. */
static const uint16_t ansitab[16] = static const uint16_t ansitab[16] =
{ {
0xf000, 0xf00a, 0xf0a0, 0xf0aa, 0xfa00, 0xfa0a, 0xfa50, 0xfaaa, 0xf000, 0xf00a, 0xf0a0, 0xf0aa, 0xfa00, 0xfa0a, 0xfa50, 0xfaaa,
0xf555, 0xf55f, 0xf5f5, 0xf5ff, 0xff55, 0xff5f, 0xfff5, 0xffff, 0xf555, 0xf55f, 0xf5f5, 0xf5ff, 0xff55, 0xff5f, 0xfff5, 0xffff,
}; };


/** \brief Set the default colour pair.
/** \brief Set the default character attribute.
* *
* Set the default ANSI colour pair for drawing. String functions such as
* Set the default character attribute for drawing. Attributes define
* foreground and background colour, transparency, bold, italics and
* underline styles, as well as blink. String functions such as
* caca_printf() and graphical primitive functions such as caca_draw_line() * caca_printf() and graphical primitive functions such as caca_draw_line()
* will use these colours.
* will use this attribute.
*
* The attribute value is a 32-bit integer as returned by cucul_get_attr().
* For more user-friendly versions of this function, see cucul_set_attr_ansi()
* and cucul_set_attr_argb().
*
* If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c EINVAL The attribute value is out of the 32-bit range.
*
* \param cv A handle to the libcucul canvas.
* \param attr The requested attribute value.
* \return 0 in case of success, -1 if an error occurred.
*/
int cucul_set_attr(cucul_canvas_t *cv, unsigned long int attr)
{
if(sizeof(unsigned long int) > sizeof(uint32_t) && attr > 0xffffffff)
{
#if defined(HAVE_ERRNO_H)
errno = EINVAL;
#endif
return -1;
}

cv->curattr = attr;

return 0;
}

/** \brief Set the default colour pair and text style (ANSI version).
*
* Set the default ANSI colour pair and text style for drawing. String
* functions such as caca_printf() and graphical primitive functions such as
* caca_draw_line() will use these attributes.
* *
* Color values are those defined in cucul.h, such as CUCUL_COLOR_RED * Color values are those defined in cucul.h, such as CUCUL_COLOR_RED
* or CUCUL_COLOR_TRANSPARENT. * or CUCUL_COLOR_TRANSPARENT.
* *
* Style values are those defined in cucul.h, such as CUCUL_STYLE_UNDERLINE
* or CUCUL_STYLE_BLINK. The values can be ORed to set several styles at
* the same time.
*
* If an error occurs, -1 is returned and \b errno is set accordingly: * If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c EINVAL At least one of the colour values is invalid.
* - \c EINVAL The colour values and/or the style mask are invalid.
* *
* \param cv A handle to the libcucul canvas. * \param cv A handle to the libcucul canvas.
* \param fg The requested foreground colour. * \param fg The requested foreground colour.
* \param bg The requested background colour. * \param bg The requested background colour.
* \param style The requested text styles.
* \return 0 in case of success, -1 if an error occurred. * \return 0 in case of success, -1 if an error occurred.
*/ */
int cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg)
int cucul_set_attr_ansi(cucul_canvas_t *cv, unsigned char fg, unsigned char bg,
unsigned char style)
{ {
if(fg > 0x20 || bg > 0x20)
uint32_t attr;

if(fg > 0x20 || bg > 0x20 || style > 0x0f)
{ {
#if defined(HAVE_ERRNO_H) #if defined(HAVE_ERRNO_H)
errno = EINVAL; errno = EINVAL;
@@ -62,33 +104,51 @@ int cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg)
return -1; return -1;
} }


cv->fgcolor = fg;
cv->bgcolor = bg;
attr = ((uint32_t)bg << 20) | ((uint32_t)fg << 4);

if(style)
attr |= (0x02004801 * style) & 0x10011001;

cv->curattr = attr;


return 0; return 0;
} }


/** \brief Set the default colour pair (truecolor version).
/* Legacy function for old programs */
int cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg)
{
return cucul_set_attr_ansi(cv, fg, bg, 0);
}

/** \brief Set the default colour pair and text style (truecolor version).
* *
* Set the default colour pair for drawing. String functions such as
* caca_printf() and graphical primitive functions such as caca_draw_line()
* will use these colours.
* Set the default colour pair and text style for drawing. String
* functions such as caca_printf() and graphical primitive functions such as
* caca_draw_line() will use these attributes.
* *
* Colors are 16-bit ARGB values, each component being coded on 4 bits. For * Colors are 16-bit ARGB values, each component being coded on 4 bits. For
* instance, 0xf088 is solid dark cyan (A=15 R=0 G=8 B=8), and 0x8fff is * instance, 0xf088 is solid dark cyan (A=15 R=0 G=8 B=8), and 0x8fff is
* white with 50% alpha (A=8 R=15 G=15 B=15). * white with 50% alpha (A=8 R=15 G=15 B=15).
* *
* Style values are those defined in cucul.h, such as CUCUL_STYLE_UNDERLINE
* or CUCUL_STYLE_BLINK. The values can be ORed to set several styles at
* the same time.
*
* If an error occurs, -1 is returned and \b errno is set accordingly: * If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c EINVAL At least one of the colour values is invalid. * - \c EINVAL At least one of the colour values is invalid.
* *
* \param cv A handle to the libcucul canvas. * \param cv A handle to the libcucul canvas.
* \param fg The requested foreground colour. * \param fg The requested foreground colour.
* \param bg The requested background colour. * \param bg The requested background colour.
* \param style The requested text styles.
* \return 0 in case of success, -1 if an error occurred. * \return 0 in case of success, -1 if an error occurred.
*/ */
int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg)
int cucul_set_attr_argb(cucul_canvas_t *cv, unsigned int fg, unsigned int bg,
unsigned char style)
{ {
if(fg > 0xffff || bg > 0xffff)
uint32_t attr;

if(fg > 0xffff || bg > 0xffff || style > 0x0f)
{ {
#if defined(HAVE_ERRNO_H) #if defined(HAVE_ERRNO_H)
errno = EINVAL; errno = EINVAL;
@@ -102,39 +162,58 @@ int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg)
if(bg < 0x100) if(bg < 0x100)
bg += 0x100; bg += 0x100;


cv->fgcolor = fg;
cv->bgcolor = bg;
attr = (((uint32_t)bg << 16) | (uint32_t)fg) & 0xeffeeffe;

if(style)
attr |= (0x02004801 * style) & 0x10011001;

cv->curattr = attr;


return 0; return 0;
} }


/** \brief Get the colour pair at the given coordinates.
/* Legacy function for old programs */
int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg)
{
return cucul_set_attr_argb(cv, fg, bg, 0);
}

/** \brief Get the text attribute at the given coordinates.
* *
* Get the internal \e libcucul colour pair value of the character at the
* given coordinates. The colour pair value has 32 significant bits: the
* lower 16 bits are for the foreground colour, the higher 16 bits are for
* the background.
* Get the internal \e libcucul attribute value of the character at the
* given coordinates. The attribute value has 32 significant bits,
* organised as follows from MSB to LSB:
* - 3 bits for the background alpha
* - 1 bit for the blink flag
* - 4 bits for the background red component
* - 4 bits for the background green component
* - 3 bits for the background blue component
* - 1 bit for the underline flag
* - 3 bits for the foreground alpha
* - 1 bit for the italics flag
* - 4 bits for the foreground red component
* - 4 bits for the foreground green component
* - 3 bits for the foreground blue component
* - 1 bit for the bold flag
* *
* If the coordinates are outside the canvas boundaries, the current colour
* pair is returned.
* If the coordinates are outside the canvas boundaries, the current
* attribute is returned.
* *
* This function never fails. * This function never fails.
* *
* \param cv A handle to the libcucul canvas. * \param cv A handle to the libcucul canvas.
* \param x X coordinate. * \param x X coordinate.
* \param y Y coordinate. * \param y Y coordinate.
* \param ch The requested colour pair value.
* \return The character always returns 0.
* \return The requested attribute.
*/ */
unsigned long int cucul_get_color(cucul_canvas_t *cv, int x, int y)
unsigned long int cucul_get_attr(cucul_canvas_t *cv, int x, int y)
{ {
if(x < 0 || x >= (int)cv->width || y < 0 || y >= (int)cv->height) if(x < 0 || x >= (int)cv->width || y < 0 || y >= (int)cv->height)
return ((uint32_t)cv->bgcolor << 16) | (uint32_t)cv->fgcolor;
return (unsigned long int)cv->curattr;


return (unsigned long int)cv->attr[x + y * cv->width];
return (unsigned long int)cv->attrs[x + y * cv->width];
} }



/* /*
* XXX: the following functions are local * XXX: the following functions are local
*/ */
@@ -143,13 +222,14 @@ static uint8_t nearest_ansi(uint16_t argb16, uint8_t def)
{ {
unsigned int i, best, dist; unsigned int i, best, dist;


if(argb16 < CUCUL_COLOR_DEFAULT)
return argb16;
if(argb16 == (argb16 & 0x00f0))
return argb16 >> 4;


if(argb16 == CUCUL_COLOR_DEFAULT || argb16 == CUCUL_COLOR_TRANSPARENT)
if(argb16 == (CUCUL_COLOR_DEFAULT << 4)
|| argb16 == (CUCUL_COLOR_TRANSPARENT << 4))
return def; return def;


if(argb16 < 0x5fff) /* too transparent, return default colour */
if(argb16 < 0x6fff) /* too transparent, return default colour */
return def; return def;


best = def; best = def;
@@ -181,52 +261,52 @@ static uint8_t nearest_ansi(uint16_t argb16, uint8_t def)
return best; return best;
} }


uint8_t _cucul_argb32_to_ansi8(uint32_t ch)
uint8_t _cucul_attr_to_ansi8(uint32_t attr)
{ {
uint16_t fg = ch & 0xffff;
uint16_t bg = ch >> 16;
uint16_t fg = attr & 0xeffe;
uint16_t bg = (attr >> 16) & 0xeffe;


return nearest_ansi(fg, CUCUL_COLOR_LIGHTGRAY) return nearest_ansi(fg, CUCUL_COLOR_LIGHTGRAY)
| (nearest_ansi(bg, CUCUL_COLOR_BLACK) << 4); | (nearest_ansi(bg, CUCUL_COLOR_BLACK) << 4);
} }


uint8_t _cucul_argb32_to_ansi4fg(uint32_t ch)
uint8_t _cucul_attr_to_ansi4fg(uint32_t attr)
{ {
return nearest_ansi(ch & 0xffff, CUCUL_COLOR_LIGHTGRAY);
return nearest_ansi(attr & 0xeffe, CUCUL_COLOR_LIGHTGRAY);
} }


uint8_t _cucul_argb32_to_ansi4bg(uint32_t ch)
uint8_t _cucul_attr_to_ansi4bg(uint32_t attr)
{ {
return nearest_ansi(ch >> 16, CUCUL_COLOR_BLACK);
return nearest_ansi((attr >> 16) & 0xeffe, CUCUL_COLOR_BLACK);
} }


uint16_t _cucul_argb32_to_rgb12fg(uint32_t ch)
uint16_t _cucul_attr_to_rgb12fg(uint32_t attr)
{ {
uint16_t fg = ch & 0xffff;
uint16_t fg = attr & 0xeffe;


if(fg < CUCUL_COLOR_DEFAULT)
return ansitab[fg] & 0x0fff;
if(fg == (fg & 0x00f0))
return ansitab[fg >> 4] & 0x0fff;


if(fg == CUCUL_COLOR_DEFAULT)
if(fg == (CUCUL_COLOR_DEFAULT << 4))
return ansitab[CUCUL_COLOR_LIGHTGRAY] & 0x0fff; return ansitab[CUCUL_COLOR_LIGHTGRAY] & 0x0fff;


if(fg == CUCUL_COLOR_TRANSPARENT)
if(fg == (CUCUL_COLOR_TRANSPARENT << 4))
return ansitab[CUCUL_COLOR_LIGHTGRAY] & 0x0fff; return ansitab[CUCUL_COLOR_LIGHTGRAY] & 0x0fff;


return fg & 0x0fff; return fg & 0x0fff;
} }


uint16_t _cucul_argb32_to_rgb12bg(uint32_t ch)
uint16_t _cucul_attr_to_rgb12bg(uint32_t attr)
{ {
uint16_t bg = ch >> 16;
uint16_t bg = (attr >> 16) & 0xeffe;


if(bg < CUCUL_COLOR_DEFAULT)
return ansitab[bg] & 0x0fff;
if(bg == (bg & 0x00f0))
return ansitab[bg >> 4] & 0x0fff;


if(bg == CUCUL_COLOR_DEFAULT)
if(bg == (CUCUL_COLOR_DEFAULT << 4))
return ansitab[CUCUL_COLOR_BLACK] & 0x0fff; return ansitab[CUCUL_COLOR_BLACK] & 0x0fff;


if(bg == CUCUL_COLOR_TRANSPARENT)
if(bg == (CUCUL_COLOR_TRANSPARENT << 4))
return ansitab[CUCUL_COLOR_BLACK] & 0x0fff; return ansitab[CUCUL_COLOR_BLACK] & 0x0fff;


return bg & 0x0fff; return bg & 0x0fff;
@@ -237,33 +317,33 @@ uint16_t _cucul_argb32_to_rgb12bg(uint32_t ch)
| ((uint32_t)((i & 0x0f0) >> 4) * 0x001100) \ | ((uint32_t)((i & 0x0f0) >> 4) * 0x001100) \
| ((uint32_t)(i & 0x00f) * 0x000011)) | ((uint32_t)(i & 0x00f) * 0x000011))


uint32_t _cucul_argb32_to_rgb24fg(uint32_t ch)
uint32_t _cucul_attr_to_rgb24fg(uint32_t attr)
{ {
return RGB12TO24(_cucul_argb32_to_rgb12fg(ch));
return RGB12TO24(_cucul_attr_to_rgb12fg(attr));
} }


uint32_t _cucul_argb32_to_rgb24bg(uint32_t ch)
uint32_t _cucul_attr_to_rgb24bg(uint32_t attr)
{ {
return RGB12TO24(_cucul_argb32_to_rgb12bg(ch));
return RGB12TO24(_cucul_attr_to_rgb12bg(attr));
} }


void _cucul_argb32_to_argb4(uint32_t ch, uint8_t argb[8])
void _cucul_attr_to_argb4(uint32_t attr, uint8_t argb[8])
{ {
uint16_t fg = ch & 0xffff;
uint16_t bg = ch >> 16;
uint16_t fg = attr & 0xeffe;
uint16_t bg = (attr >> 16) & 0xeffe;


if(fg < CUCUL_COLOR_DEFAULT)
fg = ansitab[fg];
else if(fg == CUCUL_COLOR_DEFAULT)
if(fg == (fg & 0x00f0))
fg = ansitab[fg >> 4];
else if(fg == (CUCUL_COLOR_DEFAULT << 4))
fg = ansitab[CUCUL_COLOR_LIGHTGRAY]; fg = ansitab[CUCUL_COLOR_LIGHTGRAY];
else if(fg == CUCUL_COLOR_TRANSPARENT)
else if(fg == (CUCUL_COLOR_TRANSPARENT << 4))
fg = 0x0fff; fg = 0x0fff;


if(bg < CUCUL_COLOR_DEFAULT)
bg = ansitab[bg];
else if(bg == CUCUL_COLOR_DEFAULT)
if(bg == (bg & 0x00f0))
bg = ansitab[bg >> 4];
else if(bg == (CUCUL_COLOR_DEFAULT << 4))
bg = ansitab[CUCUL_COLOR_BLACK]; bg = ansitab[CUCUL_COLOR_BLACK];
else if(bg == CUCUL_COLOR_TRANSPARENT)
else if(bg == (CUCUL_COLOR_TRANSPARENT << 4))
bg = 0x0fff; bg = 0x0fff;


argb[0] = bg >> 12; argb[0] = bg >> 12;


+ 22
- 23
cucul/cucul.c Näytä tiedosto

@@ -59,12 +59,11 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height)


cv->refcount = 0; cv->refcount = 0;


cv->fgcolor = CUCUL_COLOR_DEFAULT;
cv->bgcolor = CUCUL_COLOR_TRANSPARENT;
cv->curattr = (CUCUL_COLOR_DEFAULT << 20) | (CUCUL_COLOR_TRANSPARENT < 4);


cv->width = cv->height = 0; cv->width = cv->height = 0;
cv->chars = NULL; cv->chars = NULL;
cv->attr = NULL;
cv->attrs = NULL;


cv->frame = 0; cv->frame = 0;
cv->framecount = 1; cv->framecount = 1;
@@ -74,22 +73,22 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height)
free(cv); free(cv);
goto nomem; goto nomem;
} }
cv->allattr = malloc(sizeof(uint32_t *));
if(!cv->allattr)
cv->allattrs = malloc(sizeof(uint32_t *));
if(!cv->allattrs)
{ {
free(cv->allchars); free(cv->allchars);
free(cv); free(cv);
goto nomem; goto nomem;
} }
cv->allchars[0] = NULL; cv->allchars[0] = NULL;
cv->allattr[0] = NULL;
cv->allattrs[0] = NULL;


if(_cucul_set_canvas_size(cv, width, height) < 0) if(_cucul_set_canvas_size(cv, width, height) < 0)
{ {
#if defined(HAVE_ERRNO_H) #if defined(HAVE_ERRNO_H)
int saved_errno = errno; int saved_errno = errno;
#endif #endif
free(cv->allattr);
free(cv->allattrs);
free(cv->allchars); free(cv->allchars);
free(cv); free(cv);
#if defined(HAVE_ERRNO_H) #if defined(HAVE_ERRNO_H)
@@ -246,11 +245,11 @@ int cucul_free_canvas(cucul_canvas_t *cv)
for(f = 0; f < cv->framecount; f++) for(f = 0; f < cv->framecount; f++)
{ {
free(cv->allchars[f]); free(cv->allchars[f]);
free(cv->allattr[f]);
free(cv->allattrs[f]);
} }


free(cv->allchars); free(cv->allchars);
free(cv->allattr);
free(cv->allattrs);
free(cv); free(cv);


return 0; return 0;
@@ -304,9 +303,9 @@ int _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
{ {
cv->allchars[f] = realloc(cv->allchars[f], cv->allchars[f] = realloc(cv->allchars[f],
new_size * sizeof(uint32_t)); new_size * sizeof(uint32_t));
cv->allattr[f] = realloc(cv->allattr[f],
cv->allattrs[f] = realloc(cv->allattrs[f],
new_size * sizeof(uint32_t)); new_size * sizeof(uint32_t));
if(!cv->allchars[f] || !cv->allattr[f])
if(!cv->allchars[f] || !cv->allattrs[f])
{ {
#if defined(HAVE_ERRNO_H) #if defined(HAVE_ERRNO_H)
errno = ENOMEM; errno = ENOMEM;
@@ -330,23 +329,23 @@ int _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
for(f = 0; f < cv->framecount; f++) for(f = 0; f < cv->framecount; f++)
{ {
uint32_t *chars = cv->allchars[f]; uint32_t *chars = cv->allchars[f];
uint32_t *attr = cv->allattr[f];
uint32_t *attrs = cv->allattrs[f];


for(y = height < old_height ? height : old_height; y--; ) for(y = height < old_height ? height : old_height; y--; )
{ {
uint32_t color = (cv->bgcolor << 16) | cv->fgcolor;
uint32_t attr = cv->curattr;


for(x = old_width; x--; ) for(x = old_width; x--; )
{ {
chars[y * width + x] = chars[y * old_width + x]; chars[y * width + x] = chars[y * old_width + x];
attr[y * width + x] = attr[y * old_width + x];
attrs[y * width + x] = attrs[y * old_width + x];
} }


/* Zero the end of the line */ /* Zero the end of the line */
for(x = width - old_width; x--; ) for(x = width - old_width; x--; )
{ {
chars[y * width + old_width + x] = (uint32_t)' '; chars[y * width + old_width + x] = (uint32_t)' ';
attr[y * width + old_width + x] = color;
attrs[y * width + old_width + x] = attr;
} }
} }
} }
@@ -360,14 +359,14 @@ int _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
for(f = 0; f < cv->framecount; f++) for(f = 0; f < cv->framecount; f++)
{ {
uint32_t *chars = cv->allchars[f]; uint32_t *chars = cv->allchars[f];
uint32_t *attr = cv->allattr[f];
uint32_t *attrs = cv->allattrs[f];


for(y = 1; y < lines; y++) for(y = 1; y < lines; y++)
{ {
for(x = 0; x < width; x++) for(x = 0; x < width; x++)
{ {
chars[y * width + x] = chars[y * old_width + x]; chars[y * width + x] = chars[y * old_width + x];
attr[y * width + x] = attr[y * old_width + x];
attrs[y * width + x] = attrs[y * old_width + x];
} }
} }
} }
@@ -379,14 +378,14 @@ int _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
for(f = 0; f < cv->framecount; f++) for(f = 0; f < cv->framecount; f++)
{ {
uint32_t *chars = cv->allchars[f]; uint32_t *chars = cv->allchars[f];
uint32_t *attr = cv->allattr[f];
uint32_t color = (cv->bgcolor << 16) | cv->fgcolor;
uint32_t *attrs = cv->allattrs[f];
uint32_t attr = cv->curattr;


/* Zero the bottom of the screen */ /* Zero the bottom of the screen */
for(x = (height - old_height) * width; x--; ) for(x = (height - old_height) * width; x--; )
{ {
chars[old_height * width + x] = (uint32_t)' '; chars[old_height * width + x] = (uint32_t)' ';
attr[old_height * width + x] = color;
attrs[old_height * width + x] = attr;
} }
} }
} }
@@ -398,9 +397,9 @@ int _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
{ {
cv->allchars[f] = realloc(cv->allchars[f], cv->allchars[f] = realloc(cv->allchars[f],
new_size * sizeof(uint32_t)); new_size * sizeof(uint32_t));
cv->allattr[f] = realloc(cv->allattr[f],
cv->allattrs[f] = realloc(cv->allattrs[f],
new_size * sizeof(uint32_t)); new_size * sizeof(uint32_t));
if(!cv->allchars[f] || !cv->allattr[f])
if(!cv->allchars[f] || !cv->allattrs[f])
{ {
#if defined(HAVE_ERRNO_H) #if defined(HAVE_ERRNO_H)
errno = ENOMEM; errno = ENOMEM;
@@ -412,7 +411,7 @@ int _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,


/* Reset the current frame shortcut */ /* Reset the current frame shortcut */
cv->chars = cv->allchars[cv->frame]; cv->chars = cv->allchars[cv->frame];
cv->attr = cv->allattr[cv->frame];
cv->attrs = cv->allattrs[cv->frame];


return 0; return 0;
} }


+ 17
- 5
cucul/cucul.h Näytä tiedosto

@@ -40,9 +40,10 @@ typedef struct cucul_buffer cucul_buffer_t;
/** font structure */ /** font structure */
typedef struct cucul_font cucul_font_t; typedef struct cucul_font cucul_font_t;


/** \defgroup colour libcucul colour definitions
/** \defgroup attributes libcucul attribute definitions
* *
* Colours that can be used with cucul_set_color().
* Colours and styles that can be used with cucul_set_attr_ansi() and
* cucul_set_attr_argb().
* *
* @{ */ * @{ */
#define CUCUL_COLOR_BLACK 0x00 /**< The colour index for black. */ #define CUCUL_COLOR_BLACK 0x00 /**< The colour index for black. */
@@ -63,6 +64,11 @@ typedef struct cucul_font cucul_font_t;
#define CUCUL_COLOR_WHITE 0x0f /**< The colour index for white. */ #define CUCUL_COLOR_WHITE 0x0f /**< The colour index for white. */
#define CUCUL_COLOR_DEFAULT 0x10 /**< The output driver's default colour. */ #define CUCUL_COLOR_DEFAULT 0x10 /**< The output driver's default colour. */
#define CUCUL_COLOR_TRANSPARENT 0x20 /**< The transparent colour. */ #define CUCUL_COLOR_TRANSPARENT 0x20 /**< The transparent colour. */

#define CUCUL_STYLE_BOLD 0x01 /**< The style mask for bold. */
#define CUCUL_STYLE_ITALICS 0x02 /**< The style mask for italics. */
#define CUCUL_STYLE_UNDERLINE 0x04 /**< The style mask for underline. */
#define CUCUL_STYLE_BLINK 0x08 /**< The style mask for blink. */
/* @} */ /* @} */


/** \defgroup cucul libcucul basic functions /** \defgroup cucul libcucul basic functions
@@ -98,9 +104,12 @@ int cucul_free_buffer(cucul_buffer_t *);
* *
* @{ */ * @{ */
#define CUCUL_MAGIC_FULLWIDTH 0x000ffffe /**< Used to indicate that the previous character was a fullwidth glyph. */ #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);
int cucul_set_attr(cucul_canvas_t *, unsigned long int);
int cucul_set_attr_ansi(cucul_canvas_t *, unsigned char, unsigned char,
unsigned char);
int cucul_set_attr_argb(cucul_canvas_t *, unsigned int, unsigned int,
unsigned char);
unsigned long int cucul_get_attr(cucul_canvas_t *, int, int);
char const *cucul_get_color_name(unsigned int); char const *cucul_get_color_name(unsigned int);
int cucul_putchar(cucul_canvas_t *, int, int, unsigned long int); int cucul_putchar(cucul_canvas_t *, int, int, unsigned long int);
unsigned long int cucul_getchar(cucul_canvas_t *, int, int); unsigned long int cucul_getchar(cucul_canvas_t *, int, int);
@@ -111,6 +120,9 @@ int cucul_blit(cucul_canvas_t *, int, int, cucul_canvas_t const *,
cucul_canvas_t const *); cucul_canvas_t const *);
int cucul_set_canvas_boundaries(cucul_canvas_t *, int, int, int cucul_set_canvas_boundaries(cucul_canvas_t *, int, int,
unsigned int, unsigned int); unsigned int, unsigned int);
/* Legacy stuff */
int cucul_set_color(cucul_canvas_t *, unsigned char, unsigned char);
int cucul_set_truecolor(cucul_canvas_t *, unsigned int, unsigned int);
/* @} */ /* @} */


/** \defgroup transform libcucul canvas transformation /** \defgroup transform libcucul canvas transformation


+ 11
- 12
cucul/cucul_internals.h Näytä tiedosto

@@ -25,16 +25,15 @@ struct cucul_canvas


/* Shortcut to the active frame */ /* Shortcut to the active frame */
uint32_t *chars; uint32_t *chars;
uint32_t *attr;
uint32_t *attrs;


/* Frame information */ /* Frame information */
unsigned int frame, framecount; unsigned int frame, framecount;
uint32_t **allchars; uint32_t **allchars;
uint32_t **allattr;
uint32_t **allattrs;


/* Painting context */ /* Painting context */
uint16_t fgcolor;
uint16_t bgcolor;
uint32_t curattr;


unsigned int refcount; unsigned int refcount;
}; };
@@ -58,13 +57,13 @@ extern unsigned int _cucul_strlen_utf8(char const *);
extern char const *_cucul_skip_utf8(char const *, unsigned int); extern char const *_cucul_skip_utf8(char const *, unsigned int);


/* Colour functions */ /* Colour functions */
uint8_t _cucul_argb32_to_ansi8(uint32_t);
uint8_t _cucul_argb32_to_ansi4fg(uint32_t);
uint8_t _cucul_argb32_to_ansi4bg(uint32_t);
uint16_t _cucul_argb32_to_rgb12fg(uint32_t);
uint16_t _cucul_argb32_to_rgb12bg(uint32_t);
uint32_t _cucul_argb32_to_rgb24fg(uint32_t);
uint32_t _cucul_argb32_to_rgb24bg(uint32_t);
void _cucul_argb32_to_argb4(uint32_t, uint8_t[8]);
uint8_t _cucul_attr_to_ansi8(uint32_t);
uint8_t _cucul_attr_to_ansi4fg(uint32_t);
uint8_t _cucul_attr_to_ansi4bg(uint32_t);
uint16_t _cucul_attr_to_rgb12fg(uint32_t);
uint16_t _cucul_attr_to_rgb12bg(uint32_t);
uint32_t _cucul_attr_to_rgb24fg(uint32_t);
uint32_t _cucul_attr_to_rgb24bg(uint32_t);
void _cucul_attr_to_argb4(uint32_t, uint8_t[8]);


#endif /* __CUCUL_INTERNALS_H__ */ #endif /* __CUCUL_INTERNALS_H__ */

+ 29
- 29
cucul/export.c Näytä tiedosto

@@ -153,7 +153,7 @@ char const * const * cucul_get_export_list(void)
/* Generate a native libcaca canvas file. */ /* Generate a native libcaca canvas file. */
static int export_caca(cucul_canvas_t *cv, cucul_buffer_t *ex) static int export_caca(cucul_canvas_t *cv, cucul_buffer_t *ex)
{ {
uint32_t *attr = cv->attr;
uint32_t *attrs = cv->attrs;
uint32_t *chars = cv->chars; uint32_t *chars = cv->chars;
char *cur; char *cur;
uint32_t w, h; uint32_t w, h;
@@ -177,7 +177,7 @@ static int export_caca(cucul_canvas_t *cv, cucul_buffer_t *ex)
for(n = cv->height * cv->width; n--; ) for(n = cv->height * cv->width; n--; )
{ {
uint32_t ch = *chars++; uint32_t ch = *chars++;
uint32_t a = *attr++;
uint32_t a = *attrs++;


*cur++ = ch >> 24; *cur++ = ch >> 24;
*cur++ = (ch >> 16) & 0xff; *cur++ = (ch >> 16) & 0xff;
@@ -215,7 +215,7 @@ static int export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex)


for(y = 0; y < cv->height; y++) for(y = 0; y < cv->height; y++)
{ {
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width; uint32_t *linechar = cv->chars + y * cv->width;


uint8_t prevfg = 0x10; uint8_t prevfg = 0x10;
@@ -230,10 +230,10 @@ static int export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex)
if(ch == CUCUL_MAGIC_FULLWIDTH) if(ch == CUCUL_MAGIC_FULLWIDTH)
continue; continue;


fg = ((attr & 0xffff) == CUCUL_COLOR_DEFAULT) ?
0x10 : palette[_cucul_argb32_to_ansi4fg(attr)];
bg = ((attr >> 16) == CUCUL_COLOR_TRANSPARENT) ?
0x10 : palette[_cucul_argb32_to_ansi4bg(attr)];
fg = ((attr & 0xeffe) == (CUCUL_COLOR_DEFAULT << 4)) ?
0x10 : palette[_cucul_attr_to_ansi4fg(attr)];
bg = (((attr >> 16) & 0xeffe) == (CUCUL_COLOR_TRANSPARENT << 4)) ?
0x10 : palette[_cucul_attr_to_ansi4bg(attr)];


/* TODO: the [0 could be omitted in some cases */ /* TODO: the [0 could be omitted in some cases */
if(fg != prevfg || bg != prevbg) if(fg != prevfg || bg != prevbg)
@@ -297,13 +297,13 @@ static int export_ansi(cucul_canvas_t *cv, cucul_buffer_t *ex)


for(y = 0; y < cv->height; y++) for(y = 0; y < cv->height; y++)
{ {
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width; uint32_t *linechar = cv->chars + y * cv->width;


for(x = 0; x < cv->width; x++) for(x = 0; x < cv->width; x++)
{ {
uint8_t fg = palette[_cucul_argb32_to_ansi4fg(lineattr[x])];
uint8_t bg = palette[_cucul_argb32_to_ansi4bg(lineattr[x])];
uint8_t fg = palette[_cucul_attr_to_ansi4fg(lineattr[x])];
uint8_t bg = palette[_cucul_attr_to_ansi4bg(lineattr[x])];
uint32_t ch = linechar[x]; uint32_t ch = linechar[x];


if(ch == CUCUL_MAGIC_FULLWIDTH) if(ch == CUCUL_MAGIC_FULLWIDTH)
@@ -376,15 +376,15 @@ static int export_html(cucul_canvas_t *cv, cucul_buffer_t *ex)


for(y = 0; y < cv->height; y++) for(y = 0; y < cv->height; y++)
{ {
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width; uint32_t *linechar = cv->chars + y * cv->width;


for(x = 0; x < cv->width; x += len) for(x = 0; x < cv->width; x += len)
{ {
cur += sprintf(cur, "<span style=\"color:#%.03x;" cur += sprintf(cur, "<span style=\"color:#%.03x;"
"background-color:#%.03x\">", "background-color:#%.03x\">",
_cucul_argb32_to_rgb12fg(lineattr[x]),
_cucul_argb32_to_rgb12bg(lineattr[x]));
_cucul_attr_to_rgb12fg(lineattr[x]),
_cucul_attr_to_rgb12bg(lineattr[x]));


for(len = 0; for(len = 0;
x + len < cv->width && lineattr[x + len] == lineattr[x]; x + len < cv->width && lineattr[x + len] == lineattr[x];
@@ -441,7 +441,7 @@ static int export_html3(cucul_canvas_t *cv, cucul_buffer_t *ex)


for(y = 0; y < cv->height; y++) for(y = 0; y < cv->height; y++)
{ {
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width; uint32_t *linechar = cv->chars + y * cv->width;


cur += sprintf(cur, "<tr>"); cur += sprintf(cur, "<tr>");
@@ -457,13 +457,13 @@ static int export_html3(cucul_canvas_t *cv, cucul_buffer_t *ex)
len++; len++;


cur += sprintf(cur, "<td bgcolor=#%.06lx", (unsigned long int) cur += sprintf(cur, "<td bgcolor=#%.06lx", (unsigned long int)
_cucul_argb32_to_rgb24bg(lineattr[x]));
_cucul_attr_to_rgb24bg(lineattr[x]));


if(len > 1) if(len > 1)
cur += sprintf(cur, " colspan=%d", len); cur += sprintf(cur, " colspan=%d", len);


cur += sprintf(cur, "><font color=#%.06lx>", (unsigned long int) cur += sprintf(cur, "><font color=#%.06lx>", (unsigned long int)
_cucul_argb32_to_rgb24fg(lineattr[x]));
_cucul_attr_to_rgb24fg(lineattr[x]));


for(i = 0; i < len; i++) for(i = 0; i < len; i++)
{ {
@@ -521,7 +521,7 @@ static int export_irc(cucul_canvas_t *cv, cucul_buffer_t *ex)


for(y = 0; y < cv->height; y++) for(y = 0; y < cv->height; y++)
{ {
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width; uint32_t *linechar = cv->chars + y * cv->width;


uint8_t prevfg = 0x10; uint8_t prevfg = 0x10;
@@ -530,17 +530,17 @@ static int export_irc(cucul_canvas_t *cv, cucul_buffer_t *ex)
for(x = 0; x < cv->width; x++) for(x = 0; x < cv->width; x++)
{ {
uint32_t attr = lineattr[x]; uint32_t attr = lineattr[x];
uint8_t fg = palette[_cucul_argb32_to_ansi4fg(attr)];
uint8_t bg = palette[_cucul_argb32_to_ansi4bg(attr)];
uint8_t fg = palette[_cucul_attr_to_ansi4fg(attr)];
uint8_t bg = palette[_cucul_attr_to_ansi4bg(attr)];
uint32_t ch = linechar[x]; uint32_t ch = linechar[x];


if(ch == CUCUL_MAGIC_FULLWIDTH) if(ch == CUCUL_MAGIC_FULLWIDTH)
continue; continue;


if((attr & 0xffff) == CUCUL_COLOR_DEFAULT)
if((attr & 0xeffe) == (CUCUL_COLOR_DEFAULT << 4))
fg = 0x10; fg = 0x10;


if((attr >> 16) == CUCUL_COLOR_TRANSPARENT)
if(((attr >> 16) & 0xeffe) == (CUCUL_COLOR_TRANSPARENT << 4))
bg = 0x10; bg = 0x10;


/* TODO: optimise series of same fg / same bg /* TODO: optimise series of same fg / same bg
@@ -644,12 +644,12 @@ static int export_ps(cucul_canvas_t *cv, cucul_buffer_t *ex)
/* Background, drawn using csquare macro defined in header */ /* Background, drawn using csquare macro defined in header */
for(y = cv->height; y--; ) for(y = cv->height; y--; )
{ {
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;


for(x = 0; x < cv->width; x++) for(x = 0; x < cv->width; x++)
{ {
uint8_t argb[8]; uint8_t argb[8];
_cucul_argb32_to_argb4(*lineattr++, argb);
_cucul_attr_to_argb4(*lineattr++, argb);
cur += sprintf(cur, "1 0 translate\n %f %f %f csquare\n", cur += sprintf(cur, "1 0 translate\n %f %f %f csquare\n",
(float)argb[1] * (1.0 / 0xf), (float)argb[1] * (1.0 / 0xf),
(float)argb[2] * (1.0 / 0xf), (float)argb[2] * (1.0 / 0xf),
@@ -665,7 +665,7 @@ static int export_ps(cucul_canvas_t *cv, cucul_buffer_t *ex)


for(y = cv->height; y--; ) for(y = cv->height; y--; )
{ {
uint32_t *lineattr = cv->attr + (cv->height - y - 1) * cv->width;
uint32_t *lineattr = cv->attrs + (cv->height - y - 1) * cv->width;
uint32_t *linechar = cv->chars + (cv->height - y - 1) * cv->width; uint32_t *linechar = cv->chars + (cv->height - y - 1) * cv->width;


for(x = 0; x < cv->width; x++) for(x = 0; x < cv->width; x++)
@@ -673,7 +673,7 @@ static int export_ps(cucul_canvas_t *cv, cucul_buffer_t *ex)
uint8_t argb[8]; uint8_t argb[8];
uint32_t ch = *linechar++; uint32_t ch = *linechar++;


_cucul_argb32_to_argb4(*lineattr++, argb);
_cucul_attr_to_argb4(*lineattr++, argb);


cur += sprintf(cur, "newpath\n"); cur += sprintf(cur, "newpath\n");
cur += sprintf(cur, "%d %d moveto\n", (x + 1) * 6, y * 10 + 2); cur += sprintf(cur, "%d %d moveto\n", (x + 1) * 6, y * 10 + 2);
@@ -738,13 +738,13 @@ static int export_svg(cucul_canvas_t *cv, cucul_buffer_t *ex)
/* Background */ /* Background */
for(y = 0; y < cv->height; y++) for(y = 0; y < cv->height; y++)
{ {
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;


for(x = 0; x < cv->width; x++) for(x = 0; x < cv->width; x++)
{ {
cur += sprintf(cur, "<rect style=\"fill:#%.03x\" x=\"%d\" y=\"%d\"" cur += sprintf(cur, "<rect style=\"fill:#%.03x\" x=\"%d\" y=\"%d\""
" width=\"6\" height=\"10\"/>\n", " width=\"6\" height=\"10\"/>\n",
_cucul_argb32_to_rgb12bg(*lineattr++),
_cucul_attr_to_rgb12bg(*lineattr++),
x * 6, y * 10); x * 6, y * 10);
} }
} }
@@ -752,7 +752,7 @@ static int export_svg(cucul_canvas_t *cv, cucul_buffer_t *ex)
/* Text */ /* Text */
for(y = 0; y < cv->height; y++) for(y = 0; y < cv->height; y++)
{ {
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width; uint32_t *linechar = cv->chars + y * cv->width;


for(x = 0; x < cv->width; x++) for(x = 0; x < cv->width; x++)
@@ -767,7 +767,7 @@ static int export_svg(cucul_canvas_t *cv, cucul_buffer_t *ex)


cur += sprintf(cur, "<text style=\"fill:#%.03x\" " cur += sprintf(cur, "<text style=\"fill:#%.03x\" "
"x=\"%d\" y=\"%d\">", "x=\"%d\" y=\"%d\">",
_cucul_argb32_to_rgb12fg(*lineattr++),
_cucul_attr_to_rgb12fg(*lineattr++),
x * 6, (y * 10) + 8); x * 6, (y * 10) + 8);


if(ch < 0x00000020) if(ch < 0x00000020)


+ 2
- 2
cucul/font.c Näytä tiedosto

@@ -420,7 +420,7 @@ int cucul_render_canvas(cucul_canvas_t *cv, cucul_font_t *f,
unsigned int starty = y * f->header.height; unsigned int starty = y * f->header.height;
unsigned int startx = x * f->header.width; unsigned int startx = x * f->header.width;
uint32_t ch = cv->chars[y * cv->width + x]; uint32_t ch = cv->chars[y * cv->width + x];
uint32_t attr = cv->attr[y * cv->width + x];
uint32_t attr = cv->attrs[y * cv->width + x];
unsigned int b, i, j; unsigned int b, i, j;
struct glyph_info *g; struct glyph_info *g;


@@ -444,7 +444,7 @@ int cucul_render_canvas(cucul_canvas_t *cv, cucul_font_t *f,
g = &f->glyph_list[f->block_list[b].index g = &f->glyph_list[f->block_list[b].index
+ ch - f->block_list[b].start]; + ch - f->block_list[b].start];


_cucul_argb32_to_argb4(attr, argb);
_cucul_attr_to_argb4(attr, argb);


/* Step 1: unpack glyph */ /* Step 1: unpack glyph */
switch(f->header.bpp) switch(f->header.bpp)


+ 1
- 1
cucul/import.c Näytä tiedosto

@@ -172,7 +172,7 @@ static cucul_canvas_t *import_caca(void const *data, unsigned int size)
| ((uint32_t)buf[16 + 1 + 8 * n] << 16) | ((uint32_t)buf[16 + 1 + 8 * n] << 16)
| ((uint32_t)buf[16 + 2 + 8 * n] << 8) | ((uint32_t)buf[16 + 2 + 8 * n] << 8)
| (uint32_t)buf[16 + 3 + 8 * n]; | (uint32_t)buf[16 + 3 + 8 * n];
cv->attr[n] = ((uint32_t)buf[16 + 4 + 8 * n] << 24)
cv->attrs[n] = ((uint32_t)buf[16 + 4 + 8 * n] << 24)
| ((uint32_t)buf[16 + 5 + 8 * n] << 16) | ((uint32_t)buf[16 + 5 + 8 * n] << 16)
| ((uint32_t)buf[16 + 6 + 8 * n] << 8) | ((uint32_t)buf[16 + 6 + 8 * n] << 8)
| (uint32_t)buf[16 + 7 + 8 * n]; | (uint32_t)buf[16 + 7 + 8 * n];


+ 10
- 10
cucul/sprite.c Näytä tiedosto

@@ -72,7 +72,7 @@ int cucul_set_canvas_frame(cucul_canvas_t *cv, unsigned int frame)
cv->frame = frame; cv->frame = frame;


cv->chars = cv->allchars[cv->frame]; cv->chars = cv->allchars[cv->frame];
cv->attr = cv->allattr[cv->frame];
cv->attrs = cv->allattrs[cv->frame];


return 0; return 0;
} }
@@ -107,24 +107,24 @@ int cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int frame)


cv->framecount++; cv->framecount++;
cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount); cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount);
cv->allattr = realloc(cv->allattr, sizeof(uint32_t *) * cv->framecount);
cv->allattrs = realloc(cv->allattrs, sizeof(uint32_t *) * cv->framecount);


for(f = cv->framecount - 1; f > frame; f--) for(f = cv->framecount - 1; f > frame; f--)
{ {
cv->allchars[f] = cv->allchars[f - 1]; cv->allchars[f] = cv->allchars[f - 1];
cv->allattr[f] = cv->allattr[f - 1];
cv->allattrs[f] = cv->allattrs[f - 1];
} }


cv->allchars[frame] = malloc(size); cv->allchars[frame] = malloc(size);
memcpy(cv->allchars[frame], cv->chars, size); memcpy(cv->allchars[frame], cv->chars, size);
cv->allattr[frame] = malloc(size);
memcpy(cv->allattr[frame], cv->attr, size);
cv->allattrs[frame] = malloc(size);
memcpy(cv->allattrs[frame], cv->attrs, size);


if(cv->frame >= frame) if(cv->frame >= frame)
cv->frame++; cv->frame++;


cv->chars = cv->allchars[cv->frame]; cv->chars = cv->allchars[cv->frame];
cv->attr = cv->allattr[cv->frame];
cv->attrs = cv->allattrs[cv->frame];


return 0; return 0;
} }
@@ -171,17 +171,17 @@ int cucul_free_canvas_frame(cucul_canvas_t *cv, unsigned int frame)
} }


free(cv->allchars[frame]); free(cv->allchars[frame]);
free(cv->allattr[frame]);
free(cv->allattrs[frame]);


for(f = frame + 1; f < cv->framecount; f++) for(f = frame + 1; f < cv->framecount; f++)
{ {
cv->allchars[f - 1] = cv->allchars[f]; cv->allchars[f - 1] = cv->allchars[f];
cv->allattr[f - 1] = cv->allattr[f];
cv->allattrs[f - 1] = cv->allattrs[f];
} }


cv->framecount--; cv->framecount--;
cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount); cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount);
cv->allattr = realloc(cv->allattr, sizeof(uint32_t *) * cv->framecount);
cv->allattrs = realloc(cv->allattrs, sizeof(uint32_t *) * cv->framecount);


if(cv->frame > frame) if(cv->frame > frame)
cv->frame--; cv->frame--;
@@ -189,7 +189,7 @@ int cucul_free_canvas_frame(cucul_canvas_t *cv, unsigned int frame)
cv->frame = 0; cv->frame = 0;


cv->chars = cv->allchars[cv->frame]; cv->chars = cv->allchars[cv->frame];
cv->attr = cv->allattr[cv->frame];
cv->attrs = cv->allattrs[cv->frame];


return 0; return 0;
} }


+ 6
- 6
cucul/transform.c Näytä tiedosto

@@ -40,13 +40,13 @@ static uint32_t rotatechar(uint32_t ch);
*/ */
int cucul_invert(cucul_canvas_t *cv) int cucul_invert(cucul_canvas_t *cv)
{ {
uint32_t *attr = cv->attr;
uint32_t *attrs = cv->attrs;
unsigned int i; unsigned int i;


for(i = cv->height * cv->width; i--; ) for(i = cv->height * cv->width; i--; )
{ {
*attr = *attr ^ 0x000f000f;
attr++;
*attrs = *attrs ^ 0x000f000f;
attrs++;
} }


return 0; return 0;
@@ -70,7 +70,7 @@ int cucul_flip(cucul_canvas_t *cv)
{ {
uint32_t *cleft = cv->chars + y * cv->width; uint32_t *cleft = cv->chars + y * cv->width;
uint32_t *cright = cleft + cv->width - 1; uint32_t *cright = cleft + cv->width - 1;
uint32_t *aleft = cv->attr + y * cv->width;
uint32_t *aleft = cv->attrs + y * cv->width;
uint32_t *aright = aleft + cv->width - 1; uint32_t *aright = aleft + cv->width - 1;


while(cleft < cright) while(cleft < cright)
@@ -127,7 +127,7 @@ int cucul_flop(cucul_canvas_t *cv)
{ {
uint32_t *ctop = cv->chars + x; uint32_t *ctop = cv->chars + x;
uint32_t *cbottom = ctop + cv->width * (cv->height - 1); uint32_t *cbottom = ctop + cv->width * (cv->height - 1);
uint32_t *atop = cv->attr + x;
uint32_t *atop = cv->attrs + x;
uint32_t *abottom = atop + cv->width * (cv->height - 1); uint32_t *abottom = atop + cv->width * (cv->height - 1);


while(ctop < cbottom) while(ctop < cbottom)
@@ -166,7 +166,7 @@ int cucul_rotate(cucul_canvas_t *cv)
{ {
uint32_t *cbegin = cv->chars; uint32_t *cbegin = cv->chars;
uint32_t *cend = cbegin + cv->width * cv->height - 1; uint32_t *cend = cbegin + cv->width * cv->height - 1;
uint32_t *abegin = cv->attr;
uint32_t *abegin = cv->attrs;
uint32_t *aend = abegin + cv->width * cv->height - 1; uint32_t *aend = abegin + cv->width * cv->height - 1;
unsigned int y; unsigned int y;




Ladataan…
Peruuta
Tallenna