void move_iterator_utf8(std::string const& str, std::string::const_iterator& iter, int num_chars) { if (num_chars > 0) { std::string::difference_type num_bytes_to_end = str.end() - iter; while (num_chars > 0 && iter != str.end()) { int num_bytes = uwidth(&*iter); if (num_bytes <= num_bytes_to_end) { iter += num_bytes; num_bytes_to_end -= num_bytes; } else { iter = str.end(); } num_chars--; } } else if (num_chars < 0) { // Allegro's Unicode-handling functions do not efficiently // handle iterating backwards in UTF-8, which is rather // common for our needs (eg. truncating text being displayed) // so we'll do our own thing here. while (num_chars < 0 && iter != str.begin()) { --iter; char byte = *iter; // a valid UTF-8 encoding of a character always start with // bit-pattern 0xxxxxxx or 11xxxxxx in first byte if ((byte & 0x80) == 0 || (byte & 0xC0) == 0xC0) { num_chars++; } } } }
static void gtk_draw_menu_item(MENU *m, int x, int y, int w, int h, int bar, int sel) { BITMAP *bmp = gui_get_screen(); int fg, bg; int i, j; char buf[256], *tok; if (m->flags & D_DISABLED) { fg = nshadow; bg = normal; } else { fg = black; bg = (sel) ? highlight : normal; } rectfill(bmp, x+1, y+1, x+w-3, y+h-4, bg); if (ugetc(m->text)) { i = 0; j = ugetc(m->text); while ((j) && (j != '\t')) { i += usetc(buf+i, j); j = ugetc(m->text+i); } usetc(buf+i, 0); gui_textout_ex(bmp, buf, x+8, y+1, fg, bg, FALSE); if (j == '\t') { tok = m->text+i + uwidth(m->text+i); gui_textout_ex(bmp, tok, x+w-gui_strlen(tok)-10, y+1, fg, bg, FALSE); } if ((m->child) && (!bar)) draw_sprite(bmp, menu_arrow_bmp, x+w-12, y+(h-menu_arrow_bmp->h)/2); } else { hline(bmp, x+4, y+text_height(font)/2+2, x+w-4, nshadow); hline(bmp, x+4, y+text_height(font)/2+3, x+w-4, highlight); } if (m->flags & D_SELECTED) { line(bmp, x+1, y+text_height(font)/2+1, x+3, y+text_height(font)+1, fg); line(bmp, x+3, y+text_height(font)+1, x+6, y+2, fg); } }
/* sys_directx_message: * Displays a message. */ static void sys_directx_message(AL_CONST char *msg) { char *tmp1 = _AL_MALLOC_ATOMIC(ALLEGRO_MESSAGE_SIZE); char tmp2[WND_TITLE_SIZE*2]; HWND allegro_wnd = win_get_window(); while ((ugetc(msg) == '\r') || (ugetc(msg) == '\n')) msg += uwidth(msg); MessageBoxW(allegro_wnd, (unsigned short *)uconvert(msg, U_CURRENT, tmp1, U_UNICODE, ALLEGRO_MESSAGE_SIZE), (unsigned short *)uconvert(wnd_title, U_ASCII, tmp2, U_UNICODE, sizeof(tmp2)), MB_OK); _AL_FREE(tmp1); }
static void photon_draw_menu_item(MENU *m, int x, int y, int w, int h, int bar, int sel) { int i, j, height; char buf[256], *tok; int rtm; if (!menu_done) { photon_do_draw_menu(last_x, last_y, last_w, last_h, bar); menu_done = TRUE; } if (ugetc(m->text)) { if (bar) { if (sel) { rect(screen, x+6, y, x+w-4, y+h, container_black); hline(screen, x+7, y+1, x+w-5, white); vline(screen, x+7, y+1, y+h-2, white); hline(screen, x+7, y+h-1, x+w-5, check_gray1); vline(screen, x+w-5, y, y+h-1, check_gray1); rectgouraud(screen, x+8, y+2, x+w-6, y+h-2, &scrollbar_gray_range, FALSE); } else { hline(screen, x+6, y, x+w-4, white); hline(screen, x+6, y+h-1, x+w-4, check_gray1); rectgouraud(screen, x+6, y+1, x+w-4, y+h-2, &menu_gray_range, FALSE); } } else { if (!(m->flags & D_DISABLED)) { if (sel) rectfill(screen, x+3, y+1, x+w-5, y+h-4, highlight); else rectfill(screen, x+3, y+1, x+w-5, y+h-4, menu_gray_to); } } rtm = text_mode(-1); i = 0; j = ugetc(m->text); while ((j) && (j != '\t')) { i += usetc(buf+i, j); j = ugetc(m->text+i); } usetc(buf+i, 0); if (bar) photon_textout(screen, buf, x+9, y+1, m->flags, FALSE); else photon_textout(screen, buf, x+4, y+1, m->flags, FALSE); if (j == '\t') { tok = m->text+i + uwidth(m->text+i); photon_textout(screen, tok, x+w-gui_strlen(tok)-15, y+1, m->flags, FALSE); } text_mode(rtm); if ((m->child) && (!bar)) draw_sprite(screen, menu_arrow_bmp, x+w-12, y+(h-menu_arrow_bmp->h-1)/2); } else { height = text_height(font); hline(screen, x, y+height/2-1, x+w-1, check_gray1); hline(screen, x, y+height/2, x+w-1, container_black); hline(screen, x, y+height/2+1, x+w-1, white); } if (m->flags & D_SELECTED) { height = text_height(font); line(screen, x+w-10, y+height/2, x+w-8, y+height, checked_gray); line(screen, x+w-8, y+height, x+w-5, y+1, checked_gray); } }
static void abitmap_draw_menu_item (MENU * m, int x, int y, int w, int h, int bar, int sel) { BITMAP *bmp = gui_get_screen(); int i, j; char buf[256], *tok; int c; int fg; int x2 = x, y2 = y, w2 = w, h2 = h; if (m->flags & D_DISABLED) c = 2; else c = 0; if (sel) c = 1; if (bar) { fg = theme->bitmaps[B_MENUBAR_ITEM][c].color; y2 -= 1; h2 += 3; } else { fg = theme->bitmaps[B_MENU_ITEM][c].color; x2 -= 1; w2 += 3; } /* See the previous function. */ if (!menu_done) { /* Draw the menu background. */ if (bar) abitmap_draw_bmp (bmp, &theme->bitmaps[B_MENUBAR][c], last_x, last_y, last_w, last_h); else abitmap_draw_bmp (bmp, &theme->bitmaps[B_MENU][c], last_x, last_y, last_w, last_h); menu_done = TRUE; } abitmap_draw_bmp (bmp, &theme->bitmaps[bar ? B_MENUBAR_ITEM : B_MENU_ITEM][c], x2, y2, w2, h2); if (m->flags & D_SELECTED) { /* checked menu item */ abitmap_draw_bmp (bmp, &theme->bitmaps[B_MENU_CHECK][c], x, y, 12, h); } if (ugetc (m->text)) { i = 0; j = ugetc (m->text); while ((j) && (j != '\t')) { i += usetc (buf + i, j); j = ugetc (m->text + i); } usetc (buf + i, 0); gui_textout_ex (bmp, buf, x + 8, y + 1, fg, -1, FALSE); if (j == '\t') { tok = m->text + i + uwidth (m->text + i); gui_textout_ex (bmp, tok, x + w - gui_strlen (tok) - 10, y + 1, fg, -1, FALSE); } if ((m->child) && (!bar)) { abitmap_draw_bmp (bmp, &theme->bitmaps[B_MENU_SUB][c], x + w - 12, y, 12, h); } } else { /* menu separator */ abitmap_draw_bmp (bmp, &theme->bitmaps[B_MENU_SEP][c], x, y, w, h); } }