/*************************************************************** ** ** Broadcom Corp. Confidential ** Copyright 2002 Broadcom Corp. All Rights Reserved. ** ** THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED ** SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM. ** YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT ** SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. ** ** Description: Create SGIL bitmap fonts from freetype fonts. ** ** Created: 8/22/2002 by Jeffrey P. Fisher ** ** ** ****************************************************************/ #include #include //#include FT_FREETYPE_H #include "freetype/config/ftheader.h" #include "freetype/freetype.h" #include "freetype/ftglyph.h" #include "utf8lib.c" /* Function for converting ASCII to UTF8 */ static int unicode = ft_encoding_unicode; #define FILTER_CHINESE_FONT_LEVEL2 #ifdef FILTER_CHINESE_FONT_LEVEL2 #define FILTER_CHINESE_FONT_SET #endif #ifdef FILTER_CHINESE_FONT_LEVEL2 #ifdef FILTER_CHINESE_FONT_SET #include int in_filter_list(unsigned short charcode) { int i; if (charcode < 0xa4a1) return 1; for (i = 0; i < g_DTA_font_set_size; i++) { if (g_DTA_font_set[i] == charcode) return 1; } return 0; } #endif int in_chinese_font_level2(unsigned short charcode) { if (ft_encoding_gb2312 == unicode) { /* take first set only to reduce size */ if (charcode >= 0xd8a0) return 1; } return 0; } #endif typedef struct fontripper_t { FILE *out_fp; /* Output file pointer */ FILE *log_fp; /* Log file pointer */ int type; /* Type of bitmap font to generate 0-mono,1-grayscale */ FT_Library ft_library; /* Freetype library reference */ FT_Face face; /* Typeface reference */ int ascender; /* The font accent in pixels */ int descender; /* The font descent in pixels */ int height; /* The font height (size) */ int maxadvance; /* Maximum horizontal distance to advance after drawing a character in this font */ }fontripper_t; /**************************************************************** * INPUTS: fr_p - font ripper parameters * OUTPUTS: none * RETURNS: number of glyph entries * DESCRIPTION: Get the maximum number of glyph index entries. * ****************************************************************/ int get_max_glyph_index(fontripper_t *fr_p) { FT_ULong charcode; FT_UInt gindex; int cnt = 0; charcode = FT_Get_First_Char( fr_p->face, &gindex ); while ( gindex != 0 ) { #ifdef FILTER_CHINESE_FONT_LEVEL2 if (in_chinese_font_level2(charcode)) break; #ifdef FILTER_CHINESE_FONT_SET if (!in_filter_list(charcode)) { charcode = FT_Get_Next_Char( fr_p->face, charcode, &gindex ); continue; } #endif #endif ++cnt; charcode = FT_Get_Next_Char( fr_p->face, charcode, &gindex ); } return cnt; } /**************************************************************** * INPUTS: fr_p - font ripper parameters * OUTPUTS: none * RETURNS: non-zero on failure * DESCRIPTION: Output glyph index. * ****************************************************************/ int output_glyph_index(fontripper_t *fr_p) { FT_ULong charcode; FT_UInt gindex; int entries = get_max_glyph_index(fr_p); printf("Entries=%d\n", entries); /* Write number of entries */ if (fwrite(&entries,1,sizeof(entries),fr_p->out_fp) != sizeof(entries)) return -1; charcode = FT_Get_First_Char( fr_p->face, &gindex ); while ( gindex != 0 ) { #ifdef FILTER_CHINESE_FONT_LEVEL2 if (in_chinese_font_level2(charcode)) break; #ifdef FILTER_CHINESE_FONT_SET if (!in_filter_list(charcode)) { charcode = FT_Get_Next_Char( fr_p->face, charcode, &gindex ); continue; } #endif #endif if (fwrite(&charcode,1,sizeof(FT_ULong),fr_p->out_fp) != sizeof(FT_ULong)) return -1; charcode = FT_Get_Next_Char( fr_p->face, charcode, &gindex ); } return 0; } /**************************************************************** * INPUTS: fr_p - font ripper parameters * OUTPUTS: none * RETURNS: non-zero on failure * DESCRIPTION: Create and ouput bitmap font. * ****************************************************************/ int output_font(fontripper_t *fr_p) { FT_ULong charcode; FT_UInt gindex; FT_Int ld_flags; char left; /* horizontal offset to character start location */ char top; /* vertical offset to character start location */ char advance; /* horizontal offset to next character start location */ unsigned char width; /* width of the rendered character bitmap in pixels */ unsigned char height; /* height of the rendered character bitmap in pixels */ unsigned char pitch; /* number of bytes in each bitmap row */ int ascender; /* The font accent in pixels */ int descender; /* The font descent in pixels */ int f_height; /* The font height (size) */ int maxadvance; /* Maximum horizontal distance to advance after drawing a character in this font */ unsigned long format; /* The format flags for this font */ /* Output font info */ ascender = fr_p->face->size->metrics.ascender >> 6; descender = fr_p->face->size->metrics.descender >> 6; f_height = (fr_p->face->size->metrics.ascender - fr_p->face->size->metrics.descender) >> 6; maxadvance = fr_p->face->size->metrics.max_advance >> 6; format = (fr_p->type == 0) ? 1 : 0; if (fwrite(&ascender,1,sizeof(ascender),fr_p->out_fp) != sizeof(ascender)) return -1; if (fwrite(&descender,1,sizeof(descender),fr_p->out_fp) != sizeof(descender)) return -1; if (fwrite(&f_height,1,sizeof(f_height),fr_p->out_fp) != sizeof(f_height)) return -1; if (fwrite(&maxadvance,1,sizeof(maxadvance),fr_p->out_fp) != sizeof(maxadvance)) return -1; if (fwrite(&format,1,sizeof(format),fr_p->out_fp) != sizeof(format)) return -1; /* Output the glyph character index */ if (output_glyph_index(fr_p)) return -1; ld_flags = (FT_Int) fr_p->face->generic.data; ld_flags |= FT_LOAD_RENDER; charcode = FT_Get_First_Char( fr_p->face, &gindex ); while ( gindex != 0 ) { #ifdef FILTER_CHINESE_FONT_LEVEL2 if (in_chinese_font_level2(charcode)) break; #ifdef FILTER_CHINESE_FONT_SET if (!in_filter_list(charcode)) { charcode = FT_Get_Next_Char( fr_p->face, charcode, &gindex ); continue; } #endif #endif if (FT_Load_Glyph( fr_p->face, gindex, ld_flags )) return -1; /* Re-asign to more sane types for compactness */ left = (char)fr_p->face->glyph->bitmap_left; top = (char)fr_p->face->glyph->bitmap_top; advance = (char)(fr_p->face->glyph->advance.x >> 6); width = (unsigned char)fr_p->face->glyph->bitmap.width; height = (unsigned char)fr_p->face->glyph->bitmap.rows; pitch = (unsigned char)fr_p->face->glyph->bitmap.pitch; if (fwrite(&left,1,sizeof(left),fr_p->out_fp) != sizeof(left)) return -1; if (fwrite(&top,1,sizeof(top),fr_p->out_fp) != sizeof(top)) return -1; if (fwrite(&advance,1,sizeof(advance),fr_p->out_fp) != sizeof(advance)) return -1; if (fwrite(&width,1,sizeof(width),fr_p->out_fp) != sizeof(width)) return -1; if (fwrite(&height,1,sizeof(height),fr_p->out_fp) != sizeof(height)) return -1; if (fwrite(&pitch,1,sizeof(pitch),fr_p->out_fp) != sizeof(pitch)) return -1; if (fwrite(fr_p->face->glyph->bitmap.buffer,1,(pitch * height),fr_p->out_fp) != (pitch * height)) return -1; fprintf(fr_p->log_fp,"Char: 0x%04x,%d,%d,%d,%d,%d,%d,%d\n",charcode,gindex,top,left,width,height,advance,top+height); charcode = FT_Get_Next_Char( fr_p->face, charcode, &gindex ); } return 0; } /**************************************************************** * INPUTS: arc - argument count * argv - array of arguments * OUTPUTS: none * RETURNS: non-zero on failure * DESCRIPTION: Main entry point convert fonts to raw bitmap. * ****************************************************************/ int main(int argc, char *argv[]) { int i,italic; int fcnt = 0; int fsize[8]; static unsigned char outname[1024]; fontripper_t fr; memset(&fr,0,sizeof(fr)); fr.log_fp = stdout; italic = 0; /* Initialize the freetype library */ if (FT_Init_FreeType( &fr.ft_library )) { fprintf(fr.log_fp,"Error initializing freetype library.\n"); return -1; } /* Check argument count and ouput usage */ if (argc < 3) { fprintf(fr.log_fp,"USAGE: fontripper [-s -t <0|1>] [ -c ]\n"); fprintf(fr.log_fp,"\t-s specify the size of the bitmap font (default 24)\n"); fprintf(fr.log_fp,"\t-t <0|1> specify the bitmap font type (0-mono,1-greyscale))\n"); fprintf(fr.log_fp,"\t-i apply horizontal hear to simulate italic\n"); fprintf(fr.log_fp,"\t-c to convert a Chinese True Font with GB2312 standard\n"); goto done; } /* Parse arguments */ for (i = 3; i < argc; i += 2) { if ((strcmp(argv[i],"-s") == 0) || (strcmp(argv[i],"-S") == 0)) { sscanf(argv[i + 1],"%d",&fsize[fcnt]); printf("Font Size %d\n",fsize[fcnt]); fcnt++; } else if ((strcmp(argv[i],"-i") == 0) || (strcmp(argv[i],"-I") == 0)) { italic = 1; printf("Italic.\n"); } else if ((strcmp(argv[i],"-t") == 0) || (strcmp(argv[i],"-T") == 0)) { sscanf(argv[i + 1],"%d",&fr.type); printf("Font Type %s\n",(fr.type == 0) ? "mono":"grayscale"); } else if ((strcmp(argv[i],"-c") == 0) || (strcmp(argv[i],"-C") == 0)) { unicode = ft_encoding_gb2312; } if (fcnt >= 8) break; } /* Set defaults */ if (fcnt == 0) { fcnt = 1; fsize[0] = 24; } /* Create freetype typeface */ printf("Open %s\n",argv[1]); if (FT_New_Face( fr.ft_library, argv[1],0, &fr.face )) { fprintf(fr.log_fp,"Error creating font fr.face %s\n",argv[1]); goto done; } printf("Opened %s, 0x%08x\n",argv[1],fr.face); #if 1 printf("Num Faces: %d\n",fr.face->num_faces); printf("Face Index: %d\n",fr.face->face_index); printf("Family: %s\n",fr.face->family_name); printf("Style: %s\n",fr.face->style_name); printf("Face Flags: %d\n",fr.face->face_flags); printf("Style Flags: %d\n",fr.face->style_flags); printf("Units per EM: %d\n",fr.face->units_per_EM); #endif if (FT_Select_Charmap( fr.face, unicode )) { fprintf(fr.log_fp,"Error font fr.face %s does not have unicode encoding\n",argv[1]); goto done; } if (italic) { FT_Matrix matrix; matrix.xx = 0x10000L; matrix.xy = 0x10000L * 0.12; matrix.yx = 0; matrix.yy = 0x10000L; FT_Set_Transform( fr.face, &matrix,0 ); } /* Loop through sizes and ouput bitmap formats */ for (i = 0; i < fcnt; ++i) { if (FT_Set_Pixel_Sizes( fr.face, 0, fsize[i])) { fprintf(fr.log_fp,"Could net set font fr.face %s size %d\n",argv[1],fsize[i]); goto done; } printf("x_scale: %d\n",fr.face->size->metrics.x_scale); printf("y_scale: %d\n",fr.face->size->metrics.y_scale); printf("Underline: %d\n",FT_MulFix(fr.face->underline_position,fr.face->size->metrics.y_scale)/64); printf("Thickness: %d\n",FT_MulFix(fr.face->underline_thickness,fr.face->size->metrics.y_scale)/64); if ( fr.type == 0) fr.face->generic.data = (void *) (FT_LOAD_DEFAULT | FT_LOAD_MONOCHROME); else fr.face->generic.data = (void *) FT_LOAD_DEFAULT; /* Create file to save font too */ sprintf(outname,"%s_%d_%s.bff",argv[2],fsize[i],( fr.type == 0) ? "mono":"aa"); fr.out_fp = fopen(outname, "wb"); if (! fr.out_fp) { fprintf(fr.log_fp,"Error opening file %s\n",outname); goto done; } /* output the font definition */ output_font(&fr); fclose( fr.out_fp); fr.out_fp = NULL; } done: /* do freetype cleanup */ FT_Done_FreeType( fr.ft_library ); if ( fr.out_fp) fclose( fr.out_fp); return 0; }