#include #include "ImageToNFont.h" int OpenBox(char *result) { result[0] = 0; Fl_Native_File_Chooser fc; fc.title("Choix d'une image"); fc.filter("*.{bmp,png,jpg,jpeg,xmp,gif}"); fc.show(); strcpy(result, fc.filename()); return result[0]? 1:0; } // CLASSE : MainWindow // /*----------------------------------------------------------------------------------------- MainWindow::MainWindow(int w, int h) : Fl_Double_Window(w, h, "Image to nFont") { // création des widgets begin(); bodyPanel = new Fl_Scroll(10, 10, w-20, 300); imagePanel = new Fl_Box(FL_NO_BOX, 10, 10, w-40, 280, "No Image"); bodyPanel->end(); bSelectFile = new Fl_Button(10, 320, 160, 40, "Select file"); bConvert = new Fl_Button(w/2-80, 320, 160, 40, "Convert"); bExit = new Fl_Button(w-170, 320, 160, 40, "Exit"); input_width = new Fl_Int_Input(182, 370, w/2-212, 20, "Largeur d'un caractère : "); input_height = new Fl_Int_Input(w/2+200, 370, w/2-212, 20, "Hauteur d'un caractère : "); outputText = new Fl_Text_Display(10, 400, w-20, h-410); end(); // on édite les propriétés bConvert->deactivate(); Fl_Text_Buffer *buf = new Fl_Text_Buffer(); buf->append("Select a file before conversion.\nThe picture must have a border of 1 pixel.\nThe margin between each character should be (both horizontally and vertically) of 2 pixels.\nIf the automatic detection of characters's width and height is false, enter the real values.\nAn nSDL font has got 256 characters. Your image must have 16 characters per row, and so\n16 per column.\n"); outputText->buffer(buf); // ajout des fonctions callbacks bSelectFile->callback(MainWindow::CB_selectFile, this); bExit->callback(MainWindow::CB_exit); bConvert->callback(MainWindow::CB_convert, this); } MainWindow::~MainWindow() {} void MainWindow::CB_selectFile(Fl_Widget *bSelectFile, void *mainWindow) { static char filePath[512]; int ok = OpenBox(filePath); if (!ok || !filePath[0]) return; int resize = 0; int char_size = 8; char str[8]; // on obtient les autres widgets MainWindow *window = (MainWindow *) mainWindow; Fl_Group *bodyPanel = (Fl_Group *) window->child(0); Fl_Widget *imagePanel = bodyPanel->child(0); Fl_Widget *bConvert = window->child(2); Fl_Int_Input *input_width = (Fl_Int_Input *) window->child(4); Fl_Int_Input *input_height = (Fl_Int_Input *) window->child(5); // on ouvre l'image Fl_Shared_Image *img = Fl_Shared_Image::get(filePath); if (!img) { imagePanel->label("Echec de l'ouverture"); imagePanel->image(NULL); bConvert->deactivate(); return; // échec de l'ouverture } // on trouve la hauteur et la largeur d'un caractère char_size = img->w()/16 - 2; sprintf(str, "%i", char_size); input_width->value(str); char_size = img->h()/16 - 2; sprintf(str, "%i", char_size); input_height->value(str); // on actualise le panel imagePanel->label(""); imagePanel->image(img); window->repositionWidgets(); } void MainWindow::CB_convert(Fl_Widget *bConvert, void *mainWindow) { Fl_Group *window = (Fl_Group *) mainWindow; Fl_Group *bodyPanel = (Fl_Group *) window->child(0); Fl_Image *img = bodyPanel->child(0)->image(); Fl_Int_Input *input_width = (Fl_Int_Input *) window->child(4); Fl_Int_Input *input_height = (Fl_Int_Input *) window->child(5); Fl_Text_Display *outputText = (Fl_Text_Display *) window->child(6); // On otient les variables nécéssaires Fl_Text_Buffer *buf = new Fl_Text_Buffer(); int n, nc=0, px=0, py=0, p=0, x, y; unsigned char c=0; int w = img->w(), h = img->h(); int depth = img->d(), d = depth - (depth+1)%2; const char *data = img->data()[0]; int isPixelActive; char str[64] = "00"; // char debug[512]; int char_width = 0, char_height = 0, char_per_line = 0, bytes_per_char; int newLine = 0; // on lit la taille et la hauteur n = 0; while ((c=input_width->value()[n++])) char_width = 10*char_width + c - '0'; n = 0; while ((c=input_height->value()[n++])) char_height = 10*char_height + c - '0'; char_per_line = 16; bytes_per_char = ((char_width-1)/8 + 1) * char_height; /* For DEBUG only sprintf(debug, "width = %i, height = %i, depth = %i, ld = %i\nchar_width = %i, char_height = %i\nchar_per_line = %i, bytes_per_char = %i\n", w,h,depth,img->ld(), char_width, char_height, char_per_line, bytes_per_char); buf->append(debug); buf->append("(1,1) : "); // */ buf->append("static unsigned char fontChars[] = {\n"); sprintf(str, "%i, %i, // width and height of characters\n", char_width, char_height); buf->append(str); str[2] = 0; // on commence la conversion !!! for (c=0, nc=0; nc < 256; nc++) { px = 1 + (nc%char_per_line) * (char_width+2); py = 1 + (nc/char_per_line) * (char_height+2); for (y=0; y < char_height; y++) { for (x=0; x < char_width; x++) { // on ajoute le caractère puis le réinitialise if ((!(x%8) && (py-1 || px-1 || x || y)) || (nc == 255 && y == char_height-1 && x == char_width-1)) { // on trouve str if ((c/16) > 9) str[0] = c/16 + 'A' - 10; else str[0] = c/16 + '0'; if (c%16 > 9) str[1] = c%16 + 'A' - 10; else str[1] = c%16 + '0'; buf->append("0x"); buf->append(str); if (nc < 255 || y < char_height-1 || x < char_width-1) buf->append(", "); if (newLine) { newLine = 0; if (nc < 11) sprintf(str, " // Char 00%i (%c)\n", nc-1, nc<34 || nc>127? '.' : nc-1); else if (nc < 101) sprintf(str, " // Char 0%i (%c)\n", nc-1, nc<34 || nc>127? '.' : nc-1); else sprintf(str, " // Char %i (%c)\n", nc-1, nc<34 || nc>127? '.' : nc-1); buf->append(str); str[2] = 0; /* For DEBUG only sprintf(str, "(%i,%i) : ", px, py); buf->append(str); str[2] = 0; // */ } c = 0; } // on trouve la position du pixel p = (px+x + (py+y)*w) * depth; // on obtient si le pixel est allumé ou non if (!(depth%2) && data[p+depth-1] == 0) { // si le pixel est transparent isPixelActive = 0; } else { isPixelActive = 0; for (n=0; n < d; n++) { if (data[p+n] != -1) { // si une des couleurs n'est 255 (255 == -1), alors la couleur totale n'est pas blanche isPixelActive = 1; break; } } } // on édite le caractère if (isPixelActive) c |= (1 << 7-x%8); } } newLine = 1; } buf->append(" // Char 255 (.)\n};"); outputText->buffer(buf); } void MainWindow::CB_exit(Fl_Widget *) { exit(0); } void MainWindow::repositionWidgets() { if (!imagePanel->image()) return; int pic_w, pic_h; pic_w = imagePanel->image()->w(), pic_h = imagePanel->image()->h(); imagePanel->size(max(bodyPanel->w()-20, pic_w), max(bodyPanel->h()-20, pic_h)); imagePanel->label(""); bConvert->activate(); bodyPanel->redraw(); imagePanel->redraw(); } //*/ // Fonction MAIN int main(int argc, char **argv) { fl_register_images(); // on initialise la lib d'images MainWindow mw(640, 640); mw.show(); return Fl::run(); }