Files
commandergenius/project/jni/fonteditor/editor.cpp

345 lines
8.5 KiB
C++

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <SDL.h>
#include <vector>
#include <algorithm>
#include <string>
const char * fname = "touchscreenfont.h";
struct font_line_t { Uint8 x1, y1, x2, y2; };
std::vector< std::vector<font_line_t> > font;
enum { DRAWAREA = 512, BORDERAREA = 10 };
int currentChar = 0;
int drawX, drawY, drawStarted = 0;
void load()
{
FILE * ff = fopen(fname, "r");
if(!ff)
return;
std::string s;
char buf[32];
int readed = 0;
while( ( readed = fread(buf, 1, sizeof(buf), ff) ) > 0 )
{
s.append(buf, readed);
}
fclose(ff);
font.clear();
std::string::size_type f;
f = s.find("FONT_MAX_LINES_PER_CHAR =");
f = s.find("=", f) + 1;
int maxLines = atoi(s.c_str() + f);
f = s.find("font_line_t font[", f);
f = s.find("[", f) + 1;
int numChars = atoi(s.c_str() + f);
for(int i = 0; i < numChars; i++)
{
font.push_back( std::vector<font_line_t>() );
for( int ii = 0; ii < maxLines; ii++ )
{
font_line_t line;
f = s.find("\t\t{ ", f) + 4;
line.x1 = atoi(s.c_str() + f);
f = s.find(",", f) + 1;
line.y1 = atoi(s.c_str() + f);
f = s.find(",", f) + 1;
line.x2 = atoi(s.c_str() + f);
f = s.find(",", f) + 1;
line.y2 = atoi(s.c_str() + f);
if( line.x1 > 0 && line.y1 > 0 && line.x2 > 0 && line.y2 > 0 )
font.back().push_back(line);
};
};
if(font.size() == 0)
font.resize(1);
}
void save()
{
FILE * ff = fopen(fname, "w");
fprintf(ff, "/* This file should be edited using Touchscreen Editor utility */\n");
fprintf(ff, "#ifndef _TOUCHSCREENFONT_H_\n#define _TOUCHSCREENFONT_H_\n");
fprintf(ff, "#include <SDL_types.h>\n");
fprintf(ff, "typedef struct font_line_t { Uint8 x1, y1, x2, y2; } font_line_t;\n");
int maxLines = 0;
for( size_t i = 0; i < font.size(); i++ )
if( maxLines < font[i].size() )
maxLines = font[i].size();
fprintf(ff, "enum { FONT_MAX_LINES_PER_CHAR = %i };\n", maxLines);
fprintf(ff, "static font_line_t font[%d][FONT_MAX_LINES_PER_CHAR] = {\n", (int)font.size());
for( size_t i = 0; i < font.size(); i++ )
{
fprintf(ff, "\t{\n");
for( size_t ii = 0; ii < maxLines; ii++ )
{
fprintf(ff, "\t\t{ ");
if( ii < font[i].size() )
fprintf(ff, "%3d, %3d, %3d, %3d",
(int)font[i][ii].x1,
(int)font[i][ii].y1,
(int)font[i][ii].x2,
(int)font[i][ii].y2 );
else
fprintf(ff, " 0, 0, 0, 0");
fprintf(ff, " }%s\n", ii + 1 < maxLines ? "," : "" );
}
fprintf(ff, "\t}%s\n", i + 1 < font.size() ? "," : "" );
}
fprintf(ff, "};\n");
fprintf(ff, "#endif\n");
fclose(ff);
}
void DrawLine(SDL_Surface * bmp, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
int dx = x2-x1;
int dy = y2-y1;
int i1, i2;
int x, y;
int dd;
Uint16 d = color;
#define proc( bmp, x, y, d ) * (Uint16 *)( ((Uint8 *)bmp->pixels) + bmp->pitch * (y) + (x) * 2 ) = d
/* worker macro */
#define DO_LINE(pri_sign, pri_c, pri_cond, sec_sign, sec_c, sec_cond) \
{ \
if (d##pri_c == 0) { \
proc(bmp, x1, y1, d); \
return; \
} \
\
i1 = 2 * d##sec_c; \
dd = i1 - (sec_sign (pri_sign d##pri_c)); \
i2 = dd - (sec_sign (pri_sign d##pri_c)); \
\
x = x1; \
y = y1; \
\
while (pri_c pri_cond pri_c##2) { \
proc(bmp, x, y, d); \
\
if (dd sec_cond 0) { \
sec_c sec_sign##= 1; \
dd += i2; \
} \
else \
dd += i1; \
\
pri_c pri_sign##= 1; \
} \
}
if (dx >= 0) {
if (dy >= 0) {
if (dx >= dy) {
/* (x1 <= x2) && (y1 <= y2) && (dx >= dy) */
DO_LINE(+, x, <=, +, y, >=);
}
else {
/* (x1 <= x2) && (y1 <= y2) && (dx < dy) */
DO_LINE(+, y, <=, +, x, >=);
}
}
else {
if (dx >= -dy) {
/* (x1 <= x2) && (y1 > y2) && (dx >= dy) */
DO_LINE(+, x, <=, -, y, <=);
}
else {
/* (x1 <= x2) && (y1 > y2) && (dx < dy) */
DO_LINE(-, y, >=, +, x, >=);
}
}
}
else {
if (dy >= 0) {
if (-dx >= dy) {
/* (x1 > x2) && (y1 <= y2) && (dx >= dy) */
DO_LINE(-, x, >=, +, y, >=);
}
else {
/* (x1 > x2) && (y1 <= y2) && (dx < dy) */
DO_LINE(+, y, <=, -, x, <=);
}
}
else {
if (-dx >= -dy) {
/* (x1 > x2) && (y1 > y2) && (dx >= dy) */
DO_LINE(-, x, >=, -, y, <=);
}
else {
/* (x1 > x2) && (y1 > y2) && (dx < dy) */
DO_LINE(-, y, >=, -, x, <=);
}
}
}
#undef DO_LINE
};
void draw()
{
SDL_FillRect(SDL_GetVideoSurface(), NULL, 0);
SDL_LockSurface(SDL_GetVideoSurface());
if( font.size() > currentChar )
{
for( int i = 0; i < font[currentChar].size(); i++ )
{
DrawLine( SDL_GetVideoSurface(), font[currentChar][i].x1 * 2, font[currentChar][i].y1 * 2,
font[currentChar][i].x2 * 2, font[currentChar][i].y2 * 2, 0xffff );
}
}
if( drawStarted )
{
int x, y;
SDL_GetMouseState(&x, &y);
if( x/2 < DRAWAREA && y/2 < DRAWAREA )
DrawLine( SDL_GetVideoSurface(), (x/2)*2, (y/2)*2, drawX*2, drawY*2, 0x9999 );
}
DrawLine( SDL_GetVideoSurface(), DRAWAREA, 0, DRAWAREA, DRAWAREA, 0x4444 );
for( int i = 0; i < font.size(); i++ )
{
DrawLine( SDL_GetVideoSurface(), DRAWAREA, i * 4,
DRAWAREA + ( font[i].size() < BORDERAREA - 1 ? font[i].size() : BORDERAREA - 1 ), i * 4, 0x7777 );
}
DrawLine( SDL_GetVideoSurface(), DRAWAREA, currentChar * 4, DRAWAREA + BORDERAREA - 1, currentChar * 4, 0xAAAA );
DrawLine( SDL_GetVideoSurface(), DRAWAREA, currentChar * 4 + 1, DRAWAREA + BORDERAREA - 1, currentChar * 4 + 1, 0xAAAA );
DrawLine( SDL_GetVideoSurface(), DRAWAREA, font.size() * 4, DRAWAREA + BORDERAREA - 1, font.size() * 4, 0x5555 );
SDL_UnlockSurface(SDL_GetVideoSurface());
SDL_Flip(SDL_GetVideoSurface());
}
int
main(int argc, char *argv[])
{
int width = DRAWAREA + BORDERAREA;
int height = DRAWAREA;
SDL_Surface *screen;
int done;
Uint8 *keys;
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(width, height, 16, SDL_DOUBLEBUF);
if ( ! screen ) {
fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
SDL_Quit();
exit(2);
}
SDL_WM_SetCaption("Touchscreen keyboard font editor", "Touchscreen keyboard font editor");
if(font.size() == 0)
font.resize(1);
load();
done = 0;
while ( ! done ) {
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
switch(event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_MOUSEBUTTONDOWN:
if( event.button.x < DRAWAREA )
{
if (event.button.button == SDL_BUTTON_LEFT)
{
if( !drawStarted )
{
drawStarted = 1;
drawX = event.button.x/2;
drawY = event.button.y/2;
}
else
{
drawStarted = 0;
font_line_t line;
line.x1 = drawX;
line.y1 = drawY;
line.x2 = event.button.x/2;
line.y2 = event.button.y/2;
font[currentChar].push_back(line);
}
}
else
{
if(font[currentChar].size() > 0)
font[currentChar].pop_back();
}
}
else
{
if (event.button.button == SDL_BUTTON_LEFT)
{
currentChar = event.button.y / 4;
if(font.size() <= currentChar)
font.resize(currentChar + 1);
}
else
{
currentChar = event.button.y / 4;
font.resize(currentChar + 1);
}
}
break;
}
}
#if SDL_VERSION_ATLEAST(1,3,0)
keys = SDL_GetKeyboardState(NULL);
if ( keys[SDL_SCANCODE_ESCAPE] ) {
done = 1;
}
#else
keys = SDL_GetKeyState(NULL);
if ( keys[SDLK_ESCAPE] ) {
done = 1;
}
#endif
draw();
};
save();
SDL_Quit();
return 0;
}
#ifdef WIN32
#include <windows.h>
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
return main(0, NULL);
};
#endif