/******************************************************************************
*   Date:       2014-01-18                                                    *
*   Copyright (c) 2014 Goran Devic                                            *
*                                                                             *
*   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 2 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, write to the Free Software               *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   *
*                                                                             *
*******************************************************************************

Program Description:

This tool reads in a bitmap containing a font generated by "Bitmap Font Builder"
http://www.lmnopc.com/bitmapfontbuilder/ and creates a flat font data file
suitable to load into a ROM

*******************************************************************************
*   Include Files                                                             *
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char BYTE;

long getFileSize(FILE *file)
{
	long lCurPos, lEndPos;
	lCurPos = ftell(file);
	fseek(file, 0, 2);
	lEndPos = ftell(file);
	fseek(file, lCurPos, 0);
	return lEndPos;
}

/******************************************************************************
*   Usage: font_correct font_bitmap.raw > out.txt
*
*   - Minimal error checking
*   - You probably want to recompile to process different bitmap sizes
******************************************************************************/
int main(int argc, const char *argv[])
{
	if (argc == 1)
	{
		printf("Usage: font_correct font_bitmap.raw > out.txt\n");
		exit(-1);
	}
	const char *filePath = argv[1];
	BYTE *fileBuf;
	FILE *file;

	if ((file = fopen(filePath, "rb")) == NULL)
	{
		printf("Could not open specified file: %s\n", filePath);
		exit(-1);
	}
	long fileSize = getFileSize(file);

	printf("//Source file: %s\n", filePath);
	printf("//Size: %d bytes\n\n", fileSize);

	// Read a file into the internal BYTE buffer
	fileBuf = new BYTE[fileSize];

	fread(fileBuf, fileSize, 1, file);
	fclose(file);

	// Generate output file name by modifying the input name
	char outPath[256];
	strcpy(outPath, filePath);
	strcat(outPath, ".dat");
	FILE *fout = NULL;
	if ((fout = fopen(outPath, "wb")) == NULL)
	{
		printf("//Could not open output file: %s\n", filePath);
		exit(-1);
	}
	printf("//Output file: %s\n", outPath);

	// Define source character bitmap and the destination format
	const int max_ascii = 128;          // Last ASCII code to process
	const int size_y = 16;              // Number of lines (Y) of each character
	const int size_x = 16;              // Number of pixels (X) of each line: 8 or 16
	const int src_num_chars_x = 16;     // Number of characters in one line in the source
	const int src_stride = 256;         // Source stride in bytes from one line to the next

	bool dump = true;

	// Algorithm specific to 512x512 bitmap font square
	for (int ascii = 0; ascii < max_ascii; ascii++)
	{
		// Calculate coordinate of each ascii character into the bitmap
		int xc = ascii % src_num_chars_x;
		int yc = ascii / src_num_chars_x;

		//dump && printf("---- ASCII 0x%02X '%c'----\n", ascii, ascii >= ' ' ? ascii : ' ');
		dump && printf("//ASCII 0x%02X '%c'\n", ascii, ascii >= ' ' ? ascii : ' ');

		// For each horizontal line of that character...
		for (int y = 0; y < size_y; y++)
		{
			long outData = 0;           // Contains final character line data

										// For each pixel within that line...
			for (int a = 0; a < 2; a++) {
				dump && printf("font_rom[%d] <= 8'b", ascii*32+y*2+a);
				for (int x = a*8; x < (size_x*(a+1))/2; x++)
				{
					BYTE bit = fileBuf[yc*size_y*src_stride + y*src_stride +
						xc*size_x + x];
					if (bit) outData |= 1;
					outData <<= 1;

					dump && printf("%c", bit ? '1' : '0');
				}
				dump && printf(";\n");
			}
			// Write out a line of character data
			fwrite((const void*)&outData, 1, (size_t)size_x / 8, fout);

			//dump && printf(";\n");
		}
	}
	fclose(fout);

	return 0;
}