Пример #1
0
/* Test al_ustr_get on invalid sequences. */
static void t22(void)
{
   ALLEGRO_USTR_INFO info;
   const ALLEGRO_USTR *us;

   /* Empty string. */
   al_set_errno(0);
   CHECK(al_ustr_get(al_ustr_empty_string(), 0) < 0);
   CHECK(al_get_errno() == ERANGE);

   /* 5-byte sequence. */
   us = al_ref_cstr(&info, "\xf8\x88\x80\x80\x80");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 0) < 0);
   CHECK(al_get_errno() == EILSEQ);

   /* Start in trail byte. */
   us = al_ref_cstr(&info, "ð");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 1) < 0);
   CHECK(al_get_errno() == EILSEQ);

   /* Truncated 3-byte sequence. */
   us = al_ref_cstr(&info, "\xEF\xBF");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 0) < 0);
   CHECK(al_get_errno() == EILSEQ);
}
Пример #2
0
/* Test al_ustr_find_replace, al_ustr_find_replace_cstr. */
static void t49(void)
{
   ALLEGRO_USTR *us;
   ALLEGRO_USTR_INFO findi;
   ALLEGRO_USTR_INFO repli;
   const ALLEGRO_USTR *find;
   const ALLEGRO_USTR *repl;

   us = al_ustr_new("aábdðeéfghiíaábdðeéfghií");
   find = al_ref_cstr(&findi, "ðeéf");
   repl = al_ref_cstr(&repli, "deef");

   CHECK(al_ustr_find_replace(us, 0, find, repl));
   CHECK(0 == strcmp(al_cstr(us), "aábddeefghiíaábddeefghií"));

   find = al_ref_cstr(&findi, "aá");
   repl = al_ref_cstr(&repli, "AÁ");

   CHECK(al_ustr_find_replace(us, 14, find, repl));
   CHECK(0 == strcmp(al_cstr(us), "aábddeefghiíAÁbddeefghií"));

   CHECK(al_ustr_find_replace_cstr(us, 0, "dd", "đ"));
   CHECK(0 == strcmp(al_cstr(us), "aábđeefghiíAÁbđeefghií"));

   /* Not allowed */
   find = al_ustr_empty_string();
   CHECK(! al_ustr_find_replace(us, 0, find, repl));
   CHECK(0 == strcmp(al_cstr(us), "aábđeefghiíAÁbđeefghií"));

   al_ustr_free(us);
}
Пример #3
0
/* Function: al_ustr_find_replace_cstr
 */
bool al_ustr_find_replace_cstr(ALLEGRO_USTR *us, int start_pos,
   const char *find, const char *replace)
{
   ALLEGRO_USTR_INFO find_info;
   ALLEGRO_USTR_INFO repl_info;
   ALLEGRO_USTR *find_us = al_ref_cstr(&find_info, find);
   ALLEGRO_USTR *repl_us = al_ref_cstr(&repl_info, replace);

   return al_ustr_find_replace(us, start_pos, find_us, repl_us);
}
Пример #4
0
/* No memory needs to be freed. */
static void t3(void)
{
   ALLEGRO_USTR_INFO info;
   const ALLEGRO_USTR *us = al_ref_cstr(&info, "A static string.");

   CHECK(0 == strcmp(al_cstr(us), "A static string."));
}
Пример #5
0
/* Function: al_ustr_has_suffix_cstr
 */
