From b519d05bce6beb29839d0904503447304f7f7bc1 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sun, 25 Nov 2007 14:12:20 +0000 Subject: [PATCH] * Export cucul_attr_to_rgb12_bg(), cucul_attr_to_rgb12_fg() and cucul_attr_to_argb64() (previously _cucul_attr_to_rgb12bg, _cucul_attr_to_rgb12fg and _cucul_attr_to_argb4) in the official libcucul API. * Cleanup complete: libcaca no longer depends on "cucul_internals.h". --- caca/driver_cocoa.m | 8 +- caca/driver_gl.c | 5 +- caca/driver_x11.c | 7 +- cucul/attr.c | 207 +++++++++++++++++++++++++--------------- cucul/cucul.h | 3 + cucul/cucul_internals.h | 3 - cucul/export.c | 12 +-- cucul/font.c | 2 +- 8 files changed, 147 insertions(+), 100 deletions(-) diff --git a/caca/driver_cocoa.m b/caca/driver_cocoa.m index d5a744e..16ff007 100644 --- a/caca/driver_cocoa.m +++ b/caca/driver_cocoa.m @@ -270,7 +270,7 @@ static BOOL s_quitting = NO; attrs = _attrs + x + y * _w; NSColor* color = nil; #if USE_RGB12_FGBG - uint16_t bg = _cucul_attr_to_rgb12bg(*attrs); + uint16_t bg = cucul_attr_to_rgb12_bg(*attrs); if(bg) { # ifdef PRECACHE_WHOLE_COLOR_TABLE @@ -288,7 +288,7 @@ static BOOL s_quitting = NO; } #else uint8_t argb[8]; - _cucul_attr_to_argb4(*attrs, argb); + cucul_attr_to_argb64(*attrs, argb); color = [NSColor colorWithCalibratedRed:((float)argb[1]) / 15.0 green:((float)argb[2]) / 15.0 blue:((float)argb[3]) / 15.0 @@ -328,7 +328,7 @@ static BOOL s_quitting = NO; { NSColor* color = nil; #if USE_RGB12_FGBG - uint16_t fg = _cucul_attr_to_rgb12fg(*attrs); + uint16_t fg = cucul_attr_to_rgb12_fg(*attrs); # ifdef PRECACHE_WHOLE_COLOR_TABLE color = _colorCache[fg]; # else // PRECACHE_WHOLE_COLOR_TABLE @@ -343,7 +343,7 @@ static BOOL s_quitting = NO; # endif // PRECACHE_WHOLE_COLOR_TABLE #else // USE_RGB12_FGBG uint8_t argb[8]; - _cucul_attr_to_argb4(*attrs, argb); + cucul_attr_to_argb64(*attrs, argb); debug_log(@"x,y=[%d,%d] r,g,b back=[%u %u %u] front=[%u %u %u]", x, y, argb[1], argb[2], argb[3], argb[5], argb[6], argb[7]); color = [NSColor colorWithCalibratedRed:((float)argb[5]) / 15.0 diff --git a/caca/driver_gl.c b/caca/driver_gl.c index 8489f39..1e2472c 100644 --- a/caca/driver_gl.c +++ b/caca/driver_gl.c @@ -37,7 +37,6 @@ #include #include "cucul.h" -#include "cucul_internals.h" #include "caca.h" #include "caca_internals.h" @@ -227,7 +226,7 @@ static void gl_display(caca_display_t *dp) /* FIXME: optimise using stride */ for(x = 0; x < dp->drv.p->width; x += dp->drv.p->font_width) { - uint16_t bg = _cucul_attr_to_rgb12bg(*attrs++); + uint16_t bg = cucul_attr_to_rgb12_bg(*attrs++); glColor4b(((bg & 0xf00) >> 8) * 8, ((bg & 0x0f0) >> 4) * 8, @@ -279,7 +278,7 @@ static void gl_display(caca_display_t *dp) dp->drv.p->txid[b + ch - (uint32_t)dp->drv.p->blocks[i]]); - fg = _cucul_attr_to_rgb12fg(*attrs); + fg = cucul_attr_to_rgb12_fg(*attrs); glColor3b(((fg & 0xf00) >> 8) * 8, ((fg & 0x0f0) >> 4) * 8, (fg & 0x00f) * 8); diff --git a/caca/driver_x11.c b/caca/driver_x11.c index e11e439..7051105 100644 --- a/caca/driver_x11.c +++ b/caca/driver_x11.c @@ -34,7 +34,6 @@ #include #include "cucul.h" -#include "cucul_internals.h" #include "caca.h" #include "caca_internals.h" @@ -304,11 +303,11 @@ static void x11_display(caca_display_t *dp) for(x = 0; x < width; x += len) { uint32_t const *attrs = cvattrs + x + y * width; - uint16_t bg = _cucul_attr_to_rgb12bg(*attrs); + uint16_t bg = cucul_attr_to_rgb12_bg(*attrs); len = 1; while(x + len < width - && _cucul_attr_to_rgb12bg(attrs[len]) == bg) + && cucul_attr_to_rgb12_bg(attrs[len]) == bg) len++; XSetForeground(dp->drv.p->dpy, dp->drv.p->gc, @@ -332,7 +331,7 @@ static void x11_display(caca_display_t *dp) for(x = 0; x < width; x++, chars++, attrs++) { XSetForeground(dp->drv.p->dpy, dp->drv.p->gc, - dp->drv.p->colors[_cucul_attr_to_rgb12fg(*attrs)]); + dp->drv.p->colors[cucul_attr_to_rgb12_fg(*attrs)]); x11_put_glyph(dp, x * dp->drv.p->font_width, y * dp->drv.p->font_height, yoff, diff --git a/cucul/attr.c b/cucul/attr.c index 5464014..221c52b 100644 --- a/cucul/attr.c +++ b/cucul/attr.c @@ -25,6 +25,22 @@ static uint8_t nearest_ansi(uint16_t); +/* 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: 0xfa50 instead of 0xfaa0. */ +static const uint16_t ansitab16[16] = +{ + 0xf000, 0xf00a, 0xf0a0, 0xf0aa, 0xfa00, 0xfa0a, 0xfa50, 0xfaaa, + 0xf555, 0xf55f, 0xf5f5, 0xf5ff, 0xff55, 0xff5f, 0xfff5, 0xffff, +}; + +/* Same table, except on 14 bits (3-4-4-3) */ +static const uint16_t ansitab14[16] = +{ + 0x3800, 0x3805, 0x3850, 0x3855, 0x3d00, 0x3d05, 0x3d28, 0x3d55, + 0x3aaa, 0x3aaf, 0x3afa, 0x3aff, 0x3faa, 0x3faf, 0x3ffa, 0x3fff, +}; + /** \brief Get the text attribute at the given coordinates. * * Get the internal \e libcucul attribute value of the character at the @@ -291,69 +307,22 @@ unsigned char cucul_attr_to_ansi_bg(unsigned long int attr) return nearest_ansi(attr >> 18); } -/* - * XXX: the following functions are local +/** \brief Get 12-bit RGB foreground information from attribute. + * + * Get the 12-bit foreground colour value for a given attribute. The returned + * value is a native-endian encoded integer with each red, green and blue + * values encoded on 8 bits in the following order: + * - 8-11 most significant bits: red + * - 4-7 most significant bits: green + * - least significant bits: blue + * + * This function never fails. If the attribute value is outside the expected + * 32-bit range, higher order bits are simply ignored. + * + * \param attr The requested attribute value. + * \return The corresponding 12-bit RGB foreground value. */ - -/* 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: 0xfa50 instead of 0xfaa0. */ -static const uint16_t ansitab16[16] = -{ - 0xf000, 0xf00a, 0xf0a0, 0xf0aa, 0xfa00, 0xfa0a, 0xfa50, 0xfaaa, - 0xf555, 0xf55f, 0xf5f5, 0xf5ff, 0xff55, 0xff5f, 0xfff5, 0xffff, -}; - -/* Same table, except on 14 bits (3-4-4-3) */ -static const uint16_t ansitab14[16] = -{ - 0x3800, 0x3805, 0x3850, 0x3855, 0x3d00, 0x3d05, 0x3d28, 0x3d55, - 0x3aaa, 0x3aaf, 0x3afa, 0x3aff, 0x3faa, 0x3faf, 0x3ffa, 0x3fff, -}; - -static uint8_t nearest_ansi(uint16_t argb14) -{ - unsigned int i, best, dist; - - if(argb14 < (0x10 | 0x40)) - return argb14 ^ 0x40; - - if(argb14 == (CUCUL_DEFAULT | 0x40) || argb14 == (CUCUL_TRANSPARENT | 0x40)) - return argb14 ^ 0x40; - - if(argb14 < 0x0fff) /* too transparent */ - return CUCUL_TRANSPARENT; - - best = CUCUL_DEFAULT; - dist = 0x3fff; - for(i = 0; i < 16; i++) - { - unsigned int d = 0; - int a, b; - - a = (ansitab14[i] >> 7) & 0xf; - b = (argb14 >> 7) & 0xf; - d += (a - b) * (a - b); - - a = (ansitab14[i] >> 3) & 0xf; - b = (argb14 >> 3) & 0xf; - d += (a - b) * (a - b); - - a = (ansitab14[i] << 1) & 0xf; - b = (argb14 << 1) & 0xf; - d += (a - b) * (a - b); - - if(d < dist) - { - dist = d; - best = i; - } - } - - return best; -} - -uint16_t _cucul_attr_to_rgb12fg(uint32_t attr) +unsigned int cucul_attr_to_rgb12_fg(unsigned long int attr) { uint16_t fg = (attr >> 4) & 0x3fff; @@ -369,7 +338,22 @@ uint16_t _cucul_attr_to_rgb12fg(uint32_t attr) return (fg << 1) & 0x0fff; } -uint16_t _cucul_attr_to_rgb12bg(uint32_t attr) +/** \brief Get 12-bit RGB background information from attribute. + * + * Get the 12-bit background colour value for a given attribute. The returned + * value is a native-endian encoded integer with each red, green and blue + * values encoded on 8 bits in the following order: + * - 8-11 most significant bits: red + * - 4-7 most significant bits: green + * - least significant bits: blue + * + * This function never fails. If the attribute value is outside the expected + * 32-bit range, higher order bits are simply ignored. + * + * \param attr The requested attribute value. + * \return The corresponding 12-bit RGB background value. + */ +unsigned int cucul_attr_to_rgb12_bg(unsigned long int attr) { uint16_t bg = attr >> 18; @@ -385,22 +369,26 @@ uint16_t _cucul_attr_to_rgb12bg(uint32_t attr) return (bg << 1) & 0x0fff; } -#define RGB12TO24(i) \ - (((uint32_t)((i & 0xf00) >> 8) * 0x110000) \ - | ((uint32_t)((i & 0x0f0) >> 4) * 0x001100) \ - | ((uint32_t)(i & 0x00f) * 0x000011)) - -uint32_t _cucul_attr_to_rgb24fg(uint32_t attr) -{ - return RGB12TO24(_cucul_attr_to_rgb12fg(attr)); -} - -uint32_t _cucul_attr_to_rgb24bg(uint32_t attr) -{ - return RGB12TO24(_cucul_attr_to_rgb12bg(attr)); -} - -void _cucul_attr_to_argb4(uint32_t attr, uint8_t argb[8]) +/** \brief Get 64-bit ARGB information from attribute. + * + * Get the 64-bit colour and alpha values for a given attribute. The values + * are written as 8-bit integers in the \e argb array in the following order: + * - \e argb[0]: background alpha value + * - \e argb[1]: background red value + * - \e argb[2]: background green value + * - \e argb[3]: background blue value + * - \e argb[4]: foreground alpha value + * - \e argb[5]: foreground red value + * - \e argb[6]: foreground green value + * - \e argb[7]: foreground blue value + * + * This function never fails. If the attribute value is outside the expected + * 32-bit range, higher order bits are simply ignored. + * + * \param attr The requested attribute value. + * \param argb An array of 8-bit integers. + */ +void cucul_attr_to_argb64(unsigned long int attr, unsigned char argb[8]) { uint16_t fg = (attr >> 4) & 0x3fff; uint16_t bg = attr >> 18; @@ -434,3 +422,64 @@ void _cucul_attr_to_argb4(uint32_t attr, uint8_t argb[8]) argb[7] = fg & 0xf; } +/* + * XXX: the following functions are local + */ + +static uint8_t nearest_ansi(uint16_t argb14) +{ + unsigned int i, best, dist; + + if(argb14 < (0x10 | 0x40)) + return argb14 ^ 0x40; + + if(argb14 == (CUCUL_DEFAULT | 0x40) || argb14 == (CUCUL_TRANSPARENT | 0x40)) + return argb14 ^ 0x40; + + if(argb14 < 0x0fff) /* too transparent */ + return CUCUL_TRANSPARENT; + + best = CUCUL_DEFAULT; + dist = 0x3fff; + for(i = 0; i < 16; i++) + { + unsigned int d = 0; + int a, b; + + a = (ansitab14[i] >> 7) & 0xf; + b = (argb14 >> 7) & 0xf; + d += (a - b) * (a - b); + + a = (ansitab14[i] >> 3) & 0xf; + b = (argb14 >> 3) & 0xf; + d += (a - b) * (a - b); + + a = (ansitab14[i] << 1) & 0xf; + b = (argb14 << 1) & 0xf; + d += (a - b) * (a - b); + + if(d < dist) + { + dist = d; + best = i; + } + } + + return best; +} + +#define RGB12TO24(i) \ + (((uint32_t)((i & 0xf00) >> 8) * 0x110000) \ + | ((uint32_t)((i & 0x0f0) >> 4) * 0x001100) \ + | ((uint32_t)(i & 0x00f) * 0x000011)) + +uint32_t _cucul_attr_to_rgb24fg(uint32_t attr) +{ + return RGB12TO24(cucul_attr_to_rgb12_fg(attr)); +} + +uint32_t _cucul_attr_to_rgb24bg(uint32_t attr) +{ + return RGB12TO24(cucul_attr_to_rgb12_bg(attr)); +} + diff --git a/cucul/cucul.h b/cucul/cucul.h index 2f1cbf6..1fccea8 100644 --- a/cucul/cucul.h +++ b/cucul/cucul.h @@ -150,6 +150,9 @@ __extern int cucul_stretch_right(cucul_canvas_t *); __extern unsigned char cucul_attr_to_ansi(unsigned long int); __extern unsigned char cucul_attr_to_ansi_fg(unsigned long int); __extern unsigned char cucul_attr_to_ansi_bg(unsigned long int); +__extern unsigned int cucul_attr_to_rgb12_fg(unsigned long int); +__extern unsigned int cucul_attr_to_rgb12_bg(unsigned long int); +__extern void cucul_attr_to_argb64(unsigned long int, unsigned char[8]); /* @} */ /** \defgroup cucul_charset libcucul character set conversions diff --git a/cucul/cucul_internals.h b/cucul/cucul_internals.h index 252d3bf..ee73e99 100644 --- a/cucul/cucul_internals.h +++ b/cucul/cucul_internals.h @@ -64,11 +64,8 @@ struct cucul_buffer }; /* Colour functions */ -extern uint16_t _cucul_attr_to_rgb12fg(uint32_t); -extern uint16_t _cucul_attr_to_rgb12bg(uint32_t); extern uint32_t _cucul_attr_to_rgb24fg(uint32_t); extern uint32_t _cucul_attr_to_rgb24bg(uint32_t); -extern void _cucul_attr_to_argb4(uint32_t, uint8_t[8]); /* Frames functions */ extern void _cucul_save_frame_info(cucul_canvas_t *); diff --git a/cucul/export.c b/cucul/export.c index ab73396..b458753 100644 --- a/cucul/export.c +++ b/cucul/export.c @@ -394,10 +394,10 @@ static void *export_html(cucul_canvas_t const *cv, unsigned long int *bytes) cur += sprintf(cur, "width; x++) { uint8_t argb[8]; - _cucul_attr_to_argb4(*lineattr++, argb); + cucul_attr_to_argb64(*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), @@ -723,7 +723,7 @@ static void *export_ps(cucul_canvas_t const *cv, unsigned long int *bytes) uint8_t argb[8]; uint32_t ch = *linechar++; - _cucul_attr_to_argb4(*lineattr++, argb); + cucul_attr_to_argb64(*lineattr++, argb); cur += sprintf(cur, "newpath\n"); cur += sprintf(cur, "%d %d moveto\n", (x + 1) * 6, y * 10 + 2); @@ -794,7 +794,7 @@ static void *export_svg(cucul_canvas_t const *cv, unsigned long int *bytes) { cur += sprintf(cur, "\n", - _cucul_attr_to_rgb12bg(*lineattr++), + cucul_attr_to_rgb12_bg(*lineattr++), x * 6, y * 10); } } @@ -817,7 +817,7 @@ static void *export_svg(cucul_canvas_t const *cv, unsigned long int *bytes) cur += sprintf(cur, "", - _cucul_attr_to_rgb12fg(*lineattr++), + cucul_attr_to_rgb12_fg(*lineattr++), x * 6, (y * 10) + 8); if(ch < 0x00000020) diff --git a/cucul/font.c b/cucul/font.c index 02cede5..feb9136 100644 --- a/cucul/font.c +++ b/cucul/font.c @@ -467,7 +467,7 @@ int cucul_render_canvas(cucul_canvas_t const *cv, cucul_font_t const *f, g = &f->glyph_list[f->block_list[b].index + ch - f->block_list[b].start]; - _cucul_attr_to_argb4(attr, argb); + cucul_attr_to_argb64(attr, argb); /* Step 1: unpack glyph */ switch(f->header.bpp)