/* Function: al_grab_font_from_bitmap */ ALLEGRO_FONT *al_grab_font_from_bitmap(ALLEGRO_BITMAP *bmp, int ranges_n, const int ranges[]) { ALLEGRO_FONT *f; ALLEGRO_FONT_COLOR_DATA *cf, *prev = NULL; ALLEGRO_STATE backup; int i; ALLEGRO_COLOR mask = al_get_pixel(bmp, 0, 0); ALLEGRO_BITMAP *glyphs = NULL, *unmasked = NULL; int import_x = 0, import_y = 0; ALLEGRO_LOCKED_REGION *lock = NULL; int w, h; ASSERT(bmp); w = al_get_bitmap_width(bmp); h = al_get_bitmap_height(bmp); f = al_calloc(1, sizeof *f); f->vtable = &_al_font_vtable_color; al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); unmasked = al_clone_bitmap(bmp); /* At least with OpenGL, texture pixels at the very border of * the glyph are sometimes partly sampled from the yellow mask * pixels. To work around this, we replace the mask with full * transparency. * And we best do it on a memory copy to avoid loading back a texture. */ al_convert_mask_to_alpha(unmasked, mask); al_restore_state(&backup); al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER); // Use the users preferred format, so don't set this below! //al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); for (i = 0; i < ranges_n; i++) { int first = ranges[i * 2]; int last = ranges[i * 2 + 1]; int n = 1 + last - first; cf = al_calloc(1, sizeof(ALLEGRO_FONT_COLOR_DATA)); if (prev) prev->next = cf; else f->data = cf; cf->bitmaps = al_malloc(sizeof(ALLEGRO_BITMAP*) * n); cf->bitmaps[0] = NULL; if (!glyphs) { glyphs = al_clone_bitmap(unmasked); if (!glyphs) goto cleanup_and_fail_on_error; lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READONLY); } cf->glyphs = glyphs; if (import_bitmap_font_color(lock->data, lock->pitch, w, h, cf->bitmaps, cf->glyphs, n, &import_x, &import_y)) { goto cleanup_and_fail_on_error; } else { cf->begin = first; cf->end = last + 1; prev = cf; } } al_restore_state(&backup); cf = f->data; if (cf && cf->bitmaps[0]) f->height = al_get_bitmap_height(cf->bitmaps[0]); if (lock) al_unlock_bitmap(bmp); if (unmasked) al_destroy_bitmap(unmasked); f->dtor_item = _al_register_destructor(_al_dtor_list, "font", f, (void (*)(void *))al_destroy_font); return f; cleanup_and_fail_on_error: if (lock) al_unlock_bitmap(bmp); al_restore_state(&backup); al_destroy_font(f); if (unmasked) al_destroy_bitmap(unmasked); return NULL; }
FONT *_ji_bitmap2font(BITMAP *bmp) { FONT *f; int begin = ' '; int end = -1; import_bmp = bmp; import_x = 0; import_y = 0; if(bitmap_color_depth(import_bmp) != 8) { import_bmp = NULL; return 0; } f = (FONT*)_al_malloc(sizeof(FONT)); if(end == -1) end = bitmap_font_count(import_bmp) + begin; if (bitmap_font_ismono(import_bmp)) { FONT_MONO_DATA* mf = (FONT_MONO_DATA*)_al_malloc(sizeof(FONT_MONO_DATA)); mf->glyphs = (FONT_GLYPH**)_al_malloc(sizeof(FONT_GLYPH*) * (end - begin)); if( import_bitmap_font_mono(mf->glyphs, end - begin) ) { free(mf->glyphs); free(mf); free(f); f = 0; } else { f->data = mf; f->vtable = font_vtable_mono; f->height = mf->glyphs[0]->h; mf->begin = begin; mf->end = end; mf->next = 0; } } else { FONT_COLOR_DATA* cf = (FONT_COLOR_DATA*)_al_malloc(sizeof(FONT_COLOR_DATA)); cf->bitmaps = (BITMAP**)_al_malloc(sizeof(BITMAP*) * (end - begin)); if( import_bitmap_font_color(cf->bitmaps, end - begin) ) { free(cf->bitmaps); free(cf); free(f); f = 0; } else { f->data = cf; f->vtable = font_vtable_color; f->height = cf->bitmaps[0]->h; cf->begin = begin; cf->end = end; cf->next = 0; } } import_bmp = NULL; return f; }