bool al_ustr_has_suffix_cstr(const ALLEGRO_USTR *us1, const char *s2)
{
   ALLEGRO_USTR_INFO info;
   ALLEGRO_USTR *us2 = al_ref_cstr(&info, s2);

   return al_ustr_has_suffix(us1, us2);
}
Пример #6
0
//splits a string by a character
static int _split_string_by_char(const char *str, int ch, ALLEGRO_USTR *result[], int result_len) {
    //start from the string beginning
    int pos = 0, next_pos;
    
    //count of sub-strings found
    int count = 0;
    
    //temp allegro string 
    ALLEGRO_USTR_INFO temp_info;
    ALLEGRO_USTR *temp = al_ref_cstr(&temp_info, str);

    //iterate until the end of string
    for(;;) {
        //find the character
        next_pos = al_ustr_find_chr(temp, pos, ch);
        
        //if not found, end
        if (next_pos == -1) break;
        
        //add a string; if no more strings can be added, return
        if (!_add_substring(temp, pos, next_pos, result, result_len, &count)) goto END;
        
        //continue after the character
        pos = next_pos + al_utf8_width(ch);
    }
    
    //set the remainder of the string to be the last string in the array
    _add_substring(temp, pos, al_ustr_size(temp), result, result_len, &count);
    
    END:
    
    return count;
} 
Пример #7
0
//returns the filepath of a resource
static ALLEGRO_USTR *_get_resource_filepath(const ALLEGRO_USTR *skin_filepath, const char *resource_filename) {
    ALLEGRO_USTR *result;            
    int pos, end_pos;
    ALLEGRO_USTR *temp;
    ALLEGRO_USTR_INFO temp_info;

    //duplicate the resource filepath in order to replace '\' by '/'
    result = al_ustr_dup(skin_filepath);
    
    //replace '\' with '/'
    al_ustr_find_replace_cstr(result, 0, "\\", "/");
    
    //find the end of the string
    end_pos = al_ustr_size(result);
    
    //find the last occurrence of '/'
    pos = al_ustr_rfind_chr(result, end_pos, '/');
    
    //find the position after the '/'
    pos += al_utf8_width('/');   
    
    //the replace function needs a ustr
    temp = al_ref_cstr(&temp_info, resource_filename);
    
    //replace the string after the '/' with the resource filename
    al_ustr_replace_range(result, pos, end_pos, temp);
    
    return result;
}
Пример #8
0
/* Function: al_ustr_find_set_cstr
 */
int al_ustr_find_set_cstr(const ALLEGRO_USTR *us, int start_pos,
   const char *accept)
{
   ALLEGRO_USTR_INFO info;
   ALLEGRO_USTR *accept_us = al_ref_cstr(&info, accept);

   return al_ustr_find_set(us, start_pos, accept_us);
}
Пример #9
0
/* Function: al_ustr_rfind_cstr
 */
int al_ustr_rfind_cstr(const ALLEGRO_USTR *haystack, int end_pos,
   const char *needle)
{
   ALLEGRO_USTR_INFO info;
   ALLEGRO_USTR *needle_us = al_ref_cstr(&info, needle);

   return al_ustr_rfind_str(haystack, end_pos, needle_us);
}
Пример #10
0
/* Function: al_ustr_find_cset_cstr
 */
