在VC6.0上制作矢量字库

在做项目时,客户由于要求矢量字体,不得已研究下矢量字体,在此分享字库的制作
一.在vc6.0上安装freetype
   a.向往
http://download.savannah.gnu.org/releases/freetype/ 下载freetype安装包。

    
   b.进入builds/文件夹下,在许多平台上都可以编译freetype.在这里选择win32\visualc\
c.打开*.dsp文件,编译下,在freetype-2.4.0\objs\目录下会生成一个静态库文件freetype.lib*.dll,在制作字库时会用的.

  c.新建一个工程,拷贝freetype目录下include文件夹复制到自己工程中,把freetype.lib和freetype.dll文件拷贝到新建的工程中.

    

   

   d.打开菜单project->settings->c/c++中,在category中选择preprocessor再添加指令文件的路径(如图1-2),选择Link项,在library modules:添加freetype.lib(如图1-1)

          

                                                                         1-0

                   
                                                                        1-1
 
   e.添加测试代码
#include "ft2build.h"
#include FT_FREETYPE_H

void TestTrueType()
{
    FT_Library          m_pFTLib;
      FT_Face     m_pFTFace;

       FT_Error error = FT_Init_FreeType(&m_pFTLib);
       if(FT_New_Face(m_pFTLib, "C:/WINDOWS/Fonts/simkai.ttf", 0, &m_pFTFace))
       {
           return;
       }
       FT_Select_Charmap(m_pFTFace, FT_ENCODING_UNICODE); 
       FT_Set_Char_Size(m_pFTFace, 0, 12<<6, 300, 300);

 

// 此出将"A"改为汉字,则只显示出一个框;
       error = FT_Load_Glyph(m_pFTFace, FT_Get_Char_Index(m_pFTFace, 'A'), FT_LOAD_DEFAULT);
       // 第二个参数为渲染模式,这里渲染为1位位图(黑白位图),若为FT_RENDER_MODE_NORMAL则渲染为256级灰度图;  
       error = FT_Render_Glyph(m_pFTFace->glyph,  FT_RENDER_MODE_NORMAL);  

       FT_Bitmap& bmp = m_pFTFace->glyph->bitmap;
       int h = bmp.rows;
       int w = bmp.width;


     
       for(int i=0; i<h; i++)
       {
           for(int j=0; j<w; j++)
           {
               if((bmp.buffer[i * w  + j]) == 0 ) {
                 printf("0");
               }
               else
               {
                  printf("1");
               }
           }

        printf("\n");
       }

}


int main(int argc, char **argv)
{
    TestTrueType();
	
	return 0;
}
    运行结果:
  
   这里显示的是点阵字体,我们要做矢量字库。

二.在vc6.0上制作字库

    网上关于矢量字体讲述很多这里不细说。 

    a.这里制作分别是英文字库和汉字字库(GB2312码)

    b.关于字体,可以自己随便选择。

    c.有时候制作矢量字体可能少了些笔画,需要程序相应的调整。

       

#include "ft2build.h"
//#include FT_FREETYPE_H  
#include "freetype/freetype.h" 
#include "freetype/ftglyph.h"  
#include  <graphics.h>
#include "Unicode.h"
#include <stdlib.h>
#include "testfont.h"

typedef unsigned short UINT16;
typedef short	INT16;
typedef unsigned char UINT8;
typedef char	INT8;
typedef unsigned int UINT32;
typedef int	INT32;

#define	GB_OFFSET_NUMBER	94		//the number of one GB zone.
#define	GB_MIN_ZONE			0xA0	//min value of the zone number of GB code
#define	GB_MAX_ZONE			0xF8	//max value of the zone number of GB code
#define	GB_MIN_OFFSET		0xA1	//min value of the offset number of GB code
#define	GB_MAX_OFFSET		0xFF	//max value of the offset number of GB code
#define	MAX_OFFSET_IN_TABLE	8272	//the max offset of the conversion table.
#define ENLISH_FONT	0
#define	CHINA_FONT	1
#define	MAX	50

UINT16	set_font_width = 0;
UINT16	set_font_higth = 0;
INT8 PATH_FONT_NAME[MAX];
UINT32	Ascender;

void initgr(void) 
{ 
	int gd = DETECT, gm = 0; 

	initgraph(&gd, &gm, "");
}

