/*********************************************************************************** Bixofont - Utility for converting TTF fonts to Bixolon format Copyright (C) 2012 SAGE team s.r.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***********************************************************************************/ #include <cstdio> #include <cstring> #include <cstdlib> #include <limits.h> #include <allegro.h> #include <winalleg.h> #include <ft2build.h> #include FT_FREETYPE_H FT_Library ftl; FT_Face face; volatile int is_end=FALSE; int threshold=127; uint32_t iso88592[256]={ 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E, 0x001F,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003A,0x003B,0x003C,0x003D, 0x003E,0x003F,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005A,0x005B,0x005C, 0x005D,0x005E,0x005F,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007A,0x007B, 0x007C,0x007D,0x007E,0x007F,0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A, 0x009B,0x009C,0x009D,0x009E,0x009F,0x00A0,0x0104,0x02D8,0x0141,0x00A4,0x013D,0x015A,0x00A7,0x00A8,0x0160,0x015E,0x0164,0x0179,0x00AD,0x017D,0x017B,0x00B0,0x0105,0x02DB,0x0142,0x00B4,0x013E,0x015B,0x02C7,0x00B8,0x0161, 0x015F,0x0165,0x017A,0x02DD,0x017E,0x017C,0x0154,0x00C1,0x00C2,0x0102,0x00C4,0x0139,0x0106,0x00C7,0x010C,0x00C9,0x0118,0x00CB,0x011A,0x00CD,0x00CE,0x010E,0x0110,0x0143,0x0147,0x00D3,0x00D4,0x0150,0x00D6,0x00D7,0x0158, 0x016E,0x00DA,0x0170,0x00DC,0x00DD,0x0162,0x00DF,0x0155,0x00E1,0x00E2,0x0103,0x00E4,0x013A,0x0107,0x00E7,0x010D,0x00E9,0x0119,0x00EB,0x011B,0x00ED,0x00EE,0x010F,0x0111,0x0144,0x0148,0x00F3,0x00F4,0x0151,0x00F6,0x00F7, 0x0159,0x016F,0x00FA,0x0171,0x00FC,0x00FD,0x0163,0x02D9 }; uint32_t win1250[256]={ 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E, 0x001F,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003A,0x003B,0x003C,0x003D, 0x003E,0x003F,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005A,0x005B,0x005C, 0x005D,0x005E,0x005F,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007A,0x007B, 0x007C,0x007D,0x007E,0x007F,0x20AC,0x0000,0x201A,0x0000,0x201E,0x2026,0x2020,0x2021,0x0000,0x2030,0x0160,0x2039,0x015A,0x0164,0x017D,0x0179,0x0000,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,0x0000,0x2122,0x0161, 0x203A,0x015B,0x0165,0x017E,0x017A,0x00A0,0x02C7,0x02D8,0x0141,0x00A4,0x0104,0x00A6,0x00A7,0x00A8,0x00A9,0x015E,0x00AB,0x00AC,0x00AD,0x00AE,0x017B,0x00B0,0x00B1,0x02DB,0x0142,0x00B4,0x00B5,0x00B6,0x00B7,0x00B8,0x0105, 0x015F,0x00BB,0x013D,0x02DD,0x013E,0x017C,0x0154,0x00C1,0x00C2,0x0102,0x00C4,0x0139,0x0106,0x00C7,0x010C,0x00C9,0x0118,0x00CB,0x011A,0x00CD,0x00CE,0x010E,0x0110,0x0143,0x0147,0x00D3,0x00D4,0x0150,0x00D6,0x00D7,0x0158, 0x016E,0x00DA,0x0170,0x00DC,0x00DD,0x0162,0x00DF,0x0155,0x00E1,0x00E2,0x0103,0x00E4,0x013A,0x0107,0x00E7,0x010D,0x00E9,0x0119,0x00EB,0x011B,0x00ED,0x00EE,0x010F,0x0111,0x0144,0x0148,0x00F3,0x00F4,0x0151,0x00F6,0x00F7, 0x0159,0x016F,0x00FA,0x0171,0x00FC,0x00FD,0x0163,0x02D9 }; void close_button_handler(void) { is_end=TRUE; } END_OF_FUNCTION(close_button_handler) void main_koniec(const int e,const char *str) { set_gfx_mode(-1,0,0,0,0); if(str!=NULL){ allegro_message(str); } allegro_exit(); exit(e); } void main_koniec(const int e) { main_koniec(e,NULL); } void main_koniec(const char *str) { main_koniec(1,str); } void main_usage(const char *argv0) { char text[4096]; sprintf(text,"Usage: %s ENCODING TYPE SIZE INPUTFILE OUTPUTFILE [XDPI YDPI] [THRESHOLD]\n",argv0); strcat(text,"ENCODING:\n"); strcat(text,"\twin1250 - windows-1250\n"); strcat(text,"\tlatin2 - ISO 8859-2 (latin2)\n"); strcat(text,"TYPE:\n"); strcat(text,"\t65 - A (12x24) font\n"); strcat(text,"\t66 - B (9x17) font\n"); strcat(text,"\t67 - C (9x24) font\n"); strcat(text,"SIZE - number from 5 to 100\n"); strcat(text,"INPUTFILE - ttf font file\n"); strcat(text,"XDPI, YDPI - width and height DPI, default 60 100\n"); strcat(text,"THRESHOLD - threshold for distinguishing between black and white pixel (0-255), default 127\n"); main_koniec(1,text); } void main_draw(BITMAP *bmp,int sx,int sy,uint32_t ch,int pw,int ph,int bl,uint8_t *obuf=NULL) { FT_UInt glyph_index=0; glyph_index=FT_Get_Char_Index(face,ch); if(FT_Load_Glyph(face,glyph_index,FT_LOAD_DEFAULT)) return; if(FT_Render_Glyph(face->glyph,FT_RENDER_MODE_NORMAL)) return; int shift=(pw&7)?((pw|7)+1):pw; int p; int xx,yy; for(int y=0;y<face->glyph->bitmap.rows;y++){ for(int x=0;x<face->glyph->bitmap.width;x++){ if(face->glyph->bitmap.buffer[face->glyph->bitmap.width*y+x]>threshold){ xx=x+face->glyph->bitmap_left; yy=y+bl-face->glyph->bitmap_top; if(xx>=0&&yy>=0&&xx<pw&&y<ph){ if(obuf!=NULL){ p=xx+shift*yy; obuf[p>>3]|=1<<(7-(p&7)); } putpixel(bmp,sx+xx,sy+yy,0); } } } } } int main(int argc,char *argv[]) { int type,sz,xdpi=60,ydpi=100; int tw,th; char infile[MAX_PATH],outfile[MAX_PATH]; uint32_t *enc=NULL; try{ if(allegro_init()!=0) throw 1; set_window_title("Bixofont"); if(install_keyboard()!=0) throw 2; if(install_timer()!=0) throw 3; if(install_mouse()==0) throw 4; if(FT_Init_FreeType(&ftl)) throw 5; } catch(int e){ main_koniec(e,"INIT failed"); } if(argc<6) main_usage(argv[0]); if(sscanf(argv[2],"%d",&type)!=1) main_usage(argv[0]); if(type<65||type>67) main_usage(argv[0]); if(type==65){ tw=12; th=24; } if(type==66){ tw=9; th=17; } if(type==67){ tw=9; th=24; } if(sscanf(argv[3],"%d",&sz)!=1) main_usage(argv[0]); if(sz<5||sz>100) main_usage(argv[0]); if(strlen(argv[4])>=MAX_PATH||strlen(argv[5])>=MAX_PATH) main_usage(argv[0]); strcpy(infile,argv[4]); strcpy(outfile,argv[5]); if(!strcasecmp(argv[1],"win1250")) enc=&win1250[0]; if(!strcasecmp(argv[1],"latin2")) enc=&iso88592[0]; if(enc==NULL) main_usage(argv[0]); if(argc>=8){ if(sscanf(argv[6],"%d",&xdpi)!=1||sscanf(argv[7],"%d",&ydpi)!=1) main_usage(argv[0]); if(xdpi<10||xdpi>1200) main_usage(argv[0]); if(ydpi!=0&&(ydpi<10||ydpi>1200)) main_usage(argv[0]); } if(argc>=9){ if(sscanf(argv[8],"%d",&threshold)!=1) main_usage(argv[0]); if(threshold<0||threshold>255) main_usage(argv[0]); } if(!exists(infile)) main_koniec(1,"Input file missing!"); if(FT_New_Face(ftl,infile,0,&face)) main_koniec(1,"Can't read font!"); if(FT_Set_Char_Size(face,sz*64,0,xdpi,ydpi)) main_koniec(1,"Wrong size!"); LOCK_FUNCTION(close_button_handler); set_close_button_callback(close_button_handler); set_color_depth(24); if(set_gfx_mode(GFX_AUTODETECT_WINDOWED,480,480,0,0)!=0) main_koniec(1,"Can't set gfx mode!"); textout_centre_ex(screen,font,"Rendering, please wait...",screen->w/2,screen->h/2-4,makecol(255,255,255),0); show_mouse(screen); BITMAP *bmp=create_bitmap(screen->w,screen->h); if(bmp==NULL) main_koniec(1,"Alloc error"); clear_to_color(bmp,makecol(155,155,155)); size_t l,el; uint8_t obuf[16000]; memset(obuf,0,sizeof(obuf)); el=(((tw&7)?((tw|7)+1):tw)*th)>>3; l=0; for(int y=0;y<16;y++){ for(int x=0;x<16;x++){ set_clip_rect(bmp,x*30,y*30,x*30+tw,y*30+th); rectfill(bmp,x*30,y*30,x*30+tw,y*30+th,makecol(255,255,255)); main_draw(bmp,x*30,y*30,enc[x+y*16],tw,th,th-th/4,obuf+l); l+=el; } } FILE *s=fopen(outfile,"wb"); if(s==0) main_koniec(1,"Can't write to output file!"); fputc(0x08,s); fputc(0x46,s); fputc(0x57,s); fputc(0x0,s); fputc(type,s); fwrite(obuf,1,l/2,s); fputc(0x08,s); fputc(0x46,s); fputc(0x57,s); fputc(0x1,s); fputc(type,s); fwrite(obuf+(l/2),1,l/2,s); fclose(s); show_mouse(NULL); blit(bmp,screen,0,0,0,0,bmp->w,bmp->h); show_mouse(screen); while(!is_end){ if(key[KEY_ESC]) is_end=TRUE; if(key[KEY_SPACE]) is_end=TRUE; rest(0); } show_mouse(NULL); main_koniec(0); return 0; } END_OF_MAIN()