int al_ustr_find_cset_cstr(const ALLEGRO_USTR *us, int start_pos,
   const char *reject)
{
   ALLEGRO_USTR_INFO info;
   ALLEGRO_USTR *reject_us = al_ref_cstr(&info, reject);

   return al_ustr_find_cset(us, start_pos, reject_us);
}
Пример #11
0
/* Test al_ustr_get. */
static void t21(void)
{
   ALLEGRO_USTR_INFO info;
   const ALLEGRO_USTR *us;

   us = al_ref_buffer(&info, "", 1);
   CHECK(al_ustr_get(us, 0) == 0);

   us = al_ref_cstr(&info, "\x7f");
   CHECK(al_ustr_get(us, 0) == 0x7f);

   us = al_ref_cstr(&info, "\xC2\x80");
   CHECK(al_ustr_get(us, 0) == 0x80);

   us = al_ref_cstr(&info, "\xDF\xBf");
   CHECK(al_ustr_get(us, 0) == 0x7ff);

   us = al_ref_cstr(&info, "\xE0\xA0\x80");
   CHECK(al_ustr_get(us, 0) == 0x800);

   us = al_ref_cstr(&info, "\xEF\xBF\xBF");
   CHECK(al_ustr_get(us, 0) == 0xffff);

   us = al_ref_cstr(&info, "\xF0\x90\x80\x80");
   CHECK(al_ustr_get(us, 0) == 0x010000);

   us = al_ref_cstr(&info, "\xF4\x8F\xBF\xBF");
   CHECK(al_ustr_get(us, 0) == 0x10ffff);
}
Пример #12
0
/* Test al_ustr_has_prefix, al_ustr_has_suffix. */
static void t48(void)
{
   ALLEGRO_USTR_INFO i1;
   const ALLEGRO_USTR *us1 = al_ref_cstr(&i1, "Thú mỏ vịt");

   /* The _cstr versions are simple wrappers around the real functions so its
    * okay to test them only.
    */

   CHECK(al_ustr_has_prefix_cstr(us1, ""));
   CHECK(al_ustr_has_prefix_cstr(us1, "Thú"));
   CHECK(! al_ustr_has_prefix_cstr(us1, "Thú mỏ vịt."));

   CHECK(al_ustr_has_suffix_cstr(us1, ""));
   CHECK(al_ustr_has_suffix_cstr(us1, "vịt"));
   CHECK(! al_ustr_has_suffix_cstr(us1, "Thú mỏ vịt."));
}
Пример #13
0
//locates a resource by name
static _RESOURCE *_find_resource_by_name(const char *name) {
    ALGUI_LIST_NODE *node;
    _RESOURCE *res;    
    ALLEGRO_USTR_INFO info;
    ALLEGRO_USTR *name_ustr;
    
    //create a temporary name ustr to use in comparison
    name_ustr = al_ref_cstr(&info, name);
    
    //iterate the resources
    for(node = algui_get_first_list_node(&_resources); node; node = algui_get_next_list_node(node)) {
    
        //get the resource
        res = (_RESOURCE *)algui_get_list_node_data(node);
        
        //compare the strings
        if (al_ustr_equal(res->name, name_ustr)) return res;
    }
    
    //not found
    return NULL;
}
Пример #14
0
/* Print some text with a shadow. */
static void print(int x, int y, bool vertical, char const *format, ...)
{
   va_list list;
   char message[1024];
   ALLEGRO_COLOR color;
   int h;
   int j;

   va_start(list, format);
   vsnprintf(message, sizeof message, format, list);
   va_end(list);

   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
   h = al_get_font_line_height(ex.myfont);

   for (j = 0; j < 2; j++) {
      if (j == 0)
         color = al_map_rgb(0, 0, 0);
      else
         color = al_map_rgb(255, 255, 255);

      if (vertical) {
         int i;
         ALLEGRO_USTR_INFO ui;
         const ALLEGRO_USTR *us = al_ref_cstr(&ui, message);
         for (i = 0; i < (int)al_ustr_length(us); i++) {
            ALLEGRO_USTR_INFO letter;
            al_draw_ustr(ex.myfont, color, x + 1 - j, y + 1 - j + h * i, 0,
               al_ref_ustr(&letter, us, al_ustr_offset(us, i),
               al_ustr_offset(us, i + 1)));
         }
      }
      else {
         al_draw_text(ex.myfont, color, x + 1 - j, y + 1 - j, 0, message);
      }
   }
}
Пример #15
0
/* parse_path_string:
 *
 * Parse a path string according to the following grammar.  The last
 * component, if it is not followed by a directory separator, is interpreted
 * as the filename component, unless it is "." or "..".
 *
 * GRAMMAR
 *
 * path     ::=   "//" c+ "/" nonlast        [Windows only]
 *            |   c ":" nonlast              [Windows only]
 *            |   nonlast
 *
 * nonlast  ::=   c* "/" nonlast
 *            |   last
 *
 * last     ::=   "."
 *            |   ".."
 *            |   filename
 *
 * filename ::=   c*                         [but not "." and ".."]
 *
 * c        ::=   any character but '/'
 */
