#include #include #include #include "chat.h" int utf8_char_int (const char *string); const char *utf8_next_char (const char *string); void gui_nick_hash_djb2_64 (const char *nickname, uint64_t *color_64); int gui_nick_hash_color (const char *nickname); enum Color bx_weechat_nick_colors(const char *nick); int utf8_char_int (const char *string) { const unsigned char *ptr_string; if (!string) return 0; ptr_string = (unsigned char *)string; /* UTF-8, 2 bytes: 110vvvvv 10vvvvvv */ if ((ptr_string[0] & 0xE0) == 0xC0) { if (!ptr_string[1]) return (int)(ptr_string[0] & 0x1F); return ((int)(ptr_string[0] & 0x1F) << 6) + ((int)(ptr_string[1] & 0x3F)); } /* UTF-8, 3 bytes: 1110vvvv 10vvvvvv 10vvvvvv */ else if ((ptr_string[0] & 0xF0) == 0xE0) { if (!ptr_string[1]) return (int)(ptr_string[0] & 0x0F); if (!ptr_string[2]) return (((int)(ptr_string[0] & 0x0F)) << 6) + ((int)(ptr_string[1] & 0x3F)); return (((int)(ptr_string[0] & 0x0F)) << 12) + (((int)(ptr_string[1] & 0x3F)) << 6) + ((int)(ptr_string[2] & 0x3F)); } /* UTF-8, 4 bytes: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */ else if ((ptr_string[0] & 0xF8) == 0xF0) { if (!ptr_string[1]) return (int)(ptr_string[0] & 0x07); if (!ptr_string[2]) return (((int)(ptr_string[0] & 0x07)) << 6) + ((int)(ptr_string[1] & 0x3F)); if (!ptr_string[3]) return (((int)(ptr_string[0] & 0x07)) << 12) + (((int)(ptr_string[1] & 0x3F)) << 6) + ((int)(ptr_string[2] & 0x3F)); return (((int)(ptr_string[0] & 0x07)) << 18) + (((int)(ptr_string[1] & 0x3F)) << 12) + (((int)(ptr_string[2] & 0x3F)) << 6) + ((int)(ptr_string[3] & 0x3F)); } /* UTF-8, 1 byte: 0vvvvvvv */ return (int)ptr_string[0]; } const char * utf8_next_char (const char *string) { if (!string) return NULL; /* UTF-8, 2 bytes: 110vvvvv 10vvvvvv */ if (((unsigned char)(string[0]) & 0xE0) == 0xC0) { if (!string[1]) return (char *)string + 1; return (char *)string + 2; } /* UTF-8, 3 bytes: 1110vvvv 10vvvvvv 10vvvvvv */ else if (((unsigned char)(string[0]) & 0xF0) == 0xE0) { if (!string[1]) return (char *)string + 1; if (!string[2]) return (char *)string + 2; return (char *)string + 3; } /* UTF-8, 4 bytes: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */ else if (((unsigned char)(string[0]) & 0xF8) == 0xF0) { if (!string[1]) return (char *)string + 1; if (!string[2]) return (char *)string + 2; if (!string[3]) return (char *)string + 3; return (char *)string + 4; } /* UTF-8, 1 byte: 0vvvvvvv */ return (char *)string + 1; } void gui_nick_hash_djb2_64 (const char *nickname, uint64_t *color_64) { while (nickname && nickname[0]) { *color_64 ^= (*color_64 << 5) + (*color_64 >> 2) + utf8_char_int (nickname); nickname = utf8_next_char (nickname); } } /* cyan, magenta, green, brown, lightblue, default, lightcyan, lightmagenta, lightgreen, blue */ /* * Hashes a nickname to find color. * * Returns a number which is the index of color in the nicks colors of option * "weechat.color.chat_nick_colors". */ int gui_nick_hash_color (const char *nickname) { const char *ptr_salt; uint64_t color_64; ptr_salt = ""; color_64 = 0; switch (1) { default: /* variant of djb2 hash */ color_64 = 5381; gui_nick_hash_djb2_64 (ptr_salt, &color_64); gui_nick_hash_djb2_64 (nickname, &color_64); break; } return (color_64 % 10); } /* cyan, magenta, green, brown, lightblue, default, lightcyan, lightmagenta, lightgreen, blue */ /* struct t_gui_color gui_weechat_colors_bold[GUI_CURSES_NUM_WEECHAT_COLORS + 1] = { { -1, -1, 0, "default" }, { COLOR_BLACK, COLOR_BLACK, 0, "black" }, { COLOR_BLACK, COLOR_BLACK + 8, A_BOLD, "darkgray" }, { COLOR_RED, COLOR_RED, 0, "red" }, { COLOR_RED, COLOR_RED + 8, A_BOLD, "lightred" }, { COLOR_GREEN, COLOR_GREEN, 0, "green" }, { COLOR_GREEN, COLOR_GREEN + 8, A_BOLD, "lightgreen" }, { COLOR_YELLOW, COLOR_YELLOW, 0, "brown" }, { COLOR_YELLOW, COLOR_YELLOW + 8, A_BOLD, "yellow" }, { COLOR_BLUE, COLOR_BLUE, 0, "blue" }, { COLOR_BLUE, COLOR_BLUE + 8, A_BOLD, "lightblue" }, { COLOR_MAGENTA, COLOR_MAGENTA, 0, "magenta" }, { COLOR_MAGENTA, COLOR_MAGENTA + 8, A_BOLD, "lightmagenta" }, { COLOR_CYAN, COLOR_CYAN, 0, "cyan" }, { COLOR_CYAN, COLOR_CYAN + 8, A_BOLD, "lightcyan" }, { COLOR_WHITE, COLOR_WHITE, 0, "gray" }, { COLOR_WHITE, COLOR_WHITE + 8, A_BOLD, "white" }, { 0, 0, 0, NULL } }; */ /* [Default] = -1, [White] = 8 + COLOR_WHITE, [Black] = 0 + COLOR_BLACK, [Blue] = 0 + COLOR_BLUE, [Green] = 0 + COLOR_GREEN, [Red] = 8 + COLOR_RED, [Brown] = 0 + COLOR_RED, [Magenta] = 0 + COLOR_MAGENTA, [Orange] = 0 + COLOR_YELLOW, [Yellow] = 8 + COLOR_YELLOW, [LightGreen] = 8 + COLOR_GREEN, [Cyan] = 0 + COLOR_CYAN, [LightCyan] = 8 + COLOR_CYAN, [LightBlue] = 8 + COLOR_BLUE, [Pink] = 8 + COLOR_MAGENTA, [Gray] = 8 + COLOR_BLACK, [LightGray] = 0 + COLOR_WHITE, */ // enum Color bx_weechat_nick_colors(const char *nick) { uint32_t weechat_nick_colors(const char *nick) { enum Color weechat_colors[] = { Cyan, Magenta, Green, Orange, LightBlue, Default, LightCyan, Pink, LightGreen, Blue, }; int color = gui_nick_hash_color(nick); return (uint32_t) weechat_colors[color]; }