int writeAassicToFile( const char *file, const char *path)
{
	FILE *fp = NULL;
	FILE *fp1 =NULL;
	FT_Library    pFTLib         =  NULL;  
	FT_Face        pFTFace         =  NULL;  
	FT_Glyph    glyph;
	FT_Error    error         =   0 ; 
	UINT8 buffer[4096];
	UINT32	header[256];
	UINT16 count = 0, assic_nu = 0, read_nu, i, j = 0, k;
	UINT16 m, n;
	UINT32	address = 0;
	INT8	name[100];
	UINT16 Font_w, Font_h;
	UINT16 start_point = 0;

	if( (fp = fopen(file, "wb")) == NULL ){
		printf("fail open %s file!", file);
		return 0;
	}

#if 1	
	if( (fp1 = fopen("ASSIC_Info.txt", "w+")) == NULL ){
		printf("fail open %s file!", file);
		return 0;
	}
#endif

	if( FT_Init_FreeType( & pFTLib) ){  
		pFTLib  =   0 ;  
		printf( " There is some error when Init Library " );  
		return   - 1 ;  
	}  

	error  =  FT_New_Face(pFTLib,  path ,  0 ,  & pFTFace);
	if( error ){					
		printf("fail open %s font file err num : %d \n", path, error);
		return  -1;
	}
	address = 1024;	//存储字符码表的信息	

	FT_Set_Char_Size(pFTFace,  set_font_width * 64 , set_font_higth*64, 72,  72); 
	Ascender = pFTFace->size->metrics.ascender >> 6; 
	printf("Vector font %s file running...\n", file);
	for( k = 0x20; k < 128; k++)
	{	
		FT_Load_Glyph(pFTFace, FT_Get_Char_Index(pFTFace,  k), FT_LOAD_DEFAULT);      
		error = FT_Get_Glyph(pFTFace -> glyph,  & glyph);
		if(error){
			printf("fail get %x data info\n", i);
			return -1;
		}
		FT_Glyph_To_Bitmap( & glyph, ft_render_mode_normal,  0 ,  1 );  
		FT_BitmapGlyph bitmap_glyph  =  (FT_BitmapGlyph)glyph;  
		FT_Bitmap &bitmap  =  bitmap_glyph -> bitmap; 
		if (bitmap_glyph->left < 0){
			bitmap_glyph->left = 0;

		}	
		header[k] = ((bitmap_glyph->left+bitmap.width)<< 24) | address;
		Font_w = bitmap.width;
		Font_h = bitmap.rows;//	dy = Ascender-bitmap_glyph->top;
		start_point =  (Ascender- bitmap_glyph->top);//Ascender- bitmap_glyph->top
		if (bitmap_glyph->top < bitmap.rows)
			start_point -= (bitmap.rows - bitmap_glyph->top)/2 ;

		for( m = 0; m < set_font_higth;  ++m)  //set_font_higth
		{			
			for( n = 0; n < (bitmap.width+bitmap_glyph->left);  ++ n){  //set_font_width
				if(m < start_point) buffer[count++] = 0;
				else if(m >= start_point +bitmap.rows) buffer[count++] = 0;
				else{
					if(n < bitmap_glyph->left)buffer[count++] = 0;
					else if(n > bitmap_glyph->left+bitmap.width)buffer[count++] = 0;
					else buffer[count++] = bitmap.buffer[(m - start_point) * bitmap.width + n -bitmap_glyph->left ];
				}
				}
		}
		fseek( fp, address, SEEK_SET);
		read_nu = fwrite( buffer, count, 1, fp);

		sprintf(name,"%c address:width: %d height :%d left:%d top:%d %x Ascender:%d\n", k, bitmap.width, bitmap.rows,bitmap_glyph->left,bitmap_glyph->top, address, Ascender);
		fwrite(name, strlen(name), 1, fp1);
		address += count;
		count = 0;
	

		FT_Done_Glyph(glyph);  
		glyph  =  NULL;  

	}
	fclose(fp1);
	fseek( fp, 0, SEEK_SET);
	read_nu = fwrite( (UINT8 *)header, 1024, 1, fp);
	fclose(fp);
	printf("Generate complete vector fonts\n");
}