static bool parse_path_string(const ALLEGRO_USTR *str, ALLEGRO_PATH *path)
{
   ALLEGRO_USTR_INFO    dot_info;
   ALLEGRO_USTR_INFO    dotdot_info;
   const ALLEGRO_USTR *  dot = al_ref_cstr(&dot_info, ".");
   const ALLEGRO_USTR *  dotdot = al_ref_cstr(&dotdot_info, "..");

   ALLEGRO_USTR *piece = al_ustr_new("");
   int pos = 0;
   bool on_windows;

   /* We compile the drive handling code on non-Windows platforms to prevent
    * it becoming broken.
    */
#ifdef ALLEGRO_WINDOWS
   on_windows = true;
#else
   on_windows = false;
#endif
   if (on_windows) {
      /* UNC \\server\share name */
      if (al_ustr_has_prefix_cstr(str, "//")) {
         int slash = al_ustr_find_chr(str, 2, '/');
         if (slash == -1 || slash == 2) {
            /* Missing slash or server component is empty. */
            goto Error;
         }
         al_ustr_assign_substr(path->drive, str, pos, slash);
         pos = slash + 1;
      }
      else {
         /* Drive letter. */
         int colon = al_ustr_offset(str, 1);
         if (colon > -1 && al_ustr_get(str, colon) == ':') {
            /* Include the colon in the drive string. */
            al_ustr_assign_substr(path->drive, str, 0, colon + 1);
            pos = colon + 1;
         }
      }
   }

   for (;;) {
      int slash = al_ustr_find_chr(str, pos, '/');

      if (slash == -1) {
         /* Last component. */
         al_ustr_assign_substr(piece, str, pos, al_ustr_size(str));
         if (al_ustr_equal(piece, dot) || al_ustr_equal(piece, dotdot)) {
            al_append_path_component(path, al_cstr(piece));
         }
         else {
            /* This might be an empty string, but that's okay. */
            al_ustr_assign(path->filename, piece);
         }
         break;
      }

      /* Non-last component. */
      al_ustr_assign_substr(piece, str, pos, slash);
      al_append_path_component(path, al_cstr(piece));
      pos = slash + 1;
   }

   al_ustr_free(piece);
   return true;

Error:

   al_ustr_free(piece);
   return false;
}
Пример #16
0
/* Get more ideas for tests from
 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
 */
