static ALLEGRO_BITMAP *push_new_page(ALLEGRO_TTF_FONT_DATA *data, int glyph_size) { ALLEGRO_BITMAP **back; ALLEGRO_BITMAP *page; ALLEGRO_STATE state; int page_size = 1; /* 16 seems to work well. A particular problem are fixed width fonts which * take an inordinate amount of space. */ while (page_size < 16 * glyph_size) { page_size *= 2; } if (page_size < data->min_page_size) { page_size = data->min_page_size; } if (page_size > data->max_page_size) { page_size = data->max_page_size; } if (glyph_size > page_size) { return NULL; } unlock_current_page(data); /* The bitmap will be destroyed when the parent font is destroyed so * it is not safe to register a destructor for it. */ _al_push_destructor_owner(); al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_format(data->bitmap_format); al_set_new_bitmap_flags(data->bitmap_flags); page = al_create_bitmap(page_size, page_size); al_restore_state(&state); _al_pop_destructor_owner(); if (page) { back = _al_vector_alloc_back(&data->page_bitmaps); *back = page; data->page_pos_x = 0; data->page_pos_y = 0; data->page_line_height = 0; } return page; }
// FIXME: Add a special case for when a single glyph rendering won't fit // into 256x256 pixels. static ALLEGRO_BITMAP *push_new_page(ALLEGRO_TTF_FONT_DATA *data) { ALLEGRO_BITMAP **back; ALLEGRO_BITMAP *page; ALLEGRO_STATE state; unlock_current_page(data); /* The bitmap will be destroyed when the parent font is destroyed so * it is not safe to register a destructor for it. */ _al_push_destructor_owner(); al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_format(data->bitmap_format); al_set_new_bitmap_flags(data->bitmap_flags); page = al_create_bitmap(256, 256); al_restore_state(&state); _al_pop_destructor_owner(); back = _al_vector_alloc_back(&data->page_bitmaps); *back = page; /* Sometimes OpenGL will partly sample texels from the border of * glyphs. So we better clear the texture to transparency. * XXX This is very slow and avoidable with some effort. */ al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); al_hold_bitmap_drawing(false); al_set_target_bitmap(*back); al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); al_restore_state(&state); data->page_pos_x = 0; data->page_pos_y = 0; data->page_line_height = 0; return page; }