/* text draw truetypefont * * 2004/01/30 */ #include #include #include #include #ifdef HAVE_ICONV_H #include #endif #ifdef HAVE_FT2BUILD_H #include #include FT_FREETYPE_H #endif #include #include "driver.h" #include "driverlib.h" # define RpD ((2 * M_PI) / 360.) /* radians/degree */ # define D2R(d) (double)(d * RpD) /* degrees->radians */ /*#define DEBUG_LOG(S) {FILE *fp = fopen("debug.TXT","a");fputs(S,fp);fclose(fp);}*/ /*#define DEBUG_LOG_INT(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%d",D);fclose(fp);}*/ /*#define DEBUG_LOG_DOUBLE(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%f",D);fclose(fp);}*/ #ifdef HAVE_FT2BUILD_H static int convert_str(const char *,const char *,unsigned char **); static void release_convert_str(unsigned char *); static void set_matrix(FT_Matrix*,double); static void draw_text(FT_Face,FT_Vector*,FT_Matrix*,const unsigned char *,int,int); static void draw_bitmap(FT_Bitmap*,FT_Int,FT_Int); static void set_text_box(FT_Bitmap*,FT_Int,FT_Int); #endif static int fdont_draw = 0; static int ft, fb, fl, fr; static void draw_main( int x, int y, double text_size_x, double text_size_y, double text_rotation, const char *string) { #ifdef HAVE_FT2BUILD_H FT_Library library; FT_Face face; FT_Matrix matrix; /*FT_UInt glyph_index;*/ FT_Vector pen; FT_Error ans; const char *filename; const char *charset; unsigned char *out; int outlen; /* get file name */ filename = font_get_freetype_name(); charset = font_get_charset(); /* set freetype */ ans = FT_Init_FreeType(&library); if(ans) { /* DEBUG_LOG("Text3 error: ft init\n"); */ return; } ans = FT_New_Face(library,filename,0,&face); if (ans == FT_Err_Unknown_File_Format) { /* DEBUG_LOG("Text3 error: ft new face 1\n"); */ FT_Done_FreeType(library); return; } else if(ans) { /* DEBUG_LOG("Text3 error: ft new face 2\n"); */ FT_Done_FreeType(library); return; } /* ans = FT_Set_Pixel_Sizes(face,10,10); */ /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,0,0); */ /* ans = FT_Set_Char_Size(face,10*64,0,72,0); */ /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,72,72); */ ans = FT_Set_Char_Size(face, (int) (text_size_x * 64), (int) (text_size_y * 64), 100, 100); /* ans = FT_Set_Pixel_Sizes( face, 0, (int)text_size_y ); */ if(ans) { /* DEBUG_LOG("Text3 error: ft set size\n"); */ FT_Done_Face(face); FT_Done_FreeType(library); return; } /* init point */ pen.x = x*64; /* pen.y = 0; */ pen.y = (screen_bottom - y) * 64; /* convert string to:shift-jis from:charset */ outlen = convert_str(charset, string, &out); /* set matrix */ set_matrix(&matrix, D2R(text_rotation)); /* draw */ draw_text(face, &pen, &matrix, out, outlen, 0); /* release */ release_convert_str(out); /* FT_done */ FT_Done_Face(face); FT_Done_FreeType(library); #endif } #ifdef HAVE_FT2BUILD_H static void set_matrix(FT_Matrix *matrix, double rotation) { /* rotation is in radians */ matrix->xx = (FT_Fixed)( cos(rotation) * 0x10000); matrix->xy = (FT_Fixed)(-sin(rotation) * 0x10000); matrix->yx = (FT_Fixed)( sin(rotation) * 0x10000); matrix->yy = (FT_Fixed)( cos(rotation) * 0x10000); } static int convert_str(const char *from, const char *in, unsigned char **out) { iconv_t cd; size_t ret; size_t len = 0; size_t i = 0; int res = 0; const unsigned char *p1; unsigned char *p2; len = strlen(in); res = 2*(len+1); /* res = 4*(len+1); */ *out = G_malloc(res); memset(*out,0,res); p1 = in; p2 = *out; i = res; if( (cd = iconv_open("UCS-2BE",from)) < 0 ) /* if( (cd = iconv_open("UCS-4",from)) < 0 ) */ /* if( (cd = iconv_open("UTF-8",from)) < 0 ) */ return -1; ret = iconv(cd,(const char **)&p1,&len,(char **)&p2,&i); /* if(ret == -1){ if(errno == E2BIG){ {DEBUG_LOG("E2BIG\n")} } if(errno == EILSEQ){ {DEBUG_LOG("EILSEQ\n")} } if(errno == EINVAL){ {DEBUG_LOG("EILSEQ\n")} } } */ iconv_close(cd); res -= i; return res; } static void release_convert_str(unsigned char *out) { G_free (out); } static void draw_text(FT_Face face, FT_Vector* pen, FT_Matrix* matrix, const unsigned char *out, int len, int color) { FT_ULong ch; FT_Error ans; FT_GlyphSlot slot = face->glyph; int i; for (i = 0; i < len ; i += 2) { ch = (out[i]<<8) | out[i+1]; if (ch == 10) continue; /* transform */ FT_Set_Transform(face,matrix,pen); /* get glyph image */ ans = FT_Load_Char(face, ch, FT_LOAD_NO_BITMAP); if (ans) continue; ans = FT_Render_Glyph(face->glyph, ft_render_mode_normal); if (ans) continue; /* draw bitmap */ if (!fdont_draw) draw_bitmap(&slot->bitmap, slot->bitmap_left, screen_bottom-slot->bitmap_top); else set_text_box(&slot->bitmap, slot->bitmap_left, screen_bottom-slot->bitmap_top); /* increment pen position */ pen->x += slot->advance.x; pen->y += slot->advance.y; } } static void set_text_box(FT_Bitmap *bitmap, FT_Int x, FT_Int y) { FT_Int xMax = x + bitmap->width; FT_Int yMax = y + bitmap->rows; if((x == xMax) || (y == yMax)) return; if (x < fl) fl = x; if (xMax > fr) fr = xMax; if (y < ft) ft = y; if (yMax > fb) fb = yMax; } static void draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y) { static unsigned char *buf; static int nalloc; int w, h; int bw = bitmap->width; int bh = bitmap->rows; const unsigned char *sbuf = bitmap->buffer; int offset, i, j; double x1, y1, x2, y2; x1 = (double)x; y1 = (double)y; x2 = x1 + (double)bw; y2 = y1 + (double)bh; window_box_clip(&x1, &y1, &x2, &y2); w = x2 - x1; h = y2 - y1; if (w <= 0 || h <= 0) return; offset = ((int)y1 - y) * bw + (int)x1 - x; if (nalloc < w * h) { nalloc = w * h; buf = G_realloc(buf, nalloc); } for (j = 0; j < h; j++) for (i = 0; i < w; i++) buf[j * w + i] = sbuf[offset + j * bw + i] > 128 ? 1:0; COM_Move_abs(x1, y1); DRV_draw_bitmap(w, h, buf); } #endif void soft_text_freetype( int x, int y, double text_size_x, double text_size_y, double text_rotation, const char *string) { text_size_x *= 25.0; text_size_y *= 25.0; draw_main(x, y, text_size_x, text_size_y, text_rotation, string); } void soft_text_ext_freetype( int x, int y, double text_size_x, double text_size_y, double text_rotation, const char *string) { fdont_draw = 1; text_size_x *= 25.0; text_size_y *= 25.0; ft = 999999; fb = 0; fl = 999999; fr = 0; /* draw_main(x,y,text_size_x,text_size_y,text_rotation,string); */ /* draw_main(0,0,text_size_x,text_size_y,text_rotation,string); */ draw_main(0, y, text_size_x, text_size_y, text_rotation, string); /* ft += y; */ /* fb += y; */ fl += x; fr += x; fdont_draw = 0; } void get_text_ext_freetype(int *top, int *bot, int *left, int *rite) { *top = ft; *bot = fb; *left = fl; *rite = fr; }