static void t23(void)
{
   ALLEGRO_USTR_INFO info;
   const ALLEGRO_USTR *us;

   /* Examples of an overlong ASCII character */
   us = al_ref_cstr(&info, "\xc0\xaf");
   CHECK(al_ustr_get(us, 0) < 0);
   us = al_ref_cstr(&info, "\xe0\x80\xaf");
   CHECK(al_ustr_get(us, 0) < 0);
   us = al_ref_cstr(&info, "\xf0\x80\x80\xaf");
   CHECK(al_ustr_get(us, 0) < 0);
   us = al_ref_cstr(&info, "\xf8\x80\x80\x80\xaf");
   CHECK(al_ustr_get(us, 0) < 0);
   us = al_ref_cstr(&info, "\xfc\x80\x80\x80\x80\xaf");
   CHECK(al_ustr_get(us, 0) < 0);

   /* Maximum overlong sequences */
   us = al_ref_cstr(&info, "\xc1\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xe0\x9f\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xf0\x8f\xbf\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xf8\x87\xbf\xbf\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xfc\x83\xbf\xbf\xbf\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   /* Overlong representation of the NUL character */
   us = al_ref_cstr(&info, "\xc0\x80");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xe0\x80\x80");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xf0\x80\x80");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xf8\x80\x80\x80");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xfc\x80\x80\x80\x80");
   CHECK(al_ustr_get(us, 0) < 0);
}
static void render(void)
{
    ALLEGRO_COLOR white = al_map_rgba_f(1, 1, 1, 1);
    ALLEGRO_COLOR black = al_map_rgba_f(0, 0, 0, 1);
    ALLEGRO_COLOR red = al_map_rgba_f(1, 0, 0, 1);
    ALLEGRO_COLOR green = al_map_rgba_f(0, 0.5, 0, 1);
    ALLEGRO_COLOR blue = al_map_rgba_f(0.1, 0.2, 1, 1);
    int x, y, w, h, as, de, xpos, ypos;
    int target_w, target_h;
    ALLEGRO_USTR_INFO info, sub_info;
    const ALLEGRO_USTR *u;

    al_clear_to_color(white);

    al_hold_bitmap_drawing(true);
   
    al_draw_textf(ex.f1, black, 50,  50, 0, "Tulip (kerning)");
    al_draw_textf(ex.f2, black, 50, 100, 0, "Tulip (no kerning)");
    al_draw_textf(ex.f3, black, 50, 200, 0, "This font has a size of 12 pixels, "
        "the one above has 48 pixels.");

    al_hold_bitmap_drawing(false);
    al_hold_bitmap_drawing(true);

    al_draw_textf(ex.f3, red, 50, 220, 0, "The color can simply be changed.");
        
    al_hold_bitmap_drawing(false);
    al_hold_bitmap_drawing(true);

    al_draw_textf(ex.f3, green, 50, 240, 0, "Some unicode symbols:");
    al_draw_textf(ex.f3, green, 50, 260, 0, "%s", get_string("symbols1"));
    al_draw_textf(ex.f3, green, 50, 280, 0, "%s", get_string("symbols2"));
    al_draw_textf(ex.f3, green, 50, 300, 0, "%s", get_string("symbols3"));

   #define OFF(x) al_ustr_offset(u, x)
   #define SUB(x, y) al_ref_ustr(&sub_info, u, OFF(x), OFF(y))
    u = al_ref_cstr(&info, get_string("substr1"));
    al_draw_ustr(ex.f3, green, 50, 320, 0, SUB(0, 6));
    u = al_ref_cstr(&info, get_string("substr2"));
    al_draw_ustr(ex.f3, green, 50, 340, 0, SUB(7, 11));
    u = al_ref_cstr(&info, get_string("substr3"));
    al_draw_ustr(ex.f3, green, 50, 360, 0, SUB(4, 11));
    u = al_ref_cstr(&info, get_string("substr4"));
    al_draw_ustr(ex.f3, green, 50, 380, 0, SUB(0, 11));

    al_draw_textf(ex.f5, black, 50, 420, 0, "forced monochrome");

    al_hold_bitmap_drawing(false);

    target_w = al_get_bitmap_width(al_get_target_bitmap());
    target_h = al_get_bitmap_height(al_get_target_bitmap());

    xpos = target_w - 10;
    ypos = target_h - 10;
    al_get_text_dimensions(ex.f4, "Allegro", &x, &y, &w, &h);
    as = al_get_font_ascent(ex.f4);
    de = al_get_font_descent(ex.f4);
    xpos -= w;
    ypos -= h;
    x += xpos;
    y += ypos;

    al_draw_rectangle(x, y, x + w, y + h, black, 0);
    al_draw_line(x, y + as, x + w, y + as, black, 0);
    al_draw_line(x, y + as + de, x + w, y + as + de, black, 0);

    al_hold_bitmap_drawing(true);
    al_draw_textf(ex.f4, blue, xpos, ypos, 0, "Allegro");
    al_hold_bitmap_drawing(false);

    al_hold_bitmap_drawing(true);

    al_draw_textf(ex.f3, black, target_w, 0, ALLEGRO_ALIGN_RIGHT,
       "%.1f FPS", ex.fps);
       
    al_hold_bitmap_drawing(false);
}
Пример #18
0
/* _al_xwin_keyboard_handler:
 *  Keyboard "interrupt" handler.
 */
