Browse Source

* 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 18 years ago
parent
commit
86301dd48c
18 changed files with 286 additions and 195 deletions
  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 View File

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

#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_bg_color() __caca0_bg
#define caca_get_color_name cucul_get_color_name


+ 3
- 3
caca/driver_conio.c View File

@@ -97,7 +97,7 @@ static unsigned int conio_get_display_height(caca_display_t *dp)
static void conio_display(caca_display_t *dp)
{
char *screen = dp->drv.p->screen;
uint32_t *attr = dp->cv->attr;
uint32_t *attrs = dp->cv->attrs;
uint32_t *chars = dp->cv->chars;
unsigned int n;

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


+ 6
- 6
caca/driver_gl.c View File

@@ -214,12 +214,12 @@ static void gl_display(caca_display_t *dp)
line = 0;
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 */
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,
((bg & 0x0f0) >> 4) * 8,
@@ -244,10 +244,10 @@ static void gl_display(caca_display_t *dp)
line = 0;
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;

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++;
uint16_t fg;
@@ -271,7 +271,7 @@ static void gl_display(caca_display_t *dp)
dp->drv.p->txid[b + ch
- (uint32_t)dp->drv.p->blocks[i]]);

fg = _cucul_argb32_to_rgb12fg(*attr);
fg = _cucul_attr_to_rgb12fg(*attrs);
glColor3b(((fg & 0xf00) >> 8) * 8,
((fg & 0x0f0) >> 4) * 8,
(fg & 0x00f) * 8);
@@ -291,7 +291,7 @@ static void gl_display(caca_display_t *dp)

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


+ 2
- 2
caca/driver_ncurses.c View File

@@ -196,14 +196,14 @@ static unsigned int ncurses_get_display_height(caca_display_t *dp)
static void ncurses_display(caca_display_t *dp)
{
int x, y;
uint32_t *attr = dp->cv->attr;
uint32_t *attrs = dp->cv->attrs;
uint32_t *chars = dp->cv->chars;
for(y = 0; y < (int)dp->cv->height; y++)
{
move(y, 0);
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++);
}
}


+ 6
- 6
caca/driver_slang.c View File

@@ -201,7 +201,7 @@ static unsigned int slang_get_display_height(caca_display_t *dp)
static void slang_display(caca_display_t *dp)
{
int x, y;
uint32_t *attr = dp->cv->attr;
uint32_t *attrs = dp->cv->attrs;
uint32_t *chars = dp->cv->chars;
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
* 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);
uint8_t fgcolor = _cucul_attr_to_ansi4fg(*attrs);
uint8_t bgcolor = _cucul_attr_to_ansi4bg(*attrs);

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


+ 3
- 3
caca/driver_vga.c View File

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

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



+ 4
- 4
caca/driver_win32.c View File

@@ -190,7 +190,7 @@ static void win32_display(caca_display_t *dp)
COORD size, pos;
SMALL_RECT rect;
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;
unsigned int n;

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

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



+ 5
- 5
caca/driver_x11.c View File