int writeHZToFile( const char *file, const char *path)
{
	FILE *fp = NULL;
	FILE *fp1 =NULL;
	FT_Library    pFTLib         =  NULL;  
	FT_Face        pFTFace         =  NULL;  
	FT_Bitmap bitmap;
	FT_Glyph    glyph;
	FT_Error    error         =   0 ; 
	UINT8 buffer[4096];
	UINT32	header[256], dx, dy;
	UINT32 count = 0, assic_nu = 0, read_nu, i, j = 0, k;
	UINT32 m, n;
	UINT32	address = 0;	
	UINT16	offset, ucs2_code;
	INT8	name[100];
	INT8 charbuff[3];
	
	if( (fp = fopen(file, "wb")) == NULL ){
		printf("fail open %s file!", file);
		return 0;
	}
#if 1	
		if( (fp1 = fopen("HZ_Info.txt", "w+")) == NULL ){
			printf("fail open %s file!", file);
			return 0;
		}
#endif


	if( FT_Init_FreeType( & pFTLib) ){  
		pFTLib  =   0 ;  
		printf( " There is some error when Init Library " );  
		return   - 1 ;  
	}  

	error  =  FT_New_Face(pFTLib,  path ,  0 ,  & pFTFace);
	if( error ){															// //simhei.ttf
		printf("fail open %s font file err num : %d \n", path, error);
		return  -1;
	}//simfang.ttf
	FT_Set_Char_Size(pFTFace,  set_font_width * 64 , set_font_higth*64, 72,  72); 
	Ascender = pFTFace->size->metrics.ascender >> 6; 
	printf("start write data....\n Ascender:%d\n", Ascender);

	address = 0;
	printf("Vector font %s file running...\n", file);
	for(i = GB_MIN_ZONE;i < GB_MAX_ZONE; i++ ){
		for(j = GB_MIN_OFFSET;j < GB_MAX_OFFSET; j++ ){
			charbuff[0] = i;
			charbuff[1] = j;
			charbuff[2] = '\0';
			offset = (j - GB_MIN_OFFSET) + (i - GB_MIN_ZONE) * GB_OFFSET_NUMBER;	
			ucs2_code = (offset < MAX_OFFSET_IN_TABLE) ? gb2312_to_ucs2_table[offset] : 0x00;
			
			FT_Load_Glyph(pFTFace, FT_Get_Char_Index(pFTFace,  ucs2_code), FT_LOAD_DEFAULT);
			if( (error = FT_Get_Glyph(pFTFace -> glyph,  & glyph)) != 0){
				printf("fail get %x data info\n", i);
				return -1;	
			}
			FT_Glyph_To_Bitmap( & glyph, ft_render_mode_normal,  0 ,  1 );  
			FT_BitmapGlyph bitmap_glyph  =  (FT_BitmapGlyph)glyph;  
			bitmap = bitmap_glyph ->bitmap;
	//		if (bitmap_glyph->left < 0){
	//		bitmap_glyph->left = 0;
	//		}
			dy =Ascender - bitmap_glyph->top;//Ascender - bitmap_glyph->top
			for( m = 0 ; m < set_font_higth;  m++)  
			{			
				for( n = 0 ; n < set_font_width;  n++)
				{ 
					if( m <= dy){
						buffer[count] = 0;
					}else if( m >= dy +bitmap.rows){
						buffer[count] = 0;
					}else {
						if(n <= bitmap_glyph->left){
							buffer[count] = 0;
						}else if( n >= (bitmap_glyph->left + bitmap.width)){
							buffer[count] = 0;
						}else{
							buffer[count] = bitmap.buffer[(m-dy) * bitmap.width + n-bitmap_glyph->left];
						} 
					}
					count++;
					
				}
			}

			fseek( fp, address, SEEK_SET);
			read_nu = fwrite( buffer, 1, count, fp);
			sprintf(name,"%s address:width: %d height :%d left:%d top:%d %x Ascender:%d\n", charbuff, bitmap.width, bitmap.rows,bitmap_glyph->left,bitmap_glyph->top, address, Ascender);
			fwrite(name, strlen(name), 1, fp1);
	
			address += read_nu;
			count = 0;
			FT_Done_Glyph(glyph);  
			glyph  =  NULL; 
		}		
	}
	fclose(fp1);
	fclose(fp);
	printf("Generate complete vector fonts\n");
}

 int main(int argc, char* argv[])
{
	char kind_font = 0;
	char filename[50];
	char i, buff[1];
	char *path = "C:\\Windows\\Fonts\\simhei.ttf";//arial.ttf msyh.ttf simhei.ttf
	initgr();

	set_font_width =24;
	set_font_higth = set_font_width;
	kind_font = ENLISH_FONT;
	
	if( kind_font == ENLISH_FONT){
		sprintf(filename, "ASSIC_%d.bin", set_font_width);
		printf("filename:%s\n", filename);
		writeAassicToFile(filename, path); 
		displayAssic("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,![]", filename, set_font_higth);
	}else if( kind_font == CHINA_FONT ){
		sprintf(filename, "HZ_%d.bin", set_font_width);
		printf("filename:%s\n", filename);
		writeHZToFile(filename, path);
		displaystring("一二三四五六七八九十",filename, set_font_higth);
	}
	printf("font width %d height %d\n", set_font_width, set_font_higth);
	getchar();
	
  return 0;
}
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include "testfont.h"

#define RGBTranRGB565(x)	((((x) & 0xf80000) >> 19 << 11) | (((x)&0xfc00) >> 10 << 5) | (((x)&0xf8) >> 3)) & 0xffff		//24位的RGB转化为RGB565十六位
UINT8 data[1024*4];	// 最大45号字体

UINT32	 FontIndexTable[256];