void _al_xwin_keyboard_handler(XKeyEvent *event, ALLEGRO_DISPLAY *display)
{
    int keycode;

    if (!xkeyboard_installed)
        return;

    keycode = keycode_to_scancode[event->keycode];
    if (keycode == -1)
        keycode = find_unknown_key_assignment(event->keycode);

    update_shifts(event);

    /* Special case the pause key. */
    if (keycode == ALLEGRO_KEY_PAUSE) {
        /* Allegro ignore's releasing of the pause key. */
        if (event->type == KeyRelease)
            return;
        if (pause_key) {
            event->type = KeyRelease;
            pause_key = 0;
        }
        else {
            pause_key = 1;
        }
    }

    if (event->type == KeyPress) { /* Key pressed.  */
        int len;
        char buffer[16];
        int unicode = 0;
        int filtered = 0;

#if defined (ALLEGRO_XWINDOWS_WITH_XIM) && defined(X_HAVE_UTF8_STRING)
        if (xic) {
            len = Xutf8LookupString(xic, event, buffer, sizeof buffer, NULL, NULL);
        }
        else
#endif
        {
            /* XLookupString is supposed to only use ASCII. */
            len = XLookupString(event, buffer, sizeof buffer, NULL, NULL);
        }
        buffer[len] = '\0';
        ALLEGRO_USTR_INFO info;
        const ALLEGRO_USTR *ustr = al_ref_cstr(&info, buffer);
        unicode = al_ustr_get(ustr, 0);
        if (unicode < 0)
            unicode = 0;

#ifdef ALLEGRO_XWINDOWS_WITH_XIM
        ALLEGRO_DISPLAY_XGLX *glx = (void *)display;
        filtered = XFilterEvent((XEvent *)event, glx->window);
#endif
        if (keycode || unicode) {
            handle_key_press(keycode, unicode, filtered, _key_shifts, display);
        }
    }
    else { /* Key release. */
        /* HACK:
         * Detect key repeat by looking forward to see if this release is
         * followed by a press event, in which case we assume that this release
         * event was generated in response to that key press event. Events are
         * simultaneous if they are separated by less than 4 ms (a value that
         * worked well on one machine where this hack was needed).
         *
         * This is unnecessary on systems where XkbSetDetectableAutorepeat works.
         */
        if (XPending(event->display) > 0) {
            ALLEGRO_KEY_REPEAT_DATA d;
            XEvent dummy;
            d.event = event;
            d.found = false;
            XCheckIfEvent(event->display, &dummy, check_for_repeat, (XPointer)&d);
            if (d.found) {
                return;
            }
        }
        handle_key_release(keycode, display);
    }
}
Пример #19
0
/* Function: al_ustr_insert_cstr
 */
