#include
#include
#include "bmptext/gb2312.h"
#include "bmptext/font.h"
static struct{
char szFontName[32];
char szFontFile[128];
}FontInfo[] = {
{ "楷体", "./simkai.ttf" },
{ "黑体", "./simhei.ttf" },
{ "宋体", "./SIMSUN.TTC" },
{ "Uming", "./uming.ttf" }
};
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 InitFont(PFONT pFont, char *pszName)
{
int i;
float fAngle;
char *pszFontFile;
FT_Error Error;
FT_Matrix matrix;
if((NULL == pFont) || (NULL == pszName) || ('\0' == *pszName))
return FALSE;
pszFontFile = GetFontFile(pszName);
printf("%s, %s\n", pszName, pszFontFile);
Error = FT_Init_FreeType(&pFont->library);
if(Error != FT_Err_Ok)
{
printf("InitFont->FT_InitFreeType error: %d\n", Error);
pFont->library = NULL;
return FALSE;
}
Error = FT_New_Face(pFont->library, pszFontFile, 0, &pFont->face);
if(Error != FT_Err_Ok)
{
printf("InitFont->FT_New_Face error: %d\n", Error);
FT_Done_FreeType(pFont->library);
pFont->library = NULL;
pFont->face = NULL;
return FALSE;
}
Error = FT_Set_Char_Size(pFont->face, 0, 64 << 4, 300, 300);
if(Error != FT_Err_Ok)
{
printf("InitFont->FT_Set_Char_Size error: %d\n", Error);
FT_Done_Face(pFont->face);
FT_Done_FreeType(pFont->library);
pFont->library = NULL;
pFont->face = NULL;
return FALSE;
}
pFont->nWid = 0;
pFont->nHei = 0;
pFont->nWid0 = 0;
pFont->nHei0 = 0;
pFont->nCount = 0;
pFont->nWidStep = 0;
pFont->nAsciiChina = 0;
for(i=0; i {
pFont->nWids[i] = 0;
pFont->nHeis[i] = 0;
pFont->chTexts[i] = 0;
pFont->nFlags[i] = FONT_OTHER;
pFont->nWidSteps[i] = 0;
pFont->pusData[i] = NULL;
}
fAngle = -pFont->nEscapement/180. * 3.14;
matrix.xx = (FT_Fixed)( cos(fAngle) * 0x10000L);
matrix.xy = (FT_Fixed)(-sin(fAngle) * 0x10000L);
matrix.yx = (FT_Fixed)( sin(fAngle) * 0x10000L);
matrix.yy = (FT_Fixed)( cos(fAngle) * 0x10000L);
FT_Set_Transform(pFont->face, &matrix, NULL);
return TRUE;
}
BOOL DestroyFont(PFONT pFont)
{
int i;
if(NULL == pFont)
return FALSE;
if(pFont->face != NULL)
FT_Done_Face(pFont->face);
if(pFont->library != NULL)
FT_Done_FreeType(pFont->library);
pFont->face = NULL;
pFont->library = NULL;
for(i=0; i
nCount; i++)
{
if(pFont->pusData[i] != NULL)
free(pFont->pusData[i]);
pFont->pusData[i] = NULL;
}
return TRUE;
}
BOOL SetFontSize(PFONT pFont, int nWid, int nHei)
{
FT_Error err;
if((NULL == pFont) || (NULL == pFont->face))
return FALSE;
err = FT_Set_Pixel_Sizes(pFont->face, nWid, nHei);
if(err != FT_Err_Ok)
return FALSE;
pFont->nWid0 = nWid;
pFont->nHei0 = nHei;
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) {
unicode = (unsigned short) (utf8[0] & 0x1F) << 6;
unicode |= (unsigned short) (utf8[1] & 0x3F);
}
return unicode;
}
BOOL FreeType2_GetFontData(PFONT pFont, char *pText)
{
int i, j, k, n;
int nSize;
int num_chars;
int nFlagAscii = 0;
int nFlagChina = 0;
int nDxs[128];
char *pTemp = NULL;
unsigned char ucData1;
unsigned char ucData2;
unsigned short usData;
unsigned short *unicode = NULL;
unsigned char *pucBuf = NULL;
FT_UInt index;
FT_Error Error;
if((NULL == pFont) || (NULL == pFont->face) || (NULL == pText) || '\0' == *pText)
return FALSE;
for(num_chars=0,pTemp=pText; *pTemp!='\0'; )
{
if(*pTemp & 0x80)
pTemp += 2;
else
pTemp++;
num_chars++;
}
if(num_chars > UNICODE_MAX)
num_chars = UNICODE_MAX;
unicode = (unsigned short*)malloc(sizeof(unsigned short*)*(num_chars + 1));
if(NULL == unicode)
return FALSE;
for(n=0,pTemp=pText; *pTemp!='\0'; n++)
{
if(*pTemp & 0x80)
{
nFlagAscii = 1;
pFont->nFlags[n] = FONT_CHINA;
unicode[n] = gb2312_0_conv_to_uc32(pTemp);
pTemp += 2;
}
else
{
nFlagChina = 1;
pFont->nFlags[n] = FONT_ASCII;
pFont->chTexts[n] = *pTemp;
unicode[n] = s_font_utf8_to_unicode(pTemp);
pTemp++;
}
}
num_chars = n;
pFont->nCount = n;
pFont->nAsciiChina = 0;
if(nFlagAscii && nFlagChina)
pFont->nAsciiChina = 1;
pFont->nHei = 0;
pFont->nWid = 0;
for(n=0; n {
index = FT_Get_Char_Index(pFont->face, unicode[n]);
Error = FT_Load_Glyph(pFont->face, index, FT_LOAD_DEFAULT);
if(Error)
continue;
Error = FT_Render_Glyph(pFont->face->glyph, FT_RENDER_MODE_MONO);
if(Error)
continue;
pFont->nWids[n] = pFont->face->glyph->bitmap.pitch;
if(pFont->nWids[n] % 2)
pFont->nWids[n]++;
pFont->nWids[n] /= 2;
pFont->nHeis[n] = pFont->face->glyph->bitmap.rows;
nSize = pFont->nWids[n] * pFont->nHeis[n] * sizeof(unsigned short);
pFont->pusData[n] = (unsigned short*)malloc(nSize);
if(NULL == pFont->pusData[n])
{
free(unicode);
return FALSE;
}
memset((void*)pFont->pusData[n], 0, nSize);
pucBuf = pFont->face->glyph->bitmap.buffer;
for(i=0; i
nHeis[n]; i++)
for(j=0; jnWids[n]; j++)
{
ucData1 = *(pucBuf + i*pFont->face->glyph->bitmap.pitch + 2*j);
if(2*j+1 >= pFont->face->glyph->bitmap.pitch)
usData = (ucData1 << 8) | 0xff00;
else
{
ucData2 = *(pucBuf + i*pFont->face->glyph->bitmap.pitch + 2*j+1);
usData = (ucData1 << 8) | ucData2;
}
*(pFont->pusData[n] + i*pFont->nWids[n] + j) = usData;
}
/*{
FILE *fp = fopen("./xs.txt", "a+");
for(i=0; i
face->glyph->bitmap.rows; i++, fprintf(fp, "\n"))
for(j=0; jface->glyph->bitmap.pitch; j++)
for(k=0; k<8; k++)
{
if(*(pFont->face->glyph->bitmap.buffer + i*pFont->face->glyph->bitmap.pitch + j) & (0x80 >> k))
fprintf(fp, "1");
else
fprintf(fp, " ");
}
fclose(fp);
}*/
memset((void*)nDxs, 0, sizeof(nDxs));
for(i=0; i
nHeis[n]; )
{
for(j=pFont->nWids[n]-1; j>=0; j--)
{
if(*(pFont->pusData[n] + i*pFont->nWids[n] + j))
{
for(k=0; k<16; k++)
if((*(pFont->pusData[n] + i*pFont->nWids[n] + j) >> k) & 0x0001)
{
nDxs[i] = 16*(pFont->nWids[n] - 1 - j) + k;
goto next;
}
}
}
next:
i++;
}
pFont->nWidSteps[n] = 10000;
for(i=0; i
nHeis[n]; i++)
{
if((nDxs[i] > 0) && (pFont->nWidSteps[n] > nDxs[i]))
pFont->nWidSteps[n] = nDxs[i];
}
pFont->nHei = (pFont->nHeis[n] > pFont->nHei) ? pFont->nHeis[n] : pFont->nHei;
pFont->nWid = (pFont->nWids[n] > pFont->nWid) ? pFont->nWids[n] : pFont->nWid;
}
for(n=0; n {
if(pFont->nWids[n] < pFont->nWid)
pFont->nWidSteps[n] += (pFont->nWid - pFont->nWids[n])*16;
}
pFont->nWidStep = 1000;
for(n=0; n {
if(pFont->nWidStep > pFont->nWidSteps[n])
pFont->nWidStep = pFont->nWidSteps[n];
}
free(unicode);
return TRUE;
}