From 9137c0a05948975296bfbf6747bd3e02e8937702 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 19 May 2006 04:53:48 +0000 Subject: [PATCH] * Export the UTF-8 / UTF-32 / CP437 character conversions to applications. --- caca/driver_ncurses.c | 2 +- caca/driver_slang.c | 2 +- cucul/box.c | 2 +- cucul/canvas.c | 2 +- cucul/charset.c | 170 ++++++++++++++++++++-------------------- cucul/conic.c | 4 +- cucul/cucul.h | 11 +++ cucul/cucul_internals.h | 4 - cucul/export.c | 6 +- cucul/import.c | 2 +- cucul/line.c | 4 +- cucul/triangle.c | 2 +- tools/makefont.c | 3 +- 13 files changed, 112 insertions(+), 102 deletions(-) diff --git a/caca/driver_ncurses.c b/caca/driver_ncurses.c index 0e016f5..5389af8 100644 --- a/caca/driver_ncurses.c +++ b/caca/driver_ncurses.c @@ -490,7 +490,7 @@ static void ncurses_write_utf32(uint32_t ch) char buf[10]; int bytes; - bytes = _cucul_utf32_to_utf8(buf, ch); + bytes = cucul_utf32_to_utf8(buf, ch); buf[bytes] = '\0'; addstr(buf); #else diff --git a/caca/driver_slang.c b/caca/driver_slang.c index 5d95be5..f66ddc2 100644 --- a/caca/driver_slang.c +++ b/caca/driver_slang.c @@ -395,7 +395,7 @@ static void slang_write_utf32(uint32_t ch) char buf[10]; int bytes; - bytes = _cucul_utf32_to_utf8(buf, ch); + bytes = cucul_utf32_to_utf8(buf, ch); buf[bytes] = '\0'; SLsmg_write_string(buf); #else diff --git a/cucul/box.c b/cucul/box.c index 93bfa7a..6302a33 100644 --- a/cucul/box.c +++ b/cucul/box.c @@ -155,7 +155,7 @@ int cucul_fill_box(cucul_canvas_t *cv, int x1, int y1, int x2, int y2, if(x2 > xmax) x2 = xmax; if(y2 > ymax) y2 = ymax; - ch = _cucul_utf8_to_utf32(str); + ch = cucul_utf8_to_utf32(str); for(y = y1; y <= y2; y++) for(x = x1; x <= x2; x++) diff --git a/cucul/canvas.c b/cucul/canvas.c index dfa702d..a43a229 100644 --- a/cucul/canvas.c +++ b/cucul/canvas.c @@ -116,7 +116,7 @@ int cucul_putstr(cucul_canvas_t *cv, int x, int y, char const *s) while(len) { - *chars++ = _cucul_utf8_to_utf32(s); + *chars++ = cucul_utf8_to_utf32(s); *attr++ = (cv->bgcolor << 16) | cv->fgcolor; s = _cucul_skip_utf8(s, 1); diff --git a/cucul/charset.c b/cucul/charset.c index e37c795..1f80a86 100644 --- a/cucul/charset.c +++ b/cucul/charset.c @@ -26,6 +26,10 @@ #include "cucul.h" #include "cucul_internals.h" +/* + * UTF-8 handling + */ + static char const trailing[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -44,46 +48,51 @@ static uint32_t const offsets[6] = 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; -unsigned int _cucul_strlen_utf8(char const *s) -{ - int len = 0; - char const *parser = s; - - while(*parser) - { - int i; - int bytes = 1 + trailing[(int)(unsigned char)*parser]; - - for(i = 1; i < bytes; i++) - if(!parser[i]) - return len; - parser += bytes; - len++; - } - - return len; -} +/* + * CP437 handling + */ -char const *_cucul_skip_utf8(char const *s, unsigned int x) +static uint32_t const cp437_lookup1[] = { - char const *parser = s; - - while(x) - { - int i; - int bytes = 1 + trailing[(int)(unsigned char)*parser]; - - for(i = 1; i < bytes; i++) - if(!parser[i]) - return parser; - parser += bytes; - x--; - } + /* 0x01 - 0x0f: ☺ ☻ ♥ ♦ ♣ ♠ • ◘ ○ ◙ ♂ ♀ ♪ ♫ ☼ */ + 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c, + /* 0x10 - 0x1f: ► ◄ ↕ ‼ ¶ § ▬ ↨ ↑ ↓ → ← ∟ ↔ ▲ ▼ */ + 0x25ba, 0x25c4, 0x2195, 0x203c, 0xb6, 0xa7, 0x25ac, 0x21a8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc +}; - return parser; -} +static uint32_t const cp437_lookup2[] = +{ + /* 0x7f: ⌂ */ + 0x2302, + /* 0x80 - 0x8f: Ç ü é â ä à å ç ê ë è ï î ì Ä Å */ + 0xc7, 0xfc, 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7, + 0xea, 0xeb, 0xe8, 0xef, 0xee, 0xec, 0xc4, 0xc5, + /* 0x90 - 0x9f: É æ Æ ô ö ò û ù ÿ Ö Ü ¢ £ ¥ ₧ ƒ */ + 0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, 0xfb, 0xf9, + 0xff, 0xd6, 0xdc, 0xa2, 0xa3, 0xa5, 0x20a7, 0x192, + /* 0xa0 - 0xaf: á í ó ú ñ Ñ ª º ¿ ⌐ ¬ ½ ¼ ¡ « » */ + 0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba, + 0xbf, 0x2310, 0xac, 0xbd, 0xbc, 0xa1, 0xab, 0xbb, + /* 0xb0 - 0xbf: ░ ▒ ▓ │ ┤ ╡ ╢ ╖ ╕ ╣ ║ ╗ ╝ ╜ ╛ ┐ */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 - 0xcf: └ ┴ ┬ ├ ─ ┼ ╞ ╟ ╚ ╔ ╩ ╦ ╠ ═ ╬ ╧ */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 - 0xdf: ╨ ╤ ╥ ╙ ╘ ╒ ╓ ╫ ╪ ┘ ┌ █ ▄ ▌ ▐ ▀ */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 - 0xef: α ß Γ π Σ σ µ τ Φ Θ Ω δ ∞ φ ε ∩ */ + 0x3b1, 0xdf, 0x393, 0x3c0, 0x3a3, 0x3c3, 0xb5, 0x3c4, + 0x3a6, 0x398, 0x3a9, 0x3b4, 0x221e, 0x3c6, 0x3b5, 0x2229, + /* 0xf0 - 0xff: ≡ ± ≥ ≤ ⌠ ⌡ ÷ ≈ ° ∙ · √ ⁿ ² ■ */ + 0x2261, 0xb1, 0x2265, 0x2264, 0x2320, 0x2321, 0xf7, 0x2248, + 0xb0, 0x2219, 0xb7, 0x221a, 0x207f, 0xb2, 0x25a0, 0xa0 +}; -uint32_t _cucul_utf8_to_utf32(char const *s) +unsigned long int cucul_utf8_to_utf32(char const *s) { int bytes = trailing[(int)(unsigned char)*s]; uint32_t ret = 0; @@ -102,7 +111,7 @@ uint32_t _cucul_utf8_to_utf32(char const *s) return ret; } -unsigned int _cucul_utf32_to_utf8(void *buf, uint32_t ch) +unsigned int cucul_utf32_to_utf8(char *buf, unsigned long int ch) { static const uint8_t mark[7] = { @@ -132,51 +141,7 @@ unsigned int _cucul_utf32_to_utf8(void *buf, uint32_t ch) return bytes; } -/* - * CP437 handling - */ - -static uint32_t const cp437_lookup1[] = -{ - /* 0x01 - 0x0f: ☺ ☻ ♥ ♦ ♣ ♠ • ◘ ○ ◙ ♂ ♀ ♪ ♫ ☼ */ - 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, - 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c, - /* 0x10 - 0x1f: ► ◄ ↕ ‼ ¶ § ▬ ↨ ↑ ↓ → ← ∟ ↔ ▲ ▼ */ - 0x25ba, 0x25c4, 0x2195, 0x203c, 0xb6, 0xa7, 0x25ac, 0x21a8, - 0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc -}; - -static uint32_t const cp437_lookup2[] = -{ - /* 0x7f: ⌂ */ - 0x2302, - /* 0x80 - 0x8f: Ç ü é â ä à å ç ê ë è ï î ì Ä Å */ - 0xc7, 0xfc, 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7, - 0xea, 0xeb, 0xe8, 0xef, 0xee, 0xec, 0xc4, 0xc5, - /* 0x90 - 0x9f: É æ Æ ô ö ò û ù ÿ Ö Ü ¢ £ ¥ ₧ ƒ */ - 0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, 0xfb, 0xf9, - 0xff, 0xd6, 0xdc, 0xa2, 0xa3, 0xa5, 0x20a7, 0x192, - /* 0xa0 - 0xaf: á í ó ú ñ Ñ ª º ¿ ⌐ ¬ ½ ¼ ¡ « » */ - 0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba, - 0xbf, 0x2310, 0xac, 0xbd, 0xbc, 0xa1, 0xab, 0xbb, - /* 0xb0 - 0xbf: ░ ▒ ▓ │ ┤ ╡ ╢ ╖ ╕ ╣ ║ ╗ ╝ ╜ ╛ ┐ */ - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, - 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, - /* 0xc0 - 0xcf: └ ┴ ┬ ├ ─ ┼ ╞ ╟ ╚ ╔ ╩ ╦ ╠ ═ ╬ ╧ */ - 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, - 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, - /* 0xd0 - 0xdf: ╨ ╤ ╥ ╙ ╘ ╒ ╓ ╫ ╪ ┘ ┌ █ ▄ ▌ ▐ ▀ */ - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, - 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, - /* 0xe0 - 0xef: α ß Γ π Σ σ µ τ Φ Θ Ω δ ∞ φ ε ∩ */ - 0x3b1, 0xdf, 0x393, 0x3c0, 0x3a3, 0x3c3, 0xb5, 0x3c4, - 0x3a6, 0x398, 0x3a9, 0x3b4, 0x221e, 0x3c6, 0x3b5, 0x2229, - /* 0xf0 - 0xff: ≡ ± ≥ ≤ ⌠ ⌡ ÷ ≈ ° ∙ · √ ⁿ ² ■ */ - 0x2261, 0xb1, 0x2265, 0x2264, 0x2320, 0x2321, 0xf7, 0x2248, - 0xb0, 0x2219, 0xb7, 0x221a, 0x207f, 0xb2, 0x25a0, 0xa0 -}; - -uint8_t _cucul_utf32_to_cp437(uint32_t ch) +unsigned char cucul_utf32_to_cp437(unsigned long int ch) { unsigned int i; @@ -197,7 +162,7 @@ uint8_t _cucul_utf32_to_cp437(uint32_t ch) return '?'; } -uint32_t _cucul_cp437_to_utf32(uint8_t ch) +unsigned long int cucul_cp437_to_utf32(unsigned char ch) { if(ch > 0x7f) return cp437_lookup2[ch - 0x7f]; @@ -211,3 +176,42 @@ uint32_t _cucul_cp437_to_utf32(uint8_t ch) return 0x00000000; } +unsigned int _cucul_strlen_utf8(char const *s) +{ + int len = 0; + char const *parser = s; + + while(*parser) + { + int i; + int bytes = 1 + trailing[(int)(unsigned char)*parser]; + + for(i = 1; i < bytes; i++) + if(!parser[i]) + return len; + parser += bytes; + len++; + } + + return len; +} + +char const *_cucul_skip_utf8(char const *s, unsigned int x) +{ + char const *parser = s; + + while(x) + { + int i; + int bytes = 1 + trailing[(int)(unsigned char)*parser]; + + for(i = 1; i < bytes; i++) + if(!parser[i]) + return parser; + parser += bytes; + x--; + } + + return parser; +} + diff --git a/cucul/conic.c b/cucul/conic.c index bd640b3..6ca7183 100644 --- a/cucul/conic.c +++ b/cucul/conic.c @@ -43,7 +43,7 @@ static void ellipsepoints(cucul_canvas_t *, int, int, int, int, uint32_t); int cucul_draw_circle(cucul_canvas_t *cv, int x, int y, int r, char const *str) { int test, dx, dy; - uint32_t ch = _cucul_utf8_to_utf32(str); + uint32_t ch = cucul_utf8_to_utf32(str); /* Optimized Bresenham. Kick ass. */ for(test = 0, dx = 0, dy = r ; dx <= dy ; dx++) @@ -138,7 +138,7 @@ int cucul_draw_ellipse(cucul_canvas_t *cv, int xo, int yo, int a, int b, int x = 0; int y = b; int d1 = b*b - (a*a*b) + (a*a/4); - uint32_t ch = _cucul_utf8_to_utf32(str); + uint32_t ch = cucul_utf8_to_utf32(str); ellipsepoints(cv, xo, yo, x, y, ch); diff --git a/cucul/cucul.h b/cucul/cucul.h index f8819eb..e55f45e 100644 --- a/cucul/cucul.h +++ b/cucul/cucul.h @@ -118,6 +118,17 @@ int cucul_flop(cucul_canvas_t *); int cucul_rotate(cucul_canvas_t *); /* @} */ +/** \defgroup charset libcucul character set conversions + * + * These functions perform conversions between usual character sets. + * + * @{ */ +extern unsigned long int cucul_utf8_to_utf32(char const *); +extern unsigned int cucul_utf32_to_utf8(char *, unsigned long int); +extern unsigned char cucul_utf32_to_cp437(unsigned long int); +extern unsigned long int cucul_cp437_to_utf32(unsigned char); +/* @} */ + /** \defgroup prim libcucul primitives drawing * * These functions provide routines for primitive drawing, such as lines, diff --git a/cucul/cucul_internals.h b/cucul/cucul_internals.h index 9027545..5610c9a 100644 --- a/cucul/cucul_internals.h +++ b/cucul/cucul_internals.h @@ -56,10 +56,6 @@ extern int _cucul_set_canvas_size(cucul_canvas_t *, unsigned int, unsigned int); /* Charset functions */ extern unsigned int _cucul_strlen_utf8(char const *); extern char const *_cucul_skip_utf8(char const *, unsigned int); -extern uint32_t _cucul_utf8_to_utf32(char const *); -extern unsigned int _cucul_utf32_to_utf8(void *, uint32_t); -extern uint8_t _cucul_utf32_to_cp437(uint32_t); -extern uint32_t _cucul_cp437_to_utf32(uint8_t); /* Colour functions */ uint8_t _cucul_argb32_to_ansi8(uint32_t); diff --git a/cucul/export.c b/cucul/export.c index 7b040f4..7e009c7 100644 --- a/cucul/export.c +++ b/cucul/export.c @@ -249,7 +249,7 @@ static void export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex) fg - 8, bg - 8, fg - 8, bg - 8); } - cur += _cucul_utf32_to_utf8(cur, ch); + cur += cucul_utf32_to_utf8(cur, ch); prevfg = fg; prevbg = bg; @@ -313,7 +313,7 @@ static void export_ansi(cucul_canvas_t *cv, cucul_buffer_t *ex) cur += sprintf(cur, "5;1;3%d;4%dm", fg - 8, bg - 8); } - *cur++ = _cucul_utf32_to_cp437(ch); + *cur++ = cucul_utf32_to_cp437(ch); prevfg = fg; prevbg = bg; @@ -715,7 +715,7 @@ static void export_svg(cucul_canvas_t *cv, cucul_buffer_t *ex) if(ch < 0x00000020) *cur++ = '?'; else if(ch > 0x0000007f) - cur += _cucul_utf32_to_utf8(cur, ch); + cur += cucul_utf32_to_utf8(cur, ch); else switch((uint8_t)ch) { case '>': cur += sprintf(cur, ">"); break; diff --git a/cucul/import.c b/cucul/import.c index 139ba5d..abf4d57 100644 --- a/cucul/import.c +++ b/cucul/import.c @@ -405,7 +405,7 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) cucul_set_canvas_size(cv, width, height = y + 1); /* Now paste our character */ - cucul_putchar(cv, x, y, _cucul_cp437_to_utf32(buffer[i])); + cucul_putchar(cv, x, y, cucul_cp437_to_utf32(buffer[i])); x++; } diff --git a/cucul/line.c b/cucul/line.c index 5dcf0d2..0e558d7 100644 --- a/cucul/line.c +++ b/cucul/line.c @@ -61,7 +61,7 @@ int cucul_draw_line(cucul_canvas_t *cv, int x1, int y1, int x2, int y2, s.y1 = y1; s.x2 = x2; s.y2 = y2; - s.ch = _cucul_utf8_to_utf32(str); + s.ch = cucul_utf8_to_utf32(str); s.draw = draw_solid_line; clip_line(cv, &s); @@ -89,7 +89,7 @@ int cucul_draw_polyline(cucul_canvas_t *cv, int const x[], int const y[], { int i; struct line s; - s.ch = _cucul_utf8_to_utf32(str); + s.ch = cucul_utf8_to_utf32(str); s.draw = draw_solid_line; for(i = 0; i < n; i++) diff --git a/cucul/triangle.c b/cucul/triangle.c index d738ac0..6e13a9d 100644 --- a/cucul/triangle.c +++ b/cucul/triangle.c @@ -109,7 +109,7 @@ int cucul_fill_triangle(cucul_canvas_t *cv, int x1, int y1, int x2, int y2, xmax = cv->width - 1; ymax = cv->height - 1; - ch = _cucul_utf8_to_utf32(str); + ch = cucul_utf8_to_utf32(str); /* Rasterize our triangle */ for(y = y1 < 0 ? 0 : y1; y <= y3 && y <= ymax; y++) diff --git a/tools/makefont.c b/tools/makefont.c index 77aa70a..7c8a6ca 100644 --- a/tools/makefont.c +++ b/tools/makefont.c @@ -28,7 +28,6 @@ #endif #include "cucul.h" -#include "cucul_internals.h" #include #include @@ -221,7 +220,7 @@ int main(int argc, char *argv[]) unsigned int k; gtab[n].unicode = i; - bytes = _cucul_utf32_to_utf8(gtab[n].buf, gtab[n].unicode); + bytes = cucul_utf32_to_utf8(gtab[n].buf, gtab[n].unicode); gtab[n].buf[bytes] = '\0'; /* Render glyph on a bitmap */