void GetOneCharWidth(char *filename)
{	FILE *fp = NULL;
	UINT16 len;

	fp=fopen(filename, "rb");
	len = fread( (UINT8 *)FontIndexTable,1 ,1024 ,fp );
//	printf("read %s file head %d bytes!", filename, len);
	fclose(fp);
	
	return ;
}
int setcolor(UINT8 apha, UINT32 color ){
	UINT16 temp;
	UINT8 R, G, B;
	UINT32 back_color = 0;

	back_color = getbkcolor();
//	printf("back_color:%x\n", back_color);
	R =  GetRValue(back_color) + (GetRValue(color) - GetRValue(back_color))*apha / 255;//( (color & 0xff) + ( (-color + WHITE) & 0xff) * apha / 255) & 0xff;
	G =  GetGValue(back_color) + (GetGValue(color) - GetGValue(back_color))*apha / 255;//( ((color >> 8)&0xff) + (( (-color + WHITE) >> 8)&0xff) *apha / 255) & 0xff;
	B =  GetBValue(back_color) + (GetBValue(color) - GetBValue(back_color))*apha / 255;//( ((color  >> 16) &0xff) + (( (-color + WHITE)  >> 16) &0xff) *apha / 255) & 0xff;
	temp = B << 16 | G << 8 | R;

	return  temp;//RGBTranRGB565(temp)
}

void DisOneHZ(char *filename, int x, int y, int fontSize, char *hz){
	UINT32 address = 0;
	FILE *fp = NULL;
	UINT16 read_byte_num, i, j;
	UINT16 counter = 0;

	address = ( ( (hz[0]&0xff) - 0xA0) * 94 + (hz[1] & 0xff) - 0xA1 )*fontSize*fontSize;
//	printf("address:%x hz[0]: %x hz[1]:%x\n", address, hz[0], hz[1]);


	if( (fp = fopen(filename, "rb")) == NULL ){
		printf("fail open %s file\n", filename);	
		return ;
	}

	fseek(fp, address, SEEK_SET);
	counter = fontSize*fontSize;

	read_byte_num = fread(data, 1,counter,  fp);
	printf("from %s file read %d bytes\n", filename, read_byte_num);

	for( i = y; i < fontSize + y; i++ ){
		for( j = x; j < fontSize + x; j++ )
			putpixel( j, i, setcolor( data[(i - y)*fontSize + (j - x)] , BROWN));
#if 0
			if(data[(i - y)*fontSize + (j - x)]){//data[(i - y)*fontsize + (j - x)]){
				printf("*");
			}else{
				printf("-");
			}

#endif
	}
	fclose(fp);

}

void DisOneChar(int x, int y, int fontSize, UINT16 fontwidth, UINT8 c){
	UINT16  i, j;
	setcolor(WHITE); 
	rectangle(x - 2, y, x+fontwidth ,y + fontSize );
	if( fontwidth > fontSize / 2){
		printf("char ==> %c fontwidth:%d", c, fontwidth);
	}
	for( i = y; i < fontSize + y; i++ ){
		for( j = x; j <  fontwidth+ x; j++ ){
			putpixel( j, i, setcolor( data[(i - y)*fontwidth + (j - x)] , LIGHTGREEN));
	#if 0
			if(data[(i - y)*fontwidth + (j - x)]){//data[(i - y)*fontsize + (j - x)]){
				printf("*");
			}else{
				printf("-");
			}
	#endif
		}
	}

}
void displaystring(char *string, char *name, char size){
	UINT32 i = 0, j = 0;
	char temp[3];

	while(*string){
		if((*string)&0x80){
			temp[0] = string[0];
			temp[1] = string[1];
			temp[2] = '\0';
			DisOneHZ(name, i, j, size, temp);
			i += size;
			if(i > 25*24){
				i = 0;
				j += size;
			}
			printf("\n");
			
			string += 2;
			continue;
		}	
		string += 1;
	}
}

void displayAssic(char *str, char *name, char size)
{	
	char c = 0;
	UINT16 i = 20, j = 20;
	FILE *fp = NULL;
	UINT32	charaddr, len;
	int fontwidth;

	GetOneCharWidth(name);
	while(*str){
		if( *str < 0x80 ){
			c = *str;

			if( (fp = fopen(name, "rb")) == NULL ){
				printf("fail open %s file\n", name);	
				return ;
			}
			charaddr = FontIndexTable[c];
			fontwidth = (charaddr>>24)&0xff;
			charaddr &= 0x00ffffff;
			fseek(fp, charaddr, SEEK_SET);
			len = fread(data, 1, fontwidth*size,  fp);
			printf("read %s file %c size %d bytes!", name, c, len);
			fclose(fp);
			if( i + fontwidth > 480 ){
				i = 20;
				j += size;
			}
			DisOneChar(i, j, size, fontwidth, *str);
			i += size;
		
		}
		str++;
	}
}

测试英文显示如下图


                                                  
测试汉字如下图


原代码已经上传到cdsn上

 http://download.csdn.net/detail/wangyajietiegu/9542057

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值