#include #include #include #include
#include "gb2312.h"
#include "freetype2.h"
static struct{
char szFontName[64];
char szFontFile[128];
}FontInfo[] = {
{ "楷体", "./simkai.ttf" },
{ "黑体", "./simhei.ttf" },
{ "宋体", "./simsun.ttc" },
{ "Uming", "./uming.ttf" },
{ "Arial", "./arial.ttf" }
};
static FT_Vector pen;
static char* GetFontFile(char *pszFontName)
{
int i;
int nSize;
if((NULL == pszFontName) || ('\0' == *pszFontName))
goto err;
nSize = sizeof(FontInfo) / sizeof(FontInfo[0]);
for(i=0; i{
if(!strcmp(pszFontName, FontInfo[i].szFontName))
return FontInfo[i].szFontFile;
}
err:
return FontInfo[2].szFontFile;
}
BOOL FreeType2_SetCharSize(PFT2FONT pFont, int nWid, int nHei)
{
FT_Error nErr;
if(NULL == pFont)
return FALSE;
nErr = FT_Set_Pixel_Sizes(pFont->face, nWid, nHei);
if(nErr != FT_Err_Ok)
{
printf("FreeType_SetCharSize->FT_Set_Pixel_Sizes fail: %d\n", nErr);
return FALSE;
}
return TRUE;
}
BOOL FreeType2_InitFont(PFT2FONT pFont, char *pszName, int nFontWidth, int nFontHeight, BOOL bBold, BOOL bItalic, BOOL bUnderline)
{
BOOL bRet;
char *pszFontFile;
FT_Error nErr;
if((NULL == pFont) || (NULL == pszName) || ('\0' == *pszName) || (nFontWidth < 0) || (nFontHeight < 0))
return FALSE;
memset((void*)pFont, 0, sizeof(FT2FONT));
pszFontFile = GetFontFile(pszName);
if(NULL == pszFontFile)
return FALSE;
nErr = FT_Init_FreeType(&pFont->library);
if(nErr != FT_Err_Ok)
{
printf("FreeType2_InitFont->FT_InitFreeType fail: %d\n", nErr);
return FALSE;
}
nErr = FT_New_Face(pFont->library, pszFontFile, 0, &pFont->face);
if(nErr != FT_Err_Ok)
{
printf("FreeType2_InitFont->FT_New_Face fail: %d\n", nErr);
goto err1;
}
nErr = FT_Select_Charmap(pFont->face, ft_encoding_unicode);
if(nErr != FT_Err_Ok)
{
nErr = FT_Select_Charmap(pFont->face, ft_encoding_latin_1);
if(nErr != FT_Err_Ok)
{
printf("FreeType2_InitFont->FT_Select_Charmap error: %d\n", nErr);
goto err0;
}
}
nErr = FT_Set_Char_Size(pFont->face, 16 << 6, 16 << 6, 300, 300);
if(nErr != FT_Err_Ok)
{
printf("FreeType2_InitFont->FT_Set_Char_Size error: %d\n", nErr);
goto err0;
}
bRet = FreeType2_SetCharSize(pFont, nFontWidth, nFontHeight);
if(!bRet)
goto err0;
pFont->bBold = bBold;
pFont->bItalic = bItalic;
pFont->bUnderline = bUnderline;
pFont->nWid = nFontWidth;
pFont->nHei = nFontHeight;
return TRUE;
err0:
FT_Done_Face(pFont->face);
err1:
FT_Done_FreeType(pFont->library);
return FALSE;
}
BOOL FreeType2_ClearNode(PFT2FONT pFont)
{
PNODE pNode;
PNODE pPrevNode;
if(NULL == pFont)
return FALSE;
for(pNode=pFont->pHeadNode; pNode!=NULL; )
{
pPrevNode = pNode;
pNode = pNode->pNext;
if(pPrevNode->pucData != NULL)
free(pPrevNode->pucData);
free(pPrevNode);
}
return TRUE;
}
BOOL FreeType2_DestroyFont(PFT2FONT pFont)
{
if(NULL == pFont)
return FALSE;
FT_Done_Face(pFont->face);
FT_Done_FreeType(pFont->library);
FreeType2_ClearNode(pFont);
return TRUE;
}
static unsigned short s_font_utf8_to_unicode (const unsigned char *utf8)
{
unsigned short unicode;
unicode = utf8[0];
if (unicode >= 0xF0) {
unicode = (unsigned short) (utf8[0] & 0x07) << 18;
unicode |= (unsigned short) (utf8[1] & 0x3F) << 12;
unicode |= (unsigned short) (utf8[2] & 0x3F) << 6;
unicode |= (unsigned short) (utf8[3] & 0x3F);
} else if (unicode >= 0xE0) {
unicode = (unsigned short) (utf8[0] & 0x0F) << 12;
unicode |= (unsigned short) (utf8[1] & 0x3F) << 6;
unicode |= (unsigned short) (utf8[2] & 0x3F);
} else if (unicode >= 0xC0