diff --git a/cucul/colour.c b/cucul/colour.c index d4179e2..9d1867d 100644 --- a/cucul/colour.c +++ b/cucul/colour.c @@ -38,6 +38,8 @@ * or created using cucul_ansi_to_attr() and cucul_argb_to_attr(), optionally * ORed with style values such as CUCUL_UNDERLINE or CUCUL_BLINK. * + * Only changing the style does not affect the current colour value. + * * 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. * @@ -55,11 +57,47 @@ int cucul_set_attr(cucul_canvas_t *cv, unsigned long int attr) return -1; } + if(attr < 0x00000010) + attr = (cv->curattr & 0xfffffff0) | attr; + cv->curattr = attr; return 0; } +/** \brief Get the text attribute at the given coordinates. + * + * 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 + * - 4 bits for the background red component + * - 4 bits for the background green component + * - 3 bits for the background blue component + * - 3 bits for the foreground alpha + * - 4 bits for the foreground red component + * - 4 bits for the foreground green component + * - 3 bits for the foreground blue component + * - 4 bits for the bold, italics, underline and blink flags + * + * 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. + * \return The requested attribute. + */ +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 (unsigned long int)cv->curattr; + + return (unsigned long int)cv->attrs[x + y * cv->width]; +} + /** \brief Set the default colour pair and text style (ANSI version). * * Set the default ANSI colour pair and text style for drawing. String @@ -92,6 +130,9 @@ unsigned long int cucul_ansi_to_attr(unsigned char fg, unsigned char bg) return 0; } + fg |= 0x40; + bg |= 0x40; + return ((unsigned long int)bg << 18) | ((unsigned long int)fg << 4); } @@ -148,39 +189,6 @@ int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg) return cucul_set_attr(cv, cucul_argb_to_attr(fg, bg)); } -/** \brief Get the text attribute at the given coordinates. - * - * 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 - * - 4 bits for the background red component - * - 4 bits for the background green component - * - 3 bits for the background blue component - * - 3 bits for the foreground alpha - * - 4 bits for the foreground red component - * - 4 bits for the foreground green component - * - 3 bits for the foreground blue component - * - 4 bits for the bold, italics, underline and blink flags - * - * 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. - * \return The requested attribute. - */ -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 (unsigned long int)cv->curattr; - - return (unsigned long int)cv->attrs[x + y * cv->width]; -} - /* * XXX: the following functions are local */ @@ -205,10 +213,10 @@ static uint8_t nearest_ansi(uint16_t argb14, uint8_t def) { unsigned int i, best, dist; - if(argb14 < 0x0010) - return argb14; + if(argb14 < 0x0050) + return argb14 ^ 0x40; - if(argb14 == CUCUL_DEFAULT || argb14 == CUCUL_TRANSPARENT) + if(argb14 == (CUCUL_DEFAULT | 0x40) || argb14 == (CUCUL_TRANSPARENT | 0x40)) return def; if(argb14 < 0x0fff) /* too transparent, return default colour */ @@ -266,13 +274,13 @@ uint16_t _cucul_attr_to_rgb12fg(uint32_t attr) { uint16_t fg = (attr >> 4) & 0x3fff; - if(fg < 0x0010) - return ansitab16[fg] & 0x0fff; + if(fg < 0x0050) + return ansitab16[fg ^ 0x40] & 0x0fff; - if(fg == CUCUL_DEFAULT) + if(fg == (CUCUL_DEFAULT | 0x40)) return ansitab16[CUCUL_LIGHTGRAY] & 0x0fff; - if(fg == CUCUL_TRANSPARENT) + if(fg == (CUCUL_TRANSPARENT | 0x40)) return ansitab16[CUCUL_LIGHTGRAY] & 0x0fff; return (fg << 1) & 0x0fff; @@ -282,13 +290,13 @@ uint16_t _cucul_attr_to_rgb12bg(uint32_t attr) { uint16_t bg = attr >> 18; - if(bg < 0x0010) - return ansitab16[bg] & 0x0fff; + if(bg < 0x0050) + return ansitab16[bg ^ 0x40] & 0x0fff; - if(bg == CUCUL_DEFAULT) + if(bg == (CUCUL_DEFAULT | 0x40)) return ansitab16[CUCUL_BLACK] & 0x0fff; - if(bg == CUCUL_TRANSPARENT) + if(bg == (CUCUL_TRANSPARENT | 0x40)) return ansitab16[CUCUL_BLACK] & 0x0fff; return (bg << 1) & 0x0fff; @@ -314,11 +322,11 @@ void _cucul_attr_to_argb4(uint32_t attr, uint8_t argb[8]) uint16_t fg = (attr >> 4) & 0x3fff; uint16_t bg = attr >> 18; - if(bg < 0x0010) - bg = ansitab16[bg]; - else if(bg == CUCUL_DEFAULT) + if(bg < 0x0050) + bg = ansitab16[bg ^ 0x40]; + else if(bg == (CUCUL_DEFAULT | 0x40)) bg = ansitab16[CUCUL_BLACK]; - else if(bg == CUCUL_TRANSPARENT) + else if(bg == (CUCUL_TRANSPARENT | 0x40)) bg = 0x0fff; else bg = ((bg << 2) & 0xf000) | ((bg << 1) & 0x0fff); @@ -328,11 +336,11 @@ void _cucul_attr_to_argb4(uint32_t attr, uint8_t argb[8]) argb[2] = (bg >> 4) & 0xf; argb[3] = bg & 0xf; - if(fg < 0x0010) - fg = ansitab16[fg]; - else if(fg == CUCUL_DEFAULT) + if(fg < 0x0050) + fg = ansitab16[fg ^ 0x40]; + else if(fg == (CUCUL_DEFAULT | 0x40)) fg = ansitab16[CUCUL_LIGHTGRAY]; - else if(fg == CUCUL_TRANSPARENT) + else if(fg == (CUCUL_TRANSPARENT | 0x40)) fg = 0x0fff; else fg = ((fg << 2) & 0xf000) | ((fg << 1) & 0x0fff); diff --git a/cucul/export.c b/cucul/export.c index 3d7816d..8abcf38 100644 --- a/cucul/export.c +++ b/cucul/export.c @@ -230,9 +230,9 @@ static int export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex) if(ch == CUCUL_MAGIC_FULLWIDTH) continue; - fg = (((attr >> 4) & 0x3fff) == CUCUL_DEFAULT) ? + fg = (((attr >> 4) & 0x3fff) == (CUCUL_DEFAULT | 0x40)) ? 0x10 : palette[_cucul_attr_to_ansi4fg(attr)]; - bg = (((attr >> 18) & 0x3fff) == CUCUL_TRANSPARENT) ? + bg = (((attr >> 18) & 0x3fff) == (CUCUL_TRANSPARENT | 0x40)) ? 0x10 : palette[_cucul_attr_to_ansi4bg(attr)]; /* TODO: the [0 could be omitted in some cases */ @@ -566,10 +566,10 @@ static int export_irc(cucul_canvas_t *cv, cucul_buffer_t *ex) if(ch == CUCUL_MAGIC_FULLWIDTH) continue; - if(((attr >> 4) & 0x3fff) == CUCUL_DEFAULT) + if(((attr >> 4) & 0x3fff) == (CUCUL_DEFAULT | 0x40)) fg = 0x10; - if(((attr >> 18) & 0x3fff) == CUCUL_TRANSPARENT) + if(((attr >> 18) & 0x3fff) == (CUCUL_TRANSPARENT | 0x40)) bg = 0x10; /* TODO: optimise series of same fg / same bg diff --git a/test/colors.c b/test/colors.c index 2b51df8..f3dc503 100644 --- a/test/colors.c +++ b/test/colors.c @@ -52,13 +52,13 @@ int main(int argc, char **argv) cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_LIGHTGRAY, CUCUL_BLACK)); cucul_putstr(cv, 3, 20, "This is bold This is blink This is italics This is underline"); - cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_LIGHTGRAY, CUCUL_BLACK) | CUCUL_BOLD); + cucul_set_attr(cv, CUCUL_BOLD); cucul_putstr(cv, 3 + 8, 20, "bold"); - cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_LIGHTGRAY, CUCUL_BLACK) | CUCUL_BLINK); + cucul_set_attr(cv, CUCUL_BLINK); cucul_putstr(cv, 3 + 24, 20, "blink"); - cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_LIGHTGRAY, CUCUL_BLACK) | CUCUL_ITALICS); + cucul_set_attr(cv, CUCUL_ITALICS); cucul_putstr(cv, 3 + 41, 20, "italics"); - cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_LIGHTGRAY, CUCUL_BLACK) | CUCUL_UNDERLINE); + cucul_set_attr(cv, CUCUL_UNDERLINE); cucul_putstr(cv, 3 + 60, 20, "underline"); caca_refresh_display(dp); diff --git a/test/export.c b/test/export.c index 3699f87..e118971 100644 --- a/test/export.c +++ b/test/export.c @@ -126,17 +126,13 @@ int main(int argc, char *argv[]) cucul_putstr(cv, WIDTH / 2 - 8, HEIGHT / 2 - 2, "[ドラゴン ボーレ]"); cucul_putstr(cv, WIDTH / 2 - 7, HEIGHT / 2 + 2, "äβç ░▒▓█▓▒░ ΔЗҒ"); - cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_BLACK, CUCUL_WHITE) - | CUCUL_BOLD); + cucul_set_attr(cv, CUCUL_BOLD); cucul_putstr(cv, WIDTH / 2 - 16, HEIGHT / 2 + 3, "Bold"); - cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_BLACK, CUCUL_WHITE) - | CUCUL_BLINK); + cucul_set_attr(cv, CUCUL_BLINK); cucul_putstr(cv, WIDTH / 2 - 9, HEIGHT / 2 + 3, "Blink"); - cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_BLACK, CUCUL_WHITE) - | CUCUL_ITALICS); + cucul_set_attr(cv, CUCUL_ITALICS); cucul_putstr(cv, WIDTH / 2 - 1, HEIGHT / 2 + 3, "Italics"); - cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_BLACK, CUCUL_WHITE) - | CUCUL_UNDERLINE); + cucul_set_attr(cv, CUCUL_UNDERLINE); cucul_putstr(cv, WIDTH / 2 + 8, HEIGHT / 2 + 3, "Underline"); cucul_set_attr(cv, cucul_ansi_to_attr(CUCUL_WHITE, CUCUL_LIGHTBLUE));