Show datfont.c syntax highlighted
/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* Grabber plugin for managing al_font_8x8 objects.
*
* By Shawn Hargreaves.
*
* GRX al_font_8x8 file reader by Mark Wodrich.
*
* See readme.txt for copyright information.
*/
#include <stdio.h>
#include <string.h>
#include "allegro.h"
#include "allegro/internal/aintern.h"
#include "../datedit.h"
/* creates a new al_font_8x8 object */
static void* makenew_font(long* size)
{
AL_FONT *f;
AL_FONT_MONO_DATA* mf = 0, * mfread = al_font_8x8->data;
f = _al_malloc(sizeof(AL_FONT));
f->height = al_font_8x8->height;
f->vtable = al_font_8x8->vtable;
while(mfread) {
int i;
if(mf) {
mf->next = _al_malloc(sizeof(AL_FONT_MONO_DATA));
mf = mf->next;
} else f->data = mf = _al_malloc(sizeof(AL_FONT_MONO_DATA));
mf->begin = mfread->begin;
mf->end = mfread->end;
mf->next = 0;
mf->glyphs = _al_malloc(sizeof(AL_FONT_GLYPH*) * (mf->end - mf->begin));
for(i = mf->begin; i < mf->end; i++) {
AL_FONT_GLYPH *gsrc = mfread->glyphs[i - mf->begin], *gdest;
int sz = ((gsrc->w + 7) / 8) * gsrc->h;
gdest = _al_malloc(sizeof(AL_FONT_GLYPH) + sz);
gdest->w = gsrc->w;
gdest->h = gsrc->h;
memcpy(gdest->dat, gsrc->dat, sz);
mf->glyphs[i - mf->begin] = gdest;
}
mfread = mfread->next;
}
return f;
}
/* displays a al_font_8x8 in the grabber object view window */
static void plot_font(AL_CONST AL_DATAFILE *dat, int x, int y)
{
AL_FONT* f = dat->dat;
int cx = x, bufpos, ch;
char buf[8];
y += 32;
al_text_mode(-1);
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data;
while(mf) {
for(ch = mf->begin; ch < mf->end; ch++) {
bufpos = al_usetc(buf, ch);
al_usetc(buf + bufpos, 0);
if(al_text_length(f, buf) + cx + 4 > AL_SCREEN_W) {
cx = x;
y += al_text_height(f) + 4;
}
if(y > AL_SCREEN_H) break;
al_put_text(al_screen, f, buf, cx, y, al_gui_fg_color);
cx += al_text_length(f, buf) + 4;
}
mf = mf->next;
}
} else {
AL_FONT_COLOR_DATA* cf = f->data;
while(cf) {
for(ch = cf->begin; ch < cf->end; ch++) {
bufpos = al_usetc(buf, ch);
al_usetc(buf + bufpos, 0);
if(al_text_length(f, buf) + cx + 4 > AL_SCREEN_W) {
cx = x;
y += al_text_height(f) + 4;
}
if(y > AL_SCREEN_H) break;
al_put_text(al_screen, f, buf, cx, y, -1);
cx += al_text_length(f, buf) + 4;
}
cf = cf->next;
}
}
}
/* returns a description string for a al_font_8x8 object */
static void get_font_desc(AL_CONST AL_DATAFILE *dat, char *s)
{
AL_FONT *fnt = (AL_FONT *)dat->dat;
char *mono = (fnt->vtable == font_vtable_mono) ? "mono" : "color";
int ranges = 0;
int glyphs = 0;
if(fnt->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = fnt->data;
while(mf) {
ranges++;
glyphs += mf->end - mf->begin;
mf = mf->next;
}
} else {
AL_FONT_COLOR_DATA* cf = fnt->data;
while(cf) {
ranges++;
glyphs += cf->end - cf->begin;
cf = cf->next;
}
}
sprintf(s, "%s al_font_8x8, %d range%s, %d glyphs", mono, ranges, (ranges==1) ? "" : "s", glyphs);
}
/* exports a al_font_8x8 into an external file */
static int export_font(AL_CONST AL_DATAFILE* dat, AL_CONST char* filename)
{
char buf[1024], tmp[1024];
AL_PACKFILE *pack;
AL_FONT* f = dat->dat;
AL_BITMAP *bmp;
AL_PALETTE pal;
int w = 0, h = 0, max = 0, i;
if(stricmp(get_extension_const(filename), "txt") == 0) {
al_replace_extension(buf, filename, "pcx", sizeof(buf));
if(al_file_exists(buf, FA_ARCH | FA_RDONLY, NULL)) {
i = datedit_ask("%s already exists, overwrite", buf);
if(i == 27 || i == 'n' || i == 'N') return TRUE;
}
pack = al_pack_fopen(filename, F_WRITE);
if(!pack) return FALSE;
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data;
while(mf) {
sprintf(tmp, "%s 0x%04X 0x%04X\n", (mf == f->data) ? get_filename_const(buf) : "-", mf->begin, mf->end - 1);
pack_fputs(tmp, pack);
mf = mf->next;
}
} else {
AL_FONT_COLOR_DATA* cf = f->data;
while(cf) {
sprintf(tmp, "%s 0x%04X 0x%04X\n", (cf == f->data) ? get_filename_const(buf) : "-", cf->begin, cf->end - 1);
pack_fputs(tmp, pack);
cf = cf->next;
}
}
pack_fclose(pack);
filename = buf;
} else {
int multi = 0;
if(f->vtable == font_vtable_mono) {
if( ((AL_FONT_MONO_DATA*)f->data) ->next) multi = 1;
} else {
if( ((AL_FONT_COLOR_DATA*)f->data)->next) multi = 1;
}
if(multi) {
i = datedit_ask("Really export multi-range al_font_8x8 as bitmap rather than .txt");
if(i == 27 || i == 'n' || i == 'N') return TRUE;
}
}
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data;
while(mf) {
for(i = mf->begin; i < mf->end; i++) {
AL_FONT_GLYPH* g = mf->glyphs[i - mf->begin];
max++;
if(g->w > w) w = g->w;
if(g->h > h) h = g->h;
}
mf = mf->next;
}
} else {
AL_FONT_COLOR_DATA* cf = f->data;
int i;
while(cf) {
for(i = cf->begin; i < cf->end; i++) {
AL_BITMAP* g = cf->bitmaps[i - cf->begin];
max++;
if(g->w > w) w = g->w;
if(g->h > h) h = g->h;
}
cf = cf->next;
}
}
w = (w + 16) & 0xFFF0;
h = (h + 16) & 0xFFF0;
bmp = al_create_bitmap_ex(8, 1 + w * 16, 1 + h * ((max + 15) / 16) );
al_clear_to_color(bmp, 255);
al_text_mode(0);
max = 0;
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data;
while(mf) {
for(i = mf->begin; i < mf->end; i++) {
al_printf_text(bmp, f, 1 + w * (max & 15), 1 + h * (max / 16), 1, "%c", i);
max++;
}
mf = mf->next;
}
} else {
AL_FONT_COLOR_DATA* cf = f->data;
while(cf) {
for(i = cf->begin; i < cf->end; i++) {
al_printf_text(bmp, f, 1 + w * (max & 15), 1 + h * (max / 16), -1, "%c", i);
max++;
}
cf = cf->next;
}
}
al_get_palette(pal);
al_save_bitmap(filename, bmp, pal);
al_destroy_bitmap(bmp);
return (errno == 0);
}
/* magic number for GRX format al_font_8x8 files */
#define AL_FONTMAGIC 0x19590214L
/* import routine for the GRX al_font_8x8 format */
static AL_FONT* import_grx_font(AL_CONST char* filename)
{
AL_PACKFILE *pack;
AL_FONT *f;
AL_FONT_MONO_DATA *mf;
AL_FONT_GLYPH **gl;
int w, h, num, i;
int* wtab = 0;
pack = al_pack_fopen(filename, F_READ);
if(!pack) return 0;
if(pack_igetl(pack) != AL_FONTMAGIC) {
pack_fclose(pack);
return 0;
}
pack_igetl(pack);
f = _al_malloc(sizeof(AL_FONT));
mf = _al_malloc(sizeof(AL_FONT_MONO_DATA));
f->data = mf;
f->vtable = font_vtable_mono;
mf->next = 0;
w = pack_igetw(pack);
h = pack_igetw(pack);
f->height = h;
mf->begin = pack_igetw(pack);
mf->end = pack_igetw(pack) + 1;
num = mf->end - mf->begin;
gl = mf->glyphs = _al_malloc(sizeof(AL_FONT_GLYPH*) * num);
if(pack_igetw(pack) == 0) {
for(i = 0; i < 38; i++) pack_getc(pack);
wtab = _al_malloc(sizeof(int) * num);
for(i = 0; i < num; i++) wtab[i] = pack_igetw(pack);
} else {
for(i = 0; i < 38; i++) pack_getc(pack);
}
for(i = 0; i < num; i++) {
int sz;
if(wtab) w = wtab[i];
sz = ((w + 7) / 8) * h;
gl[i] = _al_malloc(sizeof(AL_FONT_GLYPH) + sz);
gl[i]->w = w;
gl[i]->h = h;
pack_fread(gl[i]->dat, sz, pack);
}
if(!pack_feof(pack)) {
char cw_char[1024];
strcpy(cw_char, filename);
strcpy(get_extension(cw_char), "txt");
i = datedit_ask("Save al_font_8x8 copyright message into '%s'", cw_char);
if(i != 27 && i != 'n' && i != 'N') {
AL_PACKFILE* pout = al_pack_fopen(cw_char, F_WRITE);
if(pout) {
while(!pack_feof(pack)) {
i = pack_fread(cw_char, 1024, pack);
pack_fwrite(cw_char, i, pout);
}
}
pack_fclose(pout);
}
}
pack_fclose(pack);
if(wtab) free(wtab);
return f;
}
/* import routine for the 8x8 and 8x16 BIOS al_font_8x8 formats */
static AL_FONT* import_bios_font(AL_CONST char* filename)
{
AL_PACKFILE *pack;
AL_FONT *f;
AL_FONT_MONO_DATA *mf;
AL_FONT_GLYPH **gl;
int i, h;
f = _al_malloc(sizeof(AL_FONT));
mf = _al_malloc(sizeof(AL_FONT_MONO_DATA));
gl = _al_malloc(sizeof(AL_FONT_GLYPH*) * 256);
pack = al_pack_fopen(filename, F_READ);
if(!pack) return 0;
h = (pack->todo == 2048) ? 8 : 16;
for(i = 0; i < 256; i++) {
gl[i] = _al_malloc(sizeof(AL_FONT_GLYPH) + 8);
gl[i]->w = gl[i]->h = 8;
pack_fread(gl[i]->dat, 8, pack);
}
f->vtable = font_vtable_mono;
f->data = mf;
f->height = h;
mf->begin = 0;
mf->end = 256;
mf->glyphs = gl;
mf->next = 0;
pack_fclose(pack);
return f;
}
/* state information for the bitmap al_font_8x8 importer */
static AL_BITMAP *import_bmp = NULL;
static int import_x = 0;
static int import_y = 0;
/* import_bitmap_font_mono:
* Helper for import_bitmap_font, below.
*/
static int import_bitmap_font_mono(AL_FONT_GLYPH** gl, int num)
{
int w = 1, h = 1, i;
for(i = 0; i < num; i++) {
if(w > 0 && h > 0) datedit_find_character(import_bmp, &import_x, &import_y, &w, &h);
if(w <= 0 || h <= 0) {
int j;
gl[i] = _al_malloc(sizeof(AL_FONT_GLYPH) + 8);
gl[i]->w = 8;
gl[i]->h = 8;
for(j = 0; j < 8; j++) gl[i]->dat[j] = 0;
} else {
int sx = ((w + 7) / 8), j, k;
gl[i] = _al_malloc(sizeof(AL_FONT_GLYPH) + sx * h);
gl[i]->w = w;
gl[i]->h = h;
for(j = 0; j < sx * h; j++) gl[i]->dat[j] = 0;
for(j = 0; j < h; j++) {
for(k = 0; k < w; k++) {
if(al_get_pixel(import_bmp, import_x + k + 1, import_y + j + 1))
gl[i]->dat[(j * sx) + (k / 8)] |= 0x80 >> (k & 7);
}
}
import_x += w;
}
}
return 0;
}
/* import_bitmap_font_color:
* Helper for import_bitmap_font, below.
*/
static int import_bitmap_font_color(AL_BITMAP** bits, int num)
{
int w = 1, h = 1, i;
for(i = 0; i < num; i++) {
if(w > 0 && h > 0) datedit_find_character(import_bmp, &import_x, &import_y, &w, &h);
if(w <= 0 || h <= 0) {
bits[i] = al_create_bitmap_ex(8, 8, 8);
if(!bits[i]) return -1;
al_clear_to_color(bits[i], 255);
} else {
bits[i] = al_create_bitmap_ex(8, w, h);
if(!bits[i]) return -1;
al_blit(import_bmp, bits[i], import_x + 1, import_y + 1, 0, 0, w, h);
import_x += w;
}
}
return 0;
}
/* bitmap_font_ismono:
* Helper for import_bitmap_font, below.
*/
static int bitmap_font_ismono(AL_BITMAP *bmp)
{
int x, y, col = -1, pixel;
for(y = 0; y < bmp->h; y++) {
for(x = 0; x < bmp->w; x++) {
pixel = al_get_pixel(bmp, x, y);
if(pixel == 0 || pixel == 255) continue;
if(col > 0 && pixel != col) return 0;
col = pixel;
}
}
return 1;
}
/* upgrade_to_color, upgrade_to_color_data:
* Helper functions. Upgrades a monochrome al_font_8x8 to a color al_font_8x8.
*/
static AL_FONT_COLOR_DATA* upgrade_to_color_data(AL_FONT_MONO_DATA* mf)
{
AL_FONT_COLOR_DATA* cf = _al_malloc(sizeof(AL_FONT_COLOR_DATA));
AL_BITMAP** bits = _al_malloc(sizeof(AL_BITMAP*) * (mf->end - mf->begin));
int i;
cf->begin = mf->begin;
cf->end = mf->end;
cf->bitmaps = bits;
cf->next = 0;
al_text_mode(-1);
for(i = mf->begin; i < mf->end; i++) {
AL_FONT_GLYPH* g = mf->glyphs[i - mf->begin];
AL_BITMAP* b = al_create_bitmap_ex(8, g->w, g->h);
al_clear_to_color(b, 0);
b->vtable->draw_glyph(b, g, 0, 0, 1);
bits[i - mf->begin] = b;
free(g);
}
free(mf->glyphs);
free(mf);
return cf;
}
static void upgrade_to_color(AL_FONT* f)
{
AL_FONT_MONO_DATA* mf = f->data;
AL_FONT_COLOR_DATA * cf, *cf_write = 0;
if(f->vtable == font_vtable_color) return;
f->vtable = font_vtable_color;
while(mf) {
AL_FONT_MONO_DATA* mf_next = mf->next;
cf = upgrade_to_color_data(mf);
if(!cf_write) f->data = cf;
else cf_write->next = cf;
cf_write = cf;
mf = mf_next;
}
}
/* bitmap_font_count:
* Helper for `import_bitmap_font', below.
*/
static int bitmap_font_count(AL_BITMAP* bmp)
{
int x = 0, y = 0, w = 0, h = 0;
int num = 0;
while(1) {
datedit_find_character(bmp, &x, &y, &w, &h);
if (w <= 0 || h <= 0) break;
num++;
x += w;
}
return num;
}
/* import routine for the Allegro .pcx al_font_8x8 format */
static AL_FONT* import_bitmap_font(AL_CONST char* fname, int begin, int end, int cleanup)
{
/* NB: `end' is -1 if we want every glyph */
AL_FONT *f;
if(fname) {
AL_PALETTE junk;
if(import_bmp) al_destroy_bitmap(import_bmp);
import_bmp = al_load_bitmap(fname, junk);
import_x = 0;
import_y = 0;
}
if(!import_bmp) return 0;
if(al_bitmap_color_depth(import_bmp) != 8) {
al_destroy_bitmap(import_bmp);
import_bmp = 0;
return 0;
}
f = _al_malloc(sizeof(AL_FONT));
if(end == -1) end = bitmap_font_count(import_bmp) + begin;
if (bitmap_font_ismono(import_bmp)) {
AL_FONT_MONO_DATA* mf = _al_malloc(sizeof(AL_FONT_MONO_DATA));
mf->glyphs = _al_malloc(sizeof(AL_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 {
AL_FONT_COLOR_DATA* cf = _al_malloc(sizeof(AL_FONT_COLOR_DATA));
cf->bitmaps = _al_malloc(sizeof(AL_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;
}
}
if(cleanup) {
al_destroy_bitmap(import_bmp);
import_bmp = 0;
}
return f;
}
/* import routine for the multiple range .txt al_font_8x8 format */
static AL_FONT* import_scripted_font(AL_CONST char* filename)
{
char buf[1024], *bmp_str, *start_str = 0, *end_str = 0;
AL_FONT *f, *f2;
AL_PACKFILE *pack;
int begin, end;
pack = al_pack_fopen(filename, F_READ);
if(!pack) return 0;
f = _al_malloc(sizeof(AL_FONT));
f->data = NULL;
f->height = 0;
f->vtable = NULL;
while(pack_fgets(buf, sizeof(buf)-1, pack)) {
bmp_str = strtok(buf, " \t");
if(bmp_str) start_str = strtok(0, " \t");
if(start_str) end_str = strtok(0, " \t");
if(!bmp_str || !start_str || !end_str) {
datedit_error("Bad al_font_8x8 description (expecting 'file.pcx start end')");
_al_free(f);
pack_fclose(pack);
return 0;
}
if(bmp_str[0] == '-') bmp_str = 0;
begin = strtol(start_str, 0, 0);
if(end_str) end = strtol(end_str, 0, 0) + 1;
else end = -1;
if(begin <= 0 || (end > 0 && end < begin)) {
datedit_error("Bad al_font_8x8 description (expecting 'file.pcx start end'); start > 0, end > start");
_al_free(f);
pack_fclose(pack);
return 0;
}
f2 = import_bitmap_font(bmp_str, begin, end, FALSE);
if(!f2) {
if(bmp_str) datedit_error("Unable to read al_font_8x8 images from %s", bmp_str);
else datedit_error("Unable to read continuation al_font_8x8 images");
_al_free(f);
pack_fclose(pack);
return 0;
}
if(!f->vtable) f->vtable = f2->vtable;
if(!f->height) f->height = f2->height;
if(f2->vtable != f->vtable) {
upgrade_to_color(f);
upgrade_to_color(f2);
}
/* add to end of linked list */
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data;
if(!mf) f->data = f2->data;
else {
while(mf->next) mf = mf->next;
mf->next = f2->data;
}
free(f2);
} else {
AL_FONT_COLOR_DATA* cf = f->data;
if(!cf) f->data = f2->data;
else {
while(cf->next) cf = cf->next;
cf->next = f2->data;
}
free(f2);
}
}
al_destroy_bitmap(import_bmp);
import_bmp = 0;
pack_fclose(pack);
return f;
}
/* imports a al_font_8x8 from an external file (handles various formats) */
static void *grab_font(AL_CONST char *filename, long *size, int x, int y, int w, int h, int depth)
{
AL_PACKFILE *f;
int id;
if (stricmp(get_extension_const(filename), "fnt") == 0) {
f = al_pack_fopen(filename, F_READ);
if (!f)
return NULL;
id = pack_igetl(f);
pack_fclose(f);
if (id == AL_FONTMAGIC)
return import_grx_font(filename);
else
return import_bios_font(filename);
}
else if (stricmp(get_extension_const(filename), "txt") == 0) {
return import_scripted_font(filename);
}
else {
return import_bitmap_font(filename, ' ', -1, TRUE);
}
}
/* helper for save_font, below */
static void save_mono_font(AL_FONT* f, AL_PACKFILE* pack)
{
AL_FONT_MONO_DATA* mf = f->data;
int i = 0;
/* count number of ranges */
while(mf) {
i++;
mf = mf->next;
}
pack_mputw(i, pack);
mf = f->data;
while(mf) {
/* mono, begin, end-1 */
pack_putc(1, pack);
pack_mputl(mf->begin, pack);
pack_mputl(mf->end - 1, pack);
for(i = mf->begin; i < mf->end; i++) {
AL_FONT_GLYPH* g = mf->glyphs[i - mf->begin];
pack_mputw(g->w, pack);
pack_mputw(g->h, pack);
pack_fwrite(g->dat, ((g->w + 7) / 8) * g->h, pack);
}
mf = mf->next;
}
}
/* helper for save_font, below */
static void save_color_font(AL_FONT* f, AL_PACKFILE* pack)
{
AL_FONT_COLOR_DATA* cf = f->data;
int i = 0;
/* count number of ranges */
while(cf) {
i++;
cf = cf->next;
}
pack_mputw(i, pack);
cf = f->data;
while(cf) {
/* mono, begin, end-1 */
pack_putc(0, pack);
pack_mputl(cf->begin, pack);
pack_mputl(cf->end - 1, pack);
for(i = cf->begin; i < cf->end; i++) {
AL_BITMAP* g = cf->bitmaps[i - cf->begin];
int y;
pack_mputw(g->w, pack);
pack_mputw(g->h, pack);
for(y = 0; y < g->h; y++) {
pack_fwrite(g->al_draw_line[y], g->w, pack);
}
}
cf = cf->next;
}
}
/* saves a al_font_8x8 into a datafile */
static void save_font(AL_DATAFILE* dat, int packed, int packkids, int strip, int verbose, int extra, AL_PACKFILE* pack)
{
AL_FONT* f = dat->dat;
pack_mputw(0, pack);
if(f->vtable == font_vtable_mono) save_mono_font(f, pack);
else save_color_font(f, pack);
}
/* for the al_font_8x8 viewer/editor */
static AL_FONT *the_font;
static char char_string[8] = "0x0020";
static char *range_getter(int index, int *list_size);
static int import_proc(int msg, AL_DIALOG *d, int c);
static int delete_proc(int msg, AL_DIALOG *d, int c);
static int font_view_proc(int msg, AL_DIALOG *d, int c);
static AL_DIALOG char_dlg[] =
{
/* (dialog proc) (x) (y) (w) (h) (fg) (bg) (al_key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
{ al_dialog_shadow_box_proc, 0, 0, 225, 73, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
{ al_dialog_text_proc, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, "Base character:", NULL, NULL },
{ al_dialog_edit_proc, 144, 16, 56, 8, 0, 0, 0, 0, 6, 0, char_string, NULL, NULL },
{ al_dialog_button_proc, 72, 44, 81, 17, 0, 0, 13, D_EXIT, 0, 0, "OK", NULL, NULL },
{ NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
};
static AL_DIALOG view_font_dlg[] =
{
/* (dialog proc) (x) (y) (w) (h) (fg) (bg) (al_key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
{ al_dialog_clear_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
{ font_view_proc, 0, 100, 0, 0, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL },
{ al_dialog_list_proc, 0, 0, 161, 100, 0, 0, 0, D_EXIT, 0, 0, range_getter, NULL, NULL },
{ import_proc, 180, 8, 113, 17, 0, 0, 'i', D_EXIT, 0, 0, "&Import Range", NULL, NULL },
{ delete_proc, 180, 40, 113, 17, 0, 0, 'd', D_EXIT, 0, 0, "&Delete Range", NULL, NULL },
{ al_dialog_button_proc, 180, 72, 113, 17, 0, 0, 27, D_EXIT, 0, 0, "Exit", NULL, NULL },
{ NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
};
#define VIEWER 1
#define RANGE_LIST 2
/* dialog callback for retrieving information about the al_font_8x8 range list */
static char *range_getter(int index, int *list_size)
{
static char buf[64];
AL_FONT* f = the_font;
if(index < 0) {
if(!list_size) return 0;
*list_size = 0;
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data;
while(mf) {
(*list_size)++;
mf = mf->next;
}
} else {
AL_FONT_COLOR_DATA* cf = f->data;
while(cf) {
(*list_size)++;
cf = cf->next;
}
}
return 0;
}
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data;
while(index) {
index--;
mf = mf->next;
}
sprintf(buf, "%04X-%04X, mono", mf->begin, mf->end - 1);
} else {
AL_FONT_COLOR_DATA* cf = f->data;
while(index) {
index--;
cf = cf->next;
}
sprintf(buf, "%04X-%04X, color", cf->begin, cf->end - 1);
}
return buf;
}
/* imports a new al_font_8x8 range */
static int import_proc(int msg, AL_DIALOG *d, int c)
{
char name[80*6]; /* 80 chars * max UTF8 char width */
int ret = al_dialog_button_proc(msg, d, c);
AL_FONT *fnt, *f;
long size;
int base;
int i;
if (ret & D_CLOSE) {
#define EXT_LIST "bmp;fnt;lbm;pcx;tga"
strcpy(name, grabber_import_file);
*get_filename(name) = 0;
if (al_select_file("Import range (" EXT_LIST ")", name, EXT_LIST, sizeof(name), 0, 0)) {
al_fix_filename_case(name);
strcpy(grabber_import_file, name);
grabber_busy_mouse(TRUE);
fnt = grab_font(name, &size, -1, -1, -1, -1, -1);
grabber_busy_mouse(FALSE);
if (!fnt) {
datedit_error("Error importing %s", name);
}
else {
int import_begin, import_end;
al_centre_dialog(char_dlg);
al_set_dialog_color(char_dlg, al_gui_fg_color, al_gui_bg_color);
al_do_dialog(char_dlg, 2);
base = strtol(char_string, NULL, 0);
if(fnt->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = fnt->data;
import_end = (mf->end += (base - mf->begin));
import_begin = mf->begin = base;
} else {
AL_FONT_COLOR_DATA* cf = fnt->data;
import_end = (cf->end += (base - cf->begin));
import_begin = cf->begin = base;
}
f = the_font;
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data;
while(mf) {
if(mf->end > import_begin && mf->begin < import_end) {
al_show_alert("Warning, data overlaps with an", "existing range. This almost", "certainly isn't what you want", "Silly me", NULL, 13, 0);
break;
}
mf = mf->next;
}
}
if(f->vtable != fnt->vtable) {
upgrade_to_color(f);
upgrade_to_color(fnt);
}
f = the_font;
i = 0;
if(f->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = f->data, * mf2 = fnt->data;
if(mf->begin > import_begin) {
mf2->next = mf;
f->data = mf2;
} else {
i++;
while(mf->next && mf->next->begin < import_begin) {
mf = mf->next;
i++;
}
mf2->next = mf->next;
mf->next = mf2;
}
} else {
AL_FONT_COLOR_DATA* cf = f->data, * cf2 = fnt->data;
if(cf->begin > import_begin) {
cf2->next = cf;
f->data = cf2;
} else {
i++;
while(cf->next && cf->next->begin < import_begin) {
cf = cf->next;
i++;
}
cf2->next = cf->next;
cf->next = cf2;
}
}
view_font_dlg[RANGE_LIST].d1 = i;
al_object_message(view_font_dlg+VIEWER, MSG_START, 0);
al_object_message(view_font_dlg+RANGE_LIST, MSG_START, 0);
grabber_modified(1);
}
}
return D_REDRAW;
}
return ret;
}
/* deletes a al_font_8x8 range */
static int delete_proc(int msg, AL_DIALOG *d, int c)
{
int ret = al_dialog_button_proc(msg, d, c);
AL_FONT *fnt;
int i;
if (ret & D_CLOSE) {
fnt = the_font;
if(fnt->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = fnt->data, * mf_prev = 0;
if(!mf->next) {
al_show_alert("Deletion not possible:", "fonts must always have at", "least one character range", "Sorry", NULL, 13, 0);
return D_O_K;
}
i = view_font_dlg[RANGE_LIST].d1;
while(i--) {
mf_prev = mf;
mf = mf->next;
}
if(mf_prev) mf_prev->next = mf->next;
else fnt->data = mf->next;
for(i = mf->begin; i < mf->end; i++) free(mf->glyphs[i - mf->begin]);
free(mf->glyphs);
free(mf);
} else {
AL_FONT_COLOR_DATA* cf = fnt->data, * cf_prev = 0;
if(!cf->next) {
al_show_alert("Deletion not possible:", "fonts must always have at", "least one character range", "Sorry", NULL, 13, 0);
return D_O_K;
}
i = view_font_dlg[RANGE_LIST].d1;
while(i--) {
cf_prev = cf;
cf = cf->next;
}
if(cf_prev) cf_prev->next = cf->next;
else fnt->data = cf->next;
for(i = cf->begin; i < cf->end; i++) al_destroy_bitmap(cf->bitmaps[i - cf->begin]);
free(cf->bitmaps);
free(cf);
}
al_object_message(view_font_dlg+VIEWER, MSG_START, 0);
al_object_message(view_font_dlg+RANGE_LIST, MSG_START, 0);
grabber_modified(1);
return D_REDRAW;
}
return ret;
}
/* displays the al_font_8x8 contents */
static int font_view_proc(int msg, AL_DIALOG *d, int c)
{
AL_BITMAP** bits = 0;
AL_FONT_GLYPH** gl = 0;
AL_FONT *fnt;
int x, y, w, h, i;
int font_h;
int begin, end;
al_text_mode(-1);
switch (msg) {
case MSG_START:
if (!d->dp)
d->dp = al_create_bitmap(d->w, d->h);
d->dp2 = NULL;
d->d1 = 0;
d->d2 = 0;
break;
case MSG_END:
al_destroy_bitmap(d->dp);
d->dp = NULL;
break;
case MSG_DRAW:
al_clear_to_color(d->dp, al_gui_mg_color);
fnt = the_font;
i = view_font_dlg[RANGE_LIST].d1;
if(fnt->vtable == font_vtable_mono) {
AL_FONT_MONO_DATA* mf = fnt->data;
while(i--) mf = mf->next;
gl = mf->glyphs;
begin = mf->begin;
end = mf->end;
} else {
AL_FONT_COLOR_DATA* cf = fnt->data;
while(i--) cf = cf->next;
bits = cf->bitmaps;
begin = cf->begin;
end = cf->end;
}
font_h = al_text_height(fnt);
y = d->d1 + 8;
for (i = begin; i < end; i++) {
if (gl) {
w = gl[i - begin]->w;
h = gl[i - begin]->h;
}
else {
w = bits[i - begin]->w;
h = bits[i - begin]->h;
}
al_text_mode(al_gui_mg_color);
al_printf_text(d->dp, al_font_8x8, 32, y+font_h/2-4, al_gui_fg_color, "U+%04X %3dx%-3d %c", i, w, h, i);
al_text_mode(al_make_color(0xC0, 0xC0, 0xC0));
al_printf_text(d->dp, fnt, 200, y, (gl ? al_gui_fg_color : -1), "%c", i);
y += font_h * 3/2;
}
if (d->flags & D_GOTFOCUS) {
for (i=0; i<d->w; i+=2) {
al_put_pixel(d->dp, i, 0, al_gui_fg_color);
al_put_pixel(d->dp, i+1, 0, al_gui_bg_color);
al_put_pixel(d->dp, i, d->h-1, al_gui_bg_color);
al_put_pixel(d->dp, i+1, d->h-1, al_gui_fg_color);
}
for (i=1; i<d->h-1; i+=2) {
al_put_pixel(d->dp, 0, i, al_gui_bg_color);
al_put_pixel(d->dp, 0, i+1, al_gui_fg_color);
al_put_pixel(d->dp, d->w-1, i, al_gui_fg_color);
al_put_pixel(d->dp, d->w-1, i+1, al_gui_bg_color);
}
}
al_blit(d->dp, al_screen, 0, 0, d->x, d->y, d->w, d->h);
d->d2 = y - d->d1;
d->dp2 = fnt;
break;
case MSG_WANTFOCUS:
return D_WANTFOCUS;
case MSG_CHAR:
switch (c >> 8) {
case AL_KEY_UP:
d->d1 += 8;
break;
case AL_KEY_DOWN:
d->d1 -= 8;
break;
case AL_KEY_PGUP:
d->d1 += d->h*2/3;
break;
case AL_KEY_PGDN:
d->d1 -= d->h*2/3;
break;
case AL_KEY_HOME:
d->d1 = 0;
break;
case AL_KEY_END:
d->d1 = -d->d2 + d->h;
break;
default:
return D_O_K;
}
if (d->d1 < -d->d2 + d->h)
d->d1 = -d->d2 + d->h;
if (d->d1 > 0)
d->d1 = 0;
d->flags |= D_DIRTY;
return D_USED_CHAR;
case MSG_CLICK:
if (al_mouse_b & 2)
return D_CLOSE;
x = al_mouse_x;
y = al_mouse_y;
al_show_mouse(NULL);
while (al_mouse_b) {
al_poll_mouse();
if (al_mouse_y != y) {
d->d1 += (y - al_mouse_y);
al_position_mouse(x, y);
if (d->d1 < -d->d2 + d->h)
d->d1 = -d->d2 + d->h;
if (d->d1 > 0)
d->d1 = 0;
al_object_message(d, MSG_DRAW, 0);
}
}
al_show_mouse(al_screen);
return D_O_K;
case MSG_KEY:
return D_CLOSE;
case MSG_IDLE:
if(d->fg != view_font_dlg[RANGE_LIST].d1) {
d->fg = view_font_dlg[RANGE_LIST].d1;
d->d1 = 0;
al_object_message(d, MSG_DRAW, 0);
}
}
return D_O_K;
}
/* handles double-clicking on a al_font_8x8 in the grabber */
static int view_font(AL_DATAFILE *dat)
{
al_show_mouse(NULL);
al_clear_to_color(al_screen, al_gui_mg_color);
the_font = dat->dat;
view_font_dlg[RANGE_LIST].d1 = 0;
view_font_dlg[RANGE_LIST].d2 = 0;
view_font_dlg[VIEWER].w = AL_SCREEN_W;
view_font_dlg[VIEWER].h = AL_SCREEN_H - view_font_dlg[VIEWER].y;
al_set_dialog_color(view_font_dlg, al_gui_fg_color, al_gui_bg_color);
view_font_dlg[0].bg = al_gui_mg_color;
al_do_dialog(view_font_dlg, VIEWER);
dat->dat = the_font;
al_show_mouse(al_screen);
return D_REDRAW;
}
/* plugin interface header */
DATEDIT_OBJECT_INFO datfont_info =
{
DAT_FONT,
"Font",
get_font_desc,
makenew_font,
save_font,
plot_font,
view_font,
NULL
};
DATEDIT_GRABBER_INFO datfont_grabber =
{
DAT_FONT,
"txt;fnt;bmp;lbm;pcx;tga",
"txt;bmp;pcx;tga",
grab_font,
export_font
};
See more files for this project here