bool al_ustr_insert_cstr(ALLEGRO_USTR *us, int pos, const char *s)
{
   ALLEGRO_USTR_INFO info;

   return al_ustr_insert(us, pos, al_ref_cstr(&info, s));
}
Пример #20
0
static void render(void)
{
    ALLEGRO_COLOR white = al_map_rgba_f(1, 1, 1, 1);
    ALLEGRO_COLOR black = al_map_rgba_f(0, 0, 0, 1);
    ALLEGRO_COLOR red = al_map_rgba_f(1, 0, 0, 1);
    ALLEGRO_COLOR green = al_map_rgba_f(0, 0.5, 0, 1);
    ALLEGRO_COLOR blue = al_map_rgba_f(0.1, 0.2, 1, 1);
    ALLEGRO_COLOR purple = al_map_rgba_f(0.3, 0.1, 0.2, 1);
    int x, y, w, h, as, de, xpos, ypos;
    unsigned int index;
    int target_w, target_h;
    ALLEGRO_USTR_INFO info, sub_info;
    const ALLEGRO_USTR *u;
    ALLEGRO_USTR *tulip = al_ustr_new("Tulip");
    ALLEGRO_USTR *dimension_text = al_ustr_new("Tulip");
    ALLEGRO_USTR *vertical_text  = al_ustr_new("Rose.");

    al_clear_to_color(white);

    al_hold_bitmap_drawing(true);

    al_draw_textf(ex.f1, black, 50,  20, 0, "Tulip (kerning)");
    al_draw_textf(ex.f2, black, 50,  80, 0, "Tulip (no kerning)");

    x = 50;
    y = 140;
    for (index = 0; index < al_ustr_length(dimension_text); index ++) {
       int cp  = ustr_at(dimension_text, index);
       int bbx, bby, bbw, bbh;
       al_get_glyph_dimensions(ex.f2, cp, &bbx, &bby, &bbw, &bbh);
       al_draw_rectangle(x + bbx + 0.5, y + bby + 0.5, x + bbx + bbw - 0.5, y + bby + bbh - 0.5, blue, 1);
       al_draw_rectangle(x + 0.5, y + 0.5, x + bbx + bbw - 0.5, y + bby + bbh - 0.5, green, 1);
       al_draw_glyph(ex.f2, purple, x, y, cp);
       x += al_get_glyph_advance(ex.f2, cp, ALLEGRO_NO_KERNING);
    }
    al_draw_line(50.5, y+0.5, x+0.5, y+0.5, red, 1);
    al_draw_textf(ex.f2, black, x + 10, y, 0, "(dimensions)");

    al_draw_textf(ex.f3, black, 50, 200, 0, "This font has a size of 12 pixels, "
        "the one above has 48 pixels.");

    al_hold_bitmap_drawing(false);
    al_hold_bitmap_drawing(true);

    al_draw_textf(ex.f3, red, 50, 220, 0, "The color can simply be changed.🐊← fallback glyph");

    al_hold_bitmap_drawing(false);
    al_hold_bitmap_drawing(true);

    al_draw_textf(ex.f3, green, 50, 240, 0, "Some unicode symbols:");
    al_draw_textf(ex.f3, green, 50, 260, 0, "%s", get_string("symbols1"));
    al_draw_textf(ex.f3, green, 50, 280, 0, "%s", get_string("symbols2"));
    al_draw_textf(ex.f3, green, 50, 300, 0, "%s", get_string("symbols3"));

   #define OFF(x) al_ustr_offset(u, x)
   #define SUB(x, y) al_ref_ustr(&sub_info, u, OFF(x), OFF(y))
    u = al_ref_cstr(&info, get_string("substr1"));
    al_draw_ustr(ex.f3, green, 50, 320, 0, SUB(0, 6));
    u = al_ref_cstr(&info, get_string("substr2"));
    al_draw_ustr(ex.f3, green, 50, 340, 0, SUB(7, 11));
    u = al_ref_cstr(&info, get_string("substr3"));
    al_draw_ustr(ex.f3, green, 50, 360, 0, SUB(4, 11));
    u = al_ref_cstr(&info, get_string("substr4"));
    al_draw_ustr(ex.f3, green, 50, 380, 0, SUB(0, 11));

    al_draw_textf(ex.f5, black, 50, 395, 0, "forced monochrome");

    /* Glyph rendering tests. */
    al_draw_textf(ex.f3, red, 50, 410, 0, "Glyph adv Tu: %d, draw: ",
                        al_get_glyph_advance(ex.f3, 'T', 'u'));
    x = 50;
    y = 425;
    for (index = 0; index < al_ustr_length(tulip); index ++) {
       int cp  = ustr_at(tulip, index);
       /* Use al_get_glyph_advance for the stride, with no kerning. */
       al_draw_glyph(ex.f3, red, x, y, cp);
       x += al_get_glyph_advance(ex.f3, cp, ALLEGRO_NO_KERNING);
    }

    x = 50;
    y = 440;
    /* First draw a red string using al_draw_text, that should be hidden
     * completely by the same text drawing in green per glyph
     * using al_draw_glyph and al_get_glyph_advance below. */
    al_draw_ustr(ex.f3, red, x, y, 0, tulip);
    for (index = 0; index < al_ustr_length(tulip); index ++) {
      int cp  = ustr_at(tulip, index);
      int ncp = (index < (al_ustr_length(tulip) - 1)) ?
         ustr_at(tulip, index + 1) : ALLEGRO_NO_KERNING;
      /* Use al_get_glyph_advance for the stride and apply kerning. */
      al_draw_glyph(ex.f3, green, x, y, cp);
      x += al_get_glyph_advance(ex.f3, cp, ncp);
    }

    x = 50;
    y = 466;
    al_draw_ustr(ex.f3, red, x, y, 0, tulip);
    for (index = 0; index < al_ustr_length(tulip); index ++) {
      int cp  = ustr_at(tulip, index);
      int bbx, bby, bbw, bbh;
      al_get_glyph_dimensions(ex.f3, cp, &bbx, &bby, &bbw, &bbh);
      al_draw_glyph(ex.f3, blue, x, y, cp);
      x += bbx + bbw;
    }


    x = 10;
    y = 30;
    for (index = 0; index < al_ustr_length(vertical_text); index ++) {
      int bbx, bby, bbw, bbh;
      int cp  = ustr_at(vertical_text, index);
      /* Use al_get_glyph_dimensions for the height to apply. */
      al_get_glyph_dimensions(ex.f3, cp, &bbx, &bby, &bbw, &bbh);
      al_draw_glyph(ex.f3, green, x, y, cp);
      y += bby;
      y += bbh;
    }


    x = 30;
    y = 30;
    for (index = 0; index < al_ustr_length(vertical_text); index ++) {
      int bbx, bby, bbw, bbh;
      int cp  = ustr_at(vertical_text, index);
      /* Use al_get_glyph_dimensions for the height to apply, here bby is
       * omited for the wrong result. */
      al_get_glyph_dimensions(ex.f3, cp, &bbx, &bby, &bbw, &bbh);
      al_draw_glyph(ex.f3, red, x, y, cp);
      y += bbh;
    }


    al_hold_bitmap_drawing(false);

    target_w = al_get_bitmap_width(al_get_target_bitmap());
    target_h = al_get_bitmap_height(al_get_target_bitmap());

    xpos = target_w - 10;
    ypos = target_h - 10;
    al_get_text_dimensions(ex.f4, "Allegro", &x, &y, &w, &h);
    as = al_get_font_ascent(ex.f4);
    de = al_get_font_descent(ex.f4);
    xpos -= w;
    ypos -= h;
    x += xpos;
    y += ypos;

    al_draw_rectangle(x, y, x + w - 0.5, y + h - 0.5, black, 0);
    al_draw_line(x+0.5, y + as + 0.5, x + w - 0.5, y + as + 0.5, black, 0);
    al_draw_line(x + 0.5, y + as + de + 0.5, x + w - 0.5, y + as + de + 0.5, black, 0);

    al_hold_bitmap_drawing(true);
    al_draw_textf(ex.f4, blue, xpos, ypos, 0, "Allegro");
    al_hold_bitmap_drawing(false);

    al_hold_bitmap_drawing(true);

    al_draw_textf(ex.f3, black, target_w, 0, ALLEGRO_ALIGN_RIGHT,
       "%.1f FPS", ex.fps);

    al_draw_textf(ex.f3, black, 0, 0, 0, "%s: %d unicode ranges", font_file,
       ex.ranges_count);

    al_hold_bitmap_drawing(false);
}
Пример #21
0
/* Test al_ustr_compare, al_ustr_ncompare. */
static void t47(void)
{
   ALLEGRO_USTR_INFO i1;
   ALLEGRO_USTR_INFO i2;

   CHECK(al_ustr_compare(
            al_ref_cstr(&i1, "Thú mỏ vịt"),
            al_ref_cstr(&i2, "Thú mỏ vịt")) == 0);

   CHECK(al_ustr_compare(
            al_ref_cstr(&i1, "Thú mỏ vị"),
            al_ref_cstr(&i2, "Thú mỏ vịt")) < 0);

   CHECK(al_ustr_compare(
            al_ref_cstr(&i1, "Thú mỏ vịt"),
            al_ref_cstr(&i2, "Thú mỏ vit")) > 0);

   CHECK(al_ustr_compare(
            al_ref_cstr(&i1, "abc"),
            al_ref_cstr(&i2, "abc\001")) < 0);

   CHECK(al_ustr_compare(
            al_ref_cstr(&i1, "abc\001"),
            al_ref_cstr(&i2, "abc")) > 0);

   CHECK(al_ustr_ncompare(
            al_ref_cstr(&i1, "Thú mỏ vịt"),
            al_ref_cstr(&i2, "Thú mỏ vit"), 8) == 0);

   CHECK(al_ustr_ncompare(
            al_ref_cstr(&i1, "Thú mỏ vịt"),
            al_ref_cstr(&i2, "Thú mỏ vit"), 9) > 0);

   CHECK(al_ustr_ncompare(
            al_ref_cstr(&i1, "Thú mỏ vịt"),
            al_ref_cstr(&i2, "platypus"), 0) == 0);

   CHECK(al_ustr_ncompare(
            al_ref_cstr(&i1, "abc"),
            al_ref_cstr(&i2, "abc\001"), 4) < 0);

   CHECK(al_ustr_ncompare(
            al_ref_cstr(&i1, "abc\001"),
            al_ref_cstr(&i2, "abc"), 4) > 0);

}