Skip to content

Instantly share code, notes, and snippets.

@yaitskov
Created December 11, 2012 20:55
Show Gist options
  • Save yaitskov/4262047 to your computer and use it in GitHub Desktop.
Save yaitskov/4262047 to your computer and use it in GitHub Desktop.
program for creation bitmap console font in linux terminal
#include <curses.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
//#include <malloc.h>
#define EBADFORMAT 0x0f000000
#define REG_EDIT 0
#define REG_CMD 1
char num[12];
void f(int x, char * s, int *pos){
if(x == 0)
{
s[*pos]='0' ;
s[*pos+1]='\0' ;
}else{
f(x/10, s, pos);
s[(*pos)++] = '0' + x % 10;
}
}
const char * itoa(int x){
int pos=0;
f(x,num,&pos);
return num;
}
const char * errnotostr(void){
switch(errno){
case EINVAL: return "EINVAL";
case EBADFORMAT: return "EBADFORMAT" ;
}
return itoa(errno);
}
void print_help();
void exchange(char*a, char*b);
//ÚÁÇÒÕÖÁÅÔ ÛÒÉÆÔ × ÄÉÎÁÍÉÞÅÓËÕÀ ÐÁÍÑÔØ É ÐÒÏ×ÅÒÑÅÔ ÆÏÒÍÁÔ ÆÁÊÌÁ
char * load_con_font(int filed, int * arr_size, int * letter_size);
char reverse( char v);
//ÐÅÞÁÔÁÅÔ ÂÕË×Õ ÛÒÉÆÔÁ
void print_letter(const char * font, int letter, int letter_size);
//
void clear_buf(int letter_size);
void make_cmd(const char * cmd, char * font, int * letter_num, int letter_size, int y, int x);
void delete_char(char * cmd, int * buf_pos);
main(int argc, char ** argv){
int letter_size, arr_size, filed, buf_pos,y,x,letter_num=0,b,regime,counter;
const int cmd_size=80;
char * font, cmd[cmd_size],*letter_buf;
if(argc != 2) {
errno=EINVAL;
printf("ERROR: %s; ",errnotostr());
printf("Usage: %s file_font\nFor help %s --help\n",
argv[0],argv[0]);
exit(errno);
}
if(strcmp("--help",argv[1]) == 0) print_help();
filed = open(argv[1],O_RDWR);
if(filed == -1){ printf("ERROR: %s; ",errnotostr());
printf("Usage: %s file_font\nFor help %s --help\n",argv[0],argv[0]);
exit(errno);}
font = load_con_font(filed, &arr_size, &letter_size);
if(!font) { printf("ERROR: %s; ",errnotostr());
printf("Usage: %s file_font\nFor help %s --help\n",argv[0],argv[0]);
exit(errno);
}
letter_buf = (char*) malloc(letter_size);
initscr();
noecho();
print_letter(font, letter_num, letter_size);
clear_buf(letter_size);
y=x=0;
buf_pos=0;
cmd[0]=0;
regime = REG_CMD;
do{
b = getch();
if(b == 27){
switch(regime){
case REG_EDIT: regime=REG_CMD;
clear_buf(letter_size);
break;
case REG_CMD: regime=REG_EDIT;
cmd[0] = 0;
buf_pos= 0;
move(y,x);
}
}else if(regime == REG_CMD){
switch(b){
case 10: make_cmd(cmd,font, &letter_num, letter_size , y,x);
cmd[0]= 0;
buf_pos = 0;
clear_buf(letter_size);
break;
case 127: delete_char(cmd,&buf_pos);
clear_buf(letter_size);
printw(cmd);
break;
default:
if(buf_pos < cmd_size - 1){
cmd[buf_pos++] = b;
cmd[buf_pos ] =0;
move(letter_size,0);
printw(cmd);
}
}
}else{
switch(b){
case 'j':
case 'J':
if(y < letter_size - 1) move(++y,x);
break;
case 'k':
case 'K':
if(y > 0) move(--y,x);
break;
case 'h':
case 'H':
if(x > 0) move(y,--x);
break;
case 'l':
case 'L':
if(x < 7) move(y, ++x);
break;
case 'c':
case 'C':
{int i;
for(i=0;i<letter_size;i++)
font[letter_num*letter_size+i]=0;
}
print_letter(font,letter_num,letter_size);
move(y,x);
break;
case 'q':
case 'Q':
endwin();
close(filed);
exit(0);
case 'm':
case 'M':
memcpy(letter_buf,font+letter_num
*letter_size,
letter_size);
break;
case 'r':
case 'R':
memcpy(font+letter_num*letter_size,
letter_buf,
letter_size);
print_letter(font,letter_num,letter_size);
break;
case 's':
case 'S':
lseek(filed,0,SEEK_SET);
write(filed, font, arr_size);
break;
case 'n':
case 'N':
if(letter_num<255){
print_letter(font,++letter_num,
letter_size);
move(y,x);
}
break;
case 'p':
case 'P':
if(letter_num>0){
print_letter(font,--letter_num,
letter_size);
move(y,x);
}
break;
case ' ':
if(font[letter_num*letter_size+y]&(1<<(7-x)))
font[letter_num*letter_size+y]&=
~(1<<(7-x));
else
font[letter_num*letter_size+y]|=
(1<<(7-x));
print_letter(font,
letter_num,
letter_size);
move(y,x);
}
}
}while(1);
}
char * load_con_font(int filed, int * arr_size, int * letter_size){
char * font ;
*arr_size = lseek(filed,0,SEEK_END);
switch(*arr_size){
case 4096: *letter_size = 16; break; //16x8
case 2048: *letter_size = 8; break; //8x8
default: errno=EBADFORMAT; return 0;
}
font = (char*) malloc(*arr_size);
if(!font) return 0;
lseek(filed,0,SEEK_SET);
read(filed,font,*arr_size);
return font;
}
void print_letter(const char * font, int letter, int letter_size){
int i = 0, j;
font += letter*letter_size;
for(; i < letter_size; i++){
move(i,0);
for( j = 0 ; j < 8 ; j ++)
if(font[i] & (1 << (7-j)))
addch('0');
else
addch(' ');
}
}
void clear_buf(int letter_size){
move(letter_size,0);
deleteln();
}
void print_help(void){
printf("\n");
exit(0);
}
void make_cmd(const char * cmd, char * font ,int * letter_num,int letter_size,int y,int x){
char scounter[12];
int counter=0,i=0;
while(cmd[i] == ' ' || cmd [i] == ' ') i++;
while(cmd[i] >= '0' && cmd[i] <= '9' && counter <11)
scounter[counter++]=cmd[i++];
scounter[counter] = 0;
while(cmd[i] == ' ' || cmd [i] == ' ') i++;
switch(cmd[i]){
case 'g':
case 'G':
counter = atoi(scounter);
if(counter < 256) {
*letter_num = counter;
print_letter(font,*letter_num,letter_size);
move(y,x);
}
break;
case 'v':
case 'V':
{
int i=0,j= *letter_num*letter_size;
char c;
for(; i < letter_size/2; i++)
{
c = font[j+i];
font[j+i] = font[j+letter_size-i-1];
font[j+letter_size-i-1] = c;
}
}
print_letter(font,*letter_num,letter_size);
move(y,x);
break;
case 'h':
case 'H':
{
int i=0,j= *letter_num*letter_size;
for(i = 0; i < letter_size; i++)
font[j+i] = reverse(font[j+i]);
}
print_letter(font,*letter_num,letter_size);
move(y,x);
break;
}
}
void delete_char(char * cmd, int * buf_pos){
if(*buf_pos > 0) cmd [ --(*buf_pos) ] = 0;
}
#define GETBIT(n,p) ((n&(1<<p)) >> p)
char reverse( char v){
int i; char c = 0;
for(i = 0 ; i < 8; i++)
c |= GETBIT(v,i) << (7-i);
return c;
}
void exchange(char *a, char* b){
char tmp = *a;
*a = *b;
*b = tmp;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment