mirror of
https://github.com/tpunix/HMCLOCK.git
synced 2025-12-06 08:12:48 +08:00
增加字体工具
This commit is contained in:
BIN
fontool/DSEG7CR.ttf
Normal file
BIN
fontool/DSEG7CR.ttf
Normal file
Binary file not shown.
17
fontool/Makefile
Normal file
17
fontool/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
FONT_H = sfont.h sfont16.h font50.h font66.h
|
||||
|
||||
all: bdfont eptest
|
||||
|
||||
bdfont:
|
||||
gcc -Wall -g -I/mingw64/include/freetype2 -o bdfont bdfont.c -lfreetype -lz
|
||||
|
||||
eptest: epd_gui.c $(FONT_H)
|
||||
gcc -Wall -g -o eptest epd_gui.c gdifb.c -lgdi32
|
||||
|
||||
$(FONT_H): bdfont mkfont.sh
|
||||
./mkfont.sh
|
||||
|
||||
clean:
|
||||
rm -f bdfont.exe eptest.exe $(FONT_H)
|
||||
|
||||
570
fontool/bdfont.c
Normal file
570
fontool/bdfont.c
Normal file
@@ -0,0 +1,570 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef signed int s32;
|
||||
typedef signed short s16;
|
||||
typedef signed char s8;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int unicode;
|
||||
|
||||
/* Glyph bitmap infomation */
|
||||
int bw, bh;
|
||||
int bx, by;
|
||||
int advance;
|
||||
u8 *bitmap;
|
||||
int bsize;
|
||||
} GLYPH;
|
||||
|
||||
|
||||
int clist[65536];
|
||||
GLYPH *ctab[65536];
|
||||
int total_chars;
|
||||
|
||||
int pixel_size;
|
||||
int font_ascent;
|
||||
int base_adj = 0;
|
||||
int font_size = 14;
|
||||
|
||||
u8 font_buf[0x1000000];
|
||||
int font_buf_size;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
int ucs2utf8(u16 ucs, char *p)
|
||||
{
|
||||
if(ucs<=0x7f){
|
||||
p[0] = ucs;
|
||||
return 1;
|
||||
}else if(ucs<=0x7ff){
|
||||
p[0] = 0xc0 | ((ucs>>6)&0x1f);
|
||||
p[1] = 0x80 | ((ucs>>0)&0x3f);
|
||||
return 2;
|
||||
}else if(ucs<=0xffff){
|
||||
p[0] = 0xe0 | ((ucs>>12)&0x0f);
|
||||
p[1] = 0x80 | ((ucs>>6)&0x3f);
|
||||
p[2] = 0x80 | ((ucs>>0)&0x3f);
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#if 0
|
||||
GLYPH *bdf_load_char(FILE *fp)
|
||||
{
|
||||
int bmp, lsize, x;
|
||||
char lbuf[128];
|
||||
GLYPH *pg;
|
||||
|
||||
pg = NULL;
|
||||
bmp = -1;
|
||||
while(1){
|
||||
if(fgets(lbuf, 128, fp)==NULL)
|
||||
break;
|
||||
|
||||
if(strncmp(lbuf, "STARTCHAR", 9)==0){
|
||||
pg = (GLYPH*)malloc(sizeof(GLYPH));
|
||||
memset(pg, 0, sizeof(GLYPH));
|
||||
}else if(strncmp(lbuf, "ENCODING", 8)==0){
|
||||
pg->unicode = atoi(lbuf+9);
|
||||
}else if(strncmp(lbuf, "DWIDTH", 6)==0){
|
||||
pg->advance = atoi(lbuf+7);
|
||||
}else if(strncmp(lbuf, "BBX", 3)==0){
|
||||
sscanf(lbuf+4, "%d %d %d %d", &pg->bw, &pg->bh, &pg->bx, &pg->by);
|
||||
#if 1
|
||||
int ny = (font_ascent+base_adj-1) - (pg->bh - 1 + pg->by);
|
||||
if(ny<0)
|
||||
ny = 0;
|
||||
pg->by = ny;
|
||||
#endif
|
||||
if(pg->bx<0){
|
||||
pg->advance -= pg->bx;
|
||||
pg->bx = 0;
|
||||
}
|
||||
lsize = (pg->bw+7)/8;
|
||||
pg->bsize = lsize*pg->bh;
|
||||
pg->bitmap = malloc(pg->bsize);
|
||||
}else if(strncmp(lbuf, "BITMAP", 6)==0){
|
||||
bmp = 0;
|
||||
}else if(strncmp(lbuf, "ENDCHAR", 7)==0){
|
||||
break;
|
||||
}else if(bmp>=0){
|
||||
int len = strlen(lbuf);
|
||||
if(lbuf[len-1]=='\n' || lbuf[len-1]=='\r') len -= 1;
|
||||
if(lbuf[len-1]=='\n' || lbuf[len-1]=='\r') len -= 1;
|
||||
x = 0;
|
||||
for(int i=0; i<len; i+=2){
|
||||
char tmp[4];
|
||||
tmp[0] = lbuf[i+0];
|
||||
tmp[1] = lbuf[i+1];
|
||||
tmp[2] = 0;
|
||||
if(x<lsize){
|
||||
pg->bitmap[bmp] = strtoul(tmp, NULL, 16);
|
||||
bmp += 1;
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return pg;
|
||||
}
|
||||
|
||||
|
||||
int load_bdf(char *bdf_name)
|
||||
{
|
||||
FILE *fp;
|
||||
GLYPH *pg;
|
||||
char lbuf[128];
|
||||
|
||||
total_chars = 0;
|
||||
memset(ctab, 0, sizeof(ctab));
|
||||
|
||||
fp = fopen(bdf_name, "r");
|
||||
if(fp==NULL)
|
||||
return -1;
|
||||
|
||||
fgets(lbuf, 128, fp);
|
||||
if(strncmp(lbuf, "STARTFONT", 9)){
|
||||
printf("STARTFONT not found!\n");
|
||||
return -1;
|
||||
}
|
||||
printf("\nLoad BDF: %s\n", bdf_name);
|
||||
|
||||
pixel_size = 0;
|
||||
font_ascent = 0;
|
||||
while(1){
|
||||
if(fgets(lbuf, 128, fp)==NULL)
|
||||
break;
|
||||
if(strncmp(lbuf, "PIXEL_SIZE", 10)==0){
|
||||
pixel_size = atoi(lbuf+11);
|
||||
printf(" PIXEL_SIZE: %d\n", pixel_size);
|
||||
}else if(strncmp(lbuf, "FONT_ASCENT", 11)==0){
|
||||
font_ascent = atoi(lbuf+12);
|
||||
printf(" FONT_ASCENT: %d\n", font_ascent);
|
||||
}else if(strncmp(lbuf, "CHARS ", 6)==0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(pixel_size==0){
|
||||
printf("Wrong PIXEL_SIZE: %d\n", pixel_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
while(1){
|
||||
pg = bdf_load_char(fp);
|
||||
if(pg==NULL)
|
||||
break;
|
||||
|
||||
if(clist[pg->unicode]==0){
|
||||
free(pg->bitmap);
|
||||
free(pg);
|
||||
continue;
|
||||
}
|
||||
ctab[pg->unicode] = pg;
|
||||
total_chars += 1;
|
||||
}
|
||||
printf(" Chars load: %d\n", total_chars);
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
FT_Library ft_lib;
|
||||
FT_Face ft_face;
|
||||
|
||||
|
||||
GLYPH *ttf_load_char(int ucs)
|
||||
{
|
||||
FT_Glyph glyph;
|
||||
int index, retv;
|
||||
|
||||
index = FT_Get_Char_Index(ft_face, ucs);
|
||||
if(index==0){
|
||||
//printf("FT_Get_Char_Index(%04x): not found!\n", ucs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//retv = FT_Load_Glyph(tt->face, index, FT_LOAD_DEFAULT|FT_LOAD_NO_HINTING);
|
||||
retv = FT_Load_Glyph(ft_face, index, FT_LOAD_DEFAULT);
|
||||
if(retv){
|
||||
printf("FT_Load_Gluph(%04x): error=%08x\n", ucs, retv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FT_Get_Glyph(ft_face->glyph, &glyph);
|
||||
|
||||
if(ft_face->glyph->format!=FT_GLYPH_FORMAT_BITMAP){
|
||||
retv = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_MONO, 0, 1);
|
||||
if(retv){
|
||||
printf("FT_Render_Glyph(%04x): error=%08x\n", ucs, retv);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FT_BitmapGlyph bit = (FT_BitmapGlyph)glyph;
|
||||
FT_Bitmap bm = bit->bitmap;
|
||||
|
||||
GLYPH *pg = (GLYPH*)malloc(sizeof(GLYPH));
|
||||
memset(pg, 0, sizeof(GLYPH));
|
||||
|
||||
pg->unicode = ucs;
|
||||
pg->bw = bm.width;
|
||||
pg->bh = bm.rows;
|
||||
pg->bx = bit->left;
|
||||
pg->by = font_size-bit->top;
|
||||
pg->advance = (glyph->advance.x+0x00008000)>>16;
|
||||
|
||||
int lsize = (pg->bw+7)/8;
|
||||
pg->bsize = lsize*pg->bh;
|
||||
pg->bitmap = malloc(pg->bsize);
|
||||
|
||||
for(int y=0; y<bm.rows; y++){
|
||||
memcpy(pg->bitmap+y*lsize, bm.buffer+y*bm.pitch, lsize);
|
||||
}
|
||||
|
||||
return pg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int load_ttf(char *ttf_name)
|
||||
{
|
||||
int retv, i;
|
||||
|
||||
retv = FT_Init_FreeType(&ft_lib);
|
||||
if(retv){
|
||||
printf("FT_Init_Freetype failed! error=%08x\n", retv);
|
||||
return retv;
|
||||
}
|
||||
|
||||
retv = FT_New_Face(ft_lib, ttf_name, 0, &ft_face);
|
||||
if(retv){
|
||||
printf("FT_New_Face(%s): error=%08x\n", ttf_name, retv);
|
||||
return retv;
|
||||
}
|
||||
|
||||
#if 1
|
||||
printf("FACE: num_fixed_sizes: %d\n", ft_face->num_fixed_sizes);
|
||||
for(i=0; i<ft_face->num_fixed_sizes; i++){
|
||||
printf("%2d: %2ld %2dx%2d\n", i, ft_face->available_sizes[i].size/64,
|
||||
ft_face->available_sizes[i].width,
|
||||
ft_face->available_sizes[i].height);
|
||||
}
|
||||
#endif
|
||||
|
||||
retv = FT_Set_Pixel_Sizes(ft_face, font_size, font_size);
|
||||
if(retv){
|
||||
printf("FT_Set_Pixel_Size: error=%08x\n", retv);
|
||||
//return retv;
|
||||
}
|
||||
|
||||
total_chars = 0;
|
||||
|
||||
for(i=0; i<65536; i++){
|
||||
if(clist[i]==0)
|
||||
continue;
|
||||
ctab[i] = ttf_load_char(i);
|
||||
if(ctab[i]){
|
||||
total_chars += 1;
|
||||
}else{
|
||||
//printf("load char %04x failed!\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_Done_Face(ft_face);
|
||||
FT_Done_FreeType(ft_lib);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
|
||||
void load_list(char *name)
|
||||
{
|
||||
FILE *fp;
|
||||
int n, ucs;
|
||||
|
||||
memset(clist, 1, sizeof(clist));
|
||||
|
||||
if(name==NULL)
|
||||
return;
|
||||
|
||||
fp = fopen(name, "rb");
|
||||
if(fp==NULL)
|
||||
return;
|
||||
|
||||
memset(clist, 0, sizeof(clist));
|
||||
|
||||
fread(&ucs, 2, 1, fp);
|
||||
if(ucs!=0xfeff){
|
||||
printf("文件[%s]不是UTF16-LE格式!\n", name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
while(1){
|
||||
if(fread(&ucs, 2, 1, fp)<1)
|
||||
break;
|
||||
if(ucs==0x0d || ucs==0x0a)
|
||||
continue;
|
||||
|
||||
if(clist[ucs]==0){
|
||||
clist[ucs] = 1;
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Load list form %s: %d\n", name, n);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
void print_glyph(GLYPH *pg)
|
||||
{
|
||||
int x, y;
|
||||
char ubuf[4];
|
||||
|
||||
*(u32*)(ubuf) = 0;
|
||||
ucs2utf8(pg->unicode, ubuf);
|
||||
|
||||
printf("\nchar %04x [%s]\n", pg->unicode, ubuf);
|
||||
printf(" bw=%-2d bh=%-2d bx=%-2d by=%-2d adv=%d\n", pg->bw, pg->bh, pg->bx, pg->by, pg->advance);
|
||||
|
||||
int lsize = (pg->bw+7)/8;
|
||||
for(y=0; y<pg->bh; y++){
|
||||
printf(" ");
|
||||
for(x=0; x<pg->bw; x++){
|
||||
if(pg->bitmap[y*lsize+(x>>3)]&(0x80>>(x%8)))
|
||||
printf("*");
|
||||
else
|
||||
printf(".");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void dump_glyph(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<65536; i++){
|
||||
if(ctab[i]){
|
||||
print_glyph(ctab[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dump_list(void)
|
||||
{
|
||||
int i;
|
||||
char ubuf[4];
|
||||
|
||||
for(i=0; i<65536; i++){
|
||||
if(ctab[i]){
|
||||
*(u32*)(ubuf) = 0;
|
||||
ucs2utf8(i, ubuf);
|
||||
printf("%04x=%s\n", i, ubuf);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
void write_be16(u8 *p, int val)
|
||||
{
|
||||
p[0] = val&0xff;
|
||||
p[1] = (val>>8)&0xff;
|
||||
}
|
||||
|
||||
|
||||
void build_font(void)
|
||||
{
|
||||
int i, p, offset;
|
||||
|
||||
write_be16(font_buf, total_chars);
|
||||
offset = total_chars*4+2;
|
||||
|
||||
p = 2;
|
||||
for(i=0; i<65536; i++){
|
||||
if(ctab[i]){
|
||||
GLYPH *pg = ctab[i];
|
||||
write_be16(font_buf+p, i);
|
||||
write_be16(font_buf+p+2, offset);
|
||||
p += 4;
|
||||
offset += pg->bsize+5;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<65536; i++){
|
||||
if(ctab[i]){
|
||||
GLYPH *pg = ctab[i];
|
||||
font_buf[p+0] = pg->advance;
|
||||
font_buf[p+1] = pg->bw;
|
||||
font_buf[p+2] = pg->bh;
|
||||
font_buf[p+3] = pg->bx;
|
||||
font_buf[p+4] = pg->by;
|
||||
p += 5;
|
||||
memcpy(font_buf+p, pg->bitmap, pg->bsize);
|
||||
p += pg->bsize;
|
||||
}
|
||||
}
|
||||
|
||||
font_buf_size = p;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
int bin2c(u8 *buffer, int size, char *file_name, char *label_name)
|
||||
{
|
||||
FILE *dest;
|
||||
int i, unit=1;
|
||||
|
||||
if((dest = fopen(file_name, "w")) == NULL) {
|
||||
printf("Failed to open/create %s.\n", file_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(dest, "#ifndef __%s__\n", label_name);
|
||||
fprintf(dest, "#define __%s__\n\n", label_name);
|
||||
fprintf(dest, "#define %s_size %d\n", label_name, size);
|
||||
fprintf(dest, "static const unsigned char %s[] __attribute__((aligned(4))) = {", label_name);
|
||||
|
||||
for(i=0; i<size; i+=unit) {
|
||||
if((i % (16/unit)) == 0){
|
||||
fprintf(dest, "\n\t");
|
||||
}else{
|
||||
fprintf(dest, " ");
|
||||
}
|
||||
if(unit==1){
|
||||
fprintf(dest, "0x%02x,", buffer[i]);
|
||||
}else if(unit==2){
|
||||
fprintf(dest, "0x%04x,", buffer[i]);
|
||||
}else{
|
||||
fprintf(dest, "0x%08x,", buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(dest, "\n};\n\n#endif\n");
|
||||
|
||||
fclose(dest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int retv, i;
|
||||
int flags = 0;
|
||||
char *bdf_name = NULL;
|
||||
char *font_name = NULL;
|
||||
char *list_name = NULL;
|
||||
char *label_name = NULL;
|
||||
|
||||
if(argc==1){
|
||||
printf("\nUsage:\n");
|
||||
printf("\tbdfont [-dg] [-dl] [-l list] [-adj base] [-s size] [-c name] [-h name label] font_file\n");
|
||||
printf("\t\t-dg dump glyph\n");
|
||||
printf("\t\t-dl dump char list\n");
|
||||
printf("\t\t-l list load char list\n");
|
||||
printf("\t\t-adj base adjust base line\n");
|
||||
printf("\t\t-s size set font size(for ttf)\n");
|
||||
printf("\t\t-c name\n");
|
||||
printf("\t\t output binary font\n");
|
||||
printf("\t\t-h name label\n");
|
||||
printf("\t\t output c header font\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i=1; i<argc; i++){
|
||||
if(strcmp(argv[i], "-dg")==0){
|
||||
flags |= 1;
|
||||
}else if(strcmp(argv[i], "-dl")==0){
|
||||
flags |= 2;
|
||||
}else if(strcmp(argv[i], "-l")==0){
|
||||
list_name = argv[i+1];
|
||||
i += 1;
|
||||
}else if(strcmp(argv[i], "-adj")==0){
|
||||
base_adj = atoi(argv[i+1]);
|
||||
i += 1;
|
||||
}else if(strcmp(argv[i], "-s")==0){
|
||||
font_size = atoi(argv[i+1]);
|
||||
i += 1;
|
||||
}else if(strcmp(argv[i], "-c")==0){
|
||||
flags |= 4;
|
||||
font_name = argv[i+1];
|
||||
i += 1;
|
||||
}else if(strcmp(argv[i], "-h")==0){
|
||||
flags |= 8;
|
||||
font_name = argv[i+1];
|
||||
label_name = argv[i+2];
|
||||
i += 2;
|
||||
}else if(bdf_name==NULL){
|
||||
bdf_name = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
load_list(list_name);
|
||||
|
||||
//retv = load_bdf(bdf_name);
|
||||
retv = load_ttf(bdf_name);
|
||||
if(retv<0)
|
||||
return -1;
|
||||
|
||||
if(flags&1){
|
||||
dump_glyph();
|
||||
}else if(flags&2){
|
||||
dump_list();
|
||||
}else if(flags&4){
|
||||
build_font();
|
||||
FILE *fp = fopen(font_name, "wb");
|
||||
fwrite(font_buf, 1, font_buf_size, fp);
|
||||
fclose(fp);
|
||||
}else if(flags&8){
|
||||
build_font();
|
||||
bin2c(font_buf, font_buf_size, font_name, label_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
fontool/dseg.txt
Normal file
BIN
fontool/dseg.txt
Normal file
Binary file not shown.
243
fontool/epd_gui.c
Normal file
243
fontool/epd_gui.c
Normal file
@@ -0,0 +1,243 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gdifb.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
|
||||
#define BLACK 0x00000000
|
||||
#define WHITE 0x00ffffff
|
||||
#define RED 0x000000ff
|
||||
#define GREEN 0x0000ff00
|
||||
#define BLUE 0x00ff0000
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
void draw_pixel(int x, int y, int color)
|
||||
{
|
||||
gdifb_pixel(x, y, color);
|
||||
}
|
||||
|
||||
|
||||
void draw_hline(int y, int x1, int x2, int color)
|
||||
{
|
||||
gdifb_line(x1, y, x2, y, color);
|
||||
}
|
||||
|
||||
|
||||
void draw_vline(int x, int y1, int y2, int color)
|
||||
{
|
||||
gdifb_line(x, y1, x, y2, color);
|
||||
}
|
||||
|
||||
|
||||
void draw_rect(int x1, int y1, int x2, int y2, int color)
|
||||
{
|
||||
gdifb_rect(x1, y1, x2, y2, color);
|
||||
}
|
||||
|
||||
|
||||
void draw_box(int x1, int y1, int x2, int y2, int color)
|
||||
{
|
||||
gdifb_box(x1, y1, x2, y2, color);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
#include "sfont.h"
|
||||
#include "sfont16.h"
|
||||
#include "font50.h"
|
||||
#include "font66.h"
|
||||
|
||||
const u8 *font_list[6] = {
|
||||
sfont,
|
||||
sfont16,
|
||||
F_DSEG7_50,
|
||||
F_DSEG7_66,
|
||||
};
|
||||
|
||||
const u8 *current_font = (u8*)sfont;
|
||||
|
||||
int select_font(int id)
|
||||
{
|
||||
current_font = font_list[id];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const u8 *find_font(const u8 *font, int ucs)
|
||||
{
|
||||
int total = *(u16*)font;
|
||||
int i;
|
||||
|
||||
for(i=0; i<total; i++){
|
||||
if(*(u16*)(font+2+i*4+0)==ucs){
|
||||
int offset = *(u16*)(font+2+i*4+2);
|
||||
//printf(" %04x at %04x\n", ucs, offset);
|
||||
return font+offset;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int fb_draw_font(int x, int y, int ucs, int color)
|
||||
{
|
||||
int r, c;
|
||||
const u8 *font_data = find_font(current_font, ucs);
|
||||
if(font_data==NULL){
|
||||
printf("fb_draw %04x: not found!\n", ucs);
|
||||
}
|
||||
|
||||
int ft_adv = font_data[0];
|
||||
int ft_bw = font_data[1];
|
||||
int ft_bh = font_data[2];
|
||||
int ft_bx = (signed char)font_data[3];
|
||||
int ft_by = (signed char)font_data[4];
|
||||
int ft_lsize = (ft_bw+7)/8;
|
||||
font_data += 5;
|
||||
|
||||
x += ft_bx;
|
||||
y += ft_by;
|
||||
|
||||
for (r=0; r<ft_bh; r++) {
|
||||
for (c=0; c<ft_bw; c++) {
|
||||
int b = font_data[c>>3];
|
||||
int mask = 0x80>>(c%8);
|
||||
if(b&mask){
|
||||
draw_pixel(x+c, y, color);
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
font_data += ft_lsize;
|
||||
y += 1;
|
||||
}
|
||||
|
||||
return ft_adv;
|
||||
}
|
||||
|
||||
|
||||
static int utf8_to_ucs(char **ustr)
|
||||
{
|
||||
u8 *str = (u8*)*ustr;
|
||||
int ucs = 0;
|
||||
|
||||
if(*str==0){
|
||||
return 0;
|
||||
}else if(*str<0x80){
|
||||
*ustr = (char*)str+1;
|
||||
return *str;
|
||||
}else if(*str<0xe0){
|
||||
ucs = ((str[0]&0x1f)<<6) | (str[1]&0x3f);
|
||||
*ustr = (char*)str+2;
|
||||
return ucs;
|
||||
}else{
|
||||
ucs = ((str[0]&0x0f)<<12) | ((str[1]&0x3f)<<6) | (str[2]&0x3f);
|
||||
*ustr = (char*)str+3;
|
||||
return ucs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw_text(int x, int y, char *str, int color)
|
||||
{
|
||||
int ch;
|
||||
|
||||
while(1){
|
||||
ch = utf8_to_ucs(&str);
|
||||
if(ch==0)
|
||||
break;
|
||||
x += fb_draw_font(x, y, ch, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
char *wday_str[] = {"日", "一", "二", "三", "四", "五", "六"};
|
||||
|
||||
static int wday = 0;
|
||||
|
||||
typedef struct {
|
||||
int xres, yres;
|
||||
int font_char;
|
||||
int font_dseg;
|
||||
int top;
|
||||
int mid;
|
||||
int bottom;
|
||||
int t1;
|
||||
int m1;
|
||||
int b1;
|
||||
}LAYOUT;
|
||||
|
||||
LAYOUT layouts[3] = {
|
||||
{212, 104, 0, 2, 6, 27, 82, 15, 20, 12},
|
||||
{250, 122, 1, 3, 6, 28, 98, 15, 16, 12},
|
||||
{296, 128, 1, 3, 6, 30, 102, 15, 36, 12},
|
||||
};
|
||||
|
||||
int current_layout = 0;
|
||||
|
||||
void fb_test(void)
|
||||
{
|
||||
LAYOUT *lt = &layouts[current_layout];
|
||||
|
||||
// 显示公历日期
|
||||
select_font(lt->font_char);
|
||||
char tbuf[64];
|
||||
sprintf(tbuf, "%4d年%2d月%2d日 星期%s", 2025, 4, 29, wday_str[wday]);
|
||||
draw_text(lt->t1, lt->top, tbuf, BLACK);
|
||||
// 显示农历日期(不显示年)
|
||||
sprintf(tbuf, "%s月%s日", wday_str[wday], wday_str[wday]);
|
||||
draw_text(lt->b1, lt->bottom, tbuf, BLACK);
|
||||
|
||||
wday += 1;
|
||||
if(wday==7)
|
||||
wday = 0;
|
||||
|
||||
// 使用大字显示时间
|
||||
select_font(lt->font_dseg);
|
||||
sprintf(tbuf, "%02d:%02d", 2+wday, 31+wday);
|
||||
draw_text(lt->m1, lt->mid, tbuf, BLACK);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int scr_w, scr_h;
|
||||
|
||||
|
||||
// scr_w = 212; scr_h = 104; current_layout = 0;
|
||||
// scr_w = 250; scr_h = 122; current_layout = 1;
|
||||
scr_w = 296; scr_h = 128; current_layout = 2;
|
||||
|
||||
|
||||
gdifb_init(scr_w, scr_h);
|
||||
draw_box(0, 0, scr_w-1, scr_h-1, WHITE);
|
||||
draw_rect(0, 0, scr_w-1, scr_h-1, RED);
|
||||
|
||||
fb_test();
|
||||
|
||||
gdifb_flush();
|
||||
gdifb_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
287
fontool/gdifb.c
Normal file
287
fontool/gdifb.c
Normal file
@@ -0,0 +1,287 @@
|
||||
|
||||
#define WINVER 0x0500
|
||||
|
||||
#include <windows.h>
|
||||
#include <wingdi.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
static int width;
|
||||
static int height;
|
||||
unsigned char *gdifbuf;
|
||||
static int gdifb_ready;
|
||||
|
||||
static HINSTANCE hInst;
|
||||
static HBITMAP hbmp;
|
||||
static HDC hmemdc;
|
||||
|
||||
static HANDLE h_gdifb;
|
||||
static DWORD gdifb_id;
|
||||
static HWND gdifb;
|
||||
|
||||
static ATOM MyRegisterClass(void);
|
||||
static BOOL InitInstance(void);
|
||||
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
static int vkey;
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
DWORD WINAPI gdifb_main(LPVOID lpParam)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
hInst = GetModuleHandle(0);
|
||||
MyRegisterClass();
|
||||
if (!InitInstance ()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdifb_ready = 1;
|
||||
|
||||
// Main message loop:
|
||||
while(GetMessage(&msg, NULL, 0, 0)){
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
|
||||
ATOM MyRegisterClass()
|
||||
{
|
||||
WNDCLASS wc;
|
||||
|
||||
wc.style = CS_HREDRAW|CS_VREDRAW;
|
||||
wc.lpfnWndProc = (WNDPROC)WndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInst;
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "GDI_FB";
|
||||
|
||||
return RegisterClass(&wc);
|
||||
}
|
||||
|
||||
|
||||
void memdc_create(HWND hwnd)
|
||||
{
|
||||
BITMAPINFOHEADER bh;
|
||||
HDC hdc;
|
||||
|
||||
memset(&bh, 0, sizeof(bh));
|
||||
bh.biSize = sizeof(bh);
|
||||
bh.biHeight = -(height+256);
|
||||
//bh.biWidth = width;
|
||||
bh.biWidth = 2048;
|
||||
bh.biPlanes = 1;
|
||||
bh.biBitCount = 32;
|
||||
bh.biCompression = BI_RGB;
|
||||
|
||||
hdc = GetDC(hwnd);
|
||||
hbmp = CreateDIBSection (hdc, (LPBITMAPINFO)&bh, DIB_RGB_COLORS, (void**)&gdifbuf, NULL, 0) ;
|
||||
hmemdc = CreateCompatibleDC(hdc);
|
||||
SelectObject(hmemdc, hbmp);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
|
||||
|
||||
BOOL InitInstance()
|
||||
{
|
||||
HWND hWnd;
|
||||
DWORD style = WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_MAXIMIZEBOX;
|
||||
RECT rect;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = width;
|
||||
rect.bottom = height;
|
||||
AdjustWindowRect(&rect, style, FALSE);
|
||||
|
||||
hWnd=CreateWindow("GDI_FB", "GDI_FB", style, CW_USEDEFAULT, 0,
|
||||
rect.right-rect.left, rect.bottom-rect.top,
|
||||
0, 0, hInst, 0);
|
||||
|
||||
if (!hWnd){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memdc_create(hWnd);
|
||||
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_PAINT:
|
||||
hdc = BeginPaint(hWnd, &ps);
|
||||
BitBlt(hdc, 0, 0, width, height, hmemdc, 0, 0, SRCCOPY);
|
||||
EndPaint(hWnd, &ps);
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
vkey = wParam;
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
void gdifb_textout(int x, int y, char *text)
|
||||
{
|
||||
TextOut(hmemdc, x, y, text, strlen(text));
|
||||
}
|
||||
|
||||
|
||||
void gdifb_pixel(int x, int y, int color)
|
||||
{
|
||||
*(DWORD*)(gdifbuf + (y*2048 + x)*4) = color;
|
||||
}
|
||||
|
||||
|
||||
void gdifb_line(int x1, int y1, int x2, int y2, int color)
|
||||
{
|
||||
HPEN pen, old_pen;
|
||||
|
||||
pen = CreatePen(PS_SOLID, 1, color);
|
||||
old_pen = SelectObject(hmemdc, pen);
|
||||
|
||||
MoveToEx(hmemdc, x1, y1, NULL);
|
||||
LineTo(hmemdc, x2, y2);
|
||||
SetPixel(hmemdc, x2, y2, color);
|
||||
|
||||
SelectObject(hmemdc, old_pen);
|
||||
}
|
||||
|
||||
|
||||
void gdifb_rect(int x1, int y1, int x2, int y2, int color)
|
||||
{
|
||||
HPEN pen, old_pen;
|
||||
|
||||
pen = CreatePen(PS_SOLID, 1, color);
|
||||
old_pen = SelectObject(hmemdc, pen);
|
||||
|
||||
MoveToEx(hmemdc, x1, y1, NULL);
|
||||
LineTo(hmemdc, x2, y1);
|
||||
LineTo(hmemdc, x2, y2);
|
||||
LineTo(hmemdc, x1, y2);
|
||||
LineTo(hmemdc, x1, y1);
|
||||
|
||||
SelectObject(hmemdc, old_pen);
|
||||
}
|
||||
|
||||
|
||||
void gdifb_box(int x1, int y1, int x2, int y2, int color)
|
||||
{
|
||||
HPEN pen, old_pen;
|
||||
HBRUSH brush;
|
||||
RECT rect;
|
||||
|
||||
pen = CreatePen(PS_SOLID, 1, color);
|
||||
old_pen = SelectObject(hmemdc, pen);
|
||||
brush = CreateSolidBrush(color);
|
||||
|
||||
rect.left = x1;
|
||||
rect.right = x2+1;
|
||||
rect.top = y1;
|
||||
rect.bottom = y2+1;
|
||||
FillRect(hmemdc, &rect, brush);
|
||||
|
||||
SelectObject(hmemdc, old_pen);
|
||||
}
|
||||
|
||||
|
||||
void gdifb_flush(void)
|
||||
{
|
||||
InvalidateRect(gdifb, NULL, TRUE);
|
||||
}
|
||||
|
||||
|
||||
int gdifb_waitkey(void)
|
||||
{
|
||||
vkey = 0;
|
||||
while(vkey==0);
|
||||
return vkey;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
|
||||
int gdifb_init(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
gdifb_ready = 0;
|
||||
|
||||
h_gdifb = CreateThread(NULL, 0, gdifb_main, NULL, 0, &gdifb_id);
|
||||
while(1){
|
||||
gdifb = FindWindow(NULL, "GDI_FB");
|
||||
if(gdifb)
|
||||
break;
|
||||
}
|
||||
|
||||
while(gdifb_ready==0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int gdifb_exit(void)
|
||||
{
|
||||
WaitForSingleObject(h_gdifb,INFINITE);
|
||||
CloseHandle(h_gdifb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#ifdef TEST_GDIFB
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
gdifb_init(320, 240);
|
||||
|
||||
gdifb_textout(48, 48, "gdifb_test!");
|
||||
|
||||
int i;
|
||||
for(i=0; i<100; i++){
|
||||
gdifb_pixel(20+i, 200, 0xff00ff);
|
||||
}
|
||||
|
||||
gdifb_line(10, 10, 100, 100, 0x00FF0000);
|
||||
gdifb_rect(5, 5, 300, 235, 0x000000FF);
|
||||
gdifb_box(120, 120, 140, 140, 0x0000FF00);
|
||||
|
||||
gdifb_flush();
|
||||
|
||||
gdifb_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
18
fontool/gdifb.h
Normal file
18
fontool/gdifb.h
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
extern unsigned char *gdifbuf;
|
||||
#define gdifb_llen (2048*4)
|
||||
|
||||
int gdifb_init(int w, int h);
|
||||
void gdifb_flush(void);
|
||||
int gdifb_exit(void);
|
||||
|
||||
|
||||
void gdifb_textout(int x, int y, char *text);
|
||||
void gdifb_pixel(int x, int y, int color);
|
||||
void gdifb_line(int x1, int y1, int x2, int y2, int color);
|
||||
void gdifb_rect(int x1, int y1, int x2, int y2, int color);
|
||||
void gdifb_box(int x1, int y1, int x2, int y2, int color);
|
||||
|
||||
int gdifb_waitkey(void);
|
||||
|
||||
9
fontool/mkfont.sh
Normal file
9
fontool/mkfont.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# 请自行下载文泉驿正黑字体,或用其他字体替换。
|
||||
|
||||
./bdfont.exe -l small.txt wqy-zenhei.ttc -s 14 -h sfont.h sfont
|
||||
./bdfont.exe -l small.txt wqy-zenhei.ttc -s 16 -h sfont16.h sfont16
|
||||
|
||||
./bdfont.exe -l dseg.txt DSEG7CR.ttf -s 50 -h font50.h F_DSEG7_50
|
||||
./bdfont.exe -l dseg.txt DSEG7CR.ttf -s 66 -h font66.h F_DSEG7_66
|
||||
|
||||
BIN
fontool/small.txt
Normal file
BIN
fontool/small.txt
Normal file
Binary file not shown.
Reference in New Issue
Block a user