@@ -246,12 +246,12 @@ static void x11_display(caca_display_t *dp)
{
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;
while(x + len < dp->cv->width
&& _cucul_argb32_to_rgb12bg(attr[len]) == bg)
&& _cucul_attr_to_rgb12bg(attrs[len]) == bg)
len++;

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++)
{
uint32_t *attr = dp->cv->attr + x + y * dp->cv->width;
uint32_t *attrs = dp->cv->attrs + x + y * dp->cv->width;

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

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. */
if(*chars > 0x00000020 && *chars < 0x00000080)


+ 9
- 9
cucul/canvas.c View File

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

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,
* 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)
{
uint32_t color = (cv->bgcolor << 16) | cv->fgcolor;
uint32_t attr = cv->curattr;
unsigned int n;

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

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

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
{
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 */
@@ -392,10 +392,10 @@ int cucul_set_canvas_boundaries(cucul_canvas_t *cv, int x, int y,
cucul_blit(new, -x, -y, cv, NULL);

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

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


+ 148
- 68
cucul/colour.c View File

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

/* 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
* special. */
* special: 0xfa50 instead of 0xfaa0. */
static const uint16_t ansitab[16] =
{
0xf000, 0xf00a, 0xf0a0, 0xf0aa, 0xfa00, 0xfa0a, 0xfa50, 0xfaaa,
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()
* 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
* 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:
* - \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 fg The requested foreground colour.
* \param bg The requested background colour.
* \param style The requested text styles.
* \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)
errno = EINVAL;
@@ -62,33 +104,51 @@ int cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg)
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;
}

/** \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
* 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).
*
* 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:
* - \c EINVAL At least one of the colour values is invalid.
*
* \param cv A handle to the libcucul canvas.
* \param fg The requested foreground colour.
* \param bg The requested background colour.
* \param style The requested text styles.
* \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)
errno = EINVAL;
@@ -102,39 +162,58 @@ int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg)
if(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;
}

/** \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.
*
* \param cv A handle to the libcucul canvas.
* \param x X 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)
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
*/
@@ -143,13 +222,14 @@ static uint8_t nearest_ansi(uint16_t argb16, uint8_t def)
{
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;

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

best = def;
@@ -181,52 +261,52 @@ static uint8_t nearest_ansi(uint16_t argb16, uint8_t def)
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)
| (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;

if(fg == CUCUL_COLOR_TRANSPARENT)
if(fg == (CUCUL_COLOR_TRANSPARENT << 4))
return ansitab[CUCUL_COLOR_LIGHTGRAY] & 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;

if(bg == CUCUL_COLOR_TRANSPARENT)
if(bg == (CUCUL_COLOR_TRANSPARENT << 4))
return ansitab[CUCUL_COLOR_BLACK] & 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 & 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];
else if(fg == CUCUL_COLOR_TRANSPARENT)
else if(fg == (CUCUL_COLOR_TRANSPARENT << 4))
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];
else if(bg == CUCUL_COLOR_TRANSPARENT)
else if(bg == (CUCUL_COLOR_TRANSPARENT << 4))
bg = 0x0fff;

argb[0] = bg >> 12;


+ 22
- 23
cucul/cucul.c View File

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

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->chars = NULL;
cv->attr = NULL;
cv->attrs = NULL;

cv->frame = 0;
cv->framecount = 1;
@@ -74,22 +73,22 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height)
free(cv);
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);
goto nomem;
}
cv->allchars[0] = NULL;
cv->allattr[0] = NULL;
cv->allattrs[0] = NULL;

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

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

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],
new_size * sizeof(uint32_t));
cv->allattr[f] = realloc(cv->allattr[f],
cv->allattrs[f] = realloc(cv->allattrs[f],
new_size * sizeof(uint32_t));
if(!cv->allchars[f] || !cv->allattr[f])
if(!cv->allchars[f] || !cv->allattrs[f])
{
#if defined(HAVE_ERRNO_H)
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++)
{
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--; )
{
uint32_t color = (cv->bgcolor << 16) | cv->fgcolor;
uint32_t attr = cv->curattr;

for(x = 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 */
for(x = width - old_width; x--; )
{
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++)
{
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(x = 0; x < 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++)
{
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 */
for(x = (height - old_height) * width; x--; )
{
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],
new_size * sizeof(uint32_t));
cv->allattr[f] = realloc(cv->allattr[f],
cv->allattrs[f] = realloc(cv->allattrs[f],
new_size * sizeof(uint32_t));
if(!cv->allchars[f] || !cv->allattr[f])
if(!cv->allchars[f] || !cv->allattrs[f])
{
#if defined(HAVE_ERRNO_H)
errno = ENOMEM;
@@ -412,7 +411,7 @@ int _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,

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

return 0;
}


+ 17
- 5
cucul/cucul.h View File

@@ -40,9 +40,10 @@ typedef struct cucul_buffer cucul_buffer_t;
/** font structure */
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. */
@@ -63,6 +64,11 @@ typedef struct cucul_font cucul_font_t;
#define CUCUL_COLOR_WHITE 0x0f /**< The colour index for white. */
#define CUCUL_COLOR_DEFAULT 0x10 /**< The output driver's default 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
@@ -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. */
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);
int cucul_putchar(cucul_canvas_t *, int, int, unsigned long 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 *);
int cucul_set_canvas_boundaries(cucul_canvas_t *, int, 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


+ 11
- 12
cucul/cucul_internals.h View File

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

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

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

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

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

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

+ 29
- 29
cucul/export.c View File

@@ -153,7 +153,7 @@ char const * const * cucul_get_export_list(void)
/* Generate a native libcaca canvas file. */
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;
char *cur;
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--; )
{
uint32_t ch = *chars++;
uint32_t a = *attr++;
uint32_t a = *attrs++;

*cur++ = ch >> 24;
*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++)
{
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width;

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)
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 */
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++)
{
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width;

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];

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++)
{
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width;

for(x = 0; x < cv->width; x += len)
{
cur += sprintf(cur, "<span style=\"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;
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++)
{
uint32_t *lineattr = cv->attr + y * cv->width;
uint32_t *lineattr = cv->attrs + y * cv->width;
uint32_t *linechar = cv->chars + y * cv->width;

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

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

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

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++)
{
@@ -521,7 +521,7 @@ static int export_irc(cucul_canvas_t *cv, cucul_buffer_t *ex)

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;

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++)
{
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];

if(ch == CUCUL_MAGIC_FULLWIDTH)
continue;

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

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

/* 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 */
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++)
{
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",
(float)argb[1] * (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--; )
{
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;

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];
uint32_t ch = *linechar++;

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

cur += sprintf(cur, "newpath\n");
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 */
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++)
{
cur += sprintf(cur, "<rect style=\"fill:#%.03x\" x=\"%d\" y=\"%d\""
" width=\"6\" height=\"10\"/>\n",
_cucul_argb32_to_rgb12bg(*lineattr++),
_cucul_attr_to_rgb12bg(*lineattr++),
x * 6, y * 10);
}
}
@@ -752,7 +752,7 @@ static int export_svg(cucul_canvas_t *cv, cucul_buffer_t *ex)
/* Text */
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;

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\" "
"x=\"%d\" y=\"%d\">",
_cucul_argb32_to_rgb12fg(*lineattr++),
_cucul_attr_to_rgb12fg(*lineattr++),
x * 6, (y * 10) + 8);

if(ch < 0x00000020)


+ 2
- 2
cucul/font.c View File

@@ -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 startx = x * f->header.width;
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;
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
+ ch - f->block_list[b].start];

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

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


+ 1
- 1
cucul/import.c View File

@@ -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 + 2 + 8 * n] << 8)
| (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 + 6 + 8 * n] << 8)
| (uint32_t)buf[16 + 7 + 8 * n];


+ 10
- 10
cucul/sprite.c View File

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

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

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

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--)
{
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);
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)
cv->frame++;

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

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

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

for(f = frame + 1; f < cv->framecount; 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->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)
cv->frame--;
@@ -189,7 +189,7 @@ int cucul_free_canvas_frame(cucul_canvas_t *cv, unsigned int frame)
cv->frame = 0;

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

return 0;
}


+ 6
- 6
cucul/transform.c View File

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

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

return 0;
@@ -70,7 +70,7 @@ int cucul_flip(cucul_canvas_t *cv)
{
uint32_t *cleft = cv->chars + y * cv->width;
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;

while(cleft < cright)
@@ -127,7 +127,7 @@ int cucul_flop(cucul_canvas_t *cv)
{
uint32_t *ctop = cv->chars + x;
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);

while(ctop < cbottom)
@@ -166,7 +166,7 @@ int cucul_rotate(cucul_canvas_t *cv)
{
uint32_t *cbegin = cv->chars;
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;
unsigned int y;



Loading…
Cancel
Save