/* Test al_ustr_next with invalid input. */ static void t25(void) { const char str[] = "þ\xf4\x8f\xbf."; ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us = al_ref_buffer(&info, str, sizeof(str) - 1); int pos; /* Starting in middle of a sequence. */ pos = 1; CHECK(al_ustr_next(us, &pos)); CHECK(pos == 2); /* Unexpected end of 4-byte sequence. */ CHECK(al_ustr_next(us, &pos)); CHECK(pos == 5); }
/* Function: al_ustr_length */ size_t al_ustr_length(const ALLEGRO_USTR *us) { int pos = 0; int c = 0; while (al_ustr_next(us, &pos)) c++; return c; }
/* Test al_ustr_next. */ static void t24(void) { const char str[] = "a\0þ€\xf4\x8f\xbf\xbf"; ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us = al_ref_buffer(&info, str, sizeof(str) - 1); int pos = 0; CHECK(al_ustr_next(us, &pos)); /* a */ CHECK(pos == 1); CHECK(al_ustr_next(us, &pos)); /* NUL */ CHECK(pos == 2); CHECK(al_ustr_next(us, &pos)); /* þ */ CHECK(pos == 4); CHECK(al_ustr_next(us, &pos)); /* € */ CHECK(pos == 7); CHECK(al_ustr_next(us, &pos)); /* U+10FFFF */ CHECK(pos == 11); CHECK(! al_ustr_next(us, &pos)); /* end */ CHECK(pos == 11); }
/* Function: al_ustr_offset */ int al_ustr_offset(const ALLEGRO_USTR *us, int index) { int pos = 0; if (index < 0) index += al_ustr_length(us); while (index-- > 0) { if (!al_ustr_next(us, &pos)) return pos; } return pos; }
void TextEntry::draw() { const Theme & theme = dialog->get_theme(); SaveState state; ALLEGRO_COLOR bg = theme.bg; if (is_disabled()) { bg = al_map_rgb(64, 64, 64); } al_draw_filled_rectangle(x1, y1, x2, y2, bg); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); if (!focused) { al_draw_ustr(theme.font, theme.fg, x1, y1, 0, UString(text, left_pos)); } else { int x = x1; if (cursor_pos > 0) { UString sub(text, left_pos, cursor_pos); al_draw_ustr(theme.font, theme.fg, x1, y1, 0, sub); x += al_get_ustr_width(theme.font, sub); } if ((unsigned) cursor_pos == al_ustr_size(text)) { al_draw_filled_rectangle(x, y1, x + CURSOR_WIDTH, y1 + al_get_font_line_height(theme.font), theme.fg); } else { int post_cursor = cursor_pos; al_ustr_next(text, &post_cursor); UString sub(text, cursor_pos, post_cursor); int subw = al_get_ustr_width(theme.font, sub); al_draw_filled_rectangle(x, y1, x + subw, y1 + al_get_font_line_height(theme.font), theme.fg); al_draw_ustr(theme.font, theme.bg, x, y1, 0, sub); x += subw; al_draw_ustr(theme.font, theme.fg, x, y1, 0, UString(text, post_cursor)); } } }
/* Function: al_ustr_get_next */ int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos) { int32_t c = al_ustr_get(us, *pos); if (c >= 0) { (*pos) += al_utf8_width(c); return c; } if (c == -1) { /* Past end. */ return c; } /* Some invalid byte sequence. */ al_ustr_next(us, pos); return c; }
void TextEntry::on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) { if (is_disabled()) return; switch (event.keycode) { case ALLEGRO_KEY_LEFT: al_ustr_prev(text, &cursor_pos); break; case ALLEGRO_KEY_RIGHT: al_ustr_next(text, &cursor_pos); break; case ALLEGRO_KEY_HOME: cursor_pos = 0; break; case ALLEGRO_KEY_END: cursor_pos = al_ustr_size(text); break; case ALLEGRO_KEY_DELETE: al_ustr_remove_chr(text, cursor_pos); break; case ALLEGRO_KEY_BACKSPACE: if (al_ustr_prev(text, &cursor_pos)) al_ustr_remove_chr(text, cursor_pos); break; default: if (event.unichar >= ' ') { al_ustr_insert_chr(text, cursor_pos, event.unichar); cursor_pos += al_utf8_width(event.unichar); } break; } maybe_scroll(); dialog->request_draw(); }
void TextEntry::maybe_scroll() { const Theme & theme = dialog->get_theme(); if (cursor_pos < left_pos + 3) { if (cursor_pos < 3) left_pos = 0; else left_pos = cursor_pos - 3; } else { for (;;) { const int tw = al_get_ustr_width(theme.font, UString(text, left_pos, cursor_pos)); if (x1 + tw + CURSOR_WIDTH < x2) { break; } al_ustr_next(text, &left